diff --git a/.hgignore b/.hgignore index 1b7a9019a265cfc9fb6ba03a1e7a9d6aa8ee2120..0d672e6ebc35bdc7399b31425ae4bc65feb5a0b2 100755 --- a/.hgignore +++ b/.hgignore @@ -17,6 +17,8 @@ build-darwin-* build-vc80/ build-vc100/ build-vc120/ +build-vc120-32/ +build-vc120-64/ indra/build-vc[0-9]* indra/CMakeFiles indra/lib/mono/1.0/*.dll diff --git a/.hgtags b/.hgtags index 492d89261c9cc45ddbd6b922d77b4b8ded590ed4..797f517d841f093d5a58eba6535c1d5b1272f69d 100755 --- a/.hgtags +++ b/.hgtags @@ -516,3 +516,10 @@ e9d350764dfbf5a46229e627547ef5c1b1eeef00 4.0.2-release 86dfba7ec4332c323025ebeacd8bf343ed0d8cfd 4.0.3-release 0a5de9ec2cb868f367501024d8d6958c20869053 4.0.4-release 450de775fff66a011be1a001acd117cc623c445d 4.0.5-release +4070611edd95eb3a683d1cd97c4c07fe67793812 4.0.6-release +33981d8130f031597b4c7f4c981b18359afb61a0 4.0.7-release +45eaee56883df7a439ed3300c44d3126f7e3a41e 4.0.8-release +b280a1c797a3891e68dbc237e73de9cf19f426e9 4.1.1-release +bfbba2244320dc2ae47758cd7edd8fa3b67dc756 4.1.2-release +b41e1e7c7876f7656c505f552b5888b4e478f92b 5.0.0-release +c9ce2295012995e3cf5c57bcffcb4870b94c649f 5.0.1-release diff --git a/BuildParams b/BuildParams index 264f6f8a530663f471f148ca2ab2eebe28e26b0c..a5edfadbd655ca86639239e039b550ad039624e7 100755 --- a/BuildParams +++ b/BuildParams @@ -3,36 +3,18 @@ # Please refer to: # https://wiki.secondlife.com/wiki/Automated_Build_System - -# Global setting for now.... -Darwin.symbolfiles = "newview/Release/secondlife-symbols-darwin.tar.bz2" -CYGWIN.symbolfiles = "newview/Release/secondlife-symbols-windows.tar.bz2" -Linux.symbolfiles = "newview/secondlife-symbols-linux.tar.bz2" +# Variants (NOTE: 'Release' must be last for uploads to work correctly) +variants = "RelWithDebInfo Release" # Use Public Upload Locations public_build = true build_docs = true -# disable all Debug builds (RelWithDebInfo is sufficient) -build_CYGWIN_Debug = false -build_Linux_Debug = false -build_Darwin_Debug = false -build_Debug = false - # enable Doxygen building on Linux for TeamCity (it can be done manually on any platform) build_Linux_Doxygen = true -# Update Public Inworld Build Status Indicators (setting should mirror "public_build") -email_status_this_is_os = true - -# Limit extent of codeticket updates to revisions after... -codeticket_since = 3.3.0-release - -# Override build system default toolchain -# Note that this will only affect automated builds. -Linux.distcc_version = -Linux.gcc_version = /usr/bin/gcc-4.6 -Linux.cxx_version = /usr/bin/g++-4.6 +# Need viewer-build-variables as well as other shared repositories +buildscripts_shared_more_NAMEs="build_variables" ################################################################ #### Examples of how to set the viewer_channel #### @@ -88,6 +70,5 @@ EDU_viewer_channel_suffix = "edu" # Notifications - to configure email notices use the TeamCity parameter # setting screen for your project or build configuration to set the # environment variable 'email' to a space-separated list of email addresses - - +email="" diff --git a/autobuild.xml b/autobuild.xml old mode 100755 new mode 100644 index 469f1c32f5f03c59aa476fe1d028487e6fd6506b..a655c7cae2fa3d5a6e37fb1b8d60b04bed2da2de --- a/autobuild.xml +++ b/autobuild.xml @@ -29,6 +29,18 @@ <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>7ea2df03bfc35c06acf23dd9e734adac</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1103/2554/SDL-1.2.15-linux64-501092.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> </map> <key>version</key> <string>1.2.15</string> @@ -59,33 +71,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>ae733dd8f2c83055030ea6e08c623306</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/745/1534/apr_suite-1.4.5.500735-darwin64-500735.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>402552cf158e2fe953b7224f4615a957</string> + <string>1aa2e5355bb9df09f9196d14a72b6705</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/apr_3p-update-apr/rev/297252/arch/Linux/installer/apr_suite-1.4.5.297252-linux-297252.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-apr/rev/314241/arch/Linux/installer/apr_suite-1.4.5.314241-linux-314241.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>bc8855c8253b8293c7e61af7b1ed0f05</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/744/1545/apr_suite-1.4.5.500735-linux64-500735.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>8f865b509bb5011caf3dd95a22a4589d</string> + <string>7d97a3788ea4f89eccb7789e4f015bb3</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/apr_3p-update-apr/rev/297252/arch/CYGWIN/installer/apr_suite-1.4.5.297252-windows-297252.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/747/1540/apr_suite-1.4.5.500735-windows-500735.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>8820c4df1079a9af53f52485f50ff179</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/746/1537/apr_suite-1.4.5.500735-windows64-500735.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>1.4.5.297252</string> + <string>1.4.5.500735</string> </map> <key>boost</key> <map> @@ -113,30 +161,66 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>d318c25353e41215f1f523d58cacfd44</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/893/1984/boost-1.57-darwin64-500883.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>fb1537f7ad0b490fcb4f096c15dce9cd</string> + <string>f1fdb548fd6c09a083c86f3a23d7f041</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/boost_3p-update-boost/rev/297445/arch/Linux/installer/boost-1.57-linux-297445.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-boost/rev/317807/arch/Linux/installer/boost-1.57-linux-317807.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>8e7ee97c3083f44385b09420655ebd04</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/892/1989/boost-1.57-linux64-500883.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>76a607d8a625062b9a63a88b62819894</string> + <string>80b1963d635e883cb5ed223e94406adb</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/boost_3p-update-boost/rev/297445/arch/CYGWIN/installer/boost-1.57-windows-297445.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/894/1976/boost-1.57-windows-500883.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>3d6a6373ed0daa490cdb4f92db45de52</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/895/1979/boost-1.57-windows64-500883.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> <string>1.57</string> @@ -165,33 +249,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>fa93a9a10fa379091e3e7b85665690d9</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/913/2026/colladadom-2.3.500902-darwin64-500902.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>d627c2a679f3afb8d3e090d42f53cd2e</string> + <string>78b9a6506fb7d53da166f7a65f2278f4</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/colladadom_3p-update-colladadom/rev/297450/arch/Linux/installer/colladadom-2.3.297450-linux-297450.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-colladadom/rev/317826/arch/Linux/installer/colladadom-2.3.317826-linux-317826.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>868127582794d6fd32fa69c9be4e83e4</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/912/2031/colladadom-2.3.500902-linux64-500902.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>220897a1893a188aa9d31efb48909878</string> + <string>5bd7875e16e7f88e21f4c44fe7c6433f</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/colladadom_3p-update-colladadom/rev/297450/arch/CYGWIN/installer/colladadom-2.3.297450-windows-297450.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/915/2035/colladadom-2.3.500902-windows-500902.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>8a647129a0a0a31594557785ea85f840</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/914/2034/colladadom-2.3.500902-windows64-500902.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>2.3.297450</string> + <string>2.3.500902</string> </map> <key>curl</key> <map> @@ -219,35 +339,71 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>99fbc15f514be77c36280f300d257d5a</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1077/2495/curl-7.47.0.501064-darwin64-501064.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>f49d4ed203b03852a3f6b01b18319f7a</string> + <string>9430c08954c00736117099046694e1b1</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-curl/rev/312763/arch/Linux/installer/curl-7.47.0.312763-linux-312763.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-curl/rev/314230/arch/Linux/installer/curl-7.47.0.314230-linux-314230.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>e5d1b0439235f5f3829662a45e566743</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1075/2484/curl-7.47.0.501064-linux64-501064.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>5e0d4f4a5a5bbcba610aafbb91c30b2b</string> + <string>bda9f237d3e8238440bc5bedc2657547</string> <key>hash_algorithm</key> <string>md5</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-curl/rev/312763/arch/CYGWIN/installer/curl-7.47.0.312763-windows-312763.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1078/2487/curl-7.47.0.501064-windows-501064.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>f7fa42c7157cd5007283ae7a5d97393d</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1079/2490/curl-7.47.0.501064-windows64-501064.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>7.47.0.312763</string> + <string>7.47.0.501064</string> </map> <key>db</key> <map> @@ -298,13 +454,25 @@ <key>archive</key> <map> <key>hash</key> - <string>c11ff7e2e0bd59e6e59628f24902bbcd</string> + <string>6d676abd9ad8d2883b855dbe397d9034</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/dbus-glib_3p-update-dbus-glib/rev/297768/arch/Linux/installer/dbus_glib-0.76-linux-297768.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-dbus-glib/rev/314266/arch/Linux/installer/dbus_glib-0.76-linux-314266.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>7ee7b9aed3c0c8c09e7bf26bba7af8e1</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-dbus-glib/rev/314266/arch/Linux/installer/dbus_glib-0.76-linux64-314266.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> </map> <key>version</key> <string>0.76</string> @@ -328,16 +496,16 @@ <key>archive</key> <map> <key>hash</key> - <string>a62723a6deea8187702a2f926e98a35f</string> + <string>2fa9e9e89a81ed2ed686a170681f6bbc</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/dictionaries_3p-update-dictionaries/rev/297347/arch/Linux/installer/dictionaries-1.297347-common-297347.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/571/1225/dictionaries-1.500564-common-500564.tar.bz2</string> </map> <key>name</key> <string>common</string> </map> </map> <key>version</key> - <string>1.297347</string> + <string>1.500564</string> </map> <key>elfio</key> <map> @@ -389,33 +557,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>fd182ab5bed66c94899dec3035310945</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/384/954/expat-2.1.1.500375-darwin64-500375.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>f546615d76bc0f9e8bc2b9ef89f0ca86</string> + <string>387c90b9bb5ec412587fbe7a56261dd1</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/expat_3p-update-expat/rev/297014/arch/Linux/installer/expat-2.0.1.297014-linux-297014.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-expat/rev/314211/arch/Linux/installer/expat-2.1.1.314211-linux-314211.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>5e1f025d1cebd12db542080aa755257f</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/380/943/expat-2.1.1.500375-linux64-500375.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>c70c72a8a0a1e508691a9b35739b373f</string> + <string>09ece3f04ec0bd21dd0d401235aa20f7</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/expat_3p-update-expat/rev/297014/arch/CYGWIN/installer/expat-2.0.1.297014-windows-297014.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/383/949/expat-2.1.1.500375-windows-500375.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>5c82a3482799fe22b3c8fcb317f87bbb</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/382/946/expat-2.1.1.500375-windows64-500375.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>2.0.1.297014</string> + <string>2.1.1.500375</string> </map> <key>fmodex</key> <map> @@ -441,33 +645,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>93257fce19120c01751362775a01b925</string> + <key>url</key> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1545/3481/fmodex-4.44.64.501533-darwin64-501533.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>dd0135d53706a4040d65974f7e804d6f</string> + <string>b847ec838da1ad1dd646df9d74e9b395</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/fmodex_3p-update-fmodex/rev/297261/arch/Linux/installer/fmodex-4.44.31.297261-linux-297261.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/p64_3p-fmodex/rev/314207/arch/Linux/installer/fmodex-4.44.61.314207-linux-314207.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>89a75d8719f7b2cbe1e54cd8407bb992</string> + <key>url</key> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1544/3476/fmodex-4.44.64.501533-linux64-501533.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>5aa7b826e7c1cf95e9cd3ef77e314f35</string> + <string>601c2fc41a18812a45678ef9a87ef772</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/fmodex_3p-update-fmodex/rev/297261/arch/CYGWIN/installer/fmodex-4.44.31.297261-windows-297261.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1546/3486/fmodex-4.44.64.501533-windows-501533.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>e5cde35ae26ebfa256cfe670986e152e</string> + <key>url</key> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1547/3487/fmodex-4.44.64.501533-windows64-501533.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>4.44.31.297261</string> + <string>4.44.64.501533</string> </map> <key>fontconfig</key> <map> @@ -488,46 +728,28 @@ <key>archive</key> <map> <key>hash</key> - <string>864f9361661748ecf0e2cec7110d70b3</string> + <string>a20a3d0ab7fc3401bc2ca81e9309f630</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/fontconfig_3p-update-fontconfig/rev/297551/arch/Linux/installer/fontconfig-2.11.0-linux-297551.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-fontconfig/rev/314281/arch/Linux/installer/fontconfig-2.11.0-linux-314281.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> - </map> - <key>version</key> - <string>2.11.0</string> - </map> - <key>freeglut</key> - <map> - <key>copyright</key> - <string>Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.</string> - <key>description</key> - <string>freeglut is a completely OpenSourced alternative to the OpenGL Utility Toolkit (GLUT) library.</string> - <key>license</key> - <string>freeglut</string> - <key>license_file</key> - <string>LICENSES/freeglut.txt</string> - <key>name</key> - <string>freeglut</string> - <key>platforms</key> - <map> - <key>windows</key> + <key>linux64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>58e328a8b2f3788f932c57ad77e3e117</string> + <string>e2419d56960c160670051fbb055fb729</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/freeglut_3p-update-freeglut/rev/295926/arch/CYGWIN/installer/freeglut-2.6.0.295926-windows-295926.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-fontconfig/rev/314281/arch/Linux/installer/fontconfig-2.11.0-linux64-314281.tar.bz2</string> </map> <key>name</key> - <string>windows</string> + <string>linux64</string> </map> </map> <key>version</key> - <string>2.6.0.295926</string> + <string>2.11.0</string> </map> <key>freetype</key> <map> @@ -555,33 +777,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>3f0698d53acf14b3f0a11dba889d67f3</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/875/1919/freetype-2.4.4.500865-darwin64-500865.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>1ac3152b440287c58509d8af0a50326d</string> + <string>1b401394106cedc86926bd488f5aa45e</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/freetype_3p-update-freetype/rev/297053/arch/Linux/installer/freetype-2.4.4.297053-linux-297053.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-freetype/rev/314215/arch/Linux/installer/freetype-2.4.4.314215-linux-314215.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>94cf61dfdbc86aae5bbaf0b5cb8a366c</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/874/1914/freetype-2.4.4.500865-linux64-500865.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>207aa1a29bfe4ba63edbca38170970a1</string> + <string>b7a8df22cfc910180c66bb1c1ed89cd4</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/freetype_3p-update-freetype/rev/297053/arch/CYGWIN/installer/freetype-2.4.4.297053-windows-297053.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/876/1922/freetype-2.4.4.500865-windows-500865.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>ff72a895012ed603935083496b0a7bc9</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/877/1925/freetype-2.4.4.500865-windows64-500865.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>2.4.4.297053</string> + <string>2.4.4.500865</string> </map> <key>glext</key> <map> @@ -602,30 +860,54 @@ <key>archive</key> <map> <key>hash</key> - <string>4bf4f9e65168138eebbc769e9e12230b</string> + <string>baf1fd13e1fe6aef586200fc87a70f53</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/glext_3p-update-glext/rev/296893/arch/Linux/installer/glext-68-linux-296893.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-glext/rev/314200/arch/Linux/installer/glext-68-linux-314200.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>5f3c9d61b620f949b199ebd8885218ed</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-glext/rev/314200/arch/Linux/installer/glext-68-linux64-314200.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>6eb51c6f17e717a5617b112858d41c80</string> + <string>731d4adecfcbd9f7d20c4bbd2c183962</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/glext_3p-update-glext/rev/296893/arch/CYGWIN/installer/glext-68-windows-296893.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-glext/rev/314200/arch/CYGWIN/installer/glext-68-windows-314200.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>9635e7e6fded468dfc0874a2ead54123</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-glext/rev/314200/arch/CYGWIN/installer/glext-68-windows64-314200.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> <string>68</string> </map> - <key>glh-linear</key> + <key>glh_linear</key> <map> <key>copyright</key> <string>Copyright (c) 2000 Cass Everitt</string> @@ -636,7 +918,7 @@ <key>license_file</key> <string>LICENSES/glh-linear.txt</string> <key>name</key> - <string>glh-linear</string> + <string>glh_linear</string> <key>platforms</key> <map> <key>common</key> @@ -644,9 +926,9 @@ <key>archive</key> <map> <key>hash</key> - <string>44c596c659d32a86972ac9c6f206cb68</string> + <string>fa41756977ad8b9fd2d1465dadd4f956</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/glh-linear_3p-glh-linear/rev/303446/arch/Linux/installer/glh_linear-0.0.0-common-303446.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/529/1139/glh_linear-0.0.0-common-500522.tar.bz2</string> </map> <key>name</key> <string>common</string> @@ -681,91 +963,73 @@ <key>name</key> <string>darwin</string> </map> - <key>linux</key> + <key>darwin64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>fffd130f17cbbe2b93cc241b27262647</string> - <key>hash_algorithm</key> - <string>md5</string> + <string>017ef34ddf14293099a90c6eaa3615ca</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/glod_3p-update-glod/rev/296895/arch/Linux/installer/glod-1.0pre4.296895-linux-296895.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1626/3627/glod-1.0pre3.501614-darwin64-501614.tar.bz2</string> </map> <key>name</key> - <string>linux</string> + <string>darwin64</string> </map> - <key>windows</key> + <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>b0b32155319c6441997c034bdae28a22</string> + <string>58113bcbbacbaeb2d278f745867ae6f0</string> <key>hash_algorithm</key> <string>md5</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/glod_3p-update-glod/rev/296895/arch/CYGWIN/installer/glod-1.0pre4.296895-windows-296895.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-glod/rev/314201/arch/Linux/installer/glod-1.0pre4.314201-linux-314201.tar.bz2</string> </map> <key>name</key> - <string>windows</string> + <string>linux</string> </map> - </map> - <key>version</key> - <string>1.0pre4.296895</string> - </map> - <key>glui</key> - <map> - <key>copyright</key> - <string>Copyright 2006 Paul Rademacher</string> - <key>description</key> - <string>GLUI is a GLUT-based C++ user interface library which provides controls such as buttons, checkboxes, radio buttons, and spinners to OpenGL applications.</string> - <key>license</key> - <string>ZLIB</string> - <key>license_file</key> - <string>LICENSES/glui.txt</string> - <key>name</key> - <string>glui</string> - <key>platforms</key> - <map> - <key>darwin</key> + <key>linux64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>9b7e2ab9b208b3001803294f83d2b610</string> + <string>9aef5cd576ace19568da01d9bc3db29c</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/glui_3p-update-glui/rev/297273/arch/Darwin/installer/glui-2.36.297273-darwin-297273.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1625/3628/glod-1.0pre3.501614-linux64-501614.tar.bz2</string> </map> <key>name</key> - <string>darwin</string> + <string>linux64</string> </map> - <key>linux</key> + <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>f330b3acd03526d827030eefeeb06240</string> + <string>573e68f46f825a1c040daa4994ee2a61</string> + <key>hash_algorithm</key> + <string>md5</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/glui_3p-update-glui/rev/297273/arch/Linux/installer/glui-2.36.297273-linux-297273.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1627/3633/glod-1.0pre3.501614-windows-501614.tar.bz2</string> </map> <key>name</key> - <string>linux</string> + <string>windows</string> </map> - <key>windows</key> + <key>windows64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>75b16a5a606c78aaeb2f8e6046310a58</string> + <string>f8362e1a2f4d03d99c6231101d3d472e</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/glui_3p-update-glui/rev/297273/arch/CYGWIN/installer/glui-2.36.297273-windows-297273.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1628/3638/glod-1.0pre3.501614-windows64-501614.tar.bz2</string> </map> <key>name</key> - <string>windows</string> + <string>windows64</string> </map> </map> <key>version</key> - <string>2.36.297273</string> + <string>1.0pre3.501614</string> </map> <key>google_breakpad</key> <map> @@ -793,33 +1057,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>2d43c6a149cd9c89ba19e884579b1e25</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1836/4096/google_breakpad-1413.501824-darwin64-501824.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>0bf69fbc829d964820b798a0494278c9</string> + <string>352e673897e8f36f8470150b8ace6ce9</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/google-breakpad_3p-update-google-breakpad/rev/298033/arch/Linux/installer/google_breakpad-1413.298033-linux-298033.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-google-breakpad/rev/314225/arch/Linux/installer/google_breakpad-1413.314225-linux-314225.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> - <key>windows</key> + <key>linux64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>c73a7c9aa53a4e266df2d5230a650fbf</string> + <string>6bddcc1ac470dd5eab459220102df9e9</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/google-breakpad_3p-update-google-breakpad/rev/298127/arch/CYGWIN/installer/google_breakpad-1413.298127-windows-298127.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1835/4114/google_breakpad-1413.501824-linux64-501824.tar.bz2</string> </map> <key>name</key> - <string>windows</string> + <string>linux64</string> </map> - </map> - <key>version</key> - <string>1413.298127</string> + <key>windows</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>6a7929c7280a5c9b528fdd334da5c2d1</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1838/4108/google_breakpad-1413.501824-windows-501824.tar.bz2</string> + </map> + <key>name</key> + <string>windows</string> + </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>4fb761717f3ce6ccabdaeb009272b7ca</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1837/4103/google_breakpad-1413.501824-windows64-501824.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> + </map> + <key>version</key> + <string>1413.501824</string> </map> <key>googlemock</key> <map> @@ -847,87 +1147,69 @@ <key>name</key> <string>darwin</string> </map> - <key>linux</key> + <key>darwin64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>e08b0e9e269b80b549f6044c4e608fb5</string> + <string>1a8081953bdf1bbbc9b8a8e6e062c02d</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/googlemock_3p-update-googlemock/rev/297460/arch/Linux/installer/googlemock-1.7.0.297460-linux-297460.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/919/2048/googlemock-1.7.0.500908-darwin64-500908.tar.bz2</string> </map> <key>name</key> - <string>linux</string> + <string>darwin64</string> </map> - <key>windows</key> + <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>f30de5bf36e8ca8681883fe8fd8e0092</string> + <string>ad51f68702f25ba245fff312c50c8876</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/googlemock_3p-update-googlemock/rev/297460/arch/CYGWIN/installer/googlemock-1.7.0.297460-windows-297460.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-googlemock/rev/317828/arch/Linux/installer/googlemock-1.7.0.317828-linux-317828.tar.bz2</string> </map> <key>name</key> - <string>windows</string> + <string>linux</string> </map> - </map> - <key>version</key> - <string>1.7.0.297460</string> - </map> - <key>gperftools</key> - <map> - <key>copyright</key> - <string>Copyright (c) 2005, Google Inc.</string> - <key>description</key> - <string>Fast, multi-threaded malloc() and nifty performance analysis tools</string> - <key>license</key> - <string>BSD</string> - <key>license_file</key> - <string>LICENSES/gperftools.txt</string> - <key>name</key> - <string>gperftools</string> - <key>platforms</key> - <map> - <key>darwin</key> + <key>linux64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>0137e450bf24cff7e78634bb9a1c85e4</string> + <string>0f606bf01f933f00edeb9bf9a2530930</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/google-perftools_3p-update-google-perftools/rev/297263/arch/Darwin/installer/gperftools-2.0.297263-darwin-297263.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/918/2056/googlemock-1.7.0.500908-linux64-500908.tar.bz2</string> </map> <key>name</key> - <string>darwin</string> + <string>linux64</string> </map> - <key>linux</key> + <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>0c252bcaa1cb852f5c4e46a13ed459c5</string> + <string>d01c9b12be6c5bb0749441495d45cba3</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/google-perftools_3p-update-google-perftools/rev/297263/arch/Linux/installer/gperftools-2.0.297263-linux-297263.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/920/2051/googlemock-1.7.0.500908-windows-500908.tar.bz2</string> </map> <key>name</key> - <string>linux</string> + <string>windows</string> </map> - <key>windows</key> + <key>windows64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>2946f9bbf227dee8881af43856ebb3a1</string> + <string>e508a2ac7900853cc551666d0cf06541</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/google-perftools_3p-update-google-perftools/rev/297263/arch/CYGWIN/installer/gperftools-2.0.297263-windows-297263.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/921/2059/googlemock-1.7.0.500908-windows64-500908.tar.bz2</string> </map> <key>name</key> - <string>windows</string> + <string>windows64</string> </map> </map> <key>version</key> - <string>2.0.297263</string> + <string>1.7.0.500908</string> </map> <key>gstreamer</key> <map> @@ -946,16 +1228,28 @@ <key>archive</key> <map> <key>hash</key> - <string>fb1479533a7699b44d34e3a550037eb7</string> + <string>5017b3e95d2c6f47bb111c3f9c075522</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/gstreamer_3p-update-gstreamer/rev/294903/arch/Linux/installer/gstreamer-0.10.6.294903-linux-294903.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gstreamer/rev/314267/arch/Linux/installer/gstreamer-0.10.6.314267-linux-314267.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>7c9d7cc88add7831a6afeedc20cad2fe</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gstreamer/rev/314267/arch/Linux/installer/gstreamer-0.10.6.314267-linux64-314267.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> </map> <key>version</key> - <string>0.10.6.294903</string> + <string>0.10.6.314267</string> </map> <key>gtk-atk-pango-glib</key> <map> @@ -974,16 +1268,28 @@ <key>archive</key> <map> <key>hash</key> - <string>15af375116f5c943ea6f4190bc764224</string> + <string>a6431df705526501684d9050e04bfa5b</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/gtk_3p-gtk-atk-pango-glib/rev/294804/arch/Linux/installer/gtk_atk_pango_glib-0.1-linux-294804.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gtk-atk-pango-glib/rev/314220/arch/Linux/installer/gtk_atk_pango_glib-0.1-linux-314220.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>de7bba8fd2275a11b077b124413065d0</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gtk-atk-pango-glib/rev/314220/arch/Linux/installer/gtk_atk_pango_glib-0.1-linux64-314220.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> </map> <key>version</key> - <string>0.0</string> + <string>0.1</string> </map> <key>havok-source</key> <map> @@ -1011,33 +1317,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>cbaa7619050123c3fd2a88959f88bd47</string> + <key>url</key> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/749/1553/havok_source-2012.1-2-darwin64-500739.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>6b0f41ddddfa60d8424d8a2e0bc2077d</string> + <string>03c1c5f7c3e93e905f635ca22b607494</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/havok-source_3p-update-havok-source/rev/296959/arch/Linux/installer/havok_source-2012.1-linux-296959.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/p64_3p-havok-source/rev/314226/arch/Linux/installer/havok_source-2012.1-2-linux-314226.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>00d0333936a67059a43a6ec8ac38d564</string> + <key>url</key> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/748/1563/havok_source-2012.1-2-linux64-500739.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>ab30ae74a665950d73ea559f019ff358</string> + <string>dab55cc0555d7126fda925e20af851ea</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/havok-source_3p-update-havok-source/rev/297566/arch/CYGWIN/installer/havok_source-2012.1-windows-297566.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1194/2807/havok_source-2012.1-2-windows-501181.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>7bbc1c3512a5665b7576b4b0357a9eb7</string> + <key>url</key> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1195/2816/havok_source-2012.1-2-windows64-501181.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>2012.1</string> + <string>2012.1-2</string> </map> <key>jpeglib</key> <map> @@ -1065,33 +1407,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>2a33d85c5afa07612e8c4f314ab29545</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/478/1016/jpeglib-8c.500387-darwin64-500387.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>0a6641f030e173a7bc0dc8a3087b6c7d</string> + <string>32560d3200da72fea2922371fcef25f5</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/jpeglib_3p-update-jpeglib/rev/296854/arch/Linux/installer/jpeglib-8c.296854-linux-296854.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-jpeglib/rev/314202/arch/Linux/installer/jpeglib-8c.314202-linux-314202.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>7d699142394f54a334b4fd203b4c9eea</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/457/970/jpeglib-8c.500387-linux64-500387.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>98d3dc8d107d04b572fe47bd43a56e74</string> + <string>543e25c3819399f37e0453db5eea558a</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/jpeglib_3p-update-jpeglib/rev/296854/arch/CYGWIN/installer/jpeglib-8c.296854-windows-296854.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/497/1062/jpeglib-8c.500387-windows-500387.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>dbc2baf28f83d1646d7e2f66ead2a1a4</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/494/1049/jpeglib-8c.500387-windows64-500387.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>8c.296854</string> + <string>8c.500387</string> </map> <key>jsoncpp</key> <map> @@ -1119,33 +1497,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>3564da2ab285a8652d2ee157d1f167e2</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1478/3283/jsoncpp-0.5.0.501464-darwin64-501464.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>5b3b5dbf0c82c1046482a74ce9e11c38</string> + <string>9d5d9fec28cbbb1651b95728173f8af7</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/jsoncpp_3p-update-jsoncpp/rev/297281/arch/Linux/installer/jsoncpp-0.5.0.297281-linux-297281.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-jsoncpp/rev/314229/arch/Linux/installer/jsoncpp-0.5.0.314229-linux-314229.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>9a658ae561c75e60bd9c0cee56731d21</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1475/3274/jsoncpp-0.5.0.501464-linux64-501464.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>e5a832cffe307a1e814ca0664be30b10</string> + <string>ed25115f3e53e59d4d26e0953c273648</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/jsoncpp_3p-update-jsoncpp/rev/297580/arch/CYGWIN/installer/jsoncpp-0.5.0.297580-windows-297580.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1476/3277/jsoncpp-0.5.0.501464-windows-501464.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>b328db840fd28532be39556d130c9439</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1477/3284/jsoncpp-0.5.0.501464-windows64-501464.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>0.5.0.297580</string> + <string>0.5.0.501464</string> </map> <key>kdu</key> <map> @@ -1166,13 +1580,25 @@ <key>archive</key> <map> <key>hash</key> - <string>e62f2fc1ee9ab791d603c5b717b46119</string> + <string>fec7c114b6fa3737217e6ca4ec4735e4</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/kdu_3p-update-kdu/rev/296932/arch/Darwin/installer/kdu-7.2.296932-darwin-296932.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/2449/5335/kdu-7.9.502436-darwin-502436.tar.bz2</string> </map> <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>8178c2d9bde90c21f094d39eaf0125d9</string> + <key>url</key> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/2448/5334/kdu-7.9.502436-darwin64-502436.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> @@ -1185,21 +1611,45 @@ <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>739e6e5e63a0f3b474904f5dd502516a</string> + <key>url</key> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/2447/5325/kdu-7.9.502436-linux64-502436.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>a0e5c050a4975c81611d9f1862ac57fb</string> + <string>82beab4467d5bb5b972061c3674b7593</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/kdu_3p-update-kdu/rev/296932/arch/CYGWIN/installer/kdu-7.2.296932-windows-296932.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/2450/5344/kdu-7.9.502436-windows-502436.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>8458af680eed4be44ea1246e4088e11b</string> + <key>url</key> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/2451/5349/kdu-7.9.502436-windows64-502436.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>7.2.296932</string> + <string>7.9.502436</string> </map> <key>libhunspell</key> <map> @@ -1227,33 +1677,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>4b238300cf9c405cdcab18030372832f</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/534/1149/libhunspell-1.3.2.500526-darwin64-500526.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>988deae5c63ec638ad222b400a431f5b</string> + <string>0d8009c3b6c1eb510593476dd1d821b5</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/hunspell_3p-update-hunspell/rev/296916/arch/Linux/installer/libhunspell-1.3.2.296916-linux-296916.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-hunspell/rev/314217/arch/Linux/installer/libhunspell-1.3.2.314217-linux-314217.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>ffbdd109356d66ddfefd8a5d57f63f1f</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/533/1144/libhunspell-1.3.2.500526-linux64-500526.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>ada0ad726842d902c09ab20a7ad5ac8f</string> + <string>a2025f748a6311ab390f89068b22c702</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/hunspell_3p-update-hunspell/rev/296916/arch/CYGWIN/installer/libhunspell-1.3.2.296916-windows-296916.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/535/1152/libhunspell-1.3.2.500526-windows-500526.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>233d86906ef88fa331263162a53e29f2</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/536/1155/libhunspell-1.3.2.500526-windows64-500526.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>1.3.2.296916</string> + <string>1.3.2.500526</string> </map> <key>libndofdev</key> <map> @@ -1281,21 +1767,45 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>840bb6219f63a789749f5f6583c44eee</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/704/1420/libndofdev-0.1.500695-darwin64-500695.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>1c40c22fb7b84ccccefbf797e2478ec4</string> + <string>fdbebbbde3b289d93c0c8c294cf859cb</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libndofdev_3p-update-libndofdev/rev/297264/arch/CYGWIN/installer/libndofdev-0.1.297264-windows-297264.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/708/1426/libndofdev-0.1.500695-windows-500695.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>15cef2cec6c8d1980011e26249bd4e90</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/707/1423/libndofdev-0.1.500695-windows64-500695.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>0.1.297264</string> + <string>0.1.500695</string> </map> <key>libpng</key> <map> @@ -1323,33 +1833,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>537b59a75709bd9abe0abe0c7309add4</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/883/1951/libpng-1.6.8.500873-darwin64-500873.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>6dec32fc2527f8cafd616f9271ff3478</string> + <string>0758f3cb4c02ebab61854b811b0894e9</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libpng_3p-update-libpng/rev/297051/arch/Linux/installer/libpng-1.6.8.297051-linux-297051.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libpng/rev/314214/arch/Linux/installer/libpng-1.6.8.314214-linux-314214.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>13de93ea11544051b69f238eeb644fd3</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/882/1946/libpng-1.6.8.500873-linux64-500873.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>09eb65e66e0230ab01e57e643647a4f1</string> + <string>9c2950f9d16566979dcd6ca6336778b3</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libpng_3p-update-libpng/rev/297708/arch/CYGWIN/installer/libpng-1.6.8.297708-windows-297708.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/885/1957/libpng-1.6.8.500873-windows-500873.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>18fe233471e91d5d3ac6d08a296b79ba</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/884/1954/libpng-1.6.8.500873-windows64-500873.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>1.6.8.297708</string> + <string>1.6.8.500873</string> </map> <key>libuuid</key> <map> @@ -1370,13 +1916,25 @@ <key>archive</key> <map> <key>hash</key> - <string>f231b6ec8bc2f050cfb1ee20bd83190d</string> + <string>a2eaf9515cd129f3e21a08e92689006b</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libuuid_3p-update-libuuid/rev/295209/arch/Linux/installer/libuuid-1.6.2-linux-295209.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libuuid/rev/314269/arch/Linux/installer/libuuid-1.6.2-linux-314269.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>fb89f1281dd54d8b99b339fc5b712b27</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libuuid/rev/314269/arch/Linux/installer/libuuid-1.6.2-linux64-314269.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> </map> <key>version</key> <string>1.6.2</string> @@ -1407,33 +1965,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>89a71a652a5ecd7cf6142ff56f40f018</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/891/1973/libxml2-2.9.4.500877-darwin64-500877.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>b8b584853dc1344bb3571c13b06ec39e</string> + <string>6954173a141d928f2614076577d952de</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libxml_3p-update-libxml/rev/297050/arch/Linux/installer/libxml2-2.9.1.297050-linux-297050.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libxml/rev/314197/arch/Linux/installer/libxml2-2.9.1.314197-linux-314197.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>740fc93f195c77b3a0c0800b31878ecb</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/890/1968/libxml2-2.9.4.500877-linux64-500877.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>37fa0e86e54f5f283aa653d770fc8ed5</string> + <string>c2461ba7629c4cef5af623464aded3c6</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libxml_3p-update-libxml/rev/297050/arch/CYGWIN/installer/libxml2-2.9.1.297050-windows-297050.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/888/1960/libxml2-2.9.4.500877-windows-500877.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>8ec25000f5d72e26c2e7555c73898fbb</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/889/1963/libxml2-2.9.4.500877-windows64-500877.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>2.9.1.297050</string> + <string>2.9.4.500877</string> </map> <key>llappearance_utility</key> <map> @@ -1454,9 +2048,9 @@ <key>archive</key> <map> <key>hash</key> - <string>faa1e5b7cf70c143caabe190fa5588ce</string> + <string>fddd634dec5ec03924d62cc774f7f8ea</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearance_viewer-update-llappearance-utility/rev/304432/arch/Linux/installer/llappearance_utility-0.0.1-linux-304432.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/p64_viewer-llappearance-utility/rev/317266/arch/Linux/installer/llappearance_utility-0.0.1-linux-317266.tar.bz2</string> </map> <key>name</key> <string>linux</string> @@ -1536,32 +2130,56 @@ <key>archive</key> <map> <key>hash</key> - <string>29a1f64df46094eda0d681821a98d17e</string> + <string>2845033912eb947a1401847ece1469ce</string> <key>hash_algorithm</key> <string>md5</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/311349/arch/Darwin/installer/llceflib-1.5.3.311349-darwin-311349.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/321153/arch/Darwin/installer/llceflib-1.5.3.321153-darwin-321153.tar.bz2</string> </map> <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>3af1210d90aeb9f4d5deea6020ee0d55</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1611/3591/llceflib-1.6.0.501600-darwin64-501600.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>827b7c339a2cd401d9d23f9ee02cb83f</string> + <string>9d19271829a372e028dd3c75605ded9c</string> <key>hash_algorithm</key> <string>md5</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/311349/arch/CYGWIN/installer/llceflib-1.5.3.311349-windows-311349.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1518/3437/llceflib-1.6.0.501501-windows-501501.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>da1835b11be4442f22fef36820ad46ac</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1517/3434/llceflib-1.6.0.501501-windows64-501501.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>1.5.3.311349</string> + <string>1.6.0.501600</string> </map> <key>llphysicsextensions_source</key> <map> @@ -1575,47 +2193,45 @@ <string>llphysicsextensions_source</string> <key>platforms</key> <map> - <key>darwin</key> + <key>darwin64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>01a7cc9d0e56238a9abedd7a41ccd0a3</string> - <key>hash_algorithm</key> - <string>md5</string> + <string>e2b519ee7538b25877e34ede6864a250</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions/rev/313564/arch/Darwin/installer/llphysicsextensions_source-1.0.313564-darwin-313564.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1691/3748/llphysicsextensions_source-1.0.501678-darwin64-501678.tar.bz2</string> </map> <key>name</key> - <string>darwin</string> + <string>darwin64</string> </map> - <key>linux</key> + <key>linux64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>c94dc7ab6efe59c0d5d04fc447257c57</string> + <string>9b2c1f53f7f1add01af1e7cfa737e20e</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions/rev/313564/arch/Linux/installer/llphysicsextensions_source-1.0.313564-linux-313564.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1689/3734/llphysicsextensions_source-1.0.501678-linux64-501678.tar.bz2</string> </map> <key>name</key> - <string>linux</string> + <string>linux64</string> </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>e760be34addeb0cd6e2ec43394834bac</string> + <string>5e8cb92ae79c9435b98e444322ec5798</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions/rev/313564/arch/CYGWIN/installer/llphysicsextensions_source-1.0.313564-windows-313564.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1696/3763/llphysicsextensions_source-1.0.501678-windows-501678.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> </map> <key>version</key> - <string>1.0.313564</string> + <string>1.0.501678</string> </map> <key>llphysicsextensions_stub</key> <map> @@ -1629,47 +2245,45 @@ <string>llphysicsextensions_stub</string> <key>platforms</key> <map> - <key>darwin</key> + <key>darwin64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>c8c6e5867d1ead7ad452a3359b22cf44</string> - <key>hash_algorithm</key> - <string>md5</string> + <string>32309a20161f54f42d08f7bc1e7fcf01</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions/rev/313563/arch/Darwin/installer/llphysicsextensions_stub-1.0.313563-darwin-313563.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1692/3749/llphysicsextensions_stub-1.0.501679-darwin64-501679.tar.bz2</string> </map> <key>name</key> - <string>darwin</string> + <string>darwin64</string> </map> - <key>linux</key> + <key>linux64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>e99afb25a4fd5b08c5cd3060ae9c1d59</string> + <string>58af530891721f3690a4dce9a8c73190</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions/rev/313563/arch/Linux/installer/llphysicsextensions_stub-1.0.313563-linux-313563.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1690/3739/llphysicsextensions_stub-1.0.501679-linux64-501679.tar.bz2</string> </map> <key>name</key> - <string>linux</string> + <string>linux64</string> </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>6f4307a35c692e44b872125d7932df8e</string> + <string>c59cb5d1dd96ab51f87cd0cf202304dd</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions/rev/313563/arch/CYGWIN/installer/llphysicsextensions_stub-1.0.313563-windows-313563.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1695/3757/llphysicsextensions_stub-1.0.501679-windows-501679.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> </map> <key>version</key> - <string>1.0.313563</string> + <string>1.0.501679</string> </map> <key>mesa</key> <map> @@ -1716,16 +2330,28 @@ <key>archive</key> <map> <key>hash</key> - <string>9e30c9e228d6a825b6774b97ff052973</string> + <string>22c7be12c1d2ee87b059be903d7f2fbd</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/nvapi_3p-update-nvapi/rev/295118/arch/CYGWIN/installer/nvapi-304-windows-295118.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-nvapi/rev/314405/arch/CYGWIN/installer/nvapi-352.314405-windows-314405.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>90e32843a0e21037001dc88240008e1f</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-nvapi/rev/314405/arch/CYGWIN/installer/nvapi-352.314405-windows64-314405.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>304</string> + <string>352.314405</string> </map> <key>ogg_vorbis</key> <map> @@ -1746,40 +2372,76 @@ <key>archive</key> <map> <key>hash</key> - <string>07fca1531a27915f642a5c1d95008d54</string> + <string>07fca1531a27915f642a5c1d95008d54</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/oggvorbis_3p-update-oggvorbis/rev/296878/arch/Darwin/installer/ogg_vorbis-1.2.2-1.3.2.296878-darwin-296878.tar.bz2</string> + </map> + <key>name</key> + <string>darwin</string> + </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>bb8bed08fd5973a040c509ef8b545ec8</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/490/1046/ogg_vorbis-1.2.2-1.3.2.500397-darwin64-500397.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> + <key>linux</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>5c9d94dce4551b19790057766ff939ea</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-oggvorbis/rev/314224/arch/Linux/installer/ogg_vorbis-1.2.2-1.3.2.314224-linux-314224.tar.bz2</string> + </map> + <key>name</key> + <string>linux</string> + </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>45ebd074053dc9cae8c5c74b52085d4b</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/oggvorbis_3p-update-oggvorbis/rev/296878/arch/Darwin/installer/ogg_vorbis-1.2.2-1.3.2.296878-darwin-296878.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/465/990/ogg_vorbis-1.2.2-1.3.2.500397-linux64-500397.tar.bz2</string> </map> <key>name</key> - <string>darwin</string> + <string>linux64</string> </map> - <key>linux</key> + <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>b0cd31d5b07a9fc25c4d69ba2f95eace</string> + <string>f7edf86dcf2d9be7bee98c91256fa569</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/oggvorbis_3p-update-oggvorbis/rev/296878/arch/Linux/installer/ogg_vorbis-1.2.2-1.3.2.296878-linux-296878.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/512/1108/ogg_vorbis-1.2.2-1.3.2.500397-windows-500397.tar.bz2</string> </map> <key>name</key> - <string>linux</string> + <string>windows</string> </map> - <key>windows</key> + <key>windows64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>f358717739c288ec7401d6d1936ef878</string> + <string>497ec6ac26c2e136ee65acbed86cb2ef</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/oggvorbis_3p-update-oggvorbis/rev/296878/arch/CYGWIN/installer/ogg_vorbis-1.2.2-1.3.2.296878-windows-296878.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/511/1105/ogg_vorbis-1.2.2-1.3.2.500397-windows64-500397.tar.bz2</string> </map> <key>name</key> - <string>windows</string> + <string>windows64</string> </map> </map> <key>version</key> - <string>1.2.2-1.3.2.296878</string> + <string>1.2.2-1.3.2.500397</string> </map> <key>open-libndofdev</key> <map> @@ -1830,37 +2492,61 @@ <key>archive</key> <map> <key>hash</key> - <string>15ebe611213c9577691ffbade081549d</string> + <string>24b91eda3831a51c7774644016c4cb09</string> <key>hash_algorithm</key> <string>md5</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openal_3p-update-openal/rev/297677/arch/Linux/installer/openal-1.12.854-1.1.0.297677-linux-297677.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openal/rev/314223/arch/Linux/installer/openal-1.12.854-1.1.0.314223-linux-314223.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>7530fab3979312da75a903d87b73e3a9</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openal/rev/314223/arch/Linux/installer/openal-1.12.854-1.1.0.314223-linux64-314223.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>3bf6e26aeec71f36c8b6e20c6b883fe9</string> + <string>d9c86f79a6bb56a670e2801c33fd2dd1</string> <key>hash_algorithm</key> <string>md5</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openal_3p-update-openal/rev/297677/arch/CYGWIN/installer/openal-1.12.854-1.1.0.297677-windows-297677.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openal/rev/314223/arch/CYGWIN/installer/openal-1.12.854-1.1.0.314223-windows-314223.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>e0fdd9394a8cd8c6360b922f6f237e57</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openal/rev/314223/arch/CYGWIN/installer/openal-1.12.854-1.1.0.314223-windows64-314223.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>1.12.854-1.1.0.297677</string> + <string>1.12.854-1.1.0.314223</string> </map> <key>openjpeg</key> <map> <key>copyright</key> - <string>Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium, Copyright (c) 2002-2007, Professor Benoit Macq, Copyright (c) 2001-2003, David Janssens, Copyright (c) 2002-2003, Yannick Verschueren, Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe, Copyright (c) 2005, Herve Drolon, FreeImage Team</string> + <string>Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium; Copyright (c) 2002-2007, Professor Benoit Macq; Copyright (c) 2001-2003, David Janssens; Copyright (c) 2002-2003, Yannick Verschueren; Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe; Copyright (c) 2005, Herve Drolon, FreeImage Team; Copyright (c) 2006-2007, Parvatha Elangovan; Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>; Copyright (c) 2010-2011, Kaori Hagihara; Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France; Copyright (c) 2012, CS Systemes d'Information, France;</string> <key>description</key> <string>The OpenJPEG library is an open-source JPEG 2000 codec written in C language.</string> <key>license</key> @@ -1883,33 +2569,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>f7013e1f0b6a877090622fd73ec72cbc</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1114/2576/openjpeg-1.5.1.501102-darwin64-501102.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>675c283030879d3d9c49082bfa2192eb</string> + <string>e82317482647559d46a818ba48e9423a</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openjpeg_3p-update-openjpeg/rev/297018/arch/Linux/installer/openjpeg-1.4.297018-linux-297018.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openjpeg/rev/314205/arch/Linux/installer/openjpeg-2.0.0.314205-linux-314205.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>ac66f3197010b1549a5e4467aebbc27d</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1113/2571/openjpeg-1.5.1.501102-linux64-501102.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>b35adcf74d22c128045aa87aade74736</string> + <string>8a7f0be5647e07235d205ac00805fb78</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openjpeg_3p-update-openjpeg/rev/297018/arch/CYGWIN/installer/openjpeg-1.4.297018-windows-297018.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1116/2586/openjpeg-1.5.1.501102-windows-501102.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>398544058036bc27097fcff208934d11</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1115/2581/openjpeg-1.5.1.501102-windows64-501102.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>1.4.297018</string> + <string>1.5.1.501102</string> </map> <key>openssl</key> <map> @@ -1937,33 +2659,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>7011482b07b32b375ecc3e891c37f469</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1063/2462/openssl-1.0.1u.501051-darwin64-501051.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>c310ba9971cbd796b303c3be67fb11c6</string> + <string>f46a601d60b7dbcfde32afc0cb64453e</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openssl_3p-update-openssl/rev/297168/arch/Linux/installer/openssl-1.0.1h.297168-linux-297168.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openssl/rev/314227/arch/Linux/installer/openssl-1.0.1h.314227-linux-314227.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>50bb9aca605a599cb1a46da3c45f78ac</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1062/2473/openssl-1.0.1u.501051-linux64-501051.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>398743f47578cbb44f5504128780369f</string> + <string>7d9801f9ce049ffd30fbe06b6bac4c91</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openssl_3p-update-openssl/rev/297168/arch/CYGWIN/installer/openssl-1.0.1h.297168-windows-297168.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1064/2465/openssl-1.0.1u.501051-windows-501051.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>c3e404a9cc51d64c71ec13dbd44b8409</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1065/2468/openssl-1.0.1u.501051-windows64-501051.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>1.0.1h.297168</string> + <string>1.0.1u.501051</string> </map> <key>pcre</key> <map> @@ -1991,63 +2749,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>addfbc0635b0ea65d7a151dd7ec5ef85</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/909/2015/pcre-8.35.500898-darwin64-500898.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>b82817bcc2f63094d9c915d018d0b036</string> + <string>24a119b18e63017ad932ad54df8161bc</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/pcre_3p-update-pcre/rev/297155/arch/Linux/installer/pcre-8.35.-linux-297155.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-pcre/rev/314136/arch/Linux/installer/pcre-8.35.314136-linux-314136.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>0f058ca2176e7d02d51e54c66a96f336</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/908/2010/pcre-8.35.500898-linux64-500898.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>96ed836c89a99dfc22f9c16a0d7272d3</string> + <string>150220f39f0aa5a8d9e609b450a9b147</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/pcre_3p-update-pcre/rev/297155/arch/CYGWIN/installer/pcre-8.35.-windows-297155.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/911/2021/pcre-8.35.500898-windows-500898.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> - </map> - <key>version</key> - <string>8.35.</string> - </map> - <key>quicktime</key> - <map> - <key>copyright</key> - <string>2010 Apple</string> - <key>description</key> - <string>QuickTime 7.3 SDK for Windows</string> - <key>license</key> - <string>unknown</string> - <key>license_file</key> - <string>LICENSES/quicktime.txt</string> - <key>name</key> - <string>quicktime</string> - <key>platforms</key> - <map> - <key>windows</key> + <key>windows64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>78650a79bda6435e623a940ad425a593</string> + <string>eaebfb4a96a6306ee8e0b18434d125f9</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/quicktime_3p-update-quicktime/rev/300073/arch/CYGWIN/installer/quicktime-7.3-windows-300073.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/910/2018/pcre-8.35.500898-windows64-500898.tar.bz2</string> </map> <key>name</key> - <string>windows</string> + <string>windows64</string> </map> </map> <key>version</key> - <string>7.3</string> + <string>8.35.500898</string> </map> <key>slvoice</key> <map> @@ -2068,40 +2832,76 @@ <key>archive</key> <map> <key>hash</key> - <string>3dd9bf4185bf2df413d890ca9eeab76c</string> + <string>8c2f921001a8ee29b826a45181465735</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/vivox_3p-slvoice/rev/302004/arch/Darwin/installer/slvoice-4.6.0017.22050.302004-darwin-302004.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-slvoice/rev/314209/arch/Darwin/installer/slvoice-4.6.0017.21209.314209-darwin-314209.tar.bz2</string> </map> <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>c9b0d816cf14bebba138ea6f9f463553</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/614/1294/slvoice-4.6.0017.21209.500605-darwin64-500605.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>06c3a9b1005249f0c94a8b9f3775f3d3</string> + <string>e5832a68562c3409a56a3583d101864b</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/vivox_3p-slvoice/rev/302004/arch/Linux/installer/slvoice-3.2.0002.10426.302004-linux-302004.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-slvoice/rev/314209/arch/Linux/installer/slvoice-3.2.0002.10426.314209-linux-314209.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>92b0ae08832bd0e99c34ef8f3e6346ad</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/613/1289/slvoice-3.2.0002.10426.500605-linux64-500605.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>47a3316dae47cc4e7c1ea7b74ba8dd1e</string> + <string>3ce62e3696f26a1e09e0c769280e5608</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/vivox_3p-slvoice/rev/302004/arch/CYGWIN/installer/slvoice-4.6.0017.22050.302004-windows-302004.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/616/1300/slvoice-4.6.0017.21209.500605-windows-500605.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>61c41dd565e2caa38bd0056970094749</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/615/1297/slvoice-4.6.0017.21209.500605-windows64-500605.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>3.2.0002.10426.302004</string> + <string>4.6.0017.21209.500605</string> </map> <key>tut</key> <map> @@ -2122,9 +2922,9 @@ <key>archive</key> <map> <key>hash</key> - <string>2f32faa00e600911f838a7d82da5a8db</string> + <string>722563bd6e2ae0c7e53c027d267154f7</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/tut_3p-update-tut/rev/297257/arch/Linux/installer/tut-2008.11.30-common-297257.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/496/1054/tut-2008.11.30-common-500403.tar.bz2</string> </map> <key>name</key> <string>common</string> @@ -2159,6 +2959,18 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>5b9cd1d6fac519aad59f6d53a54229c5</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/347/872/uriparser-0.8.0.1-darwin64-500342.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> @@ -2171,22 +2983,110 @@ <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>087375378f104cdac0cb0fe0ca43dd4d</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/346/880/uriparser-0.8.0.1-linux64-500342.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>e4520158dda88453e46942eab6f9c0a8</string> + <string>1becd11c19dd1763f0322ba4d1a5ee06</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/uriparser_3p-update-uriparser/rev/299435/arch/CYGWIN/installer/uriparser-0.8.0.1-windows-299435.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/521/1129/uriparser-0.8.0.1-windows-500342.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>587db55a2a3ce57628374b5e27b3272e</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/349/875/uriparser-0.8.0.1-windows64-500342.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> <string>0.8.0.1</string> </map> + <key>vlc-bin</key> + <map> + <key>copyright</key> + <string>Copyright (C) 1998-2016 VLC authors and VideoLAN</string> + <key>license</key> + <string>GPL2</string> + <key>license_file</key> + <string>LICENSES/vlc.txt</string> + <key>name</key> + <string>vlc-bin</string> + <key>platforms</key> + <map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>c5e6d9440e3a4a12102dd2bbb703963e</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/2225/4736/vlc_bin-2.2.4.502214-darwin64-502214.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> + <key>linux</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>2f410640df3f9812d1abff02a414cfa8</string> + <key>url</key> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-vlc-bin/rev/315283/arch/Linux/vlc_bin-2.2.3-linux-201606011750-r10.tar.bz2</string> + </map> + <key>name</key> + <string>linux</string> + </map> + <key>windows</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>dc37f7cc77a62891bb9ae46c9e19f95e</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1219/2834/vlc_bin-2.2.4.501207-windows-501207.tar.bz2</string> + </map> + <key>name</key> + <string>windows</string> + </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>148ee599afeba9794de14ca433389504</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1218/2829/vlc_bin-2.2.4.501207-windows64-501207.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> + </map> + <key>version</key> + <string>2.2.4.502214</string> + </map> <key>xmlrpc-epi</key> <map> <key>copyright</key> @@ -2213,33 +3113,69 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>b2d31df56a10c634657eed856c8d7895</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/728/1494/xmlrpc_epi-0.54.1.500719-darwin64-500719.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>30bb26d6cc78c16047fc85a63f48fcdb</string> + <string>b63f828e798287d475991134cdcfbca3</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/xmlrpc-emi_3p-update-xmlrpc-epi/rev/297075/arch/Linux/installer/xmlrpc_epi-0.54.1.297075-linux-297075.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-xmlrpc-epi/rev/314240/arch/Linux/installer/xmlrpc_epi-0.54.1.314240-linux-314240.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>35df17c3eb673030dea4bde9191aa506</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/727/1489/xmlrpc_epi-0.54.1.500719-linux64-500719.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>a7e1a8369a5afd52e1b6fc1f14155033</string> + <string>6c16f020bf01155e6746487af0b26173</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/xmlrpc-emi_3p-update-xmlrpc-epi/rev/297075/arch/CYGWIN/installer/xmlrpc_epi-0.54.1.297075-windows-297075.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/729/1497/xmlrpc_epi-0.54.1.500719-windows-500719.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>a9dda7caa8835c52b3735711cfee4eb9</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/730/1500/xmlrpc_epi-0.54.1.500719-windows64-500719.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>0.54.1.297075</string> + <string>0.54.1.500719</string> </map> <key>zlib</key> <map> @@ -2267,35 +3203,71 @@ <key>name</key> <string>darwin</string> </map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>e204dee29902549f50af1af2bb098df5</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/867/1903/zlib-1.2.8.500857-darwin64-500857.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> <key>linux</key> <map> <key>archive</key> <map> <key>hash</key> - <string>2eb8e59b6464222dcf4435016ad5f618</string> + <string>98a8c775c581ca80bb559e8b4e8eaae7</string> <key>hash_algorithm</key> <string>md5</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/zlib_3p-update-zlib/rev/296881/arch/Linux/installer/zlib-1.2.8.296881-linux-296881.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-zlib/rev/314131/arch/Linux/installer/zlib-1.2.8.314131-linux-314131.tar.bz2</string> </map> <key>name</key> <string>linux</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>dab6be8b0596c1e3354f2b6d41335131</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/866/1898/zlib-1.2.8.500857-linux64-500857.tar.bz2</string> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>windows</key> <map> <key>archive</key> <map> <key>hash</key> - <string>ae420ec6d30411c07aac2502d7bbc0f3</string> + <string>f92cbb0ab5e5d20789bf6102f9a27aa6</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/zlib_3p-update-zlib/rev/296881/arch/CYGWIN/installer/zlib-1.2.8.296881-windows-296881.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/868/1906/zlib-1.2.8.500857-windows-500857.tar.bz2</string> </map> <key>name</key> <string>windows</string> </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>70a56767f6a109af412838875d0b5f1b</string> + <key>url</key> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/869/1909/zlib-1.2.8.500857-windows64-500857.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> </map> <key>version</key> - <string>1.2.8.296881</string> + <string>1.2.8.500857</string> </map> </map> <key>package_description</key> @@ -2328,7 +3300,7 @@ <key>options</key> <array> <string>-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo</string> - <string>-DWORD_SIZE:STRING=32</string> + <string>-DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string> <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string> <string>-DINSTALL_PROPRIETARY=TRUE</string> </array> @@ -2349,7 +3321,7 @@ <key>options</key> <array> <string>-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo</string> - <string>-DWORD_SIZE:STRING=32</string> + <string>-DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string> <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string> <string>-DINSTALL_PROPRIETARY=FALSE</string> </array> @@ -2369,7 +3341,7 @@ <key>options</key> <array> <string>-DCMAKE_BUILD_TYPE:STRING=Release</string> - <string>-DWORD_SIZE:STRING=32</string> + <string>-DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string> <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string> <string>-DINSTALL_PROPRIETARY=TRUE</string> </array> @@ -2390,7 +3362,7 @@ <key>options</key> <array> <string>-DCMAKE_BUILD_TYPE:STRING=Release</string> - <string>-DWORD_SIZE:STRING=32</string> + <string>-DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string> <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string> <string>-DINSTALL_PROPRIETARY=FALSE</string> </array> @@ -2402,10 +3374,10 @@ <key>name</key> <string>common</string> </map> - <key>darwin</key> + <key>darwin64</key> <map> <key>build_directory</key> - <string>build-darwin-i386</string> + <string>build-darwin-x86_64</string> <key>configurations</key> <map> <key>RelWithDebInfo</key> @@ -2420,8 +3392,11 @@ </array> <key>options</key> <array> - <string>-configuration RelWithDebInfo</string> - <string>-project SecondLife.xcodeproj</string> + <string>-quiet</string> + <string>-configuration</string> + <string>RelWithDebInfo</string> + <string>-project</string> + <string>SecondLife.xcodeproj</string> </array> </map> <key>configure</key> @@ -2433,7 +3408,8 @@ <key>options</key> <array> <string>-G</string> - <string>'Xcode'</string> + <string>Xcode</string> + <string>-DHAVOK:BOOL=OFF</string> </array> </map> <key>default</key> @@ -2449,8 +3425,11 @@ <string>xcodebuild</string> <key>options</key> <array> - <string>-configuration RelWithDebInfo</string> - <string>-project SecondLife.xcodeproj</string> + <string>-quiet</string> + <string>-configuration</string> + <string>RelWithDebInfo</string> + <string>-project</string> + <string>SecondLife.xcodeproj</string> </array> </map> <key>configure</key> @@ -2458,7 +3437,8 @@ <key>options</key> <array> <string>-G</string> - <string>'Xcode'</string> + <string>Xcode</string> + <string>-DHAVOK:BOOL=OFF</string> </array> </map> <key>name</key> @@ -2476,10 +3456,11 @@ </array> <key>options</key> <array> - <string>-configuration Release</string> - <string>-project SecondLife.xcodeproj</string> - <string>-DENABLE_SIGNING:BOOL=YES</string> - <string>-DSIGNING_IDENTITY:STRING="Developer ID Application: Linden Research, Inc."</string> + <string>-quiet</string> + <string>-configuration</string> + <string>Release</string> + <string>-project</string> + <string>SecondLife.xcodeproj</string> </array> </map> <key>configure</key> @@ -2491,7 +3472,8 @@ <key>options</key> <array> <string>-G</string> - <string>'Xcode'</string> + <string>Xcode</string> + <string>-DHAVOK:BOOL=OFF</string> </array> </map> <key>name</key> @@ -2505,10 +3487,11 @@ <string>xcodebuild</string> <key>options</key> <array> - <string>-configuration Release</string> - <string>-project SecondLife.xcodeproj</string> - <string>-DENABLE_SIGNING:BOOL=YES</string> - <string>-DSIGNING_IDENTITY:STRING="Developer ID Application: Linden Research, Inc."</string> + <string>-quiet</string> + <string>-configuration</string> + <string>Release</string> + <string>-project</string> + <string>SecondLife.xcodeproj</string> </array> </map> <key>configure</key> @@ -2516,7 +3499,8 @@ <key>options</key> <array> <string>-G</string> - <string>'Xcode'</string> + <string>Xcode</string> + <string>-DHAVOK:BOOL=OFF</string> </array> </map> <key>name</key> @@ -2524,7 +3508,7 @@ </map> </map> <key>name</key> - <string>darwin</string> + <string>darwin64</string> </map> <key>linux</key> <map> @@ -2540,7 +3524,8 @@ <string>make</string> <key>options</key> <array> - <string>-j 12</string> + <string>-j</string> + <string>12</string> </array> </map> <key>configure</key> @@ -2552,7 +3537,7 @@ <key>options</key> <array> <string>-G</string> - <string>'Unix Makefiles'</string> + <string>Unix Makefiles</string> </array> </map> <key>default</key> @@ -2568,7 +3553,8 @@ <string>make</string> <key>options</key> <array> - <string>-j 7</string> + <string>-j</string> + <string>7</string> </array> </map> <key>configure</key> @@ -2576,7 +3562,7 @@ <key>options</key> <array> <string>-G</string> - <string>'Unix Makefiles'</string> + <string>Unix Makefiles</string> </array> </map> <key>name</key> @@ -2590,7 +3576,8 @@ <string>make</string> <key>options</key> <array> - <string>-j 12</string> + <string>-j</string> + <string>12</string> </array> </map> <key>configure</key> @@ -2602,7 +3589,7 @@ <key>options</key> <array> <string>-G</string> - <string>'Unix Makefiles'</string> + <string>Unix Makefiles</string> </array> </map> <key>name</key> @@ -2616,7 +3603,8 @@ <string>make</string> <key>options</key> <array> - <string>-j 7</string> + <string>-j</string> + <string>7</string> </array> </map> <key>configure</key> @@ -2624,7 +3612,7 @@ <key>options</key> <array> <string>-G</string> - <string>'Unix Makefiles'</string> + <string>Unix Makefiles</string> </array> </map> <key>name</key> @@ -2645,7 +3633,7 @@ <key>windows</key> <map> <key>build_directory</key> - <string>build-vc120</string> + <string>build-vc120-$AUTOBUILD_ADDRSIZE</string> <key>configurations</key> <map> <key>RelWithDebInfo</key> @@ -2661,7 +3649,7 @@ <key>options</key> <array> <string>/build</string> - <string>"RelWithDebInfo|Win32"</string> + <string>RelWithDebInfo|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string> </array> </map> <key>configure</key> @@ -2669,19 +3657,11 @@ <key>arguments</key> <array> <string>..\indra</string> - <string>&&</string> - <string>..\indra\tools\vstool\VSTool.exe</string> - <string>--solution</string> - <string>SecondLife.sln</string> - <string>--config</string> - <string>RelWithDebInfo</string> - <string>--startup</string> - <string>secondlife-bin</string> </array> <key>options</key> <array> <string>-G</string> - <string>"Visual Studio 12"</string> + <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string> </array> </map> <key>default</key> @@ -2702,12 +3682,12 @@ <key>options</key> <array> <string>/p:Configuration=RelWithDebInfo</string> - <string>/p:Platform=Win32</string> + <string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string> <string>/t:Build</string> <string>/p:useenv=true</string> <string>/verbosity:minimal</string> <string>/toolsversion:4.0</string> - <string>/p:"VCBuildAdditionalOptions= /incremental"</string> + <string>/p:VCBuildAdditionalOptions= /incremental</string> </array> </map> <key>configure</key> @@ -2715,19 +3695,11 @@ <key>arguments</key> <array> <string>..\indra</string> - <string>&&</string> - <string>..\indra\tools\vstool\VSTool.exe</string> - <string>--solution</string> - <string>SecondLife.sln</string> - <string>--config</string> - <string>RelWithDebInfo</string> - <string>--startup</string> - <string>secondlife-bin</string> </array> <key>options</key> <array> <string>-G</string> - <string>"Visual Studio 12"</string> + <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string> <string>-DUNATTENDED:BOOL=ON</string> <string>-DINSTALL_PROPRIETARY=FALSE</string> <string>-DUSE_KDU=FALSE</string> @@ -2749,7 +3721,7 @@ <key>options</key> <array> <string>/build</string> - <string>"Release|Win32"</string> + <string>Release|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string> </array> </map> <key>configure</key> @@ -2757,19 +3729,11 @@ <key>arguments</key> <array> <string>..\indra</string> - <string>&&</string> - <string>..\indra\tools\vstool\VSTool.exe</string> - <string>--solution</string> - <string>SecondLife.sln</string> - <string>--config</string> - <string>Release</string> - <string>--startup</string> - <string>secondlife-bin</string> </array> <key>options</key> <array> <string>-G</string> - <string>"Visual Studio 12"</string> + <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string> </array> </map> <key>name</key> @@ -2788,12 +3752,12 @@ <key>options</key> <array> <string>/p:Configuration=Release</string> - <string>/p:Platform=Win32</string> + <string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string> <string>/t:Build</string> <string>/p:useenv=true</string> <string>/verbosity:minimal</string> <string>/toolsversion:4.0</string> - <string>/p:"VCBuildAdditionalOptions= /incremental"</string> + <string>/p:VCBuildAdditionalOptions= /incremental</string> </array> </map> <key>configure</key> @@ -2801,19 +3765,11 @@ <key>arguments</key> <array> <string>..\indra</string> - <string>&&</string> - <string>..\indra\tools\vstool\VSTool.exe</string> - <string>--solution</string> - <string>SecondLife.sln</string> - <string>--config</string> - <string>Release</string> - <string>--startup</string> - <string>secondlife-bin</string> </array> <key>options</key> <array> <string>-G</string> - <string>"Visual Studio 12"</string> + <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string> <string>-DUNATTENDED:BOOL=ON</string> <string>-DINSTALL_PROPRIETARY=FALSE</string> <string>-DUSE_KDU=FALSE</string> diff --git a/build.sh b/build.sh index cd2a9ebf5e702b89edded3c8ab7cd412255d8f65..9ca130b5d53d1a76c7317f3f0a13fd323d687070 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # This is the custom build script for the viewer # @@ -18,7 +18,7 @@ build_dir_Darwin() { - echo build-darwin-i386 + echo build-darwin-x86_64 } build_dir_Linux() @@ -28,7 +28,7 @@ build_dir_Linux() build_dir_CYGWIN() { - echo build-vc120 + echo build-vc120-${AUTOBUILD_ADDRSIZE} } viewer_channel_suffix() @@ -47,8 +47,8 @@ viewer_channel_suffix() installer_Darwin() { local package_name="$1" - local package_dir="$(build_dir_Darwin ${last_built_variant:-Release})/newview/" - local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_i386\\.dmg\$" + local package_dir="$(build_dir_Darwin)/newview/" + local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_x86_64\\.dmg\$" # since the additional packages are built after the base package, # sorting oldest first ensures that the unqualified package is returned # even if someone makes a qualified name that duplicates the last word of the base name @@ -59,7 +59,7 @@ installer_Darwin() installer_Linux() { local package_name="$1" - local package_dir="$(build_dir_Linux ${last_built_variant:-Release})/newview/" + local package_dir="$(build_dir_Linux)/newview/" local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_i686\\.tar\\.bz2\$" # since the additional packages are built after the base package, # sorting oldest first ensures that the unqualified package is returned @@ -95,13 +95,28 @@ pre_build() && [ -r "$master_message_template_checkout/message_template.msg" ] \ && template_verifier_master_url="-DTEMPLATE_VERIFIER_MASTER_URL=file://$master_message_template_checkout/message_template.msg" + # nat 2016-12-20: disable HAVOK on Mac until we get a 64-bit Mac build. + RELEASE_CRASH_REPORTING=ON + SIGNING=() + if [ "$arch" == "Darwin" ] + then HAVOK=OFF + if [ "$variant" == "Release" ] + then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \ + "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.") + fi + else HAVOK=ON + fi + "$autobuild" configure --quiet -c $variant -- \ -DPACKAGE:BOOL=ON \ - -DRELEASE_CRASH_REPORTING:BOOL=ON \ - -DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \ + -DUNATTENDED:BOOL=ON \ + -DHAVOK:BOOL="$HAVOK" \ + -DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \ + -DVIEWER_CHANNEL:STRING="${viewer_channel}" \ -DGRID:STRING="\"$viewer_grid\"" \ -DLL_TESTS:BOOL="$run_tests" \ -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \ + "${SIGNING[@]}" \ || fatal "$variant configuration failed" end_section "Configure $variant" @@ -111,21 +126,21 @@ package_llphysicsextensions_tpv() { begin_section "PhysicsExtensions_TPV" tpv_status=0 - if [ "$variant" = "Release" ] + # nat 2016-12-21: without HAVOK, can't build PhysicsExtensions_TPV. + if [ "$variant" = "Release" -a "${HAVOK:-}" != "OFF" ] then - llpetpvcfg=$build_dir/packages/llphysicsextensions/autobuild-tpv.xml - "$autobuild" build --quiet --config-file $llpetpvcfg -c Tpv + test -r "$build_dir/packages/llphysicsextensions/autobuild-tpv.xml" || fatal "No llphysicsextensions_tpv autobuild configuration found" + tpvconfig=$(native_path "$build_dir/packages/llphysicsextensions/autobuild-tpv.xml") + "$autobuild" build --quiet --config-file "$tpvconfig" -c Tpv || fatal "failed to build llphysicsextensions_tpv" # capture the package file name for use in upload later... PKGTMP=`mktemp -t pgktpv.XXXXXX` trap "rm $PKGTMP* 2>/dev/null" 0 - "$autobuild" package --quiet --config-file $llpetpvcfg --results-file "$(native_path $PKGTMP)" + "$autobuild" package --quiet --config-file "$tpvconfig" --results-file "$(native_path $PKGTMP)" || fatal "failed to package llphysicsextensions_tpv" tpv_status=$? if [ -r "${PKGTMP}" ] then - cat "${PKGTMP}" >> "$build_log" - eval $(cat "${PKGTMP}") # sets autobuild_package_{name,filename,md5} - autobuild_package_filename="$(shell_path "${autobuild_package_filename}")" + . "${PKGTMP}" # sets autobuild_package_{name,filename,md5} echo "${autobuild_package_filename}" > $build_dir/llphysicsextensions_package fi else @@ -141,10 +156,14 @@ build() local variant="$1" if $build_viewer then + begin_section "autobuild $variant" "$autobuild" build --no-configure -c $variant || fatal "failed building $variant" + echo true >"$build_dir"/build_ok + end_section "autobuild $variant" + begin_section "extensions $variant" # Run build extensions - if [ $build_ok -eq 0 -a -d ${build_dir}/packages/build-extensions ] + if [ -d ${build_dir}/packages/build-extensions ] then for extension in ${build_dir}/packages/build-extensions/*.sh do @@ -156,10 +175,10 @@ build() # *TODO: Make this a build extension. package_llphysicsextensions_tpv || fatal "failed building llphysicsextensions packages" + end_section "extensions $variant" - echo true >"$build_dir"/build_ok else - echo "Skipping build due to configuration build_viewer=${build_viewer}" + record_event "Skipping build due to configuration build_viewer=${build_viewer}" echo true >"$build_dir"/build_ok fi } @@ -175,13 +194,9 @@ then exit 1 fi -# Check to see if we're skipping the platform -if ! eval '$build_'"$arch" -then - record_event "building on architecture $arch is disabled" - pass -fi +initialize_build # provided by master buildscripts build.sh +begin_section "autobuild initialize" # ensure AUTOBUILD is in native path form for child processes AUTOBUILD="$(native_path "$AUTOBUILD")" # set "$autobuild" to cygwin path form for use locally in this script @@ -193,7 +208,16 @@ then fi # load autobuild provided shell functions and variables -eval "$("$autobuild" --quiet source_environment)" +"$autobuild" --quiet source_environment > "$build_log_dir/source_environment" +begin_section "dump source environment commands" +cat "$build_log_dir/source_environment" +end_section "dump source environment commands" + +begin_section "execute source environment commands" +. "$build_log_dir/source_environment" +end_section "execute source environment commands" + +end_section "autobuild initialize" # something about the additional_packages mechanism messes up buildscripts results.py on Linux # since we don't care about those packages on Linux, just zero it out, yes - a HACK @@ -202,10 +226,9 @@ then export additional_packages= fi -# dump environment variables for debugging -begin_section "Environment" -env|sort -end_section "Environment" +python_cmd "$helpers/codeticket.py" addinput "Viewer Channel" "${viewer_channel}" + +initialize_version # provided by buildscripts build.sh; sets version id # Now run the build succeeded=true @@ -213,9 +236,6 @@ build_processes= last_built_variant= for variant in $variants do - eval '$build_'"$variant" || continue - eval '$build_'"$arch"_"$variant" || continue - # Only the last built arch is available for upload last_built_variant="$variant" @@ -231,6 +251,9 @@ do then begin_section "Build $variant" build "$variant" "$build_dir" + end_section "Build $variant" + + begin_section "post-build $variant" if `cat "$build_dir/build_ok"` then case "$variant" in @@ -238,10 +261,11 @@ do if [ -r "$build_dir/autobuild-package.xml" ] then begin_section "Autobuild metadata" - upload_item docs "$build_dir/autobuild-package.xml" text/xml + python_cmd "$helpers/codeticket.py" addoutput "Autobuild Metadata" "$build_dir/autobuild-package.xml" --mimetype text/xml \ + || fatal "Upload of autobuild metadata failed" if [ "$arch" != "Linux" ] then - record_dependencies_graph # defined in buildscripts/hg/bin/build.sh + record_dependencies_graph "$build_dir/autobuild-package.xml" # defined in buildscripts/hg/bin/build.sh else record_event "TBD - no dependency graph for linux (probable python version dependency)" fi @@ -254,12 +278,13 @@ do if [ -r "$build_dir/doxygen_warnings.log" ] then record_event "Doxygen warnings generated; see doxygen_warnings.log" - upload_item log "$build_dir/doxygen_warnings.log" text/plain + python_cmd "$helpers/codeticket.py" addoutput "Doxygen Log" "$build_dir/doxygen_warnings.log" --mimetype text/plain ## TBD fi if [ -d "$build_dir/doxygen/html" ] then tar -c -f "$build_dir/viewer-doxygen.tar.bz2" --strip-components 3 "$build_dir/doxygen/html" - upload_item docs "$build_dir/viewer-doxygen.tar.bz2" binary/octet-stream + python_cmd "$helpers/codeticket.py" addoutput "Doxygen Tarball" "$build_dir/viewer-doxygen.tar.bz2" \ + || fatal "Upload of doxygen tarball failed" fi ;; *) @@ -269,7 +294,8 @@ do else record_failure "Build of \"$variant\" failed." fi - end_section "Build $variant" + end_section "post-build $variant" + else record_event "configure for $variant failed: build skipped" fi @@ -289,7 +315,7 @@ then if $build_viewer_deb && [ "$last_built_variant" == "Release" ] then begin_section "Build Viewer Debian Package" - have_private_repo=false + # mangle the changelog dch --force-bad-version \ --distribution unstable \ @@ -319,11 +345,14 @@ then # upload debian package and create repository begin_section "Upload Debian Repository" for deb_file in `/bin/ls ../packages_public/*.deb ../*.deb 2>/dev/null`; do - upload_item debian $deb_file binary/octet-stream + deb_pkg=$(basename "$deb_file" | sed 's,_.*,,') + python_cmd "$helpers/codeticket.py" addoutput "Debian $deb_pkg" $deb_file \ + || fatal "Upload of debian $deb_pkg failed" done for deb_file in `/bin/ls ../packages_private/*.deb 2>/dev/null`; do - upload_item debian_private $deb_file binary/octet-stream - have_private_repo=true + deb_pkg=$(basename "$deb_file" | sed 's,_.*,,') + python_cmd "$helpers/codeticket.py" addoutput "Debian $deb_pkg" "$deb_file" --private \ + || fatal "Upload of debian $deb_pkg failed" done create_deb_repo @@ -335,14 +364,6 @@ then mv $build_log_dir/$debian_repo_type $build_log_dir/${debian_repo_type}_pushed fi done - - if [ $have_private_repo = true ]; then - eval "$python_command \"$redirect\" '\${private_S3PROXY_URL}${S3PREFIX}repo/$repo/rev/$revision/index.html'"\ - >"$build_log_dir/private.html" || fatal generating redirect - upload_item global_redirect "$build_log_dir/private.html" text/html - - fi - end_section "Upload Debian Repository" else @@ -358,18 +379,17 @@ if $succeeded then if $build_viewer then - begin_section Upload Installer + begin_section "Uploads" # Upload installer package=$(installer_$arch) if [ x"$package" = x ] || test -d "$package" then - record_event "??? mystery event $package // $build_coverity" + fatal "No installer found from `pwd`" succeeded=$build_coverity else # Upload base package. - upload_item installer "$package" binary/octet-stream - upload_item quicklink "$package" binary/octet-stream - [ -f $build_dir/summary.json ] && upload_item installer $build_dir/summary.json text/plain + python_cmd "$helpers/codeticket.py" addoutput Installer "$package" \ + || fatal "Upload of installer failed" # Upload additional packages. for package_id in $additional_packages @@ -377,32 +397,44 @@ then package=$(installer_$arch "$package_id") if [ x"$package" != x ] then - upload_item installer "$package" binary/octet-stream - upload_item quicklink "$package" binary/octet-stream + python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \ + || fatal "Upload of installer $package_id failed" else record_failure "Failed to find additional package for '$package_id'." fi done - case "$last_built_variant" in - Release) - # Upload crash reporter files - for symbolfile in $symbolfiles - do - upload_item symbolfile "$build_dir/$symbolfile" binary/octet-stream - done - - # Upload the llphysicsextensions_tpv package, if one was produced - # *TODO: Make this an upload-extension - if [ -r "$build_dir/llphysicsextensions_package" ] - then - llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package) - upload_item private_artifact "$llphysicsextensions_package" binary/octet-stream - fi - ;; - *) - ;; - esac + if [ "$last_built_variant" = "Release" ] + then + # nat 2016-12-22: without RELEASE_CRASH_REPORTING, we have no symbol file. + if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ] + then + # Upload crash reporter file + # These names must match the set of VIEWER_SYMBOL_FILE in indra/newview/CMakeLists.txt + case "$arch" in + CYGWIN) + symbolfile="$build_dir/newview/Release/secondlife-symbols-windows-${AUTOBUILD_ADDRSIZE}.tar.bz2" + ;; + Darwin) + symbolfile="$build_dir/newview/Release/secondlife-symbols-darwin-${AUTOBUILD_ADDRSIZE}.tar.bz2" + ;; + Linux) + symbolfile="$build_dir/newview/Release/secondlife-symbols-linux-${AUTOBUILD_ADDRSIZE}.tar.bz2" + ;; + esac + python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$symbolfile" \ + || fatal "Upload of symbolfile failed" + fi + + # Upload the llphysicsextensions_tpv package, if one was produced + # *TODO: Make this an upload-extension + if [ -r "$build_dir/llphysicsextensions_package" ] + then + llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package) + python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \ + || fatal "Upload of physics extensions package failed" + fi + fi # Run upload extensions if [ -d ${build_dir}/packages/upload-extensions ]; then @@ -413,7 +445,7 @@ then done fi fi - end_section Upload Installer + end_section "Uploads" else record_event "skipping upload of installer" fi diff --git a/doc/contributions.txt b/doc/contributions.txt index 8fe04e2ff2c6e37b0e3d7a7fae3d17886f3ea1e3..46286f99c16d61cdbe98412f8bbeed496741a463 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -12,6 +12,7 @@ Able Whitman Adam Marker VWR-2755 Adeon Writer + MAINT-1211 Aeonix Aeon Agathos Frascati CT-246 @@ -190,7 +191,28 @@ Ansariel Hiller STORM-2094 MAINT-5756 MAINT-4677 + MAINT-6300 + MAINT-6397 MAINT-6432 + MAINT-6513 + MAINT-6514 + MAINT-6552 + STORM-2133 + MAINT-6511 + MAINT-6612 + MAINT-6637 + MAINT-6636 + MAINT-6744 + MAINT-6752 + MAINT-6773 + MAINT-6906 + MAINT-6911 + STORM-2140 + MAINT-6912 + MAINT-6929 + STORM-2141 + MAINT-6953 + MAINT-7028 Aralara Rajal Arare Chantilly CHUIBUG-191 @@ -305,6 +327,7 @@ Catherine Pfeffer VWR-1282 VWR-8624 VWR-10854 +Cathy Foil Cayu Cluny Celierra Darling VWR-1274 @@ -737,6 +760,11 @@ Jonathan Yap STORM-2088 STORM-2094 STORM-2099 + STORM-2091 + STORM-2092 + STORM-2100 + STORM-2104 + STORM-2142 Kadah Coba STORM-1060 STORM-1843 @@ -788,6 +816,7 @@ Kitty Barnett MAINT-6152 MAINT-6153 MAINT-6154 + MAINT-6568 Kolor Fall Komiko Okamoto Korvel Noh @@ -857,6 +886,7 @@ MartinRJ Fayray STORM-1845 STORM-1911 STORM-1934 +Matrice Laville Matthew Anthony Matthew Dowd VWR-1344 @@ -1019,6 +1049,7 @@ Nicky Dasmijn OPEN-187 STORM-2010 STORM-2082 + MAINT-6665 Nicky Perian OPEN-1 STORM-1087 @@ -1230,6 +1261,8 @@ Shnurui Troughton Shyotl Kuhr MAINT-1138 MAINT-2334 + MAINT-6913 + STORM-2143 Siana Gearz STORM-960 STORM-1088 @@ -1263,6 +1296,8 @@ Sovereign Engineer MAINT-6107 STORM-2107 MAINT-6218 + MAINT-6913 + STORM-2143 SpacedOut Frye VWR-34 VWR-45 diff --git a/indra/cmake/00-COMPILE-LINK-RUN.txt b/indra/cmake/00-COMPILE-LINK-RUN.txt index 162b22865ca4b9723ded9fc868601a3f8be2be24..1933072a6d3ea3bb0b0e16d0b51f6f9313591d48 100644 --- a/indra/cmake/00-COMPILE-LINK-RUN.txt +++ b/indra/cmake/00-COMPILE-LINK-RUN.txt @@ -48,8 +48,8 @@ Compilation LL_WINDOWS=1 " " UNICODE " " _UNICODE " " - WINVER=0x0501 " " - _WIN32_WINNT=0x0501 " " + WINVER=0x0600 " " + _WIN32_WINNT=0x0600 " " LL_OS_DRAGDROP_ENABLED=1 " " LIB_NDOF=1 " " diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 86fc2dfff5d4fc06713e945e3b4356e4be106295..f925fdda5de7c2875cdc617784ba4287effe3c52 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -2,18 +2,32 @@ # # Compilation options shared by all Second Life components. +#***************************************************************************** +# It's important to realize that CMake implicitly concatenates +# CMAKE_CXX_FLAGS with (e.g.) CMAKE_CXX_FLAGS_RELEASE for Release builds. So +# set switches in CMAKE_CXX_FLAGS that should affect all builds, but in +# CMAKE_CXX_FLAGS_RELEASE or CMAKE_CXX_FLAGS_RELWITHDEBINFO for switches +# that should affect only that build variant. +# +# Also realize that CMAKE_CXX_FLAGS may already be partially populated on +# entry to this file. +#***************************************************************************** + if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") include(Variables) -# Portable compilation flags. -set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1") -set(CMAKE_CXX_FLAGS_RELEASE - "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -DNDEBUG") +# We go to some trouble to set LL_BUILD to the set of relevant compiler flags. +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}") +# Given that, all the flags you see added below are flags NOT present in +# https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables. +# Before adding new ones here, it's important to ask: can this flag really be +# applied to the viewer only, or should/must it be applied to all 3p libraries +# as well? -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "-DLL_RELEASE=1 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1") +# Portable compilation flags. +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DADDRESS_SIZE=${ADDRESS_SIZE}") # Configure crash reporting set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds") @@ -46,26 +60,25 @@ if (WINDOWS) # http://www.cmake.org/pipermail/cmake/2009-September/032143.html string(REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP -D_SCL_SECURE_NO_WARNINGS=1" - CACHE STRING "C++ compiler debug options" FORCE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /Zo /MD /MP /Ob0 -D_SECURE_STL=0" + "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo" CACHE STRING "C++ compiler release-with-debug options" FORCE) set(CMAKE_CXX_FLAGS_RELEASE - "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /Zo /MD /MP /Ob2 -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0" + "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /Zo" CACHE STRING "C++ compiler release options" FORCE) # zlib has assembly-language object files incompatible with SAFESEH - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE /SAFESEH:NO /NODEFAULTLIB:LIBCMT") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE /SAFESEH:NO /NODEFAULTLIB:LIBCMT /IGNORE:4099") set(CMAKE_CXX_STANDARD_LIBRARIES "") set(CMAKE_C_STANDARD_LIBRARIES "") add_definitions( - /DLL_WINDOWS=1 /DNOMINMAX # /DDOM_DYNAMIC # For shared library colladadom - /DUNICODE - /D_UNICODE + ) + add_compile_options( /GS /TP /W3 @@ -73,94 +86,41 @@ if (WINDOWS) /Zc:forScope /nologo /Oy- - /Zc:wchar_t- - /arch:SSE2 +# /arch:SSE2 /fp:fast ) + + # Nicky: x64 implies SSE2 + if( ADDRESS_SIZE EQUAL 32 ) + add_definitions( /arch:SSE2 ) + endif() # Are we using the crummy Visual Studio KDU build workaround? if (NOT VS_DISABLE_FATAL_WARNINGS) add_definitions(/WX) endif (NOT VS_DISABLE_FATAL_WARNINGS) - - # configure win32 API for windows XP+ compatibility - set(WINVER "0x0501" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)") - add_definitions("/DWINVER=${WINVER}" "/D_WIN32_WINNT=${WINVER}") endif (WINDOWS) if (LINUX) set(CMAKE_SKIP_RPATH TRUE) - # Here's a giant hack for Fedora 8, where we can't use - # _FORTIFY_SOURCE if we're using a compiler older than gcc 4.1. - - find_program(GXX g++) - mark_as_advanced(GXX) - - if (GXX) - execute_process( - COMMAND ${GXX} --version - COMMAND sed "s/^[gc+ ]*//" - COMMAND head -1 - OUTPUT_VARIABLE GXX_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - else (GXX) - set(GXX_VERSION x) - endif (GXX) - - # The quoting hack here is necessary in case we're using distcc or - # ccache as our compiler. CMake doesn't pass the command line - # through the shell by default, so we end up trying to run "distcc" - # " g++" - notice the leading space. Ugh. - - execute_process( - COMMAND sh -c "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} --version" - COMMAND sed "s/^[gc+ ]*//" - COMMAND head -1 - OUTPUT_VARIABLE CXX_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE) - - if (${GXX_VERSION} STREQUAL ${CXX_VERSION}) - add_definitions(-D_FORTIFY_SOURCE=2) - else (${GXX_VERSION} STREQUAL ${CXX_VERSION}) - if (NOT ${GXX_VERSION} MATCHES " 4.1.*Red Hat") - add_definitions(-D_FORTIFY_SOURCE=2) - endif (NOT ${GXX_VERSION} MATCHES " 4.1.*Red Hat") - endif (${GXX_VERSION} STREQUAL ${CXX_VERSION}) - - # Let's actually get a numerical version of gxx's version - STRING(REGEX REPLACE ".* ([0-9])\\.([0-9])\\.([0-9]).*" "\\1\\2\\3" CXX_VERSION_NUMBER ${CXX_VERSION}) - - # Hacks to work around gcc 4.1 TC build pool machines which can't process pragma warning disables - # This is pure rubbish; I wish there was another way. - # - if(${CXX_VERSION_NUMBER} LESS 420) - set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-uninitialized -Wno-unused-variable -Wno-unused-function ${CMAKE_CXX_FLAGS}") - endif (${CXX_VERSION_NUMBER} LESS 420) - - if(${CXX_VERSION_NUMBER} GREATER 459) - set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable ${CMAKE_CXX_FLAGS}") - endif (${CXX_VERSION_NUMBER} GREATER 459) + add_definitions(-D_FORTIFY_SOURCE=2) + + set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable ${CMAKE_CXX_FLAGS}") # gcc 4.3 and above don't like the LL boost and also # cause warnings due to our use of deprecated headers - if(${CXX_VERSION_NUMBER} GREATER 429) - add_definitions(-Wno-parentheses) - set(CMAKE_CXX_FLAGS "-Wno-deprecated ${CMAKE_CXX_FLAGS}") - endif (${CXX_VERSION_NUMBER} GREATER 429) - - # End of hacks. + add_definitions(-Wno-parentheses) add_definitions( - -DLL_LINUX=1 -D_REENTRANT + ) + add_compile_options( -fexceptions -fno-math-errno -fno-strict-aliasing -fsigned-char - -g -msse2 -mfpmath=sse -pthread @@ -170,39 +130,37 @@ if (LINUX) add_definitions(-DEXTERNAL_TOS) add_definitions(-DAPPID=secondlife) - add_definitions(-fvisibility=hidden) - # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The viewer doesn't need to catch SIGCHLD anyway. + add_compile_options(-fvisibility=hidden) + # don't catch SIGCHLD in our base application class for the viewer - some of + # our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The + # viewer doesn't need to catch SIGCHLD anyway. add_definitions(-DLL_IGNORE_SIGCHLD) - if (WORD_SIZE EQUAL 32) - add_definitions(-march=pentium4) - endif (WORD_SIZE EQUAL 32) - add_definitions(-mfpmath=sse) - #add_definitions(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2 + if (ADDRESS_SIZE EQUAL 32) + add_compile_options(-march=pentium4) + endif (ADDRESS_SIZE EQUAL 32) + #add_compile_options(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2 if (NOT USESYSTEMLIBS) # this stops us requiring a really recent glibc at runtime - add_definitions(-fno-stack-protector) + add_compile_options(-fno-stack-protector) # linking can be very memory-hungry, especially the final viewer link set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory") endif (NOT USESYSTEMLIBS) set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}") - set(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}") endif (LINUX) if (DARWIN) - add_definitions(-DLL_DARWIN=1) - set(CMAKE_CXX_LINK_FLAGS "-Wl,-no_compact_unwind -Wl,-headerpad_max_install_names,-search_paths_first") + set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}") - set(DARWIN_extra_cstar_flags "-g -Wno-unused-local-typedef -Wno-deprecated-declarations") + set(DARWIN_extra_cstar_flags "-Wno-unused-local-typedef -Wno-deprecated-declarations") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DARWIN_extra_cstar_flags}") # NOTE: it's critical that the optimization flag is put in front. # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered. - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_C_FLAGS_RELWITHDEBINFO}") - set(ENABLE_SIGNING TRUE) - set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.") +## Really?? On developer machines too? +##set(ENABLE_SIGNING TRUE) +##set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.") endif (DARWIN) @@ -226,22 +184,17 @@ if (LINUX OR DARWIN) set(CMAKE_C_FLAGS "${GCC_WARNINGS} ${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "${GCC_CXX_WARNINGS} ${CMAKE_CXX_FLAGS}") - if (WORD_SIZE EQUAL 32) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") - elseif (WORD_SIZE EQUAL 64) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64") - endif (WORD_SIZE EQUAL 32) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m${ADDRESS_SIZE}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m${ADDRESS_SIZE}") endif (LINUX OR DARWIN) if (USESYSTEMLIBS) add_definitions(-DLL_USESYSTEMLIBS=1) - if (LINUX AND ${ARCH} STREQUAL "i686") + if (LINUX AND ADDRESS_SIZE EQUAL 32) add_definitions(-march=pentiumpro) - endif (LINUX AND ${ARCH} STREQUAL "i686") + endif (LINUX AND ADDRESS_SIZE EQUAL 32) else (USESYSTEMLIBS) set(${ARCH}_linux_INCLUDES diff --git a/indra/cmake/BuildPackagesInfo.cmake b/indra/cmake/BuildPackagesInfo.cmake index 0f574ee39a17b08da618b5ed84169ec4b5744039..93461cea953c54f0d0b17bb3670c81df841186bb 100644 --- a/indra/cmake/BuildPackagesInfo.cmake +++ b/indra/cmake/BuildPackagesInfo.cmake @@ -2,9 +2,18 @@ # Construct the version and copyright information based on package data. include(Python) +# packages-formatter.py runs autobuild install --versions, which needs to know +# the build_directory, which (on Windows) depends on AUTOBUILD_ADDRSIZE. +# Within an autobuild build, AUTOBUILD_ADDRSIZE is already set. But when +# building in an IDE, it probably isn't. Set it explicitly using +# run_build_test.py. add_custom_command(OUTPUT packages-info.txt COMMENT Generating packages-info.txt for the about box MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/../autobuild.xml DEPENDS ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py > packages-info.txt + ${CMAKE_SOURCE_DIR}/../autobuild.xml + COMMAND ${PYTHON_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/cmake/run_build_test.py -DAUTOBUILD_ADDRSIZE=${ADDRESS_SIZE} + ${PYTHON_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py "${VIEWER_CHANNEL}" "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" > packages-info.txt ) diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake index 6ffa698a1c65132e172d6a59eba196b6a9f36f2b..157fdd07e4c19f5ee97e5d25ac91dcd92a4bc4a2 100644 --- a/indra/cmake/BuildVersion.cmake +++ b/indra/cmake/BuildVersion.cmake @@ -14,6 +14,10 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n set(VIEWER_VERSION_REVISION $ENV{revision}) message(STATUS "Revision (from environment): ${VIEWER_VERSION_REVISION}") + elseif (DEFINED ENV{AUTOBUILD_BUILD_ID}) + set(VIEWER_VERSION_REVISION $ENV{AUTOBUILD_BUILD_ID}) + message(STATUS "Revision (from autobuild environment): ${VIEWER_VERSION_REVISION}") + else (DEFINED ENV{revision}) find_program(MERCURIAL NAMES hg @@ -54,7 +58,7 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n endif ("${VIEWER_VERSION_REVISION}" STREQUAL "") set(VIEWER_CHANNEL_VERSION_DEFINES - "LL_VIEWER_CHANNEL=\"${VIEWER_CHANNEL}\"" + "LL_VIEWER_CHANNEL=${VIEWER_CHANNEL}" "LL_VIEWER_VERSION_MAJOR=${VIEWER_VERSION_MAJOR}" "LL_VIEWER_VERSION_MINOR=${VIEWER_VERSION_MINOR}" "LL_VIEWER_VERSION_PATCH=${VIEWER_VERSION_PATCH}" diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 6dc8e3dfbf7572d7bdca353a6588c5ac544d25ca..100645611e13c215d7f1559ef3ac7b7a4b5ee285 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -24,14 +24,12 @@ set(cmake_SOURCE_FILES DirectX.cmake DragDrop.cmake EXPAT.cmake -## ExamplePlugin.cmake FindAPR.cmake FindAutobuild.cmake FindBerkeleyDB.cmake FindFMODEX.cmake FindGLH.cmake FindGoogleBreakpad.cmake - FindGooglePerfTools.cmake FindHUNSPELL.cmake FindJsonCpp.cmake FindNDOF.cmake @@ -47,11 +45,8 @@ set(cmake_SOURCE_FILES GLOD.cmake ## GStreamer010Plugin.cmake GetPrerequisites_2_8.cmake -## Glui.cmake - Glut.cmake GoogleBreakpad.cmake GoogleMock.cmake - GooglePerfTools.cmake Havok.cmake Hunspell.cmake JPEG.cmake @@ -91,7 +86,6 @@ set(cmake_SOURCE_FILES Prebuilt.cmake PulseAudio.cmake Python.cmake - QuickTimePlugin.cmake TemplateCheck.cmake Tut.cmake UI.cmake @@ -100,6 +94,7 @@ set(cmake_SOURCE_FILES Variables.cmake ViewerMiscLibs.cmake VisualLeakDetector.cmake + LibVLCPlugin.cmake XmlRpcEpi.cmake ZLIB.cmake ) diff --git a/indra/cmake/ConfigurePkgConfig.cmake b/indra/cmake/ConfigurePkgConfig.cmake index 82ee3e7a5b54d107e852ea17bab037c76c3d9c16..55d865392e37b294459166116c8bdf71d0fdc121 100644 --- a/indra/cmake/ConfigurePkgConfig.cmake +++ b/indra/cmake/ConfigurePkgConfig.cmake @@ -6,17 +6,17 @@ SET(DEBUG_PKG_CONFIG "YES") IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "") # Guess at architecture-specific system library paths. - if (WORD_SIZE EQUAL 32) + if (ADDRESS_SIZE EQUAL 32) SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib) SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib) SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu) SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu) - else (WORD_SIZE EQUAL 32) + else (ADDRESS_SIZE EQUAL 32) SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib) SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib) SET(PKG_CONFIG_MULTI_GUESS /usr/local/lib/x86_64-linux-gnu) SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu) - endif (WORD_SIZE EQUAL 32) + endif (ADDRESS_SIZE EQUAL 32) # Use DPKG architecture, if available. IF (${DPKG_ARCH}) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 70d85b864ca4edac22ef1be9c7347acab354a337..14510d654fc346afd6b480d2f54badd320f0294e 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -30,18 +30,6 @@ if(WINDOWS) #******************************* # Misc shared libs - set(debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}") - set(debug_files - openjpegd.dll - libapr-1.dll - libaprutil-1.dll - libapriconv-1.dll - ssleay32.dll - libeay32.dll - glod.dll - libhunspell.dll - ) - set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") set(release_files openjpeg.dll @@ -54,14 +42,13 @@ if(WINDOWS) libhunspell.dll ) - if(USE_TCMALLOC) - set(debug_files ${debug_files} libtcmalloc_minimal-debug.dll) - set(release_files ${release_files} libtcmalloc_minimal.dll) - endif(USE_TCMALLOC) - if (FMODEX) - set(debug_files ${debug_files} fmodexL.dll) - set(release_files ${release_files} fmodex.dll) + + if(ADDRESS_SIZE EQUAL 32) + set(release_files ${release_files} fmodex.dll) + else(ADDRESS_SIZE EQUAL 32) + set(release_files ${release_files} fmodex64.dll) + endif(ADDRESS_SIZE EQUAL 32) endif (FMODEX) #******************************* @@ -175,10 +162,8 @@ elseif(DARWIN) libaprutil-1.0.dylib libaprutil-1.dylib libexception_handler.dylib - libexpat.1.5.2.dylib - libexpat.dylib + ${EXPAT_COPY} libGLOD.dylib - libhunspell-1.3.0.dylib libndofdev.dylib ) @@ -218,8 +203,7 @@ elseif(LINUX) libaprutil-1.so.0 libatk-1.0.so libdb-5.1.so - libexpat.so - libexpat.so.1 + ${EXPAT_COPY} libfreetype.so.6.6.2 libfreetype.so.6 libGLOD.so @@ -234,10 +218,6 @@ elseif(LINUX) libfontconfig.so.1 ) - if (USE_TCMALLOC) - set(release_files ${release_files} "libtcmalloc_minimal.so") - endif (USE_TCMALLOC) - if (FMODEX) set(debug_files ${debug_files} "libfmodexL.so") set(release_files ${release_files} "libfmodex.so") @@ -294,13 +274,13 @@ set(third_party_targets ${third_party_targets} ${out_targets}) -copy_if_different( - ${debug_src_dir} - "${SHARED_LIB_STAGING_DIR_DEBUG}" - out_targets - ${debug_files} - ) -set(third_party_targets ${third_party_targets} ${out_targets}) +#copy_if_different( +# ${debug_src_dir} +# "${SHARED_LIB_STAGING_DIR_DEBUG}" +# out_targets +# ${debug_files} +# ) +#set(third_party_targets ${third_party_targets} ${out_targets}) copy_if_different( ${release_src_dir} diff --git a/indra/cmake/DeploySharedLibs.cmake b/indra/cmake/DeploySharedLibs.cmake index 663c272e502ffca8e33b2e7c7784e672a85bf687..e57fd5eee3f1a2f58f19d7974d49d3f868355620 100644 --- a/indra/cmake/DeploySharedLibs.cmake +++ b/indra/cmake/DeploySharedLibs.cmake @@ -12,7 +12,7 @@ get_filename_component(current_dir ${CMAKE_CURRENT_LIST_FILE} PATH) include(${current_dir}/GetPrerequisites_2_8.cmake) -message("Getting recursive dependencies for file: ${BIN_NAME}") +message(STATUS "Getting recursive dependencies for file: ${BIN_NAME}") set(EXCLUDE_SYSTEM 1) set(RECURSE 1) @@ -21,7 +21,7 @@ get_filename_component(EXE_PATH ${BIN_NAME} PATH) get_prerequisites( ${BIN_NAME} RESULTS ${EXCLUDE_SYSTEM} ${RECURSE} "${EXE_PATH}" "${SEARCH_DIRS}" ) foreach(DEP ${RESULTS}) - Message("Processing dependency: ${DEP}") + Message(STATUS "Processing dependency: ${DEP}") get_filename_component(DEP_FILE ${DEP} NAME) set(DEP_FILES ${DEP_FILES} ${DEP_FILE}) endforeach(DEP) @@ -64,10 +64,10 @@ if(FOUND_FILES) foreach(FILE ${FOUND_FILES}) get_filename_component(DST_FILE ${FILE} NAME) set(DST_FILE "${DST_PATH}/${DST_FILE}") - message("Copying ${FILE} to ${DST_FILE}") + message(STATUS "Copying ${FILE} to ${DST_FILE}") execute_process( COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FILE} ${DST_FILE} ) endforeach(FILE ${FOUND_FILES}) endif(FOUND_FILES) -message("Success!") + diff --git a/indra/cmake/EXPAT.cmake b/indra/cmake/EXPAT.cmake index c1155531ff6d1a4e9b52d3edd3eafba294b499a2..cddc71b227525f1d4f6b18879c92b59d2c371f33 100644 --- a/indra/cmake/EXPAT.cmake +++ b/indra/cmake/EXPAT.cmake @@ -10,8 +10,14 @@ else (USESYSTEMLIBS) use_prebuilt_binary(expat) if (WINDOWS) set(EXPAT_LIBRARIES libexpatMT) + set(EXPAT_COPY libexpatMT.dll) else (WINDOWS) set(EXPAT_LIBRARIES expat) + if (DARWIN) + set(EXPAT_COPY libexpat.1.dylib libexpat.dylib) + else () + set(EXPAT_COPY libexpat.so.1 libexpat.so) + endif () endif (WINDOWS) set(EXPAT_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) endif (USESYSTEMLIBS) diff --git a/indra/cmake/FindHUNSPELL.cmake b/indra/cmake/FindHUNSPELL.cmake index 6faf22959c65ab189f5c10e3b3afdfaba00bd973..d411bdb9e5eba98c57ecca9f96c0cefc7f11a7f1 100644 --- a/indra/cmake/FindHUNSPELL.cmake +++ b/indra/cmake/FindHUNSPELL.cmake @@ -10,7 +10,7 @@ find_path(HUNSPELL_INCLUDE_DIR hunspell.h PATH_SUFFIXES hunspell ) -set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3.0 libhunspell) +set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3 libhunspell) find_library(HUNSPELL_LIBRARY NAMES ${HUNSPELL_NAMES} ) diff --git a/indra/cmake/GLEXT.cmake b/indra/cmake/GLEXT.cmake index 2a08c8fbaeb5890f50ca288d29ee6bd68852ab72..9fd3923bfd9b2448a4edd171a7cf299b43d24127 100644 --- a/indra/cmake/GLEXT.cmake +++ b/indra/cmake/GLEXT.cmake @@ -5,6 +5,6 @@ if (NOT USESYSTEMLIBS) if (WINDOWS OR LINUX) use_prebuilt_binary(glext) endif (WINDOWS OR LINUX) - use_prebuilt_binary(glh-linear) + use_prebuilt_binary(glh_linear) set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) endif (NOT USESYSTEMLIBS) diff --git a/indra/cmake/GLH.cmake b/indra/cmake/GLH.cmake index d0992f57b8217ef3eb12a8908705eb7995a5e768..d5262f2efa79acafca6fa6661a2bd81d6dcbbdd1 100644 --- a/indra/cmake/GLH.cmake +++ b/indra/cmake/GLH.cmake @@ -7,5 +7,5 @@ set(GLH_FIND_QUIETLY TRUE) if (USESYSTEMLIBS) include(FindGLH) else (USESYSTEMLIBS) - use_prebuilt_binary(glh-linear) + use_prebuilt_binary(glh_linear) endif (USESYSTEMLIBS) diff --git a/indra/cmake/Glui.cmake b/indra/cmake/Glui.cmake deleted file mode 100644 index db353a91ecaa9d85d1c3c0a1920980c26c16d756..0000000000000000000000000000000000000000 --- a/indra/cmake/Glui.cmake +++ /dev/null @@ -1,28 +0,0 @@ -# -*- cmake -*- -include(Linking) -include(Prebuilt) - -if (USESYSTEMLIBS) - set(GLUI OFF CACHE BOOL - "GLUI support for the llplugin/llmedia test apps.") -else (USESYSTEMLIBS) - use_prebuilt_binary(glui) - set(GLUI ON CACHE BOOL - "GLUI support for the llplugin/llmedia test apps.") -endif (USESYSTEMLIBS) - -if (LINUX) - set(GLUI ON CACHE BOOL - "llplugin media apps HACK for Linux.") -endif (LINUX) - -if (DARWIN OR LINUX) - set(GLUI_LIBRARY - glui) -endif (DARWIN OR LINUX) - -if (WINDOWS) - set(GLUI_LIBRARY - debug glui32.lib - optimized glui32.lib) -endif (WINDOWS) diff --git a/indra/cmake/Glut.cmake b/indra/cmake/Glut.cmake deleted file mode 100644 index 314da30652d2da78807112d6b48050b5792f37bd..0000000000000000000000000000000000000000 --- a/indra/cmake/Glut.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# -*- cmake -*- -include(Linking) -include(Prebuilt) - -if (WINDOWS) - use_prebuilt_binary(freeglut) - set(GLUT_LIBRARY - debug freeglut_static.lib - optimized freeglut_static.lib) -endif (WINDOWS) - -if (LINUX) - FIND_LIBRARY(GLUT_LIBRARY glut) -endif (LINUX) - -if (DARWIN) - include(CMakeFindFrameworks) - find_library(GLUT_LIBRARY GLUT) -endif (DARWIN) diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake deleted file mode 100644 index c1faeb9325241f4f54298fb6b97d9ddc3cd68b97..0000000000000000000000000000000000000000 --- a/indra/cmake/GooglePerfTools.cmake +++ /dev/null @@ -1,61 +0,0 @@ -# -*- cmake -*- -include(Prebuilt) - -# If you want to enable or disable TCMALLOC in viewer builds, this is the place. -# set ON or OFF as desired. -set (USE_TCMALLOC OFF) - -if (USESYSTEMLIBS) - include(FindGooglePerfTools) -else (USESYSTEMLIBS) - if (WINDOWS) - if (USE_TCMALLOC) - use_prebuilt_binary(gperftools) - set(TCMALLOC_LIBRARIES - debug libtcmalloc_minimal-debug - optimized libtcmalloc_minimal) - set(TCMALLOC_LINK_FLAGS "/INCLUDE:__tcmalloc") - else (USE_TCMALLOC) - set(TCMALLOC_LIBRARIES) - set(TCMALLOC_LINK_FLAGS) - endif (USE_TCMALLOC) - set(GOOGLE_PERFTOOLS_FOUND "YES") - endif (WINDOWS) - if (LINUX) - if (USE_TCMALLOC) - use_prebuilt_binary(gperftools) - set(TCMALLOC_LIBRARIES - tcmalloc) - else (USE_TCMALLOC) - set(TCMALLOC_LIBRARIES) - endif (USE_TCMALLOC) - set(PROFILER_LIBRARIES profiler) - set(GOOGLE_PERFTOOLS_INCLUDE_DIR - ${LIBS_PREBUILT_DIR}/include) - set(GOOGLE_PERFTOOLS_FOUND "YES") - endif (LINUX) -endif (USESYSTEMLIBS) - -if (GOOGLE_PERFTOOLS_FOUND) - # XXX Disable temporarily, until we have compilation issues on 64-bit - # Etch sorted. - set(USE_GOOGLE_PERFTOOLS OFF CACHE BOOL "Build with Google PerfTools support.") -endif (GOOGLE_PERFTOOLS_FOUND) - -if (WINDOWS) - set(USE_GOOGLE_PERFTOOLS ON) -endif (WINDOWS) - -if (USE_GOOGLE_PERFTOOLS) - if (USE_TCMALLOC) - set(TCMALLOC_FLAG -DLL_USE_TCMALLOC=1) - else (USE_TCMALLOC) - set(TCMALLOC_FLAG -ULL_USE_TCMALLOC) - endif (USE_TCMALLOC) -endif (USE_GOOGLE_PERFTOOLS) - -if (USE_GOOGLE_PERFTOOLS) - include_directories(${GOOGLE_PERFTOOLS_INCLUDE_DIR}) - set(GOOGLE_PERFTOOLS_LIBRARIES ${TCMALLOC_LIBRARIES} ${STACKTRACE_LIBRARIES} ${PROFILER_LIBRARIES}) -else (USE_GOOGLE_PERFTOOLS) -endif (USE_GOOGLE_PERFTOOLS) diff --git a/indra/cmake/Hunspell.cmake b/indra/cmake/Hunspell.cmake index ef74d95b2a6711f9e2fc20eba393a58242389bda..06227b3fe2336190d3277444c9b1623ac95d1d34 100644 --- a/indra/cmake/Hunspell.cmake +++ b/indra/cmake/Hunspell.cmake @@ -11,7 +11,7 @@ else (USESYSTEMLIBS) if (WINDOWS) set(HUNSPELL_LIBRARY libhunspell) elseif(DARWIN) - set(HUNSPELL_LIBRARY hunspell-1.3.0) + set(HUNSPELL_LIBRARY hunspell-1.3) elseif(LINUX) set(HUNSPELL_LIBRARY hunspell-1.3) else() diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index db8b95dbe2e80690dafed9a306206d240bc23f1c..96d3e39a0621ced983cf0457de05c5184640487c 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -35,7 +35,6 @@ INCLUDE(GoogleMock) ${APRUTIL_LIBRARIES} ${APR_LIBRARIES} llcommon - llcorehttp ) IF(NOT "${project}" STREQUAL "llmath") # add llmath as a dep unless the tested module *is* llmath! diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index b50b4bcdb223cac4201492764c01a52b4af5f808..3e29297c580435e215ea5bc8ee4bcb634fd6bde9 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -4,7 +4,6 @@ include(APR) include(Boost) include(EXPAT) include(ZLIB) -include(GooglePerfTools) set(LLCOMMON_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llcommon @@ -34,8 +33,6 @@ else (LINUX) ${BOOST_SYSTEM_LIBRARY} ) endif (LINUX) -# add_definitions(${TCMALLOC_FLAG}) - set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") if(LLCOMMON_LINK_SHARED) add_definitions(-DLL_COMMON_LINK_SHARED=1) diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake index ba07a80f051af43e9165f8f74c01f6b99be28198..80af7ff2ab2a6d1676404910ab75b55079a6f91f 100644 --- a/indra/cmake/LLWindow.cmake +++ b/indra/cmake/LLWindow.cmake @@ -18,7 +18,7 @@ else (USESYSTEMLIBS) use_prebuilt_binary(SDL) set (SDL_FOUND TRUE) set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/i686-linux) - set (SDL_LIBRARY SDL directfb fusion direct) + set (SDL_LIBRARY SDL directfb fusion direct X11) endif (LINUX) endif (USESYSTEMLIBS) diff --git a/indra/cmake/LibVLCPlugin.cmake b/indra/cmake/LibVLCPlugin.cmake new file mode 100644 index 0000000000000000000000000000000000000000..df829b615aa8fbb2defb8805a9cf9a36587bd78b --- /dev/null +++ b/indra/cmake/LibVLCPlugin.cmake @@ -0,0 +1,31 @@ +# -*- cmake -*- +include(Linking) +include(Prebuilt) + +if (USESYSTEMLIBS) + set(LIBVLCPLUGIN OFF CACHE BOOL + "LIBVLCPLUGIN support for the llplugin/llmedia test apps.") +else (USESYSTEMLIBS) + use_prebuilt_binary(vlc-bin) + set(LIBVLCPLUGIN ON CACHE BOOL + "LIBVLCPLUGIN support for the llplugin/llmedia test apps.") + set(VLC_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/vlc) +endif (USESYSTEMLIBS) + +if (WINDOWS) + set(VLC_PLUGIN_LIBRARIES + libvlc.lib + libvlccore.lib + ) +elseif (DARWIN) + set(VLC_PLUGIN_LIBRARIES + libvlc.dylib + libvlccore.dylib + ) +elseif (LINUX) + # Specify a full path to make sure we get a static link + set(VLC_PLUGIN_LIBRARIES + ${LIBS_PREBUILT_DIR}/lib/libvlc.a + ${LIBS_PREBUILT_DIR}/lib/libvlccore.a + ) +endif (WINDOWS) diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake index 98013da2f21bc67abebd418a24c2b12a25f68022..33a6d769167542a4294b4f8abbb017a0e5e2af93 100644 --- a/indra/cmake/Prebuilt.cmake +++ b/indra/cmake/Prebuilt.cmake @@ -39,7 +39,7 @@ macro (use_prebuilt_binary _binary) if(${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0) if(DEBUG_PREBUILT) - message("cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install + message(STATUS "cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install --install-dir=${AUTOBUILD_INSTALL_DIR} ${_binary} ") endif(DEBUG_PREBUILT) diff --git a/indra/cmake/QuickTimePlugin.cmake b/indra/cmake/QuickTimePlugin.cmake deleted file mode 100644 index c08e153ee3900f9313c1c8c46cf3aac06568e2c6..0000000000000000000000000000000000000000 --- a/indra/cmake/QuickTimePlugin.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# -*- cmake -*- - -if(INSTALL_PROPRIETARY) - include(Prebuilt) - if (WINDOWS) - use_prebuilt_binary(quicktime) - endif (WINDOWS) -endif(INSTALL_PROPRIETARY) - -if (DARWIN) - include(CMakeFindFrameworks) - find_library(QUICKTIME_LIBRARY QuickTime) -elseif (WINDOWS) - set(QUICKTIME_SDK_DIR "$ENV{PROGRAMFILES}/QuickTime SDK" - CACHE PATH "Location of the QuickTime SDK.") - - find_library(DEBUG_QUICKTIME_LIBRARY qtmlclient.lib - PATHS - ${ARCH_PREBUILT_DIRS_DEBUG} - "${QUICKTIME_SDK_DIR}\\libraries" - ) - - find_library(RELEASE_QUICKTIME_LIBRARY qtmlclient.lib - PATHS - ${ARCH_PREBUILT_DIRS_RELEASE} - "${QUICKTIME_SDK_DIR}\\libraries" - ) - - if (DEBUG_QUICKTIME_LIBRARY AND RELEASE_QUICKTIME_LIBRARY) - set(QUICKTIME_LIBRARY - optimized ${RELEASE_QUICKTIME_LIBRARY} - debug ${DEBUG_QUICKTIME_LIBRARY} - ) - - endif (DEBUG_QUICKTIME_LIBRARY AND RELEASE_QUICKTIME_LIBRARY) - - include_directories( - ${LIBS_PREBUILT_DIR}/include/quicktime - "${QUICKTIME_SDK_DIR}\\CIncludes" - ) -endif (DARWIN) - -mark_as_advanced(QUICKTIME_LIBRARY) - -if (QUICKTIME_LIBRARY) - set(QUICKTIME ON CACHE BOOL "Build with QuickTime streaming media support.") -endif (QUICKTIME_LIBRARY) - diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake index 31174209a313aae3e3dadeea75d9d7aacf9fb891..77fd505df361c70c3e47c9d880cafb44a268828c 100644 --- a/indra/cmake/UI.cmake +++ b/indra/cmake/UI.cmake @@ -32,9 +32,9 @@ if (USESYSTEMLIBS) add_definitions(${${pkg}_CFLAGS_OTHERS}) endforeach(pkg) else (USESYSTEMLIBS) - if (LINUX OR WINDOWS) + if (LINUX) use_prebuilt_binary(gtk-atk-pango-glib) - endif (LINUX OR WINDOWS) + endif (LINUX) if (LINUX) set(UI_LIBRARIES diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 63e296b556d243085c40d2c4ceb59522a60b1d4b..e8698ace68f47cfd06992882f461f35e14abaf88 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -9,6 +9,12 @@ # LINUX - Linux # WINDOWS - Windows +# Switches set here and in 00-Common.cmake must agree with +# https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables +# Reading $LL_BUILD is an attempt to directly use those switches. +if ("$ENV{LL_BUILD}" STREQUAL "") + message(FATAL_ERROR "Environment variable LL_BUILD must be set") +endif () # Relative and absolute paths to subtrees. @@ -60,46 +66,55 @@ if (NOT CMAKE_BUILD_TYPE) "Build type. One of: Debug Release RelWithDebInfo" FORCE) endif (NOT CMAKE_BUILD_TYPE) +# If someone has specified an address size, use that to determine the +# architecture. Otherwise, let the architecture specify the address size. +if (ADDRESS_SIZE EQUAL 32) + #message(STATUS "ADDRESS_SIZE is 32") + set(ARCH i686) +elseif (ADDRESS_SIZE EQUAL 64) + #message(STATUS "ADDRESS_SIZE is 64") + set(ARCH x86_64) +else (ADDRESS_SIZE EQUAL 32) + #message(STATUS "ADDRESS_SIZE is UNRECOGNIZED: '${ADDRESS_SIZE}'") + # Use Python's platform.machine() since uname -m isn't available everywhere. + # Even if you can assume cygwin uname -m, the answer depends on whether + # you're running 32-bit cygwin or 64-bit cygwin! But even 32-bit Python will + # report a 64-bit processor. + execute_process(COMMAND + "${PYTHON_EXECUTABLE}" "-c" + "import platform; print platform.machine()" + OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE) + # We expect values of the form i386, i686, x86_64, AMD64. + # In CMake, expressing ARCH.endswith('64') is awkward: + string(LENGTH "${ARCH}" ARCH_LENGTH) + math(EXPR ARCH_LEN_2 "${ARCH_LENGTH} - 2") + string(SUBSTRING "${ARCH}" ${ARCH_LEN_2} 2 ARCH_LAST_2) + if (ARCH_LAST_2 STREQUAL 64) + #message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}") + set(ADDRESS_SIZE 64) + else () + #message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}") + set(ADDRESS_SIZE 32) + endif () +endif (ADDRESS_SIZE EQUAL 32) + if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(WINDOWS ON BOOL FORCE) - set(ARCH i686) set(LL_ARCH ${ARCH}_win32) set(LL_ARCH_DIR ${ARCH}-win32) - set(WORD_SIZE 32) endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(LINUX ON BOOl FORCE) - # If someone has specified a word size, use that to determine the - # architecture. Otherwise, let the architecture specify the word size. - if (WORD_SIZE EQUAL 32) - #message(STATUS "WORD_SIZE is 32") - set(ARCH i686) - elseif (WORD_SIZE EQUAL 64) - #message(STATUS "WORD_SIZE is 64") - set(ARCH x86_64) - else (WORD_SIZE EQUAL 32) - #message(STATUS "WORD_SIZE is UNDEFINED") - execute_process(COMMAND uname -m COMMAND sed s/i.86/i686/ - OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE) - if (ARCH STREQUAL x86_64) - #message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}") - set(WORD_SIZE 64) - else (ARCH STREQUAL x86_64) - #message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}") - set(WORD_SIZE 32) - endif (ARCH STREQUAL x86_64) - endif (WORD_SIZE EQUAL 32) - - if (WORD_SIZE EQUAL 32) + if (ADDRESS_SIZE EQUAL 32) set(DEB_ARCHITECTURE i386) set(FIND_LIBRARY_USE_LIB64_PATHS OFF) set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib32 ${CMAKE_SYSTEM_LIBRARY_PATH}) - else (WORD_SIZE EQUAL 32) + else (ADDRESS_SIZE EQUAL 32) set(DEB_ARCHITECTURE amd64) set(FIND_LIBRARY_USE_LIB64_PATHS ON) - endif (WORD_SIZE EQUAL 32) + endif (ADDRESS_SIZE EQUAL 32) execute_process(COMMAND dpkg-architecture -a${DEB_ARCHITECTURE} -qDEB_HOST_MULTIARCH RESULT_VARIABLE DPKG_RESULT @@ -129,29 +144,45 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(DARWIN 1) - - # now we only support Xcode 7.0 using 10.11 (El Capitan), minimum OS 10.7 (Lion) + + string(REGEX MATCH "-mmacosx-version-min=([^ ]+)" scratch "$ENV{LL_BUILD}") + set(CMAKE_OSX_DEPLOYMENT_TARGET "${CMAKE_MATCH_1}") + message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET = '${CMAKE_OSX_DEPLOYMENT_TARGET}'") + + string(REGEX MATCH "-stdlib=([^ ]+)" scratch "$ENV{LL_BUILD}") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "${CMAKE_MATCH_1}") + message(STATUS "CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY = '${CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY}'") + + string(REGEX MATCH " -g([^ ]*)" scratch "$ENV{LL_BUILD}") + set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "${CMAKE_MATCH_1}") + message(STATUS "CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT = '${CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT}'") + + string(REGEX MATCH "-O([^ ]*)" scratch "$ENV{LL_BUILD}") + set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL "${CMAKE_MATCH_1}") + message(STATUS "CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL = '${CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL}'") + + string(REGEX MATCHALL "[^ ]+" LL_BUILD_LIST "$ENV{LL_BUILD}") + list(FIND LL_BUILD_LIST "-iwithsysroot" sysroot_idx) + if ("${sysroot_idx}" LESS 0) + message(FATAL_ERROR "Environment variable LL_BUILD must contain '-iwithsysroot'") + endif () + math(EXPR sysroot_idx "${sysroot_idx} + 1") + list(GET LL_BUILD_LIST "${sysroot_idx}" CMAKE_OSX_SYSROOT) + message(STATUS "CMAKE_OSX_SYSROOT = '${CMAKE_OSX_SYSROOT}'") + set(XCODE_VERSION 7.0) - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7) - set(CMAKE_OSX_SYSROOT macosx10.11) set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0") - set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL 3) set(CMAKE_XCODE_ATTRIBUTE_GCC_STRICT_ALIASING NO) set(CMAKE_XCODE_ATTRIBUTE_GCC_FAST_MATH NO) set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS ssse3) - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libstdc++") - set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym) - # Build only for i386 by default, system default on MacOSX 10.6+ is x86_64 - if (NOT CMAKE_OSX_ARCHITECTURES) - set(CMAKE_OSX_ARCHITECTURES "i386") - endif (NOT CMAKE_OSX_ARCHITECTURES) + set(CMAKE_OSX_ARCHITECTURES "${ARCH}") + string(REPLACE "i686" "i386" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") + string(REPLACE "AMD64" "x86_64" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") - set(ARCH ${CMAKE_OSX_ARCHITECTURES}) set(LL_ARCH ${ARCH}_darwin) set(LL_ARCH_DIR universal-darwin) - set(WORD_SIZE 32) endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # Default deploy grid diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index fdbb0a75f7128fcb33c3a7e12bbf43460f7fe336..f02c5e98b430c3c0b9f2034adac5834511cd8138 100755 --- a/indra/cmake/run_build_test.py +++ b/indra/cmake/run_build_test.py @@ -51,11 +51,13 @@ import re import signal import subprocess +import logging -def main(command, libpath=[], vars={}): +def main(command, arguments=[], libpath=[], vars={}): """Pass: - command is a sequence (e.g. a list) of strings. The first item in the list - must be the command name, the rest are its arguments. + command is the command to be executed + + argument is a sequence (e.g. a list) of strings to be passed to command libpath is a sequence of directory pathnames. These will be appended to the platform-specific dynamic library search path environment variable. @@ -85,7 +87,7 @@ def main(command, libpath=[], vars={}): # might not exist; instead of KeyError, just use an empty string. dirs = os.environ.get(var, "").split(os.pathsep) # Append the sequence in libpath - print "%s += %r" % (var, libpath) + log.info("%s += %r" % (var, libpath)) for dir in libpath: # append system paths at the end if dir in ('/lib', '/usr/lib'): @@ -103,20 +105,20 @@ def main(command, libpath=[], vars={}): # Now rebuild the path string. This way we use a minimum of separators # -- and we avoid adding a pointless separator when libpath is empty. os.environ[var] = os.pathsep.join(clean_dirs) - print "%s = %r" % (var, os.environ[var]) + log.info("%s = %r" % (var, os.environ[var])) # Now handle arbitrary environment variables. The tricky part is ensuring # that all the keys and values we try to pass are actually strings. if vars: - print "Setting:" - for key, value in vars.iteritems(): - print "%s=%s" % (key, value) + log.info("Setting: %s" % ("\n".join(["%s=%s" % (key, value) for key, value in vars.iteritems()]))) os.environ.update(dict([(str(key), str(value)) for key, value in vars.iteritems()])) # Run the child process. - print "Running: %s" % " ".join(command) + command_list = [command] + command_list.extend(arguments) + log.info("Running: %s" % " ".join(command_list)) # Make sure we see all relevant output *before* child-process output. sys.stdout.flush() try: - return subprocess.call(command) + return subprocess.call(command_list) except OSError as err: # If the caller is trying to execute a test program that doesn't # exist, we want to produce a reasonable error message rather than a @@ -126,9 +128,9 @@ def main(command, libpath=[], vars={}): if err.errno != errno.ENOENT: raise # In practice, the pathnames into CMake's build tree are so long as to - # obscure the name of the test program. Just print its basename. - print "No such program %s; check for preceding build errors" % \ - os.path.basename(command[0]) + # obscure the name of the test program. Just log its basename. + log.warn("No such program %s; check for preceding build errors" % \ + os.path.basename(command[0])) # What rc should we simulate for missing executable? Windows produces # 9009. return 9009 @@ -172,10 +174,10 @@ def translate_rc(rc): table = get_windows_table() symbol, desc = table[hexrc] except Exception, err: - print >>sys.stderr, "(%s -- carrying on)" % err - return "terminated with rc %s (%s)" % (rc, hexrc) + log.error("(%s -- carrying on)" % err) + log.error("terminated with rc %s (%s)" % (rc, hexrc)) else: - return "terminated with rc %s: %s: %s" % (hexrc, symbol, desc) + log.info("terminated with rc %s: %s: %s" % (hexrc, symbol, desc)) else: # On Posix, negative rc means the child was terminated by signal -rc. @@ -303,22 +305,26 @@ def get_windows_table(): return _windows_table +log=logging.getLogger(__name__) +logging.basicConfig() + if __name__ == "__main__": - from optparse import OptionParser - parser = OptionParser(usage="usage: %prog [options] command args...") - # We want optparse support for the options we ourselves handle -- but we - # DO NOT want it looking at options for the executable we intend to run, - # rejecting them as invalid because we don't define them. So configure the - # parser to stop looking for options as soon as it sees the first - # positional argument (traditional Unix syntax). - parser.disable_interspersed_args() - parser.add_option("-D", "--define", dest="vars", default=[], action="append", - metavar="VAR=value", - help="Add VAR=value to the env variables defined") - parser.add_option("-l", "--libpath", dest="libpath", default=[], action="append", - metavar="DIR", - help="Add DIR to the platform-dependent DLL search path") - opts, args = parser.parse_args() + import argparse + parser = argparse.ArgumentParser() + parser.add_argument("-d", "--debug", dest="loglevel", action="store_const", + const=logging.DEBUG, default=logging.WARNING) + parser.add_argument("-D", "--define", dest="vars", default=[], action="append", + metavar="VAR=value", + help="Add VAR=value to the env variables defined") + parser.add_argument("-l", "--libpath", dest="libpath", default=[], action="append", + metavar="DIR", + help="Add DIR to the platform-dependent DLL search path") + parser.add_argument("command") + parser.add_argument('args', nargs=argparse.REMAINDER) + args = parser.parse_args() + + log.setLevel(args.loglevel) + # What we have in opts.vars is a list of strings of the form "VAR=value" # or possibly just "VAR". What we want is a dict. We can build that dict by # constructing a list of ["VAR", "value"] pairs -- so split each @@ -326,9 +332,9 @@ def get_windows_table(): # "VAR=some=user=string"). To handle the case of just "VAR", append "" to # the list returned by split(), then slice off anything after the pair we # want. - rc = main(command=args, libpath=opts.libpath, - vars=dict([(pair.split('=', 1) + [""])[:2] for pair in opts.vars])) + rc = main(command=args.command, arguments=args.args, libpath=args.libpath, + vars=dict([(pair.split('=', 1) + [""])[:2] for pair in args.vars])) if rc not in (None, 0): - print >>sys.stderr, "Failure running: %s" % " ".join(args) - print >>sys.stderr, "Error %s: %s" % (rc, translate_rc(rc)) + log.error("Failure running: %s" % " ".join([args.command] + args.args)) + log.error("Error %s: %s" % (rc, translate_rc(rc))) sys.exit((rc < 0) and 255 or rc) diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt index 32aa08a2b71e3eae62d6f24c97ff585f67bac9d4..9f9ca6c39c990d535e37755422678182cca8a7c3 100644 --- a/indra/edit-me-to-trigger-new-build.txt +++ b/indra/edit-me-to-trigger-new-build.txt @@ -1,3 +1,4 @@ 2014-02-25 10:34 + diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt index 8a83ac498fea67716035452cefeafb082eff2831..13cf1f7bde9014b85d0ff31272e38b7867a9f796 100644 --- a/indra/integration_tests/llimage_libtest/CMakeLists.txt +++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt @@ -104,21 +104,23 @@ add_custom_command(TARGET llimage_libtest POST_BUILD if (DARWIN) # Copy the required libraries to the package app add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib + COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} + DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib ) add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib + COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} + DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib ) add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib - ) - add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib + COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} + DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib ) + foreach(expat ${EXPAT_COPY}) + add_custom_command(TARGET llimage_libtest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} ${LLIMAGE_LIBTEST_DESTINATION_DIR} + DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} + ) + endforeach(expat) endif (DARWIN) if (WINDOWS) diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 3d27b4a5b548c6e699917e15b6888132e60631e0..f4dba16a944076e5e0cb784573b427323b7738c9 100644 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -42,6 +42,7 @@ #include "lldiriterator.h" #include "v4coloru.h" #include "llsdserialize.h" +#include "llcleanup.h" // system libraries #include <iostream> @@ -634,7 +635,7 @@ int main(int argc, char** argv) } // Cleanup and exit - LLImage::cleanupClass(); + SUBSYSTEM_CLEANUP(LLImage); if (fast_timer_log_thread) { fast_timer_log_thread->shutdown(); diff --git a/indra/lib/python/indra/base/__init__.py b/indra/lib/python/indra/base/__init__.py deleted file mode 100755 index 2904fd338018da1f291d954107f84f9d4da33aa6..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/base/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -"""\ -@file __init__.py -@brief Initialization file for the indra.base module. - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" diff --git a/indra/lib/python/indra/base/cllsd_test.py b/indra/lib/python/indra/base/cllsd_test.py deleted file mode 100755 index 1f06898ffd83f828ad6062cea9628ba162f236da..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/base/cllsd_test.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/python -## -## $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$ -from indra.base import llsd, lluuid -from datetime import datetime -import cllsd -import time, sys - -class myint(int): - pass - -values = ( - '&<>', - u'\u81acj', - llsd.uri('http://foo<'), - lluuid.UUID(), - llsd.LLSD(['thing']), - 1, - myint(31337), - sys.maxint + 10, - llsd.binary('foo'), - [], - {}, - {u'f&\u1212': 3}, - 3.1, - True, - None, - datetime.fromtimestamp(time.time()), - ) - -def valuator(values): - for v in values: - yield v - -longvalues = () # (values, list(values), iter(values), valuator(values)) - -for v in values + longvalues: - print '%r => %r' % (v, cllsd.llsd_to_xml(v)) - -a = [[{'a':3}]] * 1000000 - -s = time.time() -print hash(cllsd.llsd_to_xml(a)) -e = time.time() -t1 = e - s -print t1 - -s = time.time() -print hash(llsd.LLSDXMLFormatter()._format(a)) -e = time.time() -t2 = e - s -print t2 - -print 'Speedup:', t2 / t1 diff --git a/indra/lib/python/indra/base/config.py b/indra/lib/python/indra/base/config.py deleted file mode 100755 index adafa29b518ed019d07d7013b8dc266945f6eff4..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/base/config.py +++ /dev/null @@ -1,266 +0,0 @@ -"""\ -@file config.py -@brief Utility module for parsing and accessing the indra.xml config file. - -$LicenseInfo:firstyear=2006&license=mit$ - -Copyright (c) 2006-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import copy -import errno -import os -import traceback -import time -import types - -from os.path import dirname, getmtime, join, realpath -from indra.base import llsd - -_g_config = None - -class IndraConfig(object): - """ - IndraConfig loads a 'indra' xml configuration file - and loads into memory. This representation in memory - can get updated to overwrite values or add new values. - - The xml configuration file is considered a live file and changes - to the file are checked and reloaded periodically. If a value had - been overwritten via the update or set method, the loaded values - from the file are ignored (the values from the update/set methods - override) - """ - def __init__(self, indra_config_file): - self._indra_config_file = indra_config_file - self._reload_check_interval = 30 # seconds - self._last_check_time = 0 - self._last_mod_time = 0 - - self._config_overrides = {} - self._config_file_dict = {} - self._combined_dict = {} - - self._load() - - def _load(self): - # if you initialize the IndraConfig with None, no attempt - # is made to load any files - if self._indra_config_file is None: - return - - config_file = open(self._indra_config_file) - self._config_file_dict = llsd.parse(config_file.read()) - self._combine_dictionaries() - config_file.close() - - self._last_mod_time = self._get_last_modified_time() - self._last_check_time = time.time() # now - - def _get_last_modified_time(self): - """ - Returns the mtime (last modified time) of the config file, - if such exists. - """ - if self._indra_config_file is not None: - return os.path.getmtime(self._indra_config_file) - - return 0 - - def _combine_dictionaries(self): - self._combined_dict = {} - self._combined_dict.update(self._config_file_dict) - self._combined_dict.update(self._config_overrides) - - def _reload_if_necessary(self): - now = time.time() - - if (now - self._last_check_time) > self._reload_check_interval: - self._last_check_time = now - try: - modtime = self._get_last_modified_time() - if modtime > self._last_mod_time: - self._load() - except OSError, e: - if e.errno == errno.ENOENT: # file not found - # someone messed with our internal state - # or removed the file - - print 'WARNING: Configuration file has been removed ' + (self._indra_config_file) - print 'Disabling reloading of configuration file.' - - traceback.print_exc() - - self._indra_config_file = None - self._last_check_time = 0 - self._last_mod_time = 0 - else: - raise # pass the exception along to the caller - - def __getitem__(self, key): - self._reload_if_necessary() - - return self._combined_dict[key] - - def get(self, key, default = None): - try: - return self.__getitem__(key) - except KeyError: - return default - - def __setitem__(self, key, value): - """ - Sets the value of the config setting of key to be newval - - Once any key/value pair is changed via the set method, - that key/value pair will remain set with that value until - change via the update or set method - """ - self._config_overrides[key] = value - self._combine_dictionaries() - - def set(self, key, newval): - return self.__setitem__(key, newval) - - def update(self, new_conf): - """ - Load an XML file and apply its map as overrides or additions - to the existing config. Update can be a file or a dict. - - Once any key/value pair is changed via the update method, - that key/value pair will remain set with that value until - change via the update or set method - """ - if isinstance(new_conf, dict): - overrides = new_conf - else: - # assuming that it is a filename - config_file = open(new_conf) - overrides = llsd.parse(config_file.read()) - config_file.close() - - self._config_overrides.update(overrides) - self._combine_dictionaries() - - def as_dict(self): - """ - Returns immutable copy of the IndraConfig as a dictionary - """ - return copy.deepcopy(self._combined_dict) - -def load(config_xml_file = None): - global _g_config - - load_default_files = config_xml_file is None - if load_default_files: - ## going from: - ## "/opt/linden/indra/lib/python/indra/base/config.py" - ## to: - ## "/opt/linden/etc/indra.xml" - config_xml_file = realpath( - dirname(realpath(__file__)) + "../../../../../../etc/indra.xml") - - try: - _g_config = IndraConfig(config_xml_file) - except IOError: - # Failure to load passed in file - # or indra.xml default file - if load_default_files: - try: - config_xml_file = realpath( - dirname(realpath(__file__)) + "../../../../../../etc/globals.xml") - _g_config = IndraConfig(config_xml_file) - return - except IOError: - # Failure to load globals.xml - # fall to code below - pass - - # Either failed to load passed in file - # or failed to load all default files - _g_config = IndraConfig(None) - -def dump(indra_xml_file, indra_cfg = None, update_in_mem=False): - ''' - Dump config contents into a file - Kindof reverse of load. - Optionally takes a new config to dump. - Does NOT update global config unless requested. - ''' - global _g_config - - if not indra_cfg: - if _g_config is None: - return - - indra_cfg = _g_config.as_dict() - - if not indra_cfg: - return - - config_file = open(indra_xml_file, 'w') - _config_xml = llsd.format_xml(indra_cfg) - config_file.write(_config_xml) - config_file.close() - - if update_in_mem: - update(indra_cfg) - -def update(new_conf): - global _g_config - - if _g_config is None: - # To keep with how this function behaved - # previously, a call to update - # before the global is defined - # make a new global config which does not - # load data from a file. - _g_config = IndraConfig(None) - - return _g_config.update(new_conf) - -def get(key, default = None): - global _g_config - - if _g_config is None: - load() - - return _g_config.get(key, default) - -def set(key, newval): - """ - Sets the value of the config setting of key to be newval - - Once any key/value pair is changed via the set method, - that key/value pair will remain set with that value until - change via the update or set method or program termination - """ - global _g_config - - if _g_config is None: - _g_config = IndraConfig(None) - - _g_config.set(key, newval) - -def get_config(): - global _g_config - return _g_config diff --git a/indra/lib/python/indra/base/llsd.py b/indra/lib/python/indra/base/llsd.py deleted file mode 100755 index 4527b115f9ad07b6a2f9180090466c2f562112a1..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/base/llsd.py +++ /dev/null @@ -1,1052 +0,0 @@ -"""\ -@file llsd.py -@brief Types as well as parsing and formatting functions for handling LLSD. - -$LicenseInfo:firstyear=2006&license=mit$ - -Copyright (c) 2006-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import datetime -import base64 -import string -import struct -import time -import types -import re - -from indra.util.fastest_elementtree import ElementTreeError, fromstring -from indra.base import lluuid - -# cllsd.c in server/server-1.25 has memory leaks, -# so disabling cllsd for now -#try: -# import cllsd -#except ImportError: -# cllsd = None -cllsd = None - -int_regex = re.compile(r"[-+]?\d+") -real_regex = re.compile(r"[-+]?(\d+(\.\d*)?|\d*\.\d+)([eE][-+]?\d+)?") -alpha_regex = re.compile(r"[a-zA-Z]+") -date_regex = re.compile(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})T" - r"(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})" - r"(?P<second_float>(\.\d+)?)Z") -#date: d"YYYY-MM-DDTHH:MM:SS.FFFFFFZ" - -class LLSDParseError(Exception): - pass - -class LLSDSerializationError(TypeError): - pass - - -class binary(str): - pass - -class uri(str): - pass - - -BOOL_TRUE = ('1', '1.0', 'true') -BOOL_FALSE = ('0', '0.0', 'false', '') - - -def format_datestr(v): - """ Formats a datetime or date object into the string format shared by xml and notation serializations.""" - if hasattr(v, 'microsecond'): - return v.isoformat() + 'Z' - else: - return v.strftime('%Y-%m-%dT%H:%M:%SZ') - -def parse_datestr(datestr): - """Parses a datetime object from the string format shared by xml and notation serializations.""" - if datestr == "": - return datetime.datetime(1970, 1, 1) - - match = re.match(date_regex, datestr) - if not match: - raise LLSDParseError("invalid date string '%s'." % datestr) - - year = int(match.group('year')) - month = int(match.group('month')) - day = int(match.group('day')) - hour = int(match.group('hour')) - minute = int(match.group('minute')) - second = int(match.group('second')) - seconds_float = match.group('second_float') - microsecond = 0 - if seconds_float: - microsecond = int(float('0' + seconds_float) * 1e6) - return datetime.datetime(year, month, day, hour, minute, second, microsecond) - - -def bool_to_python(node): - val = node.text or '' - if val in BOOL_TRUE: - return True - else: - return False - -def int_to_python(node): - val = node.text or '' - if not val.strip(): - return 0 - return int(val) - -def real_to_python(node): - val = node.text or '' - if not val.strip(): - return 0.0 - return float(val) - -def uuid_to_python(node): - return lluuid.UUID(node.text) - -def str_to_python(node): - return node.text or '' - -def bin_to_python(node): - return binary(base64.decodestring(node.text or '')) - -def date_to_python(node): - val = node.text or '' - if not val: - val = "1970-01-01T00:00:00Z" - return parse_datestr(val) - - -def uri_to_python(node): - val = node.text or '' - if not val: - return None - return uri(val) - -def map_to_python(node): - result = {} - for index in range(len(node))[::2]: - result[node[index].text] = to_python(node[index+1]) - return result - -def array_to_python(node): - return [to_python(child) for child in node] - - -NODE_HANDLERS = dict( - undef=lambda x: None, - boolean=bool_to_python, - integer=int_to_python, - real=real_to_python, - uuid=uuid_to_python, - string=str_to_python, - binary=bin_to_python, - date=date_to_python, - uri=uri_to_python, - map=map_to_python, - array=array_to_python, - ) - -def to_python(node): - return NODE_HANDLERS[node.tag](node) - -class Nothing(object): - pass - - -class LLSDXMLFormatter(object): - def __init__(self): - self.type_map = { - type(None) : self.UNDEF, - bool : self.BOOLEAN, - int : self.INTEGER, - long : self.INTEGER, - float : self.REAL, - lluuid.UUID : self.UUID, - binary : self.BINARY, - str : self.STRING, - unicode : self.STRING, - uri : self.URI, - datetime.datetime : self.DATE, - datetime.date : self.DATE, - list : self.ARRAY, - tuple : self.ARRAY, - types.GeneratorType : self.ARRAY, - dict : self.MAP, - LLSD : self.LLSD - } - - def elt(self, name, contents=None): - if(contents is None or contents is ''): - return "<%s />" % (name,) - else: - if type(contents) is unicode: - contents = contents.encode('utf-8') - return "<%s>%s</%s>" % (name, contents, name) - - def xml_esc(self, v): - if type(v) is unicode: - v = v.encode('utf-8') - return v.replace('&', '&').replace('<', '<').replace('>', '>') - - def LLSD(self, v): - return self.generate(v.thing) - def UNDEF(self, v): - return self.elt('undef') - def BOOLEAN(self, v): - if v: - return self.elt('boolean', 'true') - else: - return self.elt('boolean', 'false') - def INTEGER(self, v): - return self.elt('integer', v) - def REAL(self, v): - return self.elt('real', v) - def UUID(self, v): - if(v.isNull()): - return self.elt('uuid') - else: - return self.elt('uuid', v) - def BINARY(self, v): - return self.elt('binary', base64.encodestring(v)) - def STRING(self, v): - return self.elt('string', self.xml_esc(v)) - def URI(self, v): - return self.elt('uri', self.xml_esc(str(v))) - def DATE(self, v): - return self.elt('date', format_datestr(v)) - def ARRAY(self, v): - return self.elt('array', ''.join([self.generate(item) for item in v])) - def MAP(self, v): - return self.elt( - 'map', - ''.join(["%s%s" % (self.elt('key', self.xml_esc(str(key))), self.generate(value)) - for key, value in v.items()])) - - typeof = type - def generate(self, something): - t = self.typeof(something) - if self.type_map.has_key(t): - return self.type_map[t](something) - else: - raise LLSDSerializationError("Cannot serialize unknown type: %s (%s)" % ( - t, something)) - - def _format(self, something): - return '<?xml version="1.0" ?>' + self.elt("llsd", self.generate(something)) - - def format(self, something): - if cllsd: - return cllsd.llsd_to_xml(something) - return self._format(something) - -_g_xml_formatter = None -def format_xml(something): - global _g_xml_formatter - if _g_xml_formatter is None: - _g_xml_formatter = LLSDXMLFormatter() - return _g_xml_formatter.format(something) - -class LLSDXMLPrettyFormatter(LLSDXMLFormatter): - def __init__(self, indent_atom = None): - # Call the super class constructor so that we have the type map - super(LLSDXMLPrettyFormatter, self).__init__() - - # Override the type map to use our specialized formatters to - # emit the pretty output. - self.type_map[list] = self.PRETTY_ARRAY - self.type_map[tuple] = self.PRETTY_ARRAY - self.type_map[types.GeneratorType] = self.PRETTY_ARRAY, - self.type_map[dict] = self.PRETTY_MAP - - # Private data used for indentation. - self._indent_level = 1 - if indent_atom is None: - self._indent_atom = ' ' - else: - self._indent_atom = indent_atom - - def _indent(self): - "Return an indentation based on the atom and indentation level." - return self._indent_atom * self._indent_level - - def PRETTY_ARRAY(self, v): - rv = [] - rv.append('<array>\n') - self._indent_level = self._indent_level + 1 - rv.extend(["%s%s\n" % - (self._indent(), - self.generate(item)) - for item in v]) - self._indent_level = self._indent_level - 1 - rv.append(self._indent()) - rv.append('</array>') - return ''.join(rv) - - def PRETTY_MAP(self, v): - rv = [] - rv.append('<map>\n') - self._indent_level = self._indent_level + 1 - keys = v.keys() - keys.sort() - rv.extend(["%s%s\n%s%s\n" % - (self._indent(), - self.elt('key', key), - self._indent(), - self.generate(v[key])) - for key in keys]) - self._indent_level = self._indent_level - 1 - rv.append(self._indent()) - rv.append('</map>') - return ''.join(rv) - - def format(self, something): - data = [] - data.append('<?xml version="1.0" ?>\n<llsd>') - data.append(self.generate(something)) - data.append('</llsd>\n') - return '\n'.join(data) - -def format_pretty_xml(something): - """@brief Serialize a python object as 'pretty' llsd xml. - - The output conforms to the LLSD DTD, unlike the output from the - standard python xml.dom DOM::toprettyxml() method which does not - preserve significant whitespace. - This function is not necessarily suited for serializing very large - objects. It is not optimized by the cllsd module, and sorts on - dict (llsd map) keys alphabetically to ease human reading. - """ - return LLSDXMLPrettyFormatter().format(something) - -class LLSDNotationFormatter(object): - def __init__(self): - self.type_map = { - type(None) : self.UNDEF, - bool : self.BOOLEAN, - int : self.INTEGER, - long : self.INTEGER, - float : self.REAL, - lluuid.UUID : self.UUID, - binary : self.BINARY, - str : self.STRING, - unicode : self.STRING, - uri : self.URI, - datetime.datetime : self.DATE, - datetime.date : self.DATE, - list : self.ARRAY, - tuple : self.ARRAY, - types.GeneratorType : self.ARRAY, - dict : self.MAP, - LLSD : self.LLSD - } - - def LLSD(self, v): - return self.generate(v.thing) - def UNDEF(self, v): - return '!' - def BOOLEAN(self, v): - if v: - return 'true' - else: - return 'false' - def INTEGER(self, v): - return "i%s" % v - def REAL(self, v): - return "r%s" % v - def UUID(self, v): - return "u%s" % v - def BINARY(self, v): - return 'b64"' + base64.encodestring(v) + '"' - def STRING(self, v): - if isinstance(v, unicode): - v = v.encode('utf-8') - return "'%s'" % v.replace("\\", "\\\\").replace("'", "\\'") - def URI(self, v): - return 'l"%s"' % str(v).replace("\\", "\\\\").replace('"', '\\"') - def DATE(self, v): - return 'd"%s"' % format_datestr(v) - def ARRAY(self, v): - return "[%s]" % ','.join([self.generate(item) for item in v]) - def MAP(self, v): - def fix(key): - if isinstance(key, unicode): - return key.encode('utf-8') - return key - return "{%s}" % ','.join(["'%s':%s" % (fix(key).replace("\\", "\\\\").replace("'", "\\'"), self.generate(value)) - for key, value in v.items()]) - - def generate(self, something): - t = type(something) - handler = self.type_map.get(t) - if handler: - return handler(something) - else: - try: - return self.ARRAY(iter(something)) - except TypeError: - raise LLSDSerializationError( - "Cannot serialize unknown type: %s (%s)" % (t, something)) - - def format(self, something): - return self.generate(something) - -def format_notation(something): - return LLSDNotationFormatter().format(something) - -def _hex_as_nybble(hex): - if (hex >= '0') and (hex <= '9'): - return ord(hex) - ord('0') - elif (hex >= 'a') and (hex <='f'): - return 10 + ord(hex) - ord('a') - elif (hex >= 'A') and (hex <='F'): - return 10 + ord(hex) - ord('A'); - -class LLSDBinaryParser(object): - def __init__(self): - pass - - def parse(self, buffer, ignore_binary = False): - """ - This is the basic public interface for parsing. - - @param buffer the binary data to parse in an indexable sequence. - @param ignore_binary parser throws away data in llsd binary nodes. - @return returns a python object. - """ - self._buffer = buffer - self._index = 0 - self._keep_binary = not ignore_binary - return self._parse() - - def _parse(self): - cc = self._buffer[self._index] - self._index += 1 - if cc == '{': - return self._parse_map() - elif cc == '[': - return self._parse_array() - elif cc == '!': - return None - elif cc == '0': - return False - elif cc == '1': - return True - elif cc == 'i': - # 'i' = integer - idx = self._index - self._index += 4 - return struct.unpack("!i", self._buffer[idx:idx+4])[0] - elif cc == ('r'): - # 'r' = real number - idx = self._index - self._index += 8 - return struct.unpack("!d", self._buffer[idx:idx+8])[0] - elif cc == 'u': - # 'u' = uuid - idx = self._index - self._index += 16 - return lluuid.uuid_bits_to_uuid(self._buffer[idx:idx+16]) - elif cc == 's': - # 's' = string - return self._parse_string() - elif cc in ("'", '"'): - # delimited/escaped string - return self._parse_string_delim(cc) - elif cc == 'l': - # 'l' = uri - return uri(self._parse_string()) - elif cc == ('d'): - # 'd' = date in seconds since epoch - idx = self._index - self._index += 8 - seconds = struct.unpack("!d", self._buffer[idx:idx+8])[0] - return datetime.datetime.fromtimestamp(seconds) - elif cc == 'b': - binary = self._parse_string() - if self._keep_binary: - return binary - # *NOTE: maybe have a binary placeholder which has the - # length. - return None - else: - raise LLSDParseError("invalid binary token at byte %d: %d" % ( - self._index - 1, ord(cc))) - - def _parse_map(self): - rv = {} - size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0] - self._index += 4 - count = 0 - cc = self._buffer[self._index] - self._index += 1 - key = '' - while (cc != '}') and (count < size): - if cc == 'k': - key = self._parse_string() - elif cc in ("'", '"'): - key = self._parse_string_delim(cc) - else: - raise LLSDParseError("invalid map key at byte %d." % ( - self._index - 1,)) - value = self._parse() - rv[key] = value - count += 1 - cc = self._buffer[self._index] - self._index += 1 - if cc != '}': - raise LLSDParseError("invalid map close token at byte %d." % ( - self._index,)) - return rv - - def _parse_array(self): - rv = [] - size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0] - self._index += 4 - count = 0 - cc = self._buffer[self._index] - while (cc != ']') and (count < size): - rv.append(self._parse()) - count += 1 - cc = self._buffer[self._index] - if cc != ']': - raise LLSDParseError("invalid array close token at byte %d." % ( - self._index,)) - self._index += 1 - return rv - - def _parse_string(self): - size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0] - self._index += 4 - rv = self._buffer[self._index:self._index+size] - self._index += size - return rv - - def _parse_string_delim(self, delim): - list = [] - found_escape = False - found_hex = False - found_digit = False - byte = 0 - while True: - cc = self._buffer[self._index] - self._index += 1 - if found_escape: - if found_hex: - if found_digit: - found_escape = False - found_hex = False - found_digit = False - byte <<= 4 - byte |= _hex_as_nybble(cc) - list.append(chr(byte)) - byte = 0 - else: - found_digit = True - byte = _hex_as_nybble(cc) - elif cc == 'x': - found_hex = True - else: - if cc == 'a': - list.append('\a') - elif cc == 'b': - list.append('\b') - elif cc == 'f': - list.append('\f') - elif cc == 'n': - list.append('\n') - elif cc == 'r': - list.append('\r') - elif cc == 't': - list.append('\t') - elif cc == 'v': - list.append('\v') - else: - list.append(cc) - found_escape = False - elif cc == '\\': - found_escape = True - elif cc == delim: - break - else: - list.append(cc) - return ''.join(list) - -class LLSDNotationParser(object): - """ Parse LLSD notation: - map: { string:object, string:object } - array: [ object, object, object ] - undef: ! - boolean: true | false | 1 | 0 | T | F | t | f | TRUE | FALSE - integer: i#### - real: r#### - uuid: u#### - string: "g\'day" | 'have a "nice" day' | s(size)"raw data" - uri: l"escaped" - date: d"YYYY-MM-DDTHH:MM:SS.FFZ" - binary: b##"ff3120ab1" | b(size)"raw data" - """ - def __init__(self): - pass - - def parse(self, buffer, ignore_binary = False): - """ - This is the basic public interface for parsing. - - @param buffer the notation string to parse. - @param ignore_binary parser throws away data in llsd binary nodes. - @return returns a python object. - """ - if buffer == "": - return False - - self._buffer = buffer - self._index = 0 - return self._parse() - - def _parse(self): - cc = self._buffer[self._index] - self._index += 1 - if cc == '{': - return self._parse_map() - elif cc == '[': - return self._parse_array() - elif cc == '!': - return None - elif cc == '0': - return False - elif cc == '1': - return True - elif cc in ('F', 'f'): - self._skip_alpha() - return False - elif cc in ('T', 't'): - self._skip_alpha() - return True - elif cc == 'i': - # 'i' = integer - return self._parse_integer() - elif cc == ('r'): - # 'r' = real number - return self._parse_real() - elif cc == 'u': - # 'u' = uuid - return self._parse_uuid() - elif cc in ("'", '"', 's'): - return self._parse_string(cc) - elif cc == 'l': - # 'l' = uri - delim = self._buffer[self._index] - self._index += 1 - val = uri(self._parse_string(delim)) - if len(val) == 0: - return None - return val - elif cc == ('d'): - # 'd' = date in seconds since epoch - return self._parse_date() - elif cc == 'b': - return self._parse_binary() - else: - raise LLSDParseError("invalid token at index %d: %d" % ( - self._index - 1, ord(cc))) - - def _parse_binary(self): - i = self._index - if self._buffer[i:i+2] == '64': - q = self._buffer[i+2] - e = self._buffer.find(q, i+3) - try: - return base64.decodestring(self._buffer[i+3:e]) - finally: - self._index = e + 1 - else: - raise LLSDParseError('random horrible binary format not supported') - - def _parse_map(self): - """ map: { string:object, string:object } """ - rv = {} - cc = self._buffer[self._index] - self._index += 1 - key = '' - found_key = False - while (cc != '}'): - if not found_key: - if cc in ("'", '"', 's'): - key = self._parse_string(cc) - found_key = True - elif cc.isspace() or cc == ',': - cc = self._buffer[self._index] - self._index += 1 - else: - raise LLSDParseError("invalid map key at byte %d." % ( - self._index - 1,)) - elif cc.isspace() or cc == ':': - cc = self._buffer[self._index] - self._index += 1 - continue - else: - self._index += 1 - value = self._parse() - rv[key] = value - found_key = False - cc = self._buffer[self._index] - self._index += 1 - - return rv - - def _parse_array(self): - """ array: [ object, object, object ] """ - rv = [] - cc = self._buffer[self._index] - while (cc != ']'): - if cc.isspace() or cc == ',': - self._index += 1 - cc = self._buffer[self._index] - continue - rv.append(self._parse()) - cc = self._buffer[self._index] - - if cc != ']': - raise LLSDParseError("invalid array close token at index %d." % ( - self._index,)) - self._index += 1 - return rv - - def _parse_uuid(self): - match = re.match(lluuid.UUID.uuid_regex, self._buffer[self._index:]) - if not match: - raise LLSDParseError("invalid uuid token at index %d." % self._index) - - (start, end) = match.span() - start += self._index - end += self._index - self._index = end - return lluuid.UUID(self._buffer[start:end]) - - def _skip_alpha(self): - match = re.match(alpha_regex, self._buffer[self._index:]) - if match: - self._index += match.end() - - def _parse_date(self): - delim = self._buffer[self._index] - self._index += 1 - datestr = self._parse_string(delim) - return parse_datestr(datestr) - - def _parse_real(self): - match = re.match(real_regex, self._buffer[self._index:]) - if not match: - raise LLSDParseError("invalid real token at index %d." % self._index) - - (start, end) = match.span() - start += self._index - end += self._index - self._index = end - return float( self._buffer[start:end] ) - - def _parse_integer(self): - match = re.match(int_regex, self._buffer[self._index:]) - if not match: - raise LLSDParseError("invalid integer token at index %d." % self._index) - - (start, end) = match.span() - start += self._index - end += self._index - self._index = end - return int( self._buffer[start:end] ) - - def _parse_string(self, delim): - """ string: "g\'day" | 'have a "nice" day' | s(size)"raw data" """ - rv = "" - - if delim in ("'", '"'): - rv = self._parse_string_delim(delim) - elif delim == 's': - rv = self._parse_string_raw() - else: - raise LLSDParseError("invalid string token at index %d." % self._index) - - return rv - - - def _parse_string_delim(self, delim): - """ string: "g'day 'un" | 'have a "nice" day' """ - list = [] - found_escape = False - found_hex = False - found_digit = False - byte = 0 - while True: - cc = self._buffer[self._index] - self._index += 1 - if found_escape: - if found_hex: - if found_digit: - found_escape = False - found_hex = False - found_digit = False - byte <<= 4 - byte |= _hex_as_nybble(cc) - list.append(chr(byte)) - byte = 0 - else: - found_digit = True - byte = _hex_as_nybble(cc) - elif cc == 'x': - found_hex = True - else: - if cc == 'a': - list.append('\a') - elif cc == 'b': - list.append('\b') - elif cc == 'f': - list.append('\f') - elif cc == 'n': - list.append('\n') - elif cc == 'r': - list.append('\r') - elif cc == 't': - list.append('\t') - elif cc == 'v': - list.append('\v') - else: - list.append(cc) - found_escape = False - elif cc == '\\': - found_escape = True - elif cc == delim: - break - else: - list.append(cc) - return ''.join(list) - - def _parse_string_raw(self): - """ string: s(size)"raw data" """ - # Read the (size) portion. - cc = self._buffer[self._index] - self._index += 1 - if cc != '(': - raise LLSDParseError("invalid string token at index %d." % self._index) - - rparen = self._buffer.find(')', self._index) - if rparen == -1: - raise LLSDParseError("invalid string token at index %d." % self._index) - - size = int(self._buffer[self._index:rparen]) - - self._index = rparen + 1 - delim = self._buffer[self._index] - self._index += 1 - if delim not in ("'", '"'): - raise LLSDParseError("invalid string token at index %d." % self._index) - - rv = self._buffer[self._index:(self._index + size)] - self._index += size - cc = self._buffer[self._index] - self._index += 1 - if cc != delim: - raise LLSDParseError("invalid string token at index %d." % self._index) - - return rv - -def format_binary(something): - return '<?llsd/binary?>\n' + _format_binary_recurse(something) - -def _format_binary_recurse(something): - def _format_list(something): - array_builder = [] - array_builder.append('[' + struct.pack('!i', len(something))) - for item in something: - array_builder.append(_format_binary_recurse(item)) - array_builder.append(']') - return ''.join(array_builder) - - if something is None: - return '!' - elif isinstance(something, LLSD): - return _format_binary_recurse(something.thing) - elif isinstance(something, bool): - if something: - return '1' - else: - return '0' - elif isinstance(something, (int, long)): - return 'i' + struct.pack('!i', something) - elif isinstance(something, float): - return 'r' + struct.pack('!d', something) - elif isinstance(something, lluuid.UUID): - return 'u' + something._bits - elif isinstance(something, binary): - return 'b' + struct.pack('!i', len(something)) + something - elif isinstance(something, str): - return 's' + struct.pack('!i', len(something)) + something - elif isinstance(something, unicode): - something = something.encode('utf-8') - return 's' + struct.pack('!i', len(something)) + something - elif isinstance(something, uri): - return 'l' + struct.pack('!i', len(something)) + something - elif isinstance(something, datetime.datetime): - seconds_since_epoch = time.mktime(something.timetuple()) - return 'd' + struct.pack('!d', seconds_since_epoch) - elif isinstance(something, (list, tuple)): - return _format_list(something) - elif isinstance(something, dict): - map_builder = [] - map_builder.append('{' + struct.pack('!i', len(something))) - for key, value in something.items(): - if isinstance(key, unicode): - key = key.encode('utf-8') - map_builder.append('k' + struct.pack('!i', len(key)) + key) - map_builder.append(_format_binary_recurse(value)) - map_builder.append('}') - return ''.join(map_builder) - else: - try: - return _format_list(list(something)) - except TypeError: - raise LLSDSerializationError( - "Cannot serialize unknown type: %s (%s)" % - (type(something), something)) - - -def parse_binary(binary): - if binary.startswith('<?llsd/binary?>'): - just_binary = binary.split('\n', 1)[1] - else: - just_binary = binary - return LLSDBinaryParser().parse(just_binary) - -def parse_xml(something): - try: - return to_python(fromstring(something)[0]) - except ElementTreeError, err: - raise LLSDParseError(*err.args) - -def parse_notation(something): - return LLSDNotationParser().parse(something) - -def parse(something): - try: - something = string.lstrip(something) #remove any pre-trailing whitespace - if something.startswith('<?llsd/binary?>'): - return parse_binary(something) - # This should be better. - elif something.startswith('<'): - return parse_xml(something) - else: - return parse_notation(something) - except KeyError, e: - raise Exception('LLSD could not be parsed: %s' % (e,)) - -class LLSD(object): - def __init__(self, thing=None): - self.thing = thing - - def __str__(self): - return self.toXML(self.thing) - - parse = staticmethod(parse) - toXML = staticmethod(format_xml) - toPrettyXML = staticmethod(format_pretty_xml) - toBinary = staticmethod(format_binary) - toNotation = staticmethod(format_notation) - - -undef = LLSD(None) - -XML_MIME_TYPE = 'application/llsd+xml' -BINARY_MIME_TYPE = 'application/llsd+binary' - -# register converters for llsd in mulib, if it is available -try: - from mulib import stacked, mu - stacked.NoProducer() # just to exercise stacked - mu.safe_load(None) # just to exercise mu -except: - # mulib not available, don't print an error message since this is normal - pass -else: - mu.add_parser(parse, XML_MIME_TYPE) - mu.add_parser(parse, 'application/llsd+binary') - - def llsd_convert_xml(llsd_stuff, request): - request.write(format_xml(llsd_stuff)) - - def llsd_convert_binary(llsd_stuff, request): - request.write(format_binary(llsd_stuff)) - - for typ in [LLSD, dict, list, tuple, str, int, long, float, bool, unicode, type(None)]: - stacked.add_producer(typ, llsd_convert_xml, XML_MIME_TYPE) - stacked.add_producer(typ, llsd_convert_xml, 'application/xml') - stacked.add_producer(typ, llsd_convert_xml, 'text/xml') - - stacked.add_producer(typ, llsd_convert_binary, 'application/llsd+binary') - - stacked.add_producer(LLSD, llsd_convert_xml, '*/*') - - # in case someone is using the legacy mu.xml wrapper, we need to - # tell mu to produce application/xml or application/llsd+xml - # (based on the accept header) from raw xml. Phoenix 2008-07-21 - stacked.add_producer(mu.xml, mu.produce_raw, XML_MIME_TYPE) - stacked.add_producer(mu.xml, mu.produce_raw, 'application/xml') - - - -# mulib wsgi stuff -# try: -# from mulib import mu, adapters -# -# # try some known attributes from mulib to be ultra-sure we've imported it -# mu.get_current -# adapters.handlers -# except: -# # mulib not available, don't print an error message since this is normal -# pass -# else: -# def llsd_xml_handler(content_type): -# def handle_llsd_xml(env, start_response): -# llsd_stuff, _ = mu.get_current(env) -# result = format_xml(llsd_stuff) -# start_response("200 OK", [('Content-Type', content_type)]) -# env['mu.negotiated_type'] = content_type -# yield result -# return handle_llsd_xml -# -# def llsd_binary_handler(content_type): -# def handle_llsd_binary(env, start_response): -# llsd_stuff, _ = mu.get_current(env) -# result = format_binary(llsd_stuff) -# start_response("200 OK", [('Content-Type', content_type)]) -# env['mu.negotiated_type'] = content_type -# yield result -# return handle_llsd_binary -# -# adapters.DEFAULT_PARSERS[XML_MIME_TYPE] = parse - -# for typ in [LLSD, dict, list, tuple, str, int, float, bool, unicode, type(None)]: -# for content_type in (XML_MIME_TYPE, 'application/xml'): -# adapters.handlers.set_handler(typ, llsd_xml_handler(content_type), content_type) -# -# adapters.handlers.set_handler(typ, llsd_binary_handler(BINARY_MIME_TYPE), BINARY_MIME_TYPE) -# -# adapters.handlers.set_handler(LLSD, llsd_xml_handler(XML_MIME_TYPE), '*/*') diff --git a/indra/lib/python/indra/base/lluuid.py b/indra/lib/python/indra/base/lluuid.py deleted file mode 100755 index 7413ffe10d151b62bd86d462e841bab0309a42d9..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/base/lluuid.py +++ /dev/null @@ -1,319 +0,0 @@ -"""\ -@file lluuid.py -@brief UUID parser/generator. - -$LicenseInfo:firstyear=2004&license=mit$ - -Copyright (c) 2004-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import random, socket, string, time, re -import uuid -try: - # Python 2.6 - from hashlib import md5 -except ImportError: - # Python 2.5 and earlier - from md5 import new as md5 - -def _int2binstr(i,l): - s='' - for a in range(l): - s=chr(i&0xFF)+s - i>>=8 - return s - -def _binstr2int(s): - i = long(0) - for c in s: - i = (i<<8) + ord(c) - return i - -class UUID(object): - """ - A class which represents a 16 byte integer. Stored as a 16 byte 8 - bit character string. - - The string version is to be of the form: - AAAAAAAA-AAAA-BBBB-BBBB-BBBBBBCCCCCC (a 128-bit number in hex) - where A=network address, B=timestamp, C=random. - """ - - NULL_STR = "00000000-0000-0000-0000-000000000000" - - # the UUIDREGEX_STRING is helpful for parsing UUID's in text - hex_wildcard = r"[0-9a-fA-F]" - word = hex_wildcard + r"{4,4}-" - long_word = hex_wildcard + r"{8,8}-" - very_long_word = hex_wildcard + r"{12,12}" - UUID_REGEX_STRING = long_word + word + word + word + very_long_word - uuid_regex = re.compile(UUID_REGEX_STRING) - - rand = random.Random() - ip = '' - try: - ip = socket.gethostbyname(socket.gethostname()) - except(socket.gaierror, socket.error): - # no ip address, so just default to somewhere in 10.x.x.x - ip = '10' - for i in range(3): - ip += '.' + str(rand.randrange(1,254)) - hexip = ''.join(["%04x" % long(i) for i in ip.split('.')]) - lastid = '' - - def __init__(self, possible_uuid=None): - """ - Initialize to first valid UUID in argument (if a string), - or to null UUID if none found or argument is not supplied. - - If the argument is a UUID, the constructed object will be a copy of it. - """ - self._bits = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - if possible_uuid is None: - return - - if isinstance(possible_uuid, type(self)): - self.set(possible_uuid) - return - - uuid_match = UUID.uuid_regex.search(possible_uuid) - if uuid_match: - uuid_string = uuid_match.group() - s = string.replace(uuid_string, '-', '') - self._bits = _int2binstr(string.atol(s[:8],16),4) + \ - _int2binstr(string.atol(s[8:16],16),4) + \ - _int2binstr(string.atol(s[16:24],16),4) + \ - _int2binstr(string.atol(s[24:],16),4) - - def __len__(self): - """ - Used by the len() builtin. - """ - return 36 - - def __nonzero__(self): - return self._bits != "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - - def __str__(self): - uuid_string = self.toString() - return uuid_string - - __repr__ = __str__ - - def __getitem__(self, index): - return str(self)[index] - - def __eq__(self, other): - if isinstance(other, (str, unicode)): - return other == str(self) - return self._bits == getattr(other, '_bits', '') - - def __ne__(self, other): - return not self.__eq__(other) - - def __le__(self, other): - return self._bits <= other._bits - - def __ge__(self, other): - return self._bits >= other._bits - - def __lt__(self, other): - return self._bits < other._bits - - def __gt__(self, other): - return self._bits > other._bits - - def __hash__(self): - return hash(self._bits) - - def set(self, uuid): - self._bits = uuid._bits - - def setFromString(self, uuid_string): - """ - Given a string version of a uuid, set self bits - appropriately. Returns self. - """ - s = string.replace(uuid_string, '-', '') - self._bits = _int2binstr(string.atol(s[:8],16),4) + \ - _int2binstr(string.atol(s[8:16],16),4) + \ - _int2binstr(string.atol(s[16:24],16),4) + \ - _int2binstr(string.atol(s[24:],16),4) - return self - - def setFromMemoryDump(self, gdb_string): - """ - We expect to get gdb_string as four hex units. eg: - 0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2 - Which will be translated to: - db547d14-1b3f4bc3-9b984f71-d22f890a - Returns self. - """ - s = string.replace(gdb_string, '0x', '') - s = string.replace(s, ' ', '') - t = '' - for i in range(8,40,8): - for j in range(0,8,2): - t = t + s[i-j-2:i-j] - self.setFromString(t) - - def toString(self): - """ - Return as a string matching the LL standard - AAAAAAAA-AAAA-BBBB-BBBB-BBBBBBCCCCCC (a 128-bit number in hex) - where A=network address, B=timestamp, C=random. - """ - return uuid_bits_to_string(self._bits) - - def getAsString(self): - """ - Return a different string representation of the form - AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC (a 128-bit number in hex) - where A=network address, B=timestamp, C=random. - """ - i1 = _binstr2int(self._bits[0:4]) - i2 = _binstr2int(self._bits[4:8]) - i3 = _binstr2int(self._bits[8:12]) - i4 = _binstr2int(self._bits[12:16]) - return '%08lx-%08lx-%08lx-%08lx' % (i1,i2,i3,i4) - - def generate(self): - """ - Generate a new uuid. This algorithm is slightly different - from c++ implementation for portability reasons. - Returns self. - """ - m = md5() - m.update(uuid.uuid1().bytes) - self._bits = m.digest() - return self - - def isNull(self): - """ - Returns 1 if the uuid is null - ie, equal to default uuid. - """ - return (self._bits == "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") - - def xor(self, rhs): - """ - xors self with rhs. - """ - v1 = _binstr2int(self._bits[0:4]) ^ _binstr2int(rhs._bits[0:4]) - v2 = _binstr2int(self._bits[4:8]) ^ _binstr2int(rhs._bits[4:8]) - v3 = _binstr2int(self._bits[8:12]) ^ _binstr2int(rhs._bits[8:12]) - v4 = _binstr2int(self._bits[12:16]) ^ _binstr2int(rhs._bits[12:16]) - self._bits = _int2binstr(v1,4) + \ - _int2binstr(v2,4) + \ - _int2binstr(v3,4) + \ - _int2binstr(v4,4) - - -# module-level null constant -NULL = UUID() - -def printTranslatedMemory(four_hex_uints): - """ - We expect to get the string as four hex units. eg: - 0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2 - Which will be translated to: - db547d14-1b3f4bc3-9b984f71-d22f890a - """ - uuid = UUID() - uuid.setFromMemoryDump(four_hex_uints) - print uuid.toString() - -def isUUID(id_str): - """ - This function returns: - - 1 if the string passed is a UUID - - 0 is the string passed is not a UUID - - None if it neither of the if's below is satisfied - """ - if not id_str or len(id_str) < 5 or len(id_str) > 36: - return 0 - - if isinstance(id_str, UUID) or UUID.uuid_regex.match(id_str): - return 1 - - return None - -def isPossiblyID(id_str): - """ - This function returns 1 if the string passed has some uuid-like - characteristics. Otherwise returns 0. - """ - - is_uuid = isUUID(id_str) - if is_uuid is not None: - return is_uuid - - # build a string which matches every character. - hex_wildcard = r"[0-9a-fA-F]" - chars = len(id_str) - next = min(chars, 8) - matcher = hex_wildcard+"{"+str(next)+","+str(next)+"}" - chars = chars - next - if chars > 0: - matcher = matcher + "-" - chars = chars - 1 - for block in range(3): - next = max(min(chars, 4), 0) - if next: - matcher = matcher + hex_wildcard+"{"+str(next)+","+str(next)+"}" - chars = chars - next - if chars > 0: - matcher = matcher + "-" - chars = chars - 1 - if chars > 0: - next = min(chars, 12) - matcher = matcher + hex_wildcard+"{"+str(next)+","+str(next)+"}" - #print matcher - uuid_matcher = re.compile(matcher) - if uuid_matcher.match(id_str): - return 1 - return 0 - -def uuid_bits_to_string(bits): - i1 = _binstr2int(bits[0:4]) - i2 = _binstr2int(bits[4:6]) - i3 = _binstr2int(bits[6:8]) - i4 = _binstr2int(bits[8:10]) - i5 = _binstr2int(bits[10:12]) - i6 = _binstr2int(bits[12:16]) - return '%08lx-%04lx-%04lx-%04lx-%04lx%08lx' % (i1,i2,i3,i4,i5,i6) - -def uuid_bits_to_uuid(bits): - return UUID(uuid_bits_to_string(bits)) - - -try: - from mulib import stacked - stacked.NoProducer() # just to exercise stacked -except: - #print "Couldn't import mulib.stacked, not registering UUID converter" - pass -else: - def convertUUID(uuid, req): - req.write(str(uuid)) - - stacked.add_producer(UUID, convertUUID, "*/*") - stacked.add_producer(UUID, convertUUID, "text/html") diff --git a/indra/lib/python/indra/base/metrics.py b/indra/lib/python/indra/base/metrics.py deleted file mode 100755 index ff8380265f376dd391d1a11edf2a540c53f53a18..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/base/metrics.py +++ /dev/null @@ -1,121 +0,0 @@ -"""\ -@file metrics.py -@author Phoenix -@date 2007-11-27 -@brief simple interface for logging metrics - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import sys -try: - import syslog -except ImportError: - # Windows - import sys - class syslog(object): - # wrap to a lame syslog for windows - _logfp = sys.stderr - def syslog(msg): - _logfp.write(msg) - if not msg.endswith('\n'): - _logfp.write('\n') - syslog = staticmethod(syslog) - -from indra.base.llsd import format_notation - -def record_metrics(table, stats): - "Write a standard metrics log" - _log("LLMETRICS", table, stats) - -def record_event(table, data): - "Write a standard logmessage log" - _log("LLLOGMESSAGE", table, data) - -def set_destination(dest): - """Set the destination of metrics logs for this process. - - If you do not call this function prior to calling a logging - method, that function will open sys.stdout as a destination. - Attempts to set dest to None will throw a RuntimeError. - @param dest a file-like object which will be the destination for logs.""" - if dest is None: - raise RuntimeError("Attempt to unset metrics destination.") - global _destination - _destination = dest - -def destination(): - """Get the destination of the metrics logs for this process. - Returns None if no destination is set""" - global _destination - return _destination - -class SysLogger(object): - "A file-like object which writes to syslog." - def __init__(self, ident='indra', logopt = None, facility = None): - try: - if logopt is None: - logopt = syslog.LOG_CONS | syslog.LOG_PID - if facility is None: - facility = syslog.LOG_LOCAL0 - syslog.openlog(ident, logopt, facility) - import atexit - atexit.register(syslog.closelog) - except AttributeError: - # No syslog module on Windows - pass - - def write(str): - syslog.syslog(str) - write = staticmethod(write) - - def flush(): - pass - flush = staticmethod(flush) - -# -# internal API -# -_sequence_id = 0 -_destination = None - -def _next_id(): - global _sequence_id - next = _sequence_id - _sequence_id += 1 - return next - -def _dest(): - global _destination - if _destination is None: - # this default behavior is documented in the metrics functions above. - _destination = sys.stdout - return _destination - -def _log(header, table, data): - log_line = "%s (%d) %s %s" \ - % (header, _next_id(), table, format_notation(data)) - dest = _dest() - dest.write(log_line) - dest.flush() diff --git a/indra/lib/python/indra/ipc/httputil.py b/indra/lib/python/indra/ipc/httputil.py deleted file mode 100755 index d53f34a771f96cc4b84b8dc21336fe1aac8b8d57..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/ipc/httputil.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/python -## $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$ - -import warnings - -warnings.warn("indra.ipc.httputil has been deprecated; use eventlet.httpc instead", DeprecationWarning, 2) - -from eventlet.httpc import * - - -makeConnection = make_connection diff --git a/indra/lib/python/indra/ipc/llsdhttp.py b/indra/lib/python/indra/ipc/llsdhttp.py deleted file mode 100755 index cbe8ee1eca352c4c1c26ec861b9d4affb950791c..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/ipc/llsdhttp.py +++ /dev/null @@ -1,100 +0,0 @@ -"""\ -@file llsdhttp.py -@brief Functions to ease moving llsd over http - -$LicenseInfo:firstyear=2006&license=mit$ - -Copyright (c) 2006-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import os.path -import os -import urlparse - -from indra.base import llsd - -from eventlet import httpc - -suite = httpc.HttpSuite(llsd.format_xml, llsd.parse, 'application/llsd+xml') -delete = suite.delete -delete_ = suite.delete_ -get = suite.get -get_ = suite.get_ -head = suite.head -head_ = suite.head_ -post = suite.post -post_ = suite.post_ -put = suite.put -put_ = suite.put_ -request = suite.request -request_ = suite.request_ - -# import every httpc error exception into our namespace for convenience -for x in httpc.status_to_error_map.itervalues(): - globals()[x.__name__] = x -ConnectionError = httpc.ConnectionError -Retriable = httpc.Retriable - -for x in (httpc.ConnectionError,): - globals()[x.__name__] = x - - -def postFile(url, filename): - f = open(filename) - body = f.read() - f.close() - llsd_body = llsd.parse(body) - return post_(url, llsd_body) - - -# deprecated in favor of get_ -def getStatus(url, use_proxy=False): - status, _headers, _body = get_(url, use_proxy=use_proxy) - return status - -# deprecated in favor of put_ -def putStatus(url, data): - status, _headers, _body = put_(url, data) - return status - -# deprecated in favor of delete_ -def deleteStatus(url): - status, _headers, _body = delete_(url) - return status - -# deprecated in favor of post_ -def postStatus(url, data): - status, _headers, _body = post_(url, data) - return status - - -def postFileStatus(url, filename): - status, _headers, body = postFile(url, filename) - return status, body - - -def getFromSimulator(path, use_proxy=False): - return get('http://' + simulatorHostAndPort + path, use_proxy=use_proxy) - - -def postToSimulator(path, data=None): - return post('http://' + simulatorHostAndPort + path, data) diff --git a/indra/lib/python/indra/ipc/mysql_pool.py b/indra/lib/python/indra/ipc/mysql_pool.py deleted file mode 100755 index e5855a30919a318877700a08e4bf97f96f4b2858..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/ipc/mysql_pool.py +++ /dev/null @@ -1,81 +0,0 @@ -"""\ -@file mysql_pool.py -@brief Thin wrapper around eventlet.db_pool that chooses MySQLdb and Tpool. - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import MySQLdb -from eventlet import db_pool - -class DatabaseConnector(db_pool.DatabaseConnector): - def __init__(self, credentials, *args, **kwargs): - super(DatabaseConnector, self).__init__(MySQLdb, credentials, - conn_pool=db_pool.ConnectionPool, - *args, **kwargs) - - # get is extended relative to eventlet.db_pool to accept a port argument - def get(self, host, dbname, port=3306): - key = (host, dbname, port) - if key not in self._databases: - new_kwargs = self._kwargs.copy() - new_kwargs['db'] = dbname - new_kwargs['host'] = host - new_kwargs['port'] = port - new_kwargs.update(self.credentials_for(host)) - dbpool = ConnectionPool(*self._args, **new_kwargs) - self._databases[key] = dbpool - - return self._databases[key] - -class ConnectionPool(db_pool.TpooledConnectionPool): - """A pool which gives out saranwrapped MySQLdb connections from a pool - """ - - def __init__(self, *args, **kwargs): - super(ConnectionPool, self).__init__(MySQLdb, *args, **kwargs) - - def get(self): - conn = super(ConnectionPool, self).get() - # annotate the connection object with the details on the - # connection; this is used elsewhere to check that you haven't - # suddenly changed databases in midstream while making a - # series of queries on a connection. - arg_names = ['host','user','passwd','db','port','unix_socket','conv','connect_timeout', - 'compress', 'named_pipe', 'init_command', 'read_default_file', 'read_default_group', - 'cursorclass', 'use_unicode', 'charset', 'sql_mode', 'client_flag', 'ssl', - 'local_infile'] - # you could have constructed this connectionpool with a mix of - # keyword and non-keyword arguments, but we want to annotate - # the connection object with a dict so it's easy to check - # against so here we are converting the list of non-keyword - # arguments (in self._args) into a dict of keyword arguments, - # and merging that with the actual keyword arguments - # (self._kwargs). The arg_names variable lists the - # constructor arguments for MySQLdb Connection objects. - converted_kwargs = dict([ (arg_names[i], arg) for i, arg in enumerate(self._args) ]) - converted_kwargs.update(self._kwargs) - conn.connection_parameters = converted_kwargs - return conn - diff --git a/indra/lib/python/indra/ipc/russ.py b/indra/lib/python/indra/ipc/russ.py deleted file mode 100755 index ac780f128b6c68ecd5d5ead15632f0c55a11c45b..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/ipc/russ.py +++ /dev/null @@ -1,165 +0,0 @@ -"""\ -@file russ.py -@brief Recursive URL Substitution Syntax helpers -@author Phoenix - -Many details on how this should work is available on the wiki: -https://wiki.secondlife.com/wiki/Recursive_URL_Substitution_Syntax - -Adding features to this should be reflected in that page in the -implementations section. - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import urllib -from indra.ipc import llsdhttp - -class UnbalancedBraces(Exception): - pass - -class UnknownDirective(Exception): - pass - -class BadDirective(Exception): - pass - -def format_value_for_path(value): - if type(value) in [list, tuple]: - # *NOTE: treat lists as unquoted path components so that the quoting - # doesn't get out-of-hand. This is a workaround for the fact that - # russ always quotes, even if the data it's given is already quoted, - # and it's not safe to simply unquote a path directly, so if we want - # russ to substitute urls parts inside other url parts we always - # have to do so via lists of unquoted path components. - return '/'.join([urllib.quote(str(item)) for item in value]) - else: - return urllib.quote(str(value)) - -def format(format_str, context): - """@brief Format format string according to rules for RUSS. -@see https://osiris.lindenlab.com/mediawiki/index.php/Recursive_URL_Substitution_Syntax -@param format_str The input string to format. -@param context A map used for string substitutions. -@return Returns the formatted string. If no match, the braces remain intact. -""" - while True: - #print "format_str:", format_str - all_matches = _find_sub_matches(format_str) - if not all_matches: - break - substitutions = 0 - while True: - matches = all_matches.pop() - # we work from right to left to make sure we do not - # invalidate positions earlier in format_str - matches.reverse() - for pos in matches: - # Use index since _find_sub_matches should have raised - # an exception, and failure to find now is an exception. - end = format_str.index('}', pos) - #print "directive:", format_str[pos+1:pos+5] - if format_str[pos + 1] == '$': - value = context[format_str[pos + 2:end]] - if value is not None: - value = format_value_for_path(value) - elif format_str[pos + 1] == '%': - value = _build_query_string( - context.get(format_str[pos + 2:end])) - elif format_str[pos+1:pos+5] == 'http' or format_str[pos+1:pos+5] == 'file': - value = _fetch_url_directive(format_str[pos + 1:end]) - else: - raise UnknownDirective, format_str[pos:end + 1] - if value is not None: - format_str = format_str[:pos]+str(value)+format_str[end+1:] - substitutions += 1 - - # If there were any substitutions at this depth, re-parse - # since this may have revealed new things to substitute - if substitutions: - break - if not all_matches: - break - - # If there were no substitutions at all, and we have exhausted - # the possible matches, bail. - if not substitutions: - break - return format_str - -def _find_sub_matches(format_str): - """@brief Find all of the substitution matches. -@param format_str the RUSS conformant format string. -@return Returns an array of depths of arrays of positional matches in input. -""" - depth = 0 - matches = [] - for pos in range(len(format_str)): - if format_str[pos] == '{': - depth += 1 - if not len(matches) == depth: - matches.append([]) - matches[depth - 1].append(pos) - continue - if format_str[pos] == '}': - depth -= 1 - continue - if not depth == 0: - raise UnbalancedBraces, format_str - return matches - -def _build_query_string(query_dict): - """\ - @breif given a dict, return a query string. utility wrapper for urllib. - @param query_dict input query dict - @returns Returns an urlencoded query string including leading '?'. - """ - if query_dict: - keys = query_dict.keys() - keys.sort() - def stringize(value): - if type(value) in (str,unicode): - return value - else: - return str(value) - query_list = [urllib.quote(str(key)) + '=' + urllib.quote(stringize(query_dict[key])) for key in keys] - return '?' + '&'.join(query_list) - else: - return '' - -def _fetch_url_directive(directive): - "*FIX: This only supports GET" - commands = directive.split('|') - resource = llsdhttp.get(commands[0]) - if len(commands) == 3: - resource = _walk_resource(resource, commands[2]) - return resource - -def _walk_resource(resource, path): - path = path.split('/') - for child in path: - if not child: - continue - resource = resource[child] - return resource diff --git a/indra/lib/python/indra/ipc/servicebuilder.py b/indra/lib/python/indra/ipc/servicebuilder.py deleted file mode 100755 index 0a0ce2b4e2d45faecca4ef1447b1d4aa71ba280e..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/ipc/servicebuilder.py +++ /dev/null @@ -1,134 +0,0 @@ -"""\ -@file servicebuilder.py -@author Phoenix -@brief Class which will generate service urls. - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -from indra.base import config -from indra.ipc import llsdhttp -from indra.ipc import russ - -# *NOTE: agent presence relies on this variable existing and being current, it is a huge hack -services_config = {} -try: - services_config = llsdhttp.get(config.get('services-config')) -except: - pass - -_g_builder = None -def _builder(): - global _g_builder - if _g_builder is None: - _g_builder = ServiceBuilder() - return _g_builder - -def build(name, context={}, **kwargs): - """ Convenience method for using a global, singleton, service builder. Pass arguments either via a dict or via python keyword arguments, or both! - - Example use: - > context = {'channel':'Second Life Release', 'version':'1.18.2.0'} - > servicebuilder.build('version-manager-version', context) - 'http://int.util.vaak.lindenlab.com/channel/Second%20Life%20Release/1.18.2.0' - > servicebuilder.build('version-manager-version', channel='Second Life Release', version='1.18.2.0') - 'http://int.util.vaak.lindenlab.com/channel/Second%20Life%20Release/1.18.2.0' - > servicebuilder.build('version-manager-version', context, version='1.18.1.2') - 'http://int.util.vaak.lindenlab.com/channel/Second%20Life%20Release/1.18.1.2' - """ - global _g_builder - if _g_builder is None: - _g_builder = ServiceBuilder() - return _g_builder.buildServiceURL(name, context, **kwargs) - -def build_path(name, context={}, **kwargs): - context = context.copy() # shouldn't modify the caller's dictionary - context.update(kwargs) - return _builder().buildPath(name, context) - -class ServiceBuilder(object): - def __init__(self, services_definition = services_config): - """\ - @brief - @brief Create a ServiceBuilder. - @param services_definition Complete services definition, services.xml. - """ - # no need to keep a copy of the services section of the - # complete services definition, but it doesn't hurt much. - self.services = services_definition['services'] - self.builders = {} - for service in self.services: - service_builder = service.get('service-builder') - if not service_builder: - continue - if isinstance(service_builder, dict): - # We will be constructing several builders - for name, builder in service_builder.iteritems(): - full_builder_name = service['name'] + '-' + name - self.builders[full_builder_name] = builder - else: - self.builders[service['name']] = service_builder - - def buildPath(self, name, context): - """\ - @brief given the environment on construction, return a service path. - @param name The name of the service. - @param context A dict of name value lookups for the service. - @returns Returns the - """ - return russ.format(self.builders[name], context) - - def buildServiceURL(self, name, context={}, **kwargs): - """\ - @brief given the environment on construction, return a service URL. - @param name The name of the service. - @param context A dict of name value lookups for the service. - @param kwargs Any keyword arguments are treated as members of the - context, this allows you to be all 31337 by writing shit like: - servicebuilder.build('name', param=value) - @returns Returns the - """ - context = context.copy() # shouldn't modify the caller's dictionary - context.update(kwargs) - base_url = config.get('services-base-url') - svc_path = russ.format(self.builders[name], context) - return base_url + svc_path - - -def on_in(query_name, host_key, schema_key): - """\ - @brief Constructs an on/in snippet (for running named queries) - from a schema name and two keys referencing values stored in - indra.xml. - - @param query_name Name of the query. - @param host_key Logical name of destination host. Will be - looked up in indra.xml. - @param schema_key Logical name of destination schema. Will - be looked up in indra.xml. - """ - return "on/config:%s/in/config:%s/%s" % (host_key.strip('/'), - schema_key.strip('/'), - query_name.lstrip('/')) - diff --git a/indra/lib/python/indra/ipc/siesta.py b/indra/lib/python/indra/ipc/siesta.py deleted file mode 100755 index d867e715378b268ac365bada4b202b3a74d89ede..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/ipc/siesta.py +++ /dev/null @@ -1,468 +0,0 @@ -"""\ -@file siesta.py -@brief A tiny llsd based RESTful web services framework - -$LicenseInfo:firstyear=2008&license=mit$ - -Copyright (c) 2008, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -from indra.base import config -from indra.base import llsd -from webob import exc -import webob -import re, socket - -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO - -try: - import cjson - json_decode = cjson.decode - json_encode = cjson.encode - JsonDecodeError = cjson.DecodeError - JsonEncodeError = cjson.EncodeError -except ImportError: - import simplejson - json_decode = simplejson.loads - json_encode = simplejson.dumps - JsonDecodeError = ValueError - JsonEncodeError = TypeError - - -llsd_parsers = { - 'application/json': json_decode, - llsd.BINARY_MIME_TYPE: llsd.parse_binary, - 'application/llsd+notation': llsd.parse_notation, - llsd.XML_MIME_TYPE: llsd.parse_xml, - 'application/xml': llsd.parse_xml, - } - - -def mime_type(content_type): - '''Given a Content-Type header, return only the MIME type.''' - - return content_type.split(';', 1)[0].strip().lower() - -class BodyLLSD(object): - '''Give a webob Request or Response an llsd based "content" property. - - Getting the content property parses the body, and caches the result. - - Setting the content property formats a payload, and the body property - is set.''' - - def _llsd__get(self): - '''Get, set, or delete the LLSD value stored in this object.''' - - try: - return self._llsd - except AttributeError: - if not self.body: - raise AttributeError('No llsd attribute has been set') - else: - mtype = mime_type(self.content_type) - try: - parser = llsd_parsers[mtype] - except KeyError: - raise exc.HTTPUnsupportedMediaType( - 'Content type %s not supported' % mtype).exception - try: - self._llsd = parser(self.body) - except (llsd.LLSDParseError, JsonDecodeError, TypeError), err: - raise exc.HTTPBadRequest( - 'Could not parse body: %r' % err.args).exception - return self._llsd - - def _llsd__set(self, val): - req = getattr(self, 'request', None) - if req is not None: - formatter, ctype = formatter_for_request(req) - self.content_type = ctype - else: - formatter, ctype = formatter_for_mime_type( - mime_type(self.content_type)) - self.body = formatter(val) - - def _llsd__del(self): - if hasattr(self, '_llsd'): - del self._llsd - - content = property(_llsd__get, _llsd__set, _llsd__del) - - -class Response(webob.Response, BodyLLSD): - '''Response class with LLSD support. - - A sensible default content type is used. - - Setting the llsd property also sets the body. Getting the llsd - property parses the body if necessary. - - If you set the body property directly, the llsd property will be - deleted.''' - - default_content_type = 'application/llsd+xml' - - def _body__set(self, body): - if hasattr(self, '_llsd'): - del self._llsd - super(Response, self)._body__set(body) - - def cache_forever(self): - self.cache_expires(86400 * 365) - - body = property(webob.Response._body__get, _body__set, - webob.Response._body__del, - webob.Response._body__get.__doc__) - - -class Request(webob.Request, BodyLLSD): - '''Request class with LLSD support. - - Sensible content type and accept headers are used by default. - - Setting the content property also sets the body. Getting the content - property parses the body if necessary. - - If you set the body property directly, the content property will be - deleted.''' - - default_content_type = 'application/llsd+xml' - default_accept = ('application/llsd+xml; q=0.5, ' - 'application/llsd+notation; q=0.3, ' - 'application/llsd+binary; q=0.2, ' - 'application/xml; q=0.1, ' - 'application/json; q=0.0') - - def __init__(self, environ=None, *args, **kwargs): - if environ is None: - environ = {} - else: - environ = environ.copy() - if 'CONTENT_TYPE' not in environ: - environ['CONTENT_TYPE'] = self.default_content_type - if 'HTTP_ACCEPT' not in environ: - environ['HTTP_ACCEPT'] = self.default_accept - super(Request, self).__init__(environ, *args, **kwargs) - - def _body__set(self, body): - if hasattr(self, '_llsd'): - del self._llsd - super(Request, self)._body__set(body) - - def path_urljoin(self, *parts): - return '/'.join([path_url.rstrip('/')] + list(parts)) - - body = property(webob.Request._body__get, _body__set, - webob.Request._body__del, webob.Request._body__get.__doc__) - - def create_response(self, content=None, status='200 OK', - conditional_response=webob.NoDefault): - resp = self.ResponseClass(status=status, request=self, - conditional_response=conditional_response) - resp.content = content - return resp - - def curl(self): - '''Create and fill out a pycurl easy object from this request.''' - - import pycurl - c = pycurl.Curl() - c.setopt(pycurl.URL, self.url()) - if self.headers: - c.setopt(pycurl.HTTPHEADER, - ['%s: %s' % (k, self.headers[k]) for k in self.headers]) - c.setopt(pycurl.FOLLOWLOCATION, True) - c.setopt(pycurl.AUTOREFERER, True) - c.setopt(pycurl.MAXREDIRS, 16) - c.setopt(pycurl.NOSIGNAL, True) - c.setopt(pycurl.READFUNCTION, self.body_file.read) - c.setopt(pycurl.SSL_VERIFYHOST, 2) - - if self.method == 'POST': - c.setopt(pycurl.POST, True) - post301 = getattr(pycurl, 'POST301', None) - if post301 is not None: - # Added in libcurl 7.17.1. - c.setopt(post301, True) - elif self.method == 'PUT': - c.setopt(pycurl.PUT, True) - elif self.method != 'GET': - c.setopt(pycurl.CUSTOMREQUEST, self.method) - return c - -Request.ResponseClass = Response -Response.RequestClass = Request - - -llsd_formatters = { - 'application/json': json_encode, - 'application/llsd+binary': llsd.format_binary, - 'application/llsd+notation': llsd.format_notation, - 'application/llsd+xml': llsd.format_xml, - 'application/xml': llsd.format_xml, - } - -formatter_qualities = ( - ('application/llsd+xml', 1.0), - ('application/llsd+notation', 0.5), - ('application/llsd+binary', 0.4), - ('application/xml', 0.3), - ('application/json', 0.2), - ) - -def formatter_for_mime_type(mime_type): - '''Return a formatter that encodes to the given MIME type. - - The result is a pair of function and MIME type.''' - try: - return llsd_formatters[mime_type], mime_type - except KeyError: - raise exc.HTTPInternalServerError( - 'Could not use MIME type %r to format response' % - mime_type).exception - - -def formatter_for_request(req): - '''Return a formatter that encodes to the preferred type of the client. - - The result is a pair of function and actual MIME type.''' - ctype = req.accept.best_match(formatter_qualities) - try: - return llsd_formatters[ctype], ctype - except KeyError: - raise exc.HTTPNotAcceptable().exception - - -def wsgi_adapter(func, environ, start_response): - '''Adapt a Siesta callable to act as a WSGI application.''' - # Process the request as appropriate. - try: - req = Request(environ) - #print req.urlvars - resp = func(req, **req.urlvars) - if not isinstance(resp, webob.Response): - try: - formatter, ctype = formatter_for_request(req) - resp = req.ResponseClass(formatter(resp), content_type=ctype) - resp._llsd = resp - except (JsonEncodeError, TypeError), err: - resp = exc.HTTPInternalServerError( - detail='Could not format response') - except exc.HTTPException, e: - resp = e - except socket.error, e: - resp = exc.HTTPInternalServerError(detail=e.args[1]) - return resp(environ, start_response) - - -def llsd_callable(func): - '''Turn a callable into a Siesta application.''' - - def replacement(environ, start_response): - return wsgi_adapter(func, environ, start_response) - - return replacement - - -def llsd_method(http_method, func): - def replacement(environ, start_response): - if environ['REQUEST_METHOD'] == http_method: - return wsgi_adapter(func, environ, start_response) - return exc.HTTPMethodNotAllowed()(environ, start_response) - - return replacement - - -http11_methods = 'OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT'.split() -http11_methods.sort() - -def llsd_class(cls): - '''Turn a class into a Siesta application. - - A new instance is created for each request. A HTTP method FOO is - turned into a call to the handle_foo method of the instance.''' - - def foo(req, **kwargs): - instance = cls() - method = req.method.lower() - try: - handler = getattr(instance, 'handle_' + method) - except AttributeError: - allowed = [m for m in http11_methods - if hasattr(instance, 'handle_' + m.lower())] - raise exc.HTTPMethodNotAllowed( - headers={'Allow': ', '.join(allowed)}).exception - #print "kwargs: ", kwargs - return handler(req, **kwargs) - - def replacement(environ, start_response): - return wsgi_adapter(foo, environ, start_response) - - return replacement - - -def curl(reqs): - import pycurl - - m = pycurl.CurlMulti() - curls = [r.curl() for r in reqs] - io = {} - for c in curls: - fp = StringIO() - hdr = StringIO() - c.setopt(pycurl.WRITEFUNCTION, fp.write) - c.setopt(pycurl.HEADERFUNCTION, hdr.write) - io[id(c)] = fp, hdr - m.handles = curls - try: - while True: - ret, num_handles = m.perform() - if ret != pycurl.E_CALL_MULTI_PERFORM: - break - finally: - m.close() - - for req, c in zip(reqs, curls): - fp, hdr = io[id(c)] - hdr.seek(0) - status = hdr.readline().rstrip() - headers = [] - name, values = None, None - - # XXX We don't currently handle bogus header data. - - for line in hdr.readlines(): - if not line[0].isspace(): - if name: - headers.append((name, ' '.join(values))) - name, value = line.strip().split(':', 1) - value = [value] - else: - values.append(line.strip()) - if name: - headers.append((name, ' '.join(values))) - - resp = c.ResponseClass(fp.getvalue(), status, headers, request=req) - - -route_re = re.compile(r''' - \{ # exact character "{" - (\w*) # "config" or variable (restricted to a-z, 0-9, _) - (?:([:~])([^}]+))? # optional :type or ~regex part - \} # exact character "}" - ''', re.VERBOSE) - -predefined_regexps = { - 'uuid': r'[a-f0-9][a-f0-9-]{31,35}', - 'int': r'\d+', - 'host': r'[a-z0-9][a-z0-9\-\.]*', - } - -def compile_route(route): - fp = StringIO() - last_pos = 0 - for match in route_re.finditer(route): - #print "matches: ", match.groups() - fp.write(re.escape(route[last_pos:match.start()])) - var_name = match.group(1) - sep = match.group(2) - expr = match.group(3) - if var_name == 'config': - expr = re.escape(str(config.get(var_name))) - else: - if expr: - if sep == ':': - expr = predefined_regexps[expr] - # otherwise, treat what follows '~' as a regexp - else: - expr = '[^/]+' - if var_name != '': - expr = '(?P<%s>%s)' % (var_name, expr) - else: - expr = '(%s)' % (expr,) - fp.write(expr) - last_pos = match.end() - fp.write(re.escape(route[last_pos:])) - compiled_route = '^%s$' % fp.getvalue() - #print route, "->", compiled_route - return compiled_route - -class Router(object): - '''WSGI routing class. Parses a URL and hands off a request to - some other WSGI application. If no suitable application is found, - responds with a 404.''' - - def __init__(self): - self._new_routes = [] - self._routes = [] - self._paths = [] - - def add(self, route, app, methods=None): - self._new_routes.append((route, app, methods)) - - def _create_routes(self): - for route, app, methods in self._new_routes: - self._paths.append(route) - self._routes.append( - (re.compile(compile_route(route)), - app, - methods and dict.fromkeys(methods))) - self._new_routes = [] - - def __call__(self, environ, start_response): - # load up the config from the config file. Only needs to be - # done once per interpreter. This is the entry point of all - # siesta applications, so this is where we trap it. - _conf = config.get_config() - if _conf is None: - import os.path - fname = os.path.join( - environ.get('ll.config_dir', '/local/linden/etc'), - 'indra.xml') - config.load(fname) - - # proceed with handling the request - self._create_routes() - path_info = environ['PATH_INFO'] - request_method = environ['REQUEST_METHOD'] - allowed = [] - for regex, app, methods in self._routes: - m = regex.match(path_info) - if m: - #print "groupdict:",m.groupdict() - if not methods or request_method in methods: - environ['paste.urlvars'] = m.groupdict() - return app(environ, start_response) - else: - allowed += methods - if allowed: - allowed = dict.fromkeys(allows).keys() - allowed.sort() - resp = exc.HTTPMethodNotAllowed( - headers={'Allow': ', '.join(allowed)}) - else: - resp = exc.HTTPNotFound() - return resp(environ, start_response) diff --git a/indra/lib/python/indra/ipc/siesta_test.py b/indra/lib/python/indra/ipc/siesta_test.py deleted file mode 100755 index a35eed24604316c097302ecd83785b2abe384d1b..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/ipc/siesta_test.py +++ /dev/null @@ -1,235 +0,0 @@ -#!/usr/bin/python -## $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$ -from indra.base import llsd, lluuid -from indra.ipc import siesta -import datetime, math, unittest -from webob import exc - - -class ClassApp(object): - def handle_get(self, req): - pass - - def handle_post(self, req): - return req.llsd - - -def callable_app(req): - if req.method == 'UNDERPANTS': - raise exc.HTTPMethodNotAllowed() - elif req.method == 'GET': - return None - return req.llsd - - -class TestBase: - def test_basic_get(self): - req = siesta.Request.blank('/') - self.assertEquals(req.get_response(self.server).body, - llsd.format_xml(None)) - - def test_bad_method(self): - req = siesta.Request.blank('/') - req.environ['REQUEST_METHOD'] = 'UNDERPANTS' - self.assertEquals(req.get_response(self.server).status_int, - exc.HTTPMethodNotAllowed.code) - - json_safe = { - 'none': None, - 'bool_true': True, - 'bool_false': False, - 'int_zero': 0, - 'int_max': 2147483647, - 'int_min': -2147483648, - 'long_zero': 0, - 'long_max': 2147483647L, - 'long_min': -2147483648L, - 'float_zero': 0, - 'float': math.pi, - 'float_huge': 3.14159265358979323846e299, - 'str_empty': '', - 'str': 'foo', - u'unic\u1e51de_empty': u'', - u'unic\u1e51de': u'\u1e4exx\u10480', - } - json_safe['array'] = json_safe.values() - json_safe['tuple'] = tuple(json_safe.values()) - json_safe['dict'] = json_safe.copy() - - json_unsafe = { - 'uuid_empty': lluuid.UUID(), - 'uuid_full': lluuid.UUID('dc61ab0530200d7554d23510559102c1a98aab1b'), - 'binary_empty': llsd.binary(), - 'binary': llsd.binary('f\0\xff'), - 'uri_empty': llsd.uri(), - 'uri': llsd.uri('http://www.secondlife.com/'), - 'datetime_empty': datetime.datetime(1970,1,1), - 'datetime': datetime.datetime(1999,9,9,9,9,9), - } - json_unsafe.update(json_safe) - json_unsafe['array'] = json_unsafe.values() - json_unsafe['tuple'] = tuple(json_unsafe.values()) - json_unsafe['dict'] = json_unsafe.copy() - json_unsafe['iter'] = iter(json_unsafe.values()) - - def _test_client_content_type_good(self, content_type, ll): - def run(ll): - req = siesta.Request.blank('/') - req.environ['REQUEST_METHOD'] = 'POST' - req.content_type = content_type - req.llsd = ll - req.accept = content_type - resp = req.get_response(self.server) - self.assertEquals(resp.status_int, 200) - return req, resp - - if False and isinstance(ll, dict): - def fixup(v): - if isinstance(v, float): - return '%.5f' % v - if isinstance(v, long): - return int(v) - if isinstance(v, (llsd.binary, llsd.uri)): - return v - if isinstance(v, (tuple, list)): - return [fixup(i) for i in v] - if isinstance(v, dict): - return dict([(k, fixup(i)) for k, i in v.iteritems()]) - return v - for k, v in ll.iteritems(): - l = [k, v] - req, resp = run(l) - self.assertEquals(fixup(resp.llsd), fixup(l)) - - run(ll) - - def test_client_content_type_json_good(self): - self._test_client_content_type_good('application/json', self.json_safe) - - def test_client_content_type_llsd_xml_good(self): - self._test_client_content_type_good('application/llsd+xml', - self.json_unsafe) - - def test_client_content_type_llsd_notation_good(self): - self._test_client_content_type_good('application/llsd+notation', - self.json_unsafe) - - def test_client_content_type_llsd_binary_good(self): - self._test_client_content_type_good('application/llsd+binary', - self.json_unsafe) - - def test_client_content_type_xml_good(self): - self._test_client_content_type_good('application/xml', - self.json_unsafe) - - def _test_client_content_type_bad(self, content_type): - req = siesta.Request.blank('/') - req.environ['REQUEST_METHOD'] = 'POST' - req.body = '\0invalid nonsense under all encodings' - req.content_type = content_type - self.assertEquals(req.get_response(self.server).status_int, - exc.HTTPBadRequest.code) - - def test_client_content_type_json_bad(self): - self._test_client_content_type_bad('application/json') - - def test_client_content_type_llsd_xml_bad(self): - self._test_client_content_type_bad('application/llsd+xml') - - def test_client_content_type_llsd_notation_bad(self): - self._test_client_content_type_bad('application/llsd+notation') - - def test_client_content_type_llsd_binary_bad(self): - self._test_client_content_type_bad('application/llsd+binary') - - def test_client_content_type_xml_bad(self): - self._test_client_content_type_bad('application/xml') - - def test_client_content_type_bad(self): - req = siesta.Request.blank('/') - req.environ['REQUEST_METHOD'] = 'POST' - req.body = 'XXX' - req.content_type = 'application/nonsense' - self.assertEquals(req.get_response(self.server).status_int, - exc.HTTPUnsupportedMediaType.code) - - def test_request_default_content_type(self): - req = siesta.Request.blank('/') - self.assertEquals(req.content_type, req.default_content_type) - - def test_request_default_accept(self): - req = siesta.Request.blank('/') - from webob import acceptparse - self.assertEquals(str(req.accept).replace(' ', ''), - req.default_accept.replace(' ', '')) - - def test_request_llsd_auto_body(self): - req = siesta.Request.blank('/') - req.llsd = {'a': 2} - self.assertEquals(req.body, '<?xml version="1.0" ?><llsd><map>' - '<key>a</key><integer>2</integer></map></llsd>') - - def test_request_llsd_mod_body_changes_llsd(self): - req = siesta.Request.blank('/') - req.llsd = {'a': 2} - req.body = '<?xml version="1.0" ?><llsd><integer>1337</integer></llsd>' - self.assertEquals(req.llsd, 1337) - - def test_request_bad_llsd_fails(self): - def crashme(ctype): - def boom(): - class foo(object): pass - req = siesta.Request.blank('/') - req.content_type = ctype - req.llsd = foo() - for mime_type in siesta.llsd_parsers: - self.assertRaises(TypeError, crashme(mime_type)) - - -class ClassServer(TestBase, unittest.TestCase): - def __init__(self, *args, **kwargs): - unittest.TestCase.__init__(self, *args, **kwargs) - self.server = siesta.llsd_class(ClassApp) - - -class CallableServer(TestBase, unittest.TestCase): - def __init__(self, *args, **kwargs): - unittest.TestCase.__init__(self, *args, **kwargs) - self.server = siesta.llsd_callable(callable_app) - - -class RouterServer(unittest.TestCase): - def test_router(self): - def foo(req, quux): - print quux - - r = siesta.Router() - r.add('/foo/{quux:int}', siesta.llsd_callable(foo), methods=['GET']) - req = siesta.Request.blank('/foo/33') - req.get_response(r) - - req = siesta.Request.blank('/foo/bar') - self.assertEquals(req.get_response(r).status_int, - exc.HTTPNotFound.code) - -if __name__ == '__main__': - unittest.main() diff --git a/indra/lib/python/indra/ipc/webdav.py b/indra/lib/python/indra/ipc/webdav.py deleted file mode 100755 index 98b8499b6acd52d6cf68bc7c0655af9940869e66..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/ipc/webdav.py +++ /dev/null @@ -1,597 +0,0 @@ -""" -@file webdav.py -@brief Classes to make manipulation of a webdav store easier. - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import sys, os, httplib, urlparse -import socket, time -import xml.dom.minidom -import syslog -# import signal - -__revision__ = '0' - -dav_debug = False - - -# def urlsafe_b64decode (enc): -# return base64.decodestring (enc.replace ('_', '/').replace ('-', '+')) - -# def urlsafe_b64encode (str): -# return base64.encodestring (str).replace ('+', '-').replace ('/', '_') - - -class DAVError (Exception): - """ Base class for exceptions in this module. """ - def __init__ (self, status=0, message='', body='', details=''): - self.status = status - self.message = message - self.body = body - self.details = details - Exception.__init__ (self, '%d:%s:%s%s' % (self.status, self.message, - self.body, self.details)) - - def print_to_stderr (self): - """ print_to_stderr docstring """ - print >> sys.stderr, str (self.status) + ' ' + self.message - print >> sys.stderr, str (self.details) - - -class Timeout (Exception): - """ Timeout docstring """ - def __init__ (self, arg=''): - Exception.__init__ (self, arg) - - -def alarm_handler (signum, frame): - """ alarm_handler docstring """ - raise Timeout ('caught alarm') - - -class WebDAV: - """ WebDAV docstring """ - def __init__ (self, url, proxy=None, retries_before_fail=6): - self.init_url = url - self.init_proxy = proxy - self.retries_before_fail = retries_before_fail - url_parsed = urlparse.urlsplit (url) - - self.top_path = url_parsed[ 2 ] - # make sure top_path has a trailing / - if self.top_path == None or self.top_path == '': - self.top_path = '/' - elif len (self.top_path) > 1 and self.top_path[-1:] != '/': - self.top_path += '/' - - if dav_debug: - syslog.syslog ('new WebDAV %s : %s' % (str (url), str (proxy))) - - if proxy: - proxy_parsed = urlparse.urlsplit (proxy) - self.host_header = url_parsed[ 1 ] - host_and_port = proxy_parsed[ 1 ].split (':') - self.host = host_and_port[ 0 ] - if len (host_and_port) > 1: - self.port = int(host_and_port[ 1 ]) - else: - self.port = 80 - else: # no proxy - host_and_port = url_parsed[ 1 ].split (':') - self.host_header = None - self.host = host_and_port[ 0 ] - if len (host_and_port) > 1: - self.port = int(host_and_port[ 1 ]) - else: - self.port = 80 - - self.connection = False - self.connect () - - - def log (self, msg, depth=0): - """ log docstring """ - if dav_debug and depth == 0: - host = str (self.init_url) - if host == 'http://int.tuco.lindenlab.com:80/asset/': - host = 'tuco' - if host == 'http://harriet.lindenlab.com/asset-keep/': - host = 'harriet/asset-keep' - if host == 'http://harriet.lindenlab.com/asset-flag/': - host = 'harriet/asset-flag' - if host == 'http://harriet.lindenlab.com/asset/': - host = 'harriet/asset' - if host == 'http://ozzy.lindenlab.com/asset/': - host = 'ozzy/asset' - if host == 'http://station11.lindenlab.com:12041/:': - host = 'station11:12041' - proxy = str (self.init_proxy) - if proxy == 'None': - proxy = '' - if proxy == 'http://int.tuco.lindenlab.com:3128/': - proxy = 'tuco' - syslog.syslog ('WebDAV (%s:%s) %s' % (host, proxy, str (msg))) - - - def connect (self): - """ connect docstring """ - self.log ('connect') - self.connection = httplib.HTTPConnection (self.host, self.port) - - def __err (self, response, details): - """ __err docstring """ - raise DAVError (response.status, response.reason, response.read (), - str (self.init_url) + ':' + \ - str (self.init_proxy) + ':' + str (details)) - - def request (self, method, path, body=None, headers=None, - read_all=True, body_hook = None, recurse=0, allow_cache=True): - """ request docstring """ - # self.log ('request %s %s' % (method, path)) - if headers == None: - headers = {} - if not allow_cache: - headers['Pragma'] = 'no-cache' - headers['cache-control'] = 'no-cache' - try: - if method.lower () != 'purge': - if path.startswith ('/'): - path = path[1:] - if self.host_header: # use proxy - headers[ 'host' ] = self.host_header - fullpath = 'http://%s%s%s' % (self.host_header, - self.top_path, path) - else: # no proxy - fullpath = self.top_path + path - else: - fullpath = path - - self.connection.request (method, fullpath, body, headers) - if body_hook: - body_hook () - - # signal.signal (signal.SIGALRM, alarm_handler) - # try: - # signal.alarm (120) - # signal.alarm (0) - # except Timeout, e: - # if recurse < 6: - # return self.retry_request (method, path, body, headers, - # read_all, body_hook, recurse) - # else: - # raise DAVError (0, 'timeout', self.host, - # (method, path, body, headers, recurse)) - - response = self.connection.getresponse () - - if read_all: - while len (response.read (1024)) > 0: - pass - if (response.status == 500 or \ - response.status == 503 or \ - response.status == 403) and \ - recurse < self.retries_before_fail: - return self.retry_request (method, path, body, headers, - read_all, body_hook, recurse) - return response - except (httplib.ResponseNotReady, - httplib.BadStatusLine, - socket.error): - # if the server hangs up on us (keepalive off, broken pipe), - # we need to reconnect and try again. - if recurse < self.retries_before_fail: - return self.retry_request (method, path, body, headers, - read_all, body_hook, recurse) - raise DAVError (0, 'reconnect failed', self.host, - (method, path, body, headers, recurse)) - - - def retry_request (self, method, path, body, headers, - read_all, body_hook, recurse): - """ retry_request docstring """ - time.sleep (10.0 * recurse) - self.connect () - return self.request (method, path, body, headers, - read_all, body_hook, recurse+1) - - - - def propfind (self, path, body=None, depth=1): - """ propfind docstring """ - # self.log ('propfind %s' % path) - headers = {'Content-Type':'text/xml; charset="utf-8"', - 'Depth':str(depth)} - response = self.request ('PROPFIND', path, body, headers, False) - if response.status == 207: - return response # Multi-Status - self.__err (response, ('PROPFIND', path, body, headers, 0)) - - - def purge (self, path): - """ issue a squid purge command """ - headers = {'Accept':'*/*'} - response = self.request ('PURGE', path, None, headers) - if response.status == 200 or response.status == 404: - # 200 if it was purge, 404 if it wasn't there. - return response - self.__err (response, ('PURGE', path, None, headers)) - - - def get_file_size (self, path): - """ - Use propfind to ask a webdav server what the size of - a file is. If used on a directory (collection) return 0 - """ - self.log ('get_file_size %s' % path) - # "getcontentlength" property - # 8.1.1 Example - Retrieving Named Properties - # http://docs.python.org/lib/module-xml.dom.html - nsurl = 'http://apache.org/dav/props/' - doc = xml.dom.minidom.Document () - propfind_element = doc.createElementNS (nsurl, "D:propfind") - propfind_element.setAttributeNS (nsurl, 'xmlns:D', 'DAV:') - doc.appendChild (propfind_element) - prop_element = doc.createElementNS (nsurl, "D:prop") - propfind_element.appendChild (prop_element) - con_len_element = doc.createElementNS (nsurl, "D:getcontentlength") - prop_element.appendChild (con_len_element) - - response = self.propfind (path, doc.toxml ()) - doc.unlink () - - resp_doc = xml.dom.minidom.parseString (response.read ()) - cln = resp_doc.getElementsByTagNameNS ('DAV:','getcontentlength')[ 0 ] - try: - content_length = int (cln.childNodes[ 0 ].nodeValue) - except IndexError: - return 0 - resp_doc.unlink () - return content_length - - - def file_exists (self, path): - """ - do an http head on the given file. return True if it succeeds - """ - self.log ('file_exists %s' % path) - expect_gzip = path.endswith ('.gz') - response = self.request ('HEAD', path) - got_gzip = response.getheader ('Content-Encoding', '').strip () - if got_gzip.lower () == 'x-gzip' and expect_gzip == False: - # the asset server fakes us out if we ask for the non-gzipped - # version of an asset, but the server has the gzipped version. - return False - return response.status == 200 - - - def mkdir (self, path): - """ mkdir docstring """ - self.log ('mkdir %s' % path) - headers = {} - response = self.request ('MKCOL', path, None, headers) - if response.status == 201: - return # success - if response.status == 405: - return # directory already existed? - self.__err (response, ('MKCOL', path, None, headers, 0)) - - - def delete (self, path): - """ delete docstring """ - self.log ('delete %s' % path) - headers = {'Depth':'infinity'} # collections require infinity - response = self.request ('DELETE', path, None, headers) - if response.status == 204: - return # no content - if response.status == 404: - return # hmm - self.__err (response, ('DELETE', path, None, headers, 0)) - - - def list_directory (self, path, dir_filter=None, allow_cache=True, - minimum_cache_time=False): - """ - Request an http directory listing and parse the filenames out of lines - like: '<LI><A HREF="X"> X</A>'. If a filter function is provided, - only return filenames that the filter returns True for. - - This is sort of grody, but it seems faster than other ways of getting - this information from an isilon. - """ - self.log ('list_directory %s' % path) - - def try_match (lline, before, after): - """ try_match docstring """ - try: - blen = len (before) - asset_start_index = lline.index (before) - asset_end_index = lline.index (after, asset_start_index + blen) - asset = line[ asset_start_index + blen : asset_end_index ] - - if not dir_filter or dir_filter (asset): - return [ asset ] - return [] - except ValueError: - return [] - - if len (path) > 0 and path[-1:] != '/': - path += '/' - - response = self.request ('GET', path, None, {}, False, - allow_cache=allow_cache) - - if allow_cache and minimum_cache_time: # XXX - print response.getheader ('Date') - # s = "2005-12-06T12:13:14" - # from datetime import datetime - # from time import strptime - # datetime(*strptime(s, "%Y-%m-%dT%H:%M:%S")[0:6]) - # datetime.datetime(2005, 12, 6, 12, 13, 14) - - if response.status != 200: - self.__err (response, ('GET', path, None, {}, 0)) - assets = [] - for line in response.read ().split ('\n'): - lline = line.lower () - if lline.find ("parent directory") == -1: - # isilon file - assets += try_match (lline, '<li><a href="', '"> ') - # apache dir - assets += try_match (lline, 'alt="[dir]"> <a href="', '/">') - # apache file - assets += try_match (lline, 'alt="[ ]"> <a href="', '">') - return assets - - - def __tmp_filename (self, path_and_file): - """ __tmp_filename docstring """ - head, tail = os.path.split (path_and_file) - if head != '': - return head + '/.' + tail + '.' + str (os.getpid ()) - else: - return head + '.' + tail + '.' + str (os.getpid ()) - - - def __put__ (self, filesize, body_hook, remotefile): - """ __put__ docstring """ - headers = {'Content-Length' : str (filesize)} - remotefile_tmp = self.__tmp_filename (remotefile) - response = self.request ('PUT', remotefile_tmp, None, - headers, True, body_hook) - if not response.status in (201, 204): # created, no content - self.__err (response, ('PUT', remotefile, None, headers, 0)) - if filesize != self.get_file_size (remotefile_tmp): - try: - self.delete (remotefile_tmp) - except: - pass - raise DAVError (0, 'tmp upload error', remotefile_tmp) - # move the file to its final location - try: - self.rename (remotefile_tmp, remotefile) - except DAVError, exc: - if exc.status == 403: # try to clean up the tmp file - try: - self.delete (remotefile_tmp) - except: - pass - raise - if filesize != self.get_file_size (remotefile): - raise DAVError (0, 'file upload error', str (remotefile_tmp)) - - - def put_string (self, strng, remotefile): - """ put_string docstring """ - self.log ('put_string %d -> %s' % (len (strng), remotefile)) - filesize = len (strng) - def body_hook (): - """ body_hook docstring """ - self.connection.send (strng) - self.__put__ (filesize, body_hook, remotefile) - - - def put_file (self, localfile, remotefile): - """ - Send a local file to a remote webdav store. First, upload to - a temporary filename. Next make sure the file is the size we - expected. Next, move the file to its final location. Next, - check the file size at the final location. - """ - self.log ('put_file %s -> %s' % (localfile, remotefile)) - filesize = os.path.getsize (localfile) - def body_hook (): - """ body_hook docstring """ - handle = open (localfile) - while True: - data = handle.read (1300) - if len (data) == 0: - break - self.connection.send (data) - handle.close () - self.__put__ (filesize, body_hook, remotefile) - - - def create_empty_file (self, remotefile): - """ create an empty file """ - self.log ('touch_file %s' % (remotefile)) - headers = {'Content-Length' : '0'} - response = self.request ('PUT', remotefile, None, headers) - if not response.status in (201, 204): # created, no content - self.__err (response, ('PUT', remotefile, None, headers, 0)) - if self.get_file_size (remotefile) != 0: - raise DAVError (0, 'file upload error', str (remotefile)) - - - def __get_file_setup (self, remotefile, check_size=True): - """ __get_file_setup docstring """ - if check_size: - remotesize = self.get_file_size (remotefile) - response = self.request ('GET', remotefile, None, {}, False) - if response.status != 200: - self.__err (response, ('GET', remotefile, None, {}, 0)) - try: - content_length = int (response.getheader ("Content-Length")) - except TypeError: - content_length = None - if check_size: - if content_length != remotesize: - raise DAVError (0, 'file DL size error', remotefile) - return (response, content_length) - - - def __get_file_read (self, writehandle, response, content_length): - """ __get_file_read docstring """ - if content_length != None: - so_far_length = 0 - while so_far_length < content_length: - data = response.read (content_length - so_far_length) - if len (data) == 0: - raise DAVError (0, 'short file download') - so_far_length += len (data) - writehandle.write (data) - while len (response.read ()) > 0: - pass - else: - while True: - data = response.read () - if (len (data) < 1): - break - writehandle.write (data) - - - def get_file (self, remotefile, localfile, check_size=True): - """ - Get a remote file from a webdav server. Download to a local - tmp file, then move into place. Sanity check file sizes as - we go. - """ - self.log ('get_file %s -> %s' % (remotefile, localfile)) - (response, content_length) = \ - self.__get_file_setup (remotefile, check_size) - localfile_tmp = self.__tmp_filename (localfile) - handle = open (localfile_tmp, 'w') - self.__get_file_read (handle, response, content_length) - handle.close () - if check_size: - if content_length != os.path.getsize (localfile_tmp): - raise DAVError (0, 'file DL size error', - remotefile+','+localfile) - os.rename (localfile_tmp, localfile) - - - def get_file_as_string (self, remotefile, check_size=True): - """ - download a file from a webdav server and return it as a string. - """ - self.log ('get_file_as_string %s' % remotefile) - (response, content_length) = \ - self.__get_file_setup (remotefile, check_size) - # (tmp_handle, tmp_filename) = tempfile.mkstemp () - tmp_handle = os.tmpfile () - self.__get_file_read (tmp_handle, response, content_length) - tmp_handle.seek (0) - ret = tmp_handle.read () - tmp_handle.close () - # os.unlink (tmp_filename) - return ret - - - def get_post_as_string (self, remotefile, body): - """ - Do an http POST, send body, get response and return it. - """ - self.log ('get_post_as_string %s' % remotefile) - # headers = {'Content-Type':'application/x-www-form-urlencoded'} - headers = {'Content-Type':'text/xml; charset="utf-8"'} - # b64body = urlsafe_b64encode (asset_url) - response = self.request ('POST', remotefile, body, headers, False) - if response.status != 200: - self.__err (response, ('POST', remotefile, body, headers, 0)) - try: - content_length = int (response.getheader ('Content-Length')) - except TypeError: - content_length = None - tmp_handle = os.tmpfile () - self.__get_file_read (tmp_handle, response, content_length) - tmp_handle.seek (0) - ret = tmp_handle.read () - tmp_handle.close () - return ret - - - def __destination_command (self, verb, remotesrc, dstdav, remotedst): - """ - self and dstdav should point to the same http server. - """ - if len (remotedst) > 0 and remotedst[ 0 ] == '/': - remotedst = remotedst[1:] - headers = {'Destination': 'http://%s:%d%s%s' % (dstdav.host, - dstdav.port, - dstdav.top_path, - remotedst)} - response = self.request (verb, remotesrc, None, headers) - if response.status == 201: - return # created - if response.status == 204: - return # no content - self.__err (response, (verb, remotesrc, None, headers, 0)) - - - def rename (self, remotesrc, remotedst): - """ rename a file on a webdav server """ - self.log ('rename %s -> %s' % (remotesrc, remotedst)) - self.__destination_command ('MOVE', remotesrc, self, remotedst) - def xrename (self, remotesrc, dstdav, remotedst): - """ rename a file on a webdav server """ - self.log ('xrename %s -> %s' % (remotesrc, remotedst)) - self.__destination_command ('MOVE', remotesrc, dstdav, remotedst) - - - def copy (self, remotesrc, remotedst): - """ copy a file on a webdav server """ - self.log ('copy %s -> %s' % (remotesrc, remotedst)) - self.__destination_command ('COPY', remotesrc, self, remotedst) - def xcopy (self, remotesrc, dstdav, remotedst): - """ copy a file on a webdav server """ - self.log ('xcopy %s -> %s' % (remotesrc, remotedst)) - self.__destination_command ('COPY', remotesrc, dstdav, remotedst) - - -def put_string (data, url): - """ - upload string s to a url - """ - url_parsed = urlparse.urlsplit (url) - dav = WebDAV ('%s://%s/' % (url_parsed[ 0 ], url_parsed[ 1 ])) - dav.put_string (data, url_parsed[ 2 ]) - - -def get_string (url, check_size=True): - """ - return the contents of a url as a string - """ - url_parsed = urlparse.urlsplit (url) - dav = WebDAV ('%s://%s/' % (url_parsed[ 0 ], url_parsed[ 1 ])) - return dav.get_file_as_string (url_parsed[ 2 ], check_size) diff --git a/indra/lib/python/indra/ipc/xml_rpc.py b/indra/lib/python/indra/ipc/xml_rpc.py deleted file mode 100755 index 47536c10c398a7986a7e009fc2ff53538d7d62fa..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/ipc/xml_rpc.py +++ /dev/null @@ -1,273 +0,0 @@ -"""\ -@file xml_rpc.py -@brief An implementation of a parser/generator for the XML-RPC xml format. - -$LicenseInfo:firstyear=2006&license=mit$ - -Copyright (c) 2006-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - - -from greenlet import greenlet - -from mulib import mu - -from xml.sax import handler -from xml.sax import parseString - - -# States -class Expected(object): - def __init__(self, tag): - self.tag = tag - - def __getattr__(self, name): - return type(self)(name) - - def __repr__(self): - return '%s(%r)' % ( - type(self).__name__, self.tag) - - -class START(Expected): - pass - - -class END(Expected): - pass - - -class STR(object): - tag = '' - - -START = START('') -END = END('') - - -class Malformed(Exception): - pass - - -class XMLParser(handler.ContentHandler): - def __init__(self, state_machine, next_states): - handler.ContentHandler.__init__(self) - self.state_machine = state_machine - if not isinstance(next_states, tuple): - next_states = (next_states, ) - self.next_states = next_states - self._character_buffer = '' - - def assertState(self, state, name, *rest): - if not isinstance(self.next_states, tuple): - self.next_states = (self.next_states, ) - for next in self.next_states: - if type(state) == type(next): - if next.tag and next.tag != name: - raise Malformed( - "Expected %s, got %s %s %s" % ( - next, state, name, rest)) - break - else: - raise Malformed( - "Expected %s, got %s %s %s" % ( - self.next_states, state, name, rest)) - - def startElement(self, name, attrs): - self.assertState(START, name.lower(), attrs) - self.next_states = self.state_machine.switch(START, (name.lower(), dict(attrs))) - - def endElement(self, name): - if self._character_buffer.strip(): - characters = self._character_buffer.strip() - self._character_buffer = '' - self.assertState(STR, characters) - self.next_states = self.state_machine.switch(characters) - self.assertState(END, name.lower()) - self.next_states = self.state_machine.switch(END, name.lower()) - - def error(self, exc): - self.bozo = 1 - self.exc = exc - - def fatalError(self, exc): - self.error(exc) - raise exc - - def characters(self, characters): - self._character_buffer += characters - - -def parse(what): - child = greenlet(xml_rpc) - me = greenlet.getcurrent() - startup_states = child.switch(me) - parser = XMLParser(child, startup_states) - try: - parseString(what, parser) - except Malformed: - print what - raise - return child.switch() - - -def xml_rpc(yielder): - yielder.switch(START.methodcall) - yielder.switch(START.methodname) - methodName = yielder.switch(STR) - yielder.switch(END.methodname) - - yielder.switch(START.params) - - root = None - params = [] - while True: - state, _ = yielder.switch(START.param, END.params) - if state == END: - break - - yielder.switch(START.value) - - params.append( - handle(yielder)) - - yielder.switch(END.value) - yielder.switch(END.param) - - yielder.switch(END.methodcall) - ## Resume parse - yielder.switch() - ## Return result to parse - return methodName.strip(), params - - -def handle(yielder): - _, (tag, attrs) = yielder.switch(START) - if tag in ['int', 'i4']: - result = int(yielder.switch(STR)) - elif tag == 'boolean': - result = bool(int(yielder.switch(STR))) - elif tag == 'string': - result = yielder.switch(STR) - elif tag == 'double': - result = float(yielder.switch(STR)) - elif tag == 'datetime.iso8601': - result = yielder.switch(STR) - elif tag == 'base64': - result = base64.b64decode(yielder.switch(STR)) - elif tag == 'struct': - result = {} - while True: - state, _ = yielder.switch(START.member, END.struct) - if state == END: - break - - yielder.switch(START.name) - key = yielder.switch(STR) - yielder.switch(END.name) - - yielder.switch(START.value) - result[key] = handle(yielder) - yielder.switch(END.value) - - yielder.switch(END.member) - ## We already handled </struct> above, don't want to handle it below - return result - elif tag == 'array': - result = [] - yielder.switch(START.data) - while True: - state, _ = yielder.switch(START.value, END.data) - if state == END: - break - - result.append(handle(yielder)) - - yielder.switch(END.value) - - yielder.switch(getattr(END, tag)) - - return result - - -VALUE = mu.tag_factory('value') -BOOLEAN = mu.tag_factory('boolean') -INT = mu.tag_factory('int') -STRUCT = mu.tag_factory('struct') -MEMBER = mu.tag_factory('member') -NAME = mu.tag_factory('name') -ARRAY = mu.tag_factory('array') -DATA = mu.tag_factory('data') -STRING = mu.tag_factory('string') -DOUBLE = mu.tag_factory('double') -METHODRESPONSE = mu.tag_factory('methodResponse') -PARAMS = mu.tag_factory('params') -PARAM = mu.tag_factory('param') - -mu.inline_elements['string'] = True -mu.inline_elements['boolean'] = True -mu.inline_elements['name'] = True - - -def _generate(something): - if isinstance(something, dict): - result = STRUCT() - for key, value in something.items(): - result[ - MEMBER[ - NAME[key], _generate(value)]] - return VALUE[result] - elif isinstance(something, list): - result = DATA() - for item in something: - result[_generate(item)] - return VALUE[ARRAY[[result]]] - elif isinstance(something, basestring): - return VALUE[STRING[something]] - elif isinstance(something, bool): - if something: - return VALUE[BOOLEAN['1']] - return VALUE[BOOLEAN['0']] - elif isinstance(something, int): - return VALUE[INT[something]] - elif isinstance(something, float): - return VALUE[DOUBLE[something]] - -def generate(*args): - params = PARAMS() - for arg in args: - params[PARAM[_generate(arg)]] - return METHODRESPONSE[params] - - -if __name__ == '__main__': - print parse("""<?xml version="1.0"?> <methodCall> <methodName>examples.getStateName</methodName> <params> <param> <value><i4>41</i4></value> </param> </params> </methodCall> -""") - - - - - - - - - diff --git a/indra/lib/python/indra/util/fastest_elementtree.py b/indra/lib/python/indra/util/fastest_elementtree.py deleted file mode 100755 index 4fcf662dd90946ac48b9167cd9eb0e48bca97e2f..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/fastest_elementtree.py +++ /dev/null @@ -1,64 +0,0 @@ -"""\ -@file fastest_elementtree.py -@brief Concealing some gnarly import logic in here. This should export the interface of elementtree. - -$LicenseInfo:firstyear=2008&license=mit$ - -Copyright (c) 2008-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -# The parsing exception raised by the underlying library depends -# on the ElementTree implementation we're using, so we provide an -# alias here. -# -# Use ElementTreeError as the exception type for catching parsing -# errors. - - -# Using cElementTree might cause some unforeseen problems, so here's a -# convenient off switch. -use_celementree = True - -try: - if not use_celementree: - raise ImportError() - # Python 2.3 and 2.4. - from cElementTree import * - ElementTreeError = SyntaxError -except ImportError: - try: - if not use_celementree: - raise ImportError() - # Python 2.5 and above. - from xml.etree.cElementTree import * - ElementTreeError = SyntaxError - except ImportError: - # Pure Python code. - try: - # Python 2.3 and 2.4. - from elementtree.ElementTree import * - except ImportError: - # Python 2.5 and above. - from xml.etree.ElementTree import * - - # The pure Python ElementTree module uses Expat for parsing. - from xml.parsers.expat import ExpatError as ElementTreeError diff --git a/indra/lib/python/indra/util/helpformatter.py b/indra/lib/python/indra/util/helpformatter.py deleted file mode 100755 index ba5c9b67d183bb91efcd295dfea7fbc96df7d2de..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/helpformatter.py +++ /dev/null @@ -1,52 +0,0 @@ -"""\ -@file helpformatter.py -@author Phoenix -@brief Class for formatting optparse descriptions. - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import optparse -import textwrap - -class Formatter(optparse.IndentedHelpFormatter): - def __init__( - self, - p_indentIncrement = 2, - p_maxHelpPosition = 24, - p_width = 79, - p_shortFirst = 1) : - optparse.HelpFormatter.__init__( - self, - p_indentIncrement, - p_maxHelpPosition, - p_width, - p_shortFirst) - def format_description(self, p_description): - t_descWidth = self.width - self.current_indent - t_indent = " " * (self.current_indent + 2) - return "\n".join( - [textwrap.fill(descr, t_descWidth, initial_indent = t_indent, - subsequent_indent = t_indent) - for descr in p_description.split("\n")] ) diff --git a/indra/lib/python/indra/util/iterators.py b/indra/lib/python/indra/util/iterators.py deleted file mode 100755 index 9013fa63036fdc452d502150ec53f558814453b0..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/iterators.py +++ /dev/null @@ -1,63 +0,0 @@ -"""\ -@file iterators.py -@brief Useful general-purpose iterators. - -$LicenseInfo:firstyear=2008&license=mit$ - -Copyright (c) 2008-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -from __future__ import nested_scopes - -def iter_chunks(rows, aggregate_size=100): - """ - Given an iterable set of items (@p rows), produces lists of up to @p - aggregate_size items at a time, for example: - - iter_chunks([1,2,3,4,5,6,7,8,9,10], 3) - - Values for @p aggregate_size < 1 will raise ValueError. - - Will return a generator that produces, in the following order: - - [1, 2, 3] - - [4, 5, 6] - - [7, 8, 9] - - [10] - """ - if aggregate_size < 1: - raise ValueError() - - def iter_chunks_inner(): - row_iter = iter(rows) - done = False - agg = [] - while not done: - try: - row = row_iter.next() - agg.append(row) - except StopIteration: - done = True - if agg and (len(agg) >= aggregate_size or done): - yield agg - agg = [] - - return iter_chunks_inner() diff --git a/indra/lib/python/indra/util/iterators_test.py b/indra/lib/python/indra/util/iterators_test.py deleted file mode 100755 index 66928c8e7d27aae455748559a795068084130c0b..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/iterators_test.py +++ /dev/null @@ -1,72 +0,0 @@ -"""\ -@file iterators_test.py -@brief Test cases for iterators module. - -$LicenseInfo:firstyear=2008&license=mit$ - -Copyright (c) 2008-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import unittest - -from indra.util.iterators import iter_chunks - -class TestIterChunks(unittest.TestCase): - """Unittests for iter_chunks""" - def test_bad_agg_size(self): - rows = [1,2,3,4] - self.assertRaises(ValueError, iter_chunks, rows, 0) - self.assertRaises(ValueError, iter_chunks, rows, -1) - - try: - for i in iter_chunks(rows, 0): - pass - except ValueError: - pass - else: - self.fail() - - try: - result = list(iter_chunks(rows, 0)) - except ValueError: - pass - else: - self.fail() - def test_empty(self): - rows = [] - result = list(iter_chunks(rows)) - self.assertEqual(result, []) - def test_small(self): - rows = [[1]] - result = list(iter_chunks(rows, 2)) - self.assertEqual(result, [[[1]]]) - def test_size(self): - rows = [[1],[2]] - result = list(iter_chunks(rows, 2)) - self.assertEqual(result, [[[1],[2]]]) - def test_multi_agg(self): - rows = [[1],[2],[3],[4],[5]] - result = list(iter_chunks(rows, 2)) - self.assertEqual(result, [[[1],[2]],[[3],[4]],[[5]]]) - -if __name__ == "__main__": - unittest.main() diff --git a/indra/lib/python/indra/util/llperformance.py b/indra/lib/python/indra/util/llperformance.py deleted file mode 100755 index 57dd64de3fa04706eb69793361180cf52dee0fe3..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/llperformance.py +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env python -"""\ -@file llperformance.py - -$LicenseInfo:firstyear=2010&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2010-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$ -""" - -# ------------------------------------------------ -# Sim metrics utility functions. - -import glob, os, time, sys, stat, exceptions - -from indra.base import llsd - -gBlockMap = {} #Map of performance metric data with function hierarchy information. -gCurrentStatPath = "" - -gIsLoggingEnabled=False - -class LLPerfStat: - def __init__(self,key): - self.mTotalTime = 0 - self.mNumRuns = 0 - self.mName=key - self.mTimeStamp = int(time.time()*1000) - self.mUTCTime = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) - - def __str__(self): - return "%f" % self.mTotalTime - - def start(self): - self.mStartTime = int(time.time() * 1000000) - self.mNumRuns += 1 - - def stop(self): - execution_time = int(time.time() * 1000000) - self.mStartTime - self.mTotalTime += execution_time - - def get_map(self): - results={} - results['name']=self.mName - results['utc_time']=self.mUTCTime - results['timestamp']=self.mTimeStamp - results['us']=self.mTotalTime - results['count']=self.mNumRuns - return results - -class PerfError(exceptions.Exception): - def __init__(self): - return - - def __Str__(self): - print "","Unfinished LLPerfBlock" - -class LLPerfBlock: - def __init__( self, key ): - global gBlockMap - global gCurrentStatPath - global gIsLoggingEnabled - - #Check to see if we're running metrics right now. - if gIsLoggingEnabled: - self.mRunning = True #Mark myself as running. - - self.mPreviousStatPath = gCurrentStatPath - gCurrentStatPath += "/" + key - if gCurrentStatPath not in gBlockMap: - gBlockMap[gCurrentStatPath] = LLPerfStat(key) - - self.mStat = gBlockMap[gCurrentStatPath] - self.mStat.start() - - def finish( self ): - global gBlockMap - global gIsLoggingEnabled - - if gIsLoggingEnabled: - self.mStat.stop() - self.mRunning = False - gCurrentStatPath = self.mPreviousStatPath - -# def __del__( self ): -# if self.mRunning: -# #SPATTERS FIXME -# raise PerfError - -class LLPerformance: - #-------------------------------------------------- - # Determine whether or not we want to log statistics - - def __init__( self, process_name = "python" ): - self.process_name = process_name - self.init_testing() - self.mTimeStamp = int(time.time()*1000) - self.mUTCTime = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) - - def init_testing( self ): - global gIsLoggingEnabled - - host_performance_file = "/dev/shm/simperf/simperf_proc_config.llsd" - - #If file exists, open - if os.path.exists(host_performance_file): - file = open (host_performance_file,'r') - - #Read serialized LLSD from file. - body = llsd.parse(file.read()) - - #Calculate time since file last modified. - stats = os.stat(host_performance_file) - now = time.time() - mod = stats[stat.ST_MTIME] - age = now - mod - - if age < ( body['duration'] ): - gIsLoggingEnabled = True - - - def get ( self ): - global gIsLoggingEnabled - return gIsLoggingEnabled - - #def output(self,ptr,path): - # if 'stats' in ptr: - # stats = ptr['stats'] - # self.mOutputPtr[path] = stats.get_map() - - # if 'children' in ptr: - # children=ptr['children'] - - # curptr = self.mOutputPtr - # curchildren={} - # curptr['children'] = curchildren - - # for key in children: - # curchildren[key]={} - # self.mOutputPtr = curchildren[key] - # self.output(children[key],path + '/' + key) - - def done(self): - global gBlockMap - - if not self.get(): - return - - output_name = "/dev/shm/simperf/%s_proc.%d.llsd" % (self.process_name, os.getpid()) - output_file = open(output_name, 'w') - process_info = { - "name" : self.process_name, - "pid" : os.getpid(), - "ppid" : os.getppid(), - "timestamp" : self.mTimeStamp, - "utc_time" : self.mUTCTime, - } - output_file.write(llsd.format_notation(process_info)) - output_file.write('\n') - - for key in gBlockMap.keys(): - gBlockMap[key] = gBlockMap[key].get_map() - output_file.write(llsd.format_notation(gBlockMap)) - output_file.write('\n') - output_file.close() - diff --git a/indra/lib/python/indra/util/llsubprocess.py b/indra/lib/python/indra/util/llsubprocess.py deleted file mode 100755 index 7e0e115d14600f29fe4b855077232a8d10529271..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/llsubprocess.py +++ /dev/null @@ -1,117 +0,0 @@ -"""\ -@file llsubprocess.py -@author Phoenix -@date 2008-01-18 -@brief The simplest possible wrapper for a common sub-process paradigm. - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import os -import popen2 -import time -import select - -class Timeout(RuntimeError): - "Exception raised when a subprocess times out." - pass - -def run(command, args=None, data=None, timeout=None): - """\ -@brief Run command with arguments - -This is it. This is the function I want to run all the time when doing -subprocces, but end up copying the code everywhere. none of the -standard commands are secure and provide a way to specify input, get -all the output, and get the result. -@param command A string specifying a process to launch. -@param args Arguments to be passed to command. Must be list, tuple or None. -@param data input to feed to the command. -@param timeout Maximum number of many seconds to run. -@return Returns (result, stdout, stderr) from process. -""" - cmd = [command] - if args: - cmd.extend([str(arg) for arg in args]) - #print "cmd: ","' '".join(cmd) - child = popen2.Popen3(cmd, True) - #print child.pid - out = [] - err = [] - result = -1 - time_left = timeout - tochild = [child.tochild.fileno()] - while True: - time_start = time.time() - #print "time:",time_left - p_in, p_out, p_err = select.select( - [child.fromchild.fileno(), child.childerr.fileno()], - tochild, - [], - time_left) - if p_in: - new_line = os.read(child.fromchild.fileno(), 32 * 1024) - if new_line: - #print "line:",new_line - out.append(new_line) - new_line = os.read(child.childerr.fileno(), 32 * 1024) - if new_line: - #print "error:", new_line - err.append(new_line) - if p_out: - if data: - #print "p_out" - bytes = os.write(child.tochild.fileno(), data) - data = data[bytes:] - if len(data) == 0: - data = None - tochild = [] - child.tochild.close() - result = child.poll() - if result != -1: - # At this point, the child process has exited and result - # is the return value from the process. Between the time - # we called select() and poll() the process may have - # exited so read all the data left on the child process - # stdout and stderr. - last = child.fromchild.read() - if last: - out.append(last) - last = child.childerr.read() - if last: - err.append(last) - child.tochild.close() - child.fromchild.close() - child.childerr.close() - break - if time_left is not None: - time_left -= (time.time() - time_start) - if time_left < 0: - raise Timeout - #print "result:",result - out = ''.join(out) - #print "stdout:", out - err = ''.join(err) - #print "stderr:", err - return result, out, err diff --git a/indra/lib/python/indra/util/named_query.py b/indra/lib/python/indra/util/named_query.py deleted file mode 100755 index 6bf956107dec95dc92d042eab0920da463cea872..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/named_query.py +++ /dev/null @@ -1,592 +0,0 @@ -"""\ -@file named_query.py -@author Ryan Williams, Phoenix -@date 2007-07-31 -@brief An API for running named queries. - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import errno -import MySQLdb -import MySQLdb.cursors -import os -import os.path -import re -import time - -from indra.base import llsd -from indra.base import config - -DEBUG = False -NQ_FILE_SUFFIX = config.get('named-query-file-suffix', '.nq') -NQ_FILE_SUFFIX_LEN = len(NQ_FILE_SUFFIX) - -_g_named_manager = None - -def _init_g_named_manager(sql_dir = None): - """Initializes a global NamedManager object to point at a - specified named queries hierarchy. - - This function is intended entirely for testing purposes, - because it's tricky to control the config from inside a test.""" - global NQ_FILE_SUFFIX - NQ_FILE_SUFFIX = config.get('named-query-file-suffix', '.nq') - global NQ_FILE_SUFFIX_LEN - NQ_FILE_SUFFIX_LEN = len(NQ_FILE_SUFFIX) - - if sql_dir is None: - sql_dir = config.get('named-query-base-dir') - - # extra fallback directory in case config doesn't return what we want - if sql_dir is None: - sql_dir = os.path.abspath( - os.path.join( - os.path.realpath(os.path.dirname(__file__)), "..", "..", "..", "..", "web", "dataservice", "sql")) - - global _g_named_manager - _g_named_manager = NamedQueryManager( - os.path.abspath(os.path.realpath(sql_dir))) - -def get(name, schema = None): - "Get the named query object to be used to perform queries" - if _g_named_manager is None: - _init_g_named_manager() - return _g_named_manager.get(name).for_schema(schema) - -def sql(connection, name, params): - # use module-global NamedQuery object to perform default substitution - return get(name).sql(connection, params) - -def run(connection, name, params, expect_rows = None): - """\ -@brief given a connection, run a named query with the params - -Note that this function will fetch ALL rows. -@param connection The connection to use -@param name The name of the query to run -@param params The parameters passed into the query -@param expect_rows The number of rows expected. Set to 1 if return_as_map is true. Raises ExpectationFailed if the number of returned rows doesn't exactly match. Kind of a hack. -@return Returns the result set as a list of dicts. -""" - return get(name).run(connection, params, expect_rows) - -class ExpectationFailed(Exception): - """ Exception that is raised when an expectation for an sql query - is not met.""" - def __init__(self, message): - Exception.__init__(self, message) - self.message = message - -class NamedQuery(object): - def __init__(self, name, filename): - """ Construct a NamedQuery object. The name argument is an - arbitrary name as a handle for the query, and the filename is - a path to a file or a file-like object containing an llsd named - query document.""" - self._stat_interval_seconds = 5 # 5 seconds - self._name = name - if (filename is not None and isinstance(filename, (str, unicode)) - and NQ_FILE_SUFFIX != filename[-NQ_FILE_SUFFIX_LEN:]): - filename = filename + NQ_FILE_SUFFIX - self._location = filename - self._alternative = dict() - self._last_mod_time = 0 - self._last_check_time = 0 - self.deleted = False - self.load_contents() - - def name(self): - """ The name of the query. """ - return self._name - - def get_modtime(self): - """ Returns the mtime (last modified time) of the named query - filename. For file-like objects, expect a modtime of 0""" - if self._location and isinstance(self._location, (str, unicode)): - return os.path.getmtime(self._location) - return 0 - - def load_contents(self): - """ Loads and parses the named query file into self. Does - nothing if self.location is nonexistant.""" - if self._location: - if isinstance(self._location, (str, unicode)): - contents = llsd.parse(open(self._location).read()) - else: - # we probably have a file-like object. Godspeed! - contents = llsd.parse(self._location.read()) - self._reference_contents(contents) - # Check for alternative implementations - try: - for name, alt in self._contents['alternative'].items(): - nq = NamedQuery(name, None) - nq._reference_contents(alt) - self._alternative[name] = nq - except KeyError, e: - pass - self._last_mod_time = self.get_modtime() - self._last_check_time = time.time() - - def _reference_contents(self, contents): - "Helper method which builds internal structure from parsed contents" - self._contents = contents - self._ttl = int(self._contents.get('ttl', 0)) - self._return_as_map = bool(self._contents.get('return_as_map', False)) - self._legacy_dbname = self._contents.get('legacy_dbname', None) - - # reset these before doing the sql conversion because we will - # read them there. reset these while loading so we pick up - # changes. - self._around = set() - self._append = set() - self._integer = set() - self._options = self._contents.get('dynamic_where', {}) - for key in self._options: - if isinstance(self._options[key], basestring): - self._options[key] = self._convert_sql(self._options[key]) - elif isinstance(self._options[key], list): - lines = [] - for line in self._options[key]: - lines.append(self._convert_sql(line)) - self._options[key] = lines - else: - moreopt = {} - for kk in self._options[key]: - moreopt[kk] = self._convert_sql(self._options[key][kk]) - self._options[key] = moreopt - self._base_query = self._convert_sql(self._contents['base_query']) - self._query_suffix = self._convert_sql( - self._contents.get('query_suffix', '')) - - def _convert_sql(self, sql): - """convert the parsed sql into a useful internal structure. - - This function has to turn the named query format into a pyformat - style. It also has to look for %:name% and :name% and - ready them for use in LIKE statements""" - if sql: - # This first sub is to properly escape any % signs that - # are meant to be literally passed through to mysql in the - # query. It leaves any %'s that are used for - # like-expressions. - expr = re.compile("(?<=[^a-zA-Z0-9_-])%(?=[^:])") - sql = expr.sub('%%', sql) - - # This should tackle the rest of the %'s in the query, by - # converting them to LIKE clauses. - expr = re.compile("(%?):([a-zA-Z][a-zA-Z0-9_-]*)%") - sql = expr.sub(self._prepare_like, sql) - expr = re.compile("#:([a-zA-Z][a-zA-Z0-9_-]*)") - sql = expr.sub(self._prepare_integer, sql) - expr = re.compile(":([a-zA-Z][a-zA-Z0-9_-]*)") - sql = expr.sub("%(\\1)s", sql) - return sql - - def _prepare_like(self, match): - """This function changes LIKE statement replace behavior - - It works by turning %:name% to %(_name_around)s and :name% to - %(_name_append)s. Since a leading '_' is not a valid keyname - input (enforced via unit tests), it will never clash with - existing keys. Then, when building the statement, the query - runner will generate corrected strings.""" - if match.group(1) == '%': - # there is a leading % so this is treated as prefix/suffix - self._around.add(match.group(2)) - return "%(" + self._build_around_key(match.group(2)) + ")s" - else: - # there is no leading %, so this is suffix only - self._append.add(match.group(2)) - return "%(" + self._build_append_key(match.group(2)) + ")s" - - def _build_around_key(self, key): - return "_" + key + "_around" - - def _build_append_key(self, key): - return "_" + key + "_append" - - def _prepare_integer(self, match): - """This function adjusts the sql for #:name replacements - - It works by turning #:name to %(_name_as_integer)s. Since a - leading '_' is not a valid keyname input (enforced via unit - tests), it will never clash with existing keys. Then, when - building the statement, the query runner will generate - corrected strings.""" - self._integer.add(match.group(1)) - return "%(" + self._build_integer_key(match.group(1)) + ")s" - - def _build_integer_key(self, key): - return "_" + key + "_as_integer" - - def _strip_wildcards_to_list(self, value): - """Take string, and strip out the LIKE special characters. - - Technically, this is database dependant, but postgresql and - mysql use the same wildcards, and I am not aware of a general - way to handle this. I think you need a sql statement of the - form: - - LIKE_STRING( [ANY,ONE,str]... ) - - which would treat ANY as their any string, and ONE as their - single glyph, and str as something that needs database - specific encoding to not allow any % or _ to affect the query. - - As it stands, I believe it's impossible to write a named query - style interface which uses like to search the entire space of - text available. Imagine the query: - - % of brain used by average linden - - In order to search for %, it must be escaped, so once you have - escaped the string to not do wildcard searches, and be escaped - for the database, and then prepended the wildcard you come - back with one of: - - 1) %\% of brain used by average linden - 2) %%% of brain used by average linden - - Then, when passed to the database to be escaped to be database - safe, you get back: - - 1) %\\% of brain used by average linden - : which means search for any character sequence, followed by a - backslash, followed by any sequence, followed by ' of - brain...' - 2) %%% of brain used by average linden - : which (I believe) means search for a % followed by any - character sequence followed by 'of brain...' - - Neither of which is what we want! - - So, we need a vendor (or extention) for LIKE_STRING. Anyone - want to write it?""" - if isinstance(value, unicode): - utf8_value = value - else: - utf8_value = unicode(value, "utf-8") - esc_list = [] - remove_chars = set(u"%_") - for glyph in utf8_value: - if glyph in remove_chars: - continue - esc_list.append(glyph.encode("utf-8")) - return esc_list - - def delete(self): - """ Makes this query unusable by deleting all the members and - setting the deleted member. This is desired when the on-disk - query has been deleted but the in-memory copy remains.""" - # blow away all members except _name, _location, and deleted - name, location = self._name, self._location - for key in self.__dict__.keys(): - del self.__dict__[key] - self.deleted = True - self._name, self._location = name, location - - def ttl(self): - """ Estimated time to live of this query. Used for web - services to set the Expires header.""" - return self._ttl - - def legacy_dbname(self): - return self._legacy_dbname - - def return_as_map(self): - """ Returns true if this query is configured to return its - results as a single map (as opposed to a list of maps, the - normal behavior).""" - - return self._return_as_map - - def for_schema(self, db_name): - "Look trough the alternates and return the correct query" - if db_name is None: - return self - try: - return self._alternative[db_name] - except KeyError, e: - pass - return self - - def run(self, connection, params, expect_rows = None, use_dictcursor = True): - """given a connection, run a named query with the params - - Note that this function will fetch ALL rows. We do this because it - opens and closes the cursor to generate the values, and this - isn't a generator so the cursor has no life beyond the method call. - - @param cursor The connection to use (this generates its own cursor for the query) - @param name The name of the query to run - @param params The parameters passed into the query - @param expect_rows The number of rows expected. Set to 1 if return_as_map is true. Raises ExpectationFailed if the number of returned rows doesn't exactly match. Kind of a hack. - @param use_dictcursor Set to false to use a normal cursor and manually convert the rows to dicts. - @return Returns the result set as a list of dicts, or, if the named query has return_as_map set to true, returns a single dict. - """ - if use_dictcursor: - cursor = connection.cursor(MySQLdb.cursors.DictCursor) - else: - cursor = connection.cursor() - - full_query, params = self._construct_sql(params) - if DEBUG: - print "SQL:", self.sql(connection, params) - rows = cursor.execute(full_query, params) - - # *NOTE: the expect_rows argument is a very cheesy way to get some - # validation on the result set. If you want to add more expectation - # logic, do something more object-oriented and flexible. Or use an ORM. - if(self._return_as_map): - expect_rows = 1 - if expect_rows is not None and rows != expect_rows: - cursor.close() - raise ExpectationFailed("Statement expected %s rows, got %s. Sql: '%s' %s" % ( - expect_rows, rows, full_query, params)) - - # convert to dicts manually if we're not using a dictcursor - if use_dictcursor: - result_set = cursor.fetchall() - else: - if cursor.description is None: - # an insert or something - x = cursor.fetchall() - cursor.close() - return x - - names = [x[0] for x in cursor.description] - - result_set = [] - for row in cursor.fetchall(): - converted_row = {} - for idx, col_name in enumerate(names): - converted_row[col_name] = row[idx] - result_set.append(converted_row) - - cursor.close() - if self._return_as_map: - return result_set[0] - return result_set - - def _construct_sql(self, params): - """ Returns a query string and a dictionary of parameters, - suitable for directly passing to the execute() method.""" - self.refresh() - - # build the query from the options available and the params - base_query = [] - base_query.append(self._base_query) - for opt, extra_where in self._options.items(): - if type(extra_where) in (dict, list, tuple): - if opt in params: - base_query.append(extra_where[params[opt]]) - else: - if opt in params and params[opt]: - base_query.append(extra_where) - if self._query_suffix: - base_query.append(self._query_suffix) - full_query = '\n'.join(base_query) - - # Go through the query and rewrite all of the ones with the - # @:name syntax. - rewrite = _RewriteQueryForArray(params) - expr = re.compile("@%\(([a-zA-Z][a-zA-Z0-9_-]*)\)s") - full_query = expr.sub(rewrite.operate, full_query) - params.update(rewrite.new_params) - - # build out the params for like. We only have to do this - # parameters which were detected to have ued the where syntax - # during load. - # - # * treat the incoming string as utf-8 - # * strip wildcards - # * append or prepend % as appropriate - new_params = {} - for key in params: - if key in self._around: - new_value = ['%'] - new_value.extend(self._strip_wildcards_to_list(params[key])) - new_value.append('%') - new_params[self._build_around_key(key)] = ''.join(new_value) - if key in self._append: - new_value = self._strip_wildcards_to_list(params[key]) - new_value.append('%') - new_params[self._build_append_key(key)] = ''.join(new_value) - if key in self._integer: - new_params[self._build_integer_key(key)] = int(params[key]) - params.update(new_params) - - return full_query, params - - def sql(self, connection, params): - """ Generates an SQL statement from the named query document - and a dictionary of parameters. - - *NOTE: Only use for debugging, because it uses the - non-standard MySQLdb 'literal' method. - """ - if not DEBUG: - import warnings - warnings.warn("Don't use named_query.sql() when not debugging. Used on %s" % self._location) - # do substitution using the mysql (non-standard) 'literal' - # function to do the escaping. - full_query, params = self._construct_sql(params) - return full_query % connection.literal(params) - - - def refresh(self): - """ Refresh self from the file on the filesystem. - - This is optimized to be callable as frequently as you wish, - without adding too much load. It does so by only stat-ing the - file every N seconds, where N defaults to 5 and is - configurable through the member _stat_interval_seconds. If the stat - reveals that the file has changed, refresh will re-parse the - contents of the file and use them to update the named query - instance. If the stat reveals that the file has been deleted, - refresh will call self.delete to make the in-memory - representation unusable.""" - now = time.time() - if(now - self._last_check_time > self._stat_interval_seconds): - self._last_check_time = now - try: - modtime = self.get_modtime() - if(modtime > self._last_mod_time): - self.load_contents() - except OSError, e: - if e.errno == errno.ENOENT: # file not found - self.delete() # clean up self - raise # pass the exception along to the caller so they know that this query disappeared - -class NamedQueryManager(object): - """ Manages the lifespan of NamedQuery objects, drawing from a - directory hierarchy of named query documents. - - In practice this amounts to a memory cache of NamedQuery objects.""" - - def __init__(self, named_queries_dir): - """ Initializes a manager to look for named queries in a - directory.""" - self._dir = os.path.abspath(os.path.realpath(named_queries_dir)) - self._cached_queries = {} - - def sql(self, connection, name, params): - nq = self.get(name) - return nq.sql(connection, params) - - def get(self, name): - """ Returns a NamedQuery instance based on the name, either - from memory cache, or by parsing from disk. - - The name is simply a relative path to the directory associated - with the manager object. Before returning the instance, the - NamedQuery object is cached in memory, so that subsequent - accesses don't have to read from disk or do any parsing. This - means that NamedQuery objects returned by this method are - shared across all users of the manager object. - NamedQuery.refresh is used to bring the NamedQuery objects in - sync with the actual files on disk.""" - nq = self._cached_queries.get(name) - if nq is None: - nq = NamedQuery(name, os.path.join(self._dir, name)) - self._cached_queries[name] = nq - else: - try: - nq.refresh() - except OSError, e: - if e.errno == errno.ENOENT: # file not found - del self._cached_queries[name] - raise # pass exception along to caller so they know that the query disappeared - - return nq - -class _RewriteQueryForArray(object): - "Helper class for rewriting queries with the @:name syntax" - def __init__(self, params): - self.params = params - self.new_params = dict() - - def operate(self, match): - "Given a match, return the string that should be in use" - key = match.group(1) - value = self.params[key] - if type(value) in (list,tuple): - rv = [] - for idx in range(len(value)): - # if the value@idx is array-like, we are - # probably dealing with a VALUES - new_key = "_%s_%s"%(key, str(idx)) - val_item = value[idx] - if type(val_item) in (list, tuple, dict): - if type(val_item) is dict: - # this is because in Python, the order of - # key, value retrieval from the dict is not - # guaranteed to match what the input intended - # and for VALUES, order is important. - # TODO: Implemented ordered dict in LLSD parser? - raise ExpectationFailed('Only lists/tuples allowed,\ - received dict') - values_keys = [] - for value_idx, item in enumerate(val_item): - # we want a key of the format : - # key_#replacement_#value_row_#value_col - # ugh... so if we are replacing 10 rows in user_note, - # the first values clause would read (for @:user_notes) :- - # ( :_user_notes_0_1_1, :_user_notes_0_1_2, :_user_notes_0_1_3 ) - # the input LLSD for VALUES will look like: - # <llsd>... - # <map> - # <key>user_notes</key> - # <array> - # <array> <!-- row 1 for VALUES --> - # <string>...</string> - # <string>...</string> - # <string>...</string> - # </array> - # ... - # </array> - # </map> - # ... </llsd> - values_key = "%s_%s"%(new_key, value_idx) - self.new_params[values_key] = item - values_keys.append("%%(%s)s"%values_key) - # now collapse all these new place holders enclosed in () - # from [':_key_0_1_1', ':_key_0_1_2', ':_key_0_1_3,...] - # rv will have [ '(:_key_0_1_1, :_key_0_1_2, :_key_0_1_3)', ] - # which is flattened a few lines below join(rv) - rv.append('(%s)' % ','.join(values_keys)) - else: - self.new_params[new_key] = val_item - rv.append("%%(%s)s"%new_key) - return ','.join(rv) - else: - # not something that can be expanded, so just drop the - # leading @ in the front of the match. This will mean that - # the single value we have, be it a string, int, whatever - # (other than dict) will correctly show up, eg: - # - # where foo in (@:foobar) -- foobar is a string, so we get - # where foo in (:foobar) - return match.group(0)[1:] diff --git a/indra/lib/python/indra/util/shutil2.py b/indra/lib/python/indra/util/shutil2.py deleted file mode 100755 index 9e2e7a6ded8bbe6a7a6776dff0ef6a4fdbcd54b0..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/shutil2.py +++ /dev/null @@ -1,84 +0,0 @@ -''' -@file shutil2.py -@brief a better shutil.copytree replacement - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -''' - -# -# shutil2.py -# Taken from http://www.scons.org/wiki/AccumulateBuilder -# the stock copytree sucks because it insists that the -# target dir not exist -# - -import os.path -import shutil - -def copytree(src, dest, symlinks=False): - """My own copyTree which does not fail if the directory exists. - - Recursively copy a directory tree using copy2(). - - If the optional symlinks flag is true, symbolic links in the - source tree result in symbolic links in the destination tree; if - it is false, the contents of the files pointed to by symbolic - links are copied. - - Behavior is meant to be identical to GNU 'cp -R'. - """ - def copyItems(src, dest, symlinks=False): - """Function that does all the work. - - It is necessary to handle the two 'cp' cases: - - destination does exist - - destination does not exist - - See 'cp -R' documentation for more details - """ - for item in os.listdir(src): - srcPath = os.path.join(src, item) - if os.path.isdir(srcPath): - srcBasename = os.path.basename(srcPath) - destDirPath = os.path.join(dest, srcBasename) - if not os.path.exists(destDirPath): - os.makedirs(destDirPath) - copyItems(srcPath, destDirPath) - elif os.path.islink(item) and symlinks: - linkto = os.readlink(item) - os.symlink(linkto, dest) - else: - shutil.copy2(srcPath, dest) - - # case 'cp -R src/ dest/' where dest/ already exists - if os.path.exists(dest): - destPath = os.path.join(dest, os.path.basename(src)) - if not os.path.exists(destPath): - os.makedirs(destPath) - # case 'cp -R src/ dest/' where dest/ does not exist - else: - os.makedirs(dest) - destPath = dest - # actually copy the files - copyItems(src, destPath) diff --git a/indra/lib/python/indra/util/simperf_host_xml_parser.py b/indra/lib/python/indra/util/simperf_host_xml_parser.py deleted file mode 100755 index 672c1050c241c93779b739da2f26d4497a41fb78..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/simperf_host_xml_parser.py +++ /dev/null @@ -1,338 +0,0 @@ -#!/usr/bin/env python -"""\ -@file simperf_host_xml_parser.py -@brief Digest collector's XML dump and convert to simple dict/list structure - -$LicenseInfo:firstyear=2008&license=mit$ - -Copyright (c) 2008-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import sys, os, getopt, time -import simplejson -from xml import sax - - -def usage(): - print "Usage:" - print sys.argv[0] + " [options]" - print " Convert RRD's XML dump to JSON. Script to convert the simperf_host_collector-" - print " generated RRD dump into JSON. Steps include converting selected named" - print " fields from GAUGE type to COUNTER type by computing delta with preceding" - print " values. Top-level named fields are:" - print - print " lastupdate Time (javascript timestamp) of last data sample" - print " step Time in seconds between samples" - print " ds Data specification (name/type) for each column" - print " database Table of data samples, one time step per row" - print - print "Options:" - print " -i, --in Input settings filename. (Default: stdin)" - print " -o, --out Output settings filename. (Default: stdout)" - print " -h, --help Print this message and exit." - print - print "Example: %s -i rrddump.xml -o rrddump.json" % sys.argv[0] - print - print "Interfaces:" - print " class SimPerfHostXMLParser() # SAX content handler" - print " def simperf_host_xml_fixup(parser) # post-parse value fixup" - -class SimPerfHostXMLParser(sax.handler.ContentHandler): - - def __init__(self): - pass - - def startDocument(self): - self.rrd_last_update = 0 # public - self.rrd_step = 0 # public - self.rrd_ds = [] # public - self.rrd_records = [] # public - self._rrd_level = 0 - self._rrd_parse_state = 0 - self._rrd_chars = "" - self._rrd_capture = False - self._rrd_ds_val = {} - self._rrd_data_row = [] - self._rrd_data_row_has_nan = False - - def endDocument(self): - pass - - # Nasty little ad-hoc state machine to extract the elements that are - # necessary from the 'rrdtool dump' XML output. The same element - # name '<ds>' is used for two different data sets so we need to pay - # some attention to the actual structure to get the ones we want - # and ignore the ones we don't. - - def startElement(self, name, attrs): - self._rrd_level = self._rrd_level + 1 - self._rrd_capture = False - if self._rrd_level == 1: - if name == "rrd" and self._rrd_parse_state == 0: - self._rrd_parse_state = 1 # In <rrd> - self._rrd_capture = True - self._rrd_chars = "" - elif self._rrd_level == 2: - if self._rrd_parse_state == 1: - if name == "lastupdate": - self._rrd_parse_state = 2 # In <rrd><lastupdate> - self._rrd_capture = True - self._rrd_chars = "" - elif name == "step": - self._rrd_parse_state = 3 # In <rrd><step> - self._rrd_capture = True - self._rrd_chars = "" - elif name == "ds": - self._rrd_parse_state = 4 # In <rrd><ds> - self._rrd_ds_val = {} - self._rrd_chars = "" - elif name == "rra": - self._rrd_parse_state = 5 # In <rrd><rra> - elif self._rrd_level == 3: - if self._rrd_parse_state == 4: - if name == "name": - self._rrd_parse_state = 6 # In <rrd><ds><name> - self._rrd_capture = True - self._rrd_chars = "" - elif name == "type": - self._rrd_parse_state = 7 # In <rrd><ds><type> - self._rrd_capture = True - self._rrd_chars = "" - elif self._rrd_parse_state == 5: - if name == "database": - self._rrd_parse_state = 8 # In <rrd><rra><database> - elif self._rrd_level == 4: - if self._rrd_parse_state == 8: - if name == "row": - self._rrd_parse_state = 9 # In <rrd><rra><database><row> - self._rrd_data_row = [] - self._rrd_data_row_has_nan = False - elif self._rrd_level == 5: - if self._rrd_parse_state == 9: - if name == "v": - self._rrd_parse_state = 10 # In <rrd><rra><database><row><v> - self._rrd_capture = True - self._rrd_chars = "" - - def endElement(self, name): - self._rrd_capture = False - if self._rrd_parse_state == 10: - self._rrd_capture = self._rrd_level == 6 - if self._rrd_level == 5: - if self._rrd_chars == "NaN": - self._rrd_data_row_has_nan = True - else: - self._rrd_data_row.append(self._rrd_chars) - self._rrd_parse_state = 9 # In <rrd><rra><database><row> - elif self._rrd_parse_state == 9: - if self._rrd_level == 4: - if not self._rrd_data_row_has_nan: - self.rrd_records.append(self._rrd_data_row) - self._rrd_parse_state = 8 # In <rrd><rra><database> - elif self._rrd_parse_state == 8: - if self._rrd_level == 3: - self._rrd_parse_state = 5 # In <rrd><rra> - elif self._rrd_parse_state == 7: - if self._rrd_level == 3: - self._rrd_ds_val["type"] = self._rrd_chars - self._rrd_parse_state = 4 # In <rrd><ds> - elif self._rrd_parse_state == 6: - if self._rrd_level == 3: - self._rrd_ds_val["name"] = self._rrd_chars - self._rrd_parse_state = 4 # In <rrd><ds> - elif self._rrd_parse_state == 5: - if self._rrd_level == 2: - self._rrd_parse_state = 1 # In <rrd> - elif self._rrd_parse_state == 4: - if self._rrd_level == 2: - self.rrd_ds.append(self._rrd_ds_val) - self._rrd_parse_state = 1 # In <rrd> - elif self._rrd_parse_state == 3: - if self._rrd_level == 2: - self.rrd_step = long(self._rrd_chars) - self._rrd_parse_state = 1 # In <rrd> - elif self._rrd_parse_state == 2: - if self._rrd_level == 2: - self.rrd_last_update = long(self._rrd_chars) - self._rrd_parse_state = 1 # In <rrd> - elif self._rrd_parse_state == 1: - if self._rrd_level == 1: - self._rrd_parse_state = 0 # At top - - if self._rrd_level: - self._rrd_level = self._rrd_level - 1 - - def characters(self, content): - if self._rrd_capture: - self._rrd_chars = self._rrd_chars + content.strip() - -def _make_numeric(value): - try: - value = float(value) - except: - value = "" - return value - -def simperf_host_xml_fixup(parser, filter_start_time = None, filter_end_time = None): - # Fixup for GAUGE fields that are really COUNTS. They - # were forced to GAUGE to try to disable rrdtool's - # data interpolation/extrapolation for non-uniform time - # samples. - fixup_tags = [ "cpu_user", - "cpu_nice", - "cpu_sys", - "cpu_idle", - "cpu_waitio", - "cpu_intr", - # "file_active", - # "file_free", - # "inode_active", - # "inode_free", - "netif_in_kb", - "netif_in_pkts", - "netif_in_errs", - "netif_in_drop", - "netif_out_kb", - "netif_out_pkts", - "netif_out_errs", - "netif_out_drop", - "vm_page_in", - "vm_page_out", - "vm_swap_in", - "vm_swap_out", - #"vm_mem_total", - #"vm_mem_used", - #"vm_mem_active", - #"vm_mem_inactive", - #"vm_mem_free", - #"vm_mem_buffer", - #"vm_swap_cache", - #"vm_swap_total", - #"vm_swap_used", - #"vm_swap_free", - "cpu_interrupts", - "cpu_switches", - "cpu_forks" ] - - col_count = len(parser.rrd_ds) - row_count = len(parser.rrd_records) - - # Process the last row separately, just to make all values numeric. - for j in range(col_count): - parser.rrd_records[row_count - 1][j] = _make_numeric(parser.rrd_records[row_count - 1][j]) - - # Process all other row/columns. - last_different_row = row_count - 1 - current_row = row_count - 2 - while current_row >= 0: - # Check for a different value than the previous row. If everything is the same - # then this is probably just a filler/bogus entry. - is_different = False - for j in range(col_count): - parser.rrd_records[current_row][j] = _make_numeric(parser.rrd_records[current_row][j]) - if parser.rrd_records[current_row][j] != parser.rrd_records[last_different_row][j]: - # We're good. This is a different row. - is_different = True - - if not is_different: - # This is a filler/bogus entry. Just ignore it. - for j in range(col_count): - parser.rrd_records[current_row][j] = float('nan') - else: - # Some tags need to be converted into deltas. - for j in range(col_count): - if parser.rrd_ds[j]["name"] in fixup_tags: - parser.rrd_records[last_different_row][j] = \ - parser.rrd_records[last_different_row][j] - parser.rrd_records[current_row][j] - last_different_row = current_row - - current_row -= 1 - - # Set fixup_tags in the first row to 'nan' since they aren't useful anymore. - for j in range(col_count): - if parser.rrd_ds[j]["name"] in fixup_tags: - parser.rrd_records[0][j] = float('nan') - - # Add a timestamp to each row and to the catalog. Format and name - # chosen to match other simulator logging (hopefully). - start_time = parser.rrd_last_update - (parser.rrd_step * (row_count - 1)) - # Build a filtered list of rrd_records if we are limited to a time range. - filter_records = False - if filter_start_time is not None or filter_end_time is not None: - filter_records = True - filtered_rrd_records = [] - if filter_start_time is None: - filter_start_time = start_time * 1000 - if filter_end_time is None: - filter_end_time = parser.rrd_last_update * 1000 - - for i in range(row_count): - record_timestamp = (start_time + (i * parser.rrd_step)) * 1000 - parser.rrd_records[i].insert(0, record_timestamp) - if filter_records: - if filter_start_time <= record_timestamp and record_timestamp <= filter_end_time: - filtered_rrd_records.append(parser.rrd_records[i]) - - if filter_records: - parser.rrd_records = filtered_rrd_records - - parser.rrd_ds.insert(0, {"type": "GAUGE", "name": "javascript_timestamp"}) - - -def main(argv=None): - opts, args = getopt.getopt(sys.argv[1:], "i:o:h", ["in=", "out=", "help"]) - input_file = sys.stdin - output_file = sys.stdout - for o, a in opts: - if o in ("-i", "--in"): - input_file = open(a, 'r') - if o in ("-o", "--out"): - output_file = open(a, 'w') - if o in ("-h", "--help"): - usage() - sys.exit(0) - - # Using the SAX parser as it is at least 4X faster and far, far - # smaller on this dataset than the DOM-based interface in xml.dom.minidom. - # With SAX and a 5.4MB xml file, this requires about seven seconds of - # wall-clock time and 32MB VSZ. With the DOM interface, about 22 seconds - # and over 270MB VSZ. - - handler = SimPerfHostXMLParser() - sax.parse(input_file, handler) - if input_file != sys.stdin: - input_file.close() - - # Various format fixups: string-to-num, gauge-to-counts, add - # a time stamp, etc. - simperf_host_xml_fixup(handler) - - # Create JSONable dict with interesting data and format/print it - print >>output_file, simplejson.dumps({ "step" : handler.rrd_step, - "lastupdate": handler.rrd_last_update * 1000, - "ds" : handler.rrd_ds, - "database" : handler.rrd_records }) - - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/indra/lib/python/indra/util/simperf_oprof_interface.py b/indra/lib/python/indra/util/simperf_oprof_interface.py deleted file mode 100755 index 547d2f9980989b846b4898a96ed2bcd18372ba89..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/simperf_oprof_interface.py +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/env python -"""\ -@file simperf_oprof_interface.py -@brief Manage OProfile data collection on a host - -$LicenseInfo:firstyear=2008&license=mit$ - -Copyright (c) 2008-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -import sys, os, getopt -import simplejson - - -def usage(): - print "Usage:" - print sys.argv[0] + " [options]" - print " Digest the OProfile report forms that come out of the" - print " simperf_oprof_ctl program's -r/--report command. The result" - print " is an array of dictionaires with the following keys:" - print - print " symbol Name of sampled, calling, or called procedure" - print " file Executable or library where symbol resides" - print " percentage Percentage contribution to profile, calls or called" - print " samples Sample count" - print " calls Methods called by the method in question (full only)" - print " called_by Methods calling the method (full only)" - print - print " For 'full' reports the two keys 'calls' and 'called_by' are" - print " themselves arrays of dictionaries based on the first four keys." - print - print "Return Codes:" - print " None. Aggressively digests everything. Will likely mung results" - print " if a program or library has whitespace in its name." - print - print "Options:" - print " -i, --in Input settings filename. (Default: stdin)" - print " -o, --out Output settings filename. (Default: stdout)" - print " -h, --help Print this message and exit." - print - print "Interfaces:" - print " class SimPerfOProfileInterface()" - -class SimPerfOProfileInterface: - def __init__(self): - self.isBrief = True # public - self.isValid = False # public - self.result = [] # public - - def parse(self, input): - in_samples = False - for line in input: - if in_samples: - if line[0:6] == "------": - self.isBrief = False - self._parseFull(input) - else: - self._parseBrief(input, line) - self.isValid = True - return - try: - hd1, remain = line.split(None, 1) - if hd1 == "samples": - in_samples = True - except ValueError: - pass - - def _parseBrief(self, input, line1): - try: - fld1, fld2, fld3, fld4 = line1.split(None, 3) - self.result.append({"samples" : fld1, - "percentage" : fld2, - "file" : fld3, - "symbol" : fld4.strip("\n")}) - except ValueError: - pass - for line in input: - try: - fld1, fld2, fld3, fld4 = line.split(None, 3) - self.result.append({"samples" : fld1, - "percentage" : fld2, - "file" : fld3, - "symbol" : fld4.strip("\n")}) - except ValueError: - pass - - def _parseFull(self, input): - state = 0 # In 'called_by' section - calls = [] - called_by = [] - current = {} - for line in input: - if line[0:6] == "------": - if len(current): - current["calls"] = calls - current["called_by"] = called_by - self.result.append(current) - state = 0 - calls = [] - called_by = [] - current = {} - else: - try: - fld1, fld2, fld3, fld4 = line.split(None, 3) - tmp = {"samples" : fld1, - "percentage" : fld2, - "file" : fld3, - "symbol" : fld4.strip("\n")} - except ValueError: - continue - if line[0] != " ": - current = tmp - state = 1 # In 'calls' section - elif state == 0: - called_by.append(tmp) - else: - calls.append(tmp) - if len(current): - current["calls"] = calls - current["called_by"] = called_by - self.result.append(current) - - -def main(argv=None): - opts, args = getopt.getopt(sys.argv[1:], "i:o:h", ["in=", "out=", "help"]) - input_file = sys.stdin - output_file = sys.stdout - for o, a in opts: - if o in ("-i", "--in"): - input_file = open(a, 'r') - if o in ("-o", "--out"): - output_file = open(a, 'w') - if o in ("-h", "--help"): - usage() - sys.exit(0) - - oprof = SimPerfOProfileInterface() - oprof.parse(input_file) - if input_file != sys.stdin: - input_file.close() - - # Create JSONable dict with interesting data and format/print it - print >>output_file, simplejson.dumps(oprof.result) - - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/indra/lib/python/indra/util/simperf_proc_interface.py b/indra/lib/python/indra/util/simperf_proc_interface.py deleted file mode 100755 index de061f68ccfda36277b0bb2f558d464c03b3bcc7..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/simperf_proc_interface.py +++ /dev/null @@ -1,191 +0,0 @@ -#!/usr/bin/env python -"""\ -@file simperf_proc_interface.py -@brief Utility to extract log messages from *.<pid>.llsd files containing performance statistics. - -$LicenseInfo:firstyear=2008&license=mit$ - -Copyright (c) 2008-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -""" - -# ---------------------------------------------------- -# Utility to extract log messages from *.<pid>.llsd -# files that contain performance statistics. - -# ---------------------------------------------------- -import sys, os - -if os.path.exists("setup-path.py"): - execfile("setup-path.py") - -from indra.base import llsd - -DEFAULT_PATH="/dev/shm/simperf/" - - -# ---------------------------------------------------- -# Pull out the stats and return a single document -def parse_logfile(filename, target_column=None, verbose=False): - full_doc = [] - # Open source temp log file. Let exceptions percolate up. - sourcefile = open( filename,'r') - - if verbose: - print "Reading " + filename - - # Parse and output all lines from the temp file - for line in sourcefile.xreadlines(): - partial_doc = llsd.parse(line) - if partial_doc is not None: - if target_column is None: - full_doc.append(partial_doc) - else: - trim_doc = { target_column: partial_doc[target_column] } - if target_column != "fps": - trim_doc[ 'fps' ] = partial_doc[ 'fps' ] - trim_doc[ '/total_time' ] = partial_doc[ '/total_time' ] - trim_doc[ 'utc_time' ] = partial_doc[ 'utc_time' ] - full_doc.append(trim_doc) - - sourcefile.close() - return full_doc - -# Extract just the meta info line, and the timestamp of the first/last frame entry. -def parse_logfile_info(filename, verbose=False): - # Open source temp log file. Let exceptions percolate up. - sourcefile = open(filename, 'rU') # U is to open with Universal newline support - - if verbose: - print "Reading " + filename - - # The first line is the meta info line. - info_line = sourcefile.readline() - if not info_line: - sourcefile.close() - return None - - # The rest of the lines are frames. Read the first and last to get the time range. - info = llsd.parse( info_line ) - info['start_time'] = None - info['end_time'] = None - first_frame = sourcefile.readline() - if first_frame: - try: - info['start_time'] = int(llsd.parse(first_frame)['timestamp']) - except: - pass - - # Read the file backwards to find the last two lines. - sourcefile.seek(0, 2) - file_size = sourcefile.tell() - offset = 1024 - num_attempts = 0 - end_time = None - if file_size < offset: - offset = file_size - while 1: - sourcefile.seek(-1*offset, 2) - read_str = sourcefile.read(offset) - # Remove newline at the end - if read_str[offset - 1] == '\n': - read_str = read_str[0:-1] - lines = read_str.split('\n') - full_line = None - if len(lines) > 2: # Got two line - try: - end_time = llsd.parse(lines[-1])['timestamp'] - except: - # We couldn't parse this line. Try once more. - try: - end_time = llsd.parse(lines[-2])['timestamp'] - except: - # Nope. Just move on. - pass - break - if len(read_str) == file_size: # Reached the beginning - break - offset += 1024 - - info['end_time'] = int(end_time) - - sourcefile.close() - return info - - -def parse_proc_filename(filename): - try: - name_as_list = filename.split(".") - cur_stat_type = name_as_list[0].split("_")[0] - cur_pid = name_as_list[1] - except IndexError, ValueError: - return (None, None) - return (cur_pid, cur_stat_type) - -# ---------------------------------------------------- -def get_simstats_list(path=None): - """ Return stats (pid, type) listed in <type>_proc.<pid>.llsd """ - if path is None: - path = DEFAULT_PATH - simstats_list = [] - for file_name in os.listdir(path): - if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd": - simstats_info = parse_logfile_info(path + file_name) - if simstats_info is not None: - simstats_list.append(simstats_info) - return simstats_list - -def get_log_info_list(pid=None, stat_type=None, path=None, target_column=None, verbose=False): - """ Return data from all llsd files matching the pid and stat type """ - if path is None: - path = DEFAULT_PATH - log_info_list = {} - for file_name in os.listdir ( path ): - if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd": - (cur_pid, cur_stat_type) = parse_proc_filename(file_name) - if cur_pid is None: - continue - if pid is not None and pid != cur_pid: - continue - if stat_type is not None and stat_type != cur_stat_type: - continue - log_info_list[cur_pid] = parse_logfile(path + file_name, target_column, verbose) - return log_info_list - -def delete_simstats_files(pid=None, stat_type=None, path=None): - """ Delete *.<pid>.llsd files """ - if path is None: - path = DEFAULT_PATH - del_list = [] - for file_name in os.listdir(path): - if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd": - (cur_pid, cur_stat_type) = parse_proc_filename(file_name) - if cur_pid is None: - continue - if pid is not None and pid != cur_pid: - continue - if stat_type is not None and stat_type != cur_stat_type: - continue - del_list.append(cur_pid) - # Allow delete related exceptions to percolate up if this fails. - os.unlink(os.path.join(DEFAULT_PATH, file_name)) - return del_list - diff --git a/indra/lib/python/indra/util/term.py b/indra/lib/python/indra/util/term.py deleted file mode 100755 index 8c316a1f1209e9e56d3657877db810383bf61e35..0000000000000000000000000000000000000000 --- a/indra/lib/python/indra/util/term.py +++ /dev/null @@ -1,222 +0,0 @@ -''' -@file term.py -@brief a better shutil.copytree replacement - -$LicenseInfo:firstyear=2007&license=mit$ - -Copyright (c) 2007-2009, Linden Research, Inc. - -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. -$/LicenseInfo$ -''' - -#http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475116 - -import sys, re - -class TerminalController: - """ - A class that can be used to portably generate formatted output to - a terminal. - - `TerminalController` defines a set of instance variables whose - values are initialized to the control sequence necessary to - perform a given action. These can be simply included in normal - output to the terminal: - - >>> term = TerminalController() - >>> print 'This is '+term.GREEN+'green'+term.NORMAL - - Alternatively, the `render()` method can used, which replaces - '${action}' with the string required to perform 'action': - - >>> term = TerminalController() - >>> print term.render('This is ${GREEN}green${NORMAL}') - - If the terminal doesn't support a given action, then the value of - the corresponding instance variable will be set to ''. As a - result, the above code will still work on terminals that do not - support color, except that their output will not be colored. - Also, this means that you can test whether the terminal supports a - given action by simply testing the truth value of the - corresponding instance variable: - - >>> term = TerminalController() - >>> if term.CLEAR_SCREEN: - ... print 'This terminal supports clearning the screen.' - - Finally, if the width and height of the terminal are known, then - they will be stored in the `COLS` and `LINES` attributes. - """ - # Cursor movement: - BOL = '' #: Move the cursor to the beginning of the line - UP = '' #: Move the cursor up one line - DOWN = '' #: Move the cursor down one line - LEFT = '' #: Move the cursor left one char - RIGHT = '' #: Move the cursor right one char - - # Deletion: - CLEAR_SCREEN = '' #: Clear the screen and move to home position - CLEAR_EOL = '' #: Clear to the end of the line. - CLEAR_BOL = '' #: Clear to the beginning of the line. - CLEAR_EOS = '' #: Clear to the end of the screen - - # Output modes: - BOLD = '' #: Turn on bold mode - BLINK = '' #: Turn on blink mode - DIM = '' #: Turn on half-bright mode - REVERSE = '' #: Turn on reverse-video mode - NORMAL = '' #: Turn off all modes - - # Cursor display: - HIDE_CURSOR = '' #: Make the cursor invisible - SHOW_CURSOR = '' #: Make the cursor visible - - # Terminal size: - COLS = None #: Width of the terminal (None for unknown) - LINES = None #: Height of the terminal (None for unknown) - - # Foreground colors: - BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = '' - - # Background colors: - BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = '' - BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = '' - - _STRING_CAPABILITIES = """ - BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1 - CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold - BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0 - HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split() - _COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split() - _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split() - - def __init__(self, term_stream=sys.stdout): - """ - Create a `TerminalController` and initialize its attributes - with appropriate values for the current terminal. - `term_stream` is the stream that will be used for terminal - output; if this stream is not a tty, then the terminal is - assumed to be a dumb terminal (i.e., have no capabilities). - """ - # Curses isn't available on all platforms - try: import curses - except: return - - # If the stream isn't a tty, then assume it has no capabilities. - if not term_stream.isatty(): return - - # Check the terminal type. If we fail, then assume that the - # terminal has no capabilities. - try: curses.setupterm() - except: return - - # Look up numeric capabilities. - self.COLS = curses.tigetnum('cols') - self.LINES = curses.tigetnum('lines') - - # Look up string capabilities. - for capability in self._STRING_CAPABILITIES: - (attrib, cap_name) = capability.split('=') - setattr(self, attrib, self._tigetstr(cap_name) or '') - - # Colors - set_fg = self._tigetstr('setf') - if set_fg: - for i,color in zip(range(len(self._COLORS)), self._COLORS): - setattr(self, color, curses.tparm(set_fg, i) or '') - set_fg_ansi = self._tigetstr('setaf') - if set_fg_ansi: - for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): - setattr(self, color, curses.tparm(set_fg_ansi, i) or '') - set_bg = self._tigetstr('setb') - if set_bg: - for i,color in zip(range(len(self._COLORS)), self._COLORS): - setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '') - set_bg_ansi = self._tigetstr('setab') - if set_bg_ansi: - for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): - setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '') - - def _tigetstr(self, cap_name): - # String capabilities can include "delays" of the form "$<2>". - # For any modern terminal, we should be able to just ignore - # these, so strip them out. - import curses - cap = curses.tigetstr(cap_name) or '' - return re.sub(r'\$<\d+>[/*]?', '', cap) - - def render(self, template): - """ - Replace each $-substitutions in the given template string with - the corresponding terminal control string (if it's defined) or - '' (if it's not). - """ - return re.sub(r'\$\$|\${\w+}', self._render_sub, template) - - def _render_sub(self, match): - s = match.group() - if s == '$$': return s - else: return getattr(self, s[2:-1]) - -####################################################################### -# Example use case: progress bar -####################################################################### - -class ProgressBar: - """ - A 3-line progress bar, which looks like:: - - Header - 20% [===========----------------------------------] - progress message - - The progress bar is colored, if the terminal supports color - output; and adjusts to the width of the terminal. - """ - BAR = '%3d%% ${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}\n' - HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n' - - def __init__(self, term, header): - self.term = term - if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL): - raise ValueError("Terminal isn't capable enough -- you " - "should use a simpler progress dispaly.") - self.width = self.term.COLS or 75 - self.bar = term.render(self.BAR) - self.header = self.term.render(self.HEADER % header.center(self.width)) - self.cleared = 1 #: true if we haven't drawn the bar yet. - self.update(0, '') - - def update(self, percent, message): - if self.cleared: - sys.stdout.write(self.header) - self.cleared = 0 - n = int((self.width-10)*percent) - sys.stdout.write( - self.term.BOL + self.term.UP + self.term.CLEAR_EOL + - (self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) + - self.term.CLEAR_EOL + message.center(self.width)) - - def clear(self): - if not self.cleared: - sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL + - self.term.UP + self.term.CLEAR_EOL + - self.term.UP + self.term.CLEAR_EOL) - self.cleared = 1 diff --git a/indra/lib/python/uuid.py b/indra/lib/python/uuid.py deleted file mode 100755 index e956383ccabbdc4b425f16096bad95f3aa9db7e7..0000000000000000000000000000000000000000 --- a/indra/lib/python/uuid.py +++ /dev/null @@ -1,508 +0,0 @@ -#!/usr/bin/python -## $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$ -r"""UUID objects (universally unique identifiers) according to RFC 4122. - -This module provides immutable UUID objects (class UUID) and the functions -uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5 -UUIDs as specified in RFC 4122. - -If all you want is a unique ID, you should probably call uuid1() or uuid4(). -Note that uuid1() may compromise privacy since it creates a UUID containing -the computer's network address. uuid4() creates a random UUID. - -Typical usage: - - >>> import uuid - - # make a UUID based on the host ID and current time - >>> uuid.uuid1() - UUID('a8098c1a-f86e-11da-bd1a-00112444be1e') - - # make a UUID using an MD5 hash of a namespace UUID and a name - >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org') - UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e') - - # make a random UUID - >>> uuid.uuid4() - UUID('16fd2706-8baf-433b-82eb-8c7fada847da') - - # make a UUID using a SHA-1 hash of a namespace UUID and a name - >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org') - UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d') - - # make a UUID from a string of hex digits (braces and hyphens ignored) - >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}') - - # convert a UUID to a string of hex digits in standard form - >>> str(x) - '00010203-0405-0607-0809-0a0b0c0d0e0f' - - # get the raw 16 bytes of the UUID - >>> x.bytes - '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f' - - # make a UUID from a 16-byte string - >>> uuid.UUID(bytes=x.bytes) - UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') - -This module works with Python 2.3 or higher.""" - -__author__ = 'Ka-Ping Yee <ping@zesty.ca>' -__date__ = '$Date: 2006/06/12 23:15:40 $'.split()[1].replace('/', '-') -__version__ = '$Revision: 1.30 $'.split()[1] - -RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ - 'reserved for NCS compatibility', 'specified in RFC 4122', - 'reserved for Microsoft compatibility', 'reserved for future definition'] - -class UUID(object): - """Instances of the UUID class represent UUIDs as specified in RFC 4122. - UUID objects are immutable, hashable, and usable as dictionary keys. - Converting a UUID to a string with str() yields something in the form - '12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts - four possible forms: a similar string of hexadecimal digits, or a - string of 16 raw bytes as an argument named 'bytes', or a tuple of - six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and - 48-bit values respectively) as an argument named 'fields', or a single - 128-bit integer as an argument named 'int'. - - UUIDs have these read-only attributes: - - bytes the UUID as a 16-byte string - - fields a tuple of the six integer fields of the UUID, - which are also available as six individual attributes - and two derived attributes: - - time_low the first 32 bits of the UUID - time_mid the next 16 bits of the UUID - time_hi_version the next 16 bits of the UUID - clock_seq_hi_variant the next 8 bits of the UUID - clock_seq_low the next 8 bits of the UUID - node the last 48 bits of the UUID - - time the 60-bit timestamp - clock_seq the 14-bit sequence number - - hex the UUID as a 32-character hexadecimal string - - int the UUID as a 128-bit integer - - urn the UUID as a URN as specified in RFC 4122 - - variant the UUID variant (one of the constants RESERVED_NCS, - RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE) - - version the UUID version number (1 through 5, meaningful only - when the variant is RFC_4122) - """ - - def __init__(self, hex=None, bytes=None, fields=None, int=None, - version=None): - r"""Create a UUID from either a string of 32 hexadecimal digits, - a string of 16 bytes as the 'bytes' argument, a tuple of six - integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version, - 8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as - the 'fields' argument, or a single 128-bit integer as the 'int' - argument. When a string of hex digits is given, curly braces, - hyphens, and a URN prefix are all optional. For example, these - expressions all yield the same UUID: - - UUID('{12345678-1234-5678-1234-567812345678}') - UUID('12345678123456781234567812345678') - UUID('urn:uuid:12345678-1234-5678-1234-567812345678') - UUID(bytes='\x12\x34\x56\x78'*4) - UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678)) - UUID(int=0x12345678123456781234567812345678) - - Exactly one of 'hex', 'bytes', 'fields', or 'int' must be given. - The 'version' argument is optional; if given, the resulting UUID - will have its variant and version number set according to RFC 4122, - overriding bits in the given 'hex', 'bytes', 'fields', or 'int'. - """ - - if [hex, bytes, fields, int].count(None) != 3: - raise TypeError('need just one of hex, bytes, fields, or int') - if hex is not None: - hex = hex.replace('urn:', '').replace('uuid:', '') - hex = hex.strip('{}').replace('-', '') - if len(hex) != 32: - raise ValueError('badly formed hexadecimal UUID string') - int = long(hex, 16) - if bytes is not None: - if len(bytes) != 16: - raise ValueError('bytes is not a 16-char string') - int = long(('%02x'*16) % tuple(map(ord, bytes)), 16) - if fields is not None: - if len(fields) != 6: - raise ValueError('fields is not a 6-tuple') - (time_low, time_mid, time_hi_version, - clock_seq_hi_variant, clock_seq_low, node) = fields - if not 0 <= time_low < 1<<32L: - raise ValueError('field 1 out of range (need a 32-bit value)') - if not 0 <= time_mid < 1<<16L: - raise ValueError('field 2 out of range (need a 16-bit value)') - if not 0 <= time_hi_version < 1<<16L: - raise ValueError('field 3 out of range (need a 16-bit value)') - if not 0 <= clock_seq_hi_variant < 1<<8L: - raise ValueError('field 4 out of range (need an 8-bit value)') - if not 0 <= clock_seq_low < 1<<8L: - raise ValueError('field 5 out of range (need an 8-bit value)') - if not 0 <= node < 1<<48L: - raise ValueError('field 6 out of range (need a 48-bit value)') - clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low - int = ((time_low << 96L) | (time_mid << 80L) | - (time_hi_version << 64L) | (clock_seq << 48L) | node) - if int is not None: - if not 0 <= int < 1<<128L: - raise ValueError('int is out of range (need a 128-bit value)') - if version is not None: - if not 1 <= version <= 5: - raise ValueError('illegal version number') - # Set the variant to RFC 4122. - int &= ~(0xc000 << 48L) - int |= 0x8000 << 48L - # Set the version number. - int &= ~(0xf000 << 64L) - int |= version << 76L - self.__dict__['int'] = int - - def __cmp__(self, other): - if isinstance(other, UUID): - return cmp(self.int, other.int) - return NotImplemented - - def __hash__(self): - return hash(self.int) - - def __int__(self): - return self.int - - def __repr__(self): - return 'UUID(%r)' % str(self) - - def __setattr__(self, name, value): - raise TypeError('UUID objects are immutable') - - def __str__(self): - hex = '%032x' % self.int - return '%s-%s-%s-%s-%s' % ( - hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:]) - - def get_bytes(self): - bytes = '' - for shift in range(0, 128, 8): - bytes = chr((self.int >> shift) & 0xff) + bytes - return bytes - - bytes = property(get_bytes) - - def get_fields(self): - return (self.time_low, self.time_mid, self.time_hi_version, - self.clock_seq_hi_variant, self.clock_seq_low, self.node) - - fields = property(get_fields) - - def get_time_low(self): - return self.int >> 96L - - time_low = property(get_time_low) - - def get_time_mid(self): - return (self.int >> 80L) & 0xffff - - time_mid = property(get_time_mid) - - def get_time_hi_version(self): - return (self.int >> 64L) & 0xffff - - time_hi_version = property(get_time_hi_version) - - def get_clock_seq_hi_variant(self): - return (self.int >> 56L) & 0xff - - clock_seq_hi_variant = property(get_clock_seq_hi_variant) - - def get_clock_seq_low(self): - return (self.int >> 48L) & 0xff - - clock_seq_low = property(get_clock_seq_low) - - def get_time(self): - return (((self.time_hi_version & 0x0fffL) << 48L) | - (self.time_mid << 32L) | self.time_low) - - time = property(get_time) - - def get_clock_seq(self): - return (((self.clock_seq_hi_variant & 0x3fL) << 8L) | - self.clock_seq_low) - - clock_seq = property(get_clock_seq) - - def get_node(self): - return self.int & 0xffffffffffff - - node = property(get_node) - - def get_hex(self): - return '%032x' % self.int - - hex = property(get_hex) - - def get_urn(self): - return 'urn:uuid:' + str(self) - - urn = property(get_urn) - - def get_variant(self): - if not self.int & (0x8000 << 48L): - return RESERVED_NCS - elif not self.int & (0x4000 << 48L): - return RFC_4122 - elif not self.int & (0x2000 << 48L): - return RESERVED_MICROSOFT - else: - return RESERVED_FUTURE - - variant = property(get_variant) - - def get_version(self): - # The version bits are only meaningful for RFC 4122 UUIDs. - if self.variant == RFC_4122: - return int((self.int >> 76L) & 0xf) - - version = property(get_version) - -def _ifconfig_getnode(): - """Get the hardware address on Unix by running ifconfig.""" - import os - for dir in ['', '/sbin/', '/usr/sbin']: - try: - path = os.path.join(dir, 'ifconfig') - if os.path.exists(path): - pipe = os.popen(path) - else: - continue - except IOError: - continue - for line in pipe: - words = line.lower().split() - for i in range(len(words)): - if words[i] in ['hwaddr', 'ether']: - return int(words[i + 1].replace(':', ''), 16) - -def _ipconfig_getnode(): - """Get the hardware address on Windows by running ipconfig.exe.""" - import os, re - dirs = ['', r'c:\windows\system32', r'c:\winnt\system32'] - try: - import ctypes - buffer = ctypes.create_string_buffer(300) - ctypes.windll.kernel32.GetSystemDirectoryA(buffer, 300) - dirs.insert(0, buffer.value.decode('mbcs')) - except: - pass - for dir in dirs: - try: - pipe = os.popen(os.path.join(dir, 'ipconfig') + ' /all') - except IOError: - continue - for line in pipe: - value = line.split(':')[-1].strip().lower() - if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value): - return int(value.replace('-', ''), 16) - -def _netbios_getnode(): - """Get the hardware address on Windows using NetBIOS calls. - See http://support.microsoft.com/kb/118623 for details.""" - import win32wnet, netbios - ncb = netbios.NCB() - ncb.Command = netbios.NCBENUM - ncb.Buffer = adapters = netbios.LANA_ENUM() - adapters._pack() - if win32wnet.Netbios(ncb) != 0: - return - adapters._unpack() - for i in range(adapters.length): - ncb.Reset() - ncb.Command = netbios.NCBRESET - ncb.Lana_num = ord(adapters.lana[i]) - if win32wnet.Netbios(ncb) != 0: - continue - ncb.Reset() - ncb.Command = netbios.NCBASTAT - ncb.Lana_num = ord(adapters.lana[i]) - ncb.Callname = '*'.ljust(16) - ncb.Buffer = status = netbios.ADAPTER_STATUS() - if win32wnet.Netbios(ncb) != 0: - continue - status._unpack() - bytes = map(ord, status.adapter_address) - return ((bytes[0]<<40L) + (bytes[1]<<32L) + (bytes[2]<<24L) + - (bytes[3]<<16L) + (bytes[4]<<8L) + bytes[5]) - -# Thanks to Thomas Heller for ctypes and for his help with its use here. - -# If ctypes is available, use it to find system routines for UUID generation. -_uuid_generate_random = _uuid_generate_time = _UuidCreate = None -try: - import ctypes, ctypes.util - _buffer = ctypes.create_string_buffer(16) - - # The uuid_generate_* routines are provided by libuuid on at least - # Linux and FreeBSD, and provided by libc on Mac OS X. - for libname in ['uuid', 'c']: - try: - lib = ctypes.CDLL(ctypes.util.find_library(libname)) - except: - continue - if hasattr(lib, 'uuid_generate_random'): - _uuid_generate_random = lib.uuid_generate_random - if hasattr(lib, 'uuid_generate_time'): - _uuid_generate_time = lib.uuid_generate_time - - # On Windows prior to 2000, UuidCreate gives a UUID containing the - # hardware address. On Windows 2000 and later, UuidCreate makes a - # random UUID and UuidCreateSequential gives a UUID containing the - # hardware address. These routines are provided by the RPC runtime. - try: - lib = ctypes.windll.rpcrt4 - except: - lib = None - _UuidCreate = getattr(lib, 'UuidCreateSequential', - getattr(lib, 'UuidCreate', None)) -except: - pass - -def _unixdll_getnode(): - """Get the hardware address on Unix using ctypes.""" - _uuid_generate_time(_buffer) - return UUID(bytes=_buffer.raw).node - -def _windll_getnode(): - """Get the hardware address on Windows using ctypes.""" - if _UuidCreate(_buffer) == 0: - return UUID(bytes=_buffer.raw).node - -def _random_getnode(): - """Get a random node ID, with eighth bit set as suggested by RFC 4122.""" - import random - return random.randrange(0, 1<<48L) | 0x010000000000L - -_node = None - -def getnode(): - """Get the hardware address as a 48-bit integer. The first time this - runs, it may launch a separate program, which could be quite slow. If - all attempts to obtain the hardware address fail, we choose a random - 48-bit number with its eighth bit set to 1 as recommended in RFC 4122.""" - - global _node - if _node is not None: - return _node - - import sys - if sys.platform == 'win32': - getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode] - else: - getters = [_unixdll_getnode, _ifconfig_getnode] - - for getter in getters + [_random_getnode]: - try: - _node = getter() - except: - continue - if _node is not None: - return _node - -def uuid1(node=None, clock_seq=None): - """Generate a UUID from a host ID, sequence number, and the current time. - If 'node' is not given, getnode() is used to obtain the hardware - address. If 'clock_seq' is given, it is used as the sequence number; - otherwise a random 14-bit sequence number is chosen.""" - - # When the system provides a version-1 UUID generator, use it (but don't - # use UuidCreate here because its UUIDs don't conform to RFC 4122). - if _uuid_generate_time and node is clock_seq is None: - _uuid_generate_time(_buffer) - return UUID(bytes=_buffer.raw) - - import time - nanoseconds = int(time.time() * 1e9) - # 0x01b21dd213814000 is the number of 100-ns intervals between the - # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00. - timestamp = int(nanoseconds/100) + 0x01b21dd213814000L - if clock_seq is None: - import random - clock_seq = random.randrange(1<<14L) # instead of stable storage - time_low = timestamp & 0xffffffffL - time_mid = (timestamp >> 32L) & 0xffffL - time_hi_version = (timestamp >> 48L) & 0x0fffL - clock_seq_low = clock_seq & 0xffL - clock_seq_hi_variant = (clock_seq >> 8L) & 0x3fL - if node is None: - node = getnode() - return UUID(fields=(time_low, time_mid, time_hi_version, - clock_seq_hi_variant, clock_seq_low, node), version=1) - -def uuid3(namespace, name): - """Generate a UUID from the MD5 hash of a namespace UUID and a name.""" - try: - # Python 2.6 - from hashlib import md5 - except ImportError: - # Python 2.5 and earlier - from md5 import new as md5 - - hash = md5(namespace.bytes + name).digest() - return UUID(bytes=hash[:16], version=3) - -def uuid4(): - """Generate a random UUID.""" - - # When the system provides a version-4 UUID generator, use it. - if _uuid_generate_random: - _uuid_generate_random(_buffer) - return UUID(bytes=_buffer.raw) - - # Otherwise, get randomness from urandom or the 'random' module. - try: - import os - return UUID(bytes=os.urandom(16), version=4) - except: - import random - bytes = [chr(random.randrange(256)) for i in range(16)] - return UUID(bytes=bytes, version=4) - -def uuid5(namespace, name): - """Generate a UUID from the SHA-1 hash of a namespace UUID and a name.""" - import sha - hash = sha.sha(namespace.bytes + name).digest() - return UUID(bytes=hash[:16], version=5) - -# The following standard UUIDs are for use with uuid3() or uuid5(). - -NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8') -NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8') -NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8') -NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8') diff --git a/indra/linux_crash_logger/linux_crash_logger.cpp b/indra/linux_crash_logger/linux_crash_logger.cpp index 9d5ec33fed74add89e7f34e6ee401a2e542638d5..63e540987607b2c3cdcd4d5ecd994c53546f479d 100644 --- a/indra/linux_crash_logger/linux_crash_logger.cpp +++ b/indra/linux_crash_logger/linux_crash_logger.cpp @@ -51,7 +51,7 @@ int main(int argc, char **argv) return 1; } - app.mainLoop(); + app.frame(); app.cleanup(); LL_INFOS() << "Crash reporter finished normally." << LL_ENDL; return 0; diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp index e2d2e7ff26949fdfbfdc9c81db9520badbf255f2..4092d43fc5fc029818bb8cac9d76c13f003b77cc 100644 --- a/indra/linux_crash_logger/llcrashloggerlinux.cpp +++ b/indra/linux_crash_logger/llcrashloggerlinux.cpp @@ -114,7 +114,7 @@ void LLCrashLoggerLinux::gatherPlatformSpecificFiles() { } -bool LLCrashLoggerLinux::mainLoop() +bool LLCrashLoggerLinux::frame() { bool send_logs = true; if(CRASH_BEHAVIOR_ASK == getCrashBehavior()) diff --git a/indra/linux_crash_logger/llcrashloggerlinux.h b/indra/linux_crash_logger/llcrashloggerlinux.h index dae6c46651ba642e401aa09874d4c2d2567eb92f..789f6f03f578b48dd2953b992f502e3fc085c957 100644 --- a/indra/linux_crash_logger/llcrashloggerlinux.h +++ b/indra/linux_crash_logger/llcrashloggerlinux.h @@ -36,7 +36,7 @@ class LLCrashLoggerLinux : public LLCrashLogger public: LLCrashLoggerLinux(void); ~LLCrashLoggerLinux(void); - virtual bool mainLoop(); + virtual bool frame(); virtual void updateApplication(const std::string& = LLStringUtil::null); virtual void gatherPlatformSpecificFiles(); virtual bool cleanup(); diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index d1eb38901316b25621b1666c1ee62297cc977a2f..ab6d77dd9ba937be147715fbdb102e0ffebd3d13 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -44,6 +44,7 @@ #include "lltexglobalcolor.h" #include "llwearabledata.h" #include "boost/bind.hpp" +#include "boost/tokenizer.hpp" #if LL_MSVC @@ -87,8 +88,11 @@ class LLAvatarBoneInfo private: std::string mName; + std::string mSupport; + std::string mAliases; BOOL mIsJoint; LLVector3 mPos; + LLVector3 mEnd; LLVector3 mRot; LLVector3 mScale; LLVector3 mPivot; @@ -118,6 +122,7 @@ class LLAvatarSkeletonInfo private: S32 mNumBones; S32 mNumCollisionVolumes; + LLAvatarAppearance::joint_alias_map_t mJointAliasMap; typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t; bone_info_list_t mBoneInfoList; }; @@ -181,7 +186,11 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : mPelvisToFoot(0.f), mHeadOffset(), mRoot(NULL), - mWearableData(wearable_data) + mWearableData(wearable_data), + mNumBones(0), + mNumCollisionVolumes(0), + mCollisionVolumes(NULL), + mIsBuilt(FALSE) { llassert_always(mWearableData); mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES); @@ -194,11 +203,6 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : mBakedTextureDatas[i].mMaskTexName = 0; mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i); } - - mIsBuilt = FALSE; - - mNumCollisionVolumes = 0; - mCollisionVolumes = NULL; } // virtual @@ -323,36 +327,49 @@ LLAvatarAppearance::~LLAvatarAppearance() //static void LLAvatarAppearance::initClass() { - std::string xmlFile; + initClass("",""); +} - xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml"; - BOOL success = sXMLTree.parseFile( xmlFile, FALSE ); +//static +void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, const std::string& skeleton_file_name_arg) +{ + std::string avatar_file_name; + + if (!avatar_file_name_arg.empty()) + { + avatar_file_name = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,avatar_file_name_arg); + } + else + { + avatar_file_name = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR + "_lad.xml"); + } + BOOL success = sXMLTree.parseFile( avatar_file_name, FALSE ); if (!success) { - LL_ERRS() << "Problem reading avatar configuration file:" << xmlFile << LL_ENDL; + LL_ERRS() << "Problem reading avatar configuration file:" << avatar_file_name << LL_ENDL; } // now sanity check xml file LLXmlTreeNode* root = sXMLTree.getRoot(); if (!root) { - LL_ERRS() << "No root node found in avatar configuration file: " << xmlFile << LL_ENDL; + LL_ERRS() << "No root node found in avatar configuration file: " << avatar_file_name << LL_ENDL; return; } //------------------------------------------------------------------------- - // <linden_avatar version="1.0"> (root) + // <linden_avatar version="2.0"> (root) //------------------------------------------------------------------------- if( !root->hasName( "linden_avatar" ) ) { - LL_ERRS() << "Invalid avatar file header: " << xmlFile << LL_ENDL; + LL_ERRS() << "Invalid avatar file header: " << avatar_file_name << LL_ENDL; } std::string version; static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); - if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) + if( !root->getFastAttributeString( version_string, version ) || ((version != "1.0") && (version != "2.0"))) { - LL_ERRS() << "Invalid avatar file version: " << version << " in file: " << xmlFile << LL_ENDL; + LL_ERRS() << "Invalid avatar file version: " << version << " in file: " << avatar_file_name << LL_ENDL; } S32 wearable_def_version = 1; @@ -365,16 +382,19 @@ void LLAvatarAppearance::initClass() LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" ); if (!skeleton_node) { - LL_ERRS() << "No skeleton in avatar configuration file: " << xmlFile << LL_ENDL; + LL_ERRS() << "No skeleton in avatar configuration file: " << avatar_file_name << LL_ENDL; return; } - - std::string skeleton_file_name; - static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); - if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name)) - { - LL_ERRS() << "No file name in skeleton node in avatar config file: " << xmlFile << LL_ENDL; - } + + std::string skeleton_file_name = skeleton_file_name_arg; + if (skeleton_file_name.empty()) + { + static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); + if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name)) + { + LL_ERRS() << "No file name in skeleton node in avatar config file: " << avatar_file_name << LL_ENDL; + } + } std::string skeleton_path; skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name); @@ -437,11 +457,56 @@ void LLAvatarAppearance::cleanupClass() using namespace LLAvatarAppearanceDefines; +void LLAvatarAppearance::compareJointStateMaps(joint_state_map_t& last_state, + joint_state_map_t& curr_state) +{ + if (!last_state.empty() && (last_state != curr_state)) + { + S32 diff_count = 0; + joint_state_map_t::iterator it; + for (it=last_state.begin(); it != last_state.end(); ++it) + { + const std::string& key = it->first; + if (last_state[key] != curr_state[key]) + { + LL_DEBUGS("AvatarBodySize") << "BodySize change " << key << " " << last_state[key] << "->" << curr_state[key] << LL_ENDL; + diff_count++; + } + } + if (diff_count > 0) + { + LL_DEBUGS("AvatarBodySize") << "Total of BodySize changes " << diff_count << LL_ENDL; + } + + } +} + //------------------------------------------------------------------------ // The viewer can only suggest a good size for the agent, // the simulator will keep it inside a reasonable range. void LLAvatarAppearance::computeBodySize() { + mLastBodySizeState = mCurrBodySizeState; + + mCurrBodySizeState["mPelvis scale"] = mPelvisp->getScale(); + mCurrBodySizeState["mSkull pos"] = mSkullp->getPosition(); + mCurrBodySizeState["mSkull scale"] = mSkullp->getScale(); + mCurrBodySizeState["mNeck pos"] = mNeckp->getPosition(); + mCurrBodySizeState["mNeck scale"] = mNeckp->getScale(); + mCurrBodySizeState["mChest pos"] = mChestp->getPosition(); + mCurrBodySizeState["mChest scale"] = mChestp->getScale(); + mCurrBodySizeState["mHead pos"] = mHeadp->getPosition(); + mCurrBodySizeState["mHead scale"] = mHeadp->getScale(); + mCurrBodySizeState["mTorso pos"] = mTorsop->getPosition(); + mCurrBodySizeState["mTorso scale"] = mTorsop->getScale(); + mCurrBodySizeState["mHipLeft pos"] = mHipLeftp->getPosition(); + mCurrBodySizeState["mHipLeft scale"] = mHipLeftp->getScale(); + mCurrBodySizeState["mKneeLeft pos"] = mKneeLeftp->getPosition(); + mCurrBodySizeState["mKneeLeft scale"] = mKneeLeftp->getScale(); + mCurrBodySizeState["mAnkleLeft pos"] = mAnkleLeftp->getPosition(); + mCurrBodySizeState["mAnkleLeft scale"] = mAnkleLeftp->getScale(); + mCurrBodySizeState["mFootLeft pos"] = mFootLeftp->getPosition(); + LLVector3 pelvis_scale = mPelvisp->getScale(); // some of the joints have not been cached @@ -501,6 +566,8 @@ void LLAvatarAppearance::computeBodySize() if (new_body_size != mBodySize || old_offset != mAvatarOffset.mV[VZ]) { mBodySize = new_body_size; + + compareJointStateMaps(mLastBodySizeState, mCurrBodySizeState); } } @@ -536,7 +603,7 @@ BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename) std::string version; static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); - if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) + if( !root->getFastAttributeString( version_string, version ) || ((version != "1.0") && (version != "2.0"))) { LL_ERRS() << "Invalid avatar skeleton file version: " << version << " in file: " << filename << LL_ENDL; return FALSE; @@ -552,6 +619,12 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent { LLJoint* joint = NULL; + LL_DEBUGS("BVH") << "bone info: name " << info->mName + << " isJoint " << info->mIsJoint + << " volume_num " << volume_num + << " joint_num " << joint_num + << LL_ENDL; + if (info->mIsJoint) { joint = getCharacterJoint(joint_num); @@ -566,7 +639,7 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent { if (volume_num >= (S32)mNumCollisionVolumes) { - LL_WARNS() << "Too many bones" << LL_ENDL; + LL_WARNS() << "Too many collision volumes" << LL_ENDL; return FALSE; } joint = (&mCollisionVolumes[volume_num]); @@ -574,26 +647,34 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent } // add to parent - if (parent) + if (parent && (joint->getParent()!=parent)) { parent->addChild( joint ); } + // SL-315 joint->setPosition(info->mPos); + joint->setDefaultPosition(info->mPos); joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY], info->mRot.mV[VZ], LLQuaternion::XYZ)); joint->setScale(info->mScale); + joint->setDefaultScale(info->mScale); + joint->setSupport(info->mSupport); + joint->setEnd(info->mEnd); if (info->mIsJoint) { joint->setSkinOffset( info->mPivot ); + joint->setJointNum(joint_num); joint_num++; } else // collision volume { + joint->setJointNum(mNumBones+volume_num); volume_num++; } + // setup children LLAvatarBoneInfo::child_list_t::const_iterator iter; for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter) @@ -613,12 +694,12 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent //----------------------------------------------------------------------------- BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num ) { - clearSkeleton(); - - for(S32 joint_num = 0; joint_num < (S32)num; joint_num++) - { - mSkeleton.push_back(createAvatarJoint(joint_num)); - } + if (mSkeleton.size() != num) + { + clearSkeleton(); + mSkeleton = avatar_joint_list_t(num,NULL); + mNumBones = num; + } return TRUE; } @@ -629,18 +710,16 @@ BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num ) //----------------------------------------------------------------------------- BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info) { - //------------------------------------------------------------------------- + LL_DEBUGS("BVH") << "numBones " << info->mNumBones << " numCollisionVolumes " << info->mNumCollisionVolumes << LL_ENDL; + // allocate joints - //------------------------------------------------------------------------- if (!allocateCharacterJoints(info->mNumBones)) { LL_ERRS() << "Can't allocate " << info->mNumBones << " joints" << LL_ENDL; return FALSE; } - //------------------------------------------------------------------------- // allocate volumes - //------------------------------------------------------------------------- if (info->mNumCollisionVolumes) { if (!allocateCollisionVolumes(info->mNumCollisionVolumes)) @@ -655,8 +734,8 @@ BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info) LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter; for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter) { - LLAvatarBoneInfo *info = *iter; - if (!setupBone(info, NULL, current_volume_num, current_joint_num)) + LLAvatarBoneInfo *bone_info = *iter; + if (!setupBone(bone_info, NULL, current_volume_num, current_joint_num)) { LL_ERRS() << "Error parsing bone in skeleton file" << LL_ENDL; return FALSE; @@ -820,6 +899,7 @@ void LLAvatarAppearance::buildCharacter() //------------------------------------------------------------------------- // initialize the pelvis //------------------------------------------------------------------------- + // SL-315 mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) ); mIsBuilt = TRUE; @@ -834,21 +914,21 @@ BOOL LLAvatarAppearance::loadAvatar() // avatar_skeleton.xml if( !buildSkeleton(sAvatarSkeletonInfo) ) { - LL_WARNS() << "avatar file: buildSkeleton() failed" << LL_ENDL; + LL_ERRS() << "avatar file: buildSkeleton() failed" << LL_ENDL; return FALSE; } // avatar_lad.xml : <skeleton> if( !loadSkeletonNode() ) { - LL_WARNS() << "avatar file: loadNodeSkeleton() failed" << LL_ENDL; + LL_ERRS() << "avatar file: loadNodeSkeleton() failed" << LL_ENDL; return FALSE; } // avatar_lad.xml : <mesh> if( !loadMeshNodes() ) { - LL_WARNS() << "avatar file: loadNodeMesh() failed" << LL_ENDL; + LL_ERRS() << "avatar file: loadNodeMesh() failed" << LL_ENDL; return FALSE; } @@ -858,13 +938,13 @@ BOOL LLAvatarAppearance::loadAvatar() mTexSkinColor = new LLTexGlobalColor( this ); if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) ) { - LL_WARNS() << "avatar file: mTexSkinColor->setInfo() failed" << LL_ENDL; + LL_ERRS() << "avatar file: mTexSkinColor->setInfo() failed" << LL_ENDL; return FALSE; } } else { - LL_WARNS() << "<global_color> name=\"skin_color\" not found" << LL_ENDL; + LL_ERRS() << "<global_color> name=\"skin_color\" not found" << LL_ENDL; return FALSE; } if( sAvatarXmlInfo->mTexHairColorInfo ) @@ -872,13 +952,13 @@ BOOL LLAvatarAppearance::loadAvatar() mTexHairColor = new LLTexGlobalColor( this ); if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) ) { - LL_WARNS() << "avatar file: mTexHairColor->setInfo() failed" << LL_ENDL; + LL_ERRS() << "avatar file: mTexHairColor->setInfo() failed" << LL_ENDL; return FALSE; } } else { - LL_WARNS() << "<global_color> name=\"hair_color\" not found" << LL_ENDL; + LL_ERRS() << "<global_color> name=\"hair_color\" not found" << LL_ENDL; return FALSE; } if( sAvatarXmlInfo->mTexEyeColorInfo ) @@ -886,26 +966,26 @@ BOOL LLAvatarAppearance::loadAvatar() mTexEyeColor = new LLTexGlobalColor( this ); if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) ) { - LL_WARNS() << "avatar file: mTexEyeColor->setInfo() failed" << LL_ENDL; + LL_ERRS() << "avatar file: mTexEyeColor->setInfo() failed" << LL_ENDL; return FALSE; } } else { - LL_WARNS() << "<global_color> name=\"eye_color\" not found" << LL_ENDL; + LL_ERRS() << "<global_color> name=\"eye_color\" not found" << LL_ENDL; return FALSE; } // avatar_lad.xml : <layer_set> if (sAvatarXmlInfo->mLayerInfoList.empty()) { - LL_WARNS() << "avatar file: missing <layer_set> node" << LL_ENDL; + LL_ERRS() << "avatar file: missing <layer_set> node" << LL_ENDL; return FALSE; } if (sAvatarXmlInfo->mMorphMaskInfoList.empty()) { - LL_WARNS() << "avatar file: missing <morph_masks> node" << LL_ENDL; + LL_ERRS() << "avatar file: missing <morph_masks> node" << LL_ENDL; return FALSE; } @@ -1104,6 +1184,7 @@ BOOL LLAvatarAppearance::loadMeshNodes() { // This should never happen LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL; + return FALSE; } } else @@ -1240,6 +1321,10 @@ LLJoint *LLAvatarAppearance::getCharacterJoint( U32 num ) { return NULL; } + if (!mSkeleton[num]) + { + mSkeleton[num] = createAvatarJoint(); + } return mSkeleton[num]; } @@ -1476,16 +1561,19 @@ LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_in //----------------------------------------------------------------------------- BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num ) { - delete_and_clear_array(mCollisionVolumes); - mNumCollisionVolumes = 0; - - mCollisionVolumes = new LLAvatarJointCollisionVolume[num]; - if (!mCollisionVolumes) - { - return FALSE; - } - - mNumCollisionVolumes = num; + if (mNumCollisionVolumes !=num) + { + delete_and_clear_array(mCollisionVolumes); + mNumCollisionVolumes = 0; + + mCollisionVolumes = new LLAvatarJointCollisionVolume[num]; + if (!mCollisionVolumes) + { + return FALSE; + } + + mNumCollisionVolumes = num; + } return TRUE; } @@ -1503,6 +1591,9 @@ BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node) LL_WARNS() << "Bone without name" << LL_ENDL; return FALSE; } + + static LLStdStringHandle aliases_string = LLXmlTree::addAttributeString("aliases"); + node->getFastAttributeString(aliases_string, mAliases ); //Aliases are not required. } else if (node->hasName("collision_volume")) { @@ -1540,6 +1631,20 @@ BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node) return FALSE; } + static LLStdStringHandle end_string = LLXmlTree::addAttributeString("end"); + if (!node->getFastAttributeVector3(end_string, mEnd)) + { + LL_WARNS() << "Bone without end " << mName << LL_ENDL; + mEnd = LLVector3(0.0f, 0.0f, 0.0f); + } + + static LLStdStringHandle support_string = LLXmlTree::addAttributeString("support"); + if (!node->getFastAttributeString(support_string,mSupport)) + { + LL_WARNS() << "Bone without support " << mName << LL_ENDL; + mSupport = "base"; + } + if (mIsJoint) { static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); @@ -1595,6 +1700,54 @@ BOOL LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) return TRUE; } +//Make aliases for joint and push to map. +void LLAvatarAppearance::makeJointAliases(LLAvatarBoneInfo *bone_info) +{ + if (! bone_info->mIsJoint ) + { + return; + } + + std::string bone_name = bone_info->mName; + mJointAliasMap[bone_name] = bone_name; //Actual name is a valid alias. + + std::string aliases = bone_info->mAliases; + + boost::char_separator<char> sep(" "); + boost::tokenizer<boost::char_separator<char> > tok(aliases, sep); + for(boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i) + { + if ( mJointAliasMap.find(*i) != mJointAliasMap.end() ) + { + LL_WARNS() << "avatar skeleton: Joint alias \"" << *i << "\" remapped from " << mJointAliasMap[*i] << " to " << bone_name << LL_ENDL; + } + mJointAliasMap[*i] = bone_name; + } + + LLAvatarBoneInfo::child_list_t::const_iterator iter; + for (iter = bone_info->mChildList.begin(); iter != bone_info->mChildList.end(); ++iter) + { + makeJointAliases( *iter ); + } +} + +const LLAvatarAppearance::joint_alias_map_t& LLAvatarAppearance::getJointAliases () +{ + LLAvatarAppearance::joint_alias_map_t alias_map; + if (mJointAliasMap.empty()) + { + + LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter; + for (iter = sAvatarSkeletonInfo->mBoneInfoList.begin(); iter != sAvatarSkeletonInfo->mBoneInfoList.end(); ++iter) + { + //LLAvatarBoneInfo *bone_info = *iter; + makeJointAliases( *iter ); + } + } + + return mJointAliasMap; +} + //----------------------------------------------------------------------------- // parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree @@ -1625,7 +1778,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* ro { LL_WARNS() << "Unknown param type." << LL_ENDL; } - continue; + return FALSE; } LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo; @@ -1650,7 +1803,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* ro { LL_WARNS() << "No name supplied for attachment point." << LL_ENDL; delete info; - continue; + return FALSE; } static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint"); @@ -1658,7 +1811,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* ro { LL_WARNS() << "No bone declared in attachment point " << info->mName << LL_ENDL; delete info; - continue; + return FALSE; } static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position"); @@ -1684,7 +1837,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* ro { LL_WARNS() << "No id supplied for attachment point " << info->mName << LL_ENDL; delete info; - continue; + return FALSE; } static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice"); @@ -1770,7 +1923,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root) { LL_WARNS() << "Unknown param type." << LL_ENDL; } - continue; + return FALSE; } LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo(); @@ -1931,7 +2084,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root { LL_WARNS() << "No name supplied for morph mask." << LL_ENDL; delete info; - continue; + return FALSE; } static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region"); @@ -1939,7 +2092,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root { LL_WARNS() << "No region supplied for morph mask." << LL_ENDL; delete info; - continue; + return FALSE; } static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer"); @@ -1947,7 +2100,7 @@ BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root { LL_WARNS() << "No layer supplied for morph mask." << LL_ENDL; delete info; - continue; + return FALSE; } // optional parameter. don't throw a warning if not present. @@ -1973,5 +2126,3 @@ LLAvatarAppearance::LLMaskedMorph::LLMaskedMorph(LLVisualParam *morph_target, BO } } - - diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index a0ef49b7cb520e75b6bc94a4b839e1909691703f..ccd6323ed85e86cd327174360ac53dd9eba8808c 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -66,7 +66,8 @@ class LLAvatarAppearance : public LLCharacter LLAvatarAppearance(LLWearableData* wearable_data); virtual ~LLAvatarAppearance(); - static void initClass(); // initializes static members + static void initClass(const std::string& avatar_file_name, const std::string& skeleton_file_name); // initializes static members + static void initClass(); static void cleanupClass(); // Cleanup data that's only init'd once per class. virtual void initInstance(); // Called after construction to initialize the instance. virtual BOOL loadSkeletonNode(); @@ -124,8 +125,11 @@ class LLAvatarAppearance : public LLCharacter protected: virtual LLAvatarJoint* createAvatarJoint() = 0; - virtual LLAvatarJoint* createAvatarJoint(S32 joint_num) = 0; + virtual LLAvatarJoint* createAvatarJoint(S32 joint_num) = 0; virtual LLAvatarJointMesh* createAvatarJointMesh() = 0; + void makeJointAliases(LLAvatarBoneInfo *bone_info); + + public: F32 getPelvisToFoot() const { return mPelvisToFoot; } /*virtual*/ LLJoint* getRootJoint() { return mRoot; } @@ -135,9 +139,20 @@ class LLAvatarAppearance : public LLCharacter typedef std::map<std::string, LLJoint*> joint_map_t; joint_map_t mJointMap; - + + typedef std::map<std::string, LLVector3> joint_state_map_t; + joint_state_map_t mLastBodySizeState; + joint_state_map_t mCurrBodySizeState; + void compareJointStateMaps(joint_state_map_t& last_state, + joint_state_map_t& curr_state); void computeBodySize(); +public: + typedef std::vector<LLAvatarJoint*> avatar_joint_list_t; + const avatar_joint_list_t& getSkeleton() { return mSkeleton; } + typedef std::map<std::string, std::string> joint_alias_map_t; + const joint_alias_map_t& getJointAliases(); + protected: static BOOL parseSkeletonFile(const std::string& filename); @@ -147,12 +162,12 @@ class LLAvatarAppearance : public LLCharacter BOOL setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num); BOOL allocateCharacterJoints(U32 num); BOOL buildSkeleton(const LLAvatarSkeletonInfo *info); -protected: + void clearSkeleton(); BOOL mIsBuilt; // state of deferred character building - typedef std::vector<LLAvatarJoint*> avatar_joint_list_t; avatar_joint_list_t mSkeleton; - LLPosOverrideMap mPelvisFixups; + LLVector3OverrideMap mPelvisFixups; + joint_alias_map_t mJointAliasMap; //-------------------------------------------------------------------- // Pelvis height adjustment members. @@ -335,6 +350,7 @@ class LLAvatarAppearance : public LLCharacter // Collision volumes //-------------------------------------------------------------------- public: + S32 mNumBones; S32 mNumCollisionVolumes; LLAvatarJointCollisionVolume* mCollisionVolumes; protected: diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h index 8a1d2c4707e735823e94e17018240c4e8ad2fe9b..d6223bb4d24e732ceb01df1627434fd631dcda5f 100644 --- a/indra/llappearance/llavatarappearancedefines.h +++ b/indra/llappearance/llavatarappearancedefines.h @@ -127,8 +127,7 @@ class LLAvatarAppearanceDictionary : public LLSingleton<LLAvatarAppearanceDictio //-------------------------------------------------------------------- // Constructors and Destructors //-------------------------------------------------------------------- -public: - LLAvatarAppearanceDictionary(); + LLSINGLETON(LLAvatarAppearanceDictionary); virtual ~LLAvatarAppearanceDictionary(); private: void createAssociations(); diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp index 2ee3c65a01ddef2a2cde2a688fe40ffa5afb4261..29642be099a3d9c26c3fed801f332cf892ee948d 100644 --- a/indra/llappearance/llavatarjoint.cpp +++ b/indra/llappearance/llavatarjoint.cpp @@ -52,19 +52,18 @@ LLAvatarJoint::LLAvatarJoint() : init(); } -LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) : - LLJoint(name, parent) +LLAvatarJoint::LLAvatarJoint(S32 joint_num) : + LLJoint(joint_num) { - init(); + init(); } - -LLAvatarJoint::LLAvatarJoint(S32 joint_num) : - LLJoint(joint_num) + +LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) : + LLJoint(name, parent) { init(); } - void LLAvatarJoint::init() { mValid = FALSE; diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp index 520ad775db7cbc46c59a1c95b5bf01167f69325f..7ca0928171f55ab33a00832b9ac8948baf84f715 100644 --- a/indra/llappearance/llavatarjointmesh.cpp +++ b/indra/llappearance/llavatarjointmesh.cpp @@ -33,22 +33,7 @@ #include "llavatarjointmesh.h" #include "llavatarappearance.h" -//#include "llapr.h" -//#include "llbox.h" -//#include "lldrawable.h" -//#include "lldrawpoolavatar.h" -//#include "lldrawpoolbump.h" -//#include "lldynamictexture.h" -//#include "llface.h" -//#include "llgldbg.h" -//#include "llglheaders.h" #include "lltexlayer.h" -//#include "llviewercamera.h" -//#include "llviewercontrol.h" -//#include "llviewertexturelist.h" -//#include "llsky.h" -//#include "pipeline.h" -//#include "llviewershadermgr.h" #include "llmath.h" #include "v4math.h" #include "m3math.h" @@ -56,6 +41,41 @@ #include "llmatrix4a.h" +// Utility functions added with Bento to simplify handling of extra +// spine joints, or other new joints internal to the original +// skeleton, and unknown to the system avatar. + +//----------------------------------------------------------------------------- +// getBaseSkeletonAncestor() +//----------------------------------------------------------------------------- +LLAvatarJoint *getBaseSkeletonAncestor(LLAvatarJoint* joint) +{ + LLJoint *ancestor = joint->getParent(); + while (ancestor->getParent() && (ancestor->getSupport() != LLJoint::SUPPORT_BASE)) + { + LL_DEBUGS("Avatar") << "skipping non-base ancestor " << ancestor->getName() << LL_ENDL; + ancestor = ancestor->getParent(); + } + return (LLAvatarJoint*) ancestor; +} + +//----------------------------------------------------------------------------- +// totalSkinOffset() +//----------------------------------------------------------------------------- +LLVector3 totalSkinOffset(LLAvatarJoint *joint) +{ + LLVector3 totalOffset; + while (joint) + { + if (joint->getSupport() == LLJoint::SUPPORT_BASE) + { + totalOffset += joint->getSkinOffset(); + } + joint = (LLAvatarJoint*)joint->getParent(); + } + return totalOffset; +} + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // LLAvatarJointMesh::LLSkinJoint @@ -92,18 +112,12 @@ BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint) } // compute the inverse root skin matrix - mRootToJointSkinOffset.clearVec(); - - LLVector3 rootSkinOffset; - while (joint) - { - rootSkinOffset += joint->getSkinOffset(); - joint = (LLAvatarJoint*)joint->getParent(); - } + mRootToJointSkinOffset = totalSkinOffset(joint); + mRootToJointSkinOffset = -mRootToJointSkinOffset; - mRootToJointSkinOffset = -rootSkinOffset; - mRootToParentJointSkinOffset = mRootToJointSkinOffset; - mRootToParentJointSkinOffset += mJoint->getSkinOffset(); + //mRootToParentJointSkinOffset = totalSkinOffset((LLAvatarJoint*)joint->getParent()); + mRootToParentJointSkinOffset = totalSkinOffset(getBaseSkeletonAncestor(joint)); + mRootToParentJointSkinOffset = -mRootToParentJointSkinOffset; return TRUE; } @@ -289,6 +303,7 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh ) } // acquire the transform from the mesh object + // SL-315 setPosition( mMesh->getPosition() ); setRotation( mMesh->getRotation() ); setScale( mMesh->getScale() ); @@ -314,9 +329,9 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh ) if (!mMesh->isLOD()) { setupJoint((LLAvatarJoint*)getRoot()); + LL_DEBUGS("Avatar") << getName() << " joint render entries: " << mMesh->mJointRenderData.size() << LL_ENDL; } - LL_DEBUGS() << "joint render entries: " << mMesh->mJointRenderData.size() << LL_ENDL; } //----------------------------------------------------------------------------- @@ -324,9 +339,6 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh ) //----------------------------------------------------------------------------- void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint) { - LL_DEBUGS() << "Mesh: " << getName() << LL_ENDL; - - S32 joint_count = 0; U32 sj; for (sj=0; sj<mNumSkinJoints; sj++) @@ -339,22 +351,30 @@ void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint) } // we've found a skinjoint for this joint.. + LL_DEBUGS("Avatar") << "Mesh: " << getName() << " joint " << current_joint->getName() << " matches skinjoint " << sj << LL_ENDL; // is the last joint in the array our parent? - if(mMesh->mJointRenderData.size() && mMesh->mJointRenderData[mMesh->mJointRenderData.size() - 1]->mWorldMatrix == ¤t_joint->getParent()->getWorldMatrix()) + + std::vector<LLJointRenderData*> &jrd = mMesh->mJointRenderData; + + // SL-287 - need to update this so the results are the same if + // additional extended-skeleton joints lie between this joint + // and the original parent. + LLJoint *ancestor = getBaseSkeletonAncestor(current_joint); + if(jrd.size() && jrd.back()->mWorldMatrix == &ancestor->getWorldMatrix()) { // ...then just add ourselves LLAvatarJoint* jointp = js.mJoint; - mMesh->mJointRenderData.push_back(new LLJointRenderData(&jointp->getWorldMatrix(), &js)); - LL_DEBUGS() << "joint " << joint_count++ << js.mJoint->getName() << LL_ENDL; + jrd.push_back(new LLJointRenderData(&jointp->getWorldMatrix(), &js)); + LL_DEBUGS("Avatar") << "add joint[" << (jrd.size()-1) << "] = " << js.mJoint->getName() << LL_ENDL; } - // otherwise add our parent and ourselves + // otherwise add our ancestor and ourselves else { - mMesh->mJointRenderData.push_back(new LLJointRenderData(¤t_joint->getParent()->getWorldMatrix(), NULL)); - LL_DEBUGS() << "joint " << joint_count++ << current_joint->getParent()->getName() << LL_ENDL; - mMesh->mJointRenderData.push_back(new LLJointRenderData(¤t_joint->getWorldMatrix(), &js)); - LL_DEBUGS() << "joint " << joint_count++ << current_joint->getName() << LL_ENDL; + jrd.push_back(new LLJointRenderData(&ancestor->getWorldMatrix(), NULL)); + LL_DEBUGS("Avatar") << "add2 ancestor joint[" << (jrd.size()-1) << "] = " << ancestor->getName() << LL_ENDL; + jrd.push_back(new LLJointRenderData(¤t_joint->getWorldMatrix(), &js)); + LL_DEBUGS("Avatar") << "add2 joint[" << (jrd.size()-1) << "] = " << current_joint->getName() << LL_ENDL; } } diff --git a/indra/llappearance/lldriverparam.cpp b/indra/llappearance/lldriverparam.cpp index e630c1118bc859c71c8c0911e3ceb6ec0d0a144b..e5e502b158fd72b3d7e3bc4bfce10bc9635d1da6 100644 --- a/indra/llappearance/lldriverparam.cpp +++ b/indra/llappearance/lldriverparam.cpp @@ -110,6 +110,14 @@ void LLDriverParamInfo::toStream(std::ostream &out) out << std::endl; + // FIXME - this mDriverParam backlink makes no sense, because the + // LLDriverParamInfos are static objects - there's only one copy + // for each param type, so the backlink will just reference the + // corresponding param in the most recently created + // avatar. Apparently these toStream() methods are not currently + // used anywhere, so it's not an urgent problem. + LL_WARNS_ONCE() << "Invalid usage of mDriverParam." << LL_ENDL; + if(mDriverParam && mDriverParam->getAvatarAppearance()->isSelf() && mDriverParam->getAvatarAppearance()->isValid()) { diff --git a/indra/llappearance/lldriverparam.h b/indra/llappearance/lldriverparam.h index f71c930e5e3716fbf67683690f9f372fd5f02142..f278dcc2e29b0746afa157676bcf88603f832967 100644 --- a/indra/llappearance/lldriverparam.h +++ b/indra/llappearance/lldriverparam.h @@ -128,6 +128,10 @@ class LLDriverParam : public LLViewerVisualParam S32 getDrivenParamsCount() const; const LLViewerVisualParam* getDrivenParam(S32 index) const; + typedef std::vector<LLDrivenEntry> entry_list_t; + entry_list_t& getDrivenList() { return mDriven; } + void setDrivenList(entry_list_t& driven_list) { mDriven = driven_list; } + protected: LLDriverParam(const LLDriverParam& pOther); F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight); @@ -135,7 +139,6 @@ class LLDriverParam : public LLViewerVisualParam LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder - typedef std::vector<LLDrivenEntry> entry_list_t; entry_list_t mDriven; LLViewerVisualParam* mCurrentDistortionParam; // Backlink only; don't make this an LLPointer. diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index e3992a080e4b02d93c0be859e9a69100ccb4ed01..2cb4c65d7c49a197f1e871397c010a6038c6265f 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -369,7 +369,8 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info) { if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName) { - mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i], + mVolumeMorphs.push_back( + LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i], volume_info->mScale, volume_info->mPos)); break; @@ -647,6 +648,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) LLVector3 pos_delta = volume_morph->mPos * delta_weight; volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta); + // SL-315 volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta); } } @@ -730,6 +732,20 @@ void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3 apply(mLastSex); } +void LLPolyMorphTarget::applyVolumeChanges(F32 delta_weight) +{ + // now apply volume changes + for( volume_list_t::iterator iter = mVolumeMorphs.begin(); iter != mVolumeMorphs.end(); iter++ ) + { + LLPolyVolumeMorph* volume_morph = &(*iter); + LLVector3 scale_delta = volume_morph->mScale * delta_weight; + LLVector3 pos_delta = volume_morph->mPos * delta_weight; + + volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta); + // SL-315 + volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta); + } +} //----------------------------------------------------------------------------- // LLPolyVertexMask() diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h index 3c2c68079c39d29169dbc3083b96ab77aaa3da93..c6133cd83119605a7f2085db8ea9e1f37966658b 100644 --- a/indra/llappearance/llpolymorph.h +++ b/indra/llappearance/llpolymorph.h @@ -182,6 +182,8 @@ class LLPolyMorphTarget : public LLViewerVisualParam void applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert); void addPendingMorphMask() { mNumMorphMasksPending++; } + void applyVolumeChanges(F32 delta_weight); // SL-315 - for resetSkeleton() + void* operator new(size_t size) { return ll_aligned_malloc_16(size); diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp index fbc312c42642923f9700db09cb0898d27cd232f7..5b77a7433ac3d50e1f8bb96620f7fa7d824a7c6c 100644 --- a/indra/llappearance/llpolyskeletaldistortion.cpp +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -34,6 +34,7 @@ #include "llpolymorph.h" #include "llwearable.h" #include "llfasttimer.h" +#include "llcallstack.h" #include "llpolyskeletaldistortion.h" @@ -134,55 +135,49 @@ LLPolySkeletalDistortion::~LLPolySkeletalDistortion() BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) { - llassert(mInfo == NULL); - if (info->mID < 0) - return FALSE; - mInfo = info; - mID = info->mID; - setWeight(getDefaultWeight()); - - LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter; - for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++) + if (info->mID < 0) + { + return FALSE; + } + mInfo = info; + mID = info->mID; + setWeight(getDefaultWeight()); + + LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter; + for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++) + { + LLPolySkeletalBoneInfo *bone_info = &(*iter); + LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName); + if (!joint) { - LLPolySkeletalBoneInfo *bone_info = &(*iter); - LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName); - if (!joint) - { - LL_WARNS() << "Joint " << bone_info->mBoneName << " not found." << LL_ENDL; - continue; - } - - if (mJointScales.find(joint) != mJointScales.end()) - { - LL_WARNS() << "Scale deformation already supplied for joint " << joint->getName() << "." << LL_ENDL; - } + // There's no point continuing after this error - means + // that either the skeleton or lad file is broken. + LL_WARNS() << "Joint " << bone_info->mBoneName << " not found." << LL_ENDL; + return FALSE; + } - // store it - mJointScales[joint] = bone_info->mScaleDeformation; + // store it + mJointScales[joint] = bone_info->mScaleDeformation; - // apply to children that need to inherit it - for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin(); - iter != joint->mChildren.end(); ++iter) - { - LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter); - if (child_joint->inheritScale()) - { - LLVector3 childDeformation = LLVector3(child_joint->getScale()); - childDeformation.scaleVec(bone_info->mScaleDeformation); - mJointScales[child_joint] = childDeformation; - } - } + // apply to children that need to inherit it + for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin(); + iter != joint->mChildren.end(); ++iter) + { + LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter); + if (child_joint->inheritScale()) + { + LLVector3 childDeformation = LLVector3(child_joint->getScale()); + childDeformation.scaleVec(bone_info->mScaleDeformation); + mJointScales[child_joint] = childDeformation; + } + } - if (bone_info->mHasPositionDeformation) - { - if (mJointOffsets.find(joint) != mJointOffsets.end()) - { - LL_WARNS() << "Offset deformation already supplied for joint " << joint->getName() << "." << LL_ENDL; - } - mJointOffsets[joint] = bone_info->mPositionDeformation; - } + if (bone_info->mHasPositionDeformation) + { + mJointOffsets[joint] = bone_info->mPositionDeformation; } - return TRUE; + } + return TRUE; } /*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const @@ -197,42 +192,52 @@ static LLTrace::BlockTimerStatHandle FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal void LLPolySkeletalDistortion::apply( ESex avatar_sex ) { - LL_RECORD_BLOCK_TIME(FTM_POLYSKELETAL_DISTORTION_APPLY); - - F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight(); - - LLJoint* joint; - joint_vec_map_t::iterator iter; - - for (iter = mJointScales.begin(); - iter != mJointScales.end(); - iter++) - { - joint = iter->first; - LLVector3 newScale = joint->getScale(); - LLVector3 scaleDelta = iter->second; - newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta); - //An aspect of attached mesh objects (which contain joint offsets) that need to be cleaned up when detached - // needed? // joint->storeScaleForReset( newScale ); - joint->setScale(newScale); - } - - for (iter = mJointOffsets.begin(); - iter != mJointOffsets.end(); - iter++) - { - joint = iter->first; - LLVector3 newPosition = joint->getPosition(); - LLVector3 positionDelta = iter->second; - newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta); - joint->setPosition(newPosition); - } - - if (mLastWeight != mCurWeight && !mIsAnimating) - { - mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1); - } - mLastWeight = mCurWeight; + LL_RECORD_BLOCK_TIME(FTM_POLYSKELETAL_DISTORTION_APPLY); + + F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight(); + + LLJoint* joint; + joint_vec_map_t::iterator iter; + + for (iter = mJointScales.begin(); + iter != mJointScales.end(); + iter++) + { + joint = iter->first; + LLVector3 newScale = joint->getScale(); + LLVector3 scaleDelta = iter->second; + LLVector3 offset = (effective_weight - mLastWeight) * scaleDelta; + newScale = newScale + offset; + //An aspect of attached mesh objects (which contain joint offsets) that need to be cleaned up when detached + // needed? + // joint->storeScaleForReset( newScale ); + + // BENTO for detailed stack tracing of params. + std::stringstream ostr; + ostr << "LLPolySkeletalDistortion::apply, id " << getID() << " " << getName() << " effective wt " << effective_weight << " last wt " << mLastWeight << " scaleDelta " << scaleDelta << " offset " << offset; + LLScopedContextString str(ostr.str()); + + joint->setScale(newScale, true); + } + + for (iter = mJointOffsets.begin(); + iter != mJointOffsets.end(); + iter++) + { + joint = iter->first; + LLVector3 newPosition = joint->getPosition(); + LLVector3 positionDelta = iter->second; + newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta); + // SL-315 + bool allow_attachment_pos_overrides = true; + joint->setPosition(newPosition, allow_attachment_pos_overrides); + } + + if (mLastWeight != effective_weight && !mIsAnimating) + { + mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1); + } + mLastWeight = effective_weight; } diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h index 959d6e499abfb348bf8709e2b4c6b618871a9e3c..9318b23fd199b32841d84a7192748634dcf282e2 100644 --- a/indra/llappearance/lltexlayer.h +++ b/indra/llappearance/lltexlayer.h @@ -293,9 +293,9 @@ class LLTexLayerSetBuffer : public virtual LLRefCount //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList> { -public: - LLTexLayerStaticImageList(); + LLSINGLETON(LLTexLayerStaticImageList); ~LLTexLayerStaticImageList(); +public: LLGLTexture* getTexture(const std::string& file_name, BOOL is_mask); LLImageTGA* getImageTGA(const std::string& file_name); void deleteCachedImages(); diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index 5ca9f55ac8ce9d33fa2a4cb905e705cd5d5f538e..63069adcc866e33fad7c6371e9ff06b0af797d73 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -173,7 +173,7 @@ void LLWearable::createVisualParams(LLAvatarAppearance *avatarp) { if( !param->linkDrivenParams(boost::bind(param_function,avatarp,_1 ), true)) { - LL_WARNS() << "could not link driven params for wearable " << getName() << " id: " << param->getID() << LL_ENDL; + LL_DEBUGS("Avatar") << "could not link driven params for wearable " << getName() << " id: " << param->getID() << LL_ENDL; continue; } } diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp index 87109a5906ec7263b5d1957f4c6bcbe2781fc476..207e0c4011f2e9c9496ea6c34b487d991b92f8a8 100644 --- a/indra/llappearance/llwearabletype.cpp +++ b/indra/llappearance/llwearabletype.cpp @@ -71,8 +71,7 @@ struct WearableEntry : public LLDictionaryEntry class LLWearableDictionary : public LLSingleton<LLWearableDictionary>, public LLDictionary<LLWearableType::EType, WearableEntry> { -public: - LLWearableDictionary(); + LLSINGLETON(LLWearableDictionary); }; LLWearableDictionary::LLWearableDictionary() diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index 2573417b260536371d7a93c87e459514b597db37..a17a5b0aa6bee291b535ffb0bc257ed10708cad7 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -91,12 +91,12 @@ target_link_libraries( # Add tests -if (LL_TESTS) - include(LLAddBuildTest) - # UNIT TESTS - SET(llcharacter_TEST_SOURCE_FILES - lljoint.cpp - ) - LL_ADD_PROJECT_UNIT_TESTS(llcharacter "${llcharacter_TEST_SOURCE_FILES}") -endif (LL_TESTS) +#if (LL_TESTS) +# include(LLAddBuildTest) +# # UNIT TESTS +# SET(llcharacter_TEST_SOURCE_FILES +# lljoint.cpp +# ) +# LL_ADD_PROJECT_UNIT_TESTS(llcharacter "${llcharacter_TEST_SOURCE_FILES}") +#endif (LL_TESTS) diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 0d558aeaa2be3717b5f34188d5e1ac2af755c297..e906d81ce15229ae99aad55dd06c4bcecee4d5c6 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -11,7 +11,7 @@ * License as published by the Free Software Foundation; * version 2.1 of the License only. * - * This library is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful,7 * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. @@ -29,6 +29,7 @@ #include "llbvhloader.h" #include <boost/tokenizer.hpp> +#include <boost/lexical_cast.hpp> #include "lldatapacker.h" #include "lldir.h" @@ -36,6 +37,7 @@ #include "llquantize.h" #include "llstl.h" #include "llapr.h" +#include "llsdserialize.h" using namespace std; @@ -121,52 +123,16 @@ LLQuaternion::Order bvhStringToOrder( char *str ) // LLBVHLoader() //----------------------------------------------------------------------------- -/* - LLBVHLoader::LLBVHLoader(const char* buffer) -{ - reset(); - - mStatus = loadTranslationTable("anim.ini"); - - if (mStatus == LLBVHLoader::ST_NO_XLT_FILE) - { - LL_WARNS() << "NOTE: No translation table found." << LL_ENDL; - return; - } - else - { - if (mStatus != LLBVHLoader::ST_OK) - { - LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; - return; - } - } - - char error_text[128]; // Flawfinder: ignore - S32 error_line; - mStatus = loadBVHFile(buffer, error_text, error_line); - if (mStatus != LLBVHLoader::ST_OK) - { - LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; - return; - } - - applyTranslations(); - optimize(); - - mInitialized = TRUE; -} -*/ -LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine) +LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map ) { reset(); errorLine = 0; mStatus = loadTranslationTable("anim.ini"); loadStatus = mStatus; - LL_INFOS()<<"Load Status 00 : "<< loadStatus << LL_ENDL; + LL_INFOS("BVH") << "Load Status 00 : " << loadStatus << LL_ENDL; if (mStatus == E_ST_NO_XLT_FILE) { - //LL_WARNS() << "NOTE: No translation table found." << LL_ENDL; + LL_WARNS("BVH") << "NOTE: No translation table found." << LL_ENDL; loadStatus = mStatus; return; } @@ -174,28 +140,43 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error { if (mStatus != E_ST_OK) { - //LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; + LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; errorLine = getLineNumber(); loadStatus = mStatus; return; } } + + // Recognize all names we've been told are legal. + std::map<std::string, std::string>::iterator iter; + for (iter = joint_alias_map.begin(); iter != joint_alias_map.end(); iter++) + { + makeTranslation( iter->first , iter->second ); + } char error_text[128]; /* Flawfinder: ignore */ S32 error_line; - mStatus = loadBVHFile(buffer, error_text, error_line); + mStatus = loadBVHFile(buffer, error_text, error_line); //Reads all joints in BVH file. + + LL_DEBUGS("BVH") << "============================================================" << LL_ENDL; + LL_DEBUGS("BVH") << "Raw data from file" << LL_ENDL; + dumpBVHInfo(); if (mStatus != E_ST_OK) { - //LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; + LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; loadStatus = mStatus; errorLine = getLineNumber(); return; } - applyTranslations(); + applyTranslations(); //Maps between joints found in file and the aliased names. optimize(); + LL_DEBUGS("BVH") << "============================================================" << LL_ENDL; + LL_DEBUGS("BVH") << "After translations and optimize" << LL_ENDL; + dumpBVHInfo(); + mInitialized = TRUE; } @@ -211,10 +192,6 @@ LLBVHLoader::~LLBVHLoader() //------------------------------------------------------------------------ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) { - mLineNumber = 0; - mTranslations.clear(); - mConstraints.clear(); - //-------------------------------------------------------------------- // open file //-------------------------------------------------------------------- @@ -226,7 +203,7 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) if (!fp) return E_ST_NO_XLT_FILE; - LL_INFOS() << "NOTE: Loading translation table: " << fileName << LL_ENDL; + LL_INFOS("BVH") << "NOTE: Loading translation table: " << fileName << LL_ENDL; //-------------------------------------------------------------------- // register file to be closed on function exit @@ -244,7 +221,6 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) // load data one line at a time //-------------------------------------------------------------------- BOOL loadingGlobals = FALSE; - Translation *trans = NULL; while ( getLine(fp) ) { //---------------------------------------------------------------- @@ -271,13 +247,6 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) loadingGlobals = TRUE; continue; } - else - { - loadingGlobals = FALSE; - Translation &newTrans = mTranslations[ name ]; - trans = &newTrans; - continue; - } } //---------------------------------------------------------------- @@ -499,174 +468,102 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) mConstraints.push_back(constraint); continue; } + } + infile.close() ; + return E_ST_OK; +} +void LLBVHLoader::makeTranslation(std::string alias_name, std::string joint_name) +{ + //Translation &newTrans = (foomap.insert(value_type(alias_name, Translation()))).first(); + Translation &newTrans = mTranslations[ alias_name ]; //Uses []'s implicit call to ctor. + + newTrans.mOutName = joint_name; + LLMatrix3 fm; + LLVector3 vect1(0, 1, 0); + LLVector3 vect2(0, 0, 1); + LLVector3 vect3(1, 0, 0); + fm.setRows(vect1, vect2, vect3); + + newTrans.mFrameMatrix = fm; + +if (joint_name == "mPelvis") + { + newTrans.mRelativePositionKey = TRUE; + newTrans.mRelativeRotationKey = TRUE; + } - //---------------------------------------------------------------- - // at this point there must be a valid trans pointer - //---------------------------------------------------------------- - if ( ! trans ) - return E_ST_NO_XLT_NAME; - - //---------------------------------------------------------------- - // check for ignore flag - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "ignore")==0 ) - { - char trueFalse[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", trueFalse) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_IGNORE; - - trans->mIgnore = (LLStringUtil::compareInsensitive(trueFalse, "true")==0); - continue; - } - - //---------------------------------------------------------------- - // check for relativepos flag - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "relativepos")==0 ) - { - F32 x, y, z; - char relpos[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %f %f %f", &x, &y, &z) == 3 ) - { - trans->mRelativePosition.setVec( x, y, z ); - } - else if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */ - { - if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 ) - { - trans->mRelativePositionKey = TRUE; - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - - continue; - } - - //---------------------------------------------------------------- - // check for relativerot flag - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "relativerot")==0 ) - { - //F32 x, y, z; - char relpos[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */ - { - if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 ) - { - trans->mRelativeRotationKey = TRUE; - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - - continue; - } - - //---------------------------------------------------------------- - // check for outname value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "outname")==0 ) - { - char outName[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", outName) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_OUTNAME; - - trans->mOutName = outName; - continue; - } - - //---------------------------------------------------------------- - // check for frame matrix value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "frame")==0 ) - { - LLMatrix3 fm; - if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f", - &fm.mMatrix[0][0], &fm.mMatrix[0][1], &fm.mMatrix[0][2], - &fm.mMatrix[1][0], &fm.mMatrix[1][1], &fm.mMatrix[1][2], - &fm.mMatrix[2][0], &fm.mMatrix[2][1], &fm.mMatrix[2][2] ) != 9 ) - return E_ST_NO_XLT_MATRIX; - - trans->mFrameMatrix = fm; - continue; - } - - //---------------------------------------------------------------- - // check for offset matrix value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "offset")==0 ) - { - LLMatrix3 om; - if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f", - &om.mMatrix[0][0], &om.mMatrix[0][1], &om.mMatrix[0][2], - &om.mMatrix[1][0], &om.mMatrix[1][1], &om.mMatrix[1][2], - &om.mMatrix[2][0], &om.mMatrix[2][1], &om.mMatrix[2][2] ) != 9 ) - return E_ST_NO_XLT_MATRIX; - - trans->mOffsetMatrix = om; - continue; - } - - //---------------------------------------------------------------- - // check for mergeparent value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "mergeparent")==0 ) - { - char mergeParentName[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", mergeParentName) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_MERGEPARENT; - - trans->mMergeParentName = mergeParentName; - continue; - } - - //---------------------------------------------------------------- - // check for mergechild value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "mergechild")==0 ) - { - char mergeChildName[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", mergeChildName) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_MERGECHILD; +} - trans->mMergeChildName = mergeChildName; - continue; - } +ELoadStatus LLBVHLoader::loadAliases(const char * filename) +{ + LLSD aliases_sd; + + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,filename); + + llifstream input_stream; + input_stream.open(fullpath.c_str(), std::ios::in | std::ios::binary); + + if(input_stream.is_open()) + { + if ( LLSDSerialize::fromXML(aliases_sd, input_stream) ) + { + for(LLSD::map_iterator alias_iter = aliases_sd.beginMap(); + alias_iter != aliases_sd.endMap(); + ++alias_iter) + { + LLSD::String alias_name = alias_iter->first; + LLSD::String joint_name = alias_iter->second; + makeTranslation(alias_name, joint_name); + + } + } + else + { + return E_ST_NO_XLT_HEADER; + } + input_stream.close(); + } + else + { + LL_WARNS("BVH") << "Can't open joint alias file " << fullpath << LL_ENDL; + return E_ST_NO_XLT_FILE; + } + + return E_ST_OK; +} - //---------------------------------------------------------------- - // check for per-joint priority - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "priority")==0 ) +void LLBVHLoader::dumpBVHInfo() +{ + for (U32 j=0; j<mJoints.size(); j++) + { + Joint *joint = mJoints[j]; + LL_DEBUGS("BVH") << joint->mName << LL_ENDL; + for (S32 i=0; i<mNumFrames; i++) { - S32 priority; - if ( sscanf(mLine, " %*s = %d", &priority) != 1 ) - return E_ST_NO_XLT_PRIORITY; - - trans->mPriorityModifier = priority; - continue; + if (i<joint->mKeys.size()) // Check this in case file load failed. + { + Key &prevkey = joint->mKeys[llmax(i-1,0)]; + Key &key = joint->mKeys[i]; + if ((i==0) || + (key.mPos[0] != prevkey.mPos[0]) || + (key.mPos[1] != prevkey.mPos[1]) || + (key.mPos[2] != prevkey.mPos[2]) || + (key.mRot[0] != prevkey.mRot[0]) || + (key.mRot[1] != prevkey.mRot[1]) || + (key.mRot[2] != prevkey.mRot[2]) + ) + { + LL_DEBUGS("BVH") << "FRAME " << i + << " POS " << key.mPos[0] << "," << key.mPos[1] << "," << key.mPos[2] + << " ROT " << key.mRot[0] << "," << key.mRot[1] << "," << key.mRot[2] << LL_ENDL; + } + } } - } - infile.close() ; - return E_ST_OK; } - //------------------------------------------------------------------------ // LLBVHLoader::loadBVHFile() //------------------------------------------------------------------------ @@ -746,6 +643,7 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & { iter++; // { iter++; // OFFSET + iter++; // } S32 depth = 0; for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--) { @@ -777,12 +675,19 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & //--------------------------------------------------------------- // we require the root joint be "hip" - DEV-26188 //--------------------------------------------------------------- - const char* FORCED_ROOT_NAME = "hip"; - if ( (mJoints.size() == 0 ) && ( !strstr(jointName, FORCED_ROOT_NAME) ) ) - { - strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ - return E_ST_BAD_ROOT; - } + if (mJoints.size() == 0 ) + { + //The root joint of the BVH file must be hip (mPelvis) or an alias of mPelvis. + const char* FORCED_ROOT_NAME = "hip"; + + TranslationMap::iterator hip_joint = mTranslations.find( FORCED_ROOT_NAME ); + TranslationMap::iterator root_joint = mTranslations.find( jointName ); + if ( hip_joint == mTranslations.end() || root_joint == mTranslations.end() || root_joint->second.mOutName != hip_joint->second.mOutName ) + { + strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ + return E_ST_BAD_ROOT; + } + } //---------------------------------------------------------------- @@ -790,11 +695,14 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & //---------------------------------------------------------------- mJoints.push_back( new Joint( jointName ) ); Joint *joint = mJoints.back(); + LL_DEBUGS("BVH") << "Created joint " << jointName << LL_ENDL; + LL_DEBUGS("BVH") << "- index " << mJoints.size()-1 << LL_ENDL; S32 depth = 1; for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--) { Joint *pjoint = mJoints[parent_joints[j]]; + LL_DEBUGS("BVH") << "- ancestor " << pjoint->mName << LL_ENDL; if (depth > pjoint->mChildTreeMaxDepth) { pjoint->mChildTreeMaxDepth = depth; @@ -863,6 +771,21 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & return E_ST_NO_CHANNELS; } + // Animating position (via mNumChannels = 6) is only supported for mPelvis. + int res = sscanf(line.c_str(), " CHANNELS %d", &joint->mNumChannels); + if ( res != 1 ) + { + // Assume default if not otherwise specified. + if (mJoints.size()==1) + { + joint->mNumChannels = 6; + } + else + { + joint->mNumChannels = 3; + } + } + //---------------------------------------------------------------- // get rotation order //---------------------------------------------------------------- @@ -961,57 +884,49 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & line = (*(iter++)); err_line++; - // read and store values - const char *p = line.c_str(); + // Split line into a collection of floats. + std::deque<F32> floats; + boost::char_separator<char> whitespace_sep("\t "); + tokenizer float_tokens(line, whitespace_sep); + tokenizer::iterator float_token_iter = float_tokens.begin(); + while (float_token_iter != float_tokens.end()) + { + try + { + F32 val = boost::lexical_cast<float>(*float_token_iter); + floats.push_back(val); + } + catch (const boost::bad_lexical_cast&) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_POS; + } + float_token_iter++; + } + LL_DEBUGS("BVH") << "Got " << floats.size() << " floats " << LL_ENDL; for (U32 j=0; j<mJoints.size(); j++) { Joint *joint = mJoints[j]; joint->mKeys.push_back( Key() ); Key &key = joint->mKeys.back(); - // get 3 pos values for root joint only - if (j==0) + if (floats.size() < joint->mNumChannels) { - if ( sscanf(p, "%f %f %f", key.mPos, key.mPos+1, key.mPos+2) != 3 ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_POS; - } + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_POS; } - // skip to next 3 values in the line - p = find_next_whitespace(p); - if (!p) + // assume either numChannels == 6, in which case we have pos + rot, + // or numChannels == 3, in which case we have only rot. + if (joint->mNumChannels == 6) { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_ROT; + key.mPos[0] = floats.front(); floats.pop_front(); + key.mPos[1] = floats.front(); floats.pop_front(); + key.mPos[2] = floats.front(); floats.pop_front(); } - p = find_next_whitespace(++p); - if (!p) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_ROT; - } - p = find_next_whitespace(++p); - if (!p) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_ROT; - } - - // get 3 rot values for joint - F32 rot[3]; - if ( sscanf(p, " %f %f %f", rot, rot+1, rot+2) != 3 ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_ROT; - } - - p++; - - key.mRot[ joint->mOrder[0]-'X' ] = rot[0]; - key.mRot[ joint->mOrder[1]-'X' ] = rot[1]; - key.mRot[ joint->mOrder[2]-'X' ] = rot[2]; + key.mRot[ joint->mOrder[0]-'X' ] = floats.front(); floats.pop_front(); + key.mRot[ joint->mOrder[1]-'X' ] = floats.front(); floats.pop_front(); + key.mRot[ joint->mOrder[2]-'X' ] = floats.front(); floats.pop_front(); } } @@ -1045,7 +960,7 @@ void LLBVHLoader::applyTranslations() //---------------------------------------------------------------- if ( trans.mIgnore ) { - //LL_INFOS() << "NOTE: Ignoring " << joint->mName.c_str() << LL_ENDL; + //LL_INFOS() << "NOTE: Ignoring " << joint->mName.c_str() << LL_ENDL; joint->mIgnore = TRUE; continue; } @@ -1059,13 +974,12 @@ void LLBVHLoader::applyTranslations() joint->mOutName = trans.mOutName; } - //---------------------------------------------------------------- - // Set the ignorepos flag if necessary - //---------------------------------------------------------------- - if ( joint->mOutName == std::string("mPelvis") ) - { - joint->mIgnorePositions = FALSE; - } + //Allow joint position changes as of SL-318 + joint->mIgnorePositions = FALSE; + if (joint->mNumChannels == 3) + { + joint->mIgnorePositions = TRUE; + } //---------------------------------------------------------------- // Set the relativepos flags if necessary @@ -1334,6 +1248,9 @@ void LLBVHLoader::reset() mInitialized = FALSE; mEmoteName = ""; + mLineNumber = 0; + mTranslations.clear(); + mConstraints.clear(); } //------------------------------------------------------------------------ @@ -1508,8 +1425,8 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) frame++; } - // output position keys (only for 1st joint) - if ( ji == mJoints.begin() && !joint->mIgnorePositions ) + // output position keys if joint has motion. + if ( !joint->mIgnorePositions ) { dp.packS32(joint->mNumPosKeys, "num_pos_keys"); @@ -1539,6 +1456,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) outPos *= INCHES_TO_METERS; + //SL-318 Pelvis position can only move 5m. Limiting all joint position offsets to this dist. outPos -= relPos; outPos.clamp(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); @@ -1586,5 +1504,6 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) dp.packF32(constraint_it->mEaseOutStop, "ease_out_stop"); } + return TRUE; } diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h index f816b7627723bca0d18cedd545099a88835c34e5..47fe4090472bb4da83702239725a40909026bba6 100644 --- a/indra/llcharacter/llbvhloader.h +++ b/indra/llcharacter/llbvhloader.h @@ -102,6 +102,7 @@ struct Joint mNumRotKeys = 0; mChildTreeMaxDepth = 0; mPriority = 0; + mNumChannels = 3; } // Include aligned members first @@ -123,6 +124,7 @@ struct Joint S32 mNumRotKeys; S32 mChildTreeMaxDepth; S32 mPriority; + S32 mNumChannels; }; @@ -225,8 +227,7 @@ class LLBVHLoader friend class LLKeyframeMotion; public: // Constructor -// LLBVHLoader(const char* buffer); - LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine); + LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map ); ~LLBVHLoader(); /* @@ -265,13 +266,22 @@ class LLBVHLoader static const char *ST_NO_XLT_EMOTE; static const char *ST_BAD_ROOT; */ + // Loads the specified translation table. ELoadStatus loadTranslationTable(const char *fileName); + //Create a new joint alias + void makeTranslation(std::string key, std::string value); + + // Loads joint aliases from XML file. + ELoadStatus loadAliases(const char * filename); + // Load the specified BVH file. // Returns status code. ELoadStatus loadBVHFile(const char *buffer, char *error_text, S32 &error_line); + void dumpBVHInfo(); + // Applies translations to BVH data loaded. void applyTranslations(); diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index f4a37a139aa147e00fee9ee9e8ac64c492cd35b2..ddf89f30f22bb34f35df1ed65775c0ab39dd56d1 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -117,6 +117,7 @@ LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *characte addJointState( mWristState ); // propagate joint positions to kinematic chain + // SL-315 mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); @@ -143,6 +144,7 @@ LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *characte BOOL LLEditingMotion::onActivate() { // propagate joint positions to kinematic chain + // SL-315 mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); @@ -181,6 +183,7 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) focus_pt += mCharacter->getCharacterPosition(); // propagate joint positions to kinematic chain + // SL-315 mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); @@ -217,7 +220,8 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) " and focus point " << focus_pt << LL_ENDL; target.setVec(1.f, 1.f, 1.f); } - + + // SL-315 mTarget.setPosition( target + mParentJoint.getPosition()); // LL_INFOS() << "Point At: " << mTarget.getPosition() << LL_ENDL; diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 812c4201af465815b3e3442c59f0bc7982aaf9f6..e91de7a11d8a17a3e73942957a5ac4342f9f1b17 100644 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -285,7 +285,10 @@ LLEyeMotion::LLEyeMotion(const LLUUID &id) : LLMotion(id) mName = "eye_rot"; mLeftEyeState = new LLJointState; + mAltLeftEyeState = new LLJointState; + mRightEyeState = new LLJointState; + mAltRightEyeState = new LLJointState; } @@ -318,18 +321,38 @@ LLMotion::LLMotionInitStatus LLEyeMotion::onInitialize(LLCharacter *character) return STATUS_FAILURE; } + mAltLeftEyeState->setJoint( character->getJoint("mFaceEyeAltLeft") ); + if ( ! mAltLeftEyeState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get alt left eyeball joint." << LL_ENDL; + return STATUS_FAILURE; + } + mRightEyeState->setJoint( character->getJoint("mEyeRight") ); if ( ! mRightEyeState->getJoint() ) { - LL_INFOS() << getName() << ": Can't get Right eyeball joint." << LL_ENDL; + LL_INFOS() << getName() << ": Can't get right eyeball joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mAltRightEyeState->setJoint( character->getJoint("mFaceEyeAltRight") ); + if ( ! mAltRightEyeState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get alt right eyeball joint." << LL_ENDL; return STATUS_FAILURE; } mLeftEyeState->setUsage(LLJointState::ROT); + mAltLeftEyeState->setUsage(LLJointState::ROT); + mRightEyeState->setUsage(LLJointState::ROT); + mAltRightEyeState->setUsage(LLJointState::ROT); addJointState( mLeftEyeState ); + addJointState( mAltLeftEyeState ); + addJointState( mRightEyeState ); + addJointState( mAltRightEyeState ); return STATUS_SUCCESS; } @@ -343,17 +366,98 @@ BOOL LLEyeMotion::onActivate() return TRUE; } - //----------------------------------------------------------------------------- -// LLEyeMotion::onUpdate() +// LLEyeMotion::adjustEyeTarget() //----------------------------------------------------------------------------- -BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) +void LLEyeMotion::adjustEyeTarget(LLVector3* targetPos, LLJointState& left_eye_state, LLJointState& right_eye_state) { // Compute eye rotation. + BOOL has_eye_target = FALSE; LLQuaternion target_eye_rot; LLVector3 eye_look_at; F32 vergence; + if (targetPos) + { + LLVector3 skyward(0.f, 0.f, 1.f); + LLVector3 left; + LLVector3 up; + + eye_look_at = *targetPos; + has_eye_target = TRUE; + F32 lookAtDistance = eye_look_at.normVec(); + + left.setVec(skyward % eye_look_at); + up.setVec(eye_look_at % left); + + target_eye_rot = LLQuaternion(eye_look_at, left, up); + // convert target rotation to head-local coordinates + target_eye_rot *= ~mHeadJoint->getWorldRotation(); + // eliminate any Euler roll - we're lucky that roll is applied last. + F32 roll, pitch, yaw; + target_eye_rot.getEulerAngles(&roll, &pitch, &yaw); + target_eye_rot.setQuat(0.0f, pitch, yaw); + // constrain target orientation to be in front of avatar's face + target_eye_rot.constrain(EYE_ROT_LIMIT_ANGLE); + + // calculate vergence + F32 interocular_dist = (left_eye_state.getJoint()->getWorldPosition() - right_eye_state.getJoint()->getWorldPosition()).magVec(); + vergence = -atan2((interocular_dist / 2.f), lookAtDistance); + llclamp(vergence, -F_PI_BY_TWO, 0.f); + } + else + { + target_eye_rot = LLQuaternion::DEFAULT; + vergence = 0.f; + } + + //RN: subtract 4 degrees to account for foveal angular offset relative to pupil + vergence += 4.f * DEG_TO_RAD; + + // calculate eye jitter + LLQuaternion eye_jitter_rot; + + // vergence not too high... + if (vergence > -0.05f) + { + //...go ahead and jitter + eye_jitter_rot.setQuat(0.f, mEyeJitterPitch + mEyeLookAwayPitch, mEyeJitterYaw + mEyeLookAwayYaw); + } + else + { + //...or don't + eye_jitter_rot.loadIdentity(); + } + + // calculate vergence of eyes as an object gets closer to the avatar's head + LLQuaternion vergence_quat; + + if (has_eye_target) + { + vergence_quat.setQuat(vergence, LLVector3(0.f, 0.f, 1.f)); + } + else + { + vergence_quat.loadIdentity(); + } + + // calculate eye rotations + LLQuaternion left_eye_rot = target_eye_rot; + left_eye_rot = vergence_quat * eye_jitter_rot * left_eye_rot; + + LLQuaternion right_eye_rot = target_eye_rot; + vergence_quat.transQuat(); + right_eye_rot = vergence_quat * eye_jitter_rot * right_eye_rot; + + left_eye_state.setRotation( left_eye_rot ); + right_eye_state.setRotation( right_eye_rot ); +} + +//----------------------------------------------------------------------------- +// LLEyeMotion::onUpdate() +//----------------------------------------------------------------------------- +BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) +{ //calculate jitter if (mEyeJitterTimer.getElapsedTimeF32() > mEyeJitterTime) { @@ -426,83 +530,10 @@ BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) } } - BOOL has_eye_target = FALSE; LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); - if (targetPos) - { - LLVector3 skyward(0.f, 0.f, 1.f); - LLVector3 left; - LLVector3 up; - - eye_look_at = *targetPos; - has_eye_target = TRUE; - F32 lookAtDistance = eye_look_at.normVec(); - - left.setVec(skyward % eye_look_at); - up.setVec(eye_look_at % left); - - target_eye_rot = LLQuaternion(eye_look_at, left, up); - // convert target rotation to head-local coordinates - target_eye_rot *= ~mHeadJoint->getWorldRotation(); - // eliminate any Euler roll - we're lucky that roll is applied last. - F32 roll, pitch, yaw; - target_eye_rot.getEulerAngles(&roll, &pitch, &yaw); - target_eye_rot.setQuat(0.0f, pitch, yaw); - // constrain target orientation to be in front of avatar's face - target_eye_rot.constrain(EYE_ROT_LIMIT_ANGLE); - - // calculate vergence - F32 interocular_dist = (mLeftEyeState->getJoint()->getWorldPosition() - mRightEyeState->getJoint()->getWorldPosition()).magVec(); - vergence = -atan2((interocular_dist / 2.f), lookAtDistance); - llclamp(vergence, -F_PI_BY_TWO, 0.f); - } - else - { - target_eye_rot = LLQuaternion::DEFAULT; - vergence = 0.f; - } - - //RN: subtract 4 degrees to account for foveal angular offset relative to pupil - vergence += 4.f * DEG_TO_RAD; - - // calculate eye jitter - LLQuaternion eye_jitter_rot; - - // vergence not too high... - if (vergence > -0.05f) - { - //...go ahead and jitter - eye_jitter_rot.setQuat(0.f, mEyeJitterPitch + mEyeLookAwayPitch, mEyeJitterYaw + mEyeLookAwayYaw); - } - else - { - //...or don't - eye_jitter_rot.loadIdentity(); - } - - // calculate vergence of eyes as an object gets closer to the avatar's head - LLQuaternion vergence_quat; - - if (has_eye_target) - { - vergence_quat.setQuat(vergence, LLVector3(0.f, 0.f, 1.f)); - } - else - { - vergence_quat.loadIdentity(); - } - - // calculate eye rotations - LLQuaternion left_eye_rot = target_eye_rot; - left_eye_rot = vergence_quat * eye_jitter_rot * left_eye_rot; - - LLQuaternion right_eye_rot = target_eye_rot; - vergence_quat.transQuat(); - right_eye_rot = vergence_quat * eye_jitter_rot * right_eye_rot; - - mLeftEyeState->setRotation( left_eye_rot ); - mRightEyeState->setRotation( right_eye_rot ); + adjustEyeTarget(targetPos, *mLeftEyeState, *mRightEyeState); + adjustEyeTarget(targetPos, *mAltLeftEyeState, *mAltRightEyeState); return TRUE; } @@ -519,11 +550,23 @@ void LLEyeMotion::onDeactivate() joint->setRotation(LLQuaternion::DEFAULT); } + joint = mAltLeftEyeState->getJoint(); + if (joint) + { + joint->setRotation(LLQuaternion::DEFAULT); + } + joint = mRightEyeState->getJoint(); if (joint) { joint->setRotation(LLQuaternion::DEFAULT); } + + joint = mAltRightEyeState->getJoint(); + if (joint) + { + joint->setRotation(LLQuaternion::DEFAULT); + } } // End diff --git a/indra/llcharacter/llheadrotmotion.h b/indra/llcharacter/llheadrotmotion.h index 569dbef2dd7b7be73ec4f5a8570ac60782752f0f..53ae1813bc1bb5d6a50c991d91a808b5a3fc5665 100644 --- a/indra/llcharacter/llheadrotmotion.h +++ b/indra/llcharacter/llheadrotmotion.h @@ -176,6 +176,8 @@ class LLEyeMotion : // it will be deactivated virtual BOOL onActivate(); + void adjustEyeTarget(LLVector3* targetPos, LLJointState& left_eye_state, LLJointState& right_eye_state); + // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. @@ -193,6 +195,8 @@ class LLEyeMotion : LLJoint *mHeadJoint; LLPointer<LLJointState> mLeftEyeState; LLPointer<LLJointState> mRightEyeState; + LLPointer<LLJointState> mAltLeftEyeState; + LLPointer<LLJointState> mAltRightEyeState; LLFrameTimer mEyeJitterTimer; F32 mEyeJitterTime; diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 8fa08a2a6ce0ea7314e94973661c376164ec1eec..a3d5679f655a10eeab7395e9039ae386751fa195 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -32,6 +32,8 @@ #include "lljoint.h" #include "llmath.h" +#include "llcallstack.h" +#include <boost/algorithm/string.hpp> S32 LLJoint::sNumUpdates = 0; S32 LLJoint::sNumTouches = 0; @@ -42,7 +44,7 @@ bool attachment_map_iter_compare_key(const T& a, const T& b) return a.first < b.first; } -bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const +bool LLVector3OverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const { pos = LLVector3(0,0,0); mesh_id = LLUUID(); @@ -60,7 +62,7 @@ bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const return found; } -void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const +void LLVector3OverrideMap::showJointVector3Overrides( std::ostringstream& os ) const { map_type::const_iterator max_it = std::max_element(m_map.begin(), m_map.end(), @@ -73,23 +75,23 @@ void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const } } -U32 LLPosOverrideMap::count() const +U32 LLVector3OverrideMap::count() const { return m_map.size(); } -void LLPosOverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos) +void LLVector3OverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos) { m_map[mesh_id] = pos; } -bool LLPosOverrideMap::remove(const LLUUID& mesh_id) +bool LLVector3OverrideMap::remove(const LLUUID& mesh_id) { U32 remove_count = m_map.erase(mesh_id); return (remove_count > 0); } -void LLPosOverrideMap::clear() +void LLVector3OverrideMap::clear() { m_map.clear(); } @@ -108,6 +110,8 @@ void LLJoint::init() mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f)); mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY; mUpdateXform = TRUE; + mSupport = SUPPORT_BASE; + mEnd = LLVector3(0.0f, 0.0f, 0.0f); } LLJoint::LLJoint() : @@ -124,13 +128,12 @@ LLJoint::LLJoint(S32 joint_num) : touch(); } - //----------------------------------------------------------------------------- // LLJoint() // Class Constructor //----------------------------------------------------------------------------- LLJoint::LLJoint(const std::string &name, LLJoint *parent) : - mJointNum(0) + mJointNum(-2) { init(); mUpdateXform = FALSE; @@ -169,6 +172,27 @@ void LLJoint::setup(const std::string &name, LLJoint *parent) } } +//----------------------------------------------------------------------------- +// setSupport() +//----------------------------------------------------------------------------- +void LLJoint::setSupport(const std::string& support_name) +{ + if (support_name == "extended") + { + setSupport(SUPPORT_EXTENDED); + } + else if (support_name == "base") + { + setSupport(SUPPORT_BASE); + } + else + { + LL_WARNS() << "unknown support string " << support_name << LL_ENDL; + setSupport(SUPPORT_BASE); + } +} + + //----------------------------------------------------------------------------- // touch() // Sets all dirty flags for all children, recursively. @@ -194,6 +218,18 @@ void LLJoint::touch(U32 flags) } } +//----------------------------------------------------------------------------- +// setJointNum() +//----------------------------------------------------------------------------- +void LLJoint::setJointNum(S32 joint_num) +{ + mJointNum = joint_num; + if (mJointNum + 2 >= LL_CHARACTER_MAX_ANIMATED_JOINTS) + { + LL_INFOS() << "LL_CHARACTER_MAX_ANIMATED_JOINTS needs to be increased" << LL_ENDL; + LL_ERRS() << "joint_num " << joint_num << " + 2 is too large for " << LL_CHARACTER_MAX_ANIMATED_JOINTS << LL_ENDL; + } +} //----------------------------------------------------------------------------- // getRoot() //----------------------------------------------------------------------------- @@ -290,43 +326,119 @@ const LLVector3& LLJoint::getPosition() bool do_debug_joint(const std::string& name) { - return false; + if (std::find(LLJoint::s_debugJointNames.begin(), LLJoint::s_debugJointNames.end(),name) != LLJoint::s_debugJointNames.end()) + { + return true; + } + return false; } //-------------------------------------------------------------------- // setPosition() //-------------------------------------------------------------------- -void LLJoint::setPosition( const LLVector3& pos ) +void LLJoint::setPosition( const LLVector3& requested_pos, bool apply_attachment_overrides ) { - if (pos != getPosition()) + LLVector3 pos(requested_pos); + + LLVector3 active_override; + LLUUID mesh_id; + if (apply_attachment_overrides && m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override)) + { + if (pos != active_override && do_debug_joint(getName())) + { + LLScopedContextString str("setPosition"); + LL_DEBUGS("Avatar") << " joint " << getName() << " requested_pos " << requested_pos + << " overriden by attachment " << active_override << LL_ENDL; + } + pos = active_override; + } + if ((pos != getPosition()) && do_debug_joint(getName())) { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << " joint " << getName() << " set pos " << pos << LL_ENDL; - } + LLScopedContextString str("setPosition"); + LLCallStack cs; + LLContextStatus con_status; + LL_DEBUGS("Avatar") << " joint " << getName() << " set pos " << pos << LL_ENDL; + LL_DEBUGS("Avatar") << "CONTEXT:\n" << "====================\n" << con_status << "====================" << LL_ENDL; + LL_DEBUGS("Avatar") << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; } - mXform.setPosition(pos); - touch(MATRIX_DIRTY | POSITION_DIRTY); + if (pos != getPosition()) + { + mXform.setPosition(pos); + touch(MATRIX_DIRTY | POSITION_DIRTY); + } +} + +void LLJoint::setDefaultPosition( const LLVector3& pos ) +{ + mDefaultPosition = pos; +} + +const LLVector3& LLJoint::getDefaultPosition() const +{ + return mDefaultPosition; +} + +void LLJoint::setDefaultScale( const LLVector3& scale ) +{ + mDefaultScale = scale; +} + +const LLVector3& LLJoint::getDefaultScale() const +{ + return mDefaultScale; } void showJointPosOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info ) { std::ostringstream os; os << joint.m_posBeforeOverrides; - joint.m_attachmentOverrides.showJointPosOverrides(os); + joint.m_attachmentPosOverrides.showJointVector3Overrides(os); + LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL; +} + +void showJointScaleOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info ) +{ + std::ostringstream os; + os << joint.m_scaleBeforeOverrides; + joint.m_attachmentScaleOverrides.showJointVector3Overrides(os); LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL; } +bool LLJoint::aboveJointPosThreshold(const LLVector3& pos) const +{ + LLVector3 diff = pos - getDefaultPosition(); + const F32 max_joint_pos_offset = 0.0001f; // 0.1 mm + return diff.lengthSquared() > max_joint_pos_offset * max_joint_pos_offset; +} + +bool LLJoint::aboveJointScaleThreshold(const LLVector3& scale) const +{ + LLVector3 diff = scale - getDefaultScale(); + const F32 max_joint_scale_offset = 0.0001f; // 0.1 mm + return diff.lengthSquared() > max_joint_scale_offset * max_joint_scale_offset; +} + //-------------------------------------------------------------------- // addAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info ) +void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ) { + active_override_changed = false; if (mesh_id.isNull()) { return; } - if (!m_attachmentOverrides.count()) + // BENTO + // Not clear pelvis overrides are meaningful/useful. + //if (mName == "mPelvis") + //{ + // return; + //} + + LLVector3 before_pos; + LLUUID before_mesh_id; + bool has_active_override_before = hasAttachmentPosOverride( before_pos, before_mesh_id ); + if (!m_attachmentPosOverrides.count()) { if (do_debug_joint(getName())) { @@ -334,32 +446,50 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh } m_posBeforeOverrides = getPosition(); } - m_attachmentOverrides.add(mesh_id,pos); - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; - } - updatePos(av_info); + m_attachmentPosOverrides.add(mesh_id,pos); + LLVector3 after_pos; + LLUUID after_mesh_id; + hasAttachmentPosOverride(after_pos, after_mesh_id); + if (!has_active_override_before || (after_pos != before_pos)) + { + active_override_changed = true; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; + } + updatePos(av_info); + } } //-------------------------------------------------------------------- // removeAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info ) +void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ) { + active_override_changed = false; if (mesh_id.isNull()) { return; } - if (m_attachmentOverrides.remove(mesh_id)) + LLVector3 before_pos; + LLUUID before_mesh_id; + hasAttachmentPosOverride( before_pos, before_mesh_id ); + if (m_attachmentPosOverrides.remove(mesh_id)) { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() - << " removeAttachmentPosOverride for " << mesh_id << LL_ENDL; - showJointPosOverrides(*this, "remove", av_info); - } - updatePos(av_info); + LLVector3 after_pos; + LLUUID after_mesh_id; + bool has_active_override_after = hasAttachmentPosOverride(after_pos, after_mesh_id); + if (!has_active_override_after || (after_pos != before_pos)) + { + active_override_changed = true; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " removeAttachmentPosOverride for " << mesh_id << LL_ENDL; + showJointPosOverrides(*this, "remove", av_info); + } + updatePos(av_info); + } } } @@ -368,7 +498,7 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str //-------------------------------------------------------------------- bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const { - return m_attachmentOverrides.findActiveOverride(mesh_id,pos); + return m_attachmentPosOverrides.findActiveOverride(mesh_id,pos); } //-------------------------------------------------------------------- @@ -376,11 +506,81 @@ bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const //-------------------------------------------------------------------- void LLJoint::clearAttachmentPosOverrides() { - if (m_attachmentOverrides.count()) + if (m_attachmentPosOverrides.count()) { - m_attachmentOverrides.clear(); + m_attachmentPosOverrides.clear(); setPosition(m_posBeforeOverrides); - setId( LLUUID::null ); + } +} + +//-------------------------------------------------------------------- +// getAllAttachmentPosOverrides() +//-------------------------------------------------------------------- +void LLJoint::getAllAttachmentPosOverrides(S32& num_pos_overrides, + std::set<LLVector3>& distinct_pos_overrides) +{ + num_pos_overrides = m_attachmentPosOverrides.count(); + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); + for (; it != m_attachmentPosOverrides.getMap().end(); ++it) + { + distinct_pos_overrides.insert(it->second); + } +} + +//-------------------------------------------------------------------- +// getAllAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::getAllAttachmentScaleOverrides(S32& num_scale_overrides, + std::set<LLVector3>& distinct_scale_overrides) +{ + num_scale_overrides = m_attachmentScaleOverrides.count(); + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); + for (; it != m_attachmentScaleOverrides.getMap().end(); ++it) + { + distinct_scale_overrides.insert(it->second); + } +} + +//-------------------------------------------------------------------- +// showAttachmentPosOverrides() +//-------------------------------------------------------------------- +void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const +{ + LLVector3 active_override; + bool has_active_override; + LLUUID mesh_id; + has_active_override = m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override); + U32 count = m_attachmentPosOverrides.count(); + if (count==1) + { + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); + std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : ""; + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " has single attachment pos override " << highlight << "" << it->second << " default " << mDefaultPosition << LL_ENDL; + } + else if (count>1) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment pos overrides" << LL_ENDL; + std::set<LLVector3> distinct_offsets; + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); + for (; it != m_attachmentPosOverrides.getMap().end(); ++it) + { + distinct_offsets.insert(it->second); + } + if (distinct_offsets.size()>1) + { + LL_DEBUGS("Avatar") << "CONFLICTS, " << distinct_offsets.size() << " different values" << LL_ENDL; + } + else + { + LL_DEBUGS("Avatar") << "no conflicts" << LL_ENDL; + } + std::set<LLVector3>::iterator dit = distinct_offsets.begin(); + for ( ; dit != distinct_offsets.end(); ++dit) + { + std::string highlight = (has_active_override && *dit == active_override) ? "*" : ""; + LL_DEBUGS("Avatar") << " POS " << highlight << "" << (*dit) << " default " << mDefaultPosition << LL_ENDL; + } } } @@ -391,19 +591,177 @@ void LLJoint::updatePos(const std::string& av_info) { LLVector3 pos, found_pos; LLUUID mesh_id; - if (m_attachmentOverrides.findActiveOverride(mesh_id,found_pos)) + if (m_attachmentPosOverrides.findActiveOverride(mesh_id,found_pos)) { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentPosOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL; + } pos = found_pos; } else { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL; + } pos = m_posBeforeOverrides; } setPosition(pos); } +//-------------------------------------------------------------------- +// updateScale() +//-------------------------------------------------------------------- +void LLJoint::updateScale(const std::string& av_info) +{ + LLVector3 scale, found_scale; + LLUUID mesh_id; + if (m_attachmentScaleOverrides.findActiveOverride(mesh_id,found_scale)) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner of " << m_attachmentScaleOverrides.count() << " is mesh " << mesh_id << " scale " << found_scale << LL_ENDL; + } + scale = found_scale; + } + else + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner is scaleBeforeOverrides " << m_scaleBeforeOverrides << LL_ENDL; + } + scale = m_scaleBeforeOverrides; + } + setScale(scale); +} + +//-------------------------------------------------------------------- +// addAttachmentScaleOverride() +//-------------------------------------------------------------------- +void LLJoint::addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info ) +{ + if (mesh_id.isNull()) + { + return; + } + if (!m_attachmentScaleOverrides.count()) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_scaleBeforeOverrides " << getScale() << LL_ENDL; + } + m_scaleBeforeOverrides = getScale(); + } + m_attachmentScaleOverrides.add(mesh_id,scale); + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentScaleOverride for mesh " << mesh_id << " scale " << scale << LL_ENDL; + } + updateScale(av_info); +} + +//-------------------------------------------------------------------- +// removeAttachmentScaleOverride() +//-------------------------------------------------------------------- +void LLJoint::removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info ) +{ + if (mesh_id.isNull()) + { + return; + } + if (m_attachmentScaleOverrides.remove(mesh_id)) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " removeAttachmentScaleOverride for " << mesh_id << LL_ENDL; + showJointScaleOverrides(*this, "remove", av_info); + } + updateScale(av_info); + } +} + +//-------------------------------------------------------------------- + // hasAttachmentScaleOverride() + //-------------------------------------------------------------------- +bool LLJoint::hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const +{ + return m_attachmentScaleOverrides.findActiveOverride(mesh_id,scale); +} + +//-------------------------------------------------------------------- +// clearAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::clearAttachmentScaleOverrides() +{ + if (m_attachmentScaleOverrides.count()) + { + m_attachmentScaleOverrides.clear(); + setScale(m_scaleBeforeOverrides); + } +} + +//-------------------------------------------------------------------- +// showAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::showAttachmentScaleOverrides(const std::string& av_info) const +{ + LLVector3 active_override; + bool has_active_override; + LLUUID mesh_id; + has_active_override = m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override); + U32 count = m_attachmentScaleOverrides.count(); + if (count==1) + { + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); + std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : ""; + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " has single attachment scale override " << highlight << "" << it->second << " default " << mDefaultScale << LL_ENDL; + } + else if (count>1) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment scale overrides" << LL_ENDL; + std::set<LLVector3> distinct_offsets; + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); + for (; it != m_attachmentScaleOverrides.getMap().end(); ++it) + { + distinct_offsets.insert(it->second); + } + if (distinct_offsets.size()>1) + { + LL_DEBUGS("Avatar") << "CONFLICTS, " << distinct_offsets.size() << " different values" << LL_ENDL; + } + else + { + LL_DEBUGS("Avatar") << "no conflicts" << LL_ENDL; + } + std::set<LLVector3>::iterator dit = distinct_offsets.begin(); + for ( ; dit != distinct_offsets.end(); ++dit) + { + std::string highlight = (has_active_override && *dit == active_override) ? "*" : ""; + LL_DEBUGS("Avatar") << " POS " << highlight << "" << (*dit) << " default " << mDefaultScale << LL_ENDL; + } + } +} + +// init static +LLJoint::debug_joint_name_t LLJoint::s_debugJointNames = debug_joint_name_t(); + +//-------------------------------------------------------------------- +// setDebugJointNames +//-------------------------------------------------------------------- +void LLJoint::setDebugJointNames(const debug_joint_name_t& names) +{ + s_debugJointNames = names; +} +void LLJoint::setDebugJointNames(const std::string& names_string) +{ + debug_joint_name_t names; + boost::split(names, names_string, boost::is_any_of(" :,")); + setDebugJointNames(names); +} + //-------------------------------------------------------------------- // getWorldPosition() //-------------------------------------------------------------------- @@ -529,13 +887,32 @@ const LLVector3& LLJoint::getScale() //-------------------------------------------------------------------- // setScale() //-------------------------------------------------------------------- -void LLJoint::setScale( const LLVector3& scale ) +void LLJoint::setScale( const LLVector3& requested_scale, bool apply_attachment_overrides ) { -// if (mXform.getScale() != scale) + LLVector3 scale(requested_scale); + LLUUID mesh_id; + LLVector3 active_override; + if (apply_attachment_overrides && m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override)) + { + if (scale != active_override && do_debug_joint(getName())) + { + LLScopedContextString str("setScale"); + LL_DEBUGS("Avatar") << " joint " << getName() << " requested_scale " << requested_scale + << " overriden by attachment " << active_override << LL_ENDL; + } + scale = active_override; + } + if ((mXform.getScale() != scale) && do_debug_joint(getName())) { - mXform.setScale(scale); - touch(); + LLScopedContextString str("setScale"); + LLCallStack cs; + LLContextStatus con_status; + LL_DEBUGS("Avatar") << " joint " << getName() << " set scale " << scale << LL_ENDL; + LL_DEBUGS("Avatar") << "CONTEXT:\n" << "====================\n" << con_status << LL_ENDL; + LL_DEBUGS("Avatar") << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; } + mXform.setScale(scale); + touch(); } diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 2abe1d6db1510cb6da94adf987e473a271c6da73..0c8fbfebb0e0c737e3012d1439ee683eff38812d 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -40,24 +40,33 @@ #include "xform.h" const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15; -const U32 LL_CHARACTER_MAX_JOINTS = 32; // must be divisible by 4! -const U32 LL_HAND_JOINT_NUM = 31; -const U32 LL_FACE_JOINT_NUM = 30; +// Need to set this to count of animate-able joints, +// currently = #bones + #collision_volumes + #attachments + 2, +// rounded to next multiple of 4. +const U32 LL_CHARACTER_MAX_ANIMATED_JOINTS = 216; // must be divisible by 4! +const U32 LL_MAX_JOINTS_PER_MESH_OBJECT = 110; + +// These should be higher than the joint_num of any +// other joint, to avoid conflicts in updateMotionsByType() +const U32 LL_HAND_JOINT_NUM = (LL_CHARACTER_MAX_ANIMATED_JOINTS-1); +const U32 LL_FACE_JOINT_NUM = (LL_CHARACTER_MAX_ANIMATED_JOINTS-2); const S32 LL_CHARACTER_MAX_PRIORITY = 7; const F32 LL_MAX_PELVIS_OFFSET = 5.f; -class LLPosOverrideMap +class LLVector3OverrideMap { public: - LLPosOverrideMap() {} + LLVector3OverrideMap() {} bool findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const; - void showJointPosOverrides(std::ostringstream& os) const; + void showJointVector3Overrides(std::ostringstream& os) const; U32 count() const; void add(const LLUUID& mesh_id, const LLVector3& pos); bool remove(const LLUUID& mesh_id); void clear(); -private: + typedef std::map<LLUUID,LLVector3> map_type; + const map_type& getMap() const { return m_map; } +private: map_type m_map; }; @@ -86,17 +95,26 @@ class LLJoint POSITION_DIRTY = 0x1 << 2, ALL_DIRTY = 0x7 }; +public: + enum SupportCategory + { + SUPPORT_BASE, + SUPPORT_EXTENDED + }; protected: std::string mName; + SupportCategory mSupport; + // parent joint LLJoint *mParent; // explicit transformation members LLXformMatrix mXform; - LLUUID mId; - + LLVector3 mDefaultPosition; + LLVector3 mDefaultScale; + public: U32 mDirtyFlags; BOOL mUpdateXform; @@ -104,6 +122,10 @@ class LLJoint // describes the skin binding pose LLVector3 mSkinOffset; + // Endpoint of the bone, if applicable. This is only relevant for + // external programs like Blender, and for diagnostic display. + LLVector3 mEnd; + S32 mJointNum; // child joints @@ -113,15 +135,40 @@ class LLJoint // debug statics static S32 sNumTouches; static S32 sNumUpdates; + typedef std::set<std::string> debug_joint_name_t; + static debug_joint_name_t s_debugJointNames; + static void setDebugJointNames(const debug_joint_name_t& names); + static void setDebugJointNames(const std::string& names_string); - LLPosOverrideMap m_attachmentOverrides; + // Position overrides + LLVector3OverrideMap m_attachmentPosOverrides; LLVector3 m_posBeforeOverrides; + // Scale overrides + LLVector3OverrideMap m_attachmentScaleOverrides; + LLVector3 m_scaleBeforeOverrides; + void updatePos(const std::string& av_info); + void updateScale(const std::string& av_info); public: LLJoint(); - LLJoint(S32 joint_num); + + // Note: these joint_num constructors are a bad idea because there + // are only a couple of places in the code where it is useful to + // have a joint num for a joint (for joints that are used in + // animations), and including them as part of the constructor then + // forces us to maintain an alternate path through the entire + // large-ish class hierarchy of joint types. The only reason they + // are still here now is to avoid breaking the baking service + // (appearanceutility) builds; these constructors are not used in + // the viewer. Once the appearance utility is updated to remove + // these joint num references, which it shouldn't ever need, from + // its own classes, we can also remove all the joint_num + // constructors from LLJoint, LLViewerJoint, LLAvatarJoint, and + // createAvatarJoint. + LLJoint(S32 joint_num); + // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform* LLJoint( const std::string &name, LLJoint *parent=NULL ); virtual ~LLJoint(); @@ -139,6 +186,19 @@ class LLJoint const std::string& getName() const { return mName; } void setName( const std::string &name ) { mName = name; } + // joint num + S32 getJointNum() const { return mJointNum; } + void setJointNum(S32 joint_num); + + // get/set support + SupportCategory getSupport() const { return mSupport; } + void setSupport( const SupportCategory& support) { mSupport = support; } + void setSupport( const std::string& support_string); + + // get/set end point + void setEnd( const LLVector3& end) { mEnd = end; } + const LLVector3& getEnd() const { return mEnd; } + // getParent LLJoint *getParent() { return mParent; } @@ -155,10 +215,16 @@ class LLJoint // get/set local position const LLVector3& getPosition(); - void setPosition( const LLVector3& pos ); - + void setPosition( const LLVector3& pos, bool apply_attachment_overrides = false ); + + // Tracks the default position defined by the skeleton void setDefaultPosition( const LLVector3& pos ); - + const LLVector3& getDefaultPosition() const; + + // Tracks the default scale defined by the skeleton + void setDefaultScale( const LLVector3& scale ); + const LLVector3& getDefaultScale() const; + // get/set world position LLVector3 getWorldPosition(); LLVector3 getLastWorldPosition(); @@ -175,7 +241,7 @@ class LLJoint // get/set local scale const LLVector3& getScale(); - void setScale( const LLVector3& scale ); + void setScale( const LLVector3& scale, bool apply_attachment_overrides = false ); // get/set world matrix const LLMatrix4 &getWorldMatrix(); @@ -198,17 +264,26 @@ class LLJoint virtual BOOL isAnimatable() const { return TRUE; } - S32 getJointNum() const { return mJointNum; } - - void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info ); - void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info ); + void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ); + void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ); bool hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const; void clearAttachmentPosOverrides(); - - //Accessor for the joint id - LLUUID getId( void ) { return mId; } - //Setter for the joints id - void setId( const LLUUID& id ) { mId = id;} + void showAttachmentPosOverrides(const std::string& av_info) const; + + void addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info ); + void removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info ); + bool hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const; + void clearAttachmentScaleOverrides(); + void showAttachmentScaleOverrides(const std::string& av_info) const; + + void getAllAttachmentPosOverrides(S32& num_pos_overrides, + std::set<LLVector3>& distinct_pos_overrides); + void getAllAttachmentScaleOverrides(S32& num_scale_overrides, + std::set<LLVector3>& distinct_scale_overrides); + + // These are used in checks of whether a pos/scale override is considered significant. + bool aboveJointPosThreshold(const LLVector3& pos) const; + bool aboveJointScaleThreshold(const LLVector3& scale) const; }; #endif // LL_LLJOINT_H diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index cd201a65b4ef6b22a614d87759c0f7276e3f7ebe..89f34a92c84f4a362793f09165bc9d01161cb0e2 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -498,6 +498,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact // request asset mAssetStatus = ASSET_FETCHED; + LL_DEBUGS("Animation") << "Requesting data fetch for: " << mID << LL_ENDL; character_id = new LLUUID(mCharacter->getID()); gAssetStorage->getAssetData(mID, LLAssetType::AT_ANIMATION, @@ -1380,7 +1381,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) LL_WARNS() << "no joints in animation" << LL_ENDL; return FALSE; } - else if (num_motions > LL_CHARACTER_MAX_JOINTS) + else if (num_motions > LL_CHARACTER_MAX_ANIMATED_JOINTS) { LL_WARNS() << "too many joints in animation" << LL_ENDL; return FALSE; @@ -1419,7 +1420,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) LLJoint *joint = mCharacter->getJoint( joint_name ); if (joint) { + S32 joint_num = joint->getJointNum(); // LL_INFOS() << " joint: " << joint_name << LL_ENDL; + if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0)) + { + LL_WARNS() << "Joint will be omitted from animation: joint_num " << joint_num << " is outside of legal range [0-" + << LL_CHARACTER_MAX_ANIMATED_JOINTS << ") for joint " << joint->getName() << LL_ENDL; + joint = NULL; + } } else { @@ -1603,6 +1611,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (old_version) { success = dp.unpackVector3(pos_key.mPosition, "pos"); + + //MAINT-6162 + pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + pos_key.mPosition.mV[VY] = llclamp( pos_key.mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + pos_key.mPosition.mV[VZ] = llclamp( pos_key.mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + } else { @@ -1868,6 +1882,8 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const { BOOL success = TRUE; + LL_DEBUGS("BVH") << "serializing" << LL_ENDL; + success &= dp.packU16(KEYFRAME_MOTION_VERSION, "version"); success &= dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); success &= dp.packS32(mJointMotionList->mBasePriority, "base_priority"); @@ -1881,6 +1897,19 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packU32(mJointMotionList->mHandPose, "hand_pose"); success &= dp.packU32(mJointMotionList->getNumJointMotions(), "num_joints"); + LL_DEBUGS("BVH") << "version " << KEYFRAME_MOTION_VERSION << LL_ENDL; + LL_DEBUGS("BVH") << "sub_version " << KEYFRAME_MOTION_SUBVERSION << LL_ENDL; + LL_DEBUGS("BVH") << "base_priority " << mJointMotionList->mBasePriority << LL_ENDL; + LL_DEBUGS("BVH") << "duration " << mJointMotionList->mDuration << LL_ENDL; + LL_DEBUGS("BVH") << "emote_name " << mJointMotionList->mEmoteName << LL_ENDL; + LL_DEBUGS("BVH") << "loop_in_point " << mJointMotionList->mLoopInPoint << LL_ENDL; + LL_DEBUGS("BVH") << "loop_out_point " << mJointMotionList->mLoopOutPoint << LL_ENDL; + LL_DEBUGS("BVH") << "loop " << mJointMotionList->mLoop << LL_ENDL; + LL_DEBUGS("BVH") << "ease_in_duration " << mJointMotionList->mEaseInDuration << LL_ENDL; + LL_DEBUGS("BVH") << "ease_out_duration " << mJointMotionList->mEaseOutDuration << LL_ENDL; + LL_DEBUGS("BVH") << "hand_pose " << mJointMotionList->mHandPose << LL_ENDL; + LL_DEBUGS("BVH") << "num_joints " << mJointMotionList->getNumJointMotions() << LL_ENDL; + for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) { JointMotion* joint_motionp = mJointMotionList->getJointMotion(i); @@ -1888,6 +1917,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packS32(joint_motionp->mPriority, "joint_priority"); success &= dp.packS32(joint_motionp->mRotationCurve.mNumKeys, "num_rot_keys"); + LL_DEBUGS("BVH") << "Joint " << joint_motionp->mJointName << LL_ENDL; for (RotationCurve::key_map_t::iterator iter = joint_motionp->mRotationCurve.mKeys.begin(); iter != joint_motionp->mRotationCurve.mKeys.end(); ++iter) { @@ -1905,6 +1935,8 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packU16(x, "rot_angle_x"); success &= dp.packU16(y, "rot_angle_y"); success &= dp.packU16(z, "rot_angle_z"); + + LL_DEBUGS("BVH") << " rot: t " << rot_key.mTime << " angles " << rot_angles.mV[VX] <<","<< rot_angles.mV[VY] <<","<< rot_angles.mV[VZ] << LL_ENDL; } success &= dp.packS32(joint_motionp->mPositionCurve.mNumKeys, "num_pos_keys"); @@ -1923,37 +1955,54 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packU16(x, "pos_x"); success &= dp.packU16(y, "pos_y"); success &= dp.packU16(z, "pos_z"); + + LL_DEBUGS("BVH") << " pos: t " << pos_key.mTime << " pos " << pos_key.mPosition.mV[VX] <<","<< pos_key.mPosition.mV[VY] <<","<< pos_key.mPosition.mV[VZ] << LL_ENDL; } } success &= dp.packS32(mJointMotionList->mConstraints.size(), "num_constraints"); + LL_DEBUGS("BVH") << "num_constraints " << mJointMotionList->mConstraints.size() << LL_ENDL; for (JointMotionList::constraint_list_t::const_iterator iter = mJointMotionList->mConstraints.begin(); iter != mJointMotionList->mConstraints.end(); ++iter) { JointConstraintSharedData* shared_constraintp = *iter; success &= dp.packU8(shared_constraintp->mChainLength, "chain_length"); success &= dp.packU8(shared_constraintp->mConstraintType, "constraint_type"); - char volume_name[16]; /* Flawfinder: ignore */ - snprintf(volume_name, sizeof(volume_name), "%s", /* Flawfinder: ignore */ + char source_volume[16]; /* Flawfinder: ignore */ + snprintf(source_volume, sizeof(source_volume), "%s", /* Flawfinder: ignore */ mCharacter->findCollisionVolume(shared_constraintp->mSourceConstraintVolume)->getName().c_str()); - success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "source_volume"); + + success &= dp.packBinaryDataFixed((U8*)source_volume, 16, "source_volume"); success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset"); + char target_volume[16]; /* Flawfinder: ignore */ if (shared_constraintp->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) { - snprintf(volume_name,sizeof(volume_name), "%s", "GROUND"); /* Flawfinder: ignore */ + snprintf(target_volume,sizeof(target_volume), "%s", "GROUND"); /* Flawfinder: ignore */ } else { - snprintf(volume_name, sizeof(volume_name),"%s", /* Flawfinder: ignore */ + snprintf(target_volume, sizeof(target_volume),"%s", /* Flawfinder: ignore */ mCharacter->findCollisionVolume(shared_constraintp->mTargetConstraintVolume)->getName().c_str()); } - success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "target_volume"); + success &= dp.packBinaryDataFixed((U8*)target_volume, 16, "target_volume"); success &= dp.packVector3(shared_constraintp->mTargetConstraintOffset, "target_offset"); success &= dp.packVector3(shared_constraintp->mTargetConstraintDir, "target_dir"); success &= dp.packF32(shared_constraintp->mEaseInStartTime, "ease_in_start"); success &= dp.packF32(shared_constraintp->mEaseInStopTime, "ease_in_stop"); success &= dp.packF32(shared_constraintp->mEaseOutStartTime, "ease_out_start"); success &= dp.packF32(shared_constraintp->mEaseOutStopTime, "ease_out_stop"); + + LL_DEBUGS("BVH") << " chain_length " << shared_constraintp->mChainLength << LL_ENDL; + LL_DEBUGS("BVH") << " constraint_type " << (S32)shared_constraintp->mConstraintType << LL_ENDL; + LL_DEBUGS("BVH") << " source_volume " << source_volume << LL_ENDL; + LL_DEBUGS("BVH") << " source_offset " << shared_constraintp->mSourceConstraintOffset << LL_ENDL; + LL_DEBUGS("BVH") << " target_volume " << target_volume << LL_ENDL; + LL_DEBUGS("BVH") << " target_offset " << shared_constraintp->mTargetConstraintOffset << LL_ENDL; + LL_DEBUGS("BVH") << " target_dir " << shared_constraintp->mTargetConstraintDir << LL_ENDL; + LL_DEBUGS("BVH") << " ease_in_start " << shared_constraintp->mEaseInStartTime << LL_ENDL; + LL_DEBUGS("BVH") << " ease_in_stop " << shared_constraintp->mEaseInStopTime << LL_ENDL; + LL_DEBUGS("BVH") << " ease_out_start " << shared_constraintp->mEaseOutStartTime << LL_ENDL; + LL_DEBUGS("BVH") << " ease_out_stop " << shared_constraintp->mEaseOutStopTime << LL_ENDL; } return success; @@ -1971,6 +2020,51 @@ U32 LLKeyframeMotion::getFileSize() return dp.getCurrentSize(); } +//----------------------------------------------------------------------------- +// dumpToFile() +//----------------------------------------------------------------------------- +void LLKeyframeMotion::dumpToFile(const std::string& name) +{ + if (isLoaded()) + { + std::string outfile_base; + if (!name.empty()) + { + outfile_base = name; + } + else if (!getName().empty()) + { + outfile_base = getName(); + } + else + { + const LLUUID& id = getID(); + outfile_base = id.asString(); + } + std::string outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base + ".anim"); + if (LLFile::isfile(outfilename)) + { + return; + } + + S32 file_size = getFileSize(); + U8* buffer = new U8[file_size]; + + LL_DEBUGS("BVH") << "Dumping " << outfilename << LL_ENDL; + LLDataPackerBinaryBuffer dp(buffer, file_size); + if (serialize(dp)) + { + LLAPRFile outfile; + outfile.open(outfilename, LL_APR_WPB); + if (outfile.getFileHandle()) + { + outfile.write(buffer, file_size); + } + } + delete [] buffer; + } +} + //----------------------------------------------------------------------------- // getPelvisBBox() //----------------------------------------------------------------------------- @@ -2149,7 +2243,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, LLCharacter* character = *char_iter; // look for an existing instance of this motion - LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->findMotion(asset_uuid); + LLKeyframeMotion* motionp = dynamic_cast<LLKeyframeMotion*> (character->findMotion(asset_uuid)); if (motionp) { if (0 == status) @@ -2164,8 +2258,8 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, U8* buffer = new U8[size]; file.read((U8*)buffer, size); /*Flawfinder: ignore*/ - - LL_DEBUGS() << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL; + + LL_DEBUGS("Animation") << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL; LLDataPackerBinaryBuffer dp(buffer, size); if (motionp->deserialize(dp)) diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index b1422b2b903c742a0d4e13d1fd816666f0a3e9e1..f1fa56d731de6dcb821619095919902a50774b55 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -153,6 +153,7 @@ class LLKeyframeMotion : BOOL serialize(LLDataPacker& dp) const; BOOL deserialize(LLDataPacker& dp); BOOL isLoaded() { return mJointMotionList != NULL; } + void dumpToFile(const std::string& name); // setters for modifying a keyframe animation diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp index fdeddf55e16538326b600342b7fa0b4e55d55b07..02c1d3cdbd75947c35fd4b0d2c13bbb0903cb489 100644 --- a/indra/llcharacter/llkeyframestandmotion.cpp +++ b/indra/llcharacter/llkeyframestandmotion.cpp @@ -201,10 +201,12 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask) //------------------------------------------------------------------------- // propagate joint positions to internal versions //------------------------------------------------------------------------- + // SL-315 mPelvisJoint.setPosition( root_world_pos + mPelvisState->getPosition() ); + // SL-315 mHipLeftJoint.setPosition( mHipLeftState->getJoint()->getPosition() ); mKneeLeftJoint.setPosition( mKneeLeftState->getJoint()->getPosition() ); mAnkleLeftJoint.setPosition( mAnkleLeftState->getJoint()->getPosition() ); @@ -213,6 +215,7 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask) mKneeLeftJoint.setScale( mKneeLeftState->getJoint()->getScale() ); mAnkleLeftJoint.setScale( mAnkleLeftState->getJoint()->getScale() ); + // SL-315 mHipRightJoint.setPosition( mHipRightState->getJoint()->getPosition() ); mKneeRightJoint.setPosition( mKneeRightState->getJoint()->getPosition() ); mAnkleRightJoint.setPosition( mAnkleRightState->getJoint()->getPosition() ); @@ -265,6 +268,7 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask) mCharacter->getGround( mAnkleLeftJoint.getWorldPosition(), mPositionLeft, mNormalLeft); mCharacter->getGround( mAnkleRightJoint.getWorldPosition(), mPositionRight, mNormalRight); + // SL-315 mTargetLeft.setPosition( mPositionLeft ); mTargetRight.setPosition( mPositionRight ); } diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp index 4803f855de98853a96a0f5364ae98b6f4d47868d..697efc8157fde7bb4cd8132043a7fad589300516 100644 --- a/indra/llcharacter/llmotion.cpp +++ b/indra/llcharacter/llmotion.cpp @@ -55,7 +55,7 @@ LLMotion::LLMotion( const LLUUID &id ) : mDeactivateCallbackUserData(NULL) { for (S32 i=0; i<3; ++i) - memset(&mJointSignature[i][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); + memset(&mJointSignature[i][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); } //----------------------------------------------------------------------------- @@ -111,9 +111,15 @@ void LLMotion::addJointState(const LLPointer<LLJointState>& jointState) U32 usage = jointState->getUsage(); // for now, usage is everything - mJointSignature[0][jointState->getJoint()->getJointNum()] = (usage & LLJointState::POS) ? (0xff >> (7 - priority)) : 0; - mJointSignature[1][jointState->getJoint()->getJointNum()] = (usage & LLJointState::ROT) ? (0xff >> (7 - priority)) : 0; - mJointSignature[2][jointState->getJoint()->getJointNum()] = (usage & LLJointState::SCALE) ? (0xff >> (7 - priority)) : 0; + S32 joint_num = jointState->getJoint()->getJointNum(); + if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0)) + { + LL_WARNS() << "joint_num " << joint_num << " is outside of legal range [0-" << LL_CHARACTER_MAX_ANIMATED_JOINTS << ") for joint " << jointState->getJoint()->getName() << LL_ENDL; + return; + } + mJointSignature[0][joint_num] = (usage & LLJointState::POS) ? (0xff >> (7 - priority)) : 0; + mJointSignature[1][joint_num] = (usage & LLJointState::ROT) ? (0xff >> (7 - priority)) : 0; + mJointSignature[2][joint_num] = (usage & LLJointState::SCALE) ? (0xff >> (7 - priority)) : 0; } void LLMotion::setDeactivateCallback( void (*cb)(void *), void* userdata ) diff --git a/indra/llcharacter/llmotion.h b/indra/llcharacter/llmotion.h index 5e37f094b8967ec53699ccfae4c797954a039ebf..2dfc3afc7f0964ba71fa7defcb69db4e3272573f 100644 --- a/indra/llcharacter/llmotion.h +++ b/indra/llcharacter/llmotion.h @@ -181,7 +181,7 @@ class LLMotion F32 mSendStopTimestamp; // time when simulator should be told to stop this motion F32 mResidualWeight; // blend weight at beginning of stop motion phase F32 mFadeWeight; // for fading in and out based on LOD - U8 mJointSignature[3][LL_CHARACTER_MAX_JOINTS]; // signature of which joints are animated at what priority + U8 mJointSignature[3][LL_CHARACTER_MAX_ANIMATED_JOINTS]; // signature of which joints are animated at what priority void (*mDeactivateCallback)(void* data); void* mDeactivateCallbackUserData; }; diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index e02b139608fc6cb2abd04b86dff83b645591cce8..d8185aa693e65ce3a0b993d55dda45ae32407f3f 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -37,7 +37,8 @@ #include "llanimationstates.h" #include "llstl.h" -const S32 NUM_JOINT_SIGNATURE_STRIDES = LL_CHARACTER_MAX_JOINTS / 4; +// This is why LL_CHARACTER_MAX_ANIMATED_JOINTS needs to be a multiple of 4. +const S32 NUM_JOINT_SIGNATURE_STRIDES = LL_CHARACTER_MAX_ANIMATED_JOINTS / 4; const U32 MAX_MOTION_INSTANCES = 32; //----------------------------------------------------------------------------- @@ -488,8 +489,8 @@ void LLMotionController::updateAdditiveMotions() //----------------------------------------------------------------------------- void LLMotionController::resetJointSignatures() { - memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); - memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); + memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); + memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); } //----------------------------------------------------------------------------- @@ -553,9 +554,9 @@ static LLTrace::BlockTimerStatHandle FTM_MOTION_ON_UPDATE("Motion onUpdate"); void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type) { BOOL update_result = TRUE; - U8 last_joint_signature[LL_CHARACTER_MAX_JOINTS]; + U8 last_joint_signature[LL_CHARACTER_MAX_ANIMATED_JOINTS]; - memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); + memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); // iterate through active motions in chronological order for (motion_list_t::iterator iter = mActiveMotions.begin(); @@ -576,7 +577,6 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty } else { - // NUM_JOINT_SIGNATURE_STRIDES should be multiple of 4 for (S32 i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++) { U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]); diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index 2bd5271c4f73a0775985fa7f8eab83b8c3f7dfd7..72de3316947f1ce13fcca68848e087bf30e95e2d 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -223,7 +223,7 @@ class LLMotionController S32 mTimeStepCount; F32 mLastInterp; - U8 mJointSignature[2][LL_CHARACTER_MAX_JOINTS]; + U8 mJointSignature[2][LL_CHARACTER_MAX_ANIMATED_JOINTS]; }; //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp index b1a7ebb159612bdbde8e68b3178c6c8d2f62d383..fc95fafd61490f81a3b8494afdc4bc5ce24a2ea8 100644 --- a/indra/llcharacter/llpose.cpp +++ b/indra/llcharacter/llpose.cpp @@ -386,6 +386,7 @@ void LLJointStateBlender::blendJointStates(BOOL apply_now) } // apply transforms + // SL-315 target_joint->setPosition(blended_pos + added_pos); target_joint->setScale(blended_scale + added_scale); target_joint->setRotation(added_rot * blended_rot); @@ -417,6 +418,7 @@ void LLJointStateBlender::interpolate(F32 u) return; } + // SL-315 target_joint->setPosition(lerp(target_joint->getPosition(), mJointCache.getPosition(), u)); target_joint->setScale(lerp(target_joint->getScale(), mJointCache.getScale(), u)); target_joint->setRotation(nlerp(u, target_joint->getRotation(), mJointCache.getRotation())); @@ -444,6 +446,7 @@ void LLJointStateBlender::resetCachedJoint() return; } LLJoint* source_joint = mJointStates[0]->getJoint(); + // SL-315 mJointCache.setPosition(source_joint->getPosition()); mJointCache.setScale(source_joint->getScale()); mJointCache.setRotation(source_joint->getRotation()); diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h index c6b97d7e8b4f18f0a0fddc2eb80ef09c6bf59c56..0ad063fd1e113109e612ddfd5064dced4a1caf53 100644 --- a/indra/llcharacter/llvisualparam.h +++ b/indra/llcharacter/llvisualparam.h @@ -150,6 +150,7 @@ class LLVisualParam F32 getWeight() const { return mIsAnimating ? mTargetWeight : mCurWeight; } F32 getCurrentWeight() const { return mCurWeight; } F32 getLastWeight() const { return mLastWeight; } + void setLastWeight(F32 val) { mLastWeight = val; } BOOL isAnimating() const { return mIsAnimating; } BOOL isTweakable() const { return (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) || (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT); } diff --git a/indra/llcharacter/tests/lljoint_test.cpp b/indra/llcharacter/tests/lljoint_test.cpp index da151808f21c660f6e57c922d848af356f4889c8..617f31b0e46e5877198f25ce8263606ac93a9422 100644 --- a/indra/llcharacter/tests/lljoint_test.cpp +++ b/indra/llcharacter/tests/lljoint_test.cpp @@ -88,6 +88,7 @@ namespace tut { LLJoint lljoint; LLVector3 vec3(2.3f,30.f,10.f); + // SL-315 lljoint.setPosition(vec3); LLVector3 pos = lljoint.getPosition(); ensure("setPosition()/getPosition() failed ", (vec3 == pos)); @@ -98,6 +99,7 @@ namespace tut { LLJoint lljoint; LLVector3 vec3(2.3f,30.f,10.f); + // SL-315 lljoint.setWorldPosition(vec3); LLVector3 pos = lljoint.getWorldPosition(); ensure("1:setWorldPosition()/getWorldPosition() failed ", (vec3 == pos)); diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 907dbab8f8a1ba1b3f5b07a3fa2f7fe7176911c7..16b42dad3818bc0c1fd4e3a2270d63e61357192b 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -10,7 +10,6 @@ include(Boost) include(LLSharedLibs) include(JsonCpp) include(GoogleBreakpad) -include(GooglePerfTools) include(Copy3rdPartyLibs) include(ZLIB) include(URIPARSER) @@ -40,8 +39,11 @@ set(llcommon_SOURCE_FILES llbase64.cpp llbitpack.cpp llcallbacklist.cpp + llcallstack.cpp + llcleanup.cpp llcommon.cpp llcommonutils.cpp + llcoro_get_id.cpp llcoros.cpp llcrc.cpp llcriticaldamp.cpp @@ -58,6 +60,7 @@ set(llcommon_SOURCE_FILES lleventfilter.cpp llevents.cpp lleventtimer.cpp + llexception.cpp llfasttimer.cpp llfile.cpp llfindlocale.cpp @@ -65,7 +68,9 @@ set(llcommon_SOURCE_FILES llformat.cpp llframetimer.cpp llheartbeat.cpp + llheteromap.cpp llinitparam.cpp + llinitdestroyclass.cpp llinstancetracker.cpp llleap.cpp llleaplistener.cpp @@ -114,6 +119,7 @@ set(llcommon_SOURCE_FILES llworkerthread.cpp timing.cpp u64.cpp + StackWalker.cpp ) set(llcommon_HEADER_FILES @@ -134,8 +140,11 @@ set(llcommon_HEADER_FILES llbitpack.h llboost.h llcallbacklist.h + llcallstack.h + llcleanup.h llcommon.h llcommonutils.h + llcoro_get_id.h llcoros.h llcrc.h llcriticaldamp.h @@ -157,6 +166,7 @@ set(llcommon_HEADER_FILES lleventfilter.h llevents.h lleventemitter.h + llexception.h llfasttimer.h llfile.h llfindlocale.h @@ -166,7 +176,9 @@ set(llcommon_HEADER_FILES llhandle.h llhash.h llheartbeat.h + llheteromap.h llindexedvector.h + llinitdestroyclass.h llinitparam.h llinstancetracker.h llkeythrottle.h @@ -183,6 +195,7 @@ set(llcommon_HEADER_FILES llmortician.h llnametable.h llpointer.h + llpounceable.h llpredicate.h llpreprocessor.h llpriqueuemap.h @@ -235,6 +248,7 @@ set(llcommon_HEADER_FILES stringize.h timer.h u64.h + StackWalker.h ) set_source_files_properties(${llcommon_HEADER_FILES} @@ -244,13 +258,13 @@ list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) if(LLCOMMON_LINK_SHARED) add_library (llcommon SHARED ${llcommon_SOURCE_FILES}) - if(NOT WORD_SIZE EQUAL 32) + if(NOT ADDRESS_SIZE EQUAL 32) if(WINDOWS) - add_definitions(/FIXED:NO) + ##add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) - endif(NOT WORD_SIZE EQUAL 32) + endif(NOT ADDRESS_SIZE EQUAL 32) if(WINDOWS) # always generate llcommon.pdb, even for "Release" builds set_target_properties(llcommon PROPERTIES LINK_FLAGS "/DEBUG") @@ -315,7 +329,7 @@ if (LL_TESTS) LL_ADD_INTEGRATION_TEST(llprocinfo "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}") - LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lltrace "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}") @@ -327,9 +341,12 @@ if (LL_TESTS) LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(llpounceable "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(llheteromap "" "${test_libs}") + +## llexception_test.cpp isn't a regression test, and doesn't need to be run +## every build. It's to help a developer make implementation choices about +## throwing and catching exceptions. +##LL_ADD_INTEGRATION_TEST(llexception "" "${test_libs}") - # *TODO - reenable these once tcmalloc libs no longer break the build. - #ADD_BUILD_TEST(llallocator llcommon) - #ADD_BUILD_TEST(llallocator_heap_profile llcommon) - #ADD_BUILD_TEST(llmemtype llcommon) endif (LL_TESTS) diff --git a/indra/llcommon/StackWalker.cpp b/indra/llcommon/StackWalker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0d3104099f49cc7c87e856b50112fe9c3066399 --- /dev/null +++ b/indra/llcommon/StackWalker.cpp @@ -0,0 +1,1388 @@ +/********************************************************************** + * + * StackWalker.cpp + * http://stackwalker.codeplex.com/ + * + * + * $LicenseInfo:firstyear=2016&license=bsd$ + * + * Linden notes: Small modifications from the original source at https://stackwalker.codeplex.com/ + * + * History: + * 2005-07-27 v1 - First public release on http://www.codeproject.com/ + * http://www.codeproject.com/threads/StackWalker.asp + * 2005-07-28 v2 - Changed the params of the constructor and ShowCallstack + * (to simplify the usage) + * 2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL + * (should also be enough) + * - Changed to compile correctly with the PSDK of VC7.0 + * (GetFileVersionInfoSizeA and GetFileVersionInfoA is wrongly defined: + * it uses LPSTR instead of LPCSTR as first paremeter) + * - Added declarations to support VC5/6 without using 'dbghelp.h' + * - Added a 'pUserData' member to the ShowCallstack function and the + * PReadProcessMemoryRoutine declaration (to pass some user-defined data, + * which can be used in the readMemoryFunction-callback) + * 2005-08-02 v4 - OnSymInit now also outputs the OS-Version by default + * - Added example for doing an exception-callstack-walking in main.cpp + * (thanks to owillebo: http://www.codeproject.com/script/profile/whos_who.asp?id=536268) + * 2005-08-05 v5 - Removed most Lint (http://www.gimpel.com/) errors... thanks to Okko Willeboordse! + * 2008-08-04 v6 - Fixed Bug: Missing LEAK-end-tag + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2502890#xx2502890xx + * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN" + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx + * Fixed Bug: Compiling with "/Wall" + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx + * Fixed Bug: Now checking SymUseSymSrv + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1388979#xx1388979xx + * Fixed Bug: Support for recursive function calls + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1434538#xx1434538xx + * Fixed Bug: Missing FreeLibrary call in "GetModuleListTH32" + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1326923#xx1326923xx + * Fixed Bug: SymDia is number 7, not 9! + * 2008-09-11 v7 For some (undocumented) reason, dbhelp.h is needing a packing of 8! + * Thanks to Teajay which reported the bug... + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2718933#xx2718933xx + * 2008-11-27 v8 Debugging Tools for Windows are now stored in a different directory + * Thanks to Luiz Salamon which reported this "bug"... + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2822736#xx2822736xx + * 2009-04-10 v9 License slihtly corrected (<ORGANIZATION> replaced) + * 2009-11-01 v10 Moved to http://stackwalker.codeplex.com/ + * 2009-11-02 v11 Now try to use IMAGEHLP_MODULE64_V3 if available + * 2010-04-15 v12 Added support for VS2010 RTM + * 2010-05-25 v13 Now using secure MyStrcCpy. Thanks to luke.simon: + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3477467#xx3477467xx + * 2013-01-07 v14 Runtime Check Error VS2010 Debug Builds fixed: + * http://stackwalker.codeplex.com/workitem/10511 + * + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2013, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ +#if LL_WINDOWS + +#include <windows.h> +#include <tchar.h> +#include <stdio.h> +#include <stdlib.h> +#pragma comment(lib, "version.lib") // for "VerQueryValue" +#pragma warning(disable:4826) + +#include "StackWalker.h" + + +// If VC7 and later, then use the shipped 'dbghelp.h'-file +#pragma pack(push,8) +#if _MSC_VER >= 1300 +#include <dbghelp.h> +#else +// inline the important dbghelp.h-declarations... +typedef enum { + SymNone = 0, + SymCoff, + SymCv, + SymPdb, + SymExport, + SymDeferred, + SymSym, + SymDia, + SymVirtual, + NumSymTypes +} SYM_TYPE; +typedef struct _IMAGEHLP_LINE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; +typedef struct _IMAGEHLP_MODULE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; +typedef struct _IMAGEHLP_SYMBOL64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) + DWORD64 Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + CHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; +typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat +} ADDRESS_MODE; +typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; +} ADDRESS64, *LPADDRESS64; +typedef struct _KDHELP64 { + DWORD64 Thread; + DWORD ThCallbackStack; + DWORD ThCallbackBStore; + DWORD NextCallback; + DWORD FramePointer; + DWORD64 KiCallUserMode; + DWORD64 KeUserCallbackDispatcher; + DWORD64 SystemRangeStart; + DWORD64 Reserved[8]; +} KDHELP64, *PKDHELP64; +typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + PVOID FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; +} STACKFRAME64, *LPSTACKFRAME64; +typedef +BOOL +(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead + ); +typedef +PVOID +(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( + HANDLE hProcess, + DWORD64 AddrBase + ); +typedef +DWORD64 +(__stdcall *PGET_MODULE_BASE_ROUTINE64)( + HANDLE hProcess, + DWORD64 Address + ); +typedef +DWORD64 +(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)( + HANDLE hProcess, + HANDLE hThread, + LPADDRESS64 lpaddr + ); +#define SYMOPT_CASE_INSENSITIVE 0x00000001 +#define SYMOPT_UNDNAME 0x00000002 +#define SYMOPT_DEFERRED_LOADS 0x00000004 +#define SYMOPT_NO_CPP 0x00000008 +#define SYMOPT_LOAD_LINES 0x00000010 +#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 +#define SYMOPT_LOAD_ANYTHING 0x00000040 +#define SYMOPT_IGNORE_CVREC 0x00000080 +#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 +#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 +#define SYMOPT_EXACT_SYMBOLS 0x00000400 +#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 +#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 +#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 +#define SYMOPT_PUBLICS_ONLY 0x00004000 +#define SYMOPT_NO_PUBLICS 0x00008000 +#define SYMOPT_AUTO_PUBLICS 0x00010000 +#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 +#define SYMOPT_SECURE 0x00040000 +#define SYMOPT_DEBUG 0x80000000 +#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration +#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; +#endif // _MSC_VER < 1300 +#pragma pack(pop) + +// Some missing defines (for VC5/6): +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif + + +// secure-CRT_functions are only available starting with VC8 +#if _MSC_VER < 1400 +#define strcpy_s(dst, len, src) strcpy(dst, src) +#define strncpy_s(dst, len, src, maxLen) strncpy(dst, len, src) +#define strcat_s(dst, len, src) strcat(dst, src) +#define _snprintf_s _snprintf +#define _tcscat_s _tcscat +#endif + +static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc) +{ + if (nMaxDestSize <= 0) return; + strncpy_s(szDest, nMaxDestSize, szSrc, _TRUNCATE); + szDest[nMaxDestSize-1] = 0; // INFO: _TRUNCATE will ensure that it is nul-terminated; but with older compilers (<1400) it uses "strncpy" and this does not!) +} // MyStrCpy + +// Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL') +#define USED_CONTEXT_FLAGS CONTEXT_FULL + + +class StackWalkerInternal +{ +public: + StackWalkerInternal(StackWalker *parent, HANDLE hProcess) + { + m_parent = parent; + m_hDbhHelp = NULL; + pSC = NULL; + m_hProcess = hProcess; + m_szSymPath = NULL; + pSFTA = NULL; + pSGLFA = NULL; + pSGMB = NULL; + pSGMI = NULL; + pSGO = NULL; + pSGSFA = NULL; + pSI = NULL; + pSLM = NULL; + pSSO = NULL; + pSW = NULL; + pUDSN = NULL; + pSGSP = NULL; + } + ~StackWalkerInternal() + { + if (pSC != NULL) + pSC(m_hProcess); // SymCleanup + if (m_hDbhHelp != NULL) + FreeLibrary(m_hDbhHelp); + m_hDbhHelp = NULL; + m_parent = NULL; + if(m_szSymPath != NULL) + free(m_szSymPath); + m_szSymPath = NULL; + } + BOOL Init(LPCSTR szSymPath) + { + if (m_parent == NULL) + return FALSE; + // Dynamically load the Entry-Points for dbghelp.dll: + // First try to load the newsest one from + TCHAR szTemp[4096]; + // But before wqe do this, we first check if the ".local" file exists + if (GetModuleFileName(NULL, szTemp, 4096) > 0) + { + _tcscat_s(szTemp, _T(".local")); + if (GetFileAttributes(szTemp) == INVALID_FILE_ATTRIBUTES) + { + // ".local" file does not exist, so we can try to load the dbghelp.dll from the "Debugging Tools for Windows" + // Ok, first try the new path according to the archtitecture: +#ifdef _M_IX86 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x86)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#elif _M_X64 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#elif _M_IA64 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (ia64)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#endif + // If still not found, try the old directories... + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#if defined _M_X64 || defined _M_IA64 + // Still not found? Then try to load the (old) 64-Bit version: + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll")); + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#endif + } + } + if (m_hDbhHelp == NULL) // if not already loaded, try to load a default-one + m_hDbhHelp = LoadLibrary( _T("dbghelp.dll") ); + if (m_hDbhHelp == NULL) + return FALSE; + pSI = (tSI) GetProcAddress(m_hDbhHelp, "SymInitialize" ); + pSC = (tSC) GetProcAddress(m_hDbhHelp, "SymCleanup" ); + + pSW = (tSW) GetProcAddress(m_hDbhHelp, "StackWalk64" ); + pSGO = (tSGO) GetProcAddress(m_hDbhHelp, "SymGetOptions" ); + pSSO = (tSSO) GetProcAddress(m_hDbhHelp, "SymSetOptions" ); + + pSFTA = (tSFTA) GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64" ); + pSGLFA = (tSGLFA) GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64" ); + pSGMB = (tSGMB) GetProcAddress(m_hDbhHelp, "SymGetModuleBase64" ); + pSGMI = (tSGMI) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" ); + pSGSFA = (tSGSFA) GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64" ); + pUDSN = (tUDSN) GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName" ); + pSLM = (tSLM) GetProcAddress(m_hDbhHelp, "SymLoadModule64" ); + pSGSP =(tSGSP) GetProcAddress(m_hDbhHelp, "SymGetSearchPath" ); + + if ( pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL || + pSGO == NULL || pSGSFA == NULL || pSI == NULL || pSSO == NULL || + pSW == NULL || pUDSN == NULL || pSLM == NULL ) + { + FreeLibrary(m_hDbhHelp); + m_hDbhHelp = NULL; + pSC = NULL; + return FALSE; + } + + // SymInitialize + if (szSymPath != NULL) + m_szSymPath = _strdup(szSymPath); + if (this->pSI(m_hProcess, m_szSymPath, FALSE) == FALSE) + this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0); + + DWORD symOptions = this->pSGO(); // SymGetOptions + symOptions |= SYMOPT_LOAD_LINES; + symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS; + //symOptions |= SYMOPT_NO_PROMPTS; + // SymSetOptions + symOptions = this->pSSO(symOptions); + + char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0}; + if (this->pSGSP != NULL) + { + if (this->pSGSP(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE) + this->m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0); + } + char szUserName[1024] = {0}; + DWORD dwSize = 1024; + GetUserNameA(szUserName, &dwSize); + this->m_parent->OnSymInit(buf, symOptions, szUserName); + + return TRUE; + } + + StackWalker *m_parent; + + HMODULE m_hDbhHelp; + HANDLE m_hProcess; + LPSTR m_szSymPath; + +#pragma pack(push,8) +typedef struct IMAGEHLP_MODULE64_V3 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name + // new elements: 07-Jun-2002 + CHAR LoadedPdbName[256]; // pdb file name + DWORD CVSig; // Signature of the CV record in the debug directories + CHAR CVData[MAX_PATH * 3]; // Contents of the CV record + DWORD PdbSig; // Signature of PDB + GUID PdbSig70; // Signature of PDB (VC 7 and up) + DWORD PdbAge; // DBI age of pdb + BOOL PdbUnmatched; // loaded an unmatched pdb + BOOL DbgUnmatched; // loaded an unmatched dbg + BOOL LineNumbers; // we have line number information + BOOL GlobalSymbols; // we have internal symbol information + BOOL TypeInfo; // we have type information + // new elements: 17-Dec-2003 + BOOL SourceIndexed; // pdb supports source server + BOOL Publics; // contains public symbols +}; + +typedef struct IMAGEHLP_MODULE64_V2 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +}; +#pragma pack(pop) + + + // SymCleanup() + typedef BOOL (__stdcall *tSC)( IN HANDLE hProcess ); + tSC pSC; + + // SymFunctionTableAccess64() + typedef PVOID (__stdcall *tSFTA)( HANDLE hProcess, DWORD64 AddrBase ); + tSFTA pSFTA; + + // SymGetLineFromAddr64() + typedef BOOL (__stdcall *tSGLFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, + OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line ); + tSGLFA pSGLFA; + + // SymGetModuleBase64() + typedef DWORD64 (__stdcall *tSGMB)( IN HANDLE hProcess, IN DWORD64 dwAddr ); + tSGMB pSGMB; + + // SymGetModuleInfo64() + typedef BOOL (__stdcall *tSGMI)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V3 *ModuleInfo ); + tSGMI pSGMI; + + // SymGetOptions() + typedef DWORD (__stdcall *tSGO)( VOID ); + tSGO pSGO; + + // SymGetSymFromAddr64() + typedef BOOL (__stdcall *tSGSFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, + OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol ); + tSGSFA pSGSFA; + + // SymInitialize() + typedef BOOL (__stdcall *tSI)( IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess ); + tSI pSI; + + // SymLoadModule64() + typedef DWORD64 (__stdcall *tSLM)( IN HANDLE hProcess, IN HANDLE hFile, + IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll ); + tSLM pSLM; + + // SymSetOptions() + typedef DWORD (__stdcall *tSSO)( IN DWORD SymOptions ); + tSSO pSSO; + + // StackWalk64() + typedef BOOL (__stdcall *tSW)( + DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress ); + tSW pSW; + + // UnDecorateSymbolName() + typedef DWORD (__stdcall WINAPI *tUDSN)( PCSTR DecoratedName, PSTR UnDecoratedName, + DWORD UndecoratedLength, DWORD Flags ); + tUDSN pUDSN; + + typedef BOOL (__stdcall WINAPI *tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength); + tSGSP pSGSP; + + +private: + // **************************************** ToolHelp32 ************************ + #define MAX_MODULE_NAME32 255 + #define TH32CS_SNAPMODULE 0x00000008 + #pragma pack( push, 8 ) + typedef struct tagMODULEENTRY32 + { + DWORD dwSize; + DWORD th32ModuleID; // This module + DWORD th32ProcessID; // owning process + DWORD GlblcntUsage; // Global usage count on the module + DWORD ProccntUsage; // Module usage count in th32ProcessID's context + BYTE * modBaseAddr; // Base address of module in th32ProcessID's context + DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr + HMODULE hModule; // The hModule of this module in th32ProcessID's context + char szModule[MAX_MODULE_NAME32 + 1]; + char szExePath[MAX_PATH]; + } MODULEENTRY32; + typedef MODULEENTRY32 * PMODULEENTRY32; + typedef MODULEENTRY32 * LPMODULEENTRY32; + #pragma pack( pop ) + + BOOL GetModuleListTH32(HANDLE hProcess, DWORD pid) + { + // CreateToolhelp32Snapshot() + typedef HANDLE (__stdcall *tCT32S)(DWORD dwFlags, DWORD th32ProcessID); + // Module32First() + typedef BOOL (__stdcall *tM32F)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); + // Module32Next() + typedef BOOL (__stdcall *tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); + + // try both dlls... + const TCHAR *dllname[] = { _T("kernel32.dll"), _T("tlhelp32.dll") }; + HINSTANCE hToolhelp = NULL; + tCT32S pCT32S = NULL; + tM32F pM32F = NULL; + tM32N pM32N = NULL; + + HANDLE hSnap; + MODULEENTRY32 me; + me.dwSize = sizeof(me); + BOOL keepGoing; + size_t i; + + for (i = 0; i<(sizeof(dllname) / sizeof(dllname[0])); i++ ) + { + hToolhelp = LoadLibrary( dllname[i] ); + if (hToolhelp == NULL) + continue; + pCT32S = (tCT32S) GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot"); + pM32F = (tM32F) GetProcAddress(hToolhelp, "Module32First"); + pM32N = (tM32N) GetProcAddress(hToolhelp, "Module32Next"); + if ( (pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL) ) + break; // found the functions! + FreeLibrary(hToolhelp); + hToolhelp = NULL; + } + + if (hToolhelp == NULL) + return FALSE; + + hSnap = pCT32S( TH32CS_SNAPMODULE, pid ); + if (hSnap == (HANDLE) -1) + { + FreeLibrary(hToolhelp); + return FALSE; + } + + keepGoing = !!pM32F( hSnap, &me ); + int cnt = 0; + while (keepGoing) + { + this->LoadModule(hProcess, me.szExePath, me.szModule, (DWORD64) me.modBaseAddr, me.modBaseSize); + cnt++; + keepGoing = !!pM32N( hSnap, &me ); + } + CloseHandle(hSnap); + FreeLibrary(hToolhelp); + if (cnt <= 0) + return FALSE; + return TRUE; + } // GetModuleListTH32 + + // **************************************** PSAPI ************************ + typedef struct _MODULEINFO { + LPVOID lpBaseOfDll; + DWORD SizeOfImage; + LPVOID EntryPoint; + } MODULEINFO, *LPMODULEINFO; + + BOOL GetModuleListPSAPI(HANDLE hProcess) + { + // EnumProcessModules() + typedef BOOL (__stdcall *tEPM)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); + // GetModuleFileNameEx() + typedef DWORD (__stdcall *tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); + // GetModuleBaseName() + typedef DWORD (__stdcall *tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); + // GetModuleInformation() + typedef BOOL (__stdcall *tGMI)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize ); + + HINSTANCE hPsapi; + tEPM pEPM; + tGMFNE pGMFNE; + tGMBN pGMBN; + tGMI pGMI; + + DWORD i; + //ModuleEntry e; + DWORD cbNeeded; + MODULEINFO mi; + HMODULE *hMods = 0; + char *tt = NULL; + char *tt2 = NULL; + const SIZE_T TTBUFLEN = 8096; + int cnt = 0; + + hPsapi = LoadLibrary( _T("psapi.dll") ); + if (hPsapi == NULL) + return FALSE; + + pEPM = (tEPM) GetProcAddress( hPsapi, "EnumProcessModules" ); + pGMFNE = (tGMFNE) GetProcAddress( hPsapi, "GetModuleFileNameExA" ); + pGMBN = (tGMFNE) GetProcAddress( hPsapi, "GetModuleBaseNameA" ); + pGMI = (tGMI) GetProcAddress( hPsapi, "GetModuleInformation" ); + if ( (pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL) ) + { + // we couldn´t find all functions + FreeLibrary(hPsapi); + return FALSE; + } + + hMods = (HMODULE*) malloc(sizeof(HMODULE) * (TTBUFLEN / sizeof(HMODULE))); + tt = (char*) malloc(sizeof(char) * TTBUFLEN); + tt2 = (char*) malloc(sizeof(char) * TTBUFLEN); + if ( (hMods == NULL) || (tt == NULL) || (tt2 == NULL) ) + goto cleanup; + + if ( ! pEPM( hProcess, hMods, TTBUFLEN, &cbNeeded ) ) + { + //_ftprintf(fLogFile, _T("%lu: EPM failed, GetLastError = %lu\n"), g_dwShowCount, gle ); + goto cleanup; + } + + if ( cbNeeded > TTBUFLEN ) + { + //_ftprintf(fLogFile, _T("%lu: More than %lu module handles. Huh?\n"), g_dwShowCount, lenof( hMods ) ); + goto cleanup; + } + + for ( i = 0; i < cbNeeded / sizeof(hMods[0]); i++ ) + { + // base address, size + pGMI(hProcess, hMods[i], &mi, sizeof(mi)); + // image file name + tt[0] = 0; + pGMFNE(hProcess, hMods[i], tt, TTBUFLEN ); + // module name + tt2[0] = 0; + pGMBN(hProcess, hMods[i], tt2, TTBUFLEN ); + + DWORD dwRes = this->LoadModule(hProcess, tt, tt2, (DWORD64) mi.lpBaseOfDll, mi.SizeOfImage); + if (dwRes != ERROR_SUCCESS) + this->m_parent->OnDbgHelpErr("LoadModule", dwRes, 0); + cnt++; + } + + cleanup: + if (hPsapi != NULL) FreeLibrary(hPsapi); + if (tt2 != NULL) free(tt2); + if (tt != NULL) free(tt); + if (hMods != NULL) free(hMods); + + return cnt != 0; + } // GetModuleListPSAPI + + DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size) + { + CHAR *szImg = _strdup(img); + CHAR *szMod = _strdup(mod); + DWORD result = ERROR_SUCCESS; + if ( (szImg == NULL) || (szMod == NULL) ) + result = ERROR_NOT_ENOUGH_MEMORY; + else + { + if (pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0) + result = GetLastError(); + } + ULONGLONG fileVersion = 0; + if ( (m_parent != NULL) && (szImg != NULL) ) + { + // try to retrive the file-version: + if ( (this->m_parent->m_options & StackWalker::RetrieveFileVersion) != 0) + { + VS_FIXEDFILEINFO *fInfo = NULL; + DWORD dwHandle; + DWORD dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle); + if (dwSize > 0) + { + LPVOID vData = malloc(dwSize); + if (vData != NULL) + { + if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0) + { + UINT len; + TCHAR szSubBlock[] = _T("\\"); + if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) == 0) + fInfo = NULL; + else + { + fileVersion = ((ULONGLONG)fInfo->dwFileVersionLS) + ((ULONGLONG)fInfo->dwFileVersionMS << 32); + } + } + free(vData); + } + } + } + + // Retrive some additional-infos about the module + IMAGEHLP_MODULE64_V3 Module; + const char *szSymType = "-unknown-"; + if (this->GetModuleInfo(hProcess, baseAddr, &Module) != FALSE) + { + switch(Module.SymType) + { + case SymNone: + szSymType = "-nosymbols-"; + break; + case SymCoff: // 1 + szSymType = "COFF"; + break; + case SymCv: // 2 + szSymType = "CV"; + break; + case SymPdb: // 3 + szSymType = "PDB"; + break; + case SymExport: // 4 + szSymType = "-exported-"; + break; + case SymDeferred: // 5 + szSymType = "-deferred-"; + break; + case SymSym: // 6 + szSymType = "SYM"; + break; + case 7: // SymDia: + szSymType = "DIA"; + break; + case 8: //SymVirtual: + szSymType = "Virtual"; + break; + } + } + LPCSTR pdbName = Module.LoadedImageName; + if (Module.LoadedPdbName[0] != 0) + pdbName = Module.LoadedPdbName; + this->m_parent->OnLoadModule(img, mod, baseAddr, size, result, szSymType, pdbName, fileVersion); + } + if (szImg != NULL) free(szImg); + if (szMod != NULL) free(szMod); + return result; + } +public: + BOOL LoadModules(HANDLE hProcess, DWORD dwProcessId) + { + // first try toolhelp32 + if (GetModuleListTH32(hProcess, dwProcessId)) + return true; + // then try psapi + return GetModuleListPSAPI(hProcess); + } + + + BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V3 *pModuleInfo) + { + memset(pModuleInfo, 0, sizeof(IMAGEHLP_MODULE64_V3)); + if(this->pSGMI == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + // First try to use the larger ModuleInfo-Structure + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3); + void *pData = malloc(4096); // reserve enough memory, so the bug in v6.3.5.1 does not lead to memory-overwrites... + if (pData == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V3)); + static bool s_useV3Version = true; + if (s_useV3Version) + { + if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*) pData) != FALSE) + { + // only copy as much memory as is reserved... + memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V3)); + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3); + free(pData); + return TRUE; + } + s_useV3Version = false; // to prevent unneccessarry calls with the larger struct... + } + + // could not retrive the bigger structure, try with the smaller one (as defined in VC7.1)... + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); + memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V2)); + if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*) pData) != FALSE) + { + // only copy as much memory as is reserved... + memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V2)); + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); + free(pData); + return TRUE; + } + free(pData); + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } +}; + +// ############################################################# +StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess) +{ + this->m_verbose = true; + this->m_options = OptionsAll; + this->m_modulesLoaded = FALSE; + this->m_hProcess = hProcess; + this->m_sw = new StackWalkerInternal(this, this->m_hProcess); + this->m_dwProcessId = dwProcessId; + this->m_szSymPath = NULL; + this->m_MaxRecursionCount = 1000; +} +StackWalker::StackWalker(bool verbose, int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess) +{ + this->m_verbose = verbose; + this->m_options = options; + this->m_modulesLoaded = FALSE; + this->m_hProcess = hProcess; + this->m_sw = new StackWalkerInternal(this, this->m_hProcess); + this->m_dwProcessId = dwProcessId; + if (szSymPath != NULL) + { + this->m_szSymPath = _strdup(szSymPath); + this->m_options |= SymBuildPath; + } + else + this->m_szSymPath = NULL; + this->m_MaxRecursionCount = 1000; +} + +StackWalker::~StackWalker() +{ + if (m_szSymPath != NULL) + free(m_szSymPath); + m_szSymPath = NULL; + if (this->m_sw != NULL) + delete this->m_sw; + this->m_sw = NULL; +} + +BOOL StackWalker::LoadModules() +{ + if (this->m_sw == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + if (m_modulesLoaded != FALSE) + return TRUE; + + // Build the sym-path: + char *szSymPath = NULL; + if ( (this->m_options & SymBuildPath) != 0) + { + const size_t nSymPathLen = 4096; + szSymPath = (char*) malloc(nSymPathLen); + if (szSymPath == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + szSymPath[0] = 0; + // Now first add the (optional) provided sympath: + if (this->m_szSymPath != NULL) + { + strcat_s(szSymPath, nSymPathLen, this->m_szSymPath); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + strcat_s(szSymPath, nSymPathLen, ".;"); + + const size_t nTempLen = 1024; + char szTemp[nTempLen]; + // Now add the current directory: + if (GetCurrentDirectoryA(nTempLen, szTemp) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + // Now add the path for the main-module: + if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + for (char *p = (szTemp+strlen(szTemp)-1); p >= szTemp; --p) + { + // locate the rightmost path separator + if ( (*p == '\\') || (*p == '/') || (*p == ':') ) + { + *p = 0; + break; + } + } // for (search for path separator...) + if (strlen(szTemp) > 0) + { + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + } + if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + // also add the "system32"-directory: + strcat_s(szTemp, nTempLen, "\\system32"); + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + if ( (this->m_options & SymUseSymSrv) != 0) + { + if (GetEnvironmentVariableA("SYSTEMDRIVE", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, "SRV*"); + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, "\\websymbols"); + strcat_s(szSymPath, nSymPathLen, "*http://msdl.microsoft.com/download/symbols;"); + } + else + strcat_s(szSymPath, nSymPathLen, "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;"); + } + } // if SymBuildPath + + // First Init the whole stuff... + BOOL bRet = this->m_sw->Init(szSymPath); + if (szSymPath != NULL) free(szSymPath); szSymPath = NULL; + if (bRet == FALSE) + { + this->OnDbgHelpErr("Error while initializing dbghelp.dll", 0, 0); + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + + bRet = this->m_sw->LoadModules(this->m_hProcess, this->m_dwProcessId); + if (bRet != FALSE) + m_modulesLoaded = TRUE; + return bRet; +} + + +// The following is used to pass the "userData"-Pointer to the user-provided readMemoryFunction +// This has to be done due to a problem with the "hProcess"-parameter in x64... +// Because this class is in no case multi-threading-enabled (because of the limitations +// of dbghelp.dll) it is "safe" to use a static-variable +static StackWalker::PReadProcessMemoryRoutine s_readMemoryFunction = NULL; +static LPVOID s_readMemoryFunction_UserData = NULL; + +BOOL StackWalker::ShowCallstack(bool verbose, HANDLE hThread, const CONTEXT *context, PReadProcessMemoryRoutine readMemoryFunction, LPVOID pUserData) +{ + m_verbose = verbose; + CONTEXT c; + CallstackEntry csEntry; + IMAGEHLP_SYMBOL64 *pSym = NULL; + StackWalkerInternal::IMAGEHLP_MODULE64_V3 Module; + IMAGEHLP_LINE64 Line; + int frameNum; + bool bLastEntryCalled = true; + int curRecursionCount = 0; + + if (m_modulesLoaded == FALSE) + this->LoadModules(); // ignore the result... + + if (this->m_sw->m_hDbhHelp == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + + s_readMemoryFunction = readMemoryFunction; + s_readMemoryFunction_UserData = pUserData; + + if (context == NULL) + { + // If no context is provided, capture the context + // See: https://stackwalker.codeplex.com/discussions/446958 +#if _WIN32_WINNT <= 0x0501 + // If we need to support XP, we need to use the "old way", because "GetThreadId" is not available! + if (hThread == GetCurrentThread()) +#else + if (GetThreadId(hThread) == GetCurrentThreadId()) +#endif + { + GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, USED_CONTEXT_FLAGS); + } + else + { + SuspendThread(hThread); + memset(&c, 0, sizeof(CONTEXT)); + c.ContextFlags = USED_CONTEXT_FLAGS; + if (GetThreadContext(hThread, &c) == FALSE) + { + ResumeThread(hThread); + return FALSE; + } + } + } + else + c = *context; + + // init STACKFRAME for first call + STACKFRAME64 s; // in/out stackframe + memset(&s, 0, sizeof(s)); + DWORD imageType; +#ifdef _M_IX86 + // normally, call ImageNtHeader() and use machine info from PE header + imageType = IMAGE_FILE_MACHINE_I386; + s.AddrPC.Offset = c.Eip; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.Ebp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrStack.Offset = c.Esp; + s.AddrStack.Mode = AddrModeFlat; +#elif _M_X64 + imageType = IMAGE_FILE_MACHINE_AMD64; + s.AddrPC.Offset = c.Rip; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.Rsp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrStack.Offset = c.Rsp; + s.AddrStack.Mode = AddrModeFlat; +#elif _M_IA64 + imageType = IMAGE_FILE_MACHINE_IA64; + s.AddrPC.Offset = c.StIIP; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.IntSp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrBStore.Offset = c.RsBSP; + s.AddrBStore.Mode = AddrModeFlat; + s.AddrStack.Offset = c.IntSp; + s.AddrStack.Mode = AddrModeFlat; +#else +#error "Platform not supported!" +#endif + + pSym = (IMAGEHLP_SYMBOL64 *) malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); + if (!pSym) goto cleanup; // not enough memory... + memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); + pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + pSym->MaxNameLength = STACKWALK_MAX_NAMELEN; + + memset(&Line, 0, sizeof(Line)); + Line.SizeOfStruct = sizeof(Line); + + memset(&Module, 0, sizeof(Module)); + Module.SizeOfStruct = sizeof(Module); + + for (frameNum = 0; ; ++frameNum ) + { + // get next stack frame (StackWalk64(), SymFunctionTableAccess64(), SymGetModuleBase64()) + // if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can + // assume that either you are done, or that the stack is so hosed that the next + // deeper frame could not be found. + // CONTEXT need not to be suplied if imageTyp is IMAGE_FILE_MACHINE_I386! + if ( ! this->m_sw->pSW(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem, this->m_sw->pSFTA, this->m_sw->pSGMB, NULL) ) + { + // INFO: "StackWalk64" does not set "GetLastError"... + this->OnDbgHelpErr("StackWalk64", 0, s.AddrPC.Offset); + break; + } + + csEntry.offset = s.AddrPC.Offset; + csEntry.name[0] = 0; + csEntry.undName[0] = 0; + csEntry.undFullName[0] = 0; + csEntry.offsetFromSmybol = 0; + csEntry.offsetFromLine = 0; + csEntry.lineFileName[0] = 0; + csEntry.lineNumber = 0; + csEntry.loadedImageName[0] = 0; + csEntry.moduleName[0] = 0; + if (s.AddrPC.Offset == s.AddrReturn.Offset) + { + if ( (this->m_MaxRecursionCount > 0) && (curRecursionCount > m_MaxRecursionCount) ) + { + this->OnDbgHelpErr("StackWalk64-Endless-Callstack!", 0, s.AddrPC.Offset); + break; + } + curRecursionCount++; + } + else + curRecursionCount = 0; + if (s.AddrPC.Offset != 0) + { + // we seem to have a valid PC + // show procedure info (SymGetSymFromAddr64()) + if (this->m_sw->pSGSFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol), pSym) != FALSE) + { + MyStrCpy(csEntry.name, STACKWALK_MAX_NAMELEN, pSym->Name); + // UnDecorateSymbolName() + this->m_sw->pUDSN( pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY ); + this->m_sw->pUDSN( pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE ); + } + else + { + this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), s.AddrPC.Offset); + } + + // show line number info, NT5.0-method (SymGetLineFromAddr64()) + if (this->m_sw->pSGLFA != NULL ) + { // yes, we have SymGetLineFromAddr64() + if (this->m_sw->pSGLFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine), &Line) != FALSE) + { + csEntry.lineNumber = Line.LineNumber; + MyStrCpy(csEntry.lineFileName, STACKWALK_MAX_NAMELEN, Line.FileName); + } + else + { + this->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), s.AddrPC.Offset); + } + } // yes, we have SymGetLineFromAddr64() + + if (m_verbose) // getting module info is very slow, skip unless we're being verbose. + { + // show module info (SymGetModuleInfo64()) + if (this->m_sw->GetModuleInfo(this->m_hProcess, s.AddrPC.Offset, &Module ) != FALSE) + { // got module info OK + switch ( Module.SymType ) + { + case SymNone: + csEntry.symTypeString = "-nosymbols-"; + break; + case SymCoff: + csEntry.symTypeString = "COFF"; + break; + case SymCv: + csEntry.symTypeString = "CV"; + break; + case SymPdb: + csEntry.symTypeString = "PDB"; + break; + case SymExport: + csEntry.symTypeString = "-exported-"; + break; + case SymDeferred: + csEntry.symTypeString = "-deferred-"; + break; + case SymSym: + csEntry.symTypeString = "SYM"; + break; +#if API_VERSION_NUMBER >= 9 + case SymDia: + csEntry.symTypeString = "DIA"; + break; +#endif + case 8: //SymVirtual: + csEntry.symTypeString = "Virtual"; + break; + default: + //_snprintf( ty, sizeof(ty), "symtype=%ld", (long) Module.SymType ); + csEntry.symTypeString = NULL; + break; + } + + MyStrCpy(csEntry.moduleName, STACKWALK_MAX_NAMELEN, Module.ModuleName); + csEntry.baseOfImage = Module.BaseOfImage; + MyStrCpy(csEntry.loadedImageName, STACKWALK_MAX_NAMELEN, Module.LoadedImageName); + } // got module info OK + else + { + this->OnDbgHelpErr("SymGetModuleInfo64", GetLastError(), s.AddrPC.Offset); + } + } + else + { + MyStrCpy(csEntry.moduleName, STACKWALK_MAX_NAMELEN, "MODULE?"); + } + } // we seem to have a valid PC + + CallstackEntryType et = nextEntry; + if (frameNum == 0) + et = firstEntry; + bLastEntryCalled = false; + this->OnCallstackEntry(et, csEntry); + + if (s.AddrReturn.Offset == 0) + { + bLastEntryCalled = true; + this->OnCallstackEntry(lastEntry, csEntry); + SetLastError(ERROR_SUCCESS); + break; + } + } // for ( frameNum ) + + cleanup: + if (pSym) free( pSym ); + + if (bLastEntryCalled == false) + this->OnCallstackEntry(lastEntry, csEntry); + + if (context == NULL) + ResumeThread(hThread); + + return TRUE; +} + +BOOL __stdcall StackWalker::myReadProcMem( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead + ) +{ + if (s_readMemoryFunction == NULL) + { + SIZE_T st; + BOOL bRet = ReadProcessMemory(hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, &st); + *lpNumberOfBytesRead = (DWORD) st; + //printf("ReadMemory: hProcess: %p, baseAddr: %p, buffer: %p, size: %d, read: %d, result: %d\n", hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, (DWORD) st, (DWORD) bRet); + return bRet; + } + else + { + return s_readMemoryFunction(hProcess, qwBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead, s_readMemoryFunction_UserData); + } +} + +void StackWalker::OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + if (fileVersion == 0) + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName); + else + { + DWORD v4 = (DWORD) (fileVersion & 0xFFFF); + DWORD v3 = (DWORD) ((fileVersion>>16) & 0xFFFF); + DWORD v2 = (DWORD) ((fileVersion>>32) & 0xFFFF); + DWORD v1 = (DWORD) ((fileVersion>>48) & 0xFFFF); + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4); + } + if (m_verbose) + { + OnOutput(buffer); + } +} + +void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + if ( (eType != lastEntry) && (entry.offset != 0) ) + { + if (entry.name[0] == 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)"); + if (entry.undName[0] != 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undName); + if (entry.undFullName[0] != 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName); + if (entry.lineFileName[0] == 0) + { + MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)"); + if (entry.moduleName[0] == 0) + MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, "(module-name not available)"); + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%p (%s): %s: %s\n", (LPVOID) entry.offset, entry.moduleName, entry.lineFileName, entry.name); + } + else + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s (%d): %s\n", entry.lineFileName, entry.lineNumber, entry.name); + buffer[STACKWALK_MAX_NAMELEN-1] = 0; + OnOutput(buffer); + } +} + +void StackWalker::OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle, (LPVOID) addr); + if (m_verbose) + { + OnOutput(buffer); + } +} + +#pragma warning (disable : 4996) + +void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n", szSearchPath, symOptions, szUserName); + if (m_verbose) + { + OnOutput(buffer); + } + // Also display the OS-version +#if _MSC_VER <= 1200 + OSVERSIONINFOA ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOA)); + ver.dwOSVersionInfoSize = sizeof(ver); + if (GetVersionExA(&ver) != FALSE) + { + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s)\n", + ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, + ver.szCSDVersion); + if (m_verbose) + { + OnOutput(buffer); + } + } +#else + OSVERSIONINFOEXA ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA)); + ver.dwOSVersionInfoSize = sizeof(ver); + if (GetVersionExA( (OSVERSIONINFOA*) &ver) != FALSE) + { + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n", + ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, + ver.szCSDVersion, ver.wSuiteMask, ver.wProductType); + if (m_verbose) + { + OnOutput(buffer); + } + } +#endif +} + +void StackWalker::OnOutput(LPCSTR buffer) +{ + OutputDebugStringA(buffer); +} + +#endif // LL_WINDOWS diff --git a/indra/llcommon/StackWalker.h b/indra/llcommon/StackWalker.h new file mode 100644 index 0000000000000000000000000000000000000000..834f89c471ea13a090dc2773fcf66e86bac4d5d1 --- /dev/null +++ b/indra/llcommon/StackWalker.h @@ -0,0 +1,226 @@ +/********************************************************************** + * + * StackWalker.h + * + * + * + * $LicenseInfo:firstyear=2016&license=bsd$ + * + * Linden notes: Small modifications from the original source at https://stackwalker.codeplex.com/ + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2009, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * **********************************************************************/ + +#if LL_WINDOWS + +// #pragma once is supported starting with _MCS_VER 1000, +// so we need not to check the version (because we only support _MSC_VER >= 1100)! +#pragma once + +#include <windows.h> + +// special defines for VC5/6 (if no actual PSDK is installed): +#if _MSC_VER < 1300 +typedef unsigned __int64 DWORD64, *PDWORD64; +#if defined(_WIN64) +typedef unsigned __int64 SIZE_T, *PSIZE_T; +#else +typedef unsigned long SIZE_T, *PSIZE_T; +#endif +#endif // _MSC_VER < 1300 + +class StackWalkerInternal; // forward +class StackWalker +{ +public: + typedef enum StackWalkOptions + { + // No addition info will be retrived + // (only the address is available) + RetrieveNone = 0, + + // Try to get the symbol-name + RetrieveSymbol = 1, + + // Try to get the line for this symbol + RetrieveLine = 2, + + // Try to retrieve the module-infos + RetrieveModuleInfo = 4, + + // Also retrieve the version for the DLL/EXE + RetrieveFileVersion = 8, + + // Contains all the abouve + RetrieveVerbose = 0xF, + + // Generate a "good" symbol-search-path + SymBuildPath = 0x10, + + // Also use the public Microsoft-Symbol-Server + SymUseSymSrv = 0x20, + + // Contains all the abouve "Sym"-options + SymAll = 0x30, + + // Contains all options (default) + OptionsAll = 0x3F + } StackWalkOptions; + + StackWalker( + bool verbose = true, + int options = OptionsAll, // 'int' is by design, to combine the enum-flags + LPCSTR szSymPath = NULL, + DWORD dwProcessId = GetCurrentProcessId(), + HANDLE hProcess = GetCurrentProcess() + ); + StackWalker(DWORD dwProcessId, HANDLE hProcess); + virtual ~StackWalker(); + + typedef BOOL (__stdcall *PReadProcessMemoryRoutine)( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead, + LPVOID pUserData // optional data, which was passed in "ShowCallstack" + ); + + BOOL LoadModules(); + + BOOL ShowCallstack( + bool verbose, + HANDLE hThread = GetCurrentThread(), + const CONTEXT *context = NULL, + PReadProcessMemoryRoutine readMemoryFunction = NULL, + LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback + ); + +#if _MSC_VER >= 1300 +// due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public" +// in older compilers in order to use it... starting with VC7 we can declare it as "protected" +protected: +#endif + enum { STACKWALK_MAX_NAMELEN = 4096 }; // max name length for found symbols + +protected: + // Entry for each Callstack-Entry + typedef struct CallstackEntry + { + DWORD64 offset; // if 0, we have no valid entry + CHAR name[STACKWALK_MAX_NAMELEN]; + CHAR undName[STACKWALK_MAX_NAMELEN]; + CHAR undFullName[STACKWALK_MAX_NAMELEN]; + DWORD64 offsetFromSmybol; + DWORD offsetFromLine; + DWORD lineNumber; + CHAR lineFileName[STACKWALK_MAX_NAMELEN]; + DWORD symType; + LPCSTR symTypeString; + CHAR moduleName[STACKWALK_MAX_NAMELEN]; + DWORD64 baseOfImage; + CHAR loadedImageName[STACKWALK_MAX_NAMELEN]; + } CallstackEntry; + + typedef enum CallstackEntryType {firstEntry, nextEntry, lastEntry}; + + virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName); + virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion); + virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); + virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr); + virtual void OnOutput(LPCSTR szText); + + StackWalkerInternal *m_sw; + HANDLE m_hProcess; + DWORD m_dwProcessId; + BOOL m_modulesLoaded; + LPSTR m_szSymPath; + + bool m_verbose; + int m_options; + int m_MaxRecursionCount; + + static BOOL __stdcall myReadProcMem(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead); + + friend StackWalkerInternal; +}; // class StackWalker + + +// The "ugly" assembler-implementation is needed for systems before XP +// If you have a new PSDK and you only compile for XP and later, then you can use +// the "RtlCaptureContext" +// Currently there is no define which determines the PSDK-Version... +// So we just use the compiler-version (and assumes that the PSDK is +// the one which was installed by the VS-IDE) + +// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later... +// But I currently use it in x64/IA64 environments... +//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400) + +#if defined(_M_IX86) +#ifdef CURRENT_THREAD_VIA_EXCEPTION +// TODO: The following is not a "good" implementation, +// because the callstack is only valid in the "__except" block... +#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + EXCEPTION_POINTERS *pExp = NULL; \ + __try { \ + throw 0; \ + } __except( ( (pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER)) {} \ + if (pExp != NULL) \ + memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + } while(0); +#else +// The following should be enough for walking the callstack... +#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + __asm call x \ + __asm x: pop eax \ + __asm mov c.Eip, eax \ + __asm mov c.Ebp, ebp \ + __asm mov c.Esp, esp \ + } while(0); +#endif + +#else + +// The following is defined for x86 (XP and higher), x64 and IA64: +#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + RtlCaptureContext(&c); \ +} while(0); +#endif + +#endif // LL_WINDOWS diff --git a/indra/llcommon/llallocator.cpp b/indra/llcommon/llallocator.cpp index 34fc28d8cc4699349cefd235b31c44706c322cc1..ac97fb71dd11c5f8018056a5efa9f852a8add9d0 100644 --- a/indra/llcommon/llallocator.cpp +++ b/indra/llcommon/llallocator.cpp @@ -27,47 +27,6 @@ #include "linden_common.h" #include "llallocator.h" -#if (LL_USE_TCMALLOC && LL_USE_HEAP_PROFILER) - -#include "google/heap-profiler.h" -#include "google/commandlineflags_public.h" - -DECLARE_bool(heap_profile_use_stack_trace); -//DECLARE_double(tcmalloc_release_rate); - -void LLAllocator::setProfilingEnabled(bool should_enable) -{ - // NULL disables dumping to disk - static char const * const PREFIX = NULL; - if(should_enable) - { - HeapProfilerSetUseStackTrace(false); - HeapProfilerStart(PREFIX); - } - else - { - HeapProfilerStop(); - } -} - -// static -bool LLAllocator::isProfiling() -{ - return IsHeapProfilerRunning(); -} - -std::string LLAllocator::getRawProfile() -{ - // *TODO - fix google-perftools to accept an buffer to avoid this - // malloc-copy-free cycle. - char * buffer = GetHeapProfile(); - std::string ret = buffer; - free(buffer); - return ret; -} - -#else // LL_USE_TCMALLOC - // // stub implementations for when tcmalloc is disabled // @@ -87,8 +46,6 @@ std::string LLAllocator::getRawProfile() return std::string(); } -#endif // LL_USE_TCMALLOC - LLAllocatorHeapProfile const & LLAllocator::getProfile() { mProf.mLines.clear(); diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index eb0699ad4186d1427ad1f37242b586574b51ea71..2c76f2902000e752e203280ed93a96b41d2c6360 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -48,6 +48,7 @@ #include "lleventtimer.h" #include "google_breakpad/exception_handler.h" #include "stringize.h" +#include "llcleanup.h" // // Signal handling @@ -177,7 +178,7 @@ LLApp::~LLApp() if(mExceptionHandler != 0) delete mExceptionHandler; - LLCommon::cleanupClass(); + SUBSYSTEM_CLEANUP(LLCommon); } // static diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index d9933b3d369d21590bedc35c07c1a258b54f1e02..ff9a92b45f703418c1d2c03018af7fee8486566b 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -172,12 +172,12 @@ class LL_COMMON_API LLApp virtual bool cleanup() = 0; // Override to do application cleanup // - // mainLoop() + // frame() // - // Runs the application main loop. It's assumed that when you exit - // this method, the application is in one of the cleanup states, either QUITTING or ERROR + // Pass control to the application for a single frame. Returns 'done' + // flag: if frame() returns false, it expects to be called again. // - virtual bool mainLoop() = 0; // Override for the application main loop. Needs to at least gracefully notice the QUITTING state and exit. + virtual bool frame() = 0; // Override for application body logic // // Crash logging diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index a548c96002413ebfaa943a93049a547b2061a4c0..86f407cdb0f8829d3f76d0af3d4fb633589cc0d0 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -294,9 +294,11 @@ void LLScopedLock::unlock() bool ll_apr_warn_status(apr_status_t status) { if(APR_SUCCESS == status) return false; +#if !LL_LINUX char buf[MAX_STRING]; /* Flawfinder: ignore */ apr_strerror(status, buf, sizeof(buf)); LL_WARNS("APR") << "APR: " << buf << LL_ENDL; +#endif return true; } diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 5ae2df39945b6b2517fae061c6895a578c0a8b65..4304db36bea26b30380a85184f47cc5f45dbd8f7 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -63,8 +63,7 @@ struct AssetEntry : public LLDictionaryEntry class LLAssetDictionary : public LLSingleton<LLAssetDictionary>, public LLDictionary<LLAssetType::EType, AssetEntry> { -public: - LLAssetDictionary(); + LLSINGLETON(LLAssetDictionary); }; LLAssetDictionary::LLAssetDictionary() diff --git a/indra/llcommon/llcallstack.cpp b/indra/llcommon/llcallstack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8db291eed189aa7f9c3df8519c368a02139f269f --- /dev/null +++ b/indra/llcommon/llcallstack.cpp @@ -0,0 +1,190 @@ +/** + * @file llcallstack.cpp + * @brief run-time extraction of the current callstack + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2016, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llcommon.h" +#include "llcallstack.h" +#include "StackWalker.h" +#include "llthreadlocalstorage.h" + +#if LL_WINDOWS +class LLCallStackImpl: public StackWalker +{ +public: + LLCallStackImpl(): + StackWalker(false,0) // non-verbose, options = 0 + { + } + ~LLCallStackImpl() + { + } + void getStack(std::vector<std::string>& stack, S32 skip_count=0, bool verbose=false) + { + m_stack.clear(); + ShowCallstack(verbose); + // Skip the first few lines because they're just bookkeeping for LLCallStack, + // plus any additional lines requested to skip. + S32 first_line = skip_count + 3; + for (S32 i=first_line; i<m_stack.size(); ++i) + { + stack.push_back(m_stack[i]); + } + } +protected: + virtual void OnOutput(LPCSTR szText) + { + m_stack.push_back(szText); + } + std::vector<std::string> m_stack; +}; +#else +// Stub - not implemented currently on other platforms. +class LLCallStackImpl +{ +public: + LLCallStackImpl() {} + ~LLCallStackImpl() {} + void getStack(std::vector<std::string>& stack, S32 skip_count=0, bool verbose=false) + { + stack.clear(); + } +}; +#endif + +LLCallStackImpl *LLCallStack::s_impl = NULL; + +LLCallStack::LLCallStack(S32 skip_count, bool verbose): + m_skipCount(skip_count), + m_verbose(verbose) +{ + if (!s_impl) + { + s_impl = new LLCallStackImpl; + } + LLTimer t; + s_impl->getStack(m_strings, m_skipCount, m_verbose); +} + +bool LLCallStack::contains(const std::string& str) +{ + for (std::vector<std::string>::const_iterator it = m_strings.begin(); + it != m_strings.end(); ++it) + { + if (it->find(str) != std::string::npos) + { + return true; + } + } + return false; +} + +std::ostream& operator<<(std::ostream& s, const LLCallStack& call_stack) +{ +#ifndef LL_RELEASE_FOR_DOWNLOAD + std::vector<std::string>::const_iterator it; + for (it=call_stack.m_strings.begin(); it!=call_stack.m_strings.end(); ++it) + { + s << *it; + } +#else + s << "UNAVAILABLE IN RELEASE"; +#endif + return s; +} + +LLContextStrings::LLContextStrings() +{ +} + +// static +LLContextStrings* LLContextStrings::getThreadLocalInstance() +{ + LLContextStrings *cons = LLThreadLocalSingletonPointer<LLContextStrings>::getInstance(); + if (!cons) + { + LLThreadLocalSingletonPointer<LLContextStrings>::setInstance(new LLContextStrings); + } + return LLThreadLocalSingletonPointer<LLContextStrings>::getInstance(); +} + +// static +void LLContextStrings::addContextString(const std::string& str) +{ + LLContextStrings *cons = getThreadLocalInstance(); + //LL_INFOS() << "CTX " << (S32)cons << " ADD " << str << " CNT " << cons->m_contextStrings[str] << LL_ENDL; + cons->m_contextStrings[str]++; +} + +// static +void LLContextStrings::removeContextString(const std::string& str) +{ + LLContextStrings *cons = getThreadLocalInstance(); + cons->m_contextStrings[str]--; + //LL_INFOS() << "CTX " << (S32)cons << " REMOVE " << str << " CNT " << cons->m_contextStrings[str] << LL_ENDL; + if (cons->m_contextStrings[str] == 0) + { + cons->m_contextStrings.erase(str); + } +} + +// static +bool LLContextStrings::contains(const std::string& str) +{ + const std::map<std::string,S32>& strings = + LLThreadLocalSingletonPointer<LLContextStrings>::getInstance()->m_contextStrings; + for (std::map<std::string,S32>::const_iterator it = strings.begin(); it!=strings.end(); ++it) + { + if (it->first.find(str) != std::string::npos) + { + return true; + } + } + return false; +} + +// static +void LLContextStrings::output(std::ostream& os) +{ + const std::map<std::string,S32>& strings = + LLThreadLocalSingletonPointer<LLContextStrings>::getInstance()->m_contextStrings; + for (std::map<std::string,S32>::const_iterator it = strings.begin(); it!=strings.end(); ++it) + { + os << it->first << "[" << it->second << "]" << "\n"; + } +} + +// static +std::ostream& operator<<(std::ostream& s, const LLContextStatus& context_status) +{ + LLThreadLocalSingletonPointer<LLContextStrings>::getInstance()->output(s); + return s; +} + +bool LLContextStatus::contains(const std::string& str) +{ + return LLThreadLocalSingletonPointer<LLContextStrings>::getInstance()->contains(str); +} diff --git a/indra/llcommon/llcallstack.h b/indra/llcommon/llcallstack.h new file mode 100644 index 0000000000000000000000000000000000000000..1f7a7689d7671e0448cdc8ed6724263215ffe7d2 --- /dev/null +++ b/indra/llcommon/llcallstack.h @@ -0,0 +1,80 @@ +/** + * @file llcallstack.h + * @brief run-time extraction of the current callstack + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2016, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 <map> + +class LLCallStackImpl; + +class LLCallStack +{ +public: + LLCallStack(S32 skip_count=0, bool verbose=false); + std::vector<std::string> m_strings; + bool m_verbose; + bool contains(const std::string& str); +private: + static LLCallStackImpl *s_impl; + S32 m_skipCount; +}; + +LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLCallStack& call_stack); + +class LLContextStrings +{ +public: + LLContextStrings(); + static void addContextString(const std::string& str); + static void removeContextString(const std::string& str); + static void output(std::ostream& os); + static LLContextStrings* getThreadLocalInstance(); + static bool contains(const std::string& str); +private: + std::map<std::string,S32> m_contextStrings; +}; + +class LLScopedContextString +{ +public: + LLScopedContextString(const std::string& str): + m_str(str) + { + LLContextStrings::addContextString(m_str); + } + ~LLScopedContextString() + { + LLContextStrings::removeContextString(m_str); + } +private: + std::string m_str; +}; + +// Mostly exists as a class to hook an ostream override to. +struct LLContextStatus +{ + bool contains(const std::string& str); +}; + +LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLContextStatus& context_status); diff --git a/indra/llcommon/llcleanup.cpp b/indra/llcommon/llcleanup.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c5283507bfc0d8831aeeae7b6a0cff8e0946c2ec --- /dev/null +++ b/indra/llcommon/llcleanup.cpp @@ -0,0 +1,29 @@ +/** + * @file llcleanup.cpp + * @author Nat Goodspeed + * @date 2016-08-30 + * @brief Implementation for llcleanup. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llcleanup.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llerror.h" +#include "llerrorcontrol.h" + +void log_subsystem_cleanup(const char* file, int line, const char* function, + const char* classname) +{ + LL_INFOS("Cleanup") << LLError::abbreviateFile(file) << "(" << line << "): " + << "calling " << classname << "::cleanupClass() in " + << function << LL_ENDL; +} diff --git a/indra/llcommon/llcleanup.h b/indra/llcommon/llcleanup.h new file mode 100644 index 0000000000000000000000000000000000000000..a319171b5f1891d06969585c9f9a75e02ef7149c --- /dev/null +++ b/indra/llcommon/llcleanup.h @@ -0,0 +1,33 @@ +/** + * @file llcleanup.h + * @author Nat Goodspeed + * @date 2015-05-20 + * @brief Mechanism for cleaning up subsystem resources + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Copyright (c) 2015, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLCLEANUP_H) +#define LL_LLCLEANUP_H + +#include <boost/current_function.hpp> + +// Instead of directly calling SomeClass::cleanupClass(), use +// SUBSYSTEM_CLEANUP(SomeClass); +// This logs the call as well as performing it. That gives us a baseline +// subsystem shutdown order against which to compare subsequent dynamic +// shutdown schemes. +#define SUBSYSTEM_CLEANUP(CLASSNAME) \ + do { \ + log_subsystem_cleanup(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \ + CLASSNAME::cleanupClass(); \ + } while (0) +// Use ancient do { ... } while (0) macro trick to permit a block of +// statements with the same syntax as a single statement. + +void log_subsystem_cleanup(const char* file, int line, const char* function, + const char* classname); + +#endif /* ! defined(LL_LLCLEANUP_H) */ diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 19642b0982f4680f7ea459580fb28566e86d54f5..439ff4e628e965da33163f1592d9b432eb16f331 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -31,6 +31,7 @@ #include "llthread.h" #include "lltrace.h" #include "lltracethreadrecorder.h" +#include "llcleanup.h" //static BOOL LLCommon::sAprInitialized = FALSE; @@ -63,11 +64,11 @@ void LLCommon::cleanupClass() sMasterThreadRecorder = NULL; LLTrace::set_master_thread_recorder(NULL); LLThreadSafeRefCount::cleanupThreadSafeRefCount(); - LLTimer::cleanupClass(); + SUBSYSTEM_CLEANUP(LLTimer); if (sAprInitialized) { ll_cleanup_apr(); sAprInitialized = FALSE; } - LLMemory::cleanupClass(); + SUBSYSTEM_CLEANUP(LLMemory); } diff --git a/indra/llcommon/llcoro_get_id.cpp b/indra/llcommon/llcoro_get_id.cpp new file mode 100644 index 0000000000000000000000000000000000000000..24ed1fe0c9f3b4e7208126fe0b55d1105b003f49 --- /dev/null +++ b/indra/llcommon/llcoro_get_id.cpp @@ -0,0 +1,32 @@ +/** + * @file llcoro_get_id.cpp + * @author Nat Goodspeed + * @date 2016-09-03 + * @brief Implementation for llcoro_get_id. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llcoro_get_id.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llcoros.h" + +namespace llcoro +{ + +id get_id() +{ + // An instance of Current can convert to LLCoros::CoroData*, which can + // implicitly convert to void*, which is an llcoro::id. + return LLCoros::Current(); +} + +} // llcoro diff --git a/indra/llcommon/llcoro_get_id.h b/indra/llcommon/llcoro_get_id.h new file mode 100644 index 0000000000000000000000000000000000000000..4c1dca6f191a92a156fc6f0127007133f03b826a --- /dev/null +++ b/indra/llcommon/llcoro_get_id.h @@ -0,0 +1,30 @@ +/** + * @file llcoro_get_id.h + * @author Nat Goodspeed + * @date 2016-09-03 + * @brief Supplement the functionality in llcoro.h. + * + * This is broken out as a separate header file to resolve + * circularity: LLCoros isa LLSingleton, yet LLSingleton machinery + * requires llcoro::get_id(). + * + * Be very suspicious of anyone else #including this header. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLCORO_GET_ID_H) +#define LL_LLCORO_GET_ID_H + +namespace llcoro +{ + +/// Get an opaque, distinct token for the running coroutine (or main). +typedef void* id; +id get_id(); + +} // llcoro + +#endif /* ! defined(LL_LLCORO_GET_ID_H) */ diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index d16bf0160b088e595cf8075bcee88b914d0a9fdc..1e1dfd2602c5e21f07bb4777880b799068612e98 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -38,33 +38,81 @@ #include "llevents.h" #include "llerror.h" #include "stringize.h" +#include "llexception.h" -// do nothing, when we need nothing done +namespace { +void no_op() {} +} // anonymous namespace + +// Do nothing, when we need nothing done. This is a static member of LLCoros +// because CoroData is a private nested class. void LLCoros::no_cleanup(CoroData*) {} // CoroData for the currently-running coroutine. Use a thread_specific_ptr // because each thread potentially has its own distinct pool of coroutines. -// This thread_specific_ptr does NOT own the CoroData object! That's owned by -// LLCoros::mCoros. It merely identifies it. For this reason we instantiate -// it with a no-op cleanup function. -boost::thread_specific_ptr<LLCoros::CoroData> -LLCoros::sCurrentCoro(LLCoros::no_cleanup); +LLCoros::Current::Current() +{ + // Use a function-static instance so this thread_specific_ptr is + // instantiated on demand. Since we happen to know it's consumed by + // LLSingleton, this is likely to happen before the runtime has finished + // initializing module-static data. For the same reason, we can't package + // this pointer in an LLSingleton. + + // This thread_specific_ptr does NOT own the CoroData object! That's owned + // by LLCoros::mCoros. It merely identifies it. For this reason we + // instantiate it with a no-op cleanup function. + static boost::thread_specific_ptr<LLCoros::CoroData> sCurrent(LLCoros::no_cleanup); + + // If this is the first time we're accessing sCurrent for the running + // thread, its get() will be NULL. This could be a problem, in that + // llcoro::get_id() would return the same (NULL) token value for the "main + // coroutine" in every thread, whereas what we really want is a distinct + // value for every distinct stack in the process. So if get() is NULL, + // give it a heap CoroData: this ensures that llcoro::get_id() will return + // distinct values. + // This tactic is "leaky": sCurrent explicitly does not destroy any + // CoroData to which it points, and we do NOT enter these "main coroutine" + // CoroData instances in the LLCoros::mCoros map. They are dummy entries, + // and they will leak at process shutdown: one CoroData per thread. + if (! sCurrent.get()) + { + // It's tempting to provide a distinct name for each thread's "main + // coroutine." But as getName() has always returned the empty string + // to mean "not in a coroutine," empty string should suffice here -- + // and truthfully the additional (thread-safe!) machinery to ensure + // uniqueness just doesn't feel worth the trouble. + // We use a no-op callable and a minimal stack size because, although + // CoroData's constructor in fact initializes its mCoro with a + // coroutine with that stack size, no one ever actually enters it by + // calling mCoro(). + sCurrent.reset(new CoroData(0, // no prev + "", // not a named coroutine + no_op, // no-op callable + 1024)); // stacksize moot + } + + mCurrent = &sCurrent; +} //static LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller) { - CoroData* current = sCurrentCoro.get(); - if (! current) - { - LL_ERRS("LLCoros") << "Calling " << caller << " from non-coroutine context!" << LL_ENDL; - } + CoroData* current = Current(); + // With the dummy CoroData set in LLCoros::Current::Current(), this + // pointer should never be NULL. + llassert_always(current); return *current; } //static LLCoros::coro::self& LLCoros::get_self() { - return *get_CoroData("get_self()").mSelf; + CoroData& current = get_CoroData("get_self()"); + if (! current.mSelf) + { + LL_ERRS("LLCoros") << "Calling get_self() from non-coroutine context!" << LL_ENDL; + } + return *current.mSelf; } //static @@ -79,20 +127,23 @@ bool LLCoros::get_consuming() return get_CoroData("get_consuming()").mConsuming; } -llcoro::Suspending::Suspending(): - mSuspended(LLCoros::sCurrentCoro.get()) +llcoro::Suspending::Suspending() { - // Revert mCurrentCoro to the value it had at the moment we last switched + LLCoros::Current current; + // Remember currently-running coroutine: we're about to suspend it. + mSuspended = current; + // Revert Current to the value it had at the moment we last switched // into this coroutine. - LLCoros::sCurrentCoro.reset(mSuspended->mPrev); + current.reset(mSuspended->mPrev); } llcoro::Suspending::~Suspending() { + LLCoros::Current current; // Okay, we're back, update our mPrev - mSuspended->mPrev = LLCoros::sCurrentCoro.get(); - // and reinstate our sCurrentCoro. - LLCoros::sCurrentCoro.reset(mSuspended); + mSuspended->mPrev = current; + // and reinstate our Current. + current.reset(mSuspended); } LLCoros::LLCoros(): @@ -100,7 +151,11 @@ LLCoros::LLCoros(): // Previously we used // boost::context::guarded_stack_allocator::default_stacksize(); // empirically this is 64KB on Windows and Linux. Try quadrupling. +#if ADDRESS_SIZE == 64 + mStackSize(512*1024) +#else mStackSize(256*1024) +#endif { // Register our cleanup() method for "mainloop" ticks LLEventPumps::instance().obtain("mainloop").listen( @@ -131,9 +186,9 @@ bool LLCoros::cleanup(const LLSD&) if ((previousCount < 5) || !(previousCount % 50)) { if (previousCount < 5) - LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL; + LL_DEBUGS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL; else - LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << "("<< previousCount << ")" << LL_ENDL; + LL_DEBUGS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << "("<< previousCount << ")" << LL_ENDL; } // The erase() call will invalidate its passed iterator value -- @@ -185,9 +240,9 @@ std::string LLCoros::generateDistinctName(const std::string& prefix) const if ((previousCount < 5) || !(previousCount % 50)) { if (previousCount < 5) - LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL; + LL_DEBUGS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL; else - LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << "(" << previousCount << ")" << LL_ENDL; + LL_DEBUGS("LLCoros") << "LLCoros: launching coroutine " << name << "(" << previousCount << ")" << LL_ENDL; } @@ -212,33 +267,43 @@ bool LLCoros::kill(const std::string& name) std::string LLCoros::getName() const { - CoroData* current = sCurrentCoro.get(); - if (! current) - { - // not in a coroutine - return ""; - } - return current->mName; + return Current()->mName; } void LLCoros::setStackSize(S32 stacksize) { - LL_INFOS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL; + LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL; mStackSize = stacksize; } // Top-level wrapper around caller's coroutine callable. This function accepts -// the coroutine library's implicit coro::self& parameter and sets sCurrentSelf -// but does not pass it down to the caller's callable. +// the coroutine library's implicit coro::self& parameter and saves it, but +// does not pass it down to the caller's callable. void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& callable) { // capture the 'self' param in CoroData data->mSelf = &self; // run the code the caller actually wants in the coroutine - callable(); + try + { + callable(); + } + catch (const LLContinueError&) + { + // Any uncaught exception derived from LLContinueError will be caught + // here and logged. This coroutine will terminate but the rest of the + // viewer will carry on. + LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << data->mName)); + } + catch (...) + { + // Any OTHER kind of uncaught exception will cause the viewer to + // crash, hopefully informatively. + CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << data->mName)); + } // This cleanup isn't perfectly symmetrical with the way we initially set - // data->mPrev, but this is our last chance to reset mCurrentCoro. - sCurrentCoro.reset(data->mPrev); + // data->mPrev, but this is our last chance to reset Current. + Current().reset(data->mPrev); } /***************************************************************************** @@ -261,7 +326,7 @@ LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name, mPrev(prev), mName(name), // Wrap the caller's callable in our toplevel() function so we can manage - // sCurrentCoro appropriately at startup and shutdown of each coroutine. + // Current appropriately at startup and shutdown of each coroutine. mCoro(boost::bind(toplevel, _1, this, callable), stacksize), // don't consume events unless specifically directed mConsuming(false), @@ -272,13 +337,13 @@ LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name, std::string LLCoros::launch(const std::string& prefix, const callable_t& callable) { std::string name(generateDistinctName(prefix)); - // pass the current value of sCurrentCoro as previous context - CoroData* newCoro = new CoroData(sCurrentCoro.get(), name, - callable, mStackSize); + Current current; + // pass the current value of Current as previous context + CoroData* newCoro = new CoroData(current, name, callable, mStackSize); // Store it in our pointer map mCoros.insert(name, newCoro); // also set it as current - sCurrentCoro.reset(newCoro); + current.reset(newCoro); /* Run the coroutine until its first wait, then return here */ (newCoro->mCoro)(std::nothrow); return name; diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index 39316ed0e6eeb1e76558a1d0212d0e8695404511..bbe2d22af4e1b09609ff52ea93dee84002267116 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -35,8 +35,10 @@ #include <boost/ptr_container/ptr_map.hpp> #include <boost/function.hpp> #include <boost/thread/tss.hpp> +#include <boost/noncopyable.hpp> #include <string> #include <stdexcept> +#include "llcoro_get_id.h" // for friend declaration // forward-declare helper class namespace llcoro @@ -83,6 +85,7 @@ class Suspending; */ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros> { + LLSINGLETON(LLCoros); public: /// Canonical boost::dcoroutines::coroutine signature we use typedef boost::dcoroutines::coroutine<void()> coro; @@ -173,9 +176,8 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros> class Future; private: - LLCoros(); - friend class LLSingleton<LLCoros>; friend class llcoro::Suspending; + friend llcoro::id llcoro::get_id(); std::string generateDistinctName(const std::string& prefix) const; bool cleanup(const LLSD&); struct CoroData; @@ -222,8 +224,22 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros> typedef boost::ptr_map<std::string, CoroData> CoroMap; CoroMap mCoros; - // identify the current coroutine's CoroData - static boost::thread_specific_ptr<LLCoros::CoroData> sCurrentCoro; + // Identify the current coroutine's CoroData. Use a little helper class so + // a caller can either use a temporary instance, or instantiate a named + // variable and access it multiple times. + class Current + { + public: + Current(); + + operator LLCoros::CoroData*() { return get(); } + LLCoros::CoroData* operator->() { return get(); } + LLCoros::CoroData* get() { return mCurrent->get(); } + void reset(LLCoros::CoroData* ptr) { mCurrent->reset(ptr); } + + private: + boost::thread_specific_ptr<LLCoros::CoroData>* mCurrent; + }; }; namespace llcoro @@ -231,7 +247,7 @@ namespace llcoro /// Instantiate one of these in a block surrounding any leaf point when /// control literally switches away from this coroutine. -class Suspending +class Suspending: boost::noncopyable { public: Suspending(); diff --git a/indra/llcommon/lldependencies.cpp b/indra/llcommon/lldependencies.cpp index 0e72c175cb7dfff13d3f481891173e14ad58ac51..0d5757effddf550c331c91a0b78b9e6267aac27c 100644 --- a/indra/llcommon/lldependencies.cpp +++ b/indra/llcommon/lldependencies.cpp @@ -40,6 +40,7 @@ #include <boost/graph/topological_sort.hpp> #include <boost/graph/exception.hpp> // other Linden headers +#include "llexception.h" LLDependenciesBase::VertexList LLDependenciesBase::topo_sort(int vertices, const EdgeList& edges) const { @@ -76,7 +77,7 @@ LLDependenciesBase::VertexList LLDependenciesBase::topo_sort(int vertices, const // Omit independent nodes: display only those that might contribute to // the cycle. describe(out, false); - throw Cycle(out.str()); + LLTHROW(Cycle(out.str())); } // A peculiarity of boost::topological_sort() is that it emits results in // REVERSE topological order: to get the result you want, you must diff --git a/indra/llcommon/lldependencies.h b/indra/llcommon/lldependencies.h index e0294e271ba472c050d82c87a0212cb684549eaf..db2bbab8b040269e04bec4638b70bea4dd6fa4e4 100644 --- a/indra/llcommon/lldependencies.h +++ b/indra/llcommon/lldependencies.h @@ -34,13 +34,13 @@ #include <vector> #include <set> #include <map> -#include <stdexcept> #include <iosfwd> #include <boost/iterator/transform_iterator.hpp> #include <boost/iterator/indirect_iterator.hpp> #include <boost/range/iterator_range.hpp> #include <boost/function.hpp> #include <boost/bind.hpp> +#include "llexception.h" /***************************************************************************** * Utilities @@ -106,9 +106,9 @@ class LL_COMMON_API LLDependenciesBase /** * Exception thrown by sort() if there's a cycle */ - struct Cycle: public std::runtime_error + struct Cycle: public LLException { - Cycle(const std::string& what): std::runtime_error(what) {} + Cycle(const std::string& what): LLException(what) {} }; /** @@ -124,8 +124,8 @@ class LL_COMMON_API LLDependenciesBase virtual std::string describe(bool full=true) const; protected: - typedef std::vector< std::pair<int, int> > EdgeList; - typedef std::vector<int> VertexList; + typedef std::vector< std::pair<std::size_t, std::size_t> > EdgeList; + typedef std::vector<std::size_t> VertexList; VertexList topo_sort(int vertices, const EdgeList& edges) const; /** @@ -508,7 +508,7 @@ class LLDependencies: public LLDependenciesBase // been explicitly added. Rely on std::map rejecting a second attempt // to insert the same key. Use the map's size() as the vertex number // to get a distinct value for each successful insertion. - typedef std::map<KEY, int> VertexMap; + typedef std::map<KEY, std::size_t> VertexMap; VertexMap vmap; // Nest each of these loops because !@#$%? MSVC warns us that its // former broken behavior has finally been fixed -- and our builds diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 5ed348e13cf178b1a335abe20dd6af1d014163cb..e6407ecf220b0df466bb3542a745df6c1ab415d8 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -238,6 +238,14 @@ namespace { namespace { std::string className(const std::type_info& type) + { + return LLError::Log::demangle(type.name()); + } +} // anonymous + +namespace LLError +{ + std::string Log::demangle(const char* mangled) { #ifdef __GNUC__ // GCC: type_info::name() returns a mangled class name,st demangle @@ -252,31 +260,34 @@ namespace // but gcc 3.3 libstc++'s implementation of demangling is broken // and fails without. - char* name = abi::__cxa_demangle(type.name(), + char* name = abi::__cxa_demangle(mangled, abi_name_buf, &abi_name_len, &status); // this call can realloc the abi_name_buf pointer (!) - return name ? name : type.name(); + return name ? name : mangled; #elif LL_WINDOWS // DevStudio: type_info::name() includes the text "class " at the start static const std::string class_prefix = "class "; - - std::string name = type.name(); - std::string::size_type p = name.find(class_prefix); - if (p == std::string::npos) + std::string name = mangled; + if (0 != name.compare(0, class_prefix.length(), class_prefix)) { + LL_DEBUGS() << "Did not see '" << class_prefix << "' prefix on '" + << name << "'" << LL_ENDL; return name; } - return name.substr(p + class_prefix.size()); + return name.substr(class_prefix.length()); -#else - return type.name(); +#else + return mangled; #endif } +} // LLError +namespace +{ std::string functionName(const std::string& preprocessor_name) { #if LL_WINDOWS @@ -363,9 +374,8 @@ namespace class Globals : public LLSingleton<Globals> { + LLSINGLETON(Globals); public: - Globals(); - std::ostringstream messageStream; bool messageStreamInUse; @@ -438,11 +448,10 @@ namespace LLError class Settings : public LLSingleton<Settings> { + LLSINGLETON(Settings); public: - Settings(); - SettingsConfigPtr getSettingsConfig(); - + void reset(); SettingsStoragePtr saveAndReset(); void restore(SettingsStoragePtr pSettingsStorage); @@ -450,7 +459,7 @@ namespace LLError private: SettingsConfigPtr mSettingsConfig; }; - + SettingsConfig::SettingsConfig() : LLRefCount(), mPrintLocation(false), @@ -475,8 +484,7 @@ namespace LLError mRecorders.clear(); } - Settings::Settings() - : LLSingleton<Settings>(), + Settings::Settings(): mSettingsConfig(new SettingsConfig()) { } @@ -485,26 +493,31 @@ namespace LLError { return mSettingsConfig; } - + void Settings::reset() { Globals::getInstance()->invalidateCallSites(); mSettingsConfig = new SettingsConfig(); } - + SettingsStoragePtr Settings::saveAndReset() { SettingsStoragePtr oldSettingsConfig(mSettingsConfig.get()); reset(); return oldSettingsConfig; } - + void Settings::restore(SettingsStoragePtr pSettingsStorage) { Globals::getInstance()->invalidateCallSites(); SettingsConfigPtr newSettingsConfig(dynamic_cast<SettingsConfig *>(pSettingsStorage.get())); mSettingsConfig = newSettingsConfig; } + + bool is_available() + { + return Settings::instanceExists() && Globals::instanceExists(); + } } namespace LLError @@ -921,11 +934,6 @@ namespace std::ostringstream message_stream; - if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation)) - { - message_stream << site.mLocationString << " "; - } - if (show_time && r->wantsTime() && s->mTimeFunction != NULL) { message_stream << s->mTimeFunction() << " "; @@ -933,17 +941,17 @@ namespace if (show_level && r->wantsLevel()) { - message_stream << site.mLevelString; + message_stream << site.mLevelString << " "; } if (show_tags && r->wantsTags()) { message_stream << site.mTagString; } - if ((show_level && r->wantsLevel())|| - (show_tags && r->wantsTags())) + + if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation)) { - message_stream << " "; + message_stream << site.mLocationString << " "; } if (show_function && r->wantsFunctionName()) @@ -1493,3 +1501,20 @@ namespace LLError } } +bool debugLoggingEnabled(const std::string& tag) +{ + const char* tags[] = {tag.c_str()}; + ::size_t tag_count = 1; + LLError::CallSite _site(LLError::LEVEL_DEBUG, __FILE__, __LINE__, + typeid(_LL_CLASS_TO_LOG), __FUNCTION__, false, tags, tag_count); + if (LL_UNLIKELY(_site.shouldLog())) + { + return true; + } + else + { + return false; + } +} + + diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 3beef657239edcefae14c79128dbe0dcd8ae1c47..ceb1fd2c5f02aaee8685546c9857b0e8b1410bd6 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -174,7 +174,8 @@ namespace LLError // not really a level // used to indicate that no messages should be logged }; - + // If you change ELevel, please update llvlog() macro below. + /* Macro support The classes CallSite and Log are used by the logging macros below. They are not intended for general use. @@ -189,6 +190,7 @@ namespace LLError static std::ostringstream* out(); static void flush(std::ostringstream* out, char* message); static void flush(std::ostringstream*, const CallSite&); + static std::string demangle(const char* mangled); }; struct LL_COMMON_API CallSite @@ -305,24 +307,38 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; ///////////////////////////////// // Error Logging Macros -// See top of file for common usage. +// See top of file for common usage. ///////////////////////////////// -// this macro uses a one-shot do statement to avoid parsing errors when writing control flow statements -// without braces: -// if (condition) LL_INFOS() << "True" << LL_ENDL; else LL_INFOS()() << "False" << LL_ENDL - -#define lllog(level, once, ...) \ - do { \ - const char* tags[] = {"", ##__VA_ARGS__}; \ - ::size_t tag_count = LL_ARRAY_SIZE(tags) - 1; \ - static LLError::CallSite _site( \ - level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), __FUNCTION__, once, &tags[1], tag_count);\ - if (LL_UNLIKELY(_site.shouldLog())) \ - { \ - std::ostringstream* _out = LLError::Log::out(); \ +// Instead of using LL_DEBUGS(), LL_INFOS() et al., it may be tempting to +// directly code the lllog() macro so you can pass in the LLError::ELevel as a +// variable. DON'T DO IT! The reason is that the first time control passes +// through lllog(), it initializes a local static LLError::CallSite with that +// *first* ELevel value. All subsequent visits will decide whether or not to +// emit output based on the *first* ELevel value bound into that static +// CallSite instance. Use LL_VLOGS() instead. lllog() assumes its ELevel +// argument never varies. + +// this macro uses a one-shot do statement to avoid parsing errors when +// writing control flow statements without braces: +// if (condition) LL_INFOS() << "True" << LL_ENDL; else LL_INFOS()() << "False" << LL_ENDL; + +#define lllog(level, once, ...) \ + do { \ + const char* tags[] = {"", ##__VA_ARGS__}; \ + static LLError::CallSite _site(lllog_site_args_(level, once, tags)); \ + lllog_test_() + +#define lllog_test_() \ + if (LL_UNLIKELY(_site.shouldLog())) \ + { \ + std::ostringstream* _out = LLError::Log::out(); \ (*_out) +#define lllog_site_args_(level, once, tags) \ + level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), \ + __FUNCTION__, once, &tags[1], LL_ARRAY_SIZE(tags)-1 + //Use this construct if you need to do computation in the middle of a //message: // @@ -363,4 +379,49 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; #define LL_INFOS_ONCE(...) lllog(LLError::LEVEL_INFO, true, ##__VA_ARGS__) #define LL_WARNS_ONCE(...) lllog(LLError::LEVEL_WARN, true, ##__VA_ARGS__) +// Use this if you need to pass LLError::ELevel as a variable. +#define LL_VLOGS(level, ...) llvlog(level, false, ##__VA_ARGS__) +#define LL_VLOGS_ONCE(level, ...) llvlog(level, true, ##__VA_ARGS__) + +// The problem with using lllog() with a variable level is that the first time +// through, it initializes a static CallSite instance with whatever level you +// pass. That first level is bound into the CallSite; the level parameter is +// never again examined. One approach to variable level would be to +// dynamically construct a CallSite instance every call -- which could get +// expensive, depending on context. So instead, initialize a static CallSite +// for each level value we support, then dynamically select the CallSite +// instance for the passed level value. +// Compare implementation to lllog() above. +#define llvlog(level, once, ...) \ + do { \ + const char* tags[] = {"", ##__VA_ARGS__}; \ + /* Need a static CallSite instance per expected ELevel value. */ \ + /* Since we intend to index this array with the ELevel, */ \ + /* _sites[0] should be ELevel(0), and so on -- avoid using */ \ + /* ELevel symbolic names when initializing -- except for */ \ + /* the last entry, which handles anything beyond the end. */ \ + /* (Commented ELevel value names are from 2016-09-01.) */ \ + /* Passing an ELevel past the end of this array is itself */ \ + /* a fatal error, so ensure the last is LEVEL_ERROR. */ \ + static LLError::CallSite _sites[] = \ + { \ + /* LEVEL_DEBUG */ \ + LLError::CallSite(lllog_site_args_(LLError::ELevel(0), once, tags)), \ + /* LEVEL_INFO */ \ + LLError::CallSite(lllog_site_args_(LLError::ELevel(1), once, tags)), \ + /* LEVEL_WARN */ \ + LLError::CallSite(lllog_site_args_(LLError::ELevel(2), once, tags)), \ + /* LEVEL_ERROR */ \ + LLError::CallSite(lllog_site_args_(LLError::LEVEL_ERROR, once, tags)) \ + }; \ + /* Clamp the passed 'level' to at most last entry */ \ + std::size_t which((std::size_t(level) >= LL_ARRAY_SIZE(_sites)) ? \ + (LL_ARRAY_SIZE(_sites) - 1) : std::size_t(level)); \ + /* selected CallSite *must* be named _site for LL_ENDL */ \ + LLError::CallSite& _site(_sites[which]); \ + lllog_test_() + +// Check at run-time whether logging is enabled, without generating output +bool debugLoggingEnabled(const std::string& tag); + #endif // LL_LLERROR_H diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index 56ac52e5de4edfbb8b5a17c8c34abf4bef779823..56e84f71720fb4537f2c985d72d6160b5b2e0989 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -189,6 +189,11 @@ namespace LLError LL_COMMON_API std::string abbreviateFile(const std::string& filePath); LL_COMMON_API int shouldLogCallCount(); + + // Check whether Globals exists. This should only be used by LLSingleton + // infrastructure to avoid trying to log when our internal LLSingleton is + // unavailable -- circularity ensues. + LL_COMMON_API bool is_available(); }; #endif // LL_LLERRORCONTROL_H diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 2d5f964deb2fa62efe9ee671ae85175e1e0ae568..56367b8f54448ba864e5b1d1fed873150c22d159 100644 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -39,6 +39,7 @@ #include "llerror.h" #include "llcoros.h" #include "llmake.h" +#include "llexception.h" #include "lleventfilter.h" @@ -351,7 +352,7 @@ LLSD errorException(const LLEventWithID& result, const std::string& desc) // returning it, deliver it via exception. if (result.second) { - throw LLErrorEvent(desc, result.first); + LLTHROW(LLErrorEvent(desc, result.first)); } // That way, our caller knows a simple return must be from the reply // pump (pump 0). diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h index 87926c692deae5586a83be90ae7fd42642649703..84827aab4af6140be5834140df1bad2cfb8c32c5 100644 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h @@ -31,10 +31,10 @@ #include <boost/optional.hpp> #include <string> -#include <stdexcept> #include <utility> // std::pair #include "llevents.h" #include "llerror.h" +#include "llexception.h" /** * Like LLListenerOrPumpName, this is a class intended for parameter lists: @@ -234,11 +234,11 @@ LLSD errorException(const LLEventWithID& result, const std::string& desc); * because it's not an error in event processing: rather, this exception * announces an event that bears error information (for some other API). */ -class LL_COMMON_API LLErrorEvent: public std::runtime_error +class LL_COMMON_API LLErrorEvent: public LLException { public: LLErrorEvent(const std::string& what, const LLSD& data): - std::runtime_error(what), + LLException(what), mData(data) {} virtual ~LLErrorEvent() throw() {} diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index 645c29d770c70678f16388dda67438eb64670b9b..97270e4931d7cfc7a0b7196173abffd94a62c728 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -57,6 +57,7 @@ #include "stringize.h" #include "llerror.h" #include "llsdutil.h" +#include "llexception.h" #if LL_MSVC #pragma warning (disable : 4702) #endif @@ -174,7 +175,7 @@ std::string LLEventPumps::registerNew(const LLEventPump& pump, const std::string // Unless we're permitted to tweak it, that's Bad. if (! tweak) { - throw LLEventPump::DupPumpName(std::string("Duplicate LLEventPump name '") + name + "'"); + LLTHROW(LLEventPump::DupPumpName("Duplicate LLEventPump name '" + name + "'")); } // The passed name isn't unique, but we're permitted to tweak it. Find the // first decimal-integer suffix not already taken. The insert() attempt @@ -275,6 +276,8 @@ LLEventPumps::~LLEventPumps() #pragma warning (push) #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally #endif +const std::string LLEventPump::ANONYMOUS = std::string(); + LLEventPump::LLEventPump(const std::string& name, bool tweak): // Register every new instance with LLEventPumps @@ -313,145 +316,162 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL const NameList& after, const NameList& before) { - // Check for duplicate name before connecting listener to mSignal - ConnectionMap::const_iterator found = mConnections.find(name); - // In some cases the user might disconnect a connection explicitly -- or - // might use LLEventTrackable to disconnect implicitly. Either way, we can - // end up retaining in mConnections a zombie connection object that's - // already been disconnected. Such a connection object can't be - // reconnected -- nor, in the case of LLEventTrackable, would we want to - // try, since disconnection happens with the destruction of the listener - // object. That means it's safe to overwrite a disconnected connection - // object with the new one we're attempting. The case we want to prevent - // is only when the existing connection object is still connected. - if (found != mConnections.end() && found->second.connected()) - { - throw DupListenerName(std::string("Attempt to register duplicate listener name '") + name + - "' on " + typeid(*this).name() + " '" + getName() + "'"); - } - // Okay, name is unique, try to reconcile its dependencies. Specify a new - // "node" value that we never use for an mSignal placement; we'll fix it - // later. - DependencyMap::node_type& newNode = mDeps.add(name, -1.0, after, before); - // What if this listener has been added, removed and re-added? In that - // case newNode already has a non-negative value because we never remove a - // listener from mDeps. But keep processing uniformly anyway in case the - // listener was added back with different dependencies. Then mDeps.sort() - // would put it in a different position, and the old newNode placement - // value would be wrong, so we'd have to reassign it anyway. Trust that - // re-adding a listener with the same dependencies is the trivial case for - // mDeps.sort(): it can just replay its cache. - DependencyMap::sorted_range sorted_range; - try - { - // Can we pick an order that works including this new entry? - sorted_range = mDeps.sort(); - } - catch (const DependencyMap::Cycle& e) - { - // No: the new node's after/before dependencies have made mDeps - // unsortable. If we leave the new node in mDeps, it will continue - // to screw up all future attempts to sort()! Pull it out. - mDeps.remove(name); - throw Cycle(std::string("New listener '") + name + "' on " + typeid(*this).name() + - " '" + getName() + "' would cause cycle: " + e.what()); - } - // Walk the list to verify that we haven't changed the order. - float previous = 0.0, myprev = 0.0; - DependencyMap::sorted_iterator mydmi = sorted_range.end(); // need this visible after loop - for (DependencyMap::sorted_iterator dmi = sorted_range.begin(); - dmi != sorted_range.end(); ++dmi) + float nodePosition = 1.0; + + // if the supplied name is empty we are not interested in the ordering mechanism + // and can bypass attempting to find the optimal location to insert the new + // listener. We'll just tack it on to the end. + if (!name.empty()) // should be the same as testing against ANONYMOUS { - // Since we've added the new entry with an invalid placement, - // recognize it and skip it. - if (dmi->first == name) + // Check for duplicate name before connecting listener to mSignal + ConnectionMap::const_iterator found = mConnections.find(name); + // In some cases the user might disconnect a connection explicitly -- or + // might use LLEventTrackable to disconnect implicitly. Either way, we can + // end up retaining in mConnections a zombie connection object that's + // already been disconnected. Such a connection object can't be + // reconnected -- nor, in the case of LLEventTrackable, would we want to + // try, since disconnection happens with the destruction of the listener + // object. That means it's safe to overwrite a disconnected connection + // object with the new one we're attempting. The case we want to prevent + // is only when the existing connection object is still connected. + if (found != mConnections.end() && found->second.connected()) { - // Remember the iterator belonging to our new node, and which - // placement value was 'previous' at that point. - mydmi = dmi; - myprev = previous; - continue; + LLTHROW(DupListenerName("Attempt to register duplicate listener name '" + name + + "' on " + typeid(*this).name() + " '" + getName() + "'")); } - // If the new node has rearranged the existing nodes, we'll find - // that their placement values are no longer in increasing order. - if (dmi->second < previous) + // Okay, name is unique, try to reconcile its dependencies. Specify a new + // "node" value that we never use for an mSignal placement; we'll fix it + // later. + DependencyMap::node_type& newNode = mDeps.add(name, -1.0, after, before); + // What if this listener has been added, removed and re-added? In that + // case newNode already has a non-negative value because we never remove a + // listener from mDeps. But keep processing uniformly anyway in case the + // listener was added back with different dependencies. Then mDeps.sort() + // would put it in a different position, and the old newNode placement + // value would be wrong, so we'd have to reassign it anyway. Trust that + // re-adding a listener with the same dependencies is the trivial case for + // mDeps.sort(): it can just replay its cache. + DependencyMap::sorted_range sorted_range; + try { - // This is another scenario in which we'd better back out the - // newly-added node from mDeps -- but don't do it yet, we want to - // traverse the existing mDeps to report on it! - // Describe the change to the order of our listeners. Copy - // everything but the newest listener to a vector we can sort to - // obtain the old order. - typedef std::vector< std::pair<float, std::string> > SortNameList; - SortNameList sortnames; - for (DependencyMap::sorted_iterator cdmi(sorted_range.begin()), cdmend(sorted_range.end()); - cdmi != cdmend; ++cdmi) + // Can we pick an order that works including this new entry? + sorted_range = mDeps.sort(); + } + catch (const DependencyMap::Cycle& e) + { + // No: the new node's after/before dependencies have made mDeps + // unsortable. If we leave the new node in mDeps, it will continue + // to screw up all future attempts to sort()! Pull it out. + mDeps.remove(name); + LLTHROW(Cycle("New listener '" + name + "' on " + typeid(*this).name() + + " '" + getName() + "' would cause cycle: " + e.what())); + } + // Walk the list to verify that we haven't changed the order. + float previous = 0.0, myprev = 0.0; + DependencyMap::sorted_iterator mydmi = sorted_range.end(); // need this visible after loop + for (DependencyMap::sorted_iterator dmi = sorted_range.begin(); + dmi != sorted_range.end(); ++dmi) + { + // Since we've added the new entry with an invalid placement, + // recognize it and skip it. + if (dmi->first == name) { - if (cdmi->first != name) - { - sortnames.push_back(SortNameList::value_type(cdmi->second, cdmi->first)); - } + // Remember the iterator belonging to our new node, and which + // placement value was 'previous' at that point. + mydmi = dmi; + myprev = previous; + continue; } - std::sort(sortnames.begin(), sortnames.end()); - std::ostringstream out; - out << "New listener '" << name << "' on " << typeid(*this).name() << " '" << getName() - << "' would move previous listener '" << dmi->first << "'\nwas: "; - SortNameList::const_iterator sni(sortnames.begin()), snend(sortnames.end()); - if (sni != snend) + // If the new node has rearranged the existing nodes, we'll find + // that their placement values are no longer in increasing order. + if (dmi->second < previous) { - out << sni->second; - while (++sni != snend) + // This is another scenario in which we'd better back out the + // newly-added node from mDeps -- but don't do it yet, we want to + // traverse the existing mDeps to report on it! + // Describe the change to the order of our listeners. Copy + // everything but the newest listener to a vector we can sort to + // obtain the old order. + typedef std::vector< std::pair<float, std::string> > SortNameList; + SortNameList sortnames; + for (DependencyMap::sorted_iterator cdmi(sorted_range.begin()), cdmend(sorted_range.end()); + cdmi != cdmend; ++cdmi) { - out << ", " << sni->second; + if (cdmi->first != name) + { + sortnames.push_back(SortNameList::value_type(cdmi->second, cdmi->first)); + } } - } - out << "\nnow: "; - DependencyMap::sorted_iterator ddmi(sorted_range.begin()), ddmend(sorted_range.end()); - if (ddmi != ddmend) - { - out << ddmi->first; - while (++ddmi != ddmend) + std::sort(sortnames.begin(), sortnames.end()); + std::ostringstream out; + out << "New listener '" << name << "' on " << typeid(*this).name() << " '" << getName() + << "' would move previous listener '" << dmi->first << "'\nwas: "; + SortNameList::const_iterator sni(sortnames.begin()), snend(sortnames.end()); + if (sni != snend) { - out << ", " << ddmi->first; + out << sni->second; + while (++sni != snend) + { + out << ", " << sni->second; + } } + out << "\nnow: "; + DependencyMap::sorted_iterator ddmi(sorted_range.begin()), ddmend(sorted_range.end()); + if (ddmi != ddmend) + { + out << ddmi->first; + while (++ddmi != ddmend) + { + out << ", " << ddmi->first; + } + } + // NOW remove the offending listener node. + mDeps.remove(name); + // Having constructed a description of the order change, inform caller. + LLTHROW(OrderChange(out.str())); } - // NOW remove the offending listener node. - mDeps.remove(name); - // Having constructed a description of the order change, inform caller. - throw OrderChange(out.str()); + // This node becomes the previous one. + previous = dmi->second; } - // This node becomes the previous one. - previous = dmi->second; - } - // We just got done with a successful mDeps.add(name, ...) call. We'd - // better have found 'name' somewhere in that sorted list! - assert(mydmi != sorted_range.end()); - // Four cases: - // 0. name is the only entry: placement 1.0 - // 1. name is the first of several entries: placement (next placement)/2 - // 2. name is between two other entries: placement (myprev + (next placement))/2 - // 3. name is the last entry: placement ceil(myprev) + 1.0 - // Since we've cleverly arranged for myprev to be 0.0 if name is the - // first entry, this folds down to two cases. Case 1 is subsumed by - // case 2, and case 0 is subsumed by case 3. So we need only handle - // cases 2 and 3, which means we need only detect whether name is the - // last entry. Increment mydmi to see if there's anything beyond. - if (++mydmi != sorted_range.end()) - { - // The new node isn't last. Place it between the previous node and - // the successor. - newNode = (myprev + mydmi->second)/2.f; - } - else - { - // The new node is last. Bump myprev up to the next integer, add - // 1.0 and use that. - newNode = std::ceil(myprev) + 1.f; + // We just got done with a successful mDeps.add(name, ...) call. We'd + // better have found 'name' somewhere in that sorted list! + assert(mydmi != sorted_range.end()); + // Four cases: + // 0. name is the only entry: placement 1.0 + // 1. name is the first of several entries: placement (next placement)/2 + // 2. name is between two other entries: placement (myprev + (next placement))/2 + // 3. name is the last entry: placement ceil(myprev) + 1.0 + // Since we've cleverly arranged for myprev to be 0.0 if name is the + // first entry, this folds down to two cases. Case 1 is subsumed by + // case 2, and case 0 is subsumed by case 3. So we need only handle + // cases 2 and 3, which means we need only detect whether name is the + // last entry. Increment mydmi to see if there's anything beyond. + if (++mydmi != sorted_range.end()) + { + // The new node isn't last. Place it between the previous node and + // the successor. + newNode = (myprev + mydmi->second) / 2.f; + } + else + { + // The new node is last. Bump myprev up to the next integer, add + // 1.0 and use that. + newNode = std::ceil(myprev) + 1.f; + } + + nodePosition = newNode; } // Now that newNode has a value that places it appropriately in mSignal, // connect it. - LLBoundListener bound = mSignal->connect(newNode, listener); - mConnections[name] = bound; + LLBoundListener bound = mSignal->connect(nodePosition, listener); + + if (!name.empty()) + { // note that we are not tracking anonymous listeners here either. + // This means that it is the caller's responsibility to either assign + // to a TempBoundListerer (scoped_connection) or manually disconnect + // when done. + mConnections[name] = bound; + } return bound; } @@ -608,7 +628,7 @@ bool LLListenerOrPumpName::operator()(const LLSD& event) const { if (! mListener) { - throw Empty("attempting to call uninitialized"); + LLTHROW(Empty("attempting to call uninitialized")); } return (*mListener)(event); } diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index ba4fcd766ee594ff2b9c04b2582dc30fa75fb3a5..7cff7dfd4537b99d99c0a83f6753c941375b7000 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -37,7 +37,6 @@ #include <set> #include <vector> #include <deque> -#include <stdexcept> #if LL_WINDOWS #pragma warning (push) #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch @@ -62,6 +61,7 @@ #include "llsingleton.h" #include "lldependencies.h" #include "llstl.h" +#include "llexception.h" /*==========================================================================*| // override this to allow binding free functions with more parameters @@ -95,12 +95,32 @@ struct LLStopWhenHandled result_type operator()(InputIterator first, InputIterator last) const { for (InputIterator si = first; si != last; ++si) - { - if (*si) - { - return true; - } - } + { + try + { + if (*si) + { + return true; + } + } + catch (const LLContinueError&) + { + // We catch LLContinueError here because an LLContinueError- + // based exception means the viewer as a whole should carry on + // to the best of our ability. Therefore subsequent listeners + // on the same LLEventPump should still receive this event. + + // The iterator passed to a boost::signals2 Combiner is very + // clever, but provides no contextual information. We would + // very much like to be able to log the name of the LLEventPump + // plus the name of this particular listener, but alas. + LOG_UNHANDLED_EXCEPTION("LLEventPump"); + } + // We do NOT catch (...) here because we might as well let it + // propagate out to the generic handler. If we were able to log + // context information here, that would be great, but we can't, so + // there's no point. + } return false; } }; @@ -188,10 +208,10 @@ class LL_COMMON_API LLListenerOrPumpName bool operator()(const LLSD& event) const; /// exception if you try to call when empty - struct Empty: public std::runtime_error + struct Empty: public LLException { Empty(const std::string& what): - std::runtime_error(std::string("LLListenerOrPumpName::Empty: ") + what) {} + LLException(std::string("LLListenerOrPumpName::Empty: ") + what) {} }; private: @@ -209,7 +229,7 @@ class LLEventPump; */ class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps> { - friend class LLSingleton<LLEventPumps>; + LLSINGLETON(LLEventPumps); public: /** * Find or create an LLEventPump instance with a specific name. We return @@ -252,7 +272,6 @@ class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps> void unregister(const LLEventPump&); private: - LLEventPumps(); ~LLEventPumps(); testable: @@ -365,16 +384,18 @@ typedef boost::signals2::trackable LLEventTrackable; class LL_COMMON_API LLEventPump: public LLEventTrackable { public: + static const std::string ANONYMOUS; // constant for anonymous listeners. + /** * Exception thrown by LLEventPump(). You are trying to instantiate an * LLEventPump (subclass) using the same name as some other instance, and * you didn't pass <tt>tweak=true</tt> to permit it to generate a unique * variant. */ - struct DupPumpName: public std::runtime_error + struct DupPumpName: public LLException { DupPumpName(const std::string& what): - std::runtime_error(std::string("DupPumpName: ") + what) {} + LLException(std::string("DupPumpName: ") + what) {} }; /** @@ -399,9 +420,9 @@ class LL_COMMON_API LLEventPump: public LLEventTrackable /// group exceptions thrown by listen(). We use exceptions because these /// particular errors are likely to be coding errors, found and fixed by /// the developer even before preliminary checkin. - struct ListenError: public std::runtime_error + struct ListenError: public LLException { - ListenError(const std::string& what): std::runtime_error(what) {} + ListenError(const std::string& what): LLException(what) {} }; /** * exception thrown by listen(). You are attempting to register a @@ -476,6 +497,12 @@ class LL_COMMON_API LLEventPump: public LLEventTrackable * instantiate your listener, then passing the same name on each listen() * call, allows us to optimize away the second and subsequent dependency * sorts. + * + * If name is set to LLEventPump::ANONYMOUS listen will bypass the entire + * dependency and ordering calculation. In this case, it is critical that + * the result be assigned to a LLTempBoundListener or the listener is + * manually disconnected when no longer needed since there will be no + * way to later find and disconnect this listener manually. * * If (as is typical) you pass a <tt>boost::bind()</tt> expression as @a * listener, listen() will inspect the components of that expression. If a diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b32ec2c9c9f067f30a57cb636cf0e98653135429 --- /dev/null +++ b/indra/llcommon/llexception.cpp @@ -0,0 +1,55 @@ +/** + * @file llexception.cpp + * @author Nat Goodspeed + * @date 2016-08-12 + * @brief Implementation for llexception. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llexception.h" +// STL headers +// std headers +#include <typeinfo> +// external library headers +#include <boost/exception/diagnostic_information.hpp> +// other Linden headers +#include "llerror.h" +#include "llerrorcontrol.h" + +namespace { +// used by crash_on_unhandled_exception_() and log_unhandled_exception_() +void log_unhandled_exception_(LLError::ELevel level, + const char* file, int line, const char* pretty_function, + const std::string& context) +{ + // log same message but allow caller-specified severity level + LL_VLOGS(level, "LLException") << LLError::abbreviateFile(file) + << "(" << line << "): Unhandled exception caught in " << pretty_function; + if (! context.empty()) + { + LL_CONT << ": " << context; + } + LL_CONT << ":\n" << boost::current_exception_diagnostic_information() << LL_ENDL; +} +} + +void crash_on_unhandled_exception_(const char* file, int line, const char* pretty_function, + const std::string& context) +{ + // LL_ERRS() terminates and propagates message into crash dump. + log_unhandled_exception_(LLError::LEVEL_ERROR, file, line, pretty_function, context); +} + +void log_unhandled_exception_(const char* file, int line, const char* pretty_function, + const std::string& context) +{ + // Use LL_WARNS() because we seriously do not expect this to happen + // routinely, but we DO expect to return from this function. + log_unhandled_exception_(LLError::LEVEL_WARN, file, line, pretty_function, context); +} diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h new file mode 100644 index 0000000000000000000000000000000000000000..dfcb7c192fee966fed022ae2e365c4a81529763b --- /dev/null +++ b/indra/llcommon/llexception.h @@ -0,0 +1,85 @@ +/** + * @file llexception.h + * @author Nat Goodspeed + * @date 2016-06-29 + * @brief Types needed for generic exception handling + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLEXCEPTION_H) +#define LL_LLEXCEPTION_H + +#include <stdexcept> +#include <boost/exception/exception.hpp> +#include <boost/throw_exception.hpp> +#include <boost/current_function.hpp> + +// "Found someone who can comfort me +// But there are always exceptions..." +// - Empty Pages, Traffic, from John Barleycorn (1970) +// https://www.youtube.com/watch?v=dRH0CGVK7ic + +/** + * LLException is intended as the common base class from which all + * viewer-specific exceptions are derived. Rationale for why it's derived from + * both std::exception and boost::exception is explained in + * tests/llexception_test.cpp. + * + * boost::current_exception_diagnostic_information() is quite wonderful: if + * all we need to do with an exception is log it, in most places we should + * catch (...) and log boost::current_exception_diagnostic_information(). + * See CRASH_ON_UNHANDLED_EXCEPTION() and LOG_UNHANDLED_EXCEPTION() below. + * + * There may be circumstances in which it would be valuable to distinguish an + * exception explicitly thrown by viewer code from an exception thrown by + * (say) a third-party library. Catching (const LLException&) supports such + * usage. However, most of the value of this base class is in the + * diagnostic_information() available via Boost.Exception. + */ +struct LLException: + public std::runtime_error, + public boost::exception +{ + LLException(const std::string& what): + std::runtime_error(what) + {} +}; + +/** + * The point of LLContinueError is to distinguish exceptions that need not + * terminate the whole viewer session. In general, an uncaught exception will + * be logged and will crash the viewer. However, though an uncaught exception + * derived from LLContinueError will still be logged, the viewer will attempt + * to continue processing. + */ +struct LLContinueError: public LLException +{ + LLContinueError(const std::string& what): + LLException(what) + {} +}; + +/** + * Please use LLTHROW() to throw viewer exceptions whenever possible. This + * enriches the exception's diagnostic_information() with the source file, + * line and containing function of the LLTHROW() macro. + */ +// Currently we implement that using BOOST_THROW_EXCEPTION(). Wrap it in +// LLTHROW() in case we ever want to revisit that implementation decision. +#define LLTHROW(x) BOOST_THROW_EXCEPTION(x) + +/// Call this macro from a catch (...) clause +#define CRASH_ON_UNHANDLED_EXCEPTION(CONTEXT) \ + crash_on_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT) +void crash_on_unhandled_exception_(const char*, int, const char*, const std::string&); + +/// Call this from a catch (const LLContinueError&) clause, or from a catch +/// (...) clause in which you do NOT want the viewer to crash. +#define LOG_UNHANDLED_EXCEPTION(CONTEXT) \ + log_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT) +void log_unhandled_exception_(const char*, int, const char*, const std::string&); + +#endif /* ! defined(LL_LLEXCEPTION_H) */ diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 237025307843de532441cb8416c41f13dd190414..2024d707da5d3a0bbfe1e2a89a6dffe5b69cafdc 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -90,33 +90,15 @@ class BlockTimer #if LL_FASTTIMER_USE_RDTSC static U32 getCPUClockCount32() { - U32 ret_val; - __asm - { - _emit 0x0f - _emit 0x31 - shr eax,8 - shl edx,24 - or eax, edx - mov dword ptr [ret_val], eax - } - return ret_val; + unsigned __int64 val = __rdtsc(); + val = val >> 8; + return static_cast<U32>(val); } // return full timer value, *not* shifted by 8 bits static U64 getCPUClockCount64() { - U64 ret_val; - __asm - { - _emit 0x0f - _emit 0x31 - mov eax,eax - mov edx,edx - mov dword ptr [ret_val+4], edx - mov dword ptr [ret_val], eax - } - return ret_val; + return static_cast<U64>( __rdtsc() ); } #else @@ -173,16 +155,16 @@ class BlockTimer // Mac+Linux+Solaris FAST x86 implementation of CPU clock static U32 getCPUClockCount32() { - U64 x; - __asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); - return (U32)(x >> 8); + U32 low(0),high(0); + __asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) ); + return (low>>8) | (high<<24); } static U64 getCPUClockCount64() { - U64 x; - __asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); - return x; + U32 low(0),high(0); + __asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) ); + return (U64)low | ( ((U64)high) << 32); } #endif @@ -296,7 +278,16 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(BlockTimerStatHandle& timer) { #if LL_FAST_TIMER_ON BlockTimerStackRecord* cur_timer_data = LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance(); - if (!cur_timer_data) return; + if (!cur_timer_data) + { + // How likely is it that + // LLThreadLocalSingletonPointer<T>::getInstance() will return NULL? + // Even without researching, what we can say is that if we exit + // without setting mStartTime at all, gcc 4.7 produces (fatal) + // warnings about a possibly-uninitialized data member. + mStartTime = 0; + return; + } TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator(); accumulator.mActiveCount++; // keep current parent as long as it is active when we are diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 873a7bce25f5efacb8225d052be18d2a9a1aa73b..7b559861bb71696dabc19a912e5b8fc11b230d7a 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -239,7 +239,7 @@ int LLFile::close(LLFILE * file) } -int LLFile::remove(const std::string& filename) +int LLFile::remove(const std::string& filename, int supress_error) { #if LL_WINDOWS std::string utf8filename = filename; @@ -248,7 +248,7 @@ int LLFile::remove(const std::string& filename) #else int rc = ::remove(filename.c_str()); #endif - return warnif("remove", filename, rc); + return warnif("remove", filename, rc, supress_error); } int LLFile::rename(const std::string& filename, const std::string& newname) diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 3e25228aeb31bb47e1220503c13ba2954b920b30..37eb75881c2c4e8ec4449ecc1871a5bdba696d0f 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -45,7 +45,7 @@ typedef FILE LLFILE; typedef struct _stat llstat; #else typedef struct stat llstat; -#include <bits/postypes.h> +#include <sys/types.h> #endif #ifndef S_ISREG @@ -72,7 +72,7 @@ class LL_COMMON_API LLFile static int mkdir(const std::string& filename, int perms = 0700); static int rmdir(const std::string& filename); - static int remove(const std::string& filename); + static int remove(const std::string& filename, int supress_error = 0); static int rename(const std::string& filename,const std::string& newname); static bool copy(const std::string from, const std::string to); diff --git a/indra/llcommon/llhandle.h b/indra/llcommon/llhandle.h index 401e4d759ae048a43b07e618248bd9e83434f145..feb5f418489e5b401eff95591ba4dd0fc31dbd66 100644 --- a/indra/llcommon/llhandle.h +++ b/indra/llcommon/llhandle.h @@ -28,8 +28,11 @@ #define LLHANDLE_H #include "llpointer.h" +#include "llexception.h" +#include <stdexcept> #include <boost/type_traits/is_convertible.hpp> #include <boost/utility/enable_if.hpp> +#include <boost/throw_exception.hpp> /** * Helper object for LLHandle. Don't instantiate these directly, used @@ -213,4 +216,82 @@ class LLHandleProvider mutable LLRootHandle<T> mHandle; }; + + +class LLCheckedHandleBase +{ +public: + class Stale : public LLException + { + public: + Stale() : + LLException("Attempt to access stale handle.") + {} + }; + +protected: + LLCheckedHandleBase() { } + +}; + +/** + * This is a simple wrapper for Handles, allowing direct calls to the underlying + * pointer. The checked handle will throw a Stale if an attempt + * is made to access the object referenced by the handle and that object has + * been destroyed. + **/ +template <typename T> +class LLCheckedHandle: public LLCheckedHandleBase +{ +public: + + LLCheckedHandle(LLHandle<T> handle): + mHandle(handle) + { } + + /** + * Test the underlying handle. If it is no longer valid, throw a Stale exception. + */ + void check() const + { + T* ptr = mHandle.get(); + if (!ptr) + BOOST_THROW_EXCEPTION(Stale()); + } + + /** + * Cast back to an appropriate handle + */ + operator LLHandle<T>() const + { + return mHandle; + } + + /** + * Converts the LLCheckedHandle to a bool. Allows for if (chkdHandle) {} + * Does not throw. + */ + /*explicit*/ operator bool() const // explicit conversion operator not available with Linux compiler + { + return (mHandle.get() != NULL); + } + + /** + * Attempt to call a method or access a member in the structure referenced + * by the handle. If the handle no longer points to a valid structure + * throw a Stale. + */ + T* operator ->() const + { + T* ptr = mHandle.get(); + if (!ptr) + BOOST_THROW_EXCEPTION(Stale()); + return ptr; + } + +private: + + LLHandle<T> mHandle; +}; + #endif diff --git a/indra/llcommon/llheteromap.cpp b/indra/llcommon/llheteromap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7c19196e0c17607a61c03525eb99093fe6dd6724 --- /dev/null +++ b/indra/llcommon/llheteromap.cpp @@ -0,0 +1,32 @@ +/** + * @file llheteromap.cpp + * @author Nat Goodspeed + * @date 2016-10-12 + * @brief Implementation for llheteromap. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llheteromap.h" +// STL headers +// std headers +// external library headers +// other Linden headers + +LLHeteroMap::~LLHeteroMap() +{ + // For each entry in our map, we must call its deleter, which is the only + // record we have of its original type. + for (TypeMap::iterator mi(mMap.begin()), me(mMap.end()); mi != me; ++mi) + { + // mi->second is the std::pair; mi->second.first is the void*; + // mi->second.second points to the deleter function + (mi->second.second)(mi->second.first); + mi->second.first = NULL; + } +} diff --git a/indra/llcommon/llheteromap.h b/indra/llcommon/llheteromap.h new file mode 100644 index 0000000000000000000000000000000000000000..7e96172333293340840af4b9b0e1ad2ccb3fb914 --- /dev/null +++ b/indra/llcommon/llheteromap.h @@ -0,0 +1,95 @@ +/** + * @file llheteromap.h + * @author Nat Goodspeed + * @date 2016-10-12 + * @brief Map capable of storing objects of diverse types, looked up by type. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLHETEROMAP_H) +#define LL_LLHETEROMAP_H + +#include <typeinfo> +#include <utility> // std::pair +#include <map> + +/** + * LLHeteroMap addresses an odd requirement. Usually when you want to put + * objects of different classes into a runtime collection of any kind, you + * derive them all from a common base class and store pointers to that common + * base class. + * + * LLInitParam::BaseBlock uses disturbing raw-pointer arithmetic to find data + * members in its subclasses. It seems that no BaseBlock subclass can be + * stored in a polymorphic class of any kind: the presence of a vtbl pointer + * in the layout silently throws off the reinterpret_cast arithmetic. Bad + * Things result. (Many thanks to Nicky D for this analysis!) + * + * LLHeteroMap collects objects WITHOUT a common base class, retrieves them by + * object type and destroys them when the LLHeteroMap is destroyed. + */ +class LLHeteroMap +{ +public: + ~LLHeteroMap(); + + /// find or create + template <class T> + T& obtain() + { + // Look up map entry by typeid(T). We don't simply use mMap[typeid(T)] + // because that requires default-constructing T on every lookup. For + // some kinds of T, that could be expensive. + TypeMap::iterator found = mMap.find(&typeid(T)); + if (found == mMap.end()) + { + // Didn't find typeid(T). Create an entry. Because we're storing + // only a void* in the map, discarding type information, make sure + // we capture that type information in our deleter. + void* ptr = new T(); + void (*dlfn)(void*) = &deleter<T>; + std::pair<TypeMap::iterator, bool> inserted = + mMap.insert(TypeMap::value_type(&typeid(T), + TypeMap::mapped_type(ptr, dlfn))); + // Okay, now that we have an entry, claim we found it. + found = inserted.first; + } + // found->second is the std::pair; second.first is the void* + // pointer to the object in question. Cast it to correct type and + // dereference it. + return *(static_cast<T*>(found->second.first)); + } + +private: + template <class T> + static + void deleter(void* p) + { + delete static_cast<T*>(p); + } + + // Comparing two std::type_info* values is tricky, because the standard + // does not guarantee that there will be only one type_info instance for a + // given type. In other words, &typeid(A) in one part of the program may + // not always equal &typeid(A) in some other part. Use special comparator. + struct type_info_ptr_comp + { + bool operator()(const std::type_info* lhs, const std::type_info* rhs) const + { + return lhs->before(*rhs); + } + }; + + // What we actually store is a map from std::type_info (permitting lookup + // by object type) to a void* pointer to the object PLUS its deleter. + typedef std::map< + const std::type_info*, std::pair<void*, void (*)(void*)>, + type_info_ptr_comp> + TypeMap; + TypeMap mMap; +}; + +#endif /* ! defined(LL_LLHETEROMAP_H) */ diff --git a/indra/llcommon/llinitdestroyclass.cpp b/indra/llcommon/llinitdestroyclass.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e6382a79249bf445638ca712a84a5cebeadc2f09 --- /dev/null +++ b/indra/llcommon/llinitdestroyclass.cpp @@ -0,0 +1,30 @@ +/** + * @file llinitdestroyclass.cpp + * @author Nat Goodspeed + * @date 2016-08-30 + * @brief Implementation for llinitdestroyclass. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llinitdestroyclass.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llerror.h" + +void LLCallbackRegistry::fireCallbacks() const +{ + for (FuncList::const_iterator fi = mCallbacks.begin(), fe = mCallbacks.end(); + fi != fe; ++fi) + { + LL_INFOS("LLInitDestroyClass") << "calling " << fi->first << "()" << LL_ENDL; + fi->second(); + } +} diff --git a/indra/llcommon/llinitdestroyclass.h b/indra/llcommon/llinitdestroyclass.h new file mode 100644 index 0000000000000000000000000000000000000000..5f979614fe0ee94b4b8036d983a1006ae1d507ee --- /dev/null +++ b/indra/llcommon/llinitdestroyclass.h @@ -0,0 +1,175 @@ +/** + * @file llinitdestroyclass.h + * @author Nat Goodspeed + * @date 2015-05-27 + * @brief LLInitClass / LLDestroyClass mechanism + * + * The LLInitClass template, extracted from llui.h, ensures that control will + * reach a static initClass() method. LLDestroyClass does the same for a + * static destroyClass() method. + * + * The distinguishing characteristics of these templates are: + * + * - All LLInitClass<T>::initClass() methods are triggered by an explicit call + * to LLInitClassList::instance().fireCallbacks(). Presumably this call + * happens sometime after all static objects in the program have been + * initialized. In other words, each LLInitClass<T>::initClass() method + * should be able to make some assumptions about global program state. + * + * - Similarly, LLDestroyClass<T>::destroyClass() methods are triggered by + * LLDestroyClassList::instance().fireCallbacks(). Again, presumably this + * happens at a well-defined moment in the program's shutdown sequence. + * + * - The initClass() calls happen in an unspecified sequence. You may not rely + * on the relative ordering of LLInitClass<T>::initClass() versus another + * LLInitClass<U>::initClass() method. If you need such a guarantee, use + * LLSingleton instead and make the dependency explicit. + * + * - Similarly, LLDestroyClass<T>::destroyClass() may happen either before or + * after LLDestroyClass<U>::destroyClass(). You cannot rely on that order. + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Copyright (c) 2015, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLINITDESTROYCLASS_H) +#define LL_LLINITDESTROYCLASS_H + +#include "llsingleton.h" +#include <boost/function.hpp> +#include <typeinfo> +#include <vector> +#include <utility> // std::pair + +/** + * LLCallbackRegistry is an implementation detail base class for + * LLInitClassList and LLDestroyClassList. It accumulates the initClass() or + * destroyClass() callbacks for registered classes. + */ +class LLCallbackRegistry +{ +public: + typedef boost::function<void()> func_t; + + void registerCallback(const std::string& name, const func_t& func) + { + mCallbacks.push_back(FuncList::value_type(name, func)); + } + + void fireCallbacks() const; + +private: + // Arguably this should be a boost::signals2::signal, which is, after all, + // a sequence of callables. We manage it by hand so we can log a name for + // each registered function we call. + typedef std::vector< std::pair<std::string, func_t> > FuncList; + FuncList mCallbacks; +}; + +/** + * LLInitClassList is the LLCallbackRegistry for LLInitClass. It stores the + * registered initClass() methods. It must be an LLSingleton because + * LLInitClass registers its initClass() method at static construction time + * (before main()), requiring LLInitClassList to be fully constructed on + * demand regardless of module initialization order. + */ +class LLInitClassList : + public LLCallbackRegistry, + public LLSingleton<LLInitClassList> +{ + LLSINGLETON_EMPTY_CTOR(LLInitClassList); +}; + +/** + * LLDestroyClassList is the LLCallbackRegistry for LLDestroyClass. It stores + * the registered destroyClass() methods. It must be an LLSingleton because + * LLDestroyClass registers its destroyClass() method at static construction + * time (before main()), requiring LLDestroyClassList to be fully constructed + * on demand regardless of module initialization order. + */ +class LLDestroyClassList : + public LLCallbackRegistry, + public LLSingleton<LLDestroyClassList> +{ + LLSINGLETON_EMPTY_CTOR(LLDestroyClassList); +}; + +/** + * LLRegisterWith is an implementation detail for LLInitClass and + * LLDestroyClass. It is intended to be used as a static class member whose + * constructor registers the specified callback with the LLMumbleClassList + * singleton registry specified as the template argument. + */ +template<typename T> +class LLRegisterWith +{ +public: + LLRegisterWith(const std::string& name, const LLCallbackRegistry::func_t& func) + { + T::instance().registerCallback(name, func); + } + + // this avoids a MSVC bug where non-referenced static members are "optimized" away + // even if their constructors have side effects + S32 reference() + { + S32 dummy; + dummy = 0; + return dummy; + } +}; + +/** + * Derive MyClass from LLInitClass<MyClass> (the Curiously Recurring Template + * Pattern) to ensure that the static method MyClass::initClass() will be + * called (along with all other LLInitClass<T> subclass initClass() methods) + * when someone calls LLInitClassList::instance().fireCallbacks(). This gives + * the application specific control over the timing of all such + * initializations, without having to insert calls for every such class into + * generic application code. + */ +template<typename T> +class LLInitClass +{ +public: + LLInitClass() { sRegister.reference(); } + + // When this static member is initialized, the subclass initClass() method + // is registered on LLInitClassList. See sRegister definition below. + static LLRegisterWith<LLInitClassList> sRegister; +}; + +/** + * Derive MyClass from LLDestroyClass<MyClass> (the Curiously Recurring + * Template Pattern) to ensure that the static method MyClass::destroyClass() + * will be called (along with other LLDestroyClass<T> subclass destroyClass() + * methods) when someone calls LLDestroyClassList::instance().fireCallbacks(). + * This gives the application specific control over the timing of all such + * cleanup calls, without having to insert calls for every such class into + * generic application code. + */ +template<typename T> +class LLDestroyClass +{ +public: + LLDestroyClass() { sRegister.reference(); } + + // When this static member is initialized, the subclass destroyClass() + // method is registered on LLInitClassList. See sRegister definition + // below. + static LLRegisterWith<LLDestroyClassList> sRegister; +}; + +// Here's where LLInitClass<T> specifies the subclass initClass() method. +template <typename T> +LLRegisterWith<LLInitClassList> +LLInitClass<T>::sRegister(std::string(typeid(T).name()) + "::initClass", + &T::initClass); +// Here's where LLDestroyClass<T> specifies the subclass destroyClass() method. +template <typename T> +LLRegisterWith<LLDestroyClassList> +LLDestroyClass<T>::sRegister(std::string(typeid(T).name()) + "::destroyClass", + &T::destroyClass); + +#endif /* ! defined(LL_LLINITDESTROYCLASS_H) */ diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp index aa2f4eb289b5e3e47d09f1cb99bb05ebc3274287..1d104cf55df6666f468171ff1a505dfa6995b683 100644 --- a/indra/llcommon/llinitparam.cpp +++ b/indra/llcommon/llinitparam.cpp @@ -193,7 +193,12 @@ namespace LLInitParam { if (!silent) { - p.parserWarning(llformat("Failed to parse parameter \"%s\"", p.getCurrentElementName().c_str())); + std::string file_name = p.getCurrentFileName(); + if(!file_name.empty()) + { + file_name = "in file: " + file_name; + } + p.parserWarning(llformat("Failed to parse parameter \"%s\" %s", p.getCurrentElementName().c_str(), file_name.c_str())); } return false; } diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index c65b05f610a78760e1f4b1557d1a7851f1d5ec76..f1f4226c409612b578803c7484ec817c03ae60da 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -551,6 +551,7 @@ namespace LLInitParam } virtual std::string getCurrentElementName() = 0; + virtual std::string getCurrentFileName() = 0; virtual void parserWarning(const std::string& message); virtual void parserError(const std::string& message); void setParseSilently(bool silent) { mParseSilently = silent; } diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index 84d2a12f657364de4c170673bdeda1bb2b88a209..c87d2a3e588c87a6ee6a2e8a3dd808b1d540d116 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -33,6 +33,7 @@ #include "lltimer.h" #include "lluuid.h" #include "llleaplistener.h" +#include "llexception.h" #if LL_MSVC #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally @@ -69,7 +70,7 @@ class LLLeapImpl: public LLLeap // Rule out empty vector if (plugin.empty()) { - throw Error("no plugin command"); + LLTHROW(Error("no plugin command")); } // Don't leave desc empty either, but in this case, if we weren't @@ -112,7 +113,7 @@ class LLLeapImpl: public LLLeap // If that didn't work, no point in keeping this LLLeap object. if (! mChild) { - throw Error(STRINGIZE("failed to run " << mDesc)); + LLTHROW(Error(STRINGIZE("failed to run " << mDesc))); } // Okay, launch apparently worked. Change our mDonePump listener. diff --git a/indra/llcommon/llleap.h b/indra/llcommon/llleap.h index e33f25e530957fb52943c91ed429b8912b043520..8aac8a64c578e243f2ec74bbfaa434e7d301812c 100644 --- a/indra/llcommon/llleap.h +++ b/indra/llcommon/llleap.h @@ -13,9 +13,9 @@ #define LL_LLLEAP_H #include "llinstancetracker.h" +#include "llexception.h" #include <string> #include <vector> -#include <stdexcept> /** * LLSD Event API Plugin class. Because instances are managed by @@ -67,9 +67,9 @@ class LL_COMMON_API LLLeap: public LLInstanceTracker<LLLeap> * string(s) passed to create() might come from an external source. This * way the caller can catch LLLeap::Error and try to recover. */ - struct Error: public std::runtime_error + struct Error: public LLException { - Error(const std::string& what): std::runtime_error(what) {} + Error(const std::string& what): LLException(what) {} }; virtual ~LLLeap(); diff --git a/indra/llcommon/llmake.h b/indra/llcommon/llmake.h index 9a662a06408a3af5a9805bb409c8ac6b3f593e78..08744f90fb532f7ec0c3d314adf8fe7066778458 100644 --- a/indra/llcommon/llmake.h +++ b/indra/llcommon/llmake.h @@ -12,12 +12,10 @@ * * also relevant: * - * Template parameter deduction for constructors - * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0091r0.html - * - * https://github.com/viboes/std-make - * - * but obviously we're not there yet. + * Template argument deduction for class templates + * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html + * was apparently adopted in June 2016? Unclear when compilers will + * portably support this, but there is hope. * * $LicenseInfo:firstyear=2015&license=viewerlgpl$ * Copyright (c) 2015, Linden Research, Inc. diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 3a8eabac09af4d6d1ce6485a19159b6a03d35fc5..1e04044269ff6cc6a1bc41935261b6dc1a60ef19 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -591,7 +591,7 @@ char* LLPrivateMemoryPool::LLMemoryBlock::allocate() void LLPrivateMemoryPool::LLMemoryBlock::freeMem(void* addr) { //bit index - U32 idx = ((U32)addr - (U32)mBuffer - mDummySize) / mSlotSize ; + uintptr_t idx = ((uintptr_t)addr - (uintptr_t)mBuffer - mDummySize) / mSlotSize ; U32* bits = &mUsageBits ; if(idx >= 32) @@ -773,7 +773,7 @@ char* LLPrivateMemoryPool::LLMemoryChunk::allocate(U32 size) void LLPrivateMemoryPool::LLMemoryChunk::freeMem(void* addr) { - U32 blk_idx = getPageIndex((U32)addr) ; + U32 blk_idx = getPageIndex((uintptr_t)addr) ; LLMemoryBlock* blk = (LLMemoryBlock*)(mMetaBuffer + blk_idx * sizeof(LLMemoryBlock)) ; blk = blk->mSelf ; @@ -798,7 +798,7 @@ bool LLPrivateMemoryPool::LLMemoryChunk::empty() bool LLPrivateMemoryPool::LLMemoryChunk::containsAddress(const char* addr) const { - return (U32)mBuffer <= (U32)addr && (U32)mBuffer + mBufferSize > (U32)addr ; + return (uintptr_t)mBuffer <= (uintptr_t)addr && (uintptr_t)mBuffer + mBufferSize > (uintptr_t)addr ; } //debug use @@ -831,13 +831,13 @@ void LLPrivateMemoryPool::LLMemoryChunk::dump() for(U32 i = 1 ; i < blk_list.size(); i++) { total_size += blk_list[i]->getBufferSize() ; - if((U32)blk_list[i]->getBuffer() < (U32)blk_list[i-1]->getBuffer() + blk_list[i-1]->getBufferSize()) + if((uintptr_t)blk_list[i]->getBuffer() < (uintptr_t)blk_list[i-1]->getBuffer() + blk_list[i-1]->getBufferSize()) { LL_ERRS() << "buffer corrupted." << LL_ENDL ; } } - llassert_always(total_size + mMinBlockSize >= mBufferSize - ((U32)mDataBuffer - (U32)mBuffer)) ; + llassert_always(total_size + mMinBlockSize >= mBufferSize - ((uintptr_t)mDataBuffer - (uintptr_t)mBuffer)) ; U32 blk_num = (mBufferSize - (mDataBuffer - mBuffer)) / mMinBlockSize ; for(U32 i = 0 ; i < blk_num ; ) @@ -860,7 +860,7 @@ void LLPrivateMemoryPool::LLMemoryChunk::dump() #endif #if 0 LL_INFOS() << "---------------------------" << LL_ENDL ; - LL_INFOS() << "Chunk buffer: " << (U32)getBuffer() << " size: " << getBufferSize() << LL_ENDL ; + LL_INFOS() << "Chunk buffer: " << (uintptr_t)getBuffer() << " size: " << getBufferSize() << LL_ENDL ; LL_INFOS() << "available blocks ... " << LL_ENDL ; for(S32 i = 0 ; i < mBlockLevels ; i++) @@ -868,7 +868,7 @@ void LLPrivateMemoryPool::LLMemoryChunk::dump() LLMemoryBlock* blk = mAvailBlockList[i] ; while(blk) { - LL_INFOS() << "blk buffer " << (U32)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ; + LL_INFOS() << "blk buffer " << (uintptr_t)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ; blk = blk->mNext ; } } @@ -879,7 +879,7 @@ void LLPrivateMemoryPool::LLMemoryChunk::dump() LLMemoryBlock* blk = mFreeSpaceList[i] ; while(blk) { - LL_INFOS() << "blk buffer " << (U32)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ; + LL_INFOS() << "blk buffer " << (uintptr_t)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ; blk = blk->mNext ; } } @@ -1155,9 +1155,9 @@ void LLPrivateMemoryPool::LLMemoryChunk::addToAvailBlockList(LLMemoryBlock* blk) return ; } -U32 LLPrivateMemoryPool::LLMemoryChunk::getPageIndex(U32 addr) +U32 LLPrivateMemoryPool::LLMemoryChunk::getPageIndex(uintptr_t addr) { - return (addr - (U32)mDataBuffer) / mMinBlockSize ; + return (addr - (uintptr_t)mDataBuffer) / mMinBlockSize ; } //for mAvailBlockList @@ -1495,7 +1495,7 @@ void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk) U16 LLPrivateMemoryPool::findHashKey(const char* addr) { - return (((U32)addr) / CHUNK_SIZE) % mHashFactor ; + return (((uintptr_t)addr) / CHUNK_SIZE) % mHashFactor ; } LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::findChunk(const char* addr) @@ -1720,7 +1720,7 @@ LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager() S32 k = 0 ; for(mem_allocation_info_t::iterator iter = sMemAllocationTracker.begin() ; iter != sMemAllocationTracker.end() ; ++iter) { - LL_INFOS() << k++ << ", " << (U32)iter->first << " : " << iter->second << LL_ENDL ; + LL_INFOS() << k++ << ", " << (uintptr_t)iter->first << " : " << iter->second << LL_ENDL ; } sMemAllocationTracker.clear() ; } diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 0fb257aab1dbe6d89340c5831045928f6779e782..5a3c9bd762f45d8521044b3da09b5a9edf0aed87 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -110,11 +110,15 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) #if defined(LL_WINDOWS) return _aligned_malloc(size, align); #else + char* aligned = NULL; void* mem = malloc( size + (align - 1) + sizeof(void*) ); - char* aligned = ((char*)mem) + sizeof(void*); - aligned += align - ((uintptr_t)aligned & (align - 1)); + if (mem) + { + aligned = ((char*)mem) + sizeof(void*); + aligned += align - ((uintptr_t)aligned & (align - 1)); - ((void**)aligned)[-1] = mem; + ((void**)aligned)[-1] = mem; + } return aligned; #endif } @@ -134,7 +138,6 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) //------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------ -#if !LL_USE_TCMALLOC inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). { #if defined(LL_WINDOWS) @@ -183,13 +186,6 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // r #endif } -#else // USE_TCMALLOC -// ll_aligned_foo_16 are not needed with tcmalloc -#define ll_aligned_malloc_16 malloc -#define ll_aligned_realloc_16(a,b,c) realloc(a,b) -#define ll_aligned_free_16 free -#endif // USE_TCMALLOC - inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32(). { #if defined(LL_WINDOWS) @@ -419,7 +415,7 @@ class LL_COMMON_API LLPrivateMemoryPool { bool operator()(const LLMemoryBlock* const& lhs, const LLMemoryBlock* const& rhs) { - return (U32)lhs->getBuffer() < (U32)rhs->getBuffer(); + return (uintptr_t)lhs->getBuffer() < (uintptr_t)rhs->getBuffer(); } }; }; @@ -450,7 +446,7 @@ class LL_COMMON_API LLPrivateMemoryPool void dump() ; private: - U32 getPageIndex(U32 addr) ; + U32 getPageIndex(uintptr_t addr) ; U32 getBlockLevel(U32 size) ; U16 getPageLevel(U32 size) ; LLMemoryBlock* addBlock(U32 blk_idx) ; diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 1fc821d9a9622c3cb589ff7ec7b85770fea9cbc6..16fc365da1be7ec9d773181bd43611ae6279d90b 100644 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -40,7 +40,7 @@ LLMetricPerformanceTesterBasic::name_tester_map_t LLMetricPerformanceTesterBasic::sTesterMap ; /*static*/ -void LLMetricPerformanceTesterBasic::cleanClass() +void LLMetricPerformanceTesterBasic::cleanupClass() { for (name_tester_map_t::iterator iter = sTesterMap.begin() ; iter != sTesterMap.end() ; ++iter) { diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h index 1a18cdf36fbf3a55e31f6c7c6cf5bd6a422332ab..e6b46be1cf905f193652bb2458ee8e6e573eb738 100644 --- a/indra/llcommon/llmetricperformancetester.h +++ b/indra/llcommon/llmetricperformancetester.h @@ -156,7 +156,7 @@ class LL_COMMON_API LLMetricPerformanceTesterBasic /** * @brief Delete all testers and reset the tester map */ - static void cleanClass() ; + static void cleanupClass() ; private: // Add a tester to the map. Returns false if adding fails. diff --git a/indra/llcommon/llpounceable.h b/indra/llcommon/llpounceable.h new file mode 100644 index 0000000000000000000000000000000000000000..0421ce966a7276ece6570a555ab4120d60f1ad86 --- /dev/null +++ b/indra/llcommon/llpounceable.h @@ -0,0 +1,216 @@ +/** + * @file llpounceable.h + * @author Nat Goodspeed + * @date 2015-05-22 + * @brief LLPounceable is tangentially related to a future: it's a holder for + * a value that may or may not exist yet. Unlike a future, though, + * LLPounceable freely allows reading the held value. (If the held + * type T does not have a distinguished "empty" value, consider using + * LLPounceable<boost::optional<T>>.) + * + * LLPounceable::callWhenReady() is this template's claim to fame. It + * allows its caller to "pounce" on the held value as soon as it + * becomes non-empty. Call callWhenReady() with any C++ callable + * accepting T. If the held value is already non-empty, callWhenReady() + * will immediately call the callable with the held value. If the held + * value is empty, though, callWhenReady() will enqueue the callable + * for later. As soon as LLPounceable is assigned a non-empty held + * value, it will flush the queue of deferred callables. + * + * Consider a global LLMessageSystem* gMessageSystem. Message system + * initialization happens at a very specific point during viewer + * initialization. Other subsystems want to register callbacks on the + * LLMessageSystem instance as soon as it's initialized, but their own + * initialization may precede that. If we define gMessageSystem to be + * an LLPounceable<LLMessageSystem*>, a subsystem can use + * callWhenReady() to either register immediately (if gMessageSystem + * is already up and runnning) or register as soon as gMessageSystem + * is set with a new, initialized instance. + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Copyright (c) 2015, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLPOUNCEABLE_H) +#define LL_LLPOUNCEABLE_H + +#include "llsingleton.h" +#include <boost/noncopyable.hpp> +#include <boost/call_traits.hpp> +#include <boost/type_traits/remove_pointer.hpp> +#include <boost/utility/value_init.hpp> +#include <boost/unordered_map.hpp> +#include <boost/signals2/signal.hpp> + +// Forward declare the user template, since we want to be able to point to it +// in some of its implementation classes. +template <typename T, class TAG> +class LLPounceable; + +template <typename T, typename TAG> +struct LLPounceableTraits +{ + // Our "queue" is a signal object with correct signature. + typedef boost::signals2::signal<void (typename boost::call_traits<T>::param_type)> signal_t; + // Call callWhenReady() with any callable accepting T. + typedef typename signal_t::slot_type func_t; + // owner pointer type + typedef LLPounceable<T, TAG>* owner_ptr; +}; + +// Tag types distinguish the two different implementations of LLPounceable's +// queue. +struct LLPounceableQueue {}; +struct LLPounceableStatic {}; + +// generic LLPounceableQueueImpl deliberately omitted: only the above tags are +// legal +template <typename T, class TAG> +class LLPounceableQueueImpl; + +// The implementation selected by LLPounceableStatic uses an LLSingleton +// because we can't count on a data member queue being initialized at the time +// we start getting callWhenReady() calls. This is that LLSingleton. +template <typename T> +class LLPounceableQueueSingleton: + public LLSingleton<LLPounceableQueueSingleton<T> > +{ + LLSINGLETON_EMPTY_CTOR(LLPounceableQueueSingleton); + + typedef LLPounceableTraits<T, LLPounceableStatic> traits; + typedef typename traits::owner_ptr owner_ptr; + typedef typename traits::signal_t signal_t; + + // For a given held type T, every LLPounceable<T, LLPounceableStatic> + // instance will call on the SAME LLPounceableQueueSingleton instance -- + // given how class statics work. We must keep a separate queue for each + // LLPounceable instance. Use a hash map for that. + typedef boost::unordered_map<owner_ptr, signal_t> map_t; + +public: + // Disambiguate queues belonging to different LLPounceables. + signal_t& get(owner_ptr owner) + { + // operator[] has find-or-create semantics -- just what we want! + return mMap[owner]; + } + +private: + map_t mMap; +}; + +// LLPounceableQueueImpl that uses the above LLSingleton +template <typename T> +class LLPounceableQueueImpl<T, LLPounceableStatic> +{ +public: + typedef LLPounceableTraits<T, LLPounceableStatic> traits; + typedef typename traits::owner_ptr owner_ptr; + typedef typename traits::signal_t signal_t; + + signal_t& get(owner_ptr owner) const + { + // this Impl contains nothing; it delegates to the Singleton + return LLPounceableQueueSingleton<T>::instance().get(owner); + } +}; + +// The implementation selected by LLPounceableQueue directly contains the +// queue of interest, suitable for an LLPounceable we can trust to be fully +// initialized when it starts getting callWhenReady() calls. +template <typename T> +class LLPounceableQueueImpl<T, LLPounceableQueue> +{ +public: + typedef LLPounceableTraits<T, LLPounceableQueue> traits; + typedef typename traits::owner_ptr owner_ptr; + typedef typename traits::signal_t signal_t; + + signal_t& get(owner_ptr) + { + return mQueue; + } + +private: + signal_t mQueue; +}; + +// LLPounceable<T> is for an LLPounceable instance on the heap or the stack. +// LLPounceable<T, LLPounceableStatic> is for a static LLPounceable instance. +template <typename T, class TAG=LLPounceableQueue> +class LLPounceable: public boost::noncopyable +{ +private: + typedef LLPounceableTraits<T, TAG> traits; + typedef typename traits::owner_ptr owner_ptr; + typedef typename traits::signal_t signal_t; + +public: + typedef typename traits::func_t func_t; + + // By default, both the initial value and the distinguished empty value + // are a default-constructed T instance. However you can explicitly + // specify each. + LLPounceable(typename boost::call_traits<T>::value_type init =boost::value_initialized<T>(), + typename boost::call_traits<T>::param_type empty=boost::value_initialized<T>()): + mHeld(init), + mEmpty(empty) + {} + + // make read access to mHeld as cheap and transparent as possible + operator T () const { return mHeld; } + typename boost::remove_pointer<T>::type operator*() const { return *mHeld; } + typename boost::call_traits<T>::value_type operator->() const { return mHeld; } + // uncomment 'explicit' as soon as we allow C++11 compilation + /*explicit*/ operator bool() const { return bool(mHeld); } + bool operator!() const { return ! mHeld; } + + // support both assignment (dumb ptr idiom) and reset() (smart ptr) + void operator=(typename boost::call_traits<T>::param_type value) + { + reset(value); + } + + void reset(typename boost::call_traits<T>::param_type value) + { + mHeld = value; + // If this new value is non-empty, flush anything pending in the queue. + if (mHeld != mEmpty) + { + signal_t& signal(get_signal()); + signal(mHeld); + signal.disconnect_all_slots(); + } + } + + // our claim to fame + void callWhenReady(const func_t& func) + { + if (mHeld != mEmpty) + { + // If the held value is already non-empty, immediately call func() + func(mHeld); + } + else + { + // Held value still empty, queue func() for later. By default, + // connect() enqueues slots in FIFO order. + get_signal().connect(func); + } + } + +private: + signal_t& get_signal() { return mQueue.get(this); } + + // Store both the current and the empty value. + // MAYBE: Might be useful to delegate to LLPounceableTraits the meaning of + // testing for "empty." For some types we want operator!(); for others we + // want to compare to a distinguished value. + typename boost::call_traits<T>::value_type mHeld, mEmpty; + // This might either contain the queue (LLPounceableQueue) or delegate to + // an LLSingleton (LLPounceableStatic). + LLPounceableQueueImpl<T, TAG> mQueue; +}; + +#endif /* ! defined(LL_LLPOUNCEABLE_H) */ diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index 2c4bcc91f6e96ec41c8e6b588de038025a3fc807..3698d9db4420b5c5b0e0ac64e3b551c91e024935 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -138,6 +138,12 @@ #pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden #pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored //#pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file + +#if ADDRESS_SIZE == 64 +// That one is all over the place for x64 builds. +#pragma warning( disable : 4267 ) // 'var' : conversion from 'size_t' to 'type', possible loss of data) +#endif + #pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation. #pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) #pragma warning( disable : 4996 ) // warning: deprecated diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 44f56daf2dec5f6b96774dca026fcd90bd0d051a..8c321d06b9eaecad730a9e080da4bfd3e80a4eea 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -34,6 +34,7 @@ #include "llapr.h" #include "apr_signal.h" #include "llevents.h" +#include "llexception.h" #include <boost/foreach.hpp> #include <boost/bind.hpp> @@ -472,9 +473,9 @@ class ReadPipeImpl: public LLProcess::ReadPipe *****************************************************************************/ /// Need an exception to avoid constructing an invalid LLProcess object, but /// internal use only -struct LLProcessError: public std::runtime_error +struct LLProcessError: public LLException { - LLProcessError(const std::string& msg): std::runtime_error(msg) {} + LLProcessError(const std::string& msg): LLException(msg) {} }; LLProcessPtr LLProcess::create(const LLSDOrParams& params) @@ -530,8 +531,8 @@ LLProcess::LLProcess(const LLSDOrParams& params): if (! params.validateBlock(true)) { - throw LLProcessError(STRINGIZE("not launched: failed parameter validation\n" - << LLSDNotationStreamer(params))); + LLTHROW(LLProcessError(STRINGIZE("not launched: failed parameter validation\n" + << LLSDNotationStreamer(params)))); } mPostend = params.postend; @@ -596,10 +597,10 @@ LLProcess::LLProcess(const LLSDOrParams& params): } else { - throw LLProcessError(STRINGIZE("For " << params.executable() - << ": unsupported FileParam for " << which - << ": type='" << fparam.type() - << "', name='" << fparam.name() << "'")); + LLTHROW(LLProcessError(STRINGIZE("For " << params.executable() + << ": unsupported FileParam for " << which + << ": type='" << fparam.type() + << "', name='" << fparam.name() << "'"))); } } // By default, pass APR_NO_PIPE for unspecified slots. @@ -678,7 +679,7 @@ LLProcess::LLProcess(const LLSDOrParams& params): if (ll_apr_warn_status(apr_proc_create(&mProcess, argv[0], &argv[0], NULL, procattr, gAPRPoolp))) { - throw LLProcessError(STRINGIZE(params << " failed")); + LLTHROW(LLProcessError(STRINGIZE(params << " failed"))); } // arrange to call status_callback() @@ -1063,7 +1064,7 @@ PIPETYPE& LLProcess::getPipe(FILESLOT slot) PIPETYPE* wp = getPipePtr<PIPETYPE>(error, slot); if (! wp) { - throw NoPipe(error); + LLTHROW(NoPipe(error)); } return *wp; } diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h index 43ccadc41278be52dcecb8acdd5a2b646fbee530..bfac4567a50587f5816a0cfcf94ba6127b9d2501 100644 --- a/indra/llcommon/llprocess.h +++ b/indra/llcommon/llprocess.h @@ -30,13 +30,13 @@ #include "llinitparam.h" #include "llsdparam.h" #include "llwin32headerslean.h" +#include "llexception.h" #include "apr_thread_proc.h" #include <boost/shared_ptr.hpp> #include <boost/ptr_container/ptr_vector.hpp> #include <boost/optional.hpp> #include <boost/noncopyable.hpp> #include <iosfwd> // std::ostream -#include <stdexcept> #if LL_WINDOWS #include "llwin32headerslean.h" // for HANDLE @@ -479,9 +479,9 @@ class LL_COMMON_API LLProcess: public boost::noncopyable /// Exception thrown by getWritePipe(), getReadPipe() if you didn't ask to /// create a pipe at the corresponding FILESLOT. - struct NoPipe: public std::runtime_error + struct NoPipe: public LLException { - NoPipe(const std::string& what): std::runtime_error(what) {} + NoPipe(const std::string& what): LLException(what) {} }; /** diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index e3e1d0c3918c8cdf1c61d2b98305c46d105a2dc8..65b4507e2d7cb4d8b1683db9e92e2f647f67b830 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -398,7 +398,7 @@ static F64 calculate_cpu_frequency(U32 measure_msecs) HANDLE hThread = GetCurrentThread(); unsigned long dwCurPriorityClass = GetPriorityClass(hProcess); int iCurThreadPriority = GetThreadPriority(hThread); - unsigned long dwProcessMask, dwSystemMask, dwNewMask = 1; + DWORD_PTR dwProcessMask, dwSystemMask, dwNewMask = 1; GetProcessAffinityMask(hProcess, &dwProcessMask, &dwSystemMask); SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS); diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index 29950c108dbe104a54f5eb42e41583e25cb8787e..750fe9fdc8a0d3193e99cbcbf1c257d624324f77 100644 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -247,7 +247,10 @@ class LLRegistrySingleton : public LLRegistry<KEY, VALUE, COMPARATOR>, public LLSingleton<DERIVED_TYPE> { - friend class LLSingleton<DERIVED_TYPE>; + // This LLRegistrySingleton doesn't use LLSINGLETON(LLRegistrySingleton) + // because the concrete class is actually DERIVED_TYPE, not + // LLRegistrySingleton. So each concrete subclass needs + // LLSINGLETON(whatever) -- not this intermediate base class. public: typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t; typedef const KEY& ref_const_key_t; @@ -269,7 +272,7 @@ class LLRegistrySingleton ~ScopedRegistrar() { - if (!singleton_t::destroyed()) + if (singleton_t::instanceExists()) { popScope(); } diff --git a/indra/llcommon/llsdparam.h b/indra/llcommon/llsdparam.h index 09f1bdf1e3fa4b8fcac8cae5b296796ac7df3ef0..93910b70ae98957246faaa30c4579f6666eb91d6 100644 --- a/indra/llcommon/llsdparam.h +++ b/indra/llcommon/llsdparam.h @@ -66,6 +66,7 @@ typedef LLInitParam::Parser parser_t; } /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ std::string getCurrentFileName(){ return LLStringUtil::null; } private: void writeSDImpl(LLSD& sd, diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index d49ff0feb52d64ab2c21023ccd697c450b78d8fa..81ba8631c64737cab887411b2a9a7965b7b26cef 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -1200,6 +1200,7 @@ bool LLSDBinaryParser::parseString( read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ S32 size = (S32)ntohl(value_nbo); if(mCheckLimits && (size > mMaxBytesLeft)) return false; + if(size < 0) return false; std::vector<char> buf; if(size) { diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 9b49e5237717234ae6ba2179ff053e3a39cf8934..9025e53bb27a2d42d908f957a82242039e1cd170 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -25,7 +25,445 @@ */ #include "linden_common.h" - #include "llsingleton.h" +#include "llerror.h" +#include "llerrorcontrol.h" // LLError::is_available() +#include "lldependencies.h" +#include "llcoro_get_id.h" +#include <boost/foreach.hpp> +#include <boost/unordered_map.hpp> +#include <algorithm> +#include <iostream> // std::cerr in dire emergency +#include <sstream> +#include <stdexcept> + +namespace { +void log(LLError::ELevel level, + const char* p1, const char* p2, const char* p3, const char* p4); + +void logdebugs(const char* p1="", const char* p2="", const char* p3="", const char* p4=""); + +bool oktolog(); +} // anonymous namespace + +// Our master list of all LLSingletons is itself an LLSingleton. We used to +// store it in a function-local static, but that could get destroyed before +// the last of the LLSingletons -- and ~LLSingletonBase() definitely wants to +// remove itself from the master list. Since the whole point of this master +// list is to help track inter-LLSingleton dependencies, and since we have +// this implicit dependency from every LLSingleton to the master list, make it +// an LLSingleton. +class LLSingletonBase::MasterList: + public LLSingleton<LLSingletonBase::MasterList> +{ + LLSINGLETON_EMPTY_CTOR(MasterList); + +public: + // No need to make this private with accessors; nobody outside this source + // file can see it. + + // This is the master list of all instantiated LLSingletons (save the + // MasterList itself) in arbitrary order. You MUST call dep_sort() before + // traversing this list. + LLSingletonBase::list_t mMaster; + + // We need to maintain a stack of LLSingletons currently being + // initialized, either in the constructor or in initSingleton(). However, + // managing that as a stack depends on having a DISTINCT 'initializing' + // stack for every C++ stack in the process! And we have a distinct C++ + // stack for every running coroutine. It would be interesting and cool to + // implement a generic coroutine-local-storage mechanism and use that + // here. The trouble is that LLCoros is itself an LLSingleton, so + // depending on LLCoros functionality could dig us into infinite + // recursion. (Moreover, when we reimplement LLCoros on top of + // Boost.Fiber, that library already provides fiber_specific_ptr -- so + // it's not worth a great deal of time and energy implementing a generic + // equivalent on top of boost::dcoroutine, which is on its way out.) + // Instead, use a map of llcoro::id to select the appropriate + // coro-specific 'initializing' stack. llcoro::get_id() is carefully + // implemented to avoid requiring LLCoros. + typedef boost::unordered_map<llcoro::id, LLSingletonBase::list_t> InitializingMap; + InitializingMap mInitializing; + + // non-static method, cf. LLSingletonBase::get_initializing() + list_t& get_initializing_() + { + // map::operator[] has find-or-create semantics, exactly what we need + // here. It returns a reference to the selected mapped_type instance. + return mInitializing[llcoro::get_id()]; + } + + void cleanup_initializing_() + { + InitializingMap::iterator found = mInitializing.find(llcoro::get_id()); + if (found != mInitializing.end()) + { + mInitializing.erase(found); + } + } +}; + +//static +LLSingletonBase::list_t& LLSingletonBase::get_master() +{ + return LLSingletonBase::MasterList::instance().mMaster; +} + +void LLSingletonBase::add_master() +{ + // As each new LLSingleton is constructed, add to the master list. + get_master().push_back(this); +} + +void LLSingletonBase::remove_master() +{ + // When an LLSingleton is destroyed, remove from master list. + // add_master() used to capture the iterator to the newly-added list item + // so we could directly erase() it from the master list. Unfortunately + // that runs afoul of destruction-dependency order problems. So search the + // master list, and remove this item IF FOUND. We have few enough + // LLSingletons, and they are so rarely destroyed (once per run), that the + // cost of a linear search should not be an issue. + get_master().remove(this); +} + +//static +LLSingletonBase::list_t& LLSingletonBase::get_initializing() +{ + return LLSingletonBase::MasterList::instance().get_initializing_(); +} + +//static +LLSingletonBase::list_t& LLSingletonBase::get_initializing_from(MasterList* master) +{ + return master->get_initializing_(); +} + +LLSingletonBase::~LLSingletonBase() {} + +void LLSingletonBase::push_initializing(const char* name) +{ + // log BEFORE pushing so logging singletons don't cry circularity + log_initializing("Pushing", name); + get_initializing().push_back(this); +} + +void LLSingletonBase::pop_initializing() +{ + list_t& list(get_initializing()); + + if (list.empty()) + { + logerrs("Underflow in stack of currently-initializing LLSingletons at ", + demangle(typeid(*this).name()).c_str(), "::getInstance()"); + } + + // Now we know list.back() exists: capture it + LLSingletonBase* back(list.back()); + // and pop it + list.pop_back(); + + // The viewer launches an open-ended number of coroutines. While we don't + // expect most of them to initialize LLSingleton instances, our present + // get_initializing() logic could lead to an open-ended number of map + // entries. So every time we pop the stack back to empty, delete the entry + // entirely. + if (list.empty()) + { + MasterList::instance().cleanup_initializing_(); + } + + // Now validate the newly-popped LLSingleton. + if (back != this) + { + logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ", + demangle(typeid(*this).name()).c_str(), "::getInstance() trying to pop ", + demangle(typeid(*back).name()).c_str()); + } + + // log AFTER popping so logging singletons don't cry circularity + log_initializing("Popping", typeid(*back).name()); +} + +//static +void LLSingletonBase::log_initializing(const char* verb, const char* name) +{ + if (oktolog()) + { + LL_DEBUGS("LLSingleton") << verb << ' ' << demangle(name) << ';'; + list_t& list(get_initializing()); + for (list_t::const_reverse_iterator ri(list.rbegin()), rend(list.rend()); + ri != rend; ++ri) + { + LLSingletonBase* sb(*ri); + LL_CONT << ' ' << demangle(typeid(*sb).name()); + } + LL_ENDL; + } +} + +void LLSingletonBase::capture_dependency(list_t& initializing, EInitState initState) +{ + // Did this getInstance() call come from another LLSingleton, or from + // vanilla application code? Note that although this is a nontrivial + // method, the vast majority of its calls arrive here with initializing + // empty(). + if (! initializing.empty()) + { + // getInstance() is being called by some other LLSingleton. But -- is + // this a circularity? That is, does 'this' already appear in the + // initializing stack? + // For what it's worth, normally 'initializing' should contain very + // few elements. + list_t::const_iterator found = + std::find(initializing.begin(), initializing.end(), this); + if (found != initializing.end()) + { + // Report the circularity. Requiring the coder to dig through the + // logic to diagnose exactly how we got here is less than helpful. + std::ostringstream out; + for ( ; found != initializing.end(); ++found) + { + // 'found' is an iterator; *found is an LLSingletonBase*; **found + // is the actual LLSingletonBase instance. + LLSingletonBase* foundp(*found); + out << demangle(typeid(*foundp).name()) << " -> "; + } + // We promise to capture dependencies from both the constructor + // and the initSingleton() method, so an LLSingleton's instance + // pointer is on the initializing list during both. Now that we've + // detected circularity, though, we must distinguish the two. If + // the recursive call is from the constructor, we CAN'T honor it: + // otherwise we'd be returning a pointer to a partially- + // constructed object! But from initSingleton() is okay: that + // method exists specifically to support circularity. + // Decide which log helper to call based on initState. They have + // identical signatures. + ((initState == CONSTRUCTING)? logerrs : logwarns) + ("LLSingleton circularity: ", out.str().c_str(), + demangle(typeid(*this).name()).c_str(), ""); + } + else + { + // Here 'this' is NOT already in the 'initializing' stack. Great! + // Record the dependency. + // initializing.back() is the LLSingletonBase* currently being + // initialized. Store 'this' in its mDepends set. + LLSingletonBase* current(initializing.back()); + if (current->mDepends.insert(this).second) + { + // only log the FIRST time we hit this dependency! + logdebugs(demangle(typeid(*current).name()).c_str(), + " depends on ", demangle(typeid(*this).name()).c_str()); + } + } + } +} + +//static +LLSingletonBase::vec_t LLSingletonBase::dep_sort() +{ + // While it would theoretically be possible to maintain a static + // SingletonDeps through the life of the program, dynamically adding and + // removing LLSingletons as they are created and destroyed, in practice + // it's less messy to construct it on demand. The overhead of doing so + // should happen basically twice: once for cleanupAll(), once for + // deleteAll(). + typedef LLDependencies<LLSingletonBase*> SingletonDeps; + SingletonDeps sdeps; + list_t& master(get_master()); + BOOST_FOREACH(LLSingletonBase* sp, master) + { + // Build the SingletonDeps structure by adding, for each + // LLSingletonBase* sp in the master list, sp itself. It has no + // associated value type in our SingletonDeps, hence the 0. We don't + // record the LLSingletons it must follow; rather, we record the ones + // it must precede. Copy its mDepends to a KeyList to express that. + sdeps.add(sp, 0, + SingletonDeps::KeyList(), + SingletonDeps::KeyList(sp->mDepends.begin(), sp->mDepends.end())); + } + vec_t ret; + ret.reserve(master.size()); + // We should be able to effect this with a transform_iterator that + // extracts just the first (key) element from each sorted_iterator, then + // uses vec_t's range constructor... but frankly this is more + // straightforward, as long as we remember the above reserve() call! + BOOST_FOREACH(SingletonDeps::sorted_iterator::value_type pair, sdeps.sort()) + { + ret.push_back(pair.first); + } + // The master list is not itself pushed onto the master list. Add it as + // the very last entry -- it is the LLSingleton on which ALL others + // depend! -- so our caller will process it. + ret.push_back(MasterList::getInstance()); + return ret; +} + +//static +void LLSingletonBase::cleanupAll() +{ + // It's essential to traverse these in dependency order. + BOOST_FOREACH(LLSingletonBase* sp, dep_sort()) + { + // Call cleanupSingleton() only if we haven't already done so for this + // instance. + if (! sp->mCleaned) + { + sp->mCleaned = true; + + logdebugs("calling ", + demangle(typeid(*sp).name()).c_str(), "::cleanupSingleton()"); + try + { + sp->cleanupSingleton(); + } + catch (const std::exception& e) + { + logwarns("Exception in ", demangle(typeid(*sp).name()).c_str(), + "::cleanupSingleton(): ", e.what()); + } + catch (...) + { + logwarns("Unknown exception in ", demangle(typeid(*sp).name()).c_str(), + "::cleanupSingleton()"); + } + } + } +} + +//static +void LLSingletonBase::deleteAll() +{ + // It's essential to traverse these in dependency order. + BOOST_FOREACH(LLSingletonBase* sp, dep_sort()) + { + // Capture the class name first: in case of exception, don't count on + // being able to extract it later. + const std::string name = demangle(typeid(*sp).name()); + try + { + // Call static method through instance function pointer. + if (! sp->mDeleteSingleton) + { + // This Should Not Happen... but carry on. + logwarns(name.c_str(), "::mDeleteSingleton not initialized!"); + } + else + { + // properly initialized: call it. + logdebugs("calling ", name.c_str(), "::deleteSingleton()"); + // From this point on, DO NOT DEREFERENCE sp! + sp->mDeleteSingleton(); + } + } + catch (const std::exception& e) + { + logwarns("Exception in ", name.c_str(), "::deleteSingleton(): ", e.what()); + } + catch (...) + { + logwarns("Unknown exception in ", name.c_str(), "::deleteSingleton()"); + } + } +} + +/*------------------------ Final cleanup management ------------------------*/ +class LLSingletonBase::MasterRefcount +{ +public: + // store a POD int so it will be statically initialized to 0 + int refcount; +}; +static LLSingletonBase::MasterRefcount sMasterRefcount; + +LLSingletonBase::ref_ptr_t LLSingletonBase::get_master_refcount() +{ + // Calling this method constructs a new ref_ptr_t, which implicitly calls + // intrusive_ptr_add_ref(MasterRefcount*). + return &sMasterRefcount; +} + +void intrusive_ptr_add_ref(LLSingletonBase::MasterRefcount* mrc) +{ + // Count outstanding SingletonLifetimeManager instances. + ++mrc->refcount; +} + +void intrusive_ptr_release(LLSingletonBase::MasterRefcount* mrc) +{ + // Notice when each SingletonLifetimeManager instance is destroyed. + if (! --mrc->refcount) + { + // The last instance was destroyed. Time to kill any remaining + // LLSingletons -- but in dependency order. + LLSingletonBase::deleteAll(); + } +} + +/*---------------------------- Logging helpers -----------------------------*/ +namespace { +bool oktolog() +{ + // See comments in log() below. + return sMasterRefcount.refcount && LLError::is_available(); +} + +void log(LLError::ELevel level, + const char* p1, const char* p2, const char* p3, const char* p4) +{ + // Check whether we're in the implicit final LLSingletonBase::deleteAll() + // call. We've carefully arranged for deleteAll() to be called when the + // last SingletonLifetimeManager instance is destroyed -- in other words, + // when the last translation unit containing an LLSingleton instance + // cleans up static data. That could happen after std::cerr is destroyed! + // The is_available() test below ensures that we'll stop logging once + // LLError has been cleaned up. If we had a similar portable test for + // std::cerr, this would be a good place to use it. As we do not, just + // don't log anything during implicit final deleteAll(). Detect that by + // the master refcount having gone to zero. + if (sMasterRefcount.refcount == 0) + return; + + // Check LLError::is_available() because some of LLError's infrastructure + // is itself an LLSingleton. If that LLSingleton has not yet been + // initialized, trying to log will engage LLSingleton machinery... and + // around and around we go. + if (LLError::is_available()) + { + LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL; + } + else + { + // Caller may be a test program, or something else whose stderr is + // visible to the user. + std::cerr << p1 << p2 << p3 << p4 << std::endl; + } +} + +void logdebugs(const char* p1, const char* p2, const char* p3, const char* p4) +{ + log(LLError::LEVEL_DEBUG, p1, p2, p3, p4); +} +} // anonymous namespace + +//static +void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, const char* p4) +{ + log(LLError::LEVEL_WARN, p1, p2, p3, p4); +} + +//static +void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, const char* p4) +{ + log(LLError::LEVEL_ERROR, p1, p2, p3, p4); + // The other important side effect of LL_ERRS() is + // https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG) + LLError::crashAndLoop(std::string()); +} +std::string LLSingletonBase::demangle(const char* mangled) +{ + return LLError::Log::demangle(mangled); +} diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 6e6291a1653c97ac014a4913b937747898697542..1b915dfd6e96d927fd520ba58415c52387295049 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -25,188 +25,495 @@ #ifndef LLSINGLETON_H #define LLSINGLETON_H -#include "llerror.h" // *TODO: eliminate this - -#include <typeinfo> #include <boost/noncopyable.hpp> +#include <boost/unordered_set.hpp> +#include <boost/intrusive_ptr.hpp> +#include <list> +#include <vector> +#include <typeinfo> + +class LLSingletonBase: private boost::noncopyable +{ +public: + class MasterList; + class MasterRefcount; + typedef boost::intrusive_ptr<MasterRefcount> ref_ptr_t; + +private: + // All existing LLSingleton instances are tracked in this master list. + typedef std::list<LLSingletonBase*> list_t; + static list_t& get_master(); + // This, on the other hand, is a stack whose top indicates the LLSingleton + // currently being initialized. + static list_t& get_initializing(); + static list_t& get_initializing_from(MasterList*); + // Produce a vector<LLSingletonBase*> of master list, in dependency order. + typedef std::vector<LLSingletonBase*> vec_t; + static vec_t dep_sort(); + + bool mCleaned; // cleanupSingleton() has been called + // we directly depend on these other LLSingletons + typedef boost::unordered_set<LLSingletonBase*> set_t; + set_t mDepends; + +protected: + typedef enum e_init_state + { + UNINITIALIZED = 0, // must be default-initialized state + CONSTRUCTING, + INITIALIZING, + INITIALIZED, + DELETED + } EInitState; + + // Define tag<T> to pass to our template constructor. You can't explicitly + // invoke a template constructor with ordinary template syntax: + // http://stackoverflow.com/a/3960925/5533635 + template <typename T> + struct tag + { + typedef T type; + }; + + // Base-class constructor should only be invoked by the DERIVED_TYPE + // constructor, which passes tag<DERIVED_TYPE> for various purposes. + template <typename DERIVED_TYPE> + LLSingletonBase(tag<DERIVED_TYPE>); + virtual ~LLSingletonBase(); + + // Every new LLSingleton should be added to/removed from the master list + void add_master(); + void remove_master(); + // with a little help from our friends. + template <class T> friend struct LLSingleton_manage_master; + + // Maintain a stack of the LLSingleton subclass instance currently being + // initialized. We use this to notice direct dependencies: we want to know + // if A requires B. We deduce a dependency if while initializing A, + // control reaches B::getInstance(). + // We want &A to be at the top of that stack during both A::A() and + // A::initSingleton(), since a call to B::getInstance() might occur during + // either. + // Unfortunately the desired timespan does not correspond neatly with a + // single C++ scope, else we'd use RAII to track it. But we do know that + // LLSingletonBase's constructor definitely runs just before + // LLSingleton's, which runs just before the specific subclass's. + void push_initializing(const char*); + // LLSingleton is, and must remain, the only caller to initSingleton(). + // That being the case, we control exactly when it happens -- and we can + // pop the stack immediately thereafter. + void pop_initializing(); +private: + // logging + static void log_initializing(const char* verb, const char* name); +protected: + // If a given call to B::getInstance() happens during either A::A() or + // A::initSingleton(), record that A directly depends on B. + void capture_dependency(list_t& initializing, EInitState); + + // delegate LL_ERRS() logging to llsingleton.cpp + static void logerrs(const char* p1, const char* p2="", + const char* p3="", const char* p4=""); + // delegate LL_WARNS() logging to llsingleton.cpp + static void logwarns(const char* p1, const char* p2="", + const char* p3="", const char* p4=""); + static std::string demangle(const char* mangled); + + // obtain canonical ref_ptr_t + static ref_ptr_t get_master_refcount(); + + // Default methods in case subclass doesn't declare them. + virtual void initSingleton() {} + virtual void cleanupSingleton() {} + + // deleteSingleton() isn't -- and shouldn't be -- a virtual method. It's a + // class static. However, given only Foo*, deleteAll() does need to be + // able to reach Foo::deleteSingleton(). Make LLSingleton (which declares + // deleteSingleton()) store a pointer here. Since we know it's a static + // class method, a classic-C function pointer will do. + void (*mDeleteSingleton)(); + +public: + /** + * Call this to call the cleanupSingleton() method for every LLSingleton + * constructed since the start of the last cleanupAll() call. (Any + * LLSingleton constructed DURING a cleanupAll() call won't be cleaned up + * until the next cleanupAll() call.) cleanupSingleton() neither deletes + * nor destroys its LLSingleton; therefore it's safe to include logic that + * might take significant realtime or even throw an exception. + * + * The most important property of cleanupAll() is that cleanupSingleton() + * methods are called in dependency order, leaf classes last. Thus, given + * two LLSingleton subclasses A and B, if A's dependency on B is properly + * expressed as a B::getInstance() or B::instance() call during either + * A::A() or A::initSingleton(), B will be cleaned up after A. + * + * If a cleanupSingleton() method throws an exception, the exception is + * logged, but cleanupAll() attempts to continue calling the rest of the + * cleanupSingleton() methods. + */ + static void cleanupAll(); + /** + * Call this to call the deleteSingleton() method for every LLSingleton + * constructed since the start of the last deleteAll() call. (Any + * LLSingleton constructed DURING a deleteAll() call won't be cleaned up + * until the next deleteAll() call.) deleteSingleton() deletes and + * destroys its LLSingleton. Any cleanup logic that might take significant + * realtime -- or throw an exception -- must not be placed in your + * LLSingleton's destructor, but rather in its cleanupSingleton() method. + * + * The most important property of deleteAll() is that deleteSingleton() + * methods are called in dependency order, leaf classes last. Thus, given + * two LLSingleton subclasses A and B, if A's dependency on B is properly + * expressed as a B::getInstance() or B::instance() call during either + * A::A() or A::initSingleton(), B will be cleaned up after A. + * + * If a deleteSingleton() method throws an exception, the exception is + * logged, but deleteAll() attempts to continue calling the rest of the + * deleteSingleton() methods. + */ + static void deleteAll(); +}; + +// support ref_ptr_t +void intrusive_ptr_add_ref(LLSingletonBase::MasterRefcount*); +void intrusive_ptr_release(LLSingletonBase::MasterRefcount*); -// LLSingleton implements the getInstance() method part of the Singleton -// pattern. It can't make the derived class constructors protected, though, so -// you have to do that yourself. -// -// There are two ways to use LLSingleton. The first way is to inherit from it -// while using the typename that you'd like to be static as the template -// parameter, like so: -// -// class Foo: public LLSingleton<Foo>{}; -// -// Foo& instance = Foo::instance(); -// -// The second way is to use the singleton class directly, without inheritance: -// -// typedef LLSingleton<Foo> FooSingleton; -// -// Foo& instance = FooSingleton::instance(); -// -// In this case, the class being managed as a singleton needs to provide an -// initSingleton() method since the LLSingleton virtual method won't be -// available -// -// As currently written, it is not thread-safe. +// Most of the time, we want LLSingleton_manage_master() to forward its +// methods to real LLSingletonBase methods. +template <class T> +struct LLSingleton_manage_master +{ + void add(LLSingletonBase* sb) { sb->add_master(); } + void remove(LLSingletonBase* sb) { sb->remove_master(); } + void push_initializing(LLSingletonBase* sb) { sb->push_initializing(typeid(T).name()); } + void pop_initializing (LLSingletonBase* sb) { sb->pop_initializing(); } + LLSingletonBase::list_t& get_initializing(T*) { return LLSingletonBase::get_initializing(); } +}; +// But for the specific case of LLSingletonBase::MasterList, don't. +template <> +struct LLSingleton_manage_master<LLSingletonBase::MasterList> +{ + void add(LLSingletonBase*) {} + void remove(LLSingletonBase*) {} + void push_initializing(LLSingletonBase*) {} + void pop_initializing (LLSingletonBase*) {} + LLSingletonBase::list_t& get_initializing(LLSingletonBase::MasterList* instance) + { + return LLSingletonBase::get_initializing_from(instance); + } +}; + +// Now we can implement LLSingletonBase's template constructor. template <typename DERIVED_TYPE> -class LLSingleton : private boost::noncopyable +LLSingletonBase::LLSingletonBase(tag<DERIVED_TYPE>): + mCleaned(false), + mDeleteSingleton(NULL) +{ + // Make this the currently-initializing LLSingleton. + LLSingleton_manage_master<DERIVED_TYPE>().push_initializing(this); +} + +/** + * LLSingleton implements the getInstance() method part of the Singleton + * pattern. It can't make the derived class constructors protected, though, so + * you have to do that yourself. + * + * Derive your class from LLSingleton, passing your subclass name as + * LLSingleton's template parameter, like so: + * + * class Foo: public LLSingleton<Foo> + * { + * // use this macro at start of every LLSingleton subclass + * LLSINGLETON(Foo); + * public: + * // ... + * }; + * + * Foo& instance = Foo::instance(); + * + * LLSingleton recognizes a couple special methods in your derived class. + * + * If you override LLSingleton<T>::initSingleton(), your method will be called + * immediately after the instance is constructed. This is useful for breaking + * circular dependencies: if you find that your LLSingleton subclass + * constructor references other LLSingleton subclass instances in a chain + * leading back to yours, move the instance reference from your constructor to + * your initSingleton() method. + * + * If you override LLSingleton<T>::cleanupSingleton(), your method will be + * called if someone calls LLSingletonBase::cleanupAll(). The significant part + * of this promise is that cleanupAll() will call individual + * cleanupSingleton() methods in reverse dependency order. + * + * That is, consider LLSingleton subclasses C, B and A. A depends on B, which + * in turn depends on C. These dependencies are expressed as calls to + * B::instance() or B::getInstance(), and C::instance() or C::getInstance(). + * It shouldn't matter whether these calls appear in A::A() or + * A::initSingleton(), likewise B::B() or B::initSingleton(). + * + * We promise that if you later call LLSingletonBase::cleanupAll(): + * 1. A::cleanupSingleton() will be called before + * 2. B::cleanupSingleton(), which will be called before + * 3. C::cleanupSingleton(). + * Put differently, if your LLSingleton subclass constructor or + * initSingleton() method explicitly depends on some other LLSingleton + * subclass, you may continue to rely on that other subclass in your + * cleanupSingleton() method. + * + * We introduce a special cleanupSingleton() method because cleanupSingleton() + * operations can involve nontrivial realtime, or might throw an exception. A + * destructor should do neither! + * + * If your cleanupSingleton() method throws an exception, we log that + * exception but proceed with the remaining cleanupSingleton() calls. + * + * Similarly, if at some point you call LLSingletonBase::deleteAll(), all + * remaining LLSingleton instances will be destroyed in dependency order. (Or + * call MySubclass::deleteSingleton() to specifically destroy the canonical + * MySubclass instance.) + * + * As currently written, LLSingleton is not thread-safe. + */ +template <typename DERIVED_TYPE> +class LLSingleton : public LLSingletonBase { - private: - typedef enum e_init_state - { - UNINITIALIZED, - CONSTRUCTING, - INITIALIZING, - INITIALIZED, - DELETED - } EInitState; - static DERIVED_TYPE* constructSingleton() { return new DERIVED_TYPE(); } - - // stores pointer to singleton instance - struct SingletonLifetimeManager - { - SingletonLifetimeManager() - { - construct(); - } - - static void construct() - { - sData.mInitState = CONSTRUCTING; - sData.mInstance = constructSingleton(); - sData.mInitState = INITIALIZING; - } - - ~SingletonLifetimeManager() - { - if (sData.mInitState != DELETED) - { - deleteSingleton(); - } - } - }; - + + // We know of no way to instruct the compiler that every subclass + // constructor MUST be private. However, we can make the LLSINGLETON() + // macro both declare a private constructor and provide the required + // friend declaration. How can we ensure that every subclass uses + // LLSINGLETON()? By making that macro provide a definition for this pure + // virtual method. If you get "can't instantiate class due to missing pure + // virtual method" for this method, then add LLSINGLETON(yourclass) in the + // subclass body. + virtual void you_must_use_LLSINGLETON_macro() = 0; + + // stores pointer to singleton instance + struct SingletonLifetimeManager + { + SingletonLifetimeManager(): + mMasterRefcount(LLSingletonBase::get_master_refcount()) + { + construct(); + } + + static void construct() + { + sData.mInitState = CONSTRUCTING; + sData.mInstance = constructSingleton(); + sData.mInitState = INITIALIZING; + } + + ~SingletonLifetimeManager() + { + // The dependencies between LLSingletons, and the arbitrary order + // of static-object destruction, mean that we DO NOT WANT this + // destructor to delete this LLSingleton. This destructor will run + // without regard to any other LLSingleton whose cleanup might + // depend on its existence. What we really want is to count the + // runtime's attempts to cleanup LLSingleton static data -- and on + // the very last one, call LLSingletonBase::deleteAll(). That + // method will properly honor cross-LLSingleton dependencies. This + // is why we store an intrusive_ptr to a MasterRefcount: our + // ref_ptr_t member counts SingletonLifetimeManager instances. + // Once the runtime destroys the last of these, THEN we can delete + // every remaining LLSingleton. + } + + LLSingletonBase::ref_ptr_t mMasterRefcount; + }; + +protected: + // Pass DERIVED_TYPE explicitly to LLSingletonBase's constructor because, + // until our subclass constructor completes, *this isn't yet a + // full-fledged DERIVED_TYPE. + LLSingleton(): LLSingletonBase(LLSingletonBase::tag<DERIVED_TYPE>()) + { + // populate base-class function pointer with the static + // deleteSingleton() function for this particular specialization + mDeleteSingleton = &deleteSingleton; + + // add this new instance to the master list + LLSingleton_manage_master<DERIVED_TYPE>().add(this); + } + public: - virtual ~LLSingleton() - { - sData.mInstance = NULL; - sData.mInitState = DELETED; - } - - /** - * @brief Immediately delete the singleton. - * - * A subsequent call to LLProxy::getInstance() will construct a new - * instance of the class. - * - * LLSingletons are normally destroyed after main() has exited and the C++ - * runtime is cleaning up statically-constructed objects. Some classes - * derived from LLSingleton have objects that are part of a runtime system - * that is terminated before main() exits. Calling the destructor of those - * objects after the termination of their respective systems can cause - * crashes and other problems during termination of the project. Using this - * method to destroy the singleton early can prevent these crashes. - * - * An example where this is needed is for a LLSingleton that has an APR - * object as a member that makes APR calls on destruction. The APR system is - * shut down explicitly before main() exits. This causes a crash on exit. - * Using this method before the call to apr_terminate() and NOT calling - * getInstance() again will prevent the crash. - */ - static void deleteSingleton() - { - delete sData.mInstance; - sData.mInstance = NULL; - sData.mInitState = DELETED; - } - - - static DERIVED_TYPE* getInstance() - { - static SingletonLifetimeManager sLifeTimeMgr; - - switch (sData.mInitState) - { - case UNINITIALIZED: - // should never be uninitialized at this point - llassert(false); - return NULL; - case CONSTRUCTING: - LL_ERRS() << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << LL_ENDL; - return NULL; - case INITIALIZING: - // go ahead and flag ourselves as initialized so we can be reentrant during initialization - sData.mInitState = INITIALIZED; - // initialize singleton after constructing it so that it can reference other singletons which in turn depend on it, - // thus breaking cyclic dependencies - sData.mInstance->initSingleton(); - return sData.mInstance; - case INITIALIZED: - return sData.mInstance; - case DELETED: - LL_WARNS() << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << LL_ENDL; - SingletonLifetimeManager::construct(); - // same as first time construction - sData.mInitState = INITIALIZED; - sData.mInstance->initSingleton(); - return sData.mInstance; - } - - return NULL; - } - - static DERIVED_TYPE* getIfExists() - { - return sData.mInstance; - } - - // Reference version of getInstance() - // Preferred over getInstance() as it disallows checking for NULL - static DERIVED_TYPE& instance() - { - return *getInstance(); - } - - // Has this singleton been created uet? - // Use this to avoid accessing singletons before the can safely be constructed - static bool instanceExists() - { - return sData.mInitState == INITIALIZED; - } - - // Has this singleton already been deleted? - // Use this to avoid accessing singletons from a static object's destructor - static bool destroyed() - { - return sData.mInitState == DELETED; - } + virtual ~LLSingleton() + { + // remove this instance from the master list + LLSingleton_manage_master<DERIVED_TYPE>().remove(this); + sData.mInstance = NULL; + sData.mInitState = DELETED; + } -private: + /** + * @brief Immediately delete the singleton. + * + * A subsequent call to LLProxy::getInstance() will construct a new + * instance of the class. + * + * Without an explicit call to LLSingletonBase::deleteAll(), LLSingletons + * are implicitly destroyed after main() has exited and the C++ runtime is + * cleaning up statically-constructed objects. Some classes derived from + * LLSingleton have objects that are part of a runtime system that is + * terminated before main() exits. Calling the destructor of those objects + * after the termination of their respective systems can cause crashes and + * other problems during termination of the project. Using this method to + * destroy the singleton early can prevent these crashes. + * + * An example where this is needed is for a LLSingleton that has an APR + * object as a member that makes APR calls on destruction. The APR system is + * shut down explicitly before main() exits. This causes a crash on exit. + * Using this method before the call to apr_terminate() and NOT calling + * getInstance() again will prevent the crash. + */ + static void deleteSingleton() + { + delete sData.mInstance; + sData.mInstance = NULL; + sData.mInitState = DELETED; + } + + static DERIVED_TYPE* getInstance() + { + static SingletonLifetimeManager sLifeTimeMgr; - virtual void initSingleton() {} + switch (sData.mInitState) + { + case UNINITIALIZED: + // should never be uninitialized at this point + logerrs("Uninitialized singleton ", + demangle(typeid(DERIVED_TYPE).name()).c_str()); + return NULL; - struct SingletonData - { - // explicitly has a default constructor so that member variables are zero initialized in BSS - // and only changed by singleton logic, not constructor running during startup - EInitState mInitState; - DERIVED_TYPE* mInstance; - }; - static SingletonData sData; + case CONSTRUCTING: + logerrs("Tried to access singleton ", + demangle(typeid(DERIVED_TYPE).name()).c_str(), + " from singleton constructor!"); + return NULL; + + case INITIALIZING: + // go ahead and flag ourselves as initialized so we can be + // reentrant during initialization + sData.mInitState = INITIALIZED; + // initialize singleton after constructing it so that it can + // reference other singletons which in turn depend on it, thus + // breaking cyclic dependencies + sData.mInstance->initSingleton(); + // pop this off stack of initializing singletons + LLSingleton_manage_master<DERIVED_TYPE>().pop_initializing(sData.mInstance); + break; + + case INITIALIZED: + break; + + case DELETED: + logwarns("Trying to access deleted singleton ", + demangle(typeid(DERIVED_TYPE).name()).c_str(), + " -- creating new instance"); + SingletonLifetimeManager::construct(); + // same as first time construction + sData.mInitState = INITIALIZED; + sData.mInstance->initSingleton(); + // pop this off stack of initializing singletons + LLSingleton_manage_master<DERIVED_TYPE>().pop_initializing(sData.mInstance); + break; + } + + // By this point, if DERIVED_TYPE was pushed onto the initializing + // stack, it has been popped off. So the top of that stack, if any, is + // an LLSingleton that directly depends on DERIVED_TYPE. If this call + // came from another LLSingleton, rather than from vanilla application + // code, record the dependency. + sData.mInstance->capture_dependency( + LLSingleton_manage_master<DERIVED_TYPE>().get_initializing(sData.mInstance), + sData.mInitState); + return sData.mInstance; + } + + // Reference version of getInstance() + // Preferred over getInstance() as it disallows checking for NULL + static DERIVED_TYPE& instance() + { + return *getInstance(); + } + + // Has this singleton been created yet? + // Use this to avoid accessing singletons before they can safely be constructed. + static bool instanceExists() + { + return sData.mInitState == INITIALIZED; + } + +private: + struct SingletonData + { + // explicitly has a default constructor so that member variables are zero initialized in BSS + // and only changed by singleton logic, not constructor running during startup + EInitState mInitState; + DERIVED_TYPE* mInstance; + }; + static SingletonData sData; }; template<typename T> typename LLSingleton<T>::SingletonData LLSingleton<T>::sData; +/** + * Use LLSINGLETON(Foo); at the start of an LLSingleton<Foo> subclass body + * when you want to declare an out-of-line constructor: + * + * @code + * class Foo: public LLSingleton<Foo> + * { + * // use this macro at start of every LLSingleton subclass + * LLSINGLETON(Foo); + * public: + * // ... + * }; + * // ... + * [inline] + * Foo::Foo() { ... } + * @endcode + * + * Unfortunately, this mechanism does not permit you to define even a simple + * (but nontrivial) constructor within the class body. If it's literally + * trivial, use LLSINGLETON_EMPTY_CTOR(); if not, use LLSINGLETON() and define + * the constructor outside the class body. If you must define it in a header + * file, use 'inline' (unless it's a template class) to avoid duplicate-symbol + * errors at link time. + */ +#define LLSINGLETON(DERIVED_CLASS) \ +private: \ + /* implement LLSingleton pure virtual method whose sole purpose */ \ + /* is to remind people to use this macro */ \ + virtual void you_must_use_LLSINGLETON_macro() {} \ + friend class LLSingleton<DERIVED_CLASS>; \ + DERIVED_CLASS() + +/** + * Use LLSINGLETON_EMPTY_CTOR(Foo); at the start of an LLSingleton<Foo> + * subclass body when the constructor is trivial: + * + * @code + * class Foo: public LLSingleton<Foo> + * { + * // use this macro at start of every LLSingleton subclass + * LLSINGLETON_EMPTY_CTOR(Foo); + * public: + * // ... + * }; + * @endcode + */ +#define LLSINGLETON_EMPTY_CTOR(DERIVED_CLASS) \ + /* LLSINGLETON() is carefully implemented to permit exactly this */ \ + LLSINGLETON(DERIVED_CLASS) {} + #endif diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 0435cb8a08d9515afda8ea2316719b86822c2234..b024b47225a873814b081e773fa8e5c5efb1c829 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -242,7 +242,6 @@ inline T* get_ptr_in_map(const std::map<K,T*>& inmap, const K& key) template <typename K, typename T> inline bool is_in_map(const std::map<K,T>& inmap, const K& key) { - typedef typename std::map<K,T>::const_iterator map_iter; if(inmap.find(key) == inmap.end()) { return false; diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index f3b8999883ab2d1892ee769fe66ca2b6409a4419..c45db3b1859d0a67d36ec9270d8ce69c7ed5ade7 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -576,6 +576,33 @@ std::string utf8str_truncate(const std::string& utf8str, const S32 max_len) } } +std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len) +{ + if (0 == symbol_len) + { + return std::string(); + } + if ((S32)utf8str.length() <= symbol_len) + { + return utf8str; + } + else + { + int len = 0, byteIndex = 0; + const char* aStr = utf8str.c_str(); + size_t origSize = utf8str.size(); + + for (byteIndex = 0; len < symbol_len && byteIndex < origSize; byteIndex++) + { + if ((aStr[byteIndex] & 0xc0) != 0x80) + { + len += 1; + } + } + return utf8str.substr(0, byteIndex); + } +} + std::string utf8str_substChar( const std::string& utf8str, const llwchar target_char, diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 393f6d7a8c1534ef0c796079c04f7136d8fb1bcd..2fdb8be84feeaf85b5154751710b5b44dc57ec30 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -443,7 +443,7 @@ class LLStringExplicit : public std::string struct LLDictionaryLess { public: - bool operator()(const std::string& a, const std::string& b) + bool operator()(const std::string& a, const std::string& b) const { return (LLStringUtil::precedesDict(a, b) ? true : false); } @@ -563,6 +563,17 @@ LL_COMMON_API S32 utf8str_compare_insensitive( const std::string& lhs, const std::string& rhs); +/** +* @brief Properly truncate a utf8 string to a maximum character count. +* +* If symbol_len is longer than the string passed in, the return +* value == utf8str. +* @param utf8str A valid utf8 string to truncate. +* @param symbol_len The maximum number of symbols in the return value. +* @return Returns a valid utf8 string with symbol count <= max_len. +*/ +LL_COMMON_API std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len); + /** * @brief Replace all occurences of target_char with replace_char * diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index c3f235c6ee3c78d80e19a38f1093653dcee40721..52255bfaeb58b8eb401193543ba28ecc354a37a8 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -63,7 +63,7 @@ void set_thread_name( DWORD dwThreadID, const char* threadName) __try { - ::RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info ); + ::RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR*)&info ); } __except(EXCEPTION_CONTINUE_EXECUTION) { diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp index 185f0d63fb4d536d9ac11ce064c2666ff15e7bc7..491f920c0f943c6be98b3078e45ee4583cf9f9e4 100644 --- a/indra/llcommon/llthreadsafequeue.cpp +++ b/indra/llcommon/llthreadsafequeue.cpp @@ -27,6 +27,7 @@ #include <apr_pools.h> #include <apr_queue.h> #include "llthreadsafequeue.h" +#include "llexception.h" @@ -41,13 +42,13 @@ LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * po { if(mOwnsPool) { apr_status_t status = apr_pool_create(&mPool, 0); - if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate pool"); + if(status != APR_SUCCESS) LLTHROW(LLThreadSafeQueueError("failed to allocate pool")); } else { ; // No op. } apr_status_t status = apr_queue_create(&mQueue, capacity, mPool); - if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue"); + if(status != APR_SUCCESS) LLTHROW(LLThreadSafeQueueError("failed to allocate queue")); } @@ -68,9 +69,9 @@ void LLThreadSafeQueueImplementation::pushFront(void * element) apr_status_t status = apr_queue_push(mQueue, element); if(status == APR_EINTR) { - throw LLThreadSafeQueueInterrupt(); + LLTHROW(LLThreadSafeQueueInterrupt()); } else if(status != APR_SUCCESS) { - throw LLThreadSafeQueueError("push failed"); + LLTHROW(LLThreadSafeQueueError("push failed")); } else { ; // Success. } @@ -88,9 +89,9 @@ void * LLThreadSafeQueueImplementation::popBack(void) apr_status_t status = apr_queue_pop(mQueue, &element); if(status == APR_EINTR) { - throw LLThreadSafeQueueInterrupt(); + LLTHROW(LLThreadSafeQueueInterrupt()); } else if(status != APR_SUCCESS) { - throw LLThreadSafeQueueError("pop failed"); + LLTHROW(LLThreadSafeQueueError("pop failed")); } else { return element; } diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 58cac38769cd2d3801fc9f01b1d1cc2a010ae0c6..45289ef0b400fa6a0f0b3f6d4b96ae1721cf12d7 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -27,9 +27,8 @@ #ifndef LL_LLTHREADSAFEQUEUE_H #define LL_LLTHREADSAFEQUEUE_H - +#include "llexception.h" #include <string> -#include <stdexcept> struct apr_pool_t; // From apr_pools.h @@ -40,11 +39,11 @@ class LLThreadSafeQueueImplementation; // See below. // A general queue exception. // class LL_COMMON_API LLThreadSafeQueueError: -public std::runtime_error + public LLException { public: LLThreadSafeQueueError(std::string const & message): - std::runtime_error(message) + LLException(message) { ; // No op. } diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 0b10438b9f1380da1b340fbc2c050a90c0592a14..3094b627a2f35b7ecfa8d30661196a6fbd7b4304 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -257,7 +257,13 @@ F64Kilobytes Recording::getMean(const StatType<MemAccumulator>& stat) if (active_accumulator && active_accumulator->mSize.hasValue()) { - return F64Bytes(lerp(accumulator.mSize.getMean(), active_accumulator->mSize.getMean(), active_accumulator->mSize.getSampleCount() / (accumulator.mSize.getSampleCount() + active_accumulator->mSize.getSampleCount()))); + F32 t = 0.0f; + S32 div = accumulator.mSize.getSampleCount() + active_accumulator->mSize.getSampleCount(); + if (div > 0) + { + t = active_accumulator->mSize.getSampleCount() / div; + } + return F64Bytes(lerp(accumulator.mSize.getMean(), active_accumulator->mSize.getMean(), t)); } else { @@ -426,7 +432,13 @@ F64 Recording::getMean( const StatType<SampleAccumulator>& stat ) const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL; if (active_accumulator && active_accumulator->hasValue()) { - return lerp(accumulator.getMean(), active_accumulator->getMean(), active_accumulator->getSampleCount() / (accumulator.getSampleCount() + active_accumulator->getSampleCount())); + F32 t = 0.0f; + S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount(); + if (div > 0) + { + t = active_accumulator->getSampleCount() / div; + } + return lerp(accumulator.getMean(), active_accumulator->getMean(), t); } else { @@ -506,7 +518,13 @@ F64 Recording::getMean( const StatType<EventAccumulator>& stat ) const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL; if (active_accumulator && active_accumulator->hasValue()) { - return lerp(accumulator.getMean(), active_accumulator->getMean(), active_accumulator->getSampleCount() / (accumulator.getSampleCount() + active_accumulator->getSampleCount())); + F32 t = 0.0f; + S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount(); + if (div > 0) + { + t = active_accumulator->getSampleCount() / div; + } + return lerp(accumulator.getMean(), active_accumulator->getMean(), t); } else { diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp index 82d0dc8b4b25889b35c12b64f53bcf3bc094573a..c275b90120d976123822300688aa568dbeda0efa 100644 --- a/indra/llcommon/lluriparser.cpp +++ b/indra/llcommon/lluriparser.cpp @@ -205,9 +205,9 @@ void LLUriParser::glue(std::string& uri) const uri = first_part + second_part; } -void LLUriParser::glueFirst(std::string& uri) const +void LLUriParser::glueFirst(std::string& uri, bool use_scheme) const { - if (mScheme.size()) + if (use_scheme && mScheme.size()) { uri = mScheme; uri += "://"; diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h index 2df8085ae6330582453cd0c0e839a97a5ad5994a..cfbf54f3c8592fb597a1c297988b67ff8d7ad96e 100644 --- a/indra/llcommon/lluriparser.h +++ b/indra/llcommon/lluriparser.h @@ -60,7 +60,7 @@ class LL_COMMON_API LLUriParser void extractParts(); void glue(std::string& uri) const; - void glueFirst(std::string& uri) const; + void glueFirst(std::string& uri, bool use_scheme = true) const; void glueSecond(std::string& uri) const; bool test() const; S32 normalize(); diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index e3671047b4a3375921aa6bbec95726931f227f47..d4af2c6b011f2cf261247a5a798ef051060c988c 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -83,7 +83,7 @@ unsigned int decode( char const * fiveChars ) throw( bad_input_data ) unsigned int ret = 0; for( int ix = 0; ix < 5; ++ix ) { char * s = strchr( encodeTable, fiveChars[ ix ] ); -if( s == 0 ) throw bad_input_data(); +if( s == 0 ) LLTHROW(bad_input_data()); ret = ret * 85 + (s-encodeTable); } return ret; diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index f51279e8172009f0b0475189313a0b25e3070b19..20de2054547b97d051393ce2b06c85d73ea08a1e 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -237,8 +237,21 @@ namespace tut void ErrorTestObject::test<4>() // file abbreviation { - std::string thisFile = __FILE__; - std::string abbreviateFile = LLError::abbreviateFile(thisFile); + std::string prev, abbreviateFile = __FILE__; + do + { + prev = abbreviateFile; + abbreviateFile = LLError::abbreviateFile(abbreviateFile); + // __FILE__ is assumed to end with + // indra/llcommon/tests/llerror_test.cpp. This test used to call + // abbreviateFile() exactly once, then check below whether it + // still contained the string 'indra'. That fails if the FIRST + // part of the pathname also contains indra! Certain developer + // machine images put local directory trees under + // /ngi-persist/indra, which is where we observe the problem. So + // now, keep calling abbreviateFile() until it returns its + // argument unchanged, THEN check. + } while (abbreviateFile != prev); ensure_ends_with("file name abbreviation", abbreviateFile, @@ -551,9 +564,9 @@ namespace tut function; writeReturningLocationAndFunction(location, function); - ensure_equals("order is location time type function message", + ensure_equals("order is time location type function message", message(0), - location + roswell() + " INFO: " + function + ": apple"); + roswell() + " INFO: " + location + function + ": apple"); } template<> template<> diff --git a/indra/llcommon/tests/llexception_test.cpp b/indra/llcommon/tests/llexception_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6bee1943c26a870517408eafdc7fdbdd8d804123 --- /dev/null +++ b/indra/llcommon/tests/llexception_test.cpp @@ -0,0 +1,308 @@ +/** + * @file llexception_test.cpp + * @author Nat Goodspeed + * @date 2016-08-12 + * @brief Tests for throwing exceptions. + * + * This isn't a regression test: it doesn't need to be run every build, which + * is why the corresponding line in llcommon/CMakeLists.txt is commented out. + * Rather it's a head-to-head test of what kind of exception information we + * can collect from various combinations of exception base classes, type of + * throw verb and sequences of catch clauses. + * + * This "test" makes no ensure() calls: its output goes to stdout for human + * examination. + * + * As of 2016-08-12 with Boost 1.57, we come to the following conclusions. + * These should probably be re-examined from time to time as we update Boost. + * + * - It is indisputably beneficial to use BOOST_THROW_EXCEPTION() rather than + * plain throw. The macro annotates the exception object with the filename, + * line number and function name from which the exception was thrown. + * + * - That being the case, deriving only from boost::exception isn't an option. + * Every exception object passed to BOOST_THROW_EXCEPTION() must be derived + * directly or indirectly from std::exception. The only question is whether + * to also derive from boost::exception. We decided to derive LLException + * from both, as it makes message output slightly cleaner, but this is a + * trivial reason: if a strong reason emerges to prefer single inheritance, + * dropping the boost::exception base class shouldn't be a problem. + * + * - (As you will have guessed, ridiculous things like a char* or int or a + * class derived from neither boost::exception nor std::exception can only + * be caught by that specific type or (...), and + * boost::current_exception_diagnostic_information() simply throws up its + * hands and confesses utter ignorance. Stay away from such nonsense.) + * + * - But if you derive from std::exception, to nat's surprise, + * boost::current_exception_diagnostic_information() gives as much + * information about exceptions in a catch (...) clause as you can get from + * a specific catch (const std::exception&) clause, notably the concrete + * exception class and the what() string. So instead of a sequence like + * + * try { ... } + * catch (const boost::exception& e) { ... boost-flavored logging ... } + * catch (const std::exception& e) { ... std::exception logging ... } + * catch (...) { ... generic logging ... } + * + * we should be able to get away with only a catch (...) clause that logs + * boost::current_exception_diagnostic_information(). + * + * - Going further: boost::current_exception_diagnostic_information() provides + * just as much information even within a std::set_terminate() handler. So + * it might not even be strictly necessary to include a catch (...) clause + * since the viewer does use std::set_terminate(). + * + * - (We might consider adding a catch (int) clause because Kakadu internally + * throws ints, and who knows if one of those might leak out. If it does, + * boost::current_exception_diagnostic_information() can do nothing with it. + * A catch (int) clause could at least log the value and rethrow.) + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llexception.h" +// STL headers +// std headers +#include <typeinfo> +// external library headers +#include <boost/throw_exception.hpp> +// other Linden headers +#include "../test/lltut.h" + +// helper for display output +// usage: std::cout << center(some string value, fill char, width) << std::endl; +// (assumes it's the only thing on that particular line) +struct center +{ + center(const std::string& label, char fill, std::size_t width): + mLabel(label), + mFill(fill), + mWidth(width) + {} + + // Use friend declaration not because we need to grant access, but because + // it lets us declare a free operator like a member function. + friend std::ostream& operator<<(std::ostream& out, const center& ctr) + { + std::size_t padded = ctr.mLabel.length() + 2; + std::size_t left = (ctr.mWidth - padded) / 2; + std::size_t right = ctr.mWidth - left - padded; + return out << std::string(left, ctr.mFill) << ' ' << ctr.mLabel << ' ' + << std::string(right, ctr.mFill); + } + + std::string mLabel; + char mFill; + std::size_t mWidth; +}; + +/***************************************************************************** +* Four kinds of exceptions: derived from boost::exception, from +* std::exception, from both, from neither +*****************************************************************************/ +// Interestingly, we can't use this variant with BOOST_THROW_EXCEPTION() +// (which we want) -- we reach a failure topped by this comment: +// //All boost exceptions are required to derive from std::exception, +// //to ensure compatibility with BOOST_NO_EXCEPTIONS. +struct FromBoost: public boost::exception +{ + FromBoost(const std::string& what): mWhat(what) {} + ~FromBoost() throw() {} + std::string what() const { return mWhat; } + std::string mWhat; +}; + +struct FromStd: public std::runtime_error +{ + FromStd(const std::string& what): std::runtime_error(what) {} +}; + +struct FromBoth: public boost::exception, public std::runtime_error +{ + FromBoth(const std::string& what): std::runtime_error(what) {} +}; + +// Same deal with FromNeither: can't use with BOOST_THROW_EXCEPTION(). +struct FromNeither +{ + FromNeither(const std::string& what): mWhat(what) {} + std::string what() const { return mWhat; } + std::string mWhat; +}; + +/***************************************************************************** +* Two kinds of throws: plain throw and BOOST_THROW_EXCEPTION() +*****************************************************************************/ +template <typename EXC> +void plain_throw(const std::string& what) +{ + throw EXC(what); +} + +template <typename EXC> +void boost_throw(const std::string& what) +{ + BOOST_THROW_EXCEPTION(EXC(what)); +} + +// Okay, for completeness, functions that throw non-class values. We wouldn't +// even deign to consider these if we hadn't found examples in our own source +// code! (Note that Kakadu's internal exception support is still based on +// throwing ints.) +void throw_char_ptr(const std::string& what) +{ + throw what.c_str(); // umm... +} + +void throw_int(const std::string& what) +{ + throw int(what.length()); +} + +/***************************************************************************** +* Three sequences of catch clauses: +* boost::exception then ..., +* std::exception then ..., +* or just ... +*****************************************************************************/ +void catch_boost_dotdotdot(void (*thrower)(const std::string&), const std::string& what) +{ + try + { + thrower(what); + } + catch (const boost::exception& e) + { + std::cout << "catch (const boost::exception& e)" << std::endl; + std::cout << "e is " << typeid(e).name() << std::endl; + std::cout << "boost::diagnostic_information(e):\n'" + << boost::diagnostic_information(e) << "'" << std::endl; + // no way to report e.what() + } + catch (...) + { + std::cout << "catch (...)" << std::endl; + std::cout << "boost::current_exception_diagnostic_information():\n'" + << boost::current_exception_diagnostic_information() << "'" + << std::endl; + } +} + +void catch_std_dotdotdot(void (*thrower)(const std::string&), const std::string& what) +{ + try + { + thrower(what); + } + catch (const std::exception& e) + { + std::cout << "catch (const std::exception& e)" << std::endl; + std::cout << "e is " << typeid(e).name() << std::endl; + std::cout << "boost::diagnostic_information(e):\n'" + << boost::diagnostic_information(e) << "'" << std::endl; + std::cout << "e.what: '" + << e.what() << "'" << std::endl; + } + catch (...) + { + std::cout << "catch (...)" << std::endl; + std::cout << "boost::current_exception_diagnostic_information():\n'" + << boost::current_exception_diagnostic_information() << "'" + << std::endl; + } +} + +void catch_dotdotdot(void (*thrower)(const std::string&), const std::string& what) +{ + try + { + thrower(what); + } + catch (...) + { + std::cout << "catch (...)" << std::endl; + std::cout << "boost::current_exception_diagnostic_information():\n'" + << boost::current_exception_diagnostic_information() << "'" + << std::endl; + } +} + +/***************************************************************************** +* Try a particular kind of throw against each of three catch sequences +*****************************************************************************/ +void catch_several(void (*thrower)(const std::string&), const std::string& what) +{ + std::cout << std::string(20, '-') << "catch_boost_dotdotdot(" << what << ")" << std::endl; + catch_boost_dotdotdot(thrower, "catch_boost_dotdotdot(" + what + ")"); + + std::cout << std::string(20, '-') << "catch_std_dotdotdot(" << what << ")" << std::endl; + catch_std_dotdotdot(thrower, "catch_std_dotdotdot(" + what + ")"); + + std::cout << std::string(20, '-') << "catch_dotdotdot(" << what << ")" << std::endl; + catch_dotdotdot(thrower, "catch_dotdotdot(" + what + ")"); +} + +/***************************************************************************** +* For a particular kind of exception, try both kinds of throw against all +* three catch sequences +*****************************************************************************/ +template <typename EXC> +void catch_both_several(const std::string& what) +{ + std::cout << std::string(20, '*') << "plain_throw<" << what << ">" << std::endl; + catch_several(plain_throw<EXC>, "plain_throw<" + what + ">"); + + std::cout << std::string(20, '*') << "boost_throw<" << what << ">" << std::endl; + catch_several(boost_throw<EXC>, "boost_throw<" + what + ">"); +} + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct llexception_data + { + }; + typedef test_group<llexception_data> llexception_group; + typedef llexception_group::object object; + llexception_group llexceptiongrp("llexception"); + + template<> template<> + void object::test<1>() + { + set_test_name("throwing exceptions"); + + // For each kind of exception, try both kinds of throw against all + // three catch sequences + std::size_t margin = 72; + std::cout << center("FromStd", '=', margin) << std::endl; + catch_both_several<FromStd>("FromStd"); + + std::cout << center("FromBoth", '=', margin) << std::endl; + catch_both_several<FromBoth>("FromBoth"); + + std::cout << center("FromBoost", '=', margin) << std::endl; + // can't throw with BOOST_THROW_EXCEPTION(), just use catch_several() + catch_several(plain_throw<FromBoost>, "plain_throw<FromBoost>"); + + std::cout << center("FromNeither", '=', margin) << std::endl; + // can't throw this with BOOST_THROW_EXCEPTION() either + catch_several(plain_throw<FromNeither>, "plain_throw<FromNeither>"); + + std::cout << center("const char*", '=', margin) << std::endl; + // We don't expect BOOST_THROW_EXCEPTION() to throw anything so daft + // as a const char* or an int, so don't bother with + // catch_both_several() -- just catch_several(). + catch_several(throw_char_ptr, "throw_char_ptr"); + + std::cout << center("int", '=', margin) << std::endl; + catch_several(throw_int, "throw_int"); + } +} // namespace tut diff --git a/indra/llcommon/tests/llheteromap_test.cpp b/indra/llcommon/tests/llheteromap_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..686bffb878b44c8de1da45fb45d80e606cbb1127 --- /dev/null +++ b/indra/llcommon/tests/llheteromap_test.cpp @@ -0,0 +1,163 @@ +/** + * @file llheteromap_test.cpp + * @author Nat Goodspeed + * @date 2016-10-12 + * @brief Test for llheteromap. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llheteromap.h" +// STL headers +#include <set> +// std headers +// external library headers + +// (pacify clang) +std::ostream& operator<<(std::ostream& out, const std::set<std::string>& strset); +// other Linden headers +#include "../test/lltut.h" + +static std::string clog; +static std::set<std::string> dlog; + +// want to be able to use ensure_equals() on a set<string> +std::ostream& operator<<(std::ostream& out, const std::set<std::string>& strset) +{ + out << '{'; + const char* delim = ""; + for (std::set<std::string>::const_iterator si(strset.begin()), se(strset.end()); + si != se; ++si) + { + out << delim << '"' << *si << '"'; + delim = ", "; + } + out << '}'; + return out; +} + +// unrelated test classes +struct Chalk +{ + int dummy; + std::string name; + + Chalk(): + dummy(0) + { + clog.append("a"); + } + + ~Chalk() + { + dlog.insert("a"); + } + +private: + Chalk(const Chalk&); // no implementation +}; + +struct Cheese +{ + std::string name; + + Cheese() + { + clog.append("e"); + } + + ~Cheese() + { + dlog.insert("e"); + } + +private: + Cheese(const Cheese&); // no implementation +}; + +struct Chowdah +{ + char displace[17]; + std::string name; + + Chowdah() + { + displace[0] = '\0'; + clog.append("o"); + } + + ~Chowdah() + { + dlog.insert("o"); + } + +private: + Chowdah(const Chowdah&); // no implementation +}; + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct llheteromap_data + { + llheteromap_data() + { + clog.erase(); + dlog.clear(); + } + }; + typedef test_group<llheteromap_data> llheteromap_group; + typedef llheteromap_group::object object; + llheteromap_group llheteromapgrp("llheteromap"); + + template<> template<> + void object::test<1>() + { + set_test_name("create, get, delete"); + + { + LLHeteroMap map; + + { + // create each instance + Chalk& chalk = map.obtain<Chalk>(); + chalk.name = "Chalk"; + + Cheese& cheese = map.obtain<Cheese>(); + cheese.name = "Cheese"; + + Chowdah& chowdah = map.obtain<Chowdah>(); + chowdah.name = "Chowdah"; + } // refs go out of scope + + { + // verify each instance + Chalk& chalk = map.obtain<Chalk>(); + ensure_equals(chalk.name, "Chalk"); + + Cheese& cheese = map.obtain<Cheese>(); + ensure_equals(cheese.name, "Cheese"); + + Chowdah& chowdah = map.obtain<Chowdah>(); + ensure_equals(chowdah.name, "Chowdah"); + } + } // destroy map + + // Chalk, Cheese and Chowdah should have been created in specific order + ensure_equals(clog, "aeo"); + + // We don't care what order they're destroyed in, as long as each is + // appropriately destroyed. + std::set<std::string> dtorset; + for (const char* cp = "aeo"; *cp; ++cp) + dtorset.insert(std::string(1, *cp)); + ensure_equals(dlog, dtorset); + } +} // namespace tut diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp index d342dece8425e28300f45a392f06d1bc8b00aca4..c387da6c4828b4806b1e913e614fcef8d5a7ff1b 100644 --- a/indra/llcommon/tests/llleap_test.cpp +++ b/indra/llcommon/tests/llleap_test.cpp @@ -110,10 +110,7 @@ namespace tut // finding indra/lib/python. Use our __FILE__, with // raw-string syntax to deal with Windows pathnames. "mydir = os.path.dirname(r'" << __FILE__ << "')\n" - // We expect mydir to be .../indra/llcommon/tests. - "sys.path.insert(0,\n" - " os.path.join(mydir, os.pardir, os.pardir, 'lib', 'python'))\n" - "from indra.base import llsd\n" + "from llbase import llsd\n" "\n" "class ProtocolError(Exception):\n" " def __init__(self, msg, data):\n" diff --git a/indra/llcommon/tests/llpounceable_test.cpp b/indra/llcommon/tests/llpounceable_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2f4915ce11a4eb7f4f76cc032dd12890e370dd19 --- /dev/null +++ b/indra/llcommon/tests/llpounceable_test.cpp @@ -0,0 +1,230 @@ +/** + * @file llpounceable_test.cpp + * @author Nat Goodspeed + * @date 2015-05-22 + * @brief Test for llpounceable. + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Copyright (c) 2015, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llpounceable.h" +// STL headers +// std headers +// external library headers +#include <boost/bind.hpp> +// other Linden headers +#include "../test/lltut.h" + +/*----------------------------- string testing -----------------------------*/ +void append(std::string* dest, const std::string& src) +{ + dest->append(src); +} + +/*-------------------------- Data-struct testing ---------------------------*/ +struct Data +{ + Data(const std::string& data): + mData(data) + {} + const std::string mData; +}; + +void setter(Data** dest, Data* ptr) +{ + *dest = ptr; +} + +static Data* static_check = 0; + +// Set up an extern pointer to an LLPounceableStatic so the linker will fill +// in the forward reference from below, before runtime. +extern LLPounceable<Data*, LLPounceableStatic> gForward; + +struct EnqueueCall +{ + EnqueueCall() + { + // Intentionally use a forward reference to an LLPounceableStatic that + // we believe is NOT YET CONSTRUCTED. This models the scenario in + // which a constructor in another translation unit runs before + // constructors in this one. We very specifically want callWhenReady() + // to work even in that case: we need the LLPounceableQueueImpl to be + // initialized even if the LLPounceable itself is not. + gForward.callWhenReady(boost::bind(setter, &static_check, _1)); + } +} nqcall; +// When this declaration is processed, we should enqueue the +// setter(&static_check, _1) call for when gForward is set non-NULL. Needless +// to remark, we want this call not to crash. + +// Now declare gForward. Its constructor should not run until after nqcall's. +LLPounceable<Data*, LLPounceableStatic> gForward; + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct llpounceable_data + { + }; + typedef test_group<llpounceable_data> llpounceable_group; + typedef llpounceable_group::object object; + llpounceable_group llpounceablegrp("llpounceable"); + + template<> template<> + void object::test<1>() + { + set_test_name("LLPounceableStatic out-of-order test"); + // LLPounceable<T, LLPounceableStatic>::callWhenReady() must work even + // before LLPounceable's constructor runs. That's the whole point of + // implementing it with an LLSingleton queue. This models (say) + // LLPounceableStatic<LLMessageSystem*, LLPounceableStatic>. + ensure("static_check should still be null", ! static_check); + Data myData("test<1>"); + gForward = &myData; // should run setter + ensure_equals("static_check should be &myData", static_check, &myData); + } + + template<> template<> + void object::test<2>() + { + set_test_name("LLPounceableQueue different queues"); + // We expect that LLPounceable<T, LLPounceableQueue> should have + // different queues because that specialization stores the queue + // directly in the LLPounceable instance. + Data *aptr = 0, *bptr = 0; + LLPounceable<Data*> a, b; + a.callWhenReady(boost::bind(setter, &aptr, _1)); + b.callWhenReady(boost::bind(setter, &bptr, _1)); + ensure("aptr should be null", ! aptr); + ensure("bptr should be null", ! bptr); + Data adata("a"), bdata("b"); + a = &adata; + ensure_equals("aptr should be &adata", aptr, &adata); + // but we haven't yet set b + ensure("bptr should still be null", !bptr); + b = &bdata; + ensure_equals("bptr should be &bdata", bptr, &bdata); + } + + template<> template<> + void object::test<3>() + { + set_test_name("LLPounceableStatic different queues"); + // LLPounceable<T, LLPounceableStatic> should also have a distinct + // queue for each instance, but that engages an additional map lookup + // because there's only one LLSingleton for each T. + Data *aptr = 0, *bptr = 0; + LLPounceable<Data*, LLPounceableStatic> a, b; + a.callWhenReady(boost::bind(setter, &aptr, _1)); + b.callWhenReady(boost::bind(setter, &bptr, _1)); + ensure("aptr should be null", ! aptr); + ensure("bptr should be null", ! bptr); + Data adata("a"), bdata("b"); + a = &adata; + ensure_equals("aptr should be &adata", aptr, &adata); + // but we haven't yet set b + ensure("bptr should still be null", !bptr); + b = &bdata; + ensure_equals("bptr should be &bdata", bptr, &bdata); + } + + template<> template<> + void object::test<4>() + { + set_test_name("LLPounceable<T> looks like T"); + // We want LLPounceable<T, TAG> to be drop-in replaceable for a plain + // T for read constructs. In particular, it should behave like a dumb + // pointer -- and with zero abstraction cost for such usage. + Data* aptr = 0; + Data a("a"); + // should be able to initialize a pounceable (when its constructor + // runs) + LLPounceable<Data*> pounceable(&a); + // should be able to pass LLPounceable<T> to function accepting T + setter(&aptr, pounceable); + ensure_equals("aptr should be &a", aptr, &a); + // should be able to dereference with * + ensure_equals("deref with *", (*pounceable).mData, "a"); + // should be able to dereference with -> + ensure_equals("deref with ->", pounceable->mData, "a"); + // bool operations + ensure("test with operator bool()", pounceable); + ensure("test with operator !()", ! (! pounceable)); + } + + template<> template<> + void object::test<5>() + { + set_test_name("Multiple callWhenReady() queue items"); + Data *p1 = 0, *p2 = 0, *p3 = 0; + Data a("a"); + LLPounceable<Data*> pounceable; + // queue up a couple setter() calls for later + pounceable.callWhenReady(boost::bind(setter, &p1, _1)); + pounceable.callWhenReady(boost::bind(setter, &p2, _1)); + // should still be pending + ensure("p1 should be null", !p1); + ensure("p2 should be null", !p2); + ensure("p3 should be null", !p3); + pounceable = 0; + // assigning a new empty value shouldn't flush the queue + ensure("p1 should still be null", !p1); + ensure("p2 should still be null", !p2); + ensure("p3 should still be null", !p3); + // using whichever syntax + pounceable.reset(0); + // try to make ensure messages distinct... tough to pin down which + // ensure() failed if multiple ensure() calls in the same test<n> have + // the same message! + ensure("p1 should again be null", !p1); + ensure("p2 should again be null", !p2); + ensure("p3 should again be null", !p3); + pounceable.reset(&a); // should flush queue + ensure_equals("p1 should be &a", p1, &a); + ensure_equals("p2 should be &a", p2, &a); + ensure("p3 still not set", !p3); + // immediate call + pounceable.callWhenReady(boost::bind(setter, &p3, _1)); + ensure_equals("p3 should be &a", p3, &a); + } + + template<> template<> + void object::test<6>() + { + set_test_name("queue order"); + std::string data; + LLPounceable<std::string*> pounceable; + pounceable.callWhenReady(boost::bind(append, _1, "a")); + pounceable.callWhenReady(boost::bind(append, _1, "b")); + pounceable.callWhenReady(boost::bind(append, _1, "c")); + pounceable = &data; + ensure_equals("callWhenReady() must preserve chronological order", + data, "abc"); + + std::string data2; + pounceable = NULL; + pounceable.callWhenReady(boost::bind(append, _1, "d")); + pounceable.callWhenReady(boost::bind(append, _1, "e")); + pounceable.callWhenReady(boost::bind(append, _1, "f")); + pounceable = &data2; + ensure_equals("LLPounceable must reset queue when fired", + data2, "def"); + } + + template<> template<> + void object::test<7>() + { + set_test_name("compile-fail test, uncomment to check"); + // The following declaration should fail: only LLPounceableQueue and + // LLPounceableStatic should work as tags. +// LLPounceable<Data*, int> pounceable; + } +} // namespace tut diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp index 6fbb9abfc001b4dabe91b3dd8b413653fb66de31..81b930e1e2ce698bf4f4628e11c231839896b9b5 100644 --- a/indra/llcommon/tests/llsdserialize_test.cpp +++ b/indra/llcommon/tests/llsdserialize_test.cpp @@ -1518,10 +1518,7 @@ namespace tut // scanner. import_llsd("import os.path\n" "import sys\n" - "sys.path.insert(0,\n" - " os.path.join(os.path.dirname(r'" __FILE__ "'),\n" - " os.pardir, os.pardir, 'lib', 'python'))\n" - "from indra.base import llsd\n") + "from llbase import llsd\n") {} ~TestPythonCompatible() {} diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp index 385289aefef69b16997148840929fe7b94963c3f..56886bc73fd9185932f76c82d0d72232cc5c4e5c 100644 --- a/indra/llcommon/tests/llsingleton_test.cpp +++ b/indra/llcommon/tests/llsingleton_test.cpp @@ -30,47 +30,172 @@ #include "llsingleton.h" #include "../test/lltut.h" + +// Capture execution sequence by appending to log string. +std::string sLog; + +#define DECLARE_CLASS(CLS) \ +struct CLS: public LLSingleton<CLS> \ +{ \ + LLSINGLETON(CLS); \ + ~CLS(); \ +public: \ + static enum dep_flag { \ + DEP_NONE, /* no dependency */ \ + DEP_CTOR, /* dependency in ctor */ \ + DEP_INIT /* dependency in initSingleton */ \ + } sDepFlag; \ + \ + void initSingleton(); \ + void cleanupSingleton(); \ +}; \ + \ +CLS::dep_flag CLS::sDepFlag = DEP_NONE + +DECLARE_CLASS(A); +DECLARE_CLASS(B); + +#define DEFINE_MEMBERS(CLS, OTHER) \ +CLS::CLS() \ +{ \ + sLog.append(#CLS); \ + if (sDepFlag == DEP_CTOR) \ + { \ + (void)OTHER::instance(); \ + } \ +} \ + \ +void CLS::initSingleton() \ +{ \ + sLog.append("i" #CLS); \ + if (sDepFlag == DEP_INIT) \ + { \ + (void)OTHER::instance(); \ + } \ +} \ + \ +void CLS::cleanupSingleton() \ +{ \ + sLog.append("x" #CLS); \ +} \ + \ +CLS::~CLS() \ +{ \ + sLog.append("~" #CLS); \ +} + +DEFINE_MEMBERS(A, B) +DEFINE_MEMBERS(B, A) + namespace tut { - struct singleton - { - // We need a class created with the LLSingleton template to test with. - class LLSingletonTest: public LLSingleton<LLSingletonTest> - { - - }; - }; - - typedef test_group<singleton> singleton_t; - typedef singleton_t::object singleton_object_t; - tut::singleton_t tut_singleton("LLSingleton"); - - template<> template<> - void singleton_object_t::test<1>() - { - - } - template<> template<> - void singleton_object_t::test<2>() - { - LLSingletonTest* singleton_test = LLSingletonTest::getInstance(); - ensure(singleton_test); - } - template<> template<> - void singleton_object_t::test<3>() - { - //Construct the instance - LLSingletonTest::getInstance(); - ensure(LLSingletonTest::instanceExists()); - - //Delete the instance - LLSingletonTest::deleteSingleton(); - ensure(LLSingletonTest::destroyed()); - ensure(!LLSingletonTest::instanceExists()); - - //Construct it again. - LLSingletonTest* singleton_test = LLSingletonTest::getInstance(); - ensure(singleton_test); - ensure(LLSingletonTest::instanceExists()); - } + struct singleton + { + // We need a class created with the LLSingleton template to test with. + class LLSingletonTest: public LLSingleton<LLSingletonTest> + { + LLSINGLETON_EMPTY_CTOR(LLSingletonTest); + }; + }; + + typedef test_group<singleton> singleton_t; + typedef singleton_t::object singleton_object_t; + tut::singleton_t tut_singleton("LLSingleton"); + + template<> template<> + void singleton_object_t::test<1>() + { + + } + template<> template<> + void singleton_object_t::test<2>() + { + LLSingletonTest* singleton_test = LLSingletonTest::getInstance(); + ensure(singleton_test); + } + + template<> template<> + void singleton_object_t::test<3>() + { + //Construct the instance + LLSingletonTest::getInstance(); + ensure(LLSingletonTest::instanceExists()); + + //Delete the instance + LLSingletonTest::deleteSingleton(); + ensure(!LLSingletonTest::instanceExists()); + + //Construct it again. + LLSingletonTest* singleton_test = LLSingletonTest::getInstance(); + ensure(singleton_test); + ensure(LLSingletonTest::instanceExists()); + } + +#define TESTS(CLS, OTHER, N0, N1, N2, N3) \ + template<> template<> \ + void singleton_object_t::test<N0>() \ + { \ + set_test_name("just " #CLS); \ + CLS::sDepFlag = CLS::DEP_NONE; \ + OTHER::sDepFlag = OTHER::DEP_NONE; \ + sLog.clear(); \ + \ + (void)CLS::instance(); \ + ensure_equals(sLog, #CLS "i" #CLS); \ + LLSingletonBase::cleanupAll(); \ + ensure_equals(sLog, #CLS "i" #CLS "x" #CLS); \ + LLSingletonBase::deleteAll(); \ + ensure_equals(sLog, #CLS "i" #CLS "x" #CLS "~" #CLS); \ + } \ + \ + template<> template<> \ + void singleton_object_t::test<N1>() \ + { \ + set_test_name(#CLS " ctor depends " #OTHER); \ + CLS::sDepFlag = CLS::DEP_CTOR; \ + OTHER::sDepFlag = OTHER::DEP_NONE; \ + sLog.clear(); \ + \ + (void)CLS::instance(); \ + ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS); \ + LLSingletonBase::cleanupAll(); \ + ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS "x" #CLS "x" #OTHER); \ + LLSingletonBase::deleteAll(); \ + ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \ + } \ + \ + template<> template<> \ + void singleton_object_t::test<N2>() \ + { \ + set_test_name(#CLS " init depends " #OTHER); \ + CLS::sDepFlag = CLS::DEP_INIT; \ + OTHER::sDepFlag = OTHER::DEP_NONE; \ + sLog.clear(); \ + \ + (void)CLS::instance(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER); \ + LLSingletonBase::cleanupAll(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER); \ + LLSingletonBase::deleteAll(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \ + } \ + \ + template<> template<> \ + void singleton_object_t::test<N3>() \ + { \ + set_test_name(#CLS " circular init"); \ + CLS::sDepFlag = CLS::DEP_INIT; \ + OTHER::sDepFlag = OTHER::DEP_CTOR; \ + sLog.clear(); \ + \ + (void)CLS::instance(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER); \ + LLSingletonBase::cleanupAll(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER); \ + LLSingletonBase::deleteAll(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \ + } + + TESTS(A, B, 4, 5, 6, 7) + TESTS(B, A, 8, 9, 10, 11) } diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index 785197ba111fda1139b6cfbda6494faee726ffd6..9a4bbbd630d002a6effa410c39e737f0dfc23d89 100644 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -35,13 +35,13 @@ #include <tut/tut.hpp> #include "llerrorcontrol.h" +#include "llexception.h" #include "stringize.h" #include <boost/bind.hpp> #include <boost/noncopyable.hpp> #include <boost/shared_ptr.hpp> #include <list> #include <string> -#include <stdexcept> // statically reference the function in test.cpp... it's short, we could // replicate, but better to reuse @@ -67,9 +67,9 @@ struct WrapLLErrs LLError::restoreSettings(mPriorErrorSettings); } - struct FatalException: public std::runtime_error + struct FatalException: public LLException { - FatalException(const std::string& what): std::runtime_error(what) {} + FatalException(const std::string& what): LLException(what) {} }; void operator()(const std::string& message) @@ -78,7 +78,7 @@ struct WrapLLErrs error = message; // Also throw an appropriate exception since calling code is likely to // assume that control won't continue beyond LL_ERRS. - throw FatalException(message); + LLTHROW(FatalException(message)); } std::string error; diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 0bb0348d26b9f9a8112e104ba91fde2f1ea89fad..7482fc577f551c3f97a2366be7b46fc2b29bcf17 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -93,6 +93,7 @@ target_link_libraries( ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${BOOST_THREAD_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ) # tests @@ -129,8 +130,8 @@ if (LL_TESTS) ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} - ${BOOST_SYSTEM_LIBRARY} ${BOOST_THREAD_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ) # If http_proxy is in the current environment (e.g. to fetch s3-proxy @@ -147,7 +148,7 @@ if (LL_TESTS) if (DARWIN) # Path inside the app bundle where we'll need to copy libraries set(LL_TEST_DESTINATION_DIR - ${CMAKE_SOURCE_DIR}/../build-darwin-i386/sharedlibs/Resources + ${CMAKE_BINARY_DIR}/sharedlibs/Resources ) # Create the Contents/Resources directory @@ -163,21 +164,23 @@ if (DARWIN) # Copy the required libraries to the package app add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib ${LL_TEST_DESTINATION_DIR} - DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib - ) - add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib ${LL_TEST_DESTINATION_DIR} - DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib + COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib ${LL_TEST_DESTINATION_DIR} + DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib ) add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib ${LL_TEST_DESTINATION_DIR} - DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib + COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib ${LL_TEST_DESTINATION_DIR} + DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib ) add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib ${LL_TEST_DESTINATION_DIR} - DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib + COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib ${LL_TEST_DESTINATION_DIR} + DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib ) + foreach(expat ${EXPAT_COPY}) + add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} ${LL_TEST_DESTINATION_DIR} + DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} + ) + endforeach(expat) endif (DARWIN) @@ -197,8 +200,8 @@ endif (DARWIN) ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} - ${BOOST_SYSTEM_LIBRARY} ${BOOST_THREAD_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ) add_executable(http_texture_load @@ -213,7 +216,7 @@ endif (DARWIN) # The following come from LLAddBuildTest.cmake's INTEGRATION_TEST_xxxx target. set_target_properties(http_texture_load PROPERTIES - LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:CONSOLE ${TCMALLOC_LINK_FLAGS}" + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:CONSOLE" LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" LINK_FLAGS_RELEASE "" ) diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index db57869a1bb323109bec3a664f6298bd9f75c66d..07cc0e462556fd6b2a518eef19663e2eed5fd29b 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -568,7 +568,17 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) // Use the viewer-based thread-safe API which has a // fast/safe check for proxy enable. Would like to // encapsulate this someway... - LLProxy::getInstance()->applyProxySettings(mCurlHandle); + if (LLProxy::instanceExists()) + { + // Make sure proxy won't be initialized from here, + // it might conflict with LLStartUp::startLLProxy() + LLProxy::getInstance()->applyProxySettings(mCurlHandle); + } + else + { + LL_WARNS() << "Proxy is not initialized!" << LL_ENDL; + } + } else if (gpolicy.mHttpProxy.size()) { diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp index c423047bb08fa6756461e69b5bdbec41f1bafb41..1829062af6426b1137323214aec283a8ecb9a475 100644 --- a/indra/llcorehttp/httpcommon.cpp +++ b/indra/llcorehttp/httpcommon.cpp @@ -50,11 +50,12 @@ HttpStatus::type_enum_t EXT_CURL_EASY; HttpStatus::type_enum_t EXT_CURL_MULTI; HttpStatus::type_enum_t LLCORE; -HttpStatus::operator unsigned long() const +HttpStatus::operator U32() const { - static const int shift(sizeof(unsigned long) * 4); + // Effectively, concatenate mType (high) with mStatus (low). + static const int shift(sizeof(mDetails->mStatus) * 8); - unsigned long result(((unsigned long)mDetails->mType) << shift | (unsigned long)(int)mDetails->mStatus); + U32 result(U32(mDetails->mType) << shift | U32((int)mDetails->mStatus)); return result; } @@ -64,7 +65,7 @@ std::string HttpStatus::toHex() const std::ostringstream result; result.width(8); result.fill('0'); - result << std::hex << operator unsigned long(); + result << std::hex << operator U32(); return result.str(); } diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h index b2db01d0387a6432b0d7fdc2906282b565480b7b..ea0c38abd7a09ea568f42b8c982bfd7cc20f7d7f 100644 --- a/indra/llcorehttp/httpcommon.h +++ b/indra/llcorehttp/httpcommon.h @@ -382,10 +382,10 @@ struct HttpStatus /// creates an ambiguous second path to integer conversion /// which tends to find programming errors such as formatting /// the status to a stream (operator<<). - operator unsigned long() const; - unsigned long toULong() const + operator U32() const; + U32 toULong() const { - return operator unsigned long(); + return operator U32(); } /// And to convert to a hex string. diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp old mode 100644 new mode 100755 index bef762f5ce5b4a526aaade6d4c0be97595cb20dc..a310fc0508e1e3d5ebc8f681233665d6a4978bbf --- a/indra/llcorehttp/tests/llcorehttp_test.cpp +++ b/indra/llcorehttp/tests/llcorehttp_test.cpp @@ -46,6 +46,7 @@ #include "test_httprequestqueue.hpp" #include "llproxy.h" +#include "llcleanup.h" unsigned long ssl_thread_id_callback(void); void ssl_locking_callback(int mode, int type, const char * file, int line); @@ -101,7 +102,7 @@ void init_curl() void term_curl() { - LLProxy::cleanupClass(); + SUBSYSTEM_CLEANUP(LLProxy); CRYPTO_set_locking_callback(NULL); for (int i(0); i < ssl_mutex_count; ++i) diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index 463e55dd7e7595c6a7f6f11a307135f3f9ded2d7..a9c192e141c2e0258df705bac82c8416e5cd9e1a 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -729,7 +729,7 @@ void HttpRequestTestObjectType::test<7>() #if 0 // defined(WIN32) // Can't do this on any platform anymore, the LL logging system holds // on to memory and produces what looks like memory leaks... - + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); #endif @@ -1459,21 +1459,21 @@ void HttpRequestTestObjectType::test<14>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; HttpRequest * req = NULL; HttpOptions::ptr_t opts; - + try { - // Get singletons created + // Get singletons created HttpRequest::createService(); - + // Start threading early so that thread memory is invariant // over the test. HttpRequest::startThread(); @@ -1482,10 +1482,10 @@ void HttpRequestTestObjectType::test<14>() req = new HttpRequest(); ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); - opts = HttpOptions::ptr_t(new HttpOptions); - opts->setRetries(0); // Don't retry + opts = HttpOptions::ptr_t(new HttpOptions); + opts->setRetries(0); // Don't retry opts->setTimeout(2); - + // Issue a GET that sleeps mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, @@ -1494,8 +1494,8 @@ void HttpRequestTestObjectType::test<14>() 0, 0, opts, - HttpHeaders::ptr_t(), - handlerp); + HttpHeaders::ptr_t(), + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -1513,7 +1513,7 @@ void HttpRequestTestObjectType::test<14>() mStatus = HttpStatus(); handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - + // Run the notification pump again count = 0; limit = LOOP_COUNT_LONG; @@ -1535,30 +1535,29 @@ void HttpRequestTestObjectType::test<14>() ensure("Thread actually stopped running", HttpService::isStopped()); // release options - opts.reset(); - + opts.reset(); + // release the request object delete req; req = NULL; // Shut down service HttpRequest::destroyService(); - + ensure("Two handler calls on the way out", 2 == mHandlerCalls); -#if defined(WIN32) - // Can only do this memory test on Windows. On other platforms, - // the LL logging system holds on to memory and produces what looks - // like memory leaks... - - // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); +#if 0 // defined(WIN32) + // Can't do this on any platform anymore, the LL logging system holds + // on to memory and produces what looks like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); #endif } catch (...) { stop_thread(req); - opts.reset(); + opts.reset(); delete req; HttpRequest::destroyService(); throw; @@ -3065,12 +3064,11 @@ void HttpRequestTestObjectType::test<22>() // Shut down service HttpRequest::destroyService(); - -#if defined(WIN32) - // Can only do this memory test on Windows. On other platforms, - // the LL logging system holds on to memory and produces what looks - // like memory leaks... - + +#if 0 // defined(WIN32) + // Can't do this on any platform anymore, the LL logging system holds + // on to memory and produces what looks like memory leaks... + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); #endif @@ -3091,6 +3089,10 @@ void HttpRequestTestObjectType::test<23>() set_test_name("HttpRequest GET 503s with 'Retry-After'"); +#if LL_WINDOWS && ADDRESS_SIZE == 64 + skip("llcorehttp 503-with-retry test hangs on Windows 64"); +#endif + // This tests mainly that the code doesn't fall over if // various well- and mis-formed Retry-After headers are // sent along with the response. Direct inspection of @@ -3195,12 +3197,11 @@ void HttpRequestTestObjectType::test<23>() // Shut down service HttpRequest::destroyService(); - -#if defined(WIN32) - // Can only do this memory test on Windows. On other platforms, - // the LL logging system holds on to memory and produces what looks - // like memory leaks... - + +#if 0 // defined(WIN32) + // Can't do this on any platform anymore, the LL logging system holds + // on to memory and produces what looks like memory leaks... + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); #endif diff --git a/indra/llcorehttp/tests/test_httpstatus.hpp b/indra/llcorehttp/tests/test_httpstatus.hpp index 4502d32fe1f0f6c9eb96bb3bebca02442aab3be8..cbe3f574d41670541f0f2185963b8fa33325b2ea 100644 --- a/indra/llcorehttp/tests/test_httpstatus.hpp +++ b/indra/llcorehttp/tests/test_httpstatus.hpp @@ -244,7 +244,7 @@ void HttpStatusTestObjectType::test<7>() HttpStatus status(404); std::string msg = status.toHex(); // std::cout << "Result: " << msg << std::endl; - ensure(msg == "01940001"); + ensure_equals(msg, "01940001"); } diff --git a/indra/llcorehttp/tests/test_llcorehttp_peer.py b/indra/llcorehttp/tests/test_llcorehttp_peer.py index 04cde651c452f288a953e70d77f48e6c2dd9f828..493143641b04cdbb979c7dd932e4144c4010e50c 100755 --- a/indra/llcorehttp/tests/test_llcorehttp_peer.py +++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py @@ -34,18 +34,19 @@ import time import select import getopt -from threading import Thread try: from cStringIO import StringIO except ImportError: from StringIO import StringIO from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler -from SocketServer import ThreadingMixIn -mydir = os.path.dirname(__file__) # expected to be .../indra/llcorehttp/tests/ -sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) -from indra.util.fastest_elementtree import parse as xml_parse -from indra.base import llsd +from llbase.fastest_elementtree import parse as xml_parse +from llbase import llsd + +# we're in llcorehttp/tests ; testrunner.py is found in llmessage/tests +sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, + "llmessage", "tests")) + from testrunner import freeport, run, debug, VERBOSE class TestHTTPRequestHandler(BaseHTTPRequestHandler): @@ -271,7 +272,7 @@ def log_error(self, format, *args): # Suppress error output as well pass -class Server(ThreadingMixIn, HTTPServer): +class Server(HTTPServer): # This pernicious flag is on by default in HTTPServer. But proper # operation of freeport() absolutely depends on it being off. allow_reuse_address = False @@ -295,22 +296,26 @@ def handle_error(self, request, client_address): if option == "-V" or option == "--valgrind": do_valgrind = True - # Instantiate a Server(TestHTTPRequestHandler) on the first free port - # in the specified port range. Doing this inline is better than in a - # daemon thread: if it blows up here, we'll get a traceback. If it blew up - # in some other thread, the traceback would get eaten and we'd run the - # subject test program anyway. - httpd, port = freeport(xrange(8000, 8020), - lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)) + # function to make a server with specified port + make_server = lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler) + + if not sys.platform.startswith("win"): + # Instantiate a Server(TestHTTPRequestHandler) on a port chosen by the + # runtime. + httpd = make_server(0) + else: + # "Then there's Windows" + # Instantiate a Server(TestHTTPRequestHandler) on the first free port + # in the specified port range. + httpd, port = freeport(xrange(8000, 8020), make_server) # Pass the selected port number to the subject test program via the # environment. We don't want to impose requirements on the test program's # command-line parsing -- and anyway, for C++ integration tests, that's # performed in TUT code rather than our own. - os.environ["LL_TEST_PORT"] = str(port) - debug("$LL_TEST_PORT = %s", port) + os.environ["LL_TEST_PORT"] = str(httpd.server_port) + debug("$LL_TEST_PORT = %s", httpd.server_port) if do_valgrind: args = ["valgrind", "--log-file=./valgrind.log"] + args path_search = True - sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), use_path=path_search, *args)) - + sys.exit(run(server_inst=httpd, use_path=path_search, *args)) diff --git a/indra/llcorehttp/tests/testrunner.py b/indra/llcorehttp/tests/testrunner.py deleted file mode 100755 index 9a2de711425359cb4d0053139cde7d0dc5200981..0000000000000000000000000000000000000000 --- a/indra/llcorehttp/tests/testrunner.py +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/env python -"""\ -@file testrunner.py -@author Nat Goodspeed -@date 2009-03-20 -@brief Utilities for writing wrapper scripts for ADD_COMM_BUILD_TEST unit tests - -$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$ -""" - -from __future__ import with_statement - -import os -import sys -import re -import errno -import socket - -VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "0") # default to quiet -# Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if -# that construct actually turns on verbosity... -VERBOSE = not re.match(r"(0|off|false|quiet)$", VERBOSE, re.IGNORECASE) - -if VERBOSE: - def debug(fmt, *args): - print fmt % args - sys.stdout.flush() -else: - debug = lambda *args: None - -def freeport(portlist, expr): - """ - Find a free server port to use. Specifically, evaluate 'expr' (a - callable(port)) until it stops raising EADDRINUSE exception. - - Pass: - - portlist: an iterable (e.g. xrange()) of ports to try. If you exhaust the - range, freeport() lets the socket.error exception propagate. If you want - unbounded, you could pass itertools.count(baseport), though of course in - practice the ceiling is 2^16-1 anyway. But it seems prudent to constrain - the range much more sharply: if we're iterating an absurd number of times, - probably something else is wrong. - - expr: a callable accepting a port number, specifically one of the items - from portlist. If calling that callable raises socket.error with - EADDRINUSE, freeport() retrieves the next item from portlist and retries. - - Returns: (expr(port), port) - - port: the value from portlist for which expr(port) succeeded - - Raises: - - Any exception raised by expr(port) other than EADDRINUSE. - - socket.error if, for every item from portlist, expr(port) raises - socket.error. The exception you see is the one from the last item in - portlist. - - StopIteration if portlist is completely empty. - - Example: - - class Server(HTTPServer): - # If you use BaseHTTPServer.HTTPServer, turning off this flag is - # essential for proper operation of freeport()! - allow_reuse_address = False - # ... - server, port = freeport(xrange(8000, 8010), - lambda port: Server(("localhost", port), - MyRequestHandler)) - # pass 'port' to client code - # call server.serve_forever() - """ - try: - # If portlist is completely empty, let StopIteration propagate: that's an - # error because we can't return meaningful values. We have no 'port', - # therefore no 'expr(port)'. - portiter = iter(portlist) - port = portiter.next() - - while True: - try: - # If this value of port works, return as promised. - value = expr(port) - - except socket.error, err: - # Anything other than 'Address already in use', propagate - if err.args[0] != errno.EADDRINUSE: - raise - - # Here we want the next port from portiter. But on StopIteration, - # we want to raise the original exception rather than - # StopIteration. So save the original exc_info(). - type, value, tb = sys.exc_info() - try: - try: - port = portiter.next() - except StopIteration: - raise type, value, tb - finally: - # Clean up local traceback, see docs for sys.exc_info() - del tb - - else: - debug("freeport() returning %s on port %s", value, port) - return value, port - - # Recap of the control flow above: - # If expr(port) doesn't raise, return as promised. - # If expr(port) raises anything but EADDRINUSE, propagate that - # exception. - # If portiter.next() raises StopIteration -- that is, if the port - # value we just passed to expr(port) was the last available -- reraise - # the EADDRINUSE exception. - # If we've actually arrived at this point, portiter.next() delivered a - # new port value. Loop back to pass that to expr(port). - - except Exception, err: - debug("*** freeport() raising %s: %s", err.__class__.__name__, err) - raise - -def run(*args, **kwds): - """All positional arguments collectively form a command line, executed as - a synchronous child process. - In addition, pass server=new_thread_instance as an explicit keyword (to - differentiate it from an additional command-line argument). - new_thread_instance should be an instantiated but not yet started Thread - subclass instance, e.g.: - run("python", "-c", 'print "Hello, world!"', server=TestHTTPServer(name="httpd")) - """ - # If there's no server= keyword arg, don't start a server thread: simply - # run a child process. - try: - thread = kwds.pop("server") - except KeyError: - pass - else: - # Start server thread. Note that this and all other comm server - # threads should be daemon threads: we'll let them run "forever," - # confident that the whole process will terminate when the main thread - # terminates, which will be when the child process terminates. - thread.setDaemon(True) - thread.start() - # choice of os.spawnv(): - # - [v vs. l] pass a list of args vs. individual arguments, - # - [no p] don't use the PATH because we specifically want to invoke the - # executable passed as our first arg, - # - [no e] child should inherit this process's environment. - debug("Running %s...", " ".join(args)) - if kwds.get("use_path", False): - rc = os.spawnvp(os.P_WAIT, args[0], args) - else: - rc = os.spawnv(os.P_WAIT, args[0], args) - debug("%s returned %s", args[0], rc) - return rc - -# **************************************************************************** -# test code -- manual at this point, see SWAT-564 -# **************************************************************************** -def test_freeport(): - # ------------------------------- Helpers -------------------------------- - from contextlib import contextmanager - # helper Context Manager for expecting an exception - # with exc(SomeError): - # raise SomeError() - # raises AssertionError otherwise. - @contextmanager - def exc(exception_class, *args): - try: - yield - except exception_class, err: - for i, expected_arg in enumerate(args): - assert expected_arg == err.args[i], \ - "Raised %s, but args[%s] is %r instead of %r" % \ - (err.__class__.__name__, i, err.args[i], expected_arg) - print "Caught expected exception %s(%s)" % \ - (err.__class__.__name__, ', '.join(repr(arg) for arg in err.args)) - else: - assert False, "Failed to raise " + exception_class.__class__.__name__ - - # helper to raise specified exception - def raiser(exception): - raise exception - - # the usual - def assert_equals(a, b): - assert a == b, "%r != %r" % (a, b) - - # ------------------------ Sanity check the above ------------------------ - class SomeError(Exception): pass - # Without extra args, accept any err.args value - with exc(SomeError): - raiser(SomeError("abc")) - # With extra args, accept only the specified value - with exc(SomeError, "abc"): - raiser(SomeError("abc")) - with exc(AssertionError): - with exc(SomeError, "abc"): - raiser(SomeError("def")) - with exc(AssertionError): - with exc(socket.error, errno.EADDRINUSE): - raiser(socket.error(errno.ECONNREFUSED, 'Connection refused')) - - # ----------- freeport() without engaging socket functionality ----------- - # If portlist is empty, freeport() raises StopIteration. - with exc(StopIteration): - freeport([], None) - - assert_equals(freeport([17], str), ("17", 17)) - - # This is the magic exception that should prompt us to retry - inuse = socket.error(errno.EADDRINUSE, 'Address already in use') - # Get the iterator to our ports list so we can check later if we've used all - ports = iter(xrange(5)) - with exc(socket.error, errno.EADDRINUSE): - freeport(ports, lambda port: raiser(inuse)) - # did we entirely exhaust 'ports'? - with exc(StopIteration): - ports.next() - - ports = iter(xrange(2)) - # Any exception but EADDRINUSE should quit immediately - with exc(SomeError): - freeport(ports, lambda port: raiser(SomeError())) - assert_equals(ports.next(), 1) - - # ----------- freeport() with platform-dependent socket stuff ------------ - # This is what we should've had unit tests to begin with (see CHOP-661). - def newbind(port): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.bind(('127.0.0.1', port)) - return sock - - bound0, port0 = freeport(xrange(7777, 7780), newbind) - assert_equals(port0, 7777) - bound1, port1 = freeport(xrange(7777, 7780), newbind) - assert_equals(port1, 7778) - bound2, port2 = freeport(xrange(7777, 7780), newbind) - assert_equals(port2, 7779) - with exc(socket.error, errno.EADDRINUSE): - bound3, port3 = freeport(xrange(7777, 7780), newbind) - -if __name__ == "__main__": - test_freeport() diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index dfb344c908cccc66b42a0f548b3f606c0039b878..dca49be0515587a51f0855f55ff61d670b335a1b 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -45,6 +45,7 @@ #include "llhttpsdhandler.h" #include "httpcommon.h" #include "httpresponse.h" +#include "llcleanup.h" #include <curl/curl.h> #include <openssl/crypto.h> @@ -623,7 +624,7 @@ void LLCrashLogger::commonCleanup() { term_curl(); LLError::logToFile(""); //close crashreport.log - LLProxy::cleanupClass(); + SUBSYSTEM_CLEANUP(LLProxy); } void LLCrashLogger::init_curl() diff --git a/indra/llcrashlogger/llcrashlogger.h b/indra/llcrashlogger/llcrashlogger.h index 8b4afae24ab4309744897afffdd4816f3762cb45..56e26c23ba3f49ae4264d1c1dbb9f075913bd813 100644 --- a/indra/llcrashlogger/llcrashlogger.h +++ b/indra/llcrashlogger/llcrashlogger.h @@ -57,7 +57,7 @@ class LLCrashLogger : public LLApp LLSD constructPostData(); virtual void updateApplication(const std::string& message = LLStringUtil::null); virtual bool init(); - virtual bool mainLoop() = 0; + virtual bool frame() = 0; virtual bool cleanup() = 0; void commonCleanup(); void setUserText(const std::string& text) { mCrashInfo["UserNotes"] = text; } diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 08462c7834ae31b7d3ae031482238a18995a8ca2..fe49e8e0112b21cf2614245ecceab5560d677125 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -705,18 +705,21 @@ void LLImageBase::deleteData() // 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_ERRS() << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,(S32)mComponents) << LL_ENDL; + LL_WARNS() << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,(S32)mComponents) << LL_ENDL; + mBadBufferAllocation = true; } - } - - //make this function thread-safe. - static const U32 MAX_BUFFER_SIZE = 4096 * 4096 * 16 ; //256 MB - if (size < 1 || size > MAX_BUFFER_SIZE) + } + + if (!mBadBufferAllocation && (size < 1 || size > MAX_BUFFER_SIZE)) { LL_INFOS() << "width: " << mWidth << " height: " << mHeight << " components: " << mComponents << LL_ENDL ; if(mAllowOverSize) @@ -725,25 +728,31 @@ U8* LLImageBase::allocateData(S32 size) } else { - LL_ERRS() << "LLImageBase::allocateData: bad size: " << size << LL_ENDL; + LL_WARNS() << "LLImageBase::allocateData: bad size: " << size << LL_ENDL; + mBadBufferAllocation = true; } } - if (!mData || size != mDataSize) + + if (!mBadBufferAllocation && (!mData || size != mDataSize)) { deleteData(); // virtual - mBadBufferAllocation = false ; mData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size); if (!mData) { LL_WARNS() << "Failed to allocate image data size [" << size << "]" << LL_ENDL; - size = 0 ; - mWidth = mHeight = 0 ; - mBadBufferAllocation = true ; + mBadBufferAllocation = true; } - mDataSize = size; - claimMem(mDataSize); } + if (mBadBufferAllocation) + { + size = 0; + mWidth = mHeight = 0; + mData = NULL; + } + mDataSize = size; + claimMem(mDataSize); + return mData; } @@ -773,7 +782,8 @@ const U8* LLImageBase::getData() const { if(mBadBufferAllocation) { - LL_ERRS() << "Bad memory allocation for the image buffer!" << LL_ENDL ; + LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL ; + return NULL; } return mData; @@ -783,13 +793,14 @@ U8* LLImageBase::getData() { if(mBadBufferAllocation) { - LL_ERRS() << "Bad memory allocation for the image buffer!" << LL_ENDL ; + LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL; + return NULL; } return mData; } -bool LLImageBase::isBufferInvalid() +bool LLImageBase::isBufferInvalid() const { return mBadBufferAllocation || mData == NULL ; } @@ -895,30 +906,30 @@ void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components) sGlobalRawMemory += getDataSize(); } -BOOL LLImageRaw::resize(U16 width, U16 height, S8 components) +bool LLImageRaw::resize(U16 width, U16 height, S8 components) { if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components)) { - return TRUE; + return true; } // Reallocate the data buffer. deleteData(); allocateDataSize(width,height,components); - return TRUE; + return true; } -BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height, - const U8 *data, U32 stride, BOOL reverse_y) +bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height, + const U8 *data, U32 stride, bool reverse_y) { if (!getData()) { - return FALSE; + return false; } if (!data) { - return FALSE; + return false; } // Should do some simple bounds checking @@ -933,13 +944,19 @@ BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height, 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()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return; + } + U8 *pos = getData(); U32 x, y; for (x = 0; x < getWidth(); x++) @@ -988,7 +1005,7 @@ void LLImageRaw::verticalFlip() } -void LLImageRaw::expandToPowerOfTwo(S32 max_dim, BOOL scale_image) +void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image) { // Find new sizes S32 new_width = expandDimToPowerOfTwo(getWidth(), max_dim); @@ -997,7 +1014,7 @@ void LLImageRaw::expandToPowerOfTwo(S32 max_dim, BOOL scale_image) scale( new_width, new_height, scale_image ); } -void LLImageRaw::contractToPowerOfTwo(S32 max_dim, BOOL scale_image) +void LLImageRaw::contractToPowerOfTwo(S32 max_dim, bool scale_image) { // Find new sizes S32 new_width = contractDimToPowerOfTwo(getWidth(), MIN_IMAGE_SIZE); @@ -1067,6 +1084,11 @@ 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()); @@ -1134,7 +1156,6 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src ) 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(); @@ -1169,6 +1190,11 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) { LLImageRaw* dst = this; // Just for clarity. + if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst)) + { + return; + } + llassert( 1 == src->getComponents() ); llassert( 4 == dst->getComponents() ); llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); @@ -1191,13 +1217,20 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) // 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() ) { U32* data = (U32*) getData(); + U32 rgbaColor = color.asRGBA(); for( S32 i = 0; i < pixels; i++ ) { - data[i] = color.mAll; + data[ i ] = rgbaColor; } } else @@ -1229,14 +1262,13 @@ LLPointer<LLImageRaw> LLImageRaw::duplicate() // Src and dst can be any size. Src and dst can each have 3 or 4 components. void LLImageRaw::copy(LLImageRaw* src) { - if (!src) + LLImageRaw* dst = this; // Just for clarity. + + if (!validateSrcAndDst("LLImageRaw::copy", src, dst)) { - LL_WARNS() << "LLImageRaw::copy called with a null src pointer" << LL_ENDL; return; } - LLImageRaw* dst = this; // Just for clarity. - if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) { // No scaling needed @@ -1363,6 +1395,11 @@ void LLImageRaw::copyScaled( LLImageRaw* src ) { LLImageRaw* dst = this; // Just for clarity. + if (!validateSrcAndDst("LLImageRaw::copyScaled", src, dst)) + { + return; + } + llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) ); llassert_always( src->getComponents() == dst->getComponents() ); @@ -1397,86 +1434,83 @@ void LLImageRaw::copyScaled( LLImageRaw* src ) } -BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data ) +bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data ) { - llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) ); + S32 components = getComponents(); + if (! ((1 == components) || (3 == components) || (4 == components) )) + { + LL_WARNS() << "Invalid getComponents value (" << components << ")" << LL_ENDL; + return false; + } + + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return false; + } S32 old_width = getWidth(); S32 old_height = getHeight(); if( (old_width == new_width) && (old_height == new_height) ) { - return TRUE; // Nothing to do. + return true; // Nothing to do. } // Reallocate the data buffer. if (scale_image_data) { - /* - S32 temp_data_size = old_width * new_height * getComponents(); - llassert_always(temp_data_size > 0); - std::vector<U8> temp_buffer(temp_data_size); + S32 new_data_size = new_width * new_height * components; - // Vertical - for( S32 col = 0; col < old_width; col++ ) - { - copyLineScaled( getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), old_height, new_height, old_width, old_width ); - } - - deleteData(); + if (new_data_size > 0) + { + U8 *new_data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), new_data_size); + if(NULL == new_data) + { + return false; + } - U8* new_buffer = allocateDataSize(new_width, new_height, getComponents()); - - // Horizontal - for( S32 row = 0; row < new_height; row++ ) - { - copyLineScaled( &temp_buffer[0] + (getComponents() * old_width * row), new_buffer + (getComponents() * new_width * row), old_width, new_width, 1, 1 ); + 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); } - */ - - S32 new_data_size = new_width * new_height * getComponents(); - llassert_always(new_data_size > 0); - - U8 *new_data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), new_data_size); - if(NULL == new_data) - { - return FALSE; - } - - bilinear_scale(getData(), old_width, old_height, getComponents(), old_width*getComponents(), new_data, new_width, new_height, getComponents(), new_width*getComponents()); - setDataAndSize(new_data, new_width, new_height, getComponents()); } else { // copy out existing image data - S32 temp_data_size = old_width * old_height * getComponents(); + 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, getComponents()); - - for( S32 row = 0; row < new_height; row++ ) - { - if (row < old_height) - { - memcpy(new_buffer + (new_width * row * getComponents()), &temp_buffer[0] + (old_width * row * getComponents()), getComponents() * llmin(old_width, new_width)); - if (old_width < new_width) - { - // pad out rest of row with black - memset(new_buffer + (getComponents() * ((new_width * row) + old_width)), 0, getComponents() * (new_width - old_width)); - } - } - else - { - // pad remaining rows with black - memset(new_buffer + (new_width * row * getComponents()), 0, new_width * getComponents()); - } - } - } - - return TRUE ; + 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++ ) + { + 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) + { + // 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); + } + } + } + + return true ; } void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ) @@ -1690,6 +1724,25 @@ void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S3 } } +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"; + + 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; +} //---------------------------------------------------------------------------- @@ -1795,7 +1848,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip ifs.read ((char*)buffer, length); ifs.close(); - BOOL success; + bool success; success = image->updateData(); if (success) @@ -1971,7 +2024,7 @@ 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) +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. @@ -2022,7 +2075,7 @@ void LLImageFormatted::sanityCheck() //---------------------------------------------------------------------------- -BOOL LLImageFormatted::copyData(U8 *data, S32 size) +bool LLImageFormatted::copyData(U8 *data, S32 size) { if ( data && ((data != getData()) || (size != getDataSize())) ) { @@ -2030,7 +2083,7 @@ BOOL LLImageFormatted::copyData(U8 *data, S32 size) allocateData(size); memcpy(getData(), data, size); /* Flawfinder: ignore */ } - return TRUE; + return true; } // LLImageFormatted becomes the owner of data @@ -2066,7 +2119,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size) //---------------------------------------------------------------------------- -BOOL LLImageFormatted::load(const std::string &filename, int load_size) +bool LLImageFormatted::load(const std::string &filename, int load_size) { resetLastError(); @@ -2077,12 +2130,12 @@ BOOL LLImageFormatted::load(const std::string &filename, int load_size) if (!apr_file) { setLastError("Unable to open file for reading", filename); - return FALSE; + return false; } if (file_size == 0) { setLastError("File is empty",filename); - return FALSE; + return false; } // Constrain the load size to acceptable values @@ -2090,7 +2143,7 @@ BOOL LLImageFormatted::load(const std::string &filename, int load_size) { load_size = file_size; } - BOOL res; + bool res; U8 *data = allocateData(load_size); apr_size_t bytes_read = load_size; apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read @@ -2098,7 +2151,7 @@ BOOL LLImageFormatted::load(const std::string &filename, int load_size) { deleteData(); setLastError("Unable to read file",filename); - res = FALSE; + res = false; } else { @@ -2108,7 +2161,7 @@ BOOL LLImageFormatted::load(const std::string &filename, int load_size) return res; } -BOOL LLImageFormatted::save(const std::string &filename) +bool LLImageFormatted::save(const std::string &filename) { resetLastError(); @@ -2117,15 +2170,15 @@ BOOL LLImageFormatted::save(const std::string &filename) if (!outfile.getFileHandle()) { setLastError("Unable to open file for writing", filename); - return FALSE; + return false; } outfile.write(getData(), getDataSize()); outfile.close() ; - return TRUE; + return true; } -// BOOL LLImageFormatted::save(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type) +// bool LLImageFormatted::save(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type) // Depricated to remove VFS dependency. // Use: // LLVFile::writeFile(image->getData(), image->getDataSize(), vfs, uuid, type); diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index cd3f76f1fd0e3a0ac195874bd8611b211698fa15..d0bd4a2aefe554964057bd53051c28be4241f0a5 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -141,7 +141,7 @@ class LLImageBase const U8 *getData() const ; U8 *getData() ; - bool isBufferInvalid() ; + bool isBufferInvalid() const; void setSize(S32 width, S32 height, S32 ncomponents); U8* allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size = -1); // setSize() + allocateData() @@ -199,11 +199,11 @@ class LLImageRaw : public LLImageBase /*virtual*/ U8* allocateData(S32 size = -1); /*virtual*/ U8* reallocateData(S32 size); - 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); + 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); @@ -212,10 +212,10 @@ class LLImageRaw : public LLImageBase 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 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 ); + bool scale( S32 new_width, S32 new_height, bool scale_image = true ); // Fill the buffer with a constant color void fill( const LLColor4U& color ); @@ -277,6 +277,9 @@ class LLImageRaw : public LLImageBase public: static S32 sGlobalRawMemory; static S32 sRawImageCount; + +private: + bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst); }; // Compressed representation of image. @@ -314,23 +317,23 @@ class LLImageFormatted : public LLImageBase // 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); + bool load(const std::string& filename, int load_size = 0); + bool save(const std::string& filename); - virtual BOOL updateData() = 0; // pure virtual + 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; + 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 decodeChannels(LLImageRaw* raw_image, F32 decode_time, S32 first_channel, S32 max_channel); - virtual BOOL encode(const LLImageRaw* raw_image, F32 encode_time) = 0; + virtual bool encode(const LLImageRaw* raw_image, F32 encode_time) = 0; S8 getCodec() const; - BOOL isDecoding() const { return mDecoding ? TRUE : FALSE; } - BOOL isDecoded() const { return mDecoded ? TRUE : FALSE; } + 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; } @@ -341,7 +344,7 @@ class LLImageFormatted : public LLImageBase 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; diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp index a2ce2fee860a537467a174c8807ac2c696fe9e78..2cdd26c22b4616c07a212821f9d9a632b4222403 100644 --- a/indra/llimage/llimagebmp.cpp +++ b/indra/llimage/llimagebmp.cpp @@ -78,7 +78,7 @@ LLImageBMP::LLImageBMP() mColorPalette( NULL ), mBitmapOffset( 0 ), mBitsPerPixel( 0 ), - mOriginAtTop( FALSE ) + mOriginAtTop( false ) { mBitfieldMask[0] = 0; mBitfieldMask[1] = 0; @@ -92,7 +92,7 @@ LLImageBMP::~LLImageBMP() } -BOOL LLImageBMP::updateData() +bool LLImageBMP::updateData() { resetLastError(); @@ -101,7 +101,7 @@ BOOL LLImageBMP::updateData() if (!mdata || (0 == getDataSize())) { setLastError("Uninitialized instance of LLImageBMP"); - return FALSE; + return false; } // Read the bitmap headers in order to get all the useful info @@ -120,12 +120,12 @@ BOOL LLImageBMP::updateData() if ((mdata[0] != 'B') || (mdata[1] != 'A')) { setLastError("OS/2 bitmap array BMP files are not supported"); - return FALSE; + return false; } else { setLastError("Does not appear to be a bitmap file"); - return FALSE; + return false; } } @@ -160,12 +160,12 @@ BOOL LLImageBMP::updateData() llendianswizzleone(header.mNumColors); llendianswizzleone(header.mNumColorsImportant); - BOOL windows_nt_version = FALSE; - BOOL windows_95_version = FALSE; + bool windows_nt_version = false; + bool windows_95_version = false; if( 12 == header.mSize ) { setLastError("Windows 2.x and OS/2 1.x BMP files are not supported"); - return FALSE; + return false; } else if( 40 == header.mSize ) @@ -173,7 +173,7 @@ BOOL LLImageBMP::updateData() if( 3 == header.mCompression ) { // Windows NT - windows_nt_version = TRUE; + windows_nt_version = true; } else { @@ -184,32 +184,32 @@ BOOL LLImageBMP::updateData() if( 12 <= header.mSize && 64 <= header.mSize ) { setLastError("OS/2 2.x BMP files are not supported"); - return FALSE; + return false; } else if( 108 == header.mSize ) { // BITMAPV4HEADER - windows_95_version = TRUE; + windows_95_version = true; } else if( 108 < header.mSize ) { // BITMAPV5HEADER or greater // Should work as long at Microsoft maintained backwards compatibility (which they did in V4 and V5) - windows_95_version = TRUE; + windows_95_version = true; } S32 width = header.mWidth; S32 height = header.mHeight; if (height < 0) { - mOriginAtTop = TRUE; + mOriginAtTop = true; height = -height; } else { - mOriginAtTop = FALSE; + mOriginAtTop = false; } mBitsPerPixel = header.mBitsPerPixel; @@ -228,10 +228,10 @@ BOOL LLImageBMP::updateData() case 16: // Started work on 16, but doesn't work yet // These are legal, but we don't support them yet. setLastError("Unsupported bit depth"); - return FALSE; + return false; default: setLastError("Unrecognized bit depth"); - return FALSE; + return false; } setSize(width, height, components); @@ -244,11 +244,11 @@ BOOL LLImageBMP::updateData() case 1: setLastError("8 bit RLE compression not supported."); - return FALSE; + return false; case 2: setLastError("4 bit RLE compression not supported."); - return FALSE; + return false; case 3: // Windows NT or Windows 95 @@ -256,7 +256,7 @@ BOOL LLImageBMP::updateData() default: setLastError("Unsupported compression format."); - return FALSE; + return false; } //////////////////////////////////////////////////////////////////// @@ -267,13 +267,13 @@ BOOL LLImageBMP::updateData() if( (16 != header.mBitsPerPixel) && (32 != header.mBitsPerPixel) ) { setLastError("Bitfield encoding requires 16 or 32 bits per pixel."); - return FALSE; + return false; } if( 0 != header.mNumColors ) { setLastError("Bitfield encoding is not compatible with a color table."); - return FALSE; + return false; } @@ -322,15 +322,15 @@ BOOL LLImageBMP::updateData() if (!mColorPalette) { LL_ERRS() << "Out of memory in LLImageBMP::updateData()" << LL_ENDL; - return FALSE; + return false; } memcpy( mColorPalette, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE + extension_size, color_palette_size ); /* Flawfinder: ignore */ } - return TRUE; + return true; } -BOOL LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time) +bool LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time) { llassert_always(raw_image); @@ -341,7 +341,7 @@ BOOL LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time) if (!mdata || (0 == getDataSize())) { setLastError("llimagebmp trying to decode an image with no data!"); - return FALSE; + return false; } raw_image->resize(getWidth(), getHeight(), 3); @@ -349,7 +349,7 @@ BOOL LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time) U8* src = mdata + mBitmapOffset; U8* dst = raw_image->getData(); - BOOL success = FALSE; + bool success = false; switch( mBitsPerPixel ) { @@ -393,7 +393,7 @@ U32 LLImageBMP::countTrailingZeros( U32 m ) } -BOOL LLImageBMP::decodeColorMask16( U8* dst, U8* src ) +bool LLImageBMP::decodeColorMask16( U8* dst, U8* src ) { llassert( 16 == mBitsPerPixel ); @@ -426,10 +426,10 @@ BOOL LLImageBMP::decodeColorMask16( U8* dst, U8* src ) src += alignment_bytes; } - return TRUE; + return true; } -BOOL LLImageBMP::decodeColorMask32( U8* dst, U8* src ) +bool LLImageBMP::decodeColorMask32( U8* dst, U8* src ) { // Note: alpha is not supported @@ -445,7 +445,7 @@ BOOL LLImageBMP::decodeColorMask32( U8* dst, U8* src ) if (getWidth() * getHeight() * 4 > getDataSize() - mBitmapOffset) { //here we have situation when data size in src less than actually needed - return FALSE; + return false; } S32 src_row_span = getWidth() * 4; @@ -469,11 +469,11 @@ BOOL LLImageBMP::decodeColorMask32( U8* dst, U8* src ) src += alignment_bytes; } - return TRUE; + return true; } -BOOL LLImageBMP::decodeColorTable8( U8* dst, U8* src ) +bool LLImageBMP::decodeColorTable8( U8* dst, U8* src ) { llassert( (8 == mBitsPerPixel) && (mColorPaletteColors >= 256) ); @@ -482,7 +482,7 @@ BOOL LLImageBMP::decodeColorTable8( U8* dst, U8* src ) if ((getWidth() * getHeight()) + getHeight() * alignment_bytes > getDataSize() - mBitmapOffset) { //here we have situation when data size in src less than actually needed - return FALSE; + return false; } for( S32 row = 0; row < getHeight(); row++ ) @@ -499,11 +499,11 @@ BOOL LLImageBMP::decodeColorTable8( U8* dst, U8* src ) src += alignment_bytes; } - return TRUE; + return true; } -BOOL LLImageBMP::decodeTruecolor24( U8* dst, U8* src ) +bool LLImageBMP::decodeTruecolor24( U8* dst, U8* src ) { llassert( 24 == mBitsPerPixel ); llassert( 3 == getComponents() ); @@ -512,7 +512,7 @@ BOOL LLImageBMP::decodeTruecolor24( U8* dst, U8* src ) if ((getWidth() * getHeight() * 3) + getHeight() * alignment_bytes > getDataSize() - mBitmapOffset) { //here we have situation when data size in src less than actually needed - return FALSE; + return false; } for( S32 row = 0; row < getHeight(); row++ ) @@ -528,10 +528,10 @@ BOOL LLImageBMP::decodeTruecolor24( U8* dst, U8* src ) src += alignment_bytes; } - return TRUE; + return true; } -BOOL LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time) +bool LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time) { llassert_always(raw_image); @@ -563,7 +563,7 @@ BOOL LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time) // Allocate the new buffer for the data. if(!allocateData(file_bytes)) //memory allocation failed { - return FALSE ; + return false ; } magic[0] = 'B'; magic[1] = 'M'; @@ -663,5 +663,5 @@ BOOL LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time) } } - return TRUE; + return true; } diff --git a/indra/llimage/llimagebmp.h b/indra/llimage/llimagebmp.h index db0b45def0e9680298a1fd6df16ce08bbabdcc54..6a5fa4697d10872ad323f80f9ffe770ed4fb843e 100644 --- a/indra/llimage/llimagebmp.h +++ b/indra/llimage/llimagebmp.h @@ -40,15 +40,15 @@ class LLImageBMP : public LLImageFormatted LLImageBMP(); /*virtual*/ std::string getExtension() { return std::string("bmp"); } - /*virtual*/ BOOL updateData(); - /*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time); - /*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time); + /*virtual*/ bool updateData(); + /*virtual*/ bool decode(LLImageRaw* raw_image, F32 decode_time); + /*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time); protected: - BOOL decodeColorTable8( U8* dst, U8* src ); - BOOL decodeColorMask16( U8* dst, U8* src ); - BOOL decodeTruecolor24( U8* dst, U8* src ); - BOOL decodeColorMask32( U8* dst, U8* src ); + bool decodeColorTable8( U8* dst, U8* src ); + bool decodeColorMask16( U8* dst, U8* src ); + bool decodeTruecolor24( U8* dst, U8* src ); + bool decodeColorMask32( U8* dst, U8* src ); U32 countTrailingZeros( U32 m ); @@ -58,7 +58,7 @@ class LLImageBMP : public LLImageFormatted S32 mBitmapOffset; S32 mBitsPerPixel; U32 mBitfieldMask[4]; // rgba - BOOL mOriginAtTop; + bool mOriginAtTop; }; #endif diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp index 5bf3f29b3ce5b2d5dbef861e7c9418c264c7dbdc..a5e546e97772968009ba981bce6134a9d0c9d497 100644 --- a/indra/llimage/llimagedimensionsinfo.cpp +++ b/indra/llimage/llimagedimensionsinfo.cpp @@ -201,7 +201,7 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg() cinfo.out_color_space = JCS_RGB; jpeg_start_decompress (&cinfo); - mHeight = cinfo.output_width; + mWidth = cinfo.output_width; mHeight = cinfo.output_height; jpeg_destroy_decompress(&cinfo); diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp index 04e0e752ebd3374b85b5c12dfff8e466bb0fddea..0ec83415a09d98e2585d64b3c7c525235065a28d 100644 --- a/indra/llimage/llimagedxt.cpp +++ b/indra/llimage/llimagedxt.cpp @@ -172,7 +172,7 @@ LLImageDXT::~LLImageDXT() } // virtual -BOOL LLImageDXT::updateData() +bool LLImageDXT::updateData() { resetLastError(); @@ -182,7 +182,7 @@ BOOL LLImageDXT::updateData() if (!data || !data_size) { setLastError("LLImageDXT uninitialized"); - return FALSE; + return false; } S32 width, height, miplevelmax; @@ -216,7 +216,7 @@ BOOL LLImageDXT::updateData() discard = llmin(discard, miplevelmax); setDiscardLevel(discard); - return TRUE; + return true; } // discard: 0 = largest (last) mip @@ -257,7 +257,7 @@ void LLImageDXT::setFormat() } // virtual -BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time) +bool LLImageDXT::decode(LLImageRaw* raw_image, F32 time) { // *TODO: Test! This has been tweaked since its intial inception, // but we don't use it any more! @@ -266,7 +266,7 @@ BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time) if (mFileFormat >= FORMAT_DXT1 && mFileFormat <= FORMAT_DXR5) { LL_WARNS() << "Attempt to decode compressed LLImageDXT to Raw (unsupported)" << LL_ENDL; - return FALSE; + return false; } S32 width = getWidth(), height = getHeight(); @@ -286,16 +286,16 @@ BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time) if ((!getData()) || (data + image_size > getData() + getDataSize())) { setLastError("LLImageDXT trying to decode an image with not enough data!"); - return FALSE; + return false; } raw_image->resize(width, height, ncomponents); memcpy(raw_image->getData(), data, image_size); /* Flawfinder: ignore */ - return TRUE; + return true; } -BOOL LLImageDXT::getMipData(LLPointer<LLImageRaw>& raw, S32 discard) +bool LLImageDXT::getMipData(LLPointer<LLImageRaw>& raw, S32 discard) { if (discard < 0) { @@ -310,10 +310,10 @@ BOOL LLImageDXT::getMipData(LLPointer<LLImageRaw>& raw, S32 discard) S32 height = 0; calcDiscardWidthHeight(discard, mFileFormat, width, height); raw = new LLImageRaw(data, width, height, getComponents()); - return TRUE; + return true; } -BOOL LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_mips) +bool LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_mips) { llassert_always(raw_image); @@ -395,11 +395,11 @@ BOOL LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_ prev_mipdata = mipdata; } - return TRUE; + return true; } // virtual -BOOL LLImageDXT::encode(const LLImageRaw* raw_image, F32 time) +bool LLImageDXT::encode(const LLImageRaw* raw_image, F32 time) { return encodeDXT(raw_image, time, false); } diff --git a/indra/llimage/llimagedxt.h b/indra/llimage/llimagedxt.h index a8756ba8edb7bcc1c7c041a09add13a8364c3efd..a4a9bcf99c4b6c5876d843dea5cce41a9ee35fce 100644 --- a/indra/llimage/llimagedxt.h +++ b/indra/llimage/llimagedxt.h @@ -93,21 +93,21 @@ class LLImageDXT : public LLImageFormatted /*virtual*/ ~LLImageDXT(); private: - BOOL encodeDXT(const LLImageRaw* raw_image, F32 decode_time, bool explicit_mips); + bool encodeDXT(const LLImageRaw* raw_image, F32 decode_time, bool explicit_mips); public: LLImageDXT(); /*virtual*/ std::string getExtension() { return std::string("dxt"); } - /*virtual*/ BOOL updateData(); + /*virtual*/ bool updateData(); - /*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time); - /*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time); + /*virtual*/ bool decode(LLImageRaw* raw_image, F32 decode_time); + /*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time); /*virtual*/ S32 calcHeaderSize(); /*virtual*/ S32 calcDataSize(S32 discard_level = 0); - BOOL getMipData(LLPointer<LLImageRaw>& raw, S32 discard=-1); + bool getMipData(LLPointer<LLImageRaw>& raw, S32 discard=-1); void setFormat(); S32 getMipOffset(S32 discard); diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 7cd59a2983efe617250a58ec198eca828efa2fed..68694496bcf502a13989070efc283d36deeca07d 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -31,18 +31,13 @@ #include "llmath.h" #include "llmemory.h" #include "llsd.h" +#include <boost/scoped_ptr.hpp> -typedef LLImageJ2CImpl* (*CreateLLImageJ2CFunction)(); -typedef void (*DestroyLLImageJ2CFunction)(LLImageJ2CImpl*); -typedef const char* (*EngineInfoLLImageJ2CFunction)(); - -// Declare the prototype for theses functions here. Their functionality -// will be implemented in other files which define a derived LLImageJ2CImpl -// but only ONE static library which has the implementation for these -// functions should ever be included. +// Declare the prototype for this factory function here. It is implemented in +// other files which define a LLImageJ2CImpl subclass, but only ONE static +// library which has the implementation for this function should ever be +// linked. LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl(); -void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl); -const char* fallbackEngineInfoLLImageJ2CImpl(); // Test data gathering handle LLImageCompressionTester* LLImageJ2C::sTesterp = NULL ; @@ -51,17 +46,20 @@ const std::string sTesterName("ImageCompressionTester"); //static std::string LLImageJ2C::getEngineInfo() { - return fallbackEngineInfoLLImageJ2CImpl(); + // All known LLImageJ2CImpl implementation subclasses are cheap to + // construct. + boost::scoped_ptr<LLImageJ2CImpl> impl(fallbackCreateLLImageJ2CImpl()); + return impl->getEngineInfo(); } LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C), mMaxBytes(0), mRawDiscardLevel(-1), mRate(DEFAULT_COMPRESSION_RATE), - mReversible(FALSE), + mReversible(false), mAreaUsedForDataSizeCalcs(0) { - mImpl = fallbackCreateLLImageJ2CImpl(); + mImpl.reset(fallbackCreateLLImageJ2CImpl()); claimMem(mImpl); // Clear data size table @@ -83,13 +81,7 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C), } // virtual -LLImageJ2C::~LLImageJ2C() -{ - if ( mImpl ) - { - fallbackDestroyLLImageJ2CImpl(mImpl); - } -} +LLImageJ2C::~LLImageJ2C() {} // virtual void LLImageJ2C::resetLastError() @@ -111,16 +103,16 @@ S8 LLImageJ2C::getRawDiscardLevel() return mRawDiscardLevel; } -BOOL LLImageJ2C::updateData() +bool LLImageJ2C::updateData() { - BOOL res = TRUE; + bool res = true; resetLastError(); // Check to make sure that this instance has been initialized with data if (!getData() || (getDataSize() < 16)) { setLastError("LLImageJ2C uninitialized"); - res = FALSE; + res = false; } else { @@ -142,29 +134,29 @@ BOOL LLImageJ2C::updateData() return res; } -BOOL LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region) +bool LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region) { setDiscardLevel(discard_level != -1 ? discard_level : 0); return mImpl->initDecode(*this,raw_image,discard_level,region); } -BOOL LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels) +bool LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels) { return mImpl->initEncode(*this,raw_image,blocks_size,precincts_size,levels); } -BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time) +bool LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time) { return decodeChannels(raw_imagep, decode_time, 0, 4); } -// Returns TRUE to mean done, whether successful or not. -BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count ) +// Returns true to mean done, whether successful or not. +bool LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count ) { LLTimer elapsed; - BOOL res = TRUE; + bool res = true; resetLastError(); @@ -172,13 +164,13 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir if (!getData() || (getDataSize() < 16)) { setLastError("LLImageJ2C uninitialized"); - res = TRUE; // done + res = true; // done } else { // Update the raw discard level updateRawDiscardLevel(); - mDecoding = TRUE; + mDecoding = true; res = mImpl->decodeImpl(*this, *raw_imagep, decode_time, first_channel, max_channel_count); } @@ -191,7 +183,7 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir } else { - mDecoding = FALSE; + mDecoding = false; } } @@ -210,7 +202,7 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir tester->updateDecompressionStats(elapsed.getElapsedTimeF32()) ; if (res) { - // The whole data stream is finally decompressed when res is returned as TRUE + // The whole data stream is finally decompressed when res is returned as true tester->updateDecompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ; } } @@ -219,17 +211,17 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir } -BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, F32 encode_time) +bool LLImageJ2C::encode(const LLImageRaw *raw_imagep, F32 encode_time) { return encode(raw_imagep, NULL, encode_time); } -BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time) +bool LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time) { LLTimer elapsed; resetLastError(); - BOOL res = mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible); + bool res = mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible); if (!mLastError.empty()) { LLImage::setLastError(mLastError); @@ -245,7 +237,7 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, tester->updateCompressionStats(elapsed.getElapsedTimeF32()) ; if (res) { - // The whole data stream is finally compressed when res is returned as TRUE + // The whole data stream is finally compressed when res is returned as true tester->updateCompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ; } } @@ -348,15 +340,15 @@ void LLImageJ2C::setMaxBytes(S32 max_bytes) mMaxBytes = max_bytes; } -void LLImageJ2C::setReversible(const BOOL reversible) +void LLImageJ2C::setReversible(const bool reversible) { mReversible = reversible; } -BOOL LLImageJ2C::loadAndValidate(const std::string &filename) +bool LLImageJ2C::loadAndValidate(const std::string &filename) { - BOOL res = TRUE; + bool res = true; resetLastError(); @@ -367,12 +359,12 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename) if (!apr_file) { setLastError("Unable to open file for reading", filename); - res = FALSE; + res = false; } else if (file_size == 0) { setLastError("File is empty",filename); - res = FALSE; + res = false; } else { @@ -385,7 +377,7 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename) { FREE_MEM(LLImageBase::getPrivatePool(), data); setLastError("Unable to read entire file"); - res = FALSE; + res = false; } else { @@ -402,21 +394,21 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename) } -BOOL LLImageJ2C::validate(U8 *data, U32 file_size) +bool LLImageJ2C::validate(U8 *data, U32 file_size) { resetLastError(); setData(data, file_size); - BOOL res = updateData(); + bool res = updateData(); if ( res ) { // Check to make sure that this instance has been initialized with data if (!getData() || (0 == getDataSize())) { setLastError("LLImageJ2C uninitialized"); - res = FALSE; + res = false; } else { @@ -433,7 +425,7 @@ BOOL LLImageJ2C::validate(U8 *data, U32 file_size) void LLImageJ2C::decodeFailed() { - mDecoding = FALSE; + mDecoding = false; } void LLImageJ2C::updateRawDiscardLevel() diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index ce8195940d7c43683bad9380c1b40f903a1aff73..e196f7479ed0c83dd30b17e3a5db0db5f7c7d863 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -30,6 +30,7 @@ #include "llimage.h" #include "llassettype.h" #include "llmetricperformancetester.h" +#include <boost/scoped_ptr.hpp> // JPEG2000 : compression rate used in j2c conversion. const F32 DEFAULT_COMPRESSION_RATE = 1.f/8.f; @@ -47,10 +48,10 @@ class LLImageJ2C : public LLImageFormatted // Base class overrides /*virtual*/ std::string getExtension() { return std::string("j2c"); } - /*virtual*/ BOOL updateData(); - /*virtual*/ BOOL decode(LLImageRaw *raw_imagep, F32 decode_time); - /*virtual*/ BOOL decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count); - /*virtual*/ BOOL encode(const LLImageRaw *raw_imagep, F32 encode_time); + /*virtual*/ bool updateData(); + /*virtual*/ bool decode(LLImageRaw *raw_imagep, F32 decode_time); + /*virtual*/ bool decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count); + /*virtual*/ bool encode(const LLImageRaw *raw_imagep, F32 encode_time); /*virtual*/ S32 calcHeaderSize(); /*virtual*/ S32 calcDataSize(S32 discard_level = 0); /*virtual*/ S32 calcDiscardLevelBytes(S32 bytes); @@ -59,17 +60,17 @@ class LLImageJ2C : public LLImageFormatted /*virtual*/ void resetLastError(); /*virtual*/ void setLastError(const std::string& message, const std::string& filename = std::string()); - BOOL initDecode(LLImageRaw &raw_image, int discard_level, int* region); - BOOL initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels); + bool initDecode(LLImageRaw &raw_image, int discard_level, int* region); + bool initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels); // Encode with comment text - BOOL encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0); + bool encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0); - BOOL validate(U8 *data, U32 file_size); - BOOL loadAndValidate(const std::string &filename); + bool validate(U8 *data, U32 file_size); + bool loadAndValidate(const std::string &filename); // Encode accessors - void setReversible(const BOOL reversible); // Use non-lossy? + void setReversible(const bool reversible); // Use non-lossy? void setMaxBytes(S32 max_bytes); S32 getMaxBytes() const { return mMaxBytes; } @@ -93,8 +94,8 @@ class LLImageJ2C : public LLImageFormatted S8 mRawDiscardLevel; F32 mRate; - BOOL mReversible; - LLImageJ2CImpl *mImpl; + bool mReversible; + boost::scoped_ptr<LLImageJ2CImpl> mImpl; std::string mLastError; // Image compression/decompression tester @@ -111,23 +112,25 @@ class LLImageJ2CImpl // Return value: // true: image size and number of channels was determined // false: error on decode - virtual BOOL getMetadata(LLImageJ2C &base) = 0; + virtual bool getMetadata(LLImageJ2C &base) = 0; // Decode the raw image optionally aborting (to continue later) after // decode_time seconds. Decode at most max_channel_count and start // decoding channel first_channel. // Return value: // true: decoding complete (even if it failed) // false: time expired while decoding - virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) = 0; - virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0, - BOOL reversible=FALSE) = 0; - virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL) = 0; - virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0) = 0; + virtual bool decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) = 0; + virtual bool encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0, + bool reversible=false) = 0; + virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL) = 0; + virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0) = 0; + + virtual std::string getEngineInfo() const = 0; friend class LLImageJ2C; }; -#define LINDEN_J2C_COMMENT_PREFIX "LL_" +#define LINDEN_J2C_COMMENT_PREFIX "LL_" // Used by LLAppearanceUtility // // This class is used for performance data gathering only. diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp index e419c77ff2ce4b1f8f84ba8999844a2378b17c3b..60b2d0faa53fc2c11c90c24a36b6c23d18c6efdc 100644 --- a/indra/llimage/llimagejpeg.cpp +++ b/indra/llimage/llimagejpeg.cpp @@ -45,7 +45,7 @@ LLImageJPEG::~LLImageJPEG() delete[] mOutputBuffer; } -BOOL LLImageJPEG::updateData() +bool LLImageJPEG::updateData() { resetLastError(); @@ -53,7 +53,7 @@ BOOL LLImageJPEG::updateData() if (!getData() || (0 == getDataSize())) { setLastError("Uninitialized instance of LLImageJPEG"); - return FALSE; + return false; } //////////////////////////////////////// @@ -79,7 +79,7 @@ BOOL LLImageJPEG::updateData() if(setjmp(sSetjmpBuffer)) { jpeg_destroy_decompress(&cinfo); - return FALSE; + return false; } try { @@ -106,7 +106,7 @@ BOOL LLImageJPEG::updateData() //////////////////////////////////////// // Step 3: read file parameters with jpeg_read_header() - jpeg_read_header( &cinfo, TRUE ); + jpeg_read_header( &cinfo, true ); // Data set by jpeg_read_header setSize(cinfo.image_width, cinfo.image_height, 3); // Force to 3 components (RGB) @@ -115,13 +115,13 @@ BOOL LLImageJPEG::updateData() // More data set by jpeg_read_header cinfo.num_components; cinfo.jpeg_color_space; // Colorspace of image - cinfo.saw_JFIF_marker; // TRUE if a JFIF APP0 marker was seen + cinfo.saw_JFIF_marker; // true if a JFIF APP0 marker was seen cinfo.JFIF_major_version; // Version information from JFIF marker cinfo.JFIF_minor_version; // cinfo.density_unit; // Resolution data from JFIF marker cinfo.X_density; cinfo.Y_density; - cinfo.saw_Adobe_marker; // TRUE if an Adobe APP14 marker was seen + cinfo.saw_Adobe_marker; // true if an Adobe APP14 marker was seen cinfo.Adobe_transform; // Color transform code from Adobe marker */ } @@ -129,13 +129,13 @@ BOOL LLImageJPEG::updateData() { jpeg_destroy_decompress(&cinfo); - return FALSE; + return false; } //////////////////////////////////////// // Step 4: Release JPEG decompression object jpeg_destroy_decompress(&cinfo); - return TRUE; + return true; } // Initialize source --- called by jpeg_read_header @@ -154,7 +154,7 @@ boolean LLImageJPEG::decodeFillInputBuffer( j_decompress_ptr cinfo ) // Should never get here, since we provide the entire buffer up front. ERREXIT(cinfo, JERR_INPUT_EMPTY); - return TRUE; + return true; } // Skip data --- used to skip over a potentially large amount of @@ -182,7 +182,7 @@ void LLImageJPEG::decodeTermSource (j_decompress_ptr cinfo) // Returns true when done, whether or not decode was successful. -BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) +bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) { llassert_always(raw_image); @@ -192,7 +192,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) if (!getData() || (0 == getDataSize())) { setLastError("LLImageJPEG trying to decode an image with no data!"); - return TRUE; // done + return true; // done } S32 row_stride = 0; @@ -220,7 +220,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) if(setjmp(sSetjmpBuffer)) { jpeg_destroy_decompress(&cinfo); - return TRUE; // done + return true; // done } try { @@ -247,11 +247,11 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) //////////////////////////////////////// // Step 3: read file parameters with jpeg_read_header() - jpeg_read_header(&cinfo, TRUE); + jpeg_read_header(&cinfo, true); // We can ignore the return value from jpeg_read_header since // (a) suspension is not possible with our data source, and - // (b) we passed TRUE to reject a tables-only JPEG file as an error. + // (b) we passed true to reject a tables-only JPEG file as an error. // See libjpeg.doc for more info. setSize(cinfo.image_width, cinfo.image_height, 3); // Force to 3 components (RGB) @@ -314,7 +314,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) catch (int) { jpeg_destroy_decompress(&cinfo); - return TRUE; // done + return true; // done } // Check to see whether any corrupt-data warnings occurred @@ -322,10 +322,10 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) { // TODO: extract the warning to find out what went wrong. setLastError( "Unable to decode JPEG image."); - return TRUE; // done + return true; // done } - return TRUE; + return true; } @@ -344,11 +344,11 @@ void LLImageJPEG::encodeInitDestination ( j_compress_ptr cinfo ) // // In typical applications, this should write the entire output buffer // (ignoring the current state of next_output_byte & free_in_buffer), -// reset the pointer & count to the start of the buffer, and return TRUE +// reset the pointer & count to the start of the buffer, and return true // indicating that the buffer has been dumped. // // In applications that need to be able to suspend compression due to output -// overrun, a FALSE return indicates that the buffer cannot be emptied now. +// overrun, a false return indicates that the buffer cannot be emptied now. // In this situation, the compressor will return to its caller (possibly with // an indication that it has not accepted all the supplied scanlines). The // application should resume compression after it has made more room in the @@ -357,7 +357,7 @@ void LLImageJPEG::encodeInitDestination ( j_compress_ptr cinfo ) // // When suspending, the compressor will back up to a convenient restart point // (typically the start of the current MCU). next_output_byte & free_in_buffer -// indicate where the restart point will be if the current call returns FALSE. +// indicate where the restart point will be if the current call returns false. // Data beyond this point will be regenerated after resumption, so do not // write it out when emptying the buffer externally. @@ -374,7 +374,7 @@ boolean LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo ) if (!new_buffer) { LL_ERRS() << "Out of memory in LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo )" << LL_ENDL; - return FALSE; + return false; } memcpy( new_buffer, self->mOutputBuffer, self->mOutputBufferSize ); /* Flawfinder: ignore */ delete[] self->mOutputBuffer; @@ -386,7 +386,7 @@ boolean LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo ) self->mOutputBufferSize = new_buffer_size; self->claimMem(new_buffer_size); - return TRUE; + return true; } // Terminate destination --- called by jpeg_finish_compress @@ -465,11 +465,11 @@ void LLImageJPEG::errorOutputMessage( j_common_ptr cinfo ) std::string error = buffer ; LLImage::setLastError(error); - BOOL is_decode = (cinfo->is_decompressor != 0); + bool is_decode = (cinfo->is_decompressor != 0); LL_WARNS() << "LLImageJPEG " << (is_decode ? "decode " : "encode ") << " failed: " << buffer << LL_ENDL; } -BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) +bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) { llassert_always(raw_image); @@ -482,7 +482,7 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) break; default: setLastError("Unable to encode a JPEG image that doesn't have 1 or 3 components."); - return FALSE; + return false; } setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents()); @@ -531,7 +531,7 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) mOutputBuffer = NULL; disclaimMem(mOutputBufferSize); mOutputBufferSize = 0; - return FALSE; + return false; } try @@ -576,7 +576,7 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) break; default: setLastError("Unable to encode a JPEG image that doesn't have 1 or 3 components."); - return FALSE; + return false; } // Now use the library's routine to set default compression parameters. @@ -585,15 +585,15 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) jpeg_set_defaults(&cinfo); // Now you can set any non-default parameters you wish to. - jpeg_set_quality(&cinfo, mEncodeQuality, TRUE ); // limit to baseline-JPEG values + jpeg_set_quality(&cinfo, mEncodeQuality, true ); // limit to baseline-JPEG values //////////////////////////////////////// // Step 4: Start compressor // - // TRUE ensures that we will write a complete interchange-JPEG file. - // Pass TRUE unless you are very sure of what you're doing. + // true ensures that we will write a complete interchange-JPEG file. + // Pass true unless you are very sure of what you're doing. - jpeg_start_compress(&cinfo, TRUE); + jpeg_start_compress(&cinfo, true); //////////////////////////////////////// // Step 5: while (scan lines remain to be written) @@ -647,8 +647,8 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) mOutputBuffer = NULL; disclaimMem(mOutputBufferSize); mOutputBufferSize = 0; - return FALSE; + return false; } - return TRUE; + return true; } diff --git a/indra/llimage/llimagejpeg.h b/indra/llimage/llimagejpeg.h index 2142660c819ae129f185451a000f27cf8ff5a474..7a849a84212aa8f43123baf41dd2e3029cf2cef0 100644 --- a/indra/llimage/llimagejpeg.h +++ b/indra/llimage/llimagejpeg.h @@ -51,9 +51,9 @@ class LLImageJPEG : public LLImageFormatted LLImageJPEG(S32 quality = 75); /*virtual*/ std::string getExtension() { return std::string("jpg"); } - /*virtual*/ BOOL updateData(); - /*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time); - /*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time); + /*virtual*/ bool updateData(); + /*virtual*/ bool decode(LLImageRaw* raw_image, F32 decode_time); + /*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time); void setEncodeQuality( S32 q ) { mEncodeQuality = q; } // on a scale from 1 to 100 S32 getEncodeQuality() { return mEncodeQuality; } @@ -73,7 +73,7 @@ class LLImageJPEG : public LLImageFormatted static void errorEmitMessage(j_common_ptr cinfo, int msg_level); static void errorOutputMessage(j_common_ptr cinfo); - static BOOL decompress(LLImageJPEG* imagep); + static bool decompress(LLImageJPEG* imagep); protected: U8* mOutputBuffer; // temp buffer used during encoding diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp index 7735dc13797a2807c7425eed8c778f501554def1..a299602d790ddf9fab46d366187bfd92bddfd145 100644 --- a/indra/llimage/llimagepng.cpp +++ b/indra/llimage/llimagepng.cpp @@ -47,7 +47,7 @@ LLImagePNG::~LLImagePNG() // Virtual // Parse PNG image information and set the appropriate // width, height and component (channel) information. -BOOL LLImagePNG::updateData() +bool LLImagePNG::updateData() { resetLastError(); @@ -55,7 +55,7 @@ BOOL LLImagePNG::updateData() if (!getData() || (0 == getDataSize())) { setLastError("Uninitialized instance of LLImagePNG"); - return FALSE; + return false; } // Decode the PNG data and extract sizing information @@ -63,25 +63,25 @@ BOOL LLImagePNG::updateData() if (!pngWrapper.isValidPng(getData())) { setLastError("LLImagePNG data does not have a valid PNG header!"); - return FALSE; + return false; } LLPngWrapper::ImageInfo infop; if (! pngWrapper.readPng(getData(), getDataSize(), NULL, &infop)) { setLastError(pngWrapper.getErrorMessage()); - return FALSE; + return false; } setSize(infop.mWidth, infop.mHeight, infop.mComponents); - return TRUE; + return true; } // Virtual // Decode an in-memory PNG image into the raw RGB or RGBA format // used within SecondLife. -BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time) +bool LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time) { llassert_always(raw_image); @@ -91,7 +91,7 @@ BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time) if (!getData() || (0 == getDataSize())) { setLastError("LLImagePNG trying to decode an image with no data!"); - return FALSE; + return false; } // Decode the PNG data into the raw image @@ -99,21 +99,21 @@ BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time) if (!pngWrapper.isValidPng(getData())) { setLastError("LLImagePNG data does not have a valid PNG header!"); - return FALSE; + return false; } if (! pngWrapper.readPng(getData(), getDataSize(), raw_image)) { setLastError(pngWrapper.getErrorMessage()); - return FALSE; + return false; } - return TRUE; + return true; } // Virtual // Encode the in memory RGB image into PNG format. -BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time) +bool LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time) { llassert_always(raw_image); @@ -133,7 +133,7 @@ BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time) { setLastError(pngWrapper.getErrorMessage()); delete[] tmpWriteBuffer; - return FALSE; + return false; } // Resize internal buffer and copy from temp @@ -143,6 +143,6 @@ BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time) delete[] tmpWriteBuffer; - return TRUE; + return true; } diff --git a/indra/llimage/llimagepng.h b/indra/llimage/llimagepng.h index 1fbd850a2eb22c0250e2713090661558eaad5196..ef16f2996f9a533fff0b4a88ad8ea0dc84184605 100644 --- a/indra/llimage/llimagepng.h +++ b/indra/llimage/llimagepng.h @@ -38,9 +38,9 @@ class LLImagePNG : public LLImageFormatted LLImagePNG(); /*virtual*/ std::string getExtension() { return std::string("png"); } - /*virtual*/ BOOL updateData(); - /*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time); - /*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time); + /*virtual*/ bool updateData(); + /*virtual*/ bool decode(LLImageRaw* raw_image, F32 decode_time); + /*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time); }; #endif diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp index d0ae105ba79699126098012987418a6eac58fa21..5ad7658ec1bbc7ca498760fc826dc89f04d76c57 100644 --- a/indra/llimage/llimagetga.cpp +++ b/indra/llimage/llimagetga.cpp @@ -61,7 +61,7 @@ LLImageTGA::LLImageTGA() mColorMapStart( 0 ), mColorMapLength( 0 ), mColorMapBytesPerEntry( 0 ), - mIs15Bit( FALSE ), + mIs15Bit( false ), mAttributeBits(0), mColorMapDepth(0), @@ -94,7 +94,7 @@ LLImageTGA::LLImageTGA(const std::string& file_name) mColorMapStart( 0 ), mColorMapLength( 0 ), mColorMapBytesPerEntry( 0 ), - mIs15Bit( FALSE ) + mIs15Bit( false ) { loadFile(file_name); } @@ -104,7 +104,7 @@ LLImageTGA::~LLImageTGA() delete [] mColorMap; } -BOOL LLImageTGA::updateData() +bool LLImageTGA::updateData() { resetLastError(); @@ -112,7 +112,7 @@ BOOL LLImageTGA::updateData() if (!getData() || (0 == getDataSize())) { setLastError("LLImageTGA uninitialized"); - return FALSE; + return false; } // Pull image information from the header... @@ -185,13 +185,13 @@ BOOL LLImageTGA::updateData() case 0: // No image data included in file setLastError("Unable to load file. TGA file contains no image data."); - return FALSE; + return false; case 1: // Colormapped uncompressed if( 8 != mPixelSize ) { setLastError("Unable to load file. Colormapped images must have 8 bits per pixel."); - return FALSE; + return false; } break; case 2: @@ -202,7 +202,7 @@ BOOL LLImageTGA::updateData() if( 8 != mPixelSize ) { setLastError("Unable to load file. Monochrome images must have 8 bits per pixel."); - return FALSE; + return false; } break; case 9: @@ -216,12 +216,12 @@ BOOL LLImageTGA::updateData() if( 8 != mPixelSize ) { setLastError("Unable to load file. Monochrome images must have 8 bits per pixel."); - return FALSE; + return false; } break; default: setLastError("Unable to load file. Unrecoginzed TGA image type."); - return FALSE; + return false; } // discard the ID field, if any @@ -266,8 +266,8 @@ BOOL LLImageTGA::updateData() mColorMap = new U8[ color_map_bytes ]; if (!mColorMap) { - LL_ERRS() << "Out of Memory in BOOL LLImageTGA::updateData()" << LL_ENDL; - return FALSE; + LL_ERRS() << "Out of Memory in bool LLImageTGA::updateData()" << LL_ENDL; + return false; } memcpy( mColorMap, getData() + mDataOffset, color_map_bytes ); /* Flawfinder: ignore */ } @@ -302,28 +302,28 @@ BOOL LLImageTGA::updateData() // if( mAttributeBits != 8 ) // { // setLastError("Unable to load file. 32 bit TGA image does not have 8 bits of alpha."); -// return FALSE; +// return false; // } mAttributeBits = 8; break; case 15: case 16: components = 3; - mIs15Bit = TRUE; // 16th bit is used for Targa hardware interupts and is ignored. + mIs15Bit = true; // 16th bit is used for Targa hardware interupts and is ignored. break; case 8: components = 1; break; default: setLastError("Unable to load file. Unknown pixel size."); - return FALSE; + return false; } setSize(width, height, components); - return TRUE; + return true; } -BOOL LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time) +bool LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time) { llassert_always(raw_image); @@ -331,7 +331,7 @@ BOOL LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time) if (!getData() || (0 == getDataSize())) { setLastError("LLImageTGA trying to decode an image with no data!"); - return FALSE; + return false; } // Copy everything after the header. @@ -343,18 +343,18 @@ BOOL LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time) (getComponents() != 4) ) { setLastError("TGA images with a number of components other than 1, 3, and 4 are not supported."); - return FALSE; + return false; } if( mOriginRightBit ) { setLastError("TGA images with origin on right side are not supported."); - return FALSE; + return false; } - BOOL flipped = (mOriginTopBit != 0); - BOOL rle_compressed = ((mImageType & 0x08) != 0); + bool flipped = (mOriginTopBit != 0); + bool rle_compressed = ((mImageType & 0x08) != 0); if( mColorMap ) { @@ -366,10 +366,10 @@ BOOL LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time) } } -BOOL LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, BOOL rle, BOOL flipped ) +bool LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, bool rle, bool flipped ) { - BOOL success = FALSE; - BOOL alpha_opaque = FALSE; + bool success = false; + bool alpha_opaque = false; if( rle ) { @@ -404,7 +404,7 @@ BOOL LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, BOOL rle, BOOL flipped } else { - BOOL alpha_opaque; + bool alpha_opaque; success = decodeTruecolorNonRle( raw_image, alpha_opaque ); if (alpha_opaque && raw_image->getComponents() == 4) { @@ -430,9 +430,9 @@ BOOL LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, BOOL rle, BOOL flipped } -BOOL LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaque ) +bool LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, bool &alpha_opaque ) { - alpha_opaque = TRUE; + alpha_opaque = true; // Origin is the bottom left U8* dst = raw_image->getData(); @@ -442,7 +442,7 @@ BOOL LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaqu if (pixels * (mIs15Bit ? 2 : getComponents()) > getDataSize() - mDataOffset) { //here we have situation when data size in src less than actually needed - return FALSE; + return false; } if (getComponents() == 4) @@ -456,7 +456,7 @@ BOOL LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaqu dst[3] = src[3]; // Alpha if (dst[3] != 255) { - alpha_opaque = FALSE; + alpha_opaque = false; } dst += 4; src += 4; @@ -490,7 +490,7 @@ BOOL LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaqu memcpy(dst, src, pixels); /* Flawfinder: ignore */ } - return TRUE; + return true; } void LLImageTGA::decodeColorMapPixel8( U8* dst, const U8* src ) @@ -523,14 +523,14 @@ void LLImageTGA::decodeColorMapPixel32( U8* dst, const U8* src ) } -BOOL LLImageTGA::decodeColorMap( LLImageRaw* raw_image, BOOL rle, BOOL flipped ) +bool LLImageTGA::decodeColorMap( LLImageRaw* raw_image, bool rle, bool flipped ) { // If flipped, origin is the top left. Need to reverse the order of the rows. // Otherwise the origin is the bottom left. if( 8 != mPixelSize ) { - return FALSE; + return false; } U8* src = getData() + mDataOffset; @@ -544,7 +544,7 @@ BOOL LLImageTGA::decodeColorMap( LLImageRaw* raw_image, BOOL rle, BOOL flipped ) case 2: pixel_decoder = &LLImageTGA::decodeColorMapPixel15; break; case 3: pixel_decoder = &LLImageTGA::decodeColorMapPixel24; break; case 4: pixel_decoder = &LLImageTGA::decodeColorMapPixel32; break; - default: llassert(0); return FALSE; + default: llassert(0); return false; } if( rle ) @@ -613,12 +613,12 @@ BOOL LLImageTGA::decodeColorMap( LLImageRaw* raw_image, BOOL rle, BOOL flipped ) } } - return TRUE; + return true; } -BOOL LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time) +bool LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time) { llassert_always(raw_image); @@ -642,7 +642,7 @@ BOOL LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time) mImageType = 2; break; default: - return FALSE; + return false; } // Color map stuff (unsupported) @@ -678,7 +678,7 @@ BOOL LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time) bytes_per_pixel = 4; break; default: - return FALSE; + return false; } mPixelSize = U8(bytes_per_pixel * 8); // 8, 16, 24, 32 bits per pixel @@ -765,13 +765,13 @@ BOOL LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time) break; } - return TRUE; + return true; } -BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque ) +bool LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, bool &alpha_opaque ) { llassert( getComponents() == 4 ); - alpha_opaque = TRUE; + alpha_opaque = true; U8* dst = raw_image->getData(); U32* dst_pixels = (U32*) dst; @@ -788,7 +788,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque // Read RLE block header if (src >= last_src) - return FALSE; + return false; U8 block_header_byte = *src; src++; @@ -799,7 +799,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque // Encoded (duplicate-pixel) block if (src + 3 >= last_src) - return FALSE; + return false; rgba_byte_p[0] = src[2]; rgba_byte_p[1] = src[1]; @@ -807,7 +807,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque rgba_byte_p[3] = src[3]; if (rgba_byte_p[3] != 255) { - alpha_opaque = FALSE; + alpha_opaque = false; } src += 4; @@ -826,7 +826,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque do { if (src + 3 >= last_src) - return FALSE; + return false; ((U8*)dst_pixels)[0] = src[2]; ((U8*)dst_pixels)[1] = src[1]; @@ -834,7 +834,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque ((U8*)dst_pixels)[3] = src[3]; if (src[3] != 255) { - alpha_opaque = FALSE; + alpha_opaque = false; } src += 4; dst_pixels++; @@ -844,10 +844,10 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque } } - return TRUE; + return true; } -BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image ) +bool LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image ) { llassert( getComponents() == 3 ); llassert( mIs15Bit ); @@ -863,7 +863,7 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image ) // Read RLE block header if (src >= last_src) - return FALSE; + return false; U8 block_header_byte = *src; src++; @@ -875,7 +875,7 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image ) do { if (src + 2 >= last_src) - return FALSE; + return false; decodeTruecolorPixel15( dst, src ); // slow dst += 3; @@ -890,7 +890,7 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image ) do { if (src + 2 >= last_src) - return FALSE; + return false; decodeTruecolorPixel15( dst, src ); dst += 3; @@ -901,12 +901,12 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image ) } } - return TRUE; + return true; } -BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image ) +bool LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image ) { llassert( getComponents() == 3 ); @@ -921,7 +921,7 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image ) // Read RLE block header if (src >= last_src) - return FALSE; + return false; U8 block_header_byte = *src; src++; @@ -933,7 +933,7 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image ) do { if (src + 2 >= last_src) - return FALSE; + return false; dst[0] = src[2]; dst[1] = src[1]; dst[2] = src[0]; @@ -949,7 +949,7 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image ) do { if (src + 2 >= last_src) - return FALSE; + return false; dst[0] = src[2]; dst[1] = src[1]; @@ -962,11 +962,11 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image ) } } - return TRUE; + return true; } -BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image ) +bool LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image ) { llassert( getComponents() == 1 ); @@ -981,7 +981,7 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image ) // Read RLE block header if (src >= last_src) - return FALSE; + return false; U8 block_header_byte = *src; src++; @@ -990,7 +990,7 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image ) if( block_header_byte & 0x80 ) { if (src >= last_src) - return FALSE; + return false; // Encoded (duplicate-pixel) block memset( dst, *src, block_pixel_count ); @@ -1003,7 +1003,7 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image ) do { if (src >= last_src) - return FALSE; + return false; *dst = *src; dst++; @@ -1014,13 +1014,13 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image ) } } - return TRUE; + return true; } // Decoded and process the image for use in avatar gradient masks. // Processing happens during the decode for speed. -BOOL LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight ) +bool LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight ) { llassert_always(raw_image); @@ -1043,14 +1043,14 @@ BOOL LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight if (!getData() || (0 == getDataSize())) { setLastError("LLImageTGA trying to decode an image with no data!"); - return FALSE; + return false; } // Only works for unflipped monochrome RLE images if( (getComponents() != 1) || (mImageType != 11) || mOriginTopBit || mOriginRightBit ) { LL_ERRS() << "LLImageTGA trying to alpha-gradient process an image that's not a standard RLE, one component image" << LL_ENDL; - return FALSE; + return false; } raw_image->resize(getWidth(), getHeight(), getComponents()); @@ -1136,7 +1136,7 @@ BOOL LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight } } } - return TRUE; + return true; } // Reads a .tga file and creates an LLImageTGA with its data. diff --git a/indra/llimage/llimagetga.h b/indra/llimage/llimagetga.h index 5da3525149b37a016f52deb0c0e854d8c0ca05b0..b1f34dcdaddf1f90e974fe6d3579021f49d02afb 100644 --- a/indra/llimage/llimagetga.h +++ b/indra/llimage/llimagetga.h @@ -41,25 +41,25 @@ class LLImageTGA : public LLImageFormatted LLImageTGA(const std::string& file_name); /*virtual*/ std::string getExtension() { return std::string("tga"); } - /*virtual*/ BOOL updateData(); - /*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time=0.0); - /*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time=0.0); + /*virtual*/ bool updateData(); + /*virtual*/ bool decode(LLImageRaw* raw_image, F32 decode_time=0.0); + /*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time=0.0); - BOOL decodeAndProcess(LLImageRaw* raw_image, F32 domain, F32 weight); + bool decodeAndProcess(LLImageRaw* raw_image, F32 domain, F32 weight); private: - BOOL decodeTruecolor( LLImageRaw* raw_image, BOOL rle, BOOL flipped ); + bool decodeTruecolor( LLImageRaw* raw_image, bool rle, bool flipped ); - BOOL decodeTruecolorRle8( LLImageRaw* raw_image ); - BOOL decodeTruecolorRle15( LLImageRaw* raw_image ); - BOOL decodeTruecolorRle24( LLImageRaw* raw_image ); - BOOL decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque ); + bool decodeTruecolorRle8( LLImageRaw* raw_image ); + bool decodeTruecolorRle15( LLImageRaw* raw_image ); + bool decodeTruecolorRle24( LLImageRaw* raw_image ); + bool decodeTruecolorRle32( LLImageRaw* raw_image, bool &alpha_opaque ); void decodeTruecolorPixel15( U8* dst, const U8* src ); - BOOL decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaque ); + bool decodeTruecolorNonRle( LLImageRaw* raw_image, bool &alpha_opaque ); - BOOL decodeColorMap( LLImageRaw* raw_image, BOOL rle, BOOL flipped ); + bool decodeColorMap( LLImageRaw* raw_image, bool rle, bool flipped ); void decodeColorMapPixel8(U8* dst, const U8* src); void decodeColorMapPixel15(U8* dst, const U8* src); @@ -100,7 +100,7 @@ class LLImageTGA : public LLImageFormatted S32 mColorMapLength; S32 mColorMapBytesPerEntry; - BOOL mIs15Bit; + bool mIs15Bit; static const U8 s5to8bits[32]; }; diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index aad139f57087c2dc818a67f57ee08d1bf6840522..da289ea889f796f15a3ba5dcd082b1f0dd33acdb 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -31,6 +31,16 @@ #include "llimage.h" #include "llpngwrapper.h" +#include "llexception.h" + +namespace { +// Failure to load an image shouldn't crash the whole viewer. +struct PngError: public LLContinueError +{ + PngError(png_const_charp msg): LLContinueError(msg) {} +}; +} // anonymous namespace + // --------------------------------------------------------------------------- // LLPngWrapper // --------------------------------------------------------------------------- @@ -75,11 +85,10 @@ BOOL LLPngWrapper::isValidPng(U8* src) } // Called by the libpng library when a fatal encoding or decoding error -// occurs. We simply throw the error message and let our try/catch -// block clean up. +// occurs. We throw PngError and let our try/catch block clean up. void LLPngWrapper::errorHandler(png_structp png_ptr, png_const_charp msg) { - throw msg; + LLTHROW(PngError(msg)); } // Called by the libpng library when reading (decoding) the PNG file. We @@ -129,7 +138,7 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf this, &errorHandler, NULL); if (mReadPngPtr == NULL) { - throw "Problem creating png read structure"; + LLTHROW(PngError("Problem creating png read structure")); } // Allocate/initialize the memory for image information. @@ -187,9 +196,9 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf mFinalSize = dataPtr.mOffset; } - catch (png_const_charp msg) + catch (const PngError& msg) { - mErrorMessage = msg; + mErrorMessage = msg.what(); releaseResources(); return (FALSE); } @@ -288,14 +297,14 @@ BOOL LLPngWrapper::writePng(const LLImageRaw* rawImage, U8* dest) if (mColorType == -1) { - throw "Unsupported image: unexpected number of channels"; + LLTHROW(PngError("Unsupported image: unexpected number of channels")); } mWritePngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, &errorHandler, NULL); if (!mWritePngPtr) { - throw "Problem creating png write structure"; + LLTHROW(PngError("Problem creating png write structure")); } mWriteInfoPtr = png_create_info_struct(mWritePngPtr); @@ -339,9 +348,9 @@ BOOL LLPngWrapper::writePng(const LLImageRaw* rawImage, U8* dest) png_write_end(mWritePngPtr, mWriteInfoPtr); mFinalSize = dataPtr.mOffset; } - catch (png_const_charp msg) + catch (const PngError& msg) { - mErrorMessage = msg; + mErrorMessage = msg.what(); releaseResources(); return (FALSE); } diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index e98f677d9b3753a57a274ddecb07dca95dd29b00..925da5674bfc5591faa941221c035a4aea8da1da 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -33,23 +33,20 @@ #include "lltimer.h" //#include "llmemory.h" -const char* fallbackEngineInfoLLImageJ2CImpl() -{ - static std::string version_string = - std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ") - + opj_version(); - return version_string.c_str(); -} - +// Factory function: see declaration in llimagej2c.cpp LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl() { return new LLImageJ2COJ(); } -void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl) +std::string LLImageJ2COJ::getEngineInfo() const { - delete impl; - impl = NULL; +#ifdef OPENJPEG_VERSION + return std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ") + + opj_version(); +#else + return std::string("OpenJPEG runtime: ") + opj_version(); +#endif } // Return string from message, eliminating final \n if present @@ -107,19 +104,19 @@ LLImageJ2COJ::~LLImageJ2COJ() { } -BOOL LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) +bool LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) { // No specific implementation for this method in the OpenJpeg case - return FALSE; + return false; } -BOOL LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels) +bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels) { // No specific implementation for this method in the OpenJpeg case - return FALSE; + return false; } -BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) +bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) { // // FIXME: Get the comment field out of the texture @@ -186,7 +183,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod opj_image_destroy(image); } - return TRUE; // done + return true; // done } // sometimes we get bad data out of the cache - check to see if the decode succeeded @@ -196,8 +193,8 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod { // if we didn't get the discard level we're expecting, fail opj_image_destroy(image); - base.mDecoding = FALSE; - return TRUE; + base.mDecoding = false; + return true; } } @@ -209,7 +206,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod opj_image_destroy(image); } - return TRUE; + return true; } // Copy image data into our raw image format (instead of the separate channel format @@ -256,18 +253,18 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL; opj_image_destroy(image); - return TRUE; // done + return true; // done } } /* free image data structure */ opj_image_destroy(image); - return TRUE; // done + return true; // done } -BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible) +bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible) { const S32 MAX_COMPS = 5; opj_cparameters_t parameters; /* compression parameters */ @@ -388,7 +385,7 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con { opj_cio_close(cio); LL_DEBUGS("Texture") << "Failed to encode image." << LL_ENDL; - return FALSE; + return false; } codestream_length = cio_tell(cio); @@ -407,10 +404,10 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con /* free image data */ opj_image_destroy(image); - return TRUE; + return true; } -BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base) +bool LLImageJ2COJ::getMetadata(LLImageJ2C &base) { // // FIXME: We get metadata by decoding the ENTIRE image. @@ -473,7 +470,7 @@ BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base) if(!image) { LL_WARNS() << "ERROR -> getMetadata: failed to decode image!" << LL_ENDL; - return FALSE; + return false; } // Copy image data into our raw image format (instead of the separate channel format @@ -487,5 +484,5 @@ BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base) /* free image data structure */ opj_image_destroy(image); - return TRUE; + return true; } diff --git a/indra/llimagej2coj/llimagej2coj.h b/indra/llimagej2coj/llimagej2coj.h index 40ad4edb00fef16f726be93416fef5d216f4719a..5c6193944e3222a062090e06fec90b458dcee6a8 100644 --- a/indra/llimagej2coj/llimagej2coj.h +++ b/indra/llimagej2coj/llimagej2coj.h @@ -35,12 +35,13 @@ class LLImageJ2COJ : public LLImageJ2CImpl LLImageJ2COJ(); virtual ~LLImageJ2COJ(); protected: - /*virtual*/ BOOL getMetadata(LLImageJ2C &base); - /*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count); - /*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0, - BOOL reversible = FALSE); - /*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); - /*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0); + virtual bool getMetadata(LLImageJ2C &base); + virtual bool decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count); + virtual bool encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0, + bool reversible = false); + virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); + virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0); + virtual std::string getEngineInfo() const; }; #endif diff --git a/indra/llinventory/lleconomy.cpp b/indra/llinventory/lleconomy.cpp index e10402196fd568e1f1154fe3d8fef45445d55523..2a023d8c24dc4aa4481967f5496cb232d3358047 100644 --- a/indra/llinventory/lleconomy.cpp +++ b/indra/llinventory/lleconomy.cpp @@ -31,7 +31,7 @@ #include "v3math.h" -LLGlobalEconomy::LLGlobalEconomy() +LLBaseEconomy::LLBaseEconomy() : mObjectCount( -1 ), mObjectCapacity( -1 ), mPriceObjectClaim( -1 ), @@ -45,15 +45,15 @@ LLGlobalEconomy::LLGlobalEconomy() mPriceGroupCreate( -1 ) { } -LLGlobalEconomy::~LLGlobalEconomy() +LLBaseEconomy::~LLBaseEconomy() { } -void LLGlobalEconomy::addObserver(LLEconomyObserver* observer) +void LLBaseEconomy::addObserver(LLEconomyObserver* observer) { mObservers.push_back(observer); } -void LLGlobalEconomy::removeObserver(LLEconomyObserver* observer) +void LLBaseEconomy::removeObserver(LLEconomyObserver* observer) { std::list<LLEconomyObserver*>::iterator it = std::find(mObservers.begin(), mObservers.end(), observer); @@ -63,7 +63,7 @@ void LLGlobalEconomy::removeObserver(LLEconomyObserver* observer) } } -void LLGlobalEconomy::notifyObservers() +void LLBaseEconomy::notifyObservers() { for (std::list<LLEconomyObserver*>::iterator it = mObservers.begin(); it != mObservers.end(); @@ -74,7 +74,7 @@ void LLGlobalEconomy::notifyObservers() } // static -void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data) +void LLBaseEconomy::processEconomyData(LLMessageSystem *msg, LLBaseEconomy* econ_data) { S32 i; F32 f; @@ -117,7 +117,7 @@ void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data->notifyObservers(); } -S32 LLGlobalEconomy::calculateTeleportCost(F32 distance) const +S32 LLBaseEconomy::calculateTeleportCost(F32 distance) const { S32 min_cost = getTeleportMinPrice(); F32 exponent = getTeleportPriceExponent(); @@ -135,13 +135,13 @@ S32 LLGlobalEconomy::calculateTeleportCost(F32 distance) const return cost; } -S32 LLGlobalEconomy::calculateLightRent(const LLVector3& object_size) const +S32 LLBaseEconomy::calculateLightRent(const LLVector3& object_size) const { F32 intensity_mod = llmax(object_size.magVec(), 1.f); return (S32)(intensity_mod * getPriceRentLight()); } -void LLGlobalEconomy::print() +void LLBaseEconomy::print() { LL_INFOS() << "Global Economy Settings: " << LL_ENDL; LL_INFOS() << "Object Capacity: " << mObjectCapacity << LL_ENDL; @@ -159,8 +159,7 @@ void LLGlobalEconomy::print() } LLRegionEconomy::LLRegionEconomy() -: LLGlobalEconomy(), - mPriceObjectRent( -1.f ), +: mPriceObjectRent( -1.f ), mPriceObjectScaleFactor( -1.f ), mEnergyEfficiency( -1.f ), mBasePriceParcelClaimDefault(-1), @@ -187,7 +186,7 @@ void LLRegionEconomy::processEconomyData(LLMessageSystem *msg, void** user_data) LLRegionEconomy *this_ptr = (LLRegionEconomy*)user_data; - LLGlobalEconomy::processEconomyData(msg, this_ptr); + LLBaseEconomy::processEconomyData(msg, this_ptr); msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceParcelClaim, i); this_ptr->setBasePriceParcelClaimDefault(i); @@ -252,7 +251,7 @@ S32 LLRegionEconomy::getPriceParcelRent() const void LLRegionEconomy::print() { - this->LLGlobalEconomy::print(); + this->LLBaseEconomy::print(); LL_INFOS() << "Region Economy Settings: " << LL_ENDL; LL_INFOS() << "Land (square meters): " << mAreaTotal << LL_ENDL; diff --git a/indra/llinventory/lleconomy.h b/indra/llinventory/lleconomy.h index 47fcf688a26d66e9b61b70f119288d1ceb5c5303..cdfde171c1834371f9af16ecce60999935577252 100644 --- a/indra/llinventory/lleconomy.h +++ b/indra/llinventory/lleconomy.h @@ -42,18 +42,11 @@ class LLEconomyObserver virtual void onEconomyDataChange() = 0; }; -class LLGlobalEconomy +class LLBaseEconomy { public: - LLGlobalEconomy(); - virtual ~LLGlobalEconomy(); - - // This class defines its singleton internally as a typedef instead of inheriting from - // LLSingleton like most others because the LLRegionEconomy sub-class might also - // become a singleton and this pattern will more easily disambiguate them. - typedef LLSingleton<LLGlobalEconomy> Singleton; - - void initSingleton() { } + LLBaseEconomy(); + virtual ~LLBaseEconomy(); virtual void print(); @@ -61,7 +54,7 @@ class LLGlobalEconomy void removeObserver(LLEconomyObserver* observer); void notifyObservers(); - static void processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data); + static void processEconomyData(LLMessageSystem *msg, LLBaseEconomy* econ_data); S32 calculateTeleportCost(F32 distance) const; S32 calculateLightRent(const LLVector3& object_size) const; @@ -108,8 +101,12 @@ class LLGlobalEconomy std::list<LLEconomyObserver*> mObservers; }; +class LLGlobalEconomy: public LLSingleton<LLGlobalEconomy>, public LLBaseEconomy +{ + LLSINGLETON_EMPTY_CTOR(LLGlobalEconomy); +}; -class LLRegionEconomy : public LLGlobalEconomy +class LLRegionEconomy : public LLBaseEconomy { public: LLRegionEconomy(); diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp index 86aca77de894f8a4f49a1c3e34d5f6328d900185..b0daf639fad2c054e77f45b21584fa795f1fc585 100644 --- a/indra/llinventory/llfoldertype.cpp +++ b/indra/llinventory/llfoldertype.cpp @@ -51,8 +51,7 @@ struct FolderEntry : public LLDictionaryEntry class LLFolderDictionary : public LLSingleton<LLFolderDictionary>, public LLDictionary<LLFolderType::EType, FolderEntry> { -public: - LLFolderDictionary(); + LLSINGLETON(LLFolderDictionary); protected: virtual LLFolderType::EType notFound() const { diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index 8807b36117047dd08658ebe9feeaec5ef0fb5993..d1e6807f52138a3fa5fd2ed6a64b5433d6a337b9 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -63,8 +63,7 @@ struct InventoryEntry : public LLDictionaryEntry class LLInventoryDictionary : public LLSingleton<LLInventoryDictionary>, public LLDictionary<LLInventoryType::EType, InventoryEntry> { -public: - LLInventoryDictionary(); + LLSINGLETON(LLInventoryDictionary); }; LLInventoryDictionary::LLInventoryDictionary() diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt index b8f8b420c329cc8bc0c448c900f4d3ca34bfed41..cb0e204e91a6f2eb26c839727cd6b8d20e08380d 100644 --- a/indra/llkdu/CMakeLists.txt +++ b/indra/llkdu/CMakeLists.txt @@ -40,6 +40,14 @@ set_source_files_properties(${llkdu_HEADER_FILES} list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES}) +# Our KDU package is built with KDU_X86_INTRINSICS in its .vcxproj file. +# Unless that macro is also set for every consumer build, KDU freaks out, +# spamming the viewer log with alignment FUD. +set_source_files_properties(${llkdu_SOURCE_FILES} + PROPERTIES + COMPILE_DEFINITIONS + "KDU_X86_INTRINSICS") + if (USE_KDU) add_library (llkdu ${llkdu_SOURCE_FILES}) diff --git a/indra/llkdu/include_kdu_xxxx.h b/indra/llkdu/include_kdu_xxxx.h new file mode 100644 index 0000000000000000000000000000000000000000..a1dbced60b27b128dab55bdaeff52158f74dd03e --- /dev/null +++ b/indra/llkdu/include_kdu_xxxx.h @@ -0,0 +1,40 @@ +/** + * @file include_kdu_xxxx.h + * @author Nat Goodspeed + * @date 2016-04-25 + * @brief + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// This file specifically omits #include guards of its own: it's sort of an +// #include macro used to wrap KDU #includes with proper incantations. Usage: + +// #define kdu_xxxx "kdu_compressed.h" // or whichever KDU header +// #include "include_kdu_xxxx.h" +// // kdu_xxxx #undef'ed by include_kdu_xxxx.h + +#if LL_DARWIN +// don't *really* want to rebuild KDU so turn off specific warnings for this header +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wself-assign-field" +#pragma clang diagnostic ignored "-Wunused-private-field" +#include kdu_xxxx +#pragma clang diagnostic pop +#elif LL_WINDOWS +// With warnings-as-errors in effect, strange relationship between +// jp2_output_box and its subclass jp2_target in kdu_compressed.h +// causes build failures. Specifically: +// warning C4263: 'void kdu_supp::jp2_target::open(kdu_supp::jp2_family_tgt *)' : member function does not override any base class virtual member function +// warning C4264: 'void kdu_supp::jp2_output_box::open(kdu_core::kdu_uint32)' : no override available for virtual member function from base 'kdu_supp::jp2_output_box'; function is hidden +#pragma warning(push) +#pragma warning(disable : 4263 4264) +#include kdu_xxxx +#pragma warning(pop) +#else // some other platform +#include kdu_xxxx +#endif + +#undef kdu_xxxx diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 282c859e9e79c6ba702992005446443745568c9b..cb29da8f5fe8d8674229c5d046895f7637d8198d 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -1,4 +1,4 @@ - /** +/** * @file llimagej2ckdu.cpp * @brief This is an implementation of JPEG2000 encode/decode using Kakadu * @@ -25,6 +25,7 @@ */ #include "linden_common.h" + #include "llimagej2ckdu.h" #include "lltimer.h" @@ -32,12 +33,75 @@ #include "llmath.h" #include "llkdumem.h" -#include "kdu_block_coding.h" +#define kdu_xxxx "kdu_block_coding.h" +#include "include_kdu_xxxx.h" + +// Avoid ubiquitous necessity of kdu_core:: qualification +using namespace kdu_core; + +#include "llexception.h" +#include <boost/exception/diagnostic_information.hpp> +#include <sstream> +#include <iomanip> + +// stream kdu_dims to std::ostream +// Turns out this must NOT be in the anonymous namespace! +// It must also precede #include "stringize.h". +inline +std::ostream& operator<<(std::ostream& out, const kdu_dims& dims) +{ + return out << "(" << dims.pos.x << "," << dims.pos.y << ")," + "[" << dims.size.x << "x" << dims.size.y << "]"; +} + +#include "stringize.h" + +namespace { +// Failure to load an image shouldn't crash the whole viewer. +struct KDUError: public LLContinueError +{ + KDUError(const std::string& msg): LLContinueError(msg) {} +}; + +// KDU defines int error codes as hex values, so we should log them in hex +// so we can grep KDU headers for the hex. However those hex values +// generally "happen" to encode big-endian multibyte character sequences, +// e.g. KDU_ERROR_EXCEPTION is 0x6b647545: 'kduE' +// But beware because KDU_NULL_EXCEPTION is simply 0 -- which doesn't +// preclude somebody from throwing it. +std::string report_kdu_exception(kdu_exception mb) +{ + std::ostringstream out; + // always report mb in hex + out << "kdu_exception " << std::hex << mb; + + // Also display as many chars as are encoded in the kdu_exception + // value. Make a char array; reserve 1 extra byte for nul terminator. + char bytes[sizeof(kdu_exception) + 1]; + // Back up through 'bytes' + char *bptr = bytes + sizeof(bytes); + *(--bptr) = '\0'; + while (mb) + { + // store low-order byte of mb in next-left char + *(--bptr) = char(mb & 0xFF); + // then shift mb right by one byte + mb >>= 8; + } + // did that produce any characters? + if (*bptr) + { + out << " (" << bptr << ')'; + } + + return out.str(); +} +} // anonymous namespace class kdc_flow_control { public: - kdc_flow_control(kdu_image_in_base *img_in, kdu_codestream codestream); + kdc_flow_control(kdu_supp::kdu_image_in_base *img_in, kdu_codestream codestream); ~kdc_flow_control(); bool advance_components(); void process_components(); @@ -46,7 +110,7 @@ class kdc_flow_control { struct kdc_component_flow_control { public: - kdu_image_in_base *reader; + kdu_supp::kdu_image_in_base *reader; int vert_subsampling; int ratio_counter; /* Initialized to 0, decremented by `count_delta'; when < 0, a new line must be processed, after @@ -72,49 +136,28 @@ class kdc_flow_control { // void set_default_colour_weights(kdu_params *siz); -const char* engineInfoLLImageJ2CKDU() -{ - static std::string version = llformat("KDU %s", KDU_CORE_VERSION); - return version.c_str(); -} - -LLImageJ2CKDU* createLLImageJ2CKDU() -{ - return new LLImageJ2CKDU(); -} - -void destroyLLImageJ2CKDU(LLImageJ2CKDU* kdu) -{ - delete kdu; - kdu = NULL; -} - +// Factory function: see declaration in llimagej2c.cpp LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl() { return new LLImageJ2CKDU(); } -void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl) -{ - delete impl; - impl = NULL; -} - -const char* fallbackEngineInfoLLImageJ2CImpl() +std::string LLImageJ2CKDU::getEngineInfo() const { - return engineInfoLLImageJ2CKDU(); + return llformat("KDU %s", KDU_CORE_VERSION); } class LLKDUDecodeState { public: - LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap); + LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap, + kdu_codestream* codestreamp); ~LLKDUDecodeState(); - BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE); + bool processTileDecode(F32 decode_time, bool limit_time = true); private: S32 mNumComponents; - BOOL mUseYCC; + bool mUseYCC; kdu_dims mDims; kdu_sample_allocator mAllocator; kdu_tile_comp mComps[4]; @@ -128,74 +171,91 @@ class LLKDUDecodeState S32 mRowGap; }; -void ll_kdu_error( void ) -{ - // *FIX: This exception is bad, bad, bad. It gets thrown from a - // destructor which can lead to immediate program termination! - throw "ll_kdu_error() throwing an exception"; -} - // Stuff for new kdu error handling -class LLKDUMessageWarning : public kdu_message +class LLKDUMessage: public kdu_message { public: - /*virtual*/ void put_text(const char *s); - /*virtual*/ void put_text(const kdu_uint16 *s); - - static LLKDUMessageWarning sDefaultMessage; -}; + LLKDUMessage(const std::string& type): + mType(type) + {} -class LLKDUMessageError : public kdu_message -{ -public: - /*virtual*/ void put_text(const char *s); - /*virtual*/ void put_text(const kdu_uint16 *s); - /*virtual*/ void flush(bool end_of_message = false); - static LLKDUMessageError sDefaultMessage; -}; - -void LLKDUMessageWarning::put_text(const char *s) -{ - LL_INFOS() << "KDU Warning: " << s << LL_ENDL; -} + virtual void put_text(const char *s) + { + LL_INFOS() << "KDU " << mType << ": " << s << LL_ENDL; + } -void LLKDUMessageWarning::put_text(const kdu_uint16 *s) -{ - LL_INFOS() << "KDU Warning: " << s << LL_ENDL; -} + virtual void put_text(const kdu_uint16 *s) + { + // The previous implementation simply streamed 's' to the log. So + // either this put_text() override was never called -- or it produced + // some baffling log messages -- because I assert that streaming a + // const kdu_uint16* to a std::ostream will display only the hex value + // of the pointer. + LL_INFOS() << "KDU " << mType << ": " + << utf16str_to_utf8str(llutf16string(s)) << LL_ENDL; + } -void LLKDUMessageError::put_text(const char *s) -{ - LL_INFOS() << "KDU Error: " << s << LL_ENDL; -} +private: + std::string mType; +}; -void LLKDUMessageError::put_text(const kdu_uint16 *s) +struct LLKDUMessageWarning : public LLKDUMessage { - LL_INFOS() << "KDU Error: " << s << LL_ENDL; -} + LLKDUMessageWarning(): + LLKDUMessage("Warning") + { + kdu_customize_warnings(this); + } +}; +// Instantiating LLKDUMessageWarning calls kdu_customize_warnings() with the +// new instance. Make it static so this only happens once. +static LLKDUMessageWarning sWarningHandler; -void LLKDUMessageError::flush(bool end_of_message) +struct LLKDUMessageError : public LLKDUMessage { - if (end_of_message) + LLKDUMessageError(): + LLKDUMessage("Error") { - throw "KDU throwing an exception"; + kdu_customize_errors(this); } -} -LLKDUMessageWarning LLKDUMessageWarning::sDefaultMessage; -LLKDUMessageError LLKDUMessageError::sDefaultMessage; -static bool kdu_message_initialized = false; + virtual void flush(bool end_of_message = false) + { + // According to the documentation nat found: + // http://pirlwww.lpl.arizona.edu/resources/guide/software/Kakadu/html_pages/globals__kdu$mize_errors.html + // "If a kdu_error object is destroyed, handler→flush will be called with + // an end_of_message argument equal to true and the process will + // subsequently be terminated through exit. The termination may be + // avoided, however, by throwing an exception from within the message + // terminating handler→flush call." + // So throwing an exception here isn't arbitrary: we MUST throw an + // exception if we want to recover from a KDU error. + // Because this confused me: the above quote specifically refers to + // the kdu_error class, which is constructed internally within KDU at + // the point where a fatal error is discovered and reported. It is NOT + // talking about the kdu_message subclass passed to + // kdu_customize_errors(). Destroying this static object at program + // shutdown will NOT engage the behavior described above. + if (end_of_message) + { + LLTHROW(KDUError("LLKDUMessageError::flush()")); + } + } +}; +// Instantiating LLKDUMessageError calls kdu_customize_errors() with the new +// instance. Make it static so this only happens once. +static LLKDUMessageError sErrorHandler; LLImageJ2CKDU::LLImageJ2CKDU() : LLImageJ2CImpl(), -mInputp(NULL), -mCodeStreamp(NULL), -mTPosp(NULL), -mTileIndicesp(NULL), -mRawImagep(NULL), -mDecodeState(NULL), -mBlocksSize(-1), -mPrecinctsSize(-1), -mLevels(0) + mInputp(), + mCodeStreamp(), + mTPosp(), + mTileIndicesp(), + mRawImagep(NULL), + mDecodeState(), + mBlocksSize(-1), + mPrecinctsSize(-1), + mLevels(0) { } @@ -207,7 +267,11 @@ LLImageJ2CKDU::~LLImageJ2CKDU() // Stuff for new simple decode void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision); -void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode) +// This is called by the real (private) initDecode() (keep_codestream true) +// and getMetadata() methods (keep_codestream false). As far as nat can tell, +// mode is always MODE_FAST. It was called by findDiscardLevelsBoundaries() +// as well, when that still existed, with keep_codestream true and MODE_FAST. +void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode) { S32 data_size = base.getDataSize(); S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size); @@ -215,38 +279,33 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod // // Initialization // - if (!kdu_message_initialized) - { - kdu_message_initialized = true; - kdu_customize_errors(&LLKDUMessageError::sDefaultMessage); - kdu_customize_warnings(&LLKDUMessageWarning::sDefaultMessage); - } - - if (mCodeStreamp) - { - mCodeStreamp->destroy(); - delete mCodeStreamp; - mCodeStreamp = NULL; - } - + mCodeStreamp.reset(); + + // It's not clear to nat under what circumstances we would reuse a + // pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of + // two U32s and a pointer, so it's not as if it would be a huge overhead + // to allocate a new one every time. + // Also -- why is base.getData() tested specifically here? If that returns + // NULL, shouldn't we bail out of the whole method? if (!mInputp && base.getData()) { // The compressed data has been loaded // Setup the source for the codestream - mInputp = new LLKDUMemSource(base.getData(), data_size); + mInputp.reset(new LLKDUMemSource(base.getData(), data_size)); } if (mInputp) { + // This is LLKDUMemSource::reset(), not boost::scoped_ptr::reset(). mInputp->reset(); } - mCodeStreamp = new kdu_codestream; - mCodeStreamp->create(mInputp); + mCodeStreamp->create(mInputp.get()); // Set the maximum number of bytes to use from the codestream - // *TODO: This seems to be wrong. The base class should have no idea of how j2c compression works so no - // good way of computing what's the byte range to be used. + // *TODO: This seems to be wrong. The base class should have no idea of + // how j2c compression works so no good way of computing what's the byte + // range to be used. mCodeStreamp->set_max_bytes(max_bytes,true); // If you want to flip or rotate the image for some reason, change @@ -284,13 +343,19 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod S32 components = mCodeStreamp->get_num_components(); - if (components >= 3) - { // Check that components have consistent dimensions (for PPM file) - kdu_dims dims1; mCodeStreamp->get_dims(1,dims1); - kdu_dims dims2; mCodeStreamp->get_dims(2,dims2); - if ((dims1 != dims) || (dims2 != dims)) + // Check that components have consistent dimensions (for PPM file) + for (int idx = 1; idx < components; ++idx) + { + kdu_dims other_dims; + mCodeStreamp->get_dims(idx, other_dims); + if (other_dims != dims) { - LL_ERRS() << "Components don't have matching dimensions!" << LL_ENDL; + // This method is only called from methods that catch KDUError. + // We want to fail the image load, not crash the viewer. + LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions " + << stringize(other_dims) + << " do not match component 0 dimensions " + << stringize(dims) << "!"))); } } @@ -303,42 +368,29 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod if (!keep_codestream) { - mCodeStreamp->destroy(); - delete mCodeStreamp; - mCodeStreamp = NULL; - delete mInputp; - mInputp = NULL; + mCodeStreamp.reset(); + mInputp.reset(); } } void LLImageJ2CKDU::cleanupCodeStream() { - delete mInputp; - mInputp = NULL; - - delete mDecodeState; - mDecodeState = NULL; - - if (mCodeStreamp) - { - mCodeStreamp->destroy(); - delete mCodeStreamp; - mCodeStreamp = NULL; - } - - delete mTPosp; - mTPosp = NULL; - - delete mTileIndicesp; - mTileIndicesp = NULL; + mInputp.reset(); + mDecodeState.reset(); + mCodeStreamp.reset(); + mTPosp.reset(); + mTileIndicesp.reset(); } -BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) +// This is the protected virtual method called by LLImageJ2C::initDecode(). +// However, as far as nat can tell, LLImageJ2C::initDecode() is called only by +// llimage_libtest.cpp's load_image() function. No detectable production use. +bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) { return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region); } -BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels) +bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels) { mPrecinctsSize = precincts_size; if (mPrecinctsSize != -1) @@ -362,10 +414,13 @@ BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc mLevels = llclamp(mLevels,MIN_DECOMPOSITION_LEVELS,MAX_DECOMPOSITION_LEVELS); base.setLevels(mLevels); } - return TRUE; + return true; } -BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region) +// This is the real (private) initDecode() called both by the protected +// initDecode() method and by decodeImpl(). As far as nat can tell, only the +// decodeImpl() usage matters for production. +bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region) { base.resetLastError(); @@ -377,7 +432,7 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco //findDiscardLevelsBoundaries(base); base.updateRawDiscardLevel(); - setupCodeStream(base, TRUE, mode); + setupCodeStream(base, true, mode); mRawImagep = &raw_image; mCodeStreamp->change_appearance(false, true, false); @@ -412,45 +467,55 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco if (!mTileIndicesp) { - mTileIndicesp = new kdu_dims; + mTileIndicesp.reset(new kdu_dims); } mCodeStreamp->get_valid_tiles(*mTileIndicesp); if (!mTPosp) { - mTPosp = new kdu_coords; + mTPosp.reset(new kdu_coords); mTPosp->y = 0; mTPosp->x = 0; } } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); - return FALSE; + base.setLastError(msg.what()); + return false; + } + catch (kdu_exception kdu_value) + { + // KDU internally throws kdu_exception. It's possible that such an + // exception might leak out into our code. Catch kdu_exception + // specially because boost::current_exception_diagnostic_information() + // could do nothing with it. + base.setLastError(report_kdu_exception(kdu_value)); + return false; } catch (...) { - base.setLastError("Unknown J2C error"); - return FALSE; + base.setLastError("Unknown J2C error: " + + boost::current_exception_diagnostic_information()); + return false; } - return TRUE; + return true; } -// Returns TRUE to mean done, whether successful or not. -BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) +// Returns true to mean done, whether successful or not. +bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) { ECodeStreamMode mode = MODE_FAST; LLTimer decode_timer; - if (!mCodeStreamp) + if (!mCodeStreamp->exists()) { if (!initDecode(base, raw_image, decode_time, mode, first_channel, max_channel_count)) { // Initializing the J2C decode failed, bail out. cleanupCodeStream(); - return TRUE; // done + return true; // done } } @@ -460,6 +525,13 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco // Now we are ready to walk through the tiles processing them one-by-one. kdu_byte *buffer = raw_image.getData(); + if (!buffer) + { + base.setLastError("Memory error"); + base.decodeFailed(); + cleanupCodeStream(); + return true; // done + } while (mTPosp->y < mTileIndicesp->size.y) { @@ -495,36 +567,48 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco kdu_coords offset = tile_dims.pos - dims.pos; int row_gap = channels*dims.size.x; // inter-row separation kdu_byte *buf = buffer + offset.y*row_gap + offset.x*channels; - mDecodeState = new LLKDUDecodeState(tile, buf, row_gap); + mDecodeState.reset(new LLKDUDecodeState(tile, buf, row_gap, + mCodeStreamp.get())); } // Do the actual processing F32 remaining_time = decode_time - decode_timer.getElapsedTimeF32(); // This is where we do the actual decode. If we run out of time, return false. if (mDecodeState->processTileDecode(remaining_time, (decode_time > 0.0f))) { - delete mDecodeState; - mDecodeState = NULL; + mDecodeState.reset(); } else { // Not finished decoding yet. // setLastError("Ran out of time while decoding"); - return FALSE; + return false; } } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); base.decodeFailed(); cleanupCodeStream(); - return TRUE; // done + return true; // done + } + catch (kdu_exception kdu_value) + { + // KDU internally throws kdu_exception. It's possible that such an + // exception might leak out into our code. Catch kdu_exception + // specially because boost::current_exception_diagnostic_information() + // could do nothing with it. + base.setLastError(report_kdu_exception(kdu_value)); + base.decodeFailed(); + cleanupCodeStream(); + return true; // done } catch (...) { - base.setLastError( "Unknown J2C error" ); + base.setLastError("Unknown J2C error: " + + boost::current_exception_diagnostic_information()); base.decodeFailed(); cleanupCodeStream(); - return TRUE; // done + return true; // done } @@ -536,11 +620,11 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco cleanupCodeStream(); - return TRUE; + return true; } -BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible) +bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible) { // Declare and set simple arguments bool transpose = false; @@ -705,39 +789,59 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co base.updateData(); // set width, height delete[] output_buffer; } - catch(const char* msg) + catch(const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); - return FALSE; + base.setLastError(msg.what()); + return false; + } + catch (kdu_exception kdu_value) + { + // KDU internally throws kdu_exception. It's possible that such an + // exception might leak out into our code. Catch kdu_exception + // specially because boost::current_exception_diagnostic_information() + // could do nothing with it. + base.setLastError(report_kdu_exception(kdu_value)); + return false; } catch( ... ) { - base.setLastError( "Unknown J2C error" ); - return FALSE; + base.setLastError("Unknown J2C error: " + + boost::current_exception_diagnostic_information()); + return false; } - return TRUE; + return true; } -BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base) +bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base) { // *FIX: kdu calls our callback function if there's an error, and // then bombs. To regain control, we throw an exception, and // catch it here. try { - setupCodeStream(base, FALSE, MODE_FAST); - return TRUE; + setupCodeStream(base, false, MODE_FAST); + return true; } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); - return FALSE; + base.setLastError(msg.what()); + return false; + } + catch (kdu_exception kdu_value) + { + // KDU internally throws kdu_exception. It's possible that such an + // exception might leak out into our code. Catch kdu_exception + // specially because boost::current_exception_diagnostic_information() + // could do nothing with it. + base.setLastError(report_kdu_exception(kdu_value)); + return false; } catch (...) { - base.setLastError( "Unknown J2C error" ); - return FALSE; + base.setLastError("Unknown J2C error: " + + boost::current_exception_diagnostic_information()); + return false; } } @@ -745,6 +849,8 @@ BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base) /* STATIC copy_block */ /*****************************************************************************/ +/*==========================================================================*| +// Only called by copy_tile(), which is itself commented out static void copy_block(kdu_block *in, kdu_block *out) { if (in->K_max_prime != out->K_max_prime) @@ -773,11 +879,14 @@ static void copy_block(kdu_block *in, kdu_block *out) out->set_max_bytes(num_bytes,false); memcpy(out->byte_buffer,in->byte_buffer,(size_t) num_bytes); } +|*==========================================================================*/ /*****************************************************************************/ /* STATIC copy_tile */ /*****************************************************************************/ +/*==========================================================================*| +// Only called by findDiscardLevelsBoundaries(), which is itself commented out static void copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out, kdu_params *siz_in, kdu_params *siz_out, int skip_components, @@ -834,10 +943,13 @@ copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out, } } } +|*==========================================================================*/ // Find the block boundary for each discard level in the input image. // We parse the input blocks and copy them in a temporary output stream. // For the moment, we do nothing more that parsing the raw list of blocks and outputing result. +/*==========================================================================*| +// See comments in header file for why this is commented out. void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base) { // We need the number of levels in that image before starting. @@ -847,7 +959,7 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base) { //std::cout << "Parsing discard level = " << discard_level << std::endl; // Create the input codestream object. - setupCodeStream(base, TRUE, MODE_FAST); + setupCodeStream(base, true, MODE_FAST); mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, NULL); mCodeStreamp->set_max_bytes(KDU_LONG_MAX,true); siz_params *siz_in = mCodeStreamp->access_siz(); @@ -941,6 +1053,7 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base) } return; } +|*==========================================================================*/ void set_default_colour_weights(kdu_params *siz) { @@ -1143,7 +1256,8 @@ all necessary level shifting, type conversion, rounding and truncation. */ } } -LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap) +LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap, + kdu_codestream* codestreamp) { S32 c; @@ -1189,7 +1303,7 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap) mEngines[c] = kdu_synthesis(res,&mAllocator,use_shorts); } } - mAllocator.finalize(); // Actually creates buffering resources + mAllocator.finalize(*codestreamp); // Actually creates buffering resources for (c = 0; c < mNumComponents; c++) { mLines[c].create(); // Grabs resources from the allocator. @@ -1206,7 +1320,7 @@ LLKDUDecodeState::~LLKDUDecodeState() mTile.close(); } -BOOL LLKDUDecodeState::processTileDecode(F32 decode_time, BOOL limit_time) +bool LLKDUDecodeState::processTileDecode(F32 decode_time, bool limit_time) /* Decompresses a tile, writing the data into the supplied byte buffer. The buffer contains interleaved image components, if there are any. Although you may think of the buffer as belonging entirely to this tile, @@ -1238,16 +1352,16 @@ separation between consecutive rows in the real buffer. */ { if (limit_time && decode_timer.getElapsedTimeF32() > decode_time) { - return FALSE; + return false; } } } - return TRUE; + return true; } // kdc_flow_control -kdc_flow_control::kdc_flow_control (kdu_image_in_base *img_in, kdu_codestream codestream) +kdc_flow_control::kdc_flow_control (kdu_supp::kdu_image_in_base *img_in, kdu_codestream codestream) { int n; diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 02281152bf6e82abc992cfa83917bc64904bea61..b57e4cc40e51519fae5eab0b9b08caaedb89d4de 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -37,17 +37,12 @@ #include "kdu_messaging.h" #include "kdu_params.h" -// don't *really* want to rebuild KDU so turn off specific warnings for this header -#if LL_DARWIN -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-private-field" -#include "kdu_compressed.h" -#pragma clang diagnostic pop -#else -#include "kdu_compressed.h" -#endif +#define kdu_xxxx "kdu_compressed.h" +#include "include_kdu_xxxx.h" #include "kdu_sample_processing.h" +#include <boost/scoped_ptr.hpp> +#include <boost/noncopyable.hpp> class LLKDUDecodeState; class LLKDUMemSource; @@ -65,43 +60,72 @@ class LLImageJ2CKDU : public LLImageJ2CImpl virtual ~LLImageJ2CKDU(); protected: - /*virtual*/ BOOL getMetadata(LLImageJ2C &base); - /*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count); - /*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0, - BOOL reversible=FALSE); - /*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); - /*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0); - void findDiscardLevelsBoundaries(LLImageJ2C &base); + virtual bool getMetadata(LLImageJ2C &base); + virtual bool decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count); + virtual bool encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0, + bool reversible=false); + virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); + virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0); + virtual std::string getEngineInfo() const; private: - BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL); - void setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode); + bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL); + void setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode); void cleanupCodeStream(); + // This method was public, but the only call to it is commented out in our + // own initDecode() method. I (nat 2016-08-04) don't know what it does or + // why. Even if it should be uncommented, it should probably still be + // private. +// void findDiscardLevelsBoundaries(LLImageJ2C &base); + + // Helper class to hold a kdu_codestream, which is a handle to the + // underlying implementation object. When CodeStreamHolder is reset() or + // destroyed, it calls kdu_codestream::destroy() -- which kdu_codestream + // itself does not. + // + // Call through it like a smart pointer using operator->(). + // + // Every RAII class must be noncopyable. For this we don't need move + // support. + class CodeStreamHolder: public boost::noncopyable + { + public: + ~CodeStreamHolder() + { + reset(); + } + + void reset() + { + if (mCodeStream.exists()) + { + mCodeStream.destroy(); + } + } + + // for those few times when you need a raw kdu_codestream* + kdu_core::kdu_codestream* get() { return &mCodeStream; } + kdu_core::kdu_codestream* operator->() { return &mCodeStream; } + + private: + kdu_core::kdu_codestream mCodeStream; + }; + // Encode variable - LLKDUMemSource *mInputp; - kdu_codestream *mCodeStreamp; - kdu_coords *mTPosp; // tile position - kdu_dims *mTileIndicesp; + boost::scoped_ptr<LLKDUMemSource> mInputp; + CodeStreamHolder mCodeStreamp; + boost::scoped_ptr<kdu_core::kdu_coords> mTPosp; // tile position + boost::scoped_ptr<kdu_core::kdu_dims> mTileIndicesp; int mBlocksSize; int mPrecinctsSize; int mLevels; // Temporary variables for in-progress decodes... + // We don't own this LLImageRaw. We're simply pointing to an instance + // passed into initDecode(). LLImageRaw *mRawImagep; - LLKDUDecodeState *mDecodeState; + boost::scoped_ptr<LLKDUDecodeState> mDecodeState; }; -#if LL_WINDOWS -# define LLSYMEXPORT __declspec(dllexport) -#elif LL_LINUX -# define LLSYMEXPORT __attribute__ ((visibility("default"))) -#else -# define LLSYMEXPORT -#endif - -extern "C" LLSYMEXPORT const char* engineInfoLLImageJ2CKDU(); -extern "C" LLSYMEXPORT LLImageJ2CKDU* createLLImageJ2CKDU(); -extern "C" LLSYMEXPORT void destroyLLImageJ2CKDU(LLImageJ2CKDU* kdu); - #endif diff --git a/indra/llkdu/llkdumem.cpp b/indra/llkdu/llkdumem.cpp index 0347475559d8844c2530c0ce63905c31ba9cf566..96e9da25d8a614163a8d5981d9adb4224176fa06 100644 --- a/indra/llkdu/llkdumem.cpp +++ b/indra/llkdu/llkdumem.cpp @@ -28,6 +28,9 @@ #include "llkdumem.h" #include "llerror.h" +using namespace kdu_core; +using kd_supp_image_local::image_line_buf; + #if defined(LL_WINDOWS) # pragma warning(disable: 4702) // unreachable code #endif diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h index fab913d93b7af6ab12d5ea3a333f8ce88f1e0474..09d81f38dec92cd87af57a7a28cec7078c526892 100644 --- a/indra/llkdu/llkdumem.h +++ b/indra/llkdu/llkdumem.h @@ -29,26 +29,22 @@ // Support classes for reading and writing from memory buffers in KDU #define KDU_NO_THREADS -// don't *really* want to rebuild KDU so turn off specific warnings for this header -#if LL_DARWIN -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wself-assign-field" -#pragma clang diagnostic ignored "-Wunused-private-field" -#include "kdu_image.h" -#pragma clang diagnostic pop -#else -#include "kdu_image.h" -#endif + +#define kdu_xxxx "kdu_image.h" +#include "include_kdu_xxxx.h" #include "kdu_elementary.h" #include "kdu_messaging.h" #include "kdu_params.h" -#include "kdu_compressed.h" + +#define kdu_xxxx "kdu_compressed.h" +#include "include_kdu_xxxx.h" + #include "kdu_sample_processing.h" #include "image_local.h" #include "stdtypes.h" -class LLKDUMemSource: public kdu_compressed_source +class LLKDUMemSource: public kdu_core::kdu_compressed_source { public: LLKDUMemSource(U8 *input_buffer, U32 size) @@ -62,7 +58,7 @@ class LLKDUMemSource: public kdu_compressed_source { } - int read(kdu_byte *buf, int num_bytes) + int read(kdu_core::kdu_byte *buf, int num_bytes) { U32 num_out; num_out = num_bytes; @@ -87,7 +83,7 @@ class LLKDUMemSource: public kdu_compressed_source U32 mCurPos; }; -class LLKDUMemTarget: public kdu_compressed_target +class LLKDUMemTarget: public kdu_core::kdu_compressed_target { public: LLKDUMemTarget(U8 *output_buffer, U32 &output_size, const U32 buffer_size) @@ -102,7 +98,7 @@ class LLKDUMemTarget: public kdu_compressed_target { } - bool write(const kdu_byte *buf, int num_bytes) + bool write(const kdu_core::kdu_byte *buf, int num_bytes) { U32 num_out; num_out = num_bytes; @@ -126,7 +122,7 @@ class LLKDUMemTarget: public kdu_compressed_target U32 *mOutputSize; }; -class LLKDUMemIn : public kdu_image_in_base +class LLKDUMemIn : public kdu_supp::kdu_image_in_base { public: LLKDUMemIn(const U8 *data, @@ -134,10 +130,10 @@ class LLKDUMemIn : public kdu_image_in_base const U16 rows, const U16 cols, U8 in_num_components, - siz_params *siz); + kdu_core::siz_params *siz); ~LLKDUMemIn(); - bool get(int comp_idx, kdu_line_buf &line, int x_tnum); + bool get(int comp_idx, kdu_core::kdu_line_buf &line, int x_tnum); private: const U8 *mData; @@ -146,8 +142,8 @@ class LLKDUMemIn : public kdu_image_in_base int rows, cols; int alignment_bytes; // Number of 0's at end of each line. int precision[3]; - image_line_buf *incomplete_lines; // Each "sample" represents a full pixel - image_line_buf *free_lines; + kd_supp_image_local::image_line_buf *incomplete_lines; // Each "sample" represents a full pixel + kd_supp_image_local::image_line_buf *free_lines; int num_unread_rows; U32 mCurPos; diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index 0605fad06884edcb89c3c3e789bc659dda8092ae..e386a9f71b4ac5bc53144f944a10ada914f839fb 100644 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -30,6 +30,7 @@ #include "llimagej2ckdu.h" #if LL_DARWIN +// For this source, it's true that private fields in llkdumem.h are unused. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-private-field" #include "llkdumem.h" @@ -37,7 +38,6 @@ #else #include "llkdumem.h" #endif - #include "kdu_block_coding.h" // Tut header #include "lltut.h" @@ -60,7 +60,7 @@ LLImageRaw::~LLImageRaw() { } U8* LLImageRaw::allocateData(S32 ) { return NULL; } void LLImageRaw::deleteData() { } U8* LLImageRaw::reallocateData(S32 ) { return NULL; } -BOOL LLImageRaw::resize(U16, U16, S8) { return TRUE; } // this method always returns TRUE... +bool LLImageRaw::resize(U16, U16, S8) { return true; } // this method always returns true... LLImageBase::LLImageBase() : LLTrace::MemTrackable<LLImageBase>("LLImageBase"), @@ -89,8 +89,8 @@ LLImageFormatted::~LLImageFormatted() { } U8* LLImageFormatted::allocateData(S32 ) { return NULL; } S32 LLImageFormatted::calcDataSize(S32 ) { return 0; } S32 LLImageFormatted::calcDiscardLevelBytes(S32 ) { return 0; } -BOOL LLImageFormatted::decodeChannels(LLImageRaw*, F32, S32, S32) { return FALSE; } -BOOL LLImageFormatted::copyData(U8 *, S32) { return TRUE; } // this method always returns TRUE... +bool LLImageFormatted::decodeChannels(LLImageRaw*, F32, S32, S32) { return false; } +bool LLImageFormatted::copyData(U8 *, S32) { return true; } // this method always returns true... void LLImageFormatted::deleteData() { } void LLImageFormatted::dump() { } U8* LLImageFormatted::reallocateData(S32 ) { return NULL; } @@ -103,27 +103,29 @@ LLImageJ2C::~LLImageJ2C() { } S32 LLImageJ2C::calcDataSize(S32 ) { return 0; } S32 LLImageJ2C::calcDiscardLevelBytes(S32 ) { return 0; } S32 LLImageJ2C::calcHeaderSize() { return 0; } -BOOL LLImageJ2C::decode(LLImageRaw*, F32) { return FALSE; } -BOOL LLImageJ2C::decodeChannels(LLImageRaw*, F32, S32, S32 ) { return FALSE; } +bool LLImageJ2C::decode(LLImageRaw*, F32) { return false; } +bool LLImageJ2C::decodeChannels(LLImageRaw*, F32, S32, S32 ) { return false; } void LLImageJ2C::decodeFailed() { } -BOOL LLImageJ2C::encode(const LLImageRaw*, F32) { return FALSE; } +bool LLImageJ2C::encode(const LLImageRaw*, F32) { return false; } S8 LLImageJ2C::getRawDiscardLevel() { return 0; } void LLImageJ2C::resetLastError() { } void LLImageJ2C::setLastError(const std::string&, const std::string&) { } -BOOL LLImageJ2C::updateData() { return FALSE; } +bool LLImageJ2C::updateData() { return false; } void LLImageJ2C::updateRawDiscardLevel() { } -LLKDUMemIn::LLKDUMemIn(const U8*, const U32, const U16, const U16, const U8, siz_params*) { } +LLKDUMemIn::LLKDUMemIn(const U8*, const U32, const U16, const U16, const U8, kdu_core::siz_params*) { } LLKDUMemIn::~LLKDUMemIn() { } -bool LLKDUMemIn::get(int, kdu_line_buf&, int) { return false; } +bool LLKDUMemIn::get(int, kdu_core::kdu_line_buf&, int) { return false; } // Stub Kakadu Library calls +// they're all namespaced now +namespace kdu_core { kdu_tile_comp kdu_tile::access_component(int ) { kdu_tile_comp a; return a; } kdu_block_encoder::kdu_block_encoder() { } kdu_block_decoder::kdu_block_decoder() { } void kdu_block::set_max_passes(int , bool ) { } void kdu_block::set_max_bytes(int , bool ) { } -void kdu_tile::close(kdu_thread_env* ) { } +void kdu_tile::close(kdu_thread_env *, bool) {} int kdu_tile::get_num_components() { return 0; } bool kdu_tile::get_ycc() { return false; } void kdu_tile::set_components_of_interest(int , const int* ) { } @@ -156,14 +158,14 @@ void kdu_codestream::set_fussy() { } void kdu_codestream::get_dims(int, kdu_dims&, bool ) { } int kdu_codestream::get_min_dwt_levels() { return 5; } int kdu_codestream::get_max_tile_layers() { return 1; } -void kdu_codestream::change_appearance(bool, bool, bool) { } +void kdu_codestream::change_appearance(bool, bool, bool, kdu_thread_env *) {} void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { } void kdu_codestream::destroy() { } void kdu_codestream::collect_timing_stats(int ) { } void kdu_codestream::set_max_bytes(kdu_long, bool, bool ) { } void kdu_codestream::get_valid_tiles(kdu_dims& ) { } void kdu_codestream::create(kdu_compressed_source*, kdu_thread_env*) { } -void kdu_codestream::apply_input_restrictions( int, int, int, int, kdu_dims*, kdu_component_access_mode ) { } +void kdu_codestream::apply_input_restrictions(int, int, int, int, kdu_dims const *, kdu_component_access_mode, kdu_thread_env *, kdu_quality_limiter const *) {} void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { } void kdu_codestream::flush(kdu_long *, int, kdu_uint16 *, bool, bool, double, kdu_thread_env*, int) { } void kdu_codestream::set_resilient(bool ) { } @@ -178,13 +180,15 @@ siz_params* kdu_codestream::access_siz() { return NULL; } kdu_tile kdu_codestream::open_tile(kdu_coords , kdu_thread_env* ) { kdu_tile a; return a; } kdu_codestream_comment kdu_codestream::add_comment() { kdu_codestream_comment a; return a; } void kdu_subband::close_block(kdu_block*, kdu_thread_env*) { } -void kdu_subband::get_valid_blocks(kdu_dims &indices) { } -kdu_block* kdu_subband::open_block(kdu_coords, int*, kdu_thread_env*) { return NULL; } +void kdu_subband::get_valid_blocks(kdu_dims &indices) const { } +kdu_block * kdu_subband::open_block(kdu_coords, int *, kdu_thread_env *, int, bool) { return NULL; } bool kdu_codestream_comment::put_text(const char*) { return false; } void kdu_customize_warnings(kdu_message*) { } void kdu_customize_errors(kdu_message*) { } -kdu_long kdu_multi_analysis::create(kdu_codestream, kdu_tile, kdu_thread_env*, kdu_thread_queue*, int, kdu_roi_image*, int) { kdu_long a = 0; return a; } +kdu_long kdu_multi_analysis::create(kdu_codestream, kdu_tile, kdu_thread_env *,kdu_thread_queue *, int, kdu_roi_image *, int, kdu_sample_allocator *, kdu_push_pull_params const *) { return kdu_long(0); } +void kdu_multi_analysis::destroy(kdu_thread_env *) {} siz_params::siz_params() : kdu_params(NULL, false, false, false, false, false) { } +siz_params::~siz_params() {} void siz_params::finalize(bool ) { } void siz_params::copy_with_xforms(kdu_params*, int, int, bool, bool, bool) { } int siz_params::write_marker_segment(kdu_output*, kdu_params*, int) { return 0; } @@ -193,10 +197,15 @@ bool siz_params::read_marker_segment(kdu_uint16, int, kdu_byte a[], int) { retur kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*, int) { } void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long, kdu_thread_env* ) { } +kdu_sample_allocator::~kdu_sample_allocator() {} +void kdu_sample_allocator::do_finalize(kdu_codestream) {} void (*kdu_convert_ycc_to_rgb_rev16)(kdu_int16*,kdu_int16*,kdu_int16*,int); void (*kdu_convert_ycc_to_rgb_irrev16)(kdu_int16*,kdu_int16*,kdu_int16*,int); void (*kdu_convert_ycc_to_rgb_rev32)(kdu_int32*,kdu_int32*,kdu_int32*,int); void (*kdu_convert_ycc_to_rgb_irrev32)(float*,float*,float*,int); +bool kdu_core_sample_alignment_checker(int, int, int, int, bool, bool) { return false; } +void kdu_pull_ifc::destroy() {} +} // namespace kdu_core // ------------------------------------------------------------------------------------------- // TUT @@ -212,12 +221,12 @@ namespace tut { public: // Provides public access to some protected methods for testing - BOOL callGetMetadata(LLImageJ2C &base) { return getMetadata(base); } - BOOL callDecodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) + bool callGetMetadata(LLImageJ2C &base) { return getMetadata(base); } + bool callDecodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) { return decodeImpl(base, raw_image, decode_time, first_channel, max_channel_count); } - BOOL callEncodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text) + bool callEncodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text) { return encodeImpl(base, raw_image, comment_text); } @@ -254,10 +263,10 @@ namespace tut void llimagej2ckdu_object_t::test<1>() { LLImageJ2C* image = new LLImageJ2C(); - BOOL res = mImage->callGetMetadata(*image); - // Trying to set up a data stream with all NIL values and stubbed KDU will "work" and return TRUE - // Note that is linking with KDU, that call will throw an exception and fail, returning FALSE - ensure("getMetadata() test failed", res == TRUE); + bool res = mImage->callGetMetadata(*image); + // Trying to set up a data stream with all NIL values and stubbed KDU will "work" and return true + // Note that is linking with KDU, that call will throw an exception and fail, returning false + ensure("getMetadata() test failed", res); } // Test 2 : test decodeImpl() @@ -266,9 +275,9 @@ namespace tut { LLImageJ2C* image = new LLImageJ2C(); LLImageRaw* raw = new LLImageRaw(); - BOOL res = mImage->callDecodeImpl(*image, *raw, 0.0, 0, 0); - // Decoding returns TRUE whenever there's nothing else to do, including if decoding failed, so we'll get TRUE here - ensure("decodeImpl() test failed", res == TRUE); + bool res = mImage->callDecodeImpl(*image, *raw, 0.0, 0, 0); + // Decoding returns true whenever there's nothing else to do, including if decoding failed, so we'll get true here + ensure("decodeImpl() test failed", res); } // Test 3 : test encodeImpl() @@ -277,8 +286,8 @@ namespace tut { LLImageJ2C* image = new LLImageJ2C(); LLImageRaw* raw = new LLImageRaw(); - BOOL res = mImage->callEncodeImpl(*image, *raw, NULL); - // Encoding returns TRUE unless an exception was raised, so we'll get TRUE here though nothing really was done - ensure("encodeImpl() test failed", res == TRUE); + bool res = mImage->callEncodeImpl(*image, *raw, NULL); + // Encoding returns true unless an exception was raised, so we'll get true here though nothing really was done + ensure("encodeImpl() test failed", res); } } diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 0614fd92ef60f1bfaf8f1de1a52aca92ae888ae2..4c8bcdac917eb856022ac9626e33dc0cb74ce0bc 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -4,6 +4,7 @@ project(llmath) include(00-Common) include(LLCommon) +include(Boost) include_directories( ${LLCOMMON_INCLUDE_DIRS} @@ -20,6 +21,7 @@ set(llmath_SOURCE_FILES llline.cpp llmatrix3a.cpp llmodularmath.cpp + lloctree.cpp llperlin.cpp llquaternion.cpp llrect.cpp @@ -117,6 +119,11 @@ if (LL_TESTS) v4color.cpp v4coloru.cpp ) + set_source_files_properties( + ${llmath_TEST_SOURCE_FILES} + PROPERTIES + LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_THREAD_LIBRARY}" + ) LL_ADD_PROJECT_UNIT_TESTS(llmath "${llmath_TEST_SOURCE_FILES}") # INTEGRATION TESTS diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index 93b9f22b25fa9cfc722697d8d96800b4314e7adf..e508c9a19976cabea54d7055a8753dffaa6ef20a 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -153,7 +153,7 @@ inline F64 llabs(const F64 a) inline S32 lltrunc( F32 f ) { -#if LL_WINDOWS && !defined( __INTEL_COMPILER ) +#if LL_WINDOWS && !defined( __INTEL_COMPILER ) && (ADDRESS_SIZE == 32) // Avoids changing the floating point control word. // Add or subtract 0.5 - epsilon and then round const static U32 zpfp[] = { 0xBEFFFFFF, 0x3EFFFFFF }; @@ -179,7 +179,7 @@ inline S32 lltrunc( F64 f ) inline S32 llfloor( F32 f ) { -#if LL_WINDOWS && !defined( __INTEL_COMPILER ) +#if LL_WINDOWS && !defined( __INTEL_COMPILER ) && (ADDRESS_SIZE == 32) // Avoids changing the floating point control word. // Accurate (unlike Stereopsis version) for all values between S32_MIN and S32_MAX and slightly faster than Stereopsis version. // Add -(0.5 - epsilon) and then round @@ -254,6 +254,11 @@ inline int round_int(double x) } #endif // BOGUS_ROUND +inline F64 ll_round(const F64 val) +{ + return F64(floor(val + 0.5f)); +} + inline F32 ll_round( F32 val, F32 nearest ) { return F32(floor(val * (1.0f / nearest) + 0.5f)) * nearest; diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index d141298f69b65260bdfba1de551083b9afd3b062..216334752a170c5364c1f675ba7e63ab9b9fb956 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -121,7 +121,7 @@ class LLMatrix4a res.add(z); } - inline void affineTransform(const LLVector4a& v, LLVector4a& res) + inline void affineTransformSSE(const LLVector4a& v, LLVector4a& res) { LLVector4a x,y,z; @@ -137,6 +137,43 @@ class LLMatrix4a z.add(mMatrix[3]); res.setAdd(x,z); } + + inline void affineTransformNonSSE(const LLVector4a& v, LLVector4a& res) + { + F32 x = v[0] * mMatrix[0][0] + v[1] * mMatrix[1][0] + v[2] * mMatrix[2][0] + mMatrix[3][0]; + F32 y = v[0] * mMatrix[0][1] + v[1] * mMatrix[1][1] + v[2] * mMatrix[2][1] + mMatrix[3][1]; + F32 z = v[0] * mMatrix[0][2] + v[1] * mMatrix[1][2] + v[2] * mMatrix[2][2] + mMatrix[3][2]; + F32 w = 1.0f; + res.set(x,y,z,w); + } + + inline void affineTransform(const LLVector4a& v, LLVector4a& res) + { + affineTransformSSE(v,res); + } }; +inline LLVector4a rowMul(const LLVector4a &row, const LLMatrix4a &mat) +{ + LLVector4a result; + result = _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(0, 0, 0, 0)), mat.mMatrix[0]); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(1, 1, 1, 1)), mat.mMatrix[1])); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(2, 2, 2, 2)), mat.mMatrix[2])); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(3, 3, 3, 3)), mat.mMatrix[3])); + return result; +} + +inline void matMul(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res) +{ + LLVector4a row0 = rowMul(a.mMatrix[0], b); + LLVector4a row1 = rowMul(a.mMatrix[1], b); + LLVector4a row2 = rowMul(a.mMatrix[2], b); + LLVector4a row3 = rowMul(a.mMatrix[3], b); + + res.mMatrix[0] = row0; + res.mMatrix[1] = row1; + res.mMatrix[2] = row2; + res.mMatrix[3] = row3; +} + #endif diff --git a/indra/llmath/lloctree.cpp b/indra/llmath/lloctree.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3fcb3a27d79f3be983068ae0291ca9504317c6ba --- /dev/null +++ b/indra/llmath/lloctree.cpp @@ -0,0 +1,29 @@ +/** + * @file lloctree.cpp + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#include "stdtypes.h" + +U32 gOctreeMaxCapacity; +F32 gOctreeMinSize; + diff --git a/indra/llmath/llsimdmath.h b/indra/llmath/llsimdmath.h index cebd2ace7d8cee33699da11846de43f1930bc21a..54a275633f5cd5248d1fd8af5fce55c145a04044 100644 --- a/indra/llmath/llsimdmath.h +++ b/indra/llmath/llsimdmath.h @@ -31,7 +31,7 @@ #error "Please include llmath.h before this file." #endif -#if ( ( LL_DARWIN || LL_LINUX ) && !(__SSE2__) ) || ( LL_WINDOWS && ( _M_IX86_FP < 2 ) ) +#if ( ( LL_DARWIN || LL_LINUX ) && !(__SSE2__) ) || ( LL_WINDOWS && ( _M_IX86_FP < 2 && ADDRESS_SIZE == 32 ) ) #error SSE2 not enabled. LLVector4a and related class will not compile. #endif diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d932eb53a0509dbf2050adc2ad980cd94a8e0b93..f63a721c35c9e5d7819ca96eaa60e71e96feae16 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -89,7 +89,7 @@ const F32 SKEW_MAX = 0.95f; const F32 SCULPT_MIN_AREA = 0.002f; const S32 SCULPT_MIN_AREA_DETAIL = 1; -extern BOOL gDebugGL; +BOOL gDebugGL = FALSE; BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) { @@ -2143,19 +2143,22 @@ BOOL LLVolume::generate() F32 profile_detail = mDetail; F32 path_detail = mDetail; - - 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); + + 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); @@ -2544,7 +2547,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) U16 influence = weights[idx++]; influence |= ((U16) weights[idx++] << 8); - F32 w = llclamp((F32) influence / 65535.f, 0.f, 0.99999f); + F32 w = llclamp((F32) influence / 65535.f, 0.001f, 0.999f); wght.mV[cur_influence] = w; joints[cur_influence] = joint; cur_influence++; @@ -2561,11 +2564,15 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW]; if (wsum <= 0.f) { - wght = LLVector4(0.99999f,0.f,0.f,0.f); + wght = LLVector4(0.999f,0.f,0.f,0.f); } for (U32 k=0; k<4; k++) { - joints_with_weights[k] = (F32) joints[k] + wght[k]; + F32 f_combined = (F32) joints[k] + wght[k]; + joints_with_weights[k] = f_combined; + // Any weights we added above should wind up non-zero and applied to a specific bone. + // 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); @@ -4568,6 +4575,7 @@ LLVolumeFace::LLVolumeFace() : mTexCoords(NULL), mIndices(NULL), mWeights(NULL), + mWeightsScrubbed(FALSE), mOctree(NULL), mOptimized(FALSE) { @@ -4593,6 +4601,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mTexCoords(NULL), mIndices(NULL), mWeights(NULL), + mWeightsScrubbed(FALSE), mOctree(NULL) { mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); @@ -4664,6 +4673,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) ll_aligned_free_16(mWeights); mWeights = NULL; } + mWeightsScrubbed = src.mWeightsScrubbed; } if (mNumIndices) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 1da2d0c6b15f9ea47bed4f9c8b64b693625ddb3d..bf81c978a039282dcea328d64e3604f55b1bde21 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -199,6 +199,8 @@ const U8 LL_SCULPT_FLAG_MASK = LL_SCULPT_FLAG_INVERT | LL_SCULPT_FLAG_MIRROR; const S32 LL_SCULPT_MESH_MAX_FACES = 8; +extern BOOL gDebugGL; + class LLProfileParams { public: @@ -953,6 +955,8 @@ class LLVolumeFace // mWeights.size() should be empty or match mVertices.size() LLVector4a* mWeights; + mutable BOOL mWeightsScrubbed; + LLOctreeNode<LLVolumeTriangle>* mOctree; //whether or not face has been cache optimized diff --git a/indra/llmath/tests/v4math_test.cpp b/indra/llmath/tests/v4math_test.cpp index 191ac864dfcf315123a7c7619d4e442478db25aa..9779dfded383f57e3272f10b0844d55127b037d9 100644 --- a/indra/llmath/tests/v4math_test.cpp +++ b/indra/llmath/tests/v4math_test.cpp @@ -355,7 +355,8 @@ namespace tut val3 = z1 + (z2 - z1)* val; val4 = w1 + (w2 - w1)* val; LLVector4 vec4b = lerp(vec4,vec4a,val); - ensure("lerp failed", ((val1 ==vec4b.mV[VX])&& (val2 ==vec4b.mV[VY]) && (val3 ==vec4b.mV[VZ])&& (val4 ==vec4b.mV[VW]))); + LLVector4 check(val1, val2, val3, val4); + ensure_equals("lerp failed", check, vec4b); } template<> template<> diff --git a/indra/llmath/v4coloru.h b/indra/llmath/v4coloru.h index fddad349789139a076f86a1e72285245359151d0..704ce852d92717478fbff45fe5bc880779eb5607 100644 --- a/indra/llmath/v4coloru.h +++ b/indra/llmath/v4coloru.h @@ -47,14 +47,7 @@ class LLColor4U { public: - union - { - U8 mV[LENGTHOFCOLOR4U]; - U32 mAll; - LLColor4* mSources; - LLColor4U* mSourcesU; - }; - + U8 mV[LENGTHOFCOLOR4U]; LLColor4U(); // Initializes LLColor4U to (0, 0, 0, 1) LLColor4U(U8 r, U8 g, U8 b); // Initializes LLColor4U to (r, g, b, 1) @@ -132,6 +125,9 @@ class LLColor4U return LLColor4(*this); } + U32 asRGBA() const; + void fromRGBA( U32 aVal ); + static LLColor4U white; static LLColor4U black; static LLColor4U red; @@ -565,6 +561,26 @@ void LLColor4U::setVecScaleClamp(const LLColor3& color) mV[3] = 255; } +inline U32 LLColor4U::asRGBA() const +{ + // Little endian: values are swapped in memory. The original code access the array like a U32, so we need to swap here + + return (mV[3] << 24) | (mV[2] << 16) | (mV[1] << 8) | mV[0]; +} + +inline void LLColor4U::fromRGBA( U32 aVal ) +{ + // Little endian: values are swapped in memory. The original code access the array like a U32, so we need to swap here + + mV[ 0 ] = aVal & 0xFF; + aVal >>= 8; + mV[ 1 ] = aVal & 0xFF; + aVal >>= 8; + mV[ 2 ] = aVal & 0xFF; + aVal >>= 8; + mV[ 3 ] = aVal & 0xFF; +} + #endif diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index 4be677a4b0735a38e529a896abce9d0f86137cb6..0f237540969fc8a620717168b76985aaa62a0b10 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -181,6 +181,10 @@ class LLEstateAssetRequest : public LLBaseDownloadRequest // Map of known bad assets typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t; +// *TODO: these typedefs are passed into the VFS via a legacy C function pointer +// future project would be to convert these to C++ callables (std::function<>) so that +// we can use bind and remove the userData parameter. +// typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status); diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 1ca5f58ae2742f568163091757ecd046d49fba0f..004db546b701191145d178c48e46c4b462786737 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -43,6 +43,8 @@ #include "llcoros.h" #include "lleventcoro.h" #include "llcorehttputil.h" +#include "llexception.h" +#include "stringize.h" #include <map> #include <set> @@ -231,13 +233,12 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU LLAvatarNameCache::handleAvNameCacheSuccess(results, httpResults); } - catch (std::exception e) - { - LL_WARNS() << "Caught exception '" << e.what() << "'" << LL_ENDL; - } catch (...) { - LL_WARNS() << "Caught unknown exception." << LL_ENDL; + LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::instance().getName() + << "('" << url << "', " << agentIds.size() + << " Agent Ids)")); + throw; } } diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index d4c0788b7d5ef272abb0e6c1e4c51e9988d6c7dd..74cdff2b0087d6480d6ead893d3328adae176286 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -27,6 +27,8 @@ #include "linden_common.h" #include "llcoproceduremanager.h" +#include "llexception.h" +#include "stringize.h" #include <boost/assign.hpp> //========================================================================= @@ -388,14 +390,14 @@ void LLCoprocedurePool::coprocedureInvokerCoro(LLCoreHttpUtil::HttpCoroutineAdap { coproc->mProc(httpAdapter, coproc->mId); } - catch (std::exception &e) - { - LL_WARNS() << "Coprocedure(" << coproc->mName << ") id=" << coproc->mId.asString() << - " threw an exception! Message=\"" << e.what() << "\"" << LL_ENDL; - } catch (...) { - LL_WARNS() << "A non std::exception was thrown from " << coproc->mName << " with id=" << coproc->mId << "." << " in pool \"" << mPoolName << "\"" << LL_ENDL; + LOG_UNHANDLED_EXCEPTION(STRINGIZE("Coprocedure('" << coproc->mName + << "', id=" << coproc->mId.asString() + << ") in pool '" << mPoolName << "'")); + // must NOT omit this or we deplete the pool + mActiveCoprocs.erase(itActive); + throw; } LL_INFOS() << "Finished coprocedure(" << coproc->mName << ")" << " in pool \"" << mPoolName << "\"" << LL_ENDL; diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 497367b80cdc5713415a1cbd5f27320fcde950a8..7d0e83180ce1593dc3451b96be834f319e300c2e 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -37,7 +37,8 @@ class LLCoprocedurePool; class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager > { - friend class LLSingleton < LLCoprocedureManager > ; + LLSINGLETON(LLCoprocedureManager); + virtual ~LLCoprocedureManager(); public: typedef boost::function<U32(const std::string &)> SettingQuery_t; @@ -45,9 +46,6 @@ class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager > typedef boost::function<void(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, const LLUUID &id)> CoProcedure_t; - LLCoprocedureManager(); - virtual ~LLCoprocedureManager(); - /// Places the coprocedure on the queue for processing. /// /// @param name Is used for debugging and should identify this coroutine. diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 7742cbc18235c5fb0ae42f028871f63e3b9373cd..9bf38fb336e7af383e07b8b65cc520c5e6e616b5 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -642,7 +642,7 @@ HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request) mHttpRequest(request) { mBoundListener = LLEventPumps::instance().obtain("mainloop"). - listen(LLEventPump::inventName(), boost::bind(&HttpRequestPumper::pollRequest, this, _1)); + listen(LLEventPump::ANONYMOUS, boost::bind(&HttpRequestPumper::pollRequest, this, _1)); } HttpRequestPumper::~HttpRequestPumper() diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h index 1002b33f801865acf6c7665cc65da017ecee7f78..8ee7080d3822ae52b9c288877c845540fccb9fd3 100644 --- a/indra/llmessage/llexperiencecache.h +++ b/indra/llmessage/llexperiencecache.h @@ -43,7 +43,7 @@ class LLUUID; class LLExperienceCache: public LLSingleton < LLExperienceCache > { - friend class LLSingleton < LLExperienceCache > ; + LLSINGLETON(LLExperienceCache); public: typedef boost::function<std::string(const std::string &)> CapabilityQuery_t; @@ -103,7 +103,6 @@ class LLExperienceCache: public LLSingleton < LLExperienceCache > static const int PROPERTY_SUSPENDED; // 1 << 7 private: - LLExperienceCache(); virtual ~LLExperienceCache(); virtual void initSingleton(); diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp index f235965879cf60118130839b7ef68885e95ca6bb..04b34a296c13c4961498a4f58f6dccdf014689f2 100644 --- a/indra/llmessage/llhttpnode.cpp +++ b/indra/llmessage/llhttpnode.cpp @@ -31,6 +31,7 @@ #include "llstl.h" #include "llhttpconstants.h" +#include "llexception.h" const std::string CONTEXT_HEADERS("headers"); const std::string CONTEXT_PATH("path"); @@ -92,27 +93,28 @@ LLHTTPNode::~LLHTTPNode() namespace { - class NotImplemented + struct NotImplemented: public LLException { + NotImplemented(): LLException("LLHTTPNode::NotImplemented") {} }; } // virtual LLSD LLHTTPNode::simpleGet() const { - throw NotImplemented(); + LLTHROW(NotImplemented()); } // virtual LLSD LLHTTPNode::simplePut(const LLSD& input) const { - throw NotImplemented(); + LLTHROW(NotImplemented()); } // virtual LLSD LLHTTPNode::simplePost(const LLSD& input) const { - throw NotImplemented(); + LLTHROW(NotImplemented()); } @@ -172,7 +174,7 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons // virtual LLSD LLHTTPNode::simpleDel(const LLSD&) const { - throw NotImplemented(); + LLTHROW(NotImplemented()); } // virtual diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index bd23dd39defcb644ba2d904fd9c9748cf3d8c7ca..688dff7c8320916b9f2027f91f16d0cd6408867f 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -218,14 +218,14 @@ enum LLSocks5AuthType */ class LLProxy: public LLSingleton<LLProxy> { - LOG_CLASS(LLProxy); -public: /*########################################################################################### METHODS THAT DO NOT LOCK mProxyMutex! ###########################################################################################*/ // Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only. - LLProxy(); + LLSINGLETON(LLProxy); + LOG_CLASS(LLProxy); +public: // Static check for enabled status for UDP packets. Call from main thread only. static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } @@ -239,9 +239,11 @@ class LLProxy: public LLSingleton<LLProxy> /*########################################################################################### METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED! ###########################################################################################*/ +private: // Destructor, closes open connections. Do not call directly, use cleanupClass(). ~LLProxy(); +public: // Delete LLProxy singleton. Allows the apr_socket used in the SOCKS 5 control channel to be // destroyed before the call to apr_terminate. Call from main thread only. static void cleanupClass(); diff --git a/indra/llmessage/llxfer.cpp b/indra/llmessage/llxfer.cpp index 4aba5cae72eb9eb197066550f154a96ac2a79501..e0590dfdff094b4dac451b7629ecc0b8ecdac285 100644 --- a/indra/llmessage/llxfer.cpp +++ b/indra/llmessage/llxfer.cpp @@ -294,7 +294,7 @@ S32 LLXfer::processEOF() } else { - LL_INFOS() << "xfer from " << mRemoteHost << " failed, code " + LL_INFOS() << "xfer from " << mRemoteHost << " failed or aborted, code " << mCallbackResult << ": " << getFileName() << LL_ENDL; } diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp index 257a13f277062fec84bbe70fbb98f6d80b09ffd7..8e2ed890e72f47d64c66822e1a89657fdd47dfea 100644 --- a/indra/llmessage/llxfer_file.cpp +++ b/indra/llmessage/llxfer_file.cpp @@ -98,12 +98,12 @@ void LLXfer_File::cleanup () mFp = NULL; } - LLFile::remove(mTempFilename); + LLFile::remove(mTempFilename, ENOENT); if (mDeleteLocalOnCompletion) { LL_DEBUGS() << "Removing file: " << mLocalFilename << LL_ENDL; - LLFile::remove(mLocalFilename); + LLFile::remove(mLocalFilename, ENOENT); } else { @@ -321,7 +321,7 @@ S32 LLXfer_File::processEOF() mCallbackResult = flushval; } - LLFile::remove(mLocalFilename); + LLFile::remove(mLocalFilename, ENOENT); if (!mCallbackResult) { diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 0ab67b8dda13743744dc438f8e2116d465ddaca8..2ceb64ce8f98a3d172a6271e7da1778a9bf3a6d4 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -401,7 +401,7 @@ U64 LLXferManager::registerXfer(const void *datap, const S32 length) /////////////////////////////////////////////////////////// -void LLXferManager::requestFile(const std::string& local_filename, +U64 LLXferManager::requestFile(const std::string& local_filename, const std::string& remote_filename, ELLPath remote_path, const LLHost& remote_host, @@ -424,10 +424,12 @@ void LLXferManager::requestFile(const std::string& local_filename, { // cout << "requested a xfer already in progress" << endl; - return; + return xferp->mID; } } + U64 xfer_id = 0; + S32 chunk_size = use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1; xferp = (LLXfer *) new LLXfer_File(chunk_size); if (xferp) @@ -438,13 +440,15 @@ void LLXferManager::requestFile(const std::string& local_filename, // around. // Note: according to AaronB, this is here to deal with locks on files that were // in transit during a crash, - if(delete_remote_on_completion && - (remote_filename.substr(remote_filename.length()-4) == ".tmp")) + if( delete_remote_on_completion + && (remote_filename.substr(remote_filename.length()-4) == ".tmp") + && gDirUtilp->fileExists(local_filename)) { - LLFile::remove(local_filename); + LLFile::remove(local_filename, ENOENT); } + xfer_id = getNextID(); ((LLXfer_File *)xferp)->initializeRequest( - getNextID(), + xfer_id, local_filename, remote_filename, remote_path, @@ -457,6 +461,7 @@ void LLXferManager::requestFile(const std::string& local_filename, { LL_ERRS() << "Xfer allocation error" << LL_ENDL; } + return xfer_id; } void LLXferManager::requestFile(const std::string& remote_filename, @@ -616,7 +621,7 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user if (!xferp) { char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ - LL_WARNS() << "received xfer data from " << mesgsys->getSender() + LL_INFOS() << "received xfer data from " << mesgsys->getSender() << " for non-existent xfer id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << LL_ENDL; return; @@ -1103,6 +1108,29 @@ void LLXferManager::retransmitUnackedPackets () } } +/////////////////////////////////////////////////////////// + +void LLXferManager::abortRequestById(U64 xfer_id, S32 result_code) +{ + LLXfer * xferp = findXfer(xfer_id, mReceiveList); + if (xferp) + { + if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) + { + // causes processAbort(); + xferp->abort(result_code); + } + else + { + xferp->mCallbackResult = result_code; + xferp->processEOF(); //should notify requester + removeXfer(xferp, &mReceiveList); + } + // Since already removed or marked as aborted no need + // to wait for processAbort() to start new download + startPendingDownloads(); + } +} /////////////////////////////////////////////////////////// diff --git a/indra/llmessage/llxfermanager.h b/indra/llmessage/llxfermanager.h index b3d110e7a145bf897fa67725765c7fda0ff6c723..d258f0a5ce2d82ffa2c56801bfa8dbbf416094a7 100644 --- a/indra/llmessage/llxfermanager.h +++ b/indra/llmessage/llxfermanager.h @@ -140,7 +140,7 @@ class LLXferManager // file requesting routines // .. to file - virtual void requestFile(const std::string& local_filename, + virtual U64 requestFile(const std::string& local_filename, const std::string& remote_filename, ELLPath remote_path, const LLHost& remote_host, @@ -202,6 +202,7 @@ class LLXferManager virtual void retransmitUnackedPackets (); // error handling + void abortRequestById(U64 xfer_id, S32 result_code); virtual void processAbort (LLMessageSystem *mesgsys, void **user_data); }; diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index cecb2021e7e9888d979b90965a56042befef1ab4..6ef4025ab1823bfa55f8f42a8cd44cb498a97107 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -76,6 +76,7 @@ #include "v4math.h" #include "lltransfertargetvfile.h" #include "llcorehttputil.h" +#include "llpounceable.h" // Constants //const char* MESSAGE_LOG_FILENAME = "message.log"; @@ -1724,7 +1725,9 @@ std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg) return s; } -LLMessageSystem *gMessageSystem = NULL; +// LLPounceable supports callWhenReady(), to permit clients to queue up (e.g.) +// callback registrations for when gMessageSystem is first assigned +LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; // update appropriate ping info void process_complete_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/) @@ -2641,7 +2644,7 @@ void end_messaging_system(bool print_summary) LL_INFOS("Messaging") << str.str().c_str() << LL_ENDL; } - delete gMessageSystem; + delete static_cast<LLMessageSystem*>(gMessageSystem); gMessageSystem = NULL; } } @@ -4007,7 +4010,7 @@ void LLMessageSystem::sendUntrustedSimulatorMessageCoro(std::string url, std::st { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy)); + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("untrustedSimulatorMessage", httpPolicy)); LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions); diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 133db620e68541e6deec77506027384bdc328186..f6c5d9e228d8087ddbb0f985aa18f895d91b2973 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -60,6 +60,7 @@ #include "llstoredmessage.h" #include "boost/function.hpp" +#include "llpounceable.h" const U32 MESSAGE_MAX_STRINGS_LENGTH = 64; const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192; @@ -68,10 +69,10 @@ const S32 MESSAGE_MAX_PER_FRAME = 400; class LLMessageStringTable : public LLSingleton<LLMessageStringTable> { -public: - LLMessageStringTable(); + LLSINGLETON(LLMessageStringTable); ~LLMessageStringTable(); +public: char *getString(const char *str); U32 mUsed; @@ -832,7 +833,7 @@ class LLMessageSystem : public LLMessageSenderInterface // external hook into messaging system -extern LLMessageSystem *gMessageSystem; +extern LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; // Must specific overall system version, which is used to determine // if a patch is available in the message template checksum verification. diff --git a/indra/llmessage/tests/commtest.h b/indra/llmessage/tests/commtest.h index 0d149b5258deae37fe033a325f6b161f3112319f..7c8f27bbd2f1ae266190a413fec9af3e7657c5d2 100644 --- a/indra/llmessage/tests/commtest.h +++ b/indra/llmessage/tests/commtest.h @@ -33,15 +33,15 @@ #include "llevents.h" #include "llsd.h" #include "llhost.h" +#include "llexception.h" #include "stringize.h" #include <map> #include <string> -#include <stdexcept> #include <boost/lexical_cast.hpp> -struct CommtestError: public std::runtime_error +struct CommtestError: public LLException { - CommtestError(const std::string& what): std::runtime_error(what) {} + CommtestError(const std::string& what): LLException(what) {} }; static bool query_verbose() @@ -68,7 +68,7 @@ static int query_port(const std::string& var) const char* cport = getenv(var.c_str()); if (! cport) { - throw CommtestError(STRINGIZE("missing environment variable" << var)); + LLTHROW(CommtestError(STRINGIZE("missing environment variable" << var))); } // This will throw, too, if the value of PORT isn't numeric. int port(boost::lexical_cast<int>(cport)); diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp index a32bfa59ce8d046bf443c85d1e49cbd519e3a0d3..9356a14f1f89fd24a5ee6bc0047bf763c4744002 100644 --- a/indra/llmessage/tests/llhttpclient_test.cpp +++ b/indra/llmessage/tests/llhttpclient_test.cpp @@ -42,6 +42,7 @@ #include "lliosocket.h" #include "stringize.h" +#include "llcleanup.h" namespace tut { @@ -66,7 +67,7 @@ namespace tut ~HTTPClientTestData() { delete mClientPump; - LLProxy::cleanupClass(); + SUBSYSTEM_CLEANUP(LLProxy); apr_pool_destroy(mPool); } diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp index 3b04530c1ac9e5bd98e596a4e9360c144a9f6d09..e20f61b73f8fddadfff14eaf397907ec8bc162e0 100644 --- a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp +++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp @@ -31,11 +31,12 @@ #include "llhost.h" #include "message.h" #include "llsd.h" +#include "llpounceable.h" #include "llhost.cpp" // Needed for copy operator #include "net.cpp" // Needed by LLHost. -LLMessageSystem * gMessageSystem = NULL; +LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; // sensor test doubles bool gClearRecvWasCalled = false; diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp index 55748ad27e36d2c4fc0c34fea63bea8bd6995f09..41f982a7e22668c70f5312e74967e64dddd1d210 100644 --- a/indra/llmessage/tests/lltrustedmessageservice_test.cpp +++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp @@ -33,8 +33,9 @@ #include "message.h" #include "llmessageconfig.h" #include "llhttpnode_stub.cpp" +#include "llpounceable.h" -LLMessageSystem* gMessageSystem = NULL; +LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; LLMessageConfig::SenderTrust LLMessageConfig::getSenderTrustedness(const std::string& msg_name) diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h index 2aff90ca1ef8657f0c56cced2cc9a33c02f98041..598652434233e5f1b2e4a90bec4df809cbd54fd5 100644 --- a/indra/llmessage/tests/networkio.h +++ b/indra/llmessage/tests/networkio.h @@ -34,6 +34,7 @@ #include "llares.h" #include "llpumpio.h" #include "llhttpclient.h" +#include "llexception.h" /***************************************************************************** * NetworkIO @@ -43,7 +44,7 @@ // init time. Use the lazy, on-demand initialization we get from LLSingleton. class NetworkIO: public LLSingleton<NetworkIO> { -public: + LLSINGLETON(NetworkIO); NetworkIO(): mServicePump(NULL), mDone(false) @@ -51,7 +52,7 @@ class NetworkIO: public LLSingleton<NetworkIO> ll_init_apr(); if (! gAPRPoolp) { - throw std::runtime_error("Can't initialize APR"); + LLTHROW(LLException("Can't initialize APR")); } // Create IO Pump to use for HTTP Requests. @@ -59,7 +60,7 @@ class NetworkIO: public LLSingleton<NetworkIO> LLHTTPClient::setPump(*mServicePump); if (ll_init_ares() == NULL || !gAres->isInitialized()) { - throw std::runtime_error("Can't start DNS resolver"); + LLTHROW(LLException("Can't start DNS resolver")); } // You can interrupt pump() without waiting the full timeout duration @@ -68,6 +69,7 @@ class NetworkIO: public LLSingleton<NetworkIO> boost::bind(&NetworkIO::done, this, _1)); } +public: bool pump(F32 timeout=10) { // Reset the done flag so we don't pop out prematurely diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py index e45249b1cba1ca41b539b2dfa1d2aff1034409fe..9cd2959ea18e59b1999ca72cfeb2ecfd5cfa99ec 100755 --- a/indra/llmessage/tests/test_llsdmessage_peer.py +++ b/indra/llmessage/tests/test_llsdmessage_peer.py @@ -31,13 +31,10 @@ import os import sys -from threading import Thread from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler -mydir = os.path.dirname(__file__) # expected to be .../indra/llmessage/tests/ -sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) -from indra.util.fastest_elementtree import parse as xml_parse -from indra.base import llsd +from llbase.fastest_elementtree import parse as xml_parse +from llbase import llsd from testrunner import freeport, run, debug, VERBOSE import time @@ -157,17 +154,23 @@ class Server(HTTPServer): allow_reuse_address = False if __name__ == "__main__": - # Instantiate a Server(TestHTTPRequestHandler) on the first free port - # in the specified port range. Doing this inline is better than in a - # daemon thread: if it blows up here, we'll get a traceback. If it blew up - # in some other thread, the traceback would get eaten and we'd run the - # subject test program anyway. - httpd, port = freeport(xrange(8000, 8020), - lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)) + # function to make a server with specified port + make_server = lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler) + + if not sys.platform.startswith("win"): + # Instantiate a Server(TestHTTPRequestHandler) on a port chosen by the + # runtime. + httpd = make_server(0) + else: + # "Then there's Windows" + # Instantiate a Server(TestHTTPRequestHandler) on the first free port + # in the specified port range. + httpd, port = freeport(xrange(8000, 8020), make_server) + # Pass the selected port number to the subject test program via the # environment. We don't want to impose requirements on the test program's # command-line parsing -- and anyway, for C++ integration tests, that's # performed in TUT code rather than our own. - os.environ["PORT"] = str(port) - debug("$PORT = %s", port) - sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:])) + os.environ["PORT"] = str(httpd.server_port) + debug("$PORT = %s", httpd.server_port) + sys.exit(run(server_inst=httpd, *sys.argv[1:])) diff --git a/indra/llmessage/tests/testrunner.py b/indra/llmessage/tests/testrunner.py index 5b9beb359b8ec729f6ecb8310d0a7d7da112b578..c25945067eb0fd4ab5628fca93174aaef62b42a2 100755 --- a/indra/llmessage/tests/testrunner.py +++ b/indra/llmessage/tests/testrunner.py @@ -27,13 +27,12 @@ $/LicenseInfo$ """ -from __future__ import with_statement - import os import sys import re import errno import socket +import subprocess VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "0") # default to quiet # Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if @@ -47,6 +46,9 @@ def debug(fmt, *args): else: debug = lambda *args: None +class Error(Exception): + pass + def freeport(portlist, expr): """ Find a free server port to use. Specifically, evaluate 'expr' (a @@ -141,34 +143,73 @@ class Server(HTTPServer): raise def run(*args, **kwds): - """All positional arguments collectively form a command line, executed as - a synchronous child process. - In addition, pass server=new_thread_instance as an explicit keyword (to - differentiate it from an additional command-line argument). - new_thread_instance should be an instantiated but not yet started Thread - subclass instance, e.g.: - run("python", "-c", 'print "Hello, world!"', server=TestHTTPServer(name="httpd")) """ - # If there's no server= keyword arg, don't start a server thread: simply - # run a child process. + Run a specified command as a synchronous child process, optionally + launching a server Thread during the run. + + All positional arguments collectively form a command line. The first + positional argument names the program file to execute. + + Returns the termination code of the child process. + + In addition, you may pass keyword-only arguments: + + use_path=True: allow a simple filename as command and search PATH for that + filename. (This argument is retained for backwards compatibility but is + now the default behavior.) + + server_inst: an instance of a subclass of SocketServer.BaseServer. + + When you pass server_inst, run() calls its handle_request() method in a + loop until the child process terminates. + """ + # server= keyword arg is discontinued try: thread = kwds.pop("server") except KeyError: pass else: - # Start server thread. Note that this and all other comm server - # threads should be daemon threads: we'll let them run "forever," - # confident that the whole process will terminate when the main thread - # terminates, which will be when the child process terminates. - thread.setDaemon(True) - thread.start() - # choice of os.spawnv(): - # - [v vs. l] pass a list of args vs. individual arguments, - # - [no p] don't use the PATH because we specifically want to invoke the - # executable passed as our first arg, - # - [no e] child should inherit this process's environment. + raise Error("Obsolete call to testrunner.run(): pass server_inst=, not server=") + debug("Running %s...", " ".join(args)) - rc = os.spawnv(os.P_WAIT, args[0], args) + + try: + server_inst = kwds.pop("server_inst") + except KeyError: + # Without server_inst, this is very simple: just run child process. + rc = subprocess.call(args) + else: + # We're being asked to run a local server while the child process + # runs. We used to launch a daemon thread calling + # server_inst.serve_forever(), then eventually call sys.exit() with + # the daemon thread still running -- but in recent versions of Python + # 2, even when you call sys.exit(0), apparently killing the thread + # causes the Python runtime to force the process termination code + # nonzero. So now we avoid the extra thread altogether. + + # SocketServer.BaseServer.handle_request() honors a 'timeout' + # attribute, if it's set to something other than None. + # We pick 0.5 seconds because that's the default poll timeout for + # BaseServer.serve_forever(), which is what we used to use. + server_inst.timeout = 0.5 + + child = subprocess.Popen(args) + while child.poll() is None: + # Setting server_inst.timeout is what keeps this handle_request() + # call from blocking "forever." Interestingly, looping over + # handle_request() with a timeout is very like the implementation + # of serve_forever(). We just check a different flag to break out. + # It might be interesting if handle_request() returned an + # indication of whether it in fact handled a request or timed out. + # Oddly, it doesn't. We could discover that by overriding + # handle_timeout(), whose default implementation does nothing -- + # but in fact we really don't care. All that matters is that we + # regularly poll both the child process and the server socket. + server_inst.handle_request() + # We don't bother to capture the rc returned by child.poll() because + # poll() is already defined to capture that in its returncode attr. + rc = child.returncode + debug("%s returned %s", args[0], rc) return rc diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 84667f1b826f5a38ed400bd038cac0b912479687..2cdea67723b135368a02362e0560a4bbb74866ee 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -56,13 +56,13 @@ set(llplugin_HEADER_FILES set_source_files_properties(${llplugin_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) -if(NOT WORD_SIZE EQUAL 32) +if(NOT ADDRESS_SIZE EQUAL 32) if(WINDOWS) - add_definitions(/FIXED:NO) + ##add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) -endif(NOT WORD_SIZE EQUAL 32) +endif(NOT ADDRESS_SIZE EQUAL 32) list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 3d173d04595366dae7bf1db1479be02a23eb7a4a..f1b6fe0a1246048da6e5035d81200f5f4d212c02 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -73,6 +73,7 @@ bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::s // Queue up the media init message -- it will be sent after all the currently queued messages. LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "init"); message.setValue("target", mTarget); + message.setValueReal("factor", mZoomFactor); sendMessage(message); mPlugin->init(launcher_filename, plugin_dir, plugin_filename, debug); @@ -116,7 +117,7 @@ void LLPluginClassMedia::reset() mMediaHeight = 0; mDirtyRect = LLRect::null; mAutoScaleMedia = false; - mRequestedVolume = 1.0f; + mRequestedVolume = 0.0f; mPriority = PRIORITY_NORMAL; mLowPrioritySizeLimit = LOW_PRIORITY_TEXTURE_SIZE_DEFAULT; mAllowDownsample = false; @@ -1259,7 +1260,7 @@ void LLPluginClassMedia::focus(bool focused) sendMessage(message); } -void LLPluginClassMedia::set_page_zoom_factor( double factor ) +void LLPluginClassMedia::set_page_zoom_factor( F64 factor ) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_page_zoom_factor"); diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index fc27b7bea368436f220273084e93ac6f5637188f..3b0739d044ca7999783bb6d6516d9d3173312880 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -68,6 +68,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner int getTextureHeight() const; int getFullWidth() const { return mFullMediaWidth; }; int getFullHeight() const { return mFullMediaHeight; }; + F64 getZoomFactor() const { return mZoomFactor; }; // This may return NULL. Callers need to check for and handle this case. unsigned char* getBitsData(); @@ -83,7 +84,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner void setSize(int width, int height); void setAutoScale(bool auto_scale); - + void setZoomFactor(F64 zoom_factor) { mZoomFactor = zoom_factor; } + void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; }; void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; }; @@ -204,7 +206,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner bool pluginSupportsMediaBrowser(void); void focus(bool focused); - void set_page_zoom_factor( double factor ); + void set_page_zoom_factor( F64 factor ); void clear_cache(); void clear_cookies(); void set_cookies(const std::string &cookies); @@ -367,6 +369,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner int mTextureHeight; int mMediaWidth; int mMediaHeight; + + F64 mZoomFactor; float mRequestedVolume; diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 00bde8dbc32a8a4710f7984b3d0347c747855f8d..76d3a405d849a0446a760ed7c547ce0f3ec28bb5 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -807,17 +807,19 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac // LLDAELoader //----------------------------------------------------------------------------- LLDAELoader::LLDAELoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, load_callback_t load_cb, joint_lookup_func_t joint_lookup_func, texture_load_func_t texture_load_func, - state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes, + state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + std::map<std::string, std::string>& jointAliasMap, + U32 maxJointsPerMesh, U32 modelLimit, - bool preprocess) + bool preprocess) : LLModelLoader( filename, lod, @@ -826,10 +828,12 @@ LLDAELoader::LLDAELoader( texture_load_func, state_cb, opaque_userdata, - jointMap, - jointsFromNodes), -mGeneratedModelLimit(modelLimit), -mPreprocessDAE(preprocess) + jointTransformMap, + jointsFromNodes, + jointAliasMap, + maxJointsPerMesh), + mGeneratedModelLimit(modelLimit), + mPreprocessDAE(preprocess) { } @@ -851,6 +855,8 @@ struct ModelSort bool LLDAELoader::OpenFile(const std::string& filename) { + setLoadState( READING_FILE ); + //no suitable slm exists, load from the .dae file DAE dae; domCOLLADA* dom; @@ -1071,7 +1077,7 @@ bool LLDAELoader::OpenFile(const std::string& filename) std::string LLDAELoader::preprocessDAE(std::string filename) { // Open a DAE file for some preprocessing (like removing space characters in IDs), see MAINT-5678 - std::ifstream inFile; + llifstream inFile; inFile.open(filename.c_str(), std::ios_base::in); std::stringstream strStream; strStream << inFile.rdbuf(); @@ -1148,28 +1154,29 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do //Some collada setup for accessing the skeleton - daeElement* pElement = 0; - dae->getDatabase()->getElement( &pElement, 0, 0, "skeleton" ); - - //Try to get at the skeletal instance controller - domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement ); + U32 skeleton_count = dae->getDatabase()->getElementCount( NULL, "skeleton" ); + std::vector<domInstance_controller::domSkeleton*> skeletons; + for (S32 i=0; i<skeleton_count; i++) + { + daeElement* pElement = 0; + dae->getDatabase()->getElement( &pElement, i, 0, "skeleton" ); + + //Try to get at the skeletal instance controller + domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement ); + daeElement* pSkeletonRootNode = NULL; + if (pSkeleton) + { + pSkeletonRootNode = pSkeleton->getValue().getElement(); + } + if (pSkeleton && pSkeletonRootNode) + { + skeletons.push_back(pSkeleton); + } + } bool missingSkeletonOrScene = false; //If no skeleton, do a breadth-first search to get at specific joints - bool rootNode = false; - - //Need to test for a skeleton that does not have a root node - //This occurs when your instance controller does not have an associated scene - if ( pSkeleton ) - { - daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); - if ( pSkeletonRootNode ) - { - rootNode = true; - } - - } - if ( !pSkeleton || !rootNode ) + if ( skeletons.size() == 0 ) { daeElement* pScene = root->getDescendant("visual_scene"); if ( !pScene ) @@ -1184,7 +1191,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do S32 childCount = children.getCount(); //Process any children that are joints - //Not all children are joints, some code be ambient lights, cameras, geometry etc.. + //Not all children are joints, some could be ambient lights, cameras, geometry etc.. for (S32 i = 0; i < childCount; ++i) { domNode* pNode = daeSafeCast<domNode>(children[i]); @@ -1196,83 +1203,90 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do } } else - //Has Skeleton - { - //Get the root node of the skeleton - daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); - if ( pSkeletonRootNode ) - { - //Once we have the root node - start acccessing it's joint components - const int jointCnt = mJointMap.size(); - JointMap :: const_iterator jointIt = mJointMap.begin(); - - //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. - for ( int i=0; i<jointCnt; ++i, ++jointIt ) - { - //Build a joint for the resolver to work with - char str[64]={0}; - sprintf(str,"./%s",(*jointIt).first.c_str() ); - //LL_WARNS()<<"Joint "<< str <<LL_ENDL; - - //Setup the resolver - daeSIDResolver resolver( pSkeletonRootNode, str ); - - //Look for the joint - domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() ); - if ( pJoint ) - { - //Pull out the translate id and store it in the jointTranslations map - daeSIDResolver jointResolverA( pJoint, "./translate" ); - domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() ); - daeSIDResolver jointResolverB( pJoint, "./location" ); - domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() ); - - LLMatrix4 workingTransform; - - //Translation via SID - if ( pTranslateA ) - { - extractTranslation( pTranslateA, workingTransform ); - } - else - if ( pTranslateB ) - { - extractTranslation( pTranslateB, workingTransform ); - } - else - { - //Translation via child from element - daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); - if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) - { - LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL; - missingSkeletonOrScene = true; - } - else - if ( pTranslateElement ) - { - extractTranslationViaElement( pTranslateElement, workingTransform ); - } - else - { - extractTranslationViaSID( pJoint, workingTransform ); - } - - } - - //Store the joint transform w/respect to it's name. - mJointList[(*jointIt).second.c_str()] = workingTransform; - } - } - - //If anything failed in regards to extracting the skeleton, joints or translation id, - //mention it - if ( missingSkeletonOrScene ) - { - LL_WARNS()<< "Partial jointmap found in asset - did you mean to just have a partial map?" << LL_ENDL; - } - }//got skeleton? - } + //Has one or more skeletons + for (std::vector<domInstance_controller::domSkeleton*>::iterator skel_it = skeletons.begin(); + skel_it != skeletons.end(); ++skel_it) + { + domInstance_controller::domSkeleton* pSkeleton = *skel_it; + //Get the root node of the skeleton + daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); + if ( pSkeletonRootNode ) + { + //Once we have the root node - start acccessing it's joint components + const int jointCnt = mJointMap.size(); + JointMap :: const_iterator jointIt = mJointMap.begin(); + + //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. + for ( int i=0; i<jointCnt; ++i, ++jointIt ) + { + //Build a joint for the resolver to work with + char str[64]={0}; + sprintf(str,"./%s",(*jointIt).first.c_str() ); + //LL_WARNS()<<"Joint "<< str <<LL_ENDL; + + //Setup the resolver + daeSIDResolver resolver( pSkeletonRootNode, str ); + + //Look for the joint + domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() ); + if ( pJoint ) + { + // FIXME this has a lot of overlap with processJointNode(), would be nice to refactor. + + //Pull out the translate id and store it in the jointTranslations map + daeSIDResolver jointResolverA( pJoint, "./translate" ); + domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() ); + daeSIDResolver jointResolverB( pJoint, "./location" ); + domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() ); + + LLMatrix4 workingTransform; + + //Translation via SID + if ( pTranslateA ) + { + extractTranslation( pTranslateA, workingTransform ); + } + else + { + if ( pTranslateB ) + { + extractTranslation( pTranslateB, workingTransform ); + } + else + { + //Translation via child from element + daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); + if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) + { + LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL; + missingSkeletonOrScene = true; + } + else + if ( pTranslateElement ) + { + extractTranslationViaElement( pTranslateElement, workingTransform ); + } + else + { + extractTranslationViaSID( pJoint, workingTransform ); + } + + } + } + + //Store the joint transform w/respect to its name. + mJointList[(*jointIt).second.c_str()] = workingTransform; + } + } + + //If anything failed in regards to extracting the skeleton, joints or translation id, + //mention it + if ( missingSkeletonOrScene ) + { + LL_WARNS()<< "Partial jointmap found in asset - did you mean to just have a partial map?" << LL_ENDL; + } + }//got skeleton? + } domSkin::domJoints* joints = skin->getJoints(); @@ -1307,7 +1321,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); - model->mSkinInfo.mJointMap[name] = j; + model->mSkinInfo.mJointNums.push_back(-1); } } else @@ -1325,7 +1339,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); - model->mSkinInfo.mJointMap[name] = j; + model->mSkinInfo.mJointNums.push_back(-1); } } } @@ -1353,8 +1367,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do mat.mMatrix[i][j] = transform[k*16 + i + j*4]; } } - - model->mSkinInfo.mInvBindMatrix.push_back(mat); + model->mSkinInfo.mInvBindMatrix.push_back(mat); } } } @@ -1370,35 +1383,48 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do if ( !missingSkeletonOrScene ) { - //Set the joint translations on the avatar - if it's a full mapping - //The joints are reset in the dtor - if ( getRigWithSceneParity() ) - { - JointMap :: const_iterator masterJointIt = mJointMap.begin(); - JointMap :: const_iterator masterJointItEnd = mJointMap.end(); - for (;masterJointIt!=masterJointItEnd;++masterJointIt ) - { - std::string lookingForJoint = (*masterJointIt).first.c_str(); - - if ( mJointList.find( lookingForJoint ) != mJointList.end() ) - { - //LL_INFOS()<<"joint "<<lookingForJoint.c_str()<<LL_ENDL; - LLMatrix4 jointTransform = mJointList[lookingForJoint]; - LLJoint* pJoint = mJointLookupFunc(lookingForJoint,mOpaqueData); - if ( pJoint ) - { - LLUUID fake_mesh_id; - fake_mesh_id.generate(); - pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, ""); - } - else - { - //Most likely an error in the asset. - LL_WARNS()<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << LL_ENDL; - } - } - } - } + // FIXME: mesh_id is used to determine which mesh gets to + // set the joint offset, in the event of a conflict. Since + // we don't know the mesh id yet, we can't guarantee that + // joint offsets will be applied with the same priority as + // in the uploaded model. If the file contains multiple + // meshes with conflicting joint offsets, preview may be + // incorrect. + LLUUID fake_mesh_id; + fake_mesh_id.generate(); + + //Set the joint translations on the avatar + JointMap :: const_iterator masterJointIt = mJointMap.begin(); + JointMap :: const_iterator masterJointItEnd = mJointMap.end(); + for (;masterJointIt!=masterJointItEnd;++masterJointIt ) + { + std::string lookingForJoint = (*masterJointIt).first.c_str(); + + if ( mJointList.find( lookingForJoint ) != mJointList.end() ) + { + //LL_INFOS()<<"joint "<<lookingForJoint.c_str()<<LL_ENDL; + LLMatrix4 jointTransform = mJointList[lookingForJoint]; + LLJoint* pJoint = mJointLookupFunc(lookingForJoint,mOpaqueData); + if ( pJoint ) + { + const LLVector3& joint_pos = jointTransform.getTranslation(); + if (pJoint->aboveJointPosThreshold(joint_pos)) + { + bool override_changed; // not used + pJoint->addAttachmentPosOverride(joint_pos, fake_mesh_id, "", override_changed); + if (model->mSkinInfo.mLockScaleIfJointPosition) + { + pJoint->addAttachmentScaleOverride(pJoint->getDefaultScale(), fake_mesh_id, ""); + } + } + } + else + { + //Most likely an error in the asset. + LL_WARNS()<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << LL_ENDL; + } + } + } } //missingSkeletonOrScene //We need to construct the alternate bind matrix (which contains the new joint positions) @@ -1412,16 +1438,15 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do std::string lookingForJoint = (*jointIt).c_str(); //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key //and store it in the alternate bind matrix - if ( mJointList.find( lookingForJoint ) != mJointList.end() ) + if ( mJointMap.find( lookingForJoint ) != mJointMap.end() ) { - LLMatrix4 jointTransform = mJointList[lookingForJoint]; LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i]; newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() ); model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse ); - } + } else { - LL_WARNS()<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<LL_ENDL; + LL_DEBUGS("Mesh")<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<"] "<<LL_ENDL; } } @@ -1868,7 +1893,7 @@ daeElement* LLDAELoader::getChildFromElement( daeElement* pElement, std::string { return pChildOfElement; } - LL_WARNS()<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL; + LL_DEBUGS("Mesh")<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL; return NULL; } diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 27db5326d50ff8e17721dd19475d7b25b19d2c9a..4e990dbe5e51b887f40ec09501bdd8eabd4b9350 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -47,17 +47,19 @@ class LLDAELoader : public LLModelLoader dae_model_map mModelsMap; LLDAELoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, LLModelLoader::load_callback_t load_cb, LLModelLoader::joint_lookup_func_t joint_lookup_func, LLModelLoader::texture_load_func_t texture_load_func, LLModelLoader::state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + std::map<std::string, std::string>& jointAliasMap, + U32 maxJointsPerMesh, U32 modelLimit, - bool preprocess); + bool preprocess); virtual ~LLDAELoader() ; virtual bool OpenFile(const std::string& filename); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index e494c55250145c74704fbc35690bb67b465c78e4..db6d00bc2cfc9b749e0ca7617ac6fdea0d166322 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -50,8 +50,12 @@ std::string model_names[] = const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string); LLModel::LLModel(LLVolumeParams& params, F32 detail) - : LLVolume(params, detail), mNormalizedScale(1,1,1), mNormalizedTranslation(0,0,0) - , mPelvisOffset( 0.0f ), mStatus(NO_ERRORS), mSubmodelID(0) + : LLVolume(params, detail), + mNormalizedScale(1,1,1), + mNormalizedTranslation(0,0,0), + mPelvisOffset( 0.0f ), + mStatus(NO_ERRORS), + mSubmodelID(0) { mDecompID = -1; mLocalID = -1; @@ -667,6 +671,7 @@ LLSD LLModel::writeModel( const LLModel::Decomposition& decomp, BOOL upload_skin, BOOL upload_joints, + BOOL lock_scale_if_joint_position, BOOL nowrite, BOOL as_slm, int submodel_id) @@ -686,7 +691,7 @@ LLSD LLModel::writeModel( if (skinning) { //write skinning block - mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints); + mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints, lock_scale_if_joint_position); } if (!decomp.mBaseHull.empty() || @@ -867,6 +872,7 @@ LLSD LLModel::writeModel( S32 count = 0; for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) { + // Note joint index cannot exceed 255. if (iter->mJointIdx < 255 && iter->mJointIdx >= 0) { U8 idx = (U8) iter->mJointIdx; @@ -1000,7 +1006,7 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) { - //1. If a vertex has been weighted then we'll find it via pos and return it's weight list + //1. If a vertex has been weighted then we'll find it via pos and return its weight list weight_map::iterator iterPos = mSkinWeights.begin(); weight_map::iterator iterEnd = mSkinWeights.end(); @@ -1223,7 +1229,6 @@ bool LLModel::loadModel(std::istream& is) } return false; - } bool LLModel::isMaterialListSubset( LLModel* ref ) @@ -1338,7 +1343,6 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn return true; } - bool LLModel::loadSkinInfo(LLSD& header, std::istream &is) { S32 offset = header["skin"]["offset"].asInteger(); @@ -1381,8 +1385,17 @@ bool LLModel::loadDecomposition(LLSD& header, std::istream& is) return true; } +LLMeshSkinInfo::LLMeshSkinInfo(): + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false) +{ +} -LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin) +LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin): + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false) { fromLLSD(skin); } @@ -1394,6 +1407,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) for (U32 i = 0; i < skin["joint_names"].size(); ++i) { mJointNames.push_back(skin["joint_names"][i]); + mJointNums.push_back(-1); } } @@ -1446,9 +1460,18 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) { mPelvisOffset = skin["pelvis_offset"].asReal(); } + + if (skin.has("lock_scale_if_joint_position")) + { + mLockScaleIfJointPosition = skin["lock_scale_if_joint_position"].asBoolean(); + } + else + { + mLockScaleIfJointPosition = false; + } } -LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const +LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_position) const { LLSD ret; @@ -1486,6 +1509,11 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const } } + if (lock_scale_if_joint_position) + { + ret["lock_scale_if_joint_position"] = lock_scale_if_joint_position; + } + ret["pelvis_offset"] = mPelvisOffset; } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index ae602c09df55b8098f0e3479e1e85e49f33c5b99..097558ef679a83b50c3bfc33f897439ac9a18910 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -42,18 +42,21 @@ class domMesh; class LLMeshSkinInfo { public: + LLMeshSkinInfo(); + LLMeshSkinInfo(LLSD& data); + void fromLLSD(LLSD& data); + LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; + LLUUID mMeshID; std::vector<std::string> mJointNames; + mutable std::vector<S32> mJointNums; std::vector<LLMatrix4> mInvBindMatrix; std::vector<LLMatrix4> mAlternateBindMatrix; - std::map<std::string, U32> mJointMap; - LLMeshSkinInfo() { } - LLMeshSkinInfo(LLSD& data); - void fromLLSD(LLSD& data); - LLSD asLLSD(bool include_joints) const; LLMatrix4 mBindShapeMatrix; float mPelvisOffset; + bool mLockScaleIfJointPosition; + bool mInvalidJointsScrubbed; }; class LLModel : public LLVolume @@ -138,6 +141,7 @@ class LLModel : public LLVolume const LLModel::Decomposition& decomp, BOOL upload_skin, BOOL upload_joints, + BOOL lock_scale_if_joint_position, BOOL nowrite = FALSE, BOOL as_slm = FALSE, int submodel_id = 0); diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index f86eceb98d8e5dc351c87db8568cdcff4e402146..4e468ff45f57c62785d0bed0ae3537c2a442cb66 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -102,16 +102,18 @@ void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& // LLModelLoader //----------------------------------------------------------------------------- LLModelLoader::LLModelLoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, load_callback_t load_cb, joint_lookup_func_t joint_lookup_func, texture_load_func_t texture_load_func, - state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes ) -: mJointList( jointMap ) + state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + JointMap& legalJointNamesMap, + U32 maxJointsPerMesh) +: mJointList( jointTransformMap ) , mJointsFromNode( jointsFromNodes ) , LLThread("Model Loader") , mFilename(filename) @@ -124,124 +126,14 @@ LLModelLoader::LLModelLoader( , mTextureLoadFunc(texture_load_func) , mStateCallback(state_cb) , mOpaqueData(opaque_userdata) -, mRigParityWithScene(false) -, mRigValidJointUpload(false) -, mLegacyRigValid(false) +, mRigValidJointUpload(true) +, mLegacyRigValid(true) , mNoNormalize(false) , mNoOptimize(false) , mCacheOnlyHitIfRigged(false) -{ - mJointMap["mPelvis"] = "mPelvis"; - mJointMap["mTorso"] = "mTorso"; - mJointMap["mChest"] = "mChest"; - mJointMap["mNeck"] = "mNeck"; - mJointMap["mHead"] = "mHead"; - mJointMap["mSkull"] = "mSkull"; - mJointMap["mEyeRight"] = "mEyeRight"; - mJointMap["mEyeLeft"] = "mEyeLeft"; - mJointMap["mCollarLeft"] = "mCollarLeft"; - mJointMap["mShoulderLeft"] = "mShoulderLeft"; - mJointMap["mElbowLeft"] = "mElbowLeft"; - mJointMap["mWristLeft"] = "mWristLeft"; - mJointMap["mCollarRight"] = "mCollarRight"; - mJointMap["mShoulderRight"] = "mShoulderRight"; - mJointMap["mElbowRight"] = "mElbowRight"; - mJointMap["mWristRight"] = "mWristRight"; - mJointMap["mHipRight"] = "mHipRight"; - mJointMap["mKneeRight"] = "mKneeRight"; - mJointMap["mAnkleRight"] = "mAnkleRight"; - mJointMap["mFootRight"] = "mFootRight"; - mJointMap["mToeRight"] = "mToeRight"; - mJointMap["mHipLeft"] = "mHipLeft"; - mJointMap["mKneeLeft"] = "mKneeLeft"; - mJointMap["mAnkleLeft"] = "mAnkleLeft"; - mJointMap["mFootLeft"] = "mFootLeft"; - mJointMap["mToeLeft"] = "mToeLeft"; - - mJointMap["avatar_mPelvis"] = "mPelvis"; - mJointMap["avatar_mTorso"] = "mTorso"; - mJointMap["avatar_mChest"] = "mChest"; - mJointMap["avatar_mNeck"] = "mNeck"; - mJointMap["avatar_mHead"] = "mHead"; - mJointMap["avatar_mSkull"] = "mSkull"; - mJointMap["avatar_mEyeRight"] = "mEyeRight"; - mJointMap["avatar_mEyeLeft"] = "mEyeLeft"; - mJointMap["avatar_mCollarLeft"] = "mCollarLeft"; - mJointMap["avatar_mShoulderLeft"] = "mShoulderLeft"; - mJointMap["avatar_mElbowLeft"] = "mElbowLeft"; - mJointMap["avatar_mWristLeft"] = "mWristLeft"; - mJointMap["avatar_mCollarRight"] = "mCollarRight"; - mJointMap["avatar_mShoulderRight"] = "mShoulderRight"; - mJointMap["avatar_mElbowRight"] = "mElbowRight"; - mJointMap["avatar_mWristRight"] = "mWristRight"; - mJointMap["avatar_mHipRight"] = "mHipRight"; - mJointMap["avatar_mKneeRight"] = "mKneeRight"; - mJointMap["avatar_mAnkleRight"] = "mAnkleRight"; - mJointMap["avatar_mFootRight"] = "mFootRight"; - mJointMap["avatar_mToeRight"] = "mToeRight"; - mJointMap["avatar_mHipLeft"] = "mHipLeft"; - mJointMap["avatar_mKneeLeft"] = "mKneeLeft"; - mJointMap["avatar_mAnkleLeft"] = "mAnkleLeft"; - mJointMap["avatar_mFootLeft"] = "mFootLeft"; - mJointMap["avatar_mToeLeft"] = "mToeLeft"; - - - mJointMap["hip"] = "mPelvis"; - mJointMap["abdomen"] = "mTorso"; - mJointMap["chest"] = "mChest"; - mJointMap["neck"] = "mNeck"; - mJointMap["head"] = "mHead"; - mJointMap["figureHair"] = "mSkull"; - mJointMap["lCollar"] = "mCollarLeft"; - mJointMap["lShldr"] = "mShoulderLeft"; - mJointMap["lForeArm"] = "mElbowLeft"; - mJointMap["lHand"] = "mWristLeft"; - mJointMap["rCollar"] = "mCollarRight"; - mJointMap["rShldr"] = "mShoulderRight"; - mJointMap["rForeArm"] = "mElbowRight"; - mJointMap["rHand"] = "mWristRight"; - mJointMap["rThigh"] = "mHipRight"; - mJointMap["rShin"] = "mKneeRight"; - mJointMap["rFoot"] = "mFootRight"; - mJointMap["lThigh"] = "mHipLeft"; - mJointMap["lShin"] = "mKneeLeft"; - mJointMap["lFoot"] = "mFootLeft"; - - //move into joint mapper class - //1. joints for joint offset verification - mMasterJointList.push_front("mPelvis"); - mMasterJointList.push_front("mTorso"); - mMasterJointList.push_front("mChest"); - mMasterJointList.push_front("mNeck"); - mMasterJointList.push_front("mHead"); - mMasterJointList.push_front("mCollarLeft"); - mMasterJointList.push_front("mShoulderLeft"); - mMasterJointList.push_front("mElbowLeft"); - mMasterJointList.push_front("mWristLeft"); - mMasterJointList.push_front("mCollarRight"); - mMasterJointList.push_front("mShoulderRight"); - mMasterJointList.push_front("mElbowRight"); - mMasterJointList.push_front("mWristRight"); - mMasterJointList.push_front("mHipRight"); - mMasterJointList.push_front("mKneeRight"); - mMasterJointList.push_front("mFootRight"); - mMasterJointList.push_front("mHipLeft"); - mMasterJointList.push_front("mKneeLeft"); - mMasterJointList.push_front("mFootLeft"); - - //2. legacy joint list - used to verify rigs that will not be using joint offsets - mMasterLegacyJointList.push_front("mPelvis"); - mMasterLegacyJointList.push_front("mTorso"); - mMasterLegacyJointList.push_front("mChest"); - mMasterLegacyJointList.push_front("mNeck"); - mMasterLegacyJointList.push_front("mHead"); - mMasterLegacyJointList.push_front("mHipRight"); - mMasterLegacyJointList.push_front("mKneeRight"); - mMasterLegacyJointList.push_front("mFootRight"); - mMasterLegacyJointList.push_front("mHipLeft"); - mMasterLegacyJointList.push_front("mKneeLeft"); - mMasterLegacyJointList.push_front("mFootLeft"); - +, mMaxJointsPerMesh(maxJointsPerMesh) +, mJointMap(legalJointNamesMap) +{ assert_main_thread(); sActiveLoaderList.push_back(this) ; } @@ -258,6 +150,23 @@ void LLModelLoader::run() doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this)); } +// static +bool LLModelLoader::getSLMFilename(const std::string& model_filename, std::string& slm_filename) +{ + slm_filename = model_filename; + + std::string::size_type i = model_filename.rfind("."); + if (i != std::string::npos) + { + slm_filename.replace(i, model_filename.size()-1, ".slm"); + return true; + } + else + { + return false; + } +} + bool LLModelLoader::doLoadModel() { //first, look for a .slm file of the same name that was modified later @@ -265,20 +174,17 @@ bool LLModelLoader::doLoadModel() if (mTrySLM) { - std::string filename = mFilename; - - std::string::size_type i = filename.rfind("."); - if (i != std::string::npos) - { - filename.replace(i, filename.size()-1, ".slm"); + std::string slm_filename; + if (getSLMFilename(mFilename, slm_filename)) + { llstat slm_status; - if (LLFile::stat(filename, &slm_status) == 0) + if (LLFile::stat(slm_filename, &slm_status) == 0) { //slm file exists llstat dae_status; if (LLFile::stat(mFilename, &dae_status) != 0 || dae_status.st_mtime < slm_status.st_mtime) { - if (loadFromSLM(filename)) + if (loadFromSLM(slm_filename)) { //slm successfully loaded, if this fails, fall through and //try loading from dae @@ -476,8 +382,6 @@ void LLModelLoader::loadModelCallback() //----------------------------------------------------------------------------- void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ) { - critiqueJointToNodeMappingFromScene(); - //Determines the following use cases for a rig: //1. It is suitable for upload with skin weights & joint positions, or //2. It is suitable for upload as standard av with just skin weights @@ -485,59 +389,27 @@ void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::st bool isJointPositionUploadOK = isRigSuitableForJointPositionUpload( jointListFromAsset ); bool isRigLegacyOK = isRigLegacy( jointListFromAsset ); - //It's OK that both could end up being true, both default to false - if ( isJointPositionUploadOK ) + // It's OK that both could end up being true. + + // Both start out as true and are forced to false if any mesh in + // the model file is not vald by that criterion. Note that a file + // can contain multiple meshes. + if ( !isJointPositionUploadOK ) { - setRigValidForJointPositionUpload( true ); + // This starts out true, becomes false if false for any loaded + // mesh. + setRigValidForJointPositionUpload( false ); } - if ( isRigLegacyOK) + if ( !isRigLegacyOK) { - setLegacyRigValid( true ); + // This starts out true, becomes false if false for any loaded + // mesh. + setLegacyRigValid( false ); } } -//----------------------------------------------------------------------------- -// critiqueJointToNodeMappingFromScene() -//----------------------------------------------------------------------------- -void LLModelLoader::critiqueJointToNodeMappingFromScene( void ) -{ - //Do the actual nodes back the joint listing from the dae? - //if yes then this is a fully rigged asset, otherwise it's just a partial rig - - JointSet::iterator jointsFromNodeIt = mJointsFromNode.begin(); - JointSet::iterator jointsFromNodeEndIt = mJointsFromNode.end(); - bool result = true; - - if ( !mJointsFromNode.empty() ) - { - for ( ;jointsFromNodeIt!=jointsFromNodeEndIt;++jointsFromNodeIt ) - { - std::string name = *jointsFromNodeIt; - if ( mJointTransformMap.find( name ) != mJointTransformMap.end() ) - { - continue; - } - else - { - LL_INFOS() <<"critiqueJointToNodeMappingFromScene is missing a: " << name << LL_ENDL; - result = false; - } - } - } - else - { - result = false; - } - //Determines the following use cases for a rig: - //1. Full av rig w/1-1 mapping from the scene and joint array - //2. Partial rig but w/o parity between the scene and joint array - if ( result ) - { - setRigWithSceneParity( true ); - } -} //----------------------------------------------------------------------------- // isRigLegacy() //----------------------------------------------------------------------------- @@ -549,68 +421,39 @@ bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAs return false; } - bool result = false; - - JointSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin(); - JointSet :: const_iterator masterJointEndIt = mMasterLegacyJointList.end(); - - std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin(); - std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end(); - - for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) - { - result = false; - modelJointIt = jointListFromAsset.begin(); + // Too many joints in asset + if (jointListFromAsset.size()>mMaxJointsPerMesh) + { + LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL; + LL_WARNS() << "Skinning disabled due to too many joints" << LL_ENDL; + return false; + } + + // Unknown joints in asset + S32 unknown_joint_count = 0; + for (std::vector<std::string>::const_iterator it = jointListFromAsset.begin(); + it != jointListFromAsset.end(); ++it) + { + if (mJointMap.find(*it)==mJointMap.end()) + { + LL_WARNS() << "Rigged to unrecognized joint name " << *it << LL_ENDL; + unknown_joint_count++; + } + } + if (unknown_joint_count>0) + { + LL_WARNS() << "Skinning disabled due to unknown joints" << LL_ENDL; + return false; + } - for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) - { - if ( *masterJointIt == *modelJointIt ) - { - result = true; - break; - } - } - if ( !result ) - { - LL_INFOS() <<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL; - break; - } - } - return result; + return true; } //----------------------------------------------------------------------------- // isRigSuitableForJointPositionUpload() //----------------------------------------------------------------------------- bool LLModelLoader::isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ) { - bool result = false; - - JointSet :: const_iterator masterJointIt = mMasterJointList.begin(); - JointSet :: const_iterator masterJointEndIt = mMasterJointList.end(); - - std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin(); - std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end(); - - for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) - { - result = false; - modelJointIt = jointListFromAsset.begin(); - - for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) - { - if ( *masterJointIt == *modelJointIt ) - { - result = true; - break; - } - } - if ( !result ) - { - LL_INFOS() <<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL; - break; - } - } - return result; + return true; } diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index bb4d06dca3c5f9a43de3b322d77d3f535c88207d..d64e0a077352727687d6575da23bc87269266cb6 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -34,10 +34,10 @@ class LLJoint; -typedef std::map<std::string, LLMatrix4> JointTransformMap; -typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt; -typedef std::map<std::string, std::string> JointMap; -typedef std::deque<std::string> JointSet; +typedef std::map<std::string, LLMatrix4> JointTransformMap; +typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt; +typedef std::map<std::string, std::string> JointMap; +typedef std::deque<std::string> JointNameSet; const S32 SLM_SUPPORTED_VERSION = 3; const S32 NUM_LOD = 4; @@ -116,25 +116,30 @@ class LLModelLoader : public LLThread //map of avatar joints as named in COLLADA assets to internal joint names JointMap mJointMap; JointTransformMap& mJointList; - JointSet& mJointsFromNode; + JointNameSet& mJointsFromNode; + U32 mMaxJointsPerMesh; LLModelLoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, LLModelLoader::load_callback_t load_cb, LLModelLoader::joint_lookup_func_t joint_lookup_func, LLModelLoader::texture_load_func_t texture_load_func, LLModelLoader::state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes); + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + JointMap& legalJointNamesMap, + U32 maxJointsPerMesh); virtual ~LLModelLoader() ; virtual void setNoNormalize() { mNoNormalize = true; } virtual void setNoOptimize() { mNoOptimize = true; } virtual void run(); - + + static bool getSLMFilename(const std::string& model_filename, std::string& slm_filename); + // Will try SLM or derived class OpenFile as appropriate // virtual bool doLoadModel(); @@ -158,7 +163,6 @@ class LLModelLoader : public LLThread //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ); - void critiqueJointToNodeMappingFromScene( void ); //Determines if a rig is a legacy from the joint list bool isRigLegacy( const std::vector<std::string> &jointListFromAsset ); @@ -166,9 +170,6 @@ class LLModelLoader : public LLThread //Determines if a rig is suitable for upload bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ); - void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } - const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } - const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; } void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; } @@ -180,7 +181,7 @@ class LLModelLoader : public LLThread //----------------------------------------------------------------------------- bool isNodeAJoint(const char* name) { - return mJointMap.find(name) != mJointMap.end(); + return name != NULL && mJointMap.find(name) != mJointMap.end(); } protected: @@ -189,17 +190,14 @@ class LLModelLoader : public LLThread LLModelLoader::joint_lookup_func_t mJointLookupFunc; LLModelLoader::texture_load_func_t mTextureLoadFunc; LLModelLoader::state_callback_t mStateCallback; - void* mOpaqueData; + void* mOpaqueData; - bool mRigParityWithScene; bool mRigValidJointUpload; bool mLegacyRigValid; bool mNoNormalize; bool mNoOptimize; - JointSet mMasterJointList; - JointSet mMasterLegacyJointList; JointTransformMap mJointTransformMap; static std::list<LLModelLoader*> sActiveLoaderList; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 0e2946632a7170ef88ec86a78aebc97e17e5cd7b..cf0a1175676fd8d426873643c63b7fd32f1f595a 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -364,12 +364,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons if (right_x) { - F32 cr_x = (cur_x - origin.mV[VX]) / sScaleX; - if (*right_x < cr_x) - { - // rightmost edge of previously drawn text, don't draw over previous text - *right_x = cr_x; - } + *right_x = (cur_x - origin.mV[VX]) / sScaleX; } //FIXME: add underline as glyph? diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index e24d3bb5ba2388ebbe4e7585d394b445c648b7ec..18063e9700131b257102353a8e75ba91f7c87623 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -55,7 +55,6 @@ BOOL gDebugSession = FALSE; -BOOL gDebugGL = FALSE; BOOL gClothRipple = FALSE; BOOL gHeadlessClient = FALSE; BOOL gGLActive = FALSE; @@ -306,6 +305,7 @@ PFNGLUNIFORM3IVARBPROC glUniform3ivARB = NULL; PFNGLUNIFORM4IVARBPROC glUniform4ivARB = NULL; PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB = NULL; PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv = NULL; PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB = NULL; PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB = NULL; PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL; @@ -1333,6 +1333,7 @@ void LLGLManager::initExtensions() glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB"); glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB"); glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB"); + glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4fv"); glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB"); glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB"); glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB"); diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index a95872e883edc17ea44672dcb5b919cb2ddf458f..722dd9050bc1819fb31c72382226805e04f5593b 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -155,6 +155,7 @@ extern PFNGLUNIFORM3IVARBPROC glUniform3ivARB; extern PFNGLUNIFORM4IVARBPROC glUniform4ivARB; extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB; extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB; +extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB; extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB; extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB; @@ -422,6 +423,7 @@ extern PFNGLUNIFORM3IVARBPROC glUniform3ivARB; extern PFNGLUNIFORM4IVARBPROC glUniform4ivARB; extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB; extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB; +extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB; extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB; extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB; @@ -668,6 +670,7 @@ extern PFNGLUNIFORM3IVARBPROC glUniform3ivARB; extern PFNGLUNIFORM4IVARBPROC glUniform4ivARB; extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB; extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB; +extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB; extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB; extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index b30bc1aed65c0ac9d0e84096342d246bf93ebd91..5d669fb955b086b9c9a3dbec3e8bccbb0ab67dc0 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -349,8 +349,8 @@ void LLGLSLShader::unloadInternal() for (GLsizei i = 0; i < count; i++) { glDetachObjectARB(mProgramObject, obj[i]); - glDeleteObjectARB(obj[i]); - } + glDeleteObjectARB(obj[i]); + } glDeleteObjectARB(mProgramObject); @@ -1257,6 +1257,23 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c } } +void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + glUniformMatrix3x4fv(mUniform[index], count, transpose, v); + } + } +} + void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) { if (mProgramObject > 0) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 0746e8760abfbd5426f60502f631d812f10d12b4..6f10d122cb1d19ffcdf6664b38ba667218876b43 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -115,6 +115,7 @@ class LLGLSLShader void uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j); void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); + void uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); void uniform1i(const LLStaticHashedString& uniform, GLint i); void uniform1f(const LLStaticHashedString& uniform, GLfloat v); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index ebed4542712a03625b12d2862252e75305a19993..20cba68f84779cbdbad1bc77560aa044f07662e6 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -487,14 +487,15 @@ bool LLImageGL::checkSize(S32 width, S32 height) return check_power_of_two(width) && check_power_of_two(height); } -void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level) +bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level) { if (width != mWidth || height != mHeight || ncomponents != mComponents) { // Check if dimensions are a power of two! if (!checkSize(width,height)) { - LL_ERRS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL; + LL_WARNS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL; + return false; } if (mTexName) @@ -529,6 +530,8 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve mMaxDiscardLevel = MAX_DISCARD_LEVEL; } } + + return true; } //---------------------------------------------------------------------------- @@ -909,7 +912,11 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image) S32 h = raw_image->getHeight() << discard_level; // setSize may call destroyGLTexture if the size does not match - setSize(w, h, raw_image->getComponents(), discard_level); + if (!setSize(w, h, raw_image->getComponents(), discard_level)) + { + LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL; + return FALSE; + } if( !mHasExplicitFormat ) { @@ -1260,6 +1267,12 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S llassert(gGLManager.mInited); stop_glerror(); + if (!imageraw || imageraw->isBufferInvalid()) + { + LL_WARNS() << "Trying to create a texture from invalid image data" << LL_ENDL; + return FALSE; + } + if (discard_level < 0) { llassert(mCurrentDiscardLevel >= 0); @@ -1273,7 +1286,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S S32 h = raw_h << discard_level; // setSize may call destroyGLTexture if the size does not match - setSize(w, h, imageraw->getComponents(), discard_level); + if (!setSize(w, h, imageraw->getComponents(), discard_level)) + { + LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL; + return FALSE; + } if( !mHasExplicitFormat ) { diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 21982eab1dd8276a575399dafa364b00be4a0e91..ad2aea90675e9b63d5f1bb6229e562fc44b1be68 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -94,7 +94,7 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> public: virtual void dump(); // debugging info to LL_INFOS() - void setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level = -1); + bool setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level = -1); void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;} void setAllowCompression(bool allow) { mAllowCompression = allow; } diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 69420dd0bb338b07539a62847916ddfdc443743b..77c5921c9cb82fba488788ce1a8563cbb18af625 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -267,7 +267,14 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) } else { - LL_WARNS() << "NULL LLTexUnit::bind texture" << LL_ENDL; + if (texture) + { + LL_DEBUGS() << "NULL LLTexUnit::bind GL image" << LL_ENDL; + } + else + { + LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL; + } return false; } } @@ -286,7 +293,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) if(!texture) { - LL_WARNS() << "NULL LLTexUnit::bind texture" << LL_ENDL; + LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL; return false; } @@ -2039,7 +2046,8 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count) } } - mVerticesp[mCount] = mVerticesp[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) @@ -2155,9 +2163,12 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLCol } } - mVerticesp[mCount] = mVerticesp[mCount-1]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; + 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) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index b297223c2e92280f598814acaf5ae0a278c066b8..55f079117477f538bcc834e6d76f7ffb5306139e 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -520,7 +520,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string& if (!filename.empty()) { LL_CONT << "From " << filename << ":\n"; - } + } LL_CONT << log << LL_ENDL; } } diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 0fae600a90b7e0e8e743e78377b8678f026ddcb0..385166936023853ab9f5bd2c70b652890f10d5ca 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -448,7 +448,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) else { - GLenum array[] = + static const GLenum array[] = { GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, @@ -456,7 +456,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) GL_COLOR_ARRAY, }; - GLenum mask[] = + static const GLenum mask[] = { MAP_VERTEX, MAP_NORMAL, @@ -1436,13 +1436,22 @@ void LLVertexBuffer::setupVertexArray() //glVertexattribIPointer requires GLSL 1.30 or later if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) { - glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], (void*) mOffsets[i]); + glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], (const GLvoid*) mOffsets[i]); } #endif } else { - glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]); + // nat 2016-12-16: With 64-bit clang compile, the compiler + // produces an error if we simply cast mOffsets[i] -- an S32 + // -- to (GLvoid *), the type of the parameter. It correctly + // points out that there's no way an S32 could fit a real + // pointer value. Ruslan asserts that in this case the last + // param is interpreted as an array data offset within the VBO + // rather than as an actual pointer, so it's okay. + glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], + attrib_normalized[i], sTypeSize[i], + reinterpret_cast<GLvoid*>(mOffsets[i])); } } else diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 7fb1db15fb232128978c99d56edba439e06cfd20..8054eb36199cdf57ebc8bafea46b1c026911b00a 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -3,6 +3,7 @@ project(llui) include(00-Common) +include(Hunspell) include(LLCommon) include(LLImage) include(LLInventory) @@ -294,7 +295,11 @@ if(LL_TESTS) ) LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}") # INTEGRATION TESTS - set(test_libs llui llmessage llcorehttp llcommon ${LLCOMMON_LIBRARIES} ${BOOST_COROUTINE_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ${WINDOWS_LIBRARIES}) + set(test_libs llui llmessage llcorehttp llcommon + ${HUNSPELL_LIBRARY} + ${LLCOMMON_LIBRARIES} + ${BOOST_COROUTINE_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} + ${WINDOWS_LIBRARIES}) if(NOT LINUX) LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}") endif(NOT LINUX) diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 53720a604433fba5153f564be800494cc06f3814..f8ef5289db03eb558c6603a860cd222779695a60 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -361,6 +361,7 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p) { mStoredOpenCloseState = false; mWasStateStored = false; + mSkipChangesOnNotifyParent = false; mDropdownBGColor = LLColor4::white; LLAccordionCtrlTabHeader::Params headerParams; @@ -691,7 +692,7 @@ S32 LLAccordionCtrlTab::notifyParent(const LLSD& info) mExpandedHeight = height; - if(isExpanded()) + if(isExpanded() && !mSkipChangesOnNotifyParent) { LLRect panel_rect = getRect(); panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), height); diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 7a78700e0f21aa89df82e70f076df6e5c57e7893..0263bce4be7e8947a07a31a12ce0a33fbbdf21eb 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -195,6 +195,8 @@ class LLAccordionCtrlTab : public LLUICtrl void setFitPanel( bool fit ) { mFitPanel = true; } bool getFitParent() const { return mFitPanel; } + void setIgnoreResizeNotification(bool ignore) { mSkipChangesOnNotifyParent = ignore;} + protected: void adjustContainerPanel (const LLRect& child_rect); void adjustContainerPanel (); @@ -235,6 +237,7 @@ class LLAccordionCtrlTab : public LLUICtrl bool mStoredOpenCloseState; bool mWasStateStored; + bool mSkipChangesOnNotifyParent; bool mSelectionEnabled; diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp index 1d18cb2bb039173911f85608e27903314d7d0a01..06fac190ed225ca80f7cf3bddf8564a5acb0d6ec 100644 --- a/indra/llui/llclipboard.cpp +++ b/indra/llui/llclipboard.cpp @@ -123,7 +123,15 @@ bool LLClipboard::copyToClipboard(const LLWString &src, S32 pos, S32 len, bool u // Concatenate the input string to the LL and the system clipboard bool LLClipboard::addToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary) { - mString = src.substr(pos, len); + try + { + mString = src.substr(pos, len); + } + catch (const std::exception& e) + { + LL_WARNS() << "Can't add the substring to clipboard: " << e.what() << LL_ENDL; + return false; + } return (use_primary ? LLView::getWindow()->copyTextToPrimary(mString) : LLView::getWindow()->copyTextToClipboard(mString)); } diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h index 58d80e26876419977f48b4f216dbb780a5a76609..a668ac1ac6cfe9a30963d58340127117d23be931 100644 --- a/indra/llui/llclipboard.h +++ b/indra/llui/llclipboard.h @@ -48,10 +48,10 @@ class LLClipboard : public LLSingleton<LLClipboard> { -public: - LLClipboard(); + LLSINGLETON(LLClipboard); ~LLClipboard(); +public: // Clears the clipboard void reset(); // Returns the state of the clipboard so client can know if it has been modified (comparing with tracked state) diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h index f2f2145953c3f35820dbb6f2f6146fc69c39922a..8cec5e2b244e6d3e1b1dbdb32f3f711392675b5c 100644 --- a/indra/llui/llcommandmanager.h +++ b/indra/llui/llcommandmanager.h @@ -173,6 +173,9 @@ class LLCommand class LLCommandManager : public LLSingleton<LLCommandManager> { + LLSINGLETON(LLCommandManager); + ~LLCommandManager(); + public: struct Params : public LLInitParam::Block<Params> { @@ -184,9 +187,6 @@ class LLCommandManager } }; - LLCommandManager(); - ~LLCommandManager(); - U32 commandCount() const; LLCommand * getCommand(U32 commandIndex); LLCommand * getCommand(const LLCommandId& commandId); diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h index ac92b19977512043dc5e15ea2e0877f654742ea1..99267d978aa49f7c5283f846441bd15e81a7044c 100644 --- a/indra/llui/llcontainerview.h +++ b/indra/llui/llcontainerview.h @@ -35,7 +35,9 @@ class LLScrollContainer; struct ContainerViewRegistry : public LLChildRegistry<ContainerViewRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(ContainerViewRegistry); +}; class LLContainerView : public LLView { diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 299f5e42d4b35d7f49d83b5f5d4cc50c8a67c881..5e00bf7f4501bfa9389f2f722af0f53465da1f88 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -105,6 +105,81 @@ bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null* return true; } +bool LLFlatListView::addItemPairs(pairs_list_t panel_list, bool rearrange /*= true*/) +{ + if (!mItemComparator) + { + LL_WARNS_ONCE() << "No comparator specified for inserting FlatListView items." << LL_ENDL; + return false; + } + if (panel_list.size() == 0) + { + return false; + } + + // presort list so that it will be easier to sort elements into mItemPairs + panel_list.sort(ComparatorAdaptor(*mItemComparator)); + + pairs_const_iterator_t new_pair_it = panel_list.begin(); + item_pair_t* new_pair = *new_pair_it; + pairs_iterator_t pair_it = mItemPairs.begin(); + item_pair_t* item_pair = *pair_it; + + // sort panel_list into mItemPars + while (new_pair_it != panel_list.end() && pair_it != mItemPairs.end()) + { + if (!new_pair->first || new_pair->first->getParent() == mItemsPanel) + { + // iterator already used or we are reusing existing panel + new_pair_it++; + new_pair = *new_pair_it; + } + else if (mItemComparator->compare(new_pair->first, item_pair->first)) + { + LLPanel* panel = new_pair->first; + + mItemPairs.insert(pair_it, new_pair); + mItemsPanel->addChild(panel); + + //_4 is for MASK + panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4)); + panel->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, new_pair, _4)); + // Children don't accept the focus + panel->setTabStop(false); + } + else + { + pair_it++; + item_pair = *pair_it; + } + } + + // Add what is left of panel_list into the end of mItemPairs. + for (; new_pair_it != panel_list.end(); ++new_pair_it) + { + item_pair_t* item_pair = *new_pair_it; + LLPanel *panel = item_pair->first; + if (panel && panel->getParent() != mItemsPanel) + { + mItemPairs.push_back(item_pair); + mItemsPanel->addChild(panel); + + //_4 is for MASK + panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, item_pair, _4)); + panel->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, item_pair, _4)); + // Children don't accept the focus + panel->setTabStop(false); + } + } + + if (rearrange) + { + rearrangeItems(); + notifyParentItemsRectChanged(); + } + return true; +} + bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value /*= LLUUID::null*/) { @@ -1289,6 +1364,28 @@ void LLFlatListViewEx::setFilterSubString(const std::string& filter_str) } } +void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action) +{ + if (!item) return; + + // 0 signifies that filter is matched, + // i.e. we don't hide items that don't support 'match_filter' action, separators etc. + if (0 == item->notify(action)) + { + mHasMatchedItems = true; + item->setVisible(true); + } + else + { + // TODO: implement (re)storing of current selection. + if (!mForceShowingUnmatchedItems) + { + selectItem(item, false); + } + item->setVisible(mForceShowingUnmatchedItems); + } +} + void LLFlatListViewEx::filterItems() { typedef std::vector <LLPanel*> item_panel_list_t; @@ -1309,22 +1406,7 @@ void LLFlatListViewEx::filterItems() iter != iter_end; ++iter) { LLPanel* pItem = (*iter); - // 0 signifies that filter is matched, - // i.e. we don't hide items that don't support 'match_filter' action, separators etc. - if (0 == pItem->notify(action)) - { - mHasMatchedItems = true; - pItem->setVisible(true); - } - else - { - // TODO: implement (re)storing of current selection. - if(!mForceShowingUnmatchedItems) - { - selectItem(pItem, false); - } - pItem->setVisible(mForceShowingUnmatchedItems); - } + updateItemVisibility(pItem, action); } sort(); diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 92bf429031d216a9a3e85209bb8058816cbe1713..230ea200d888545ecee96e0a52f30f1fa68e6487 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -351,6 +351,8 @@ class LLFlatListView : public LLScrollContainer, public LLEditMenuHandler virtual bool removeItemPair(item_pair_t* item_pair, bool rearrange); + bool addItemPairs(pairs_list_t panel_list, bool rearrange = true); + /** * Notify parent about changed size of internal controls with "size_changes" action * @@ -480,6 +482,7 @@ class LLFlatListViewEx : public LLFlatListView * Sets up new filter string and filters the list. */ void setFilterSubString(const std::string& filter_str); + std::string getFilterSubString() { return mFilterSubString; } /** * Filters the list, rearranges and notifies parent about shape changes. @@ -503,6 +506,14 @@ class LLFlatListViewEx : public LLFlatListView */ void updateNoItemsMessage(const std::string& filter_string); + /** + * Applies visibility acording to action and LLFlatListView settings. + * + * @param item - item we are changing + * @param item - action - parameters to determin visibility from + */ + void updateItemVisibility(LLPanel* item, const LLSD &action); + private: std::string mNoFilteredItemsMsg; std::string mNoItemsMsg; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 5ea9f5b6ccf714daf7aa597a6ca29c6ea98ca025..3ece1c12bf6e9ad98aadecc951a1f4c603c5f7cb 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -64,8 +64,6 @@ // use this to control "jumping" behavior when Ctrl-Tabbing const S32 TABBED_FLOATER_OFFSET = 0; -extern LLControlGroup gSavedSettings; - namespace LLInitParam { void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues() @@ -653,13 +651,7 @@ void LLFloater::openFloater(const LLSD& key) && !getFloaterHost() && (!getVisible() || isMinimized())) { - //Don't play a sound for incoming voice call based upon chat preference setting - bool playSound = !(getName() == "incoming call" && gSavedSettings.getBOOL("PlaySoundIncomingVoiceCall") == FALSE); - - if(playSound) - { - make_ui_sound("UISndWindowOpen"); - } + make_ui_sound("UISndWindowOpen"); } //RN: for now, we don't allow rehosting from one multifloater to another @@ -2263,7 +2255,7 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent) for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) { LLView* viewp = *child_it; - LLFloater* floaterp = (LLFloater*)viewp; + LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp); if (floaterp->isDependent()) { // dependents are moved with their "dependee" @@ -2318,10 +2310,14 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent) void LLFloaterView::restoreAll() { // make sure all subwindows aren't minimized - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + child_list_t child_list = *(getChildList()); + for (child_list_const_iter_t child_it = child_list.begin(); child_it != child_list.end(); ++child_it) { - LLFloater* floaterp = (LLFloater*)*child_it; - floaterp->setMinimized(FALSE); + LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it); + if (floaterp) + { + floaterp->setMinimized(FALSE); + } } // *FIX: make sure dependents are restored @@ -2597,7 +2593,7 @@ void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom) ++child_it) //loop floaters { // Examine minimized children. - LLFloater* floater = (LLFloater*)((LLView*)*child_it); + LLFloater* floater = dynamic_cast<LLFloater*>(*child_it); if(floater->isMinimized()) { LLRect r = floater->getRect(); @@ -2650,7 +2646,7 @@ void LLFloaterView::closeAllChildren(bool app_quitting) continue; } - LLFloater* floaterp = (LLFloater*)viewp; + LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp); // Attempt to close floater. This will cause the "do you want to save" // dialogs to appear. @@ -2716,8 +2712,7 @@ BOOL LLFloaterView::allChildrenClosed() // by setting themselves invisible) for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) { - LLView* viewp = *it; - LLFloater* floaterp = (LLFloater*)viewp; + LLFloater* floaterp = dynamic_cast<LLFloater*>(*it); if (floaterp->getVisible() && !floaterp->isDead() && floaterp->isCloseable()) { @@ -2953,7 +2948,7 @@ void LLFloaterView::syncFloaterTabOrder() // otherwise, make sure the focused floater is in the front of the child list for ( child_list_const_reverse_iter_t child_it = getChildList()->rbegin(); child_it != getChildList()->rend(); ++child_it) { - LLFloater* floaterp = (LLFloater*)*child_it; + LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it); if (gFocusMgr.childHasKeyboardFocus(floaterp)) { bringToFront(floaterp, FALSE); @@ -2975,7 +2970,7 @@ LLFloater* LLFloaterView::getParentFloater(LLView* viewp) const if (parentp == this) { - return (LLFloater*)viewp; + return dynamic_cast<LLFloater*>(viewp); } return NULL; diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 1a51b96fdf25dac9b877504d1a59f051179efdb2..1b213c34186e7ee4d08ba30d5a04a3eab24d1877 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -186,7 +186,6 @@ void LLFocusMgr::releaseFocusIfNeeded( LLView* view ) LLUI::removePopup(view); } - void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only) { // notes if keyboard focus is changed again (by onFocusLost/onFocusReceived) diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 8166ef6a07ad777efa1387cd7572af1576d3b9a4..f9664e0658549d35e4ec4c04b292c3b92b8c19f1 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -684,6 +684,13 @@ void LLFolderView::draw() } } + if (mRenameItem && mRenamer && mRenamer->getVisible() && !getVisibleRect().overlaps(mRenamer->getRect())) + { + // renamer is not connected to the item we are renaming in any form so manage it manually + // TODO: consider stopping on any scroll action instead of when out of visible area + finishRenamingItem(); + } + // skip over LLFolderViewFolder::draw since we don't want the folder icon, label, // and arrow for the root folder LLView::draw(); diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 5eb5ca4f82783e1f958c8129f83dc6d0b823db4a..3d618548c4ffc1a8f5366f4ecfd1ac81a8ce84b7 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -127,6 +127,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) mIsSelected( FALSE ), mIsCurSelection( FALSE ), mSelectPending(FALSE), + mIsItemCut(false), + mCutGeneration(0), mLabelStyle( LLFontGL::NORMAL ), mHasVisibleChildren(FALSE), mIsFolderComplete(true), @@ -694,6 +696,19 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L return mIsCurSelection; } +/*virtual*/ bool LLFolderViewItem::isFadeItem() +{ + LLClipboard& clipboard = LLClipboard::instance(); + if (mCutGeneration != clipboard.getGeneration()) + { + mCutGeneration = clipboard.getGeneration(); + mIsItemCut = clipboard.isCutMode() + && ((getParentFolder() && getParentFolder()->isFadeItem()) + || getViewModelItem()->isCutToClipboard()); + } + return mIsItemCut; +} + void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor, const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor) { @@ -875,6 +890,12 @@ void LLFolderViewItem::draw() } LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor; + + if (isFadeItem()) + { + // Fade out item color to indicate it's being cut + color.mV[VALPHA] *= 0.5f; + } drawLabel(font, text_left, y, color, right_x); //--------------------------------------------------------------------------------// @@ -882,7 +903,7 @@ void LLFolderViewItem::draw() // if (!mLabelSuffix.empty()) { - font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, + font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x, FALSE ); } diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index 0322c8836db293a26ed5a9b744160e43120150ac..61c39e0175fb0680cd37bab6e3d87c28f55a5673 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -121,8 +121,11 @@ class LLFolderViewItem : public LLView mIsMouseOverTitle, mAllowWear, mAllowDrop, - mSelectPending; - + mSelectPending, + mIsItemCut; + + S32 mCutGeneration; + LLUIColor mFontColor; LLUIColor mFontHighlightColor; @@ -145,6 +148,7 @@ class LLFolderViewItem : public LLView virtual void addFolder(LLFolderViewFolder*) { } virtual bool isHighlightAllowed(); virtual bool isHighlightActive(); + virtual bool isFadeItem(); virtual bool isFlashing() { return false; } virtual void setFlashState(bool) { } diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index a395af537a01713e094462e1ec2674ca88571dd3..641241a88c48822e4cc349ed22716901935de751 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -173,6 +173,7 @@ class LLFolderViewModelItem : public LLRefCount, public LLTrace::MemTrackable<LL virtual BOOL isItemCopyable() const = 0; virtual BOOL copyToClipboard() const = 0; virtual BOOL cutToClipboard() = 0; + virtual bool isCutToClipboard() { return false; }; virtual BOOL isClipboardPasteable() const = 0; virtual void pasteFromClipboard() = 0; diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h index f5364f48636d12c81e7e9fe46e6052a5fcc2ffa5..e43974bc52fa9d44324538d05de1fadbb17a1340 100644 --- a/indra/llui/llfunctorregistry.h +++ b/indra/llui/llfunctorregistry.h @@ -53,14 +53,8 @@ template <typename FUNCTOR_TYPE> class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> > { - friend class LLSingleton<LLFunctorRegistry>; + LLSINGLETON(LLFunctorRegistry); LOG_CLASS(LLFunctorRegistry); -private: - LLFunctorRegistry() : LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing") - { - mMap[LOGFUNCTOR] = log_functor; - mMap[DONOTHING] = do_nothing; - } public: typedef FUNCTOR_TYPE ResponseFunctor; @@ -124,6 +118,14 @@ class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> > FunctorMap mMap; }; +template <typename FUNCTOR_TYPE> +LLFunctorRegistry<FUNCTOR_TYPE>::LLFunctorRegistry() : + LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing") +{ + mMap[LOGFUNCTOR] = log_functor; + mMap[DONOTHING] = do_nothing; +} + template <typename FUNCTOR_TYPE> class LLFunctorRegistration { diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index a245ebe1b9cce788732535aa26a5c8e8ba9aaee3..f772dbc6b49940921d246c99080753f49f773291 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -40,7 +40,9 @@ class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack> public: struct LayoutStackRegistry : public LLChildRegistry<LayoutStackRegistry> - {}; + { + LLSINGLETON_EMPTY_CTOR(LayoutStackRegistry); + }; struct Params : public LLInitParam::Block<Params, LLView::Params> { diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index a08cf91a69dbcbb85c1ec4c3427699e597285ff3..becb45fa793e32aedb3ec22fb01e2013d56c1dbd 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -163,6 +163,9 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) { llassert( mMaxLengthBytes > 0 ); + LLUICtrl::setEnabled(TRUE); + setEnabled(p.enabled); + mScrollTimer.reset(); mTripleClickTimer.reset(); setText(p.default_text()); @@ -218,6 +221,13 @@ LLLineEditor::~LLLineEditor() gFocusMgr.releaseFocusIfNeeded( this ); } +void LLLineEditor::initFromParams(const LLLineEditor::Params& params) +{ + LLUICtrl::initFromParams(params); + LLUICtrl::setEnabled(TRUE); + setEnabled(params.enabled); +} + void LLLineEditor::onFocusReceived() { gEditMenuHandler = this; @@ -400,12 +410,7 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) if (mMaxLengthChars) { - LLWString truncated_wstring = utf8str_to_wstring(truncated_utf8); - if (truncated_wstring.size() > (U32)mMaxLengthChars) - { - truncated_wstring = truncated_wstring.substr(0, mMaxLengthChars); - } - mText.assign(wstring_to_utf8str(truncated_wstring)); + mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars)); } if (all_selected) @@ -2641,10 +2646,17 @@ void LLLineEditor::showContextMenu(S32 x, S32 y) void LLLineEditor::setContextMenu(LLContextMenu* new_context_menu) { - if (new_context_menu) - mContextMenuHandle = new_context_menu->getHandle(); - else - mContextMenuHandle.markDead(); + LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get()); + if (menu) + { + menu->die(); + mContextMenuHandle.markDead(); + } + + if (new_context_menu) + { + mContextMenuHandle = new_context_menu->getHandle(); + } } void LLLineEditor::setFont(const LLFontGL* font) diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index c6d472f59b7b7d12ca8ee33056fc1c24e5a652c4..88468503df42558fd745f3e71517bede779f56c4 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -108,6 +108,9 @@ class LLLineEditor Params(); }; + + void initFromParams(const LLLineEditor::Params& params); + protected: LLLineEditor(const Params&); friend class LLUICtrlFactory; @@ -272,7 +275,7 @@ class LLLineEditor void setReplaceNewlinesWithSpaces(BOOL replace); - void setContextMenu(LLContextMenu* new_context_menu); + void resetContextMenu() { setContextMenu(NULL); }; private: // private helper methods @@ -308,6 +311,8 @@ class LLLineEditor virtual S32 getPreeditFontSize() const; virtual LLWString getPreeditString() const { return getWText(); } + void setContextMenu(LLContextMenu* new_context_menu); + protected: LLUIString mText; // The string being edited. std::string mPrevText; // Saved string for 'ESC' revert diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 628dedb906ed4c2b871c24f7e32fca22079664ec..c7f7f6848cd7fa186e7564a365f6616af817026d 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -347,7 +347,9 @@ class LLMenuItemCheckGL // child widget registry struct MenuRegistry : public LLChildRegistry<MenuRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(MenuRegistry); +}; class LLMenuGL diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 354add0b82a0e022bc8d64f8bb53d49c463bf48e..024332ee65c66fd624aa439ebdd4b68e6bd38c81 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -884,9 +884,9 @@ class LLNotifications : public LLSingleton<LLNotifications>, public LLNotificationChannelBase { + LLSINGLETON(LLNotifications); LOG_CLASS(LLNotifications); - friend class LLSingleton<LLNotifications>; public: // Needed to clear up RefCounted things prior to actual destruction @@ -966,8 +966,6 @@ class LLNotifications : bool isVisibleByRules(LLNotificationPtr pNotification); private: - // we're a singleton, so we don't have a public constructor - LLNotifications(); /*virtual*/ void initSingleton(); void loadPersistentNotifications(); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index c2185f24ded66e8c4b303eb0931bb86866980393..b8f47ef6badd427fdf00b03df3821278c99b0420 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -268,8 +268,9 @@ typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc; class LLRegisterPanelClass : public LLSingleton< LLRegisterPanelClass > { + LLSINGLETON_EMPTY_CTOR(LLRegisterPanelClass); public: - // reigister with either the provided builder, or the generic templated builder + // register with either the provided builder, or the generic templated builder void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func) { mPanelClassesNames[tag] = func; diff --git a/indra/llui/llresmgr.h b/indra/llui/llresmgr.h index a652dcd2c06cf08bed409c7010a6d339ede7dc98..b19d8d40b89f48912284950d1c8bbe849304cbd7 100644 --- a/indra/llui/llresmgr.h +++ b/indra/llui/llresmgr.h @@ -42,9 +42,9 @@ enum LLLOCALE_ID class LLResMgr : public LLSingleton<LLResMgr> { -public: - LLResMgr(); + LLSINGLETON(LLResMgr); +public: void setLocale( LLLOCALE_ID locale_id ); LLLOCALE_ID getLocale() const { return mLocale; } diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index f64cf43a8ed48ce2c8863979535bdf4e3e5fd4b8..c4c4d0a136b7ba052bbccc951c7f49644a42a3ac 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -48,7 +48,9 @@ class LLUICtrlFactory; *****************************************************************************/ struct ScrollContainerRegistry : public LLChildRegistry<ScrollContainerRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(ScrollContainerRegistry); +}; class LLScrollContainer : public LLUICtrl { diff --git a/indra/llui/llspellcheck.h b/indra/llui/llspellcheck.h index 4ab80195ead318f7f586563474d0f9fb5706d10d..acac589e433dd8d33c452641c1638bb751199559 100644 --- a/indra/llui/llspellcheck.h +++ b/indra/llui/llspellcheck.h @@ -29,16 +29,15 @@ #include "llsingleton.h" #include "llui.h" +#include "llinitdestroyclass.h" #include <boost/signals2.hpp> class Hunspell; class LLSpellChecker : public LLSingleton<LLSpellChecker>, public LLInitClass<LLSpellChecker> { - friend class LLSingleton<LLSpellChecker>; + LLSINGLETON(LLSpellChecker); friend class LLInitClass<LLSpellChecker>; -protected: - LLSpellChecker(); ~LLSpellChecker(); public: diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 8b1ba406c8f6f0d3a15463b20d51d737f78c8ec3..d49e21689883a8bb6d6086e14be80fbe4c6d8407 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -153,7 +153,7 @@ F32 clamp_precision(F32 value, S32 decimal_precision) for (S32 i = 0; i < decimal_precision; i++) clamped_value *= 10.0; - clamped_value = ll_round((F32)clamped_value); + clamped_value = ll_round(clamped_value); for (S32 i = 0; i < decimal_precision; i++) clamped_value /= 10.0; diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 35f5330a3f28ddbbb0d1a9a488dc823dcd73ce3f..6c8e63442badf14ca6498a37bad9057d2ddaadcd 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -40,6 +40,7 @@ #include "lltooltip.h" #include "lllocalcliprect.h" #include <iostream> +#include "lltrans.h" // rate at which to update display of value that is rapidly changing const F32 MEAN_VALUE_UPDATE_TIME = 1.f / 4.f; @@ -619,19 +620,19 @@ void LLStatBar::drawLabelAndValue( F32 value, std::string &label, LLRect &bar_re std::string value_str = !llisnan(value) ? llformat("%10.*f %s", decimal_digits, value, label.c_str()) - : "n/a"; + : LLTrans::getString("na"); // Draw the current value. if (mOrientation == HORIZONTAL) { LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_rect.mRight, getRect().getHeight(), - LLColor4(1.f, 1.f, 1.f, 0.5f), + LLColor4(1.f, 1.f, 1.f, 1.f), LLFontGL::RIGHT, LLFontGL::TOP); } else { LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_rect.mRight, getRect().getHeight(), - LLColor4(1.f, 1.f, 1.f, 0.5f), + LLColor4(1.f, 1.f, 1.f, 1.f), LLFontGL::RIGHT, LLFontGL::TOP); } } diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h index f381e92a4dba1364d5e269611707c307699d1ed2..ba7cfc5d10fa52c54fc7c3b0e84692d8fa2c30e8 100644 --- a/indra/llui/llstatgraph.h +++ b/indra/llui/llstatgraph.h @@ -126,7 +126,7 @@ class LLStatGraph : public LLView F32 mValue; LLUIColor mColor; - bool operator <(const Threshold& other) + bool operator <(const Threshold& other) const { return mValue < other.mValue; } diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h index bc78d3b5fdca9379bd0e8e1a01e0bea68fcafe1a..af4db7d7ea0a56f50ef8e64bf97e19637e477be4 100644 --- a/indra/llui/llstatview.h +++ b/indra/llui/llstatview.h @@ -35,7 +35,9 @@ class LLStatBar; // widget registrars struct StatViewRegistry : public LLChildRegistry<StatViewRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(StatViewRegistry); +}; class LLStatView : public LLContainerView { diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index c7d7535f87cc2aab862ec296bf680aa5005a7d49..20be73928677d920806dc2c492e53269657b19b4 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -181,7 +181,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mMaxTextByteLength( p.max_text_length ), mFont(p.font), mFontShadow(p.font_shadow), - mPopupMenu(NULL), + mPopupMenuHandle(), mReadOnly(p.read_only), mSpellCheck(p.spellcheck), mSpellCheckStart(-1), @@ -1263,9 +1263,10 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c) //virtual void LLTextBase::onVisibilityChange( BOOL new_visibility ) { - if(!new_visibility && mPopupMenu) + LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get()); + if(!new_visibility && menu) { - mPopupMenu->hide(); + menu->hide(); } LLUICtrl::onVisibilityChange(new_visibility); } @@ -1956,41 +1957,48 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url)); // create and return the context menu from the XUI file - delete mPopupMenu; + + LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get()); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } llassert(LLMenuGL::sMenuContainer != NULL); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer, - LLMenuHolderGL::child_registry_t::instance()); - if (mIsFriendSignal) - { - bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url))); - LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend"); - LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend"); + menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer, + LLMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); - if (addFriendButton && removeFriendButton) - { - addFriendButton->setEnabled(!isFriend); - removeFriendButton->setEnabled(isFriend); - } - } + if (mIsFriendSignal) + { + bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url))); + LLView* addFriendButton = menu->getChild<LLView>("add_friend"); + LLView* removeFriendButton = menu->getChild<LLView>("remove_friend"); - if (mIsObjectBlockedSignal) - { - bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url)); - LLView* blockButton = mPopupMenu->getChild<LLView>("block_object"); - LLView* unblockButton = mPopupMenu->getChild<LLView>("unblock_object"); + if (addFriendButton && removeFriendButton) + { + addFriendButton->setEnabled(!isFriend); + removeFriendButton->setEnabled(isFriend); + } + } - if (blockButton && unblockButton) - { - blockButton->setVisible(!is_blocked); - unblockButton->setVisible(is_blocked); - } - } - - if (mPopupMenu) - { - mPopupMenu->show(x, y); - LLMenuGL::showPopup(this, mPopupMenu, x, y); - } + if (mIsObjectBlockedSignal) + { + bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url)); + LLView* blockButton = menu->getChild<LLView>("block_object"); + LLView* unblockButton = menu->getChild<LLView>("unblock_object"); + + if (blockButton && unblockButton) + { + blockButton->setVisible(!is_blocked); + unblockButton->setVisible(is_blocked); + } + } + menu->show(x, y); + LLMenuGL::showPopup(this, menu, x, y); + } } void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params& input_params) diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 85641fd89920463bf5a94b7c0ccd45193170a07e..3d3a6ca869678051206ccf633e7dee73e7d061b9 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -673,7 +673,7 @@ class LLTextBase S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes // support widgets - LLContextMenu* mPopupMenu; + LLHandle<LLContextMenu> mPopupMenuHandle; LLView* mDocumentView; LLScrollContainer* mScroller; diff --git a/indra/llui/lltextparser.h b/indra/llui/lltextparser.h index 400aeeb8be78dd22d330a34f4b0a37dcf00fe890..3d71e40452d84342a708e0dd1db41553110432e5 100644 --- a/indra/llui/lltextparser.h +++ b/indra/llui/lltextparser.h @@ -37,14 +37,14 @@ class LLColor4; class LLTextParser : public LLSingleton<LLTextParser> { + LLSINGLETON(LLTextParser); + public: typedef enum e_condition_type { CONTAINS, MATCHES, STARTS_WITH, ENDS_WITH } EConditionType; typedef enum e_highlight_type { PART, ALL } EHighlightType; typedef enum e_highlight_position { WHOLE, START, MIDDLE, END } EHighlightPosition; typedef enum e_dialog_action { ACTION_NONE, ACTION_CLOSE, ACTION_ADD, ACTION_COPY, ACTION_UPDATE } EDialogAction; - LLTextParser(); - LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color, EHighlightPosition part=WHOLE, S32 index=0); bool parseFullLineHighlights(const std::string &text, LLColor4 *color); diff --git a/indra/llui/lltextvalidate.cpp b/indra/llui/lltextvalidate.cpp index 324ceb7fbab88a9fd84fba6a18b740ecd63e8920..bfe0a5bb5d46d4fee27d28bc3cbcd87a431bd40f 100644 --- a/indra/llui/lltextvalidate.cpp +++ b/indra/llui/lltextvalidate.cpp @@ -328,6 +328,15 @@ namespace LLTextValidate return rv; } + bool validateASCIINoLeadingSpace(const LLWString &str) + { + if (LLStringOps::isSpace(str[0])) + { + return FALSE; + } + return validateASCII(str); + } + // Used for multiline text stored on the server. // Example is landmark description in Places SP. bool validateASCIIWithNewLine(const LLWString &str) diff --git a/indra/llui/lltextvalidate.h b/indra/llui/lltextvalidate.h index 5c830d7db394fa50a9f01695c5fa07e73d0cca0c..e2b6c313d6d8ac3df9a938e7f76544f345cbf36f 100644 --- a/indra/llui/lltextvalidate.h +++ b/indra/llui/lltextvalidate.h @@ -52,6 +52,7 @@ namespace LLTextValidate bool validateASCIIPrintableNoPipe(const LLWString &str); bool validateASCIIPrintableNoSpace(const LLWString &str); bool validateASCII(const LLWString &str); + bool validateASCIINoLeadingSpace(const LLWString &str); bool validateASCIIWithNewLine(const LLWString &str); } diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h index fad127fc4cd440d980115bd66333c0ca2616d21b..0b1fbe536748946108178440b823c9421846c394 100644 --- a/indra/llui/lltooltip.h +++ b/indra/llui/lltooltip.h @@ -129,9 +129,10 @@ class LLInspector : public LLToolTip class LLToolTipMgr : public LLSingleton<LLToolTipMgr> { + LLSINGLETON(LLToolTipMgr); LOG_CLASS(LLToolTipMgr); + public: - LLToolTipMgr(); void show(const LLToolTip::Params& params); void show(const std::string& message); diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index aabc7ed2e423b61fc6cbff0a63b7f5cfeb4fd121..770f13c1c398d710266752010afaad60132eb150 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -60,6 +60,7 @@ #include "llflyoutbutton.h" #include "llsearcheditor.h" #include "lltoolbar.h" +#include "llcleanup.h" // for XUIParse #include "llquaternion.h" @@ -208,7 +209,7 @@ void LLUI::initClass(const settings_map_t& settings, void LLUI::cleanupClass() { - LLRender2D::cleanupClass(); + SUBSYSTEM_CLEANUP(LLRender2D); } void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups) @@ -522,7 +523,7 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path) else { std::string part(ti->begin(), ti->end()); - context = context->findChildView(part, recurse); + context = context->findChildView(LLURI::unescape(part), recurse); recurse = false; } } diff --git a/indra/llui/llui.h b/indra/llui/llui.h index c727f75c4fa6a953f8abdc244ef05225f4c764e7..d7151dbee9939fd0ecf9af5d65e5646394e00833 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -344,95 +344,6 @@ class LLUI // Moved LLLocalClipRect to lllocalcliprect.h -class LLCallbackRegistry -{ -public: - typedef boost::signals2::signal<void()> callback_signal_t; - - void registerCallback(const callback_signal_t::slot_type& slot) - { - mCallbacks.connect(slot); - } - - void fireCallbacks() - { - mCallbacks(); - } - -private: - callback_signal_t mCallbacks; -}; - -class LLInitClassList : - public LLCallbackRegistry, - public LLSingleton<LLInitClassList> -{ - friend class LLSingleton<LLInitClassList>; -private: - LLInitClassList() {} -}; - -class LLDestroyClassList : - public LLCallbackRegistry, - public LLSingleton<LLDestroyClassList> -{ - friend class LLSingleton<LLDestroyClassList>; -private: - LLDestroyClassList() {} -}; - -template<typename T> -class LLRegisterWith -{ -public: - LLRegisterWith(boost::function<void ()> func) - { - T::instance().registerCallback(func); - } - - // this avoids a MSVC bug where non-referenced static members are "optimized" away - // even if their constructors have side effects - S32 reference() - { - S32 dummy; - dummy = 0; - return dummy; - } -}; - -template<typename T> -class LLInitClass -{ -public: - LLInitClass() { sRegister.reference(); } - - static LLRegisterWith<LLInitClassList> sRegister; -private: - - static void initClass() - { - LL_ERRS() << "No static initClass() method defined for " << typeid(T).name() << LL_ENDL; - } -}; - -template<typename T> -class LLDestroyClass -{ -public: - LLDestroyClass() { sRegister.reference(); } - - static LLRegisterWith<LLDestroyClassList> sRegister; -private: - - static void destroyClass() - { - LL_ERRS() << "No static destroyClass() method defined for " << typeid(T).name() << LL_ENDL; - } -}; - -template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass); -template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass); - // useful parameter blocks struct TimeIntervalParam : public LLInitParam::ChoiceBlock<TimeIntervalParam> { diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h index 6a7a681d57a005775764cda908c343023439ea82..44472070cc4f4249d1dc1c7daebc21bcd4089f4f 100644 --- a/indra/llui/lluicolortable.h +++ b/indra/llui/lluicolortable.h @@ -38,7 +38,8 @@ class LLUIColor; class LLUIColorTable : public LLSingleton<LLUIColorTable> { -LOG_CLASS(LLUIColorTable); + LLSINGLETON_EMPTY_CTOR(LLUIColorTable); + LOG_CLASS(LLUIColorTable); // consider using sorted vector, can be much faster typedef std::map<std::string, LLUIColor> string_color_map_t; diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 99553ee0d26c701fb042895c54c15d6a7d987498..550bee5c709e7989e0506a3fa1ee3814faba1435 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -258,18 +258,25 @@ class LLUICtrl class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter> { + LLSINGLETON_EMPTY_CTOR(LLTextInputFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const { return filterResult_t(view->isCtrl() && static_cast<const LLUICtrl *>(view)->acceptsTextInput(), TRUE); } }; - + template <typename F, typename DERIVED> class CallbackRegistry : public LLRegistrySingleton<std::string, F, DERIVED > {}; - class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>{}; + class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry> + { + LLSINGLETON_EMPTY_CTOR(CommitCallbackRegistry); + }; // the enable callback registry is also used for visiblity callbacks - class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>{}; + class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry> + { + LLSINGLETON_EMPTY_CTOR(EnableCallbackRegistry); + }; protected: diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 4cc7da12679a94d8a4741dd65a3939687e8d1f30..fdefae01b172e72627c08c2e8d64bdfed7ff10b6 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -92,15 +92,27 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa { std::string filename = gDirUtilp->add("widgets", widget_tag + ".xml"); LLXMLNodePtr root_node; + std::vector<std::string> search_paths = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, filename); - // Here we're looking for the "en" version, the default-language version - // of the file, rather than the localized version. - std::string full_filename = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, filename); - if (!full_filename.empty()) + if (search_paths.empty()) { - LLUICtrlFactory::instance().pushFileName(full_filename); - LLSimpleXUIParser parser; - parser.readXUI(full_filename, block); + return; + } + + // "en" version, the default-language version of the file. + std::string base_filename = search_paths.front(); + if (!base_filename.empty()) + { + LLUICtrlFactory::instance().pushFileName(base_filename); + + if (!LLXMLNode::getLayeredXMLNode(root_node, search_paths)) + { + LL_WARNS() << "Couldn't parse widget from: " << base_filename << LL_ENDL; + return; + } + LLXUIParser parser; + parser.readXUI(root_node, block, base_filename); LLUICtrlFactory::instance().popFileName(); } } diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 3ce39c947f7e87f90fcc69f98f6aec82864b8dbf..03d946f1b7729e6cc9808ba78529e5abc06b0877 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -33,6 +33,8 @@ #include "llxuiparser.h" #include "llstl.h" #include "lldir.h" +#include "llsingleton.h" +#include "llheteromap.h" class LLView; @@ -57,22 +59,24 @@ class LLChildRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorF class LLDefaultChildRegistry : public LLChildRegistry<LLDefaultChildRegistry> { -protected: - LLDefaultChildRegistry(){} - friend class LLSingleton<LLDefaultChildRegistry>; + LLSINGLETON_EMPTY_CTOR(LLDefaultChildRegistry); }; // lookup widget name by type class LLWidgetNameRegistry : public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLWidgetNameRegistry); +}; // lookup function for generating empty param block by widget type // this is used for schema generation //typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); //class LLDefaultParamBlockRegistry //: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry> -//{}; +//{ +// LLSINGLETON(LLDefaultParamBlockRegistry); +//}; extern LLTrace::BlockTimerStatHandle FTM_WIDGET_SETUP; extern LLTrace::BlockTimerStatHandle FTM_WIDGET_CONSTRUCTION; @@ -85,31 +89,15 @@ extern template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getIn class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory> { -private: - friend class LLSingleton<LLUICtrlFactory>; - LLUICtrlFactory(); + LLSINGLETON(LLUICtrlFactory); ~LLUICtrlFactory(); // only partial specialization allowed in inner classes, so use extra dummy parameter template <typename PARAM_BLOCK, int DUMMY> - class ParamDefaults : public LLSingleton<ParamDefaults<PARAM_BLOCK, DUMMY> > + class ParamDefaults { public: - ParamDefaults() - { - // look up template file for this param block... - const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); - if (param_block_tag) - { // ...and if it exists, back fill values using the most specific template first - PARAM_BLOCK params; - LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params); - mPrototype.fillFrom(params); - } - // recursively fill from base class param block - ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get()); - - } - + ParamDefaults(); const PARAM_BLOCK& get() { return mPrototype; } private: @@ -118,9 +106,10 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory> // base case for recursion, there are NO base classes of LLInitParam::BaseBlock template<int DUMMY> - class ParamDefaults<LLInitParam::BaseBlock, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlock, DUMMY> > + class ParamDefaults<LLInitParam::BaseBlock, DUMMY> { public: + ParamDefaults(); const LLInitParam::BaseBlock& get() { return mBaseBlock; } private: LLInitParam::BaseBlock mBaseBlock; @@ -132,7 +121,7 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory> template<typename T> static const typename T::Params& getDefaultParams() { - return ParamDefaults<typename T::Params, 0>::instance().get(); + return instance().mParamDefaultsMap.obtain< ParamDefaults<typename T::Params, 0> >().get(); } // Does what you want for LLFloaters and LLPanels @@ -147,7 +136,8 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory> template<typename T> static T* create(typename T::Params& params, LLView* parent = NULL) { - params.fillFrom(ParamDefaults<typename T::Params, 0>::instance().get()); + params.fillFrom(instance().mParamDefaultsMap.obtain< + ParamDefaults<typename T::Params, 0> >().get()); T* widget = createWidgetImpl<T>(params, parent); if (widget) @@ -295,8 +285,40 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory> class LLPanel* mDummyPanel; std::vector<std::string> mFileNames; + + // store ParamDefaults specializations + // Each ParamDefaults specialization used to be an LLSingleton in its own + // right. But the 2016 changes to the LLSingleton mechanism, making + // LLSingleton instances polymorphic, are incompatible with current + // LLInitParam::BaseBlock functionality. (Thanks NickyD for spotting + // that!) Moreover, instances of the private nested ParamDefaults template + // aren't global resources -- which is what LLSingleton is designed for. + // This is simply a cache looked up by type. Its lifespan is tied to + // LLUICtrlFactory. Use LLHeteroMap for this cache. + LLHeteroMap mParamDefaultsMap; }; +template <typename PARAM_BLOCK, int DUMMY> +LLUICtrlFactory::ParamDefaults<PARAM_BLOCK, DUMMY>::ParamDefaults() +{ + // look up template file for this param block... + const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); + if (param_block_tag) + { // ...and if it exists, back fill values using the most specific template first + PARAM_BLOCK params; + LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params); + mPrototype.fillFrom(params); + } + // recursively fill from base class param block + ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom( + LLUICtrlFactory::instance().mParamDefaultsMap.obtain< + ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY> >().get()); + +} + +template <int DUMMY> +LLUICtrlFactory::ParamDefaults<LLInitParam::BaseBlock, DUMMY>::ParamDefaults() {} + // this is here to make gcc happy with reference to LLUICtrlFactory template<typename DERIVED> template<typename T> diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index e4848362a76bcfd4ac0edf8f4ee52f9cfb86c798..b5a31f51180973148d2d1d99f7b288af77601757 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -183,8 +183,9 @@ bool LLUrlEntryBase::isLinkDisabled() const bool LLUrlEntryBase::isWikiLinkCorrect(std::string url) { - std::string label = getLabelFromWikiLink(url); - return (LLUrlRegistry::instance().hasUrl(label)) ? false : true; + LLWString label = utf8str_to_wstring(getLabelFromWikiLink(url)); + label.erase(std::remove(label.begin(), label.end(), L'\u200B'), label.end()); + return (LLUrlRegistry::instance().hasUrl(wstring_to_utf8str(label))) ? false : true; } std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const @@ -205,9 +206,15 @@ std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const std::string label; up.extractParts(); - up.glueFirst(label); - std::string query = url.substr(label.size()); - return query; + up.glueFirst(label, false); + + size_t pos = url.find(label); + if (pos == std::string::npos) + { + return ""; + } + pos += label.size(); + return url.substr(pos); } @@ -1370,7 +1377,7 @@ std::string LLUrlEntryIcon::getIcon(const std::string &url) LLUrlEntryEmail::LLUrlEntryEmail() : LLUrlEntryBase() { - mPattern = boost::regex("(mailto:)?[\\w\\.\\-]+@[\\w\\.\\-]+\\.[a-z]{2,6}", + mPattern = boost::regex("(mailto:)?[\\w\\.\\-]+@[\\w\\.\\-]+\\.[a-z]{2,63}", boost::regex::perl | boost::regex::icase); mMenuName = "menu_url_email.xml"; mTooltip = LLTrans::getString("TooltipEmail"); diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 24c3a2b513c3826fa11ffbd07976146f1f0e77c4..efafe543abc65278835b292d6195bdecc561221f 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -62,9 +62,9 @@ void LLUrlRegistryNullCallback(const std::string &url, /// class LLUrlRegistry : public LLSingleton<LLUrlRegistry> { -public: + LLSINGLETON(LLUrlRegistry); ~LLUrlRegistry(); - +public: /// add a new Url handler to the registry (will be freed on destruction) /// optionally force it to the front of the list, making it take /// priority over other regular expression matches for URLs @@ -89,9 +89,6 @@ class LLUrlRegistry : public LLSingleton<LLUrlRegistry> bool isUrl(const LLWString &text); private: - LLUrlRegistry(); - friend class LLSingleton<LLUrlRegistry>; - std::vector<LLUrlEntryBase *> mUrlEntry; LLUrlEntryBase* mUrlEntryTrusted; LLUrlEntryBase* mUrlEntryIcon; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 8f7cac1f61ffd8f88ebea7b04d2fccef6858d02e..89ad8138d89749cdbee477ef540f98edf7f1ec57 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -391,7 +391,27 @@ static void buildPathname(std::ostream& out, const LLView* view) buildPathname(out, view->getParent()); // Build pathname into ostream on the way back from recursion. - out << '/' << view->getName(); + out << '/'; + + // substitute all '/' in name with appropriate code + std::string name = view->getName(); + std::size_t found = name.find('/'); + std::size_t start = 0; + while (found != std::string::npos) + { + std::size_t sub_len = found - start; + if (sub_len > 0) + { + out << name.substr(start, sub_len); + } + out << "%2F"; + start = found + 1; + found = name.find('/', start); + } + if (start < name.size()) + { + out << name.substr(start, name.size() - start); + } } std::string LLView::getPathname() const @@ -588,6 +608,11 @@ void LLView::onVisibilityChange ( BOOL new_visibility ) BOOL log_visibility_change = LLViewerEventRecorder::instance().getLoggingStatus(); BOOST_FOREACH(LLView* viewp, mChildList) { + if (!viewp) + { + continue; + } + // only views that are themselves visible will have their overall visibility affected by their ancestors old_visibility=viewp->getVisible(); @@ -807,7 +832,7 @@ LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask) LLView* LLView::childFromPoint(S32 x, S32 y, bool recur) { if (!getVisible()) - return false; + return NULL; BOOST_FOREACH(LLView* viewp, mChildList) { @@ -1887,6 +1912,7 @@ class CompareByTabOrder class SortByTabOrder : public LLQuerySorter, public LLSingleton<SortByTabOrder> { + LLSINGLETON_EMPTY_CTOR(SortByTabOrder); /*virtual*/ void sort(LLView * parent, LLView::child_list_t &children) const { children.sort(CompareByTabOrder(parent->getTabOrder(), parent->getDefaultTabGroup())); @@ -1910,6 +1936,7 @@ const LLViewQuery & LLView::getTabOrderQuery() // This class is only used internally by getFocusRootsQuery below. class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton<LLFocusRootsFilter> { + LLSINGLETON_EMPTY_CTOR(LLFocusRootsFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const { return filterResult_t(view->isCtrl() && view->isFocusRoot(), !view->isFocusRoot()); diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h index 375efcc3de870ab83ca2c8590fa651dafdebc18d..d1059d55deb75bdfecbc46b83cc44711e66ad013 100644 --- a/indra/llui/llviewereventrecorder.h +++ b/indra/llui/llviewereventrecorder.h @@ -44,13 +44,10 @@ class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder> { - - public: - - LLViewerEventRecorder(); // TODO Protect constructor better if we can (not happy in private section) - could add a factory... - we are singleton + LLSINGLETON(LLViewerEventRecorder); ~LLViewerEventRecorder(); - + public: void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y, std::string mName); void setMouseLocalCoords(S32 x,S32 y); void setMouseGlobalCoords(S32 x,S32 y); diff --git a/indra/llui/llviewquery.h b/indra/llui/llviewquery.h index 9044c4ff29c16d7d016e4f9853ff834ca67d9b9b..21bb1be26f8d5c86a17e19c569446d79ecbebf8d 100644 --- a/indra/llui/llviewquery.h +++ b/indra/llui/llviewquery.h @@ -54,31 +54,37 @@ class LLQuerySorter class LLLeavesFilter : public LLQueryFilter, public LLSingleton<LLLeavesFilter> { + LLSINGLETON_EMPTY_CTOR(LLLeavesFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLRootsFilter : public LLQueryFilter, public LLSingleton<LLRootsFilter> { + LLSINGLETON_EMPTY_CTOR(LLRootsFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLVisibleFilter : public LLQueryFilter, public LLSingleton<LLVisibleFilter> { + LLSINGLETON_EMPTY_CTOR(LLVisibleFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLEnabledFilter : public LLQueryFilter, public LLSingleton<LLEnabledFilter> { + LLSINGLETON_EMPTY_CTOR(LLEnabledFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLTabStopFilter : public LLQueryFilter, public LLSingleton<LLTabStopFilter> { + LLSINGLETON_EMPTY_CTOR(LLTabStopFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLCtrlFilter : public LLQueryFilter, public LLSingleton<LLCtrlFilter> { + LLSINGLETON_EMPTY_CTOR(LLCtrlFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index ad2a39cab7f0082f84520bfc1bd0b8156c9bc1a1..eb0eac8194def07f180a18aa5d758ecd3b49ce21 100644 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -41,7 +41,9 @@ class LLView; // lookup widget type by name class LLWidgetTypeRegistry : public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLWidgetTypeRegistry); +}; // global static instance for registering all widget types @@ -51,7 +53,9 @@ typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t; class LLChildRegistryRegistry : public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLChildRegistryRegistry); +}; class LLXSDWriter : public LLInitParam::Parser { @@ -60,7 +64,7 @@ class LLXSDWriter : public LLInitParam::Parser void writeXSD(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } - + /*virtual*/ std::string getCurrentFileName() { return LLStringUtil::null; } LLXSDWriter(); ~LLXSDWriter(); @@ -98,6 +102,7 @@ LOG_CLASS(LLXUIParser); typedef LLInitParam::Parser::name_stack_t name_stack_t; /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ std::string getCurrentFileName() { return mCurFileName; } /*virtual*/ void parserWarning(const std::string& message); /*virtual*/ void parserError(const std::string& message); @@ -200,6 +205,7 @@ LOG_CLASS(LLSimpleXUIParser); virtual ~LLSimpleXUIParser(); /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ std::string getCurrentFileName() { return mCurFileName; } /*virtual*/ void parserWarning(const std::string& message); /*virtual*/ void parserError(const std::string& message); diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp old mode 100644 new mode 100755 index f01178c374c6fac0c30026c6c9100979e5d7842c..338be1808dd84d174d0293c15a93e8c740f9f944 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -31,6 +31,7 @@ #include "llcachename.h" #include "lluuid.h" #include "message.h" +#include "llpounceable.h" #include <string> @@ -165,7 +166,7 @@ LLFontGL* LLFontGL::getFontDefault() char const* const _PREHASH_AgentData = (char *)"AgentData"; char const* const _PREHASH_AgentID = (char *)"AgentID"; -LLMessageSystem* gMessageSystem = NULL; +LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; // // Stub implementation for LLMessageSystem diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 233fb6da23451ee3bdc02410a8581352f303d79b..119cbebc8146f693a69fcacef545605a28a9a1ff 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -28,7 +28,7 @@ #include "linden_common.h" #include "../llurlentry.h" #include "../lluictrl.h" -#include "llurlentry_stub.cpp" +//#include "llurlentry_stub.cpp" #include "lltut.h" #include "../lluicolortable.h" #include "../llrender/lluiimage.h" @@ -49,6 +49,7 @@ // // } +/*==========================================================================*| typedef std::map<std::string, LLControlGroup*> settings_map_t; settings_map_t LLUI::sSettingGroups; @@ -83,6 +84,7 @@ S32 LLUIImage::getHeight() const { return 0; } +|*==========================================================================*/ namespace tut { diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 5f4fb8f4a00fdab8c332def5c3f708cfa71b241f..86a15f2ef2c4e1a9a6764fb4a2e55d3b4fdddf1c 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -531,6 +531,13 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd case LL_PATH_PER_ACCOUNT_CHAT_LOGS: prefix = getPerAccountChatLogsDir(); + if (prefix.empty()) + { + // potentially directory was not set yet + // intentionally return a blank string to the caller + LL_DEBUGS("LLDir") << "Conversation log directory is not yet set" << LL_ENDL; + return std::string(); + } break; case LL_PATH_LOGS: diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp index 4038c924654487e00cbdb8504fdef98d040061a1..e776b84a12da93e280ff530c0f99650d1110b36a 100644 --- a/indra/llvfs/lldir_mac.cpp +++ b/indra/llvfs/lldir_mac.cpp @@ -94,7 +94,7 @@ LLDir_Mac::LLDir_Mac() // MBW -- This keeps the mac application from finding other things. // If this is really for skins, it should JUST apply to skins. - U32 build_dir_pos = mExecutableDir.rfind("/build-darwin-"); + std::string::size_type build_dir_pos = mExecutableDir.rfind("/build-darwin-"); if (build_dir_pos != std::string::npos) { // ...we're in a dev checkout diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp index 1cc0e819db5e30ab75b5dede39c30aa7d33753dc..db0eac703189747d3a0623d38e8cacbd6f8631c5 100644 --- a/indra/llvfs/llvfs.cpp +++ b/indra/llvfs/llvfs.cpp @@ -2114,6 +2114,17 @@ void LLVFS::dumpFiles() LL_INFOS() << "Extracted " << files_extracted << " files out of " << mFileBlocks.size() << LL_ENDL; } +time_t LLVFS::creationTime() +{ + llstat data_file_stat; + int errors = LLFile::stat(mDataFilename, &data_file_stat); + if (0 == errors) + { + return data_file_stat.st_ctime; + } + return 0; +} + //============================================================================ // protected //============================================================================ diff --git a/indra/llvfs/llvfs.h b/indra/llvfs/llvfs.h index 39f31a221b9143c19fe529aa9433d04640b8cd53..dca5ff4ad5f9a3ac88ca32c9006ed573ae328ed4 100644 --- a/indra/llvfs/llvfs.h +++ b/indra/llvfs/llvfs.h @@ -127,6 +127,7 @@ class LLVFS void dumpStatistics(); void listFiles(); void dumpFiles(); + time_t creationTime(); protected: void removeFileBlock(LLVFSFileBlock *fileblock); diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h index faa5d3abb71e2049e33d03d76fde6145fa130673..6daf1ac55b98c6f080c49deb483d34d7ff8e934d 100644 --- a/indra/llwindow/llappdelegate-objc.h +++ b/indra/llwindow/llappdelegate-objc.h @@ -41,7 +41,7 @@ @property (retain) NSString *currentInputLanguage; -- (void) mainLoop; +- (void) oneFrame; - (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent; - (void) languageUpdated; - (bool) romanScript; diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index d00d9ab47ea1caa2d0a8347f4fbefc13ba4ebe64..0d1a47408bb6e6bd9a47043dee4cf9c26cbf3f42 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -113,7 +113,7 @@ class LLDragDropWin32Target: PVOID data = GlobalLock( stgmed.hGlobal ); mDropUrl = std::string( (char*)data ); // XXX MAJOR MAJOR HACK! - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mAppWindowHandle, GWL_USERDATA); + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); if (NULL != window_imp) { LLCoordGL gl_coord( 0, 0 ); @@ -168,7 +168,7 @@ class LLDragDropWin32Target: if ( mAllowDrop ) { // XXX MAJOR MAJOR HACK! - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mAppWindowHandle, GWL_USERDATA); + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); if (NULL != window_imp) { LLCoordGL gl_coord( 0, 0 ); @@ -215,7 +215,7 @@ class LLDragDropWin32Target: HRESULT __stdcall DragLeave( void ) { // XXX MAJOR MAJOR HACK! - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mAppWindowHandle, GWL_USERDATA); + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); if (NULL != window_imp) { LLCoordGL gl_coord( 0, 0 ); @@ -232,7 +232,7 @@ class LLDragDropWin32Target: if ( mAllowDrop ) { // window impl stored in Window data (neat!) - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong( mAppWindowHandle, GWL_USERDATA ); + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( mAppWindowHandle, GWLP_USERDATA ); if ( NULL != window_imp ) { POINT pt_client; diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 0a30f4c807fefa91ca85edf89ab2bfc455584aec..a05ba8cbbaea578e0069bd918d9e950e41fa4427 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -166,6 +166,8 @@ class LLWindow : public LLInstanceTracker<LLWindow> // Provide native key event data virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); } + // Get system UI size based on DPI (for 96 DPI UI size should be 1.0) + virtual F32 getSystemUISize() { return 1.0; } protected: LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags); virtual ~LLWindow(); diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index d2afb3f91b304ad1621e1020692fae5c5983f77d..7e90ade423c402df0bbc50f893df4b115cb28cdd 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -175,6 +175,11 @@ BOOL LLWindowCallbacks::handleDeviceChange(LLWindow *window) return FALSE; } +BOOL LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height) +{ + return FALSE; +} + void LLWindowCallbacks::handlePingWatchdog(LLWindow *window, const char * msg) { diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 6a7137e5933fd5e21cb817db96bfdeb64a2c1d01..47d5a18858b45724747663bc77ac9b474a9cf748 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -65,6 +65,7 @@ class LLWindowCallbacks 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); enum DragNDropAction { DNDA_START_TRACKING = 0,// Start tracking an incoming drag diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index c22f3382fb3fca5dc08a3c55f527ecc4752adf31..b06cd2c184ec61488d54e024c931cac20ace1fca 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -69,7 +69,7 @@ typedef const NativeKeyEventData * NSKeyEventRef; // These are defined in llappviewermacosx.cpp. bool initViewer(); void handleQuit(); -bool runMainLoop(); +bool pumpMainLoop(); void initMainLoop(); void cleanupViewer(); void handleUrl(const char* url); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 875ffe4cd43c02db968708e53844e87d5ed02afe..301ae7f9c4ee7d2c0620ce2f46134a935332306d 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -60,24 +60,50 @@ #include <dinput.h> #include <Dbt.h.> -// culled from winuser.h -#ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */ -const S32 WM_MOUSEWHEEL = 0x020A; -#endif -#ifndef WHEEL_DELTA /* Added to be compatible with later SDK's */ -const S32 WHEEL_DELTA = 120; /* Value for rolling one detent */ -#endif const S32 MAX_MESSAGE_PER_UPDATE = 20; const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; const F32 ICON_FLASH_TIME = 0.5f; +#ifndef WM_DPICHANGED +#define WM_DPICHANGED 0x02E0 +#endif + extern BOOL gDebugWindowProc; LPWSTR gIconResource = IDI_APPLICATION; LLW32MsgCallback gAsyncMsgCallback = NULL; +#ifndef DPI_ENUMS_DECLARED + +typedef enum PROCESS_DPI_AWARENESS { + PROCESS_DPI_UNAWARE = 0, + PROCESS_SYSTEM_DPI_AWARE = 1, + PROCESS_PER_MONITOR_DPI_AWARE = 2 +} PROCESS_DPI_AWARENESS; + +typedef enum MONITOR_DPI_TYPE { + MDT_EFFECTIVE_DPI = 0, + MDT_ANGULAR_DPI = 1, + MDT_RAW_DPI = 2, + MDT_DEFAULT = MDT_EFFECTIVE_DPI +} MONITOR_DPI_TYPE; + +#endif + +typedef HRESULT(STDAPICALLTYPE *SetProcessDpiAwarenessType)(_In_ PROCESS_DPI_AWARENESS value); + +typedef HRESULT(STDAPICALLTYPE *GetProcessDpiAwarenessType)( + _In_ HANDLE hprocess, + _Out_ PROCESS_DPI_AWARENESS *value); + +typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)( + _In_ HMONITOR hmonitor, + _In_ MONITOR_DPI_TYPE dpiType, + _Out_ UINT *dpiX, + _Out_ UINT *dpiY); + // // LLWindowWin32 // @@ -759,7 +785,7 @@ void LLWindowWin32::close() LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; // Don't process events in our mainWindowProc any longer. - SetWindowLong(mWindowHandle, GWL_USERDATA, NULL); + SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, NULL); // Make sure we don't leave a blank toolbar button. ShowWindow(mWindowHandle, SW_HIDE); @@ -1538,7 +1564,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO LL_DEBUGS("Window") << "Keeping vertical sync" << LL_ENDL; } - SetWindowLong(mWindowHandle, GWL_USERDATA, (U32)this); + SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, (LONG_PTR)this); // register this window as handling drag/drop events from the OS DragAcceptFiles( mWindowHandle, TRUE ); @@ -1850,7 +1876,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // This is to avoid triggering double click teleport after returning focus (see MAINT-3786). static bool sHandleDoubleClick = true; - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(h_wnd, GWL_USERDATA); + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( h_wnd, GWLP_USERDATA ); if (NULL != window_imp) @@ -2593,6 +2619,26 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ return 0; } + + case WM_DPICHANGED: + { + LPRECT lprc_new_scale; + F32 new_scale = F32(LOWORD(w_param)) / F32(USER_DEFAULT_SCREEN_DPI); + lprc_new_scale = (LPRECT)l_param; + S32 new_width = lprc_new_scale->right - lprc_new_scale->left; + S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top; + if (window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height)) + { + SetWindowPos(h_wnd, + HWND_TOP, + lprc_new_scale->left, + lprc_new_scale->top, + new_width, + new_height, + SWP_NOZORDER | SWP_NOACTIVATE); + } + return 0; + } case WM_SETFOCUS: window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS"); @@ -3878,6 +3924,92 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result) return FALSE; } +//static +void LLWindowWin32::setDPIAwareness() +{ + HMODULE hShcore = LoadLibrary(L"shcore.dll"); + if (hShcore != NULL) + { + SetProcessDpiAwarenessType pSPDA; + pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness"); + if (pSPDA) + { + + HRESULT hr = pSPDA(PROCESS_PER_MONITOR_DPI_AWARE); + if (hr != S_OK) + { + LL_WARNS() << "SetProcessDpiAwareness() function returned an error. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL; + } + } + FreeLibrary(hShcore); + } + else + { + LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL; + } +} + +F32 LLWindowWin32::getSystemUISize() +{ + float scale_value = 0; + HWND hWnd = (HWND)getPlatformWindow(); + HDC hdc = GetDC(hWnd); + HMONITOR hMonitor; + HANDLE hProcess = GetCurrentProcess(); + PROCESS_DPI_AWARENESS dpi_awareness; + + HMODULE hShcore = LoadLibrary(L"shcore.dll"); + + if (hShcore != NULL) + { + GetProcessDpiAwarenessType pGPDA; + pGPDA = (GetProcessDpiAwarenessType)GetProcAddress(hShcore, "GetProcessDpiAwareness"); + GetDpiForMonitorType pGDFM; + pGDFM = (GetDpiForMonitorType)GetProcAddress(hShcore, "GetDpiForMonitor"); + if (pGPDA != NULL && pGDFM != NULL) + { + pGPDA(hProcess, &dpi_awareness); + if (dpi_awareness == PROCESS_PER_MONITOR_DPI_AWARE) + { + POINT pt; + UINT dpix = 0, dpiy = 0; + HRESULT hr = E_FAIL; + RECT rect; + + GetWindowRect(hWnd, &rect); + // Get the DPI for the monitor, on which the center of window is displayed and set the scaling factor + pt.x = (rect.left + rect.right) / 2; + pt.y = (rect.top + rect.bottom) / 2; + hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); + hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy); + if (hr == S_OK) + { + scale_value = F32(dpix) / F32(USER_DEFAULT_SCREEN_DPI); + } + else + { + LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL; + scale_value = 1.0f; + } + } + else + { + LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL; + scale_value = 1.0f; + } + } + FreeLibrary(hShcore); + } + else + { + LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL; + scale_value = F32(GetDeviceCaps(hdc, LOGPIXELSX)) / F32(USER_DEFAULT_SCREEN_DPI); + } + + ReleaseDC(hWnd, hdc); + return scale_value; +} + //static std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList() { diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 1a775eadaf46caad3648f1bd8eb3d8cda35c21a6..39ef9b31a4e1ca8f16881e0fbd60c931c01fd867 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -110,10 +110,12 @@ class LLWindowWin32 : public LLWindow /*virtual*/ void interruptLanguageTextInput(); /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); + /*virtual*/ F32 getSystemUISize(); + LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); static std::vector<std::string> getDynamicFallbackFontList(); - + static void setDPIAwareness(); protected: LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, diff --git a/indra/mac_crash_logger/llcrashloggermac.cpp b/indra/mac_crash_logger/llcrashloggermac.cpp index 3149fad6e8732a59312f868b21ec189607960262..ec3616e26a93a173c052407a62c0e46cae31b3ea 100644 --- a/indra/mac_crash_logger/llcrashloggermac.cpp +++ b/indra/mac_crash_logger/llcrashloggermac.cpp @@ -64,7 +64,7 @@ void LLCrashLoggerMac::gatherPlatformSpecificFiles() { } -bool LLCrashLoggerMac::mainLoop() +bool LLCrashLoggerMac::frame() { if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND) diff --git a/indra/mac_crash_logger/llcrashloggermac.h b/indra/mac_crash_logger/llcrashloggermac.h index 6d8f63ecac0570c8e8000a111568c384c191bfc3..05ef8c9f53976161c8ac392a9ea8f095a64ac75d 100644 --- a/indra/mac_crash_logger/llcrashloggermac.h +++ b/indra/mac_crash_logger/llcrashloggermac.h @@ -37,7 +37,7 @@ class LLCrashLoggerMac : public LLCrashLogger LLCrashLoggerMac(void); ~LLCrashLoggerMac(void); virtual bool init(); - virtual bool mainLoop(); + virtual bool frame(); virtual bool cleanup(); virtual void gatherPlatformSpecificFiles(); }; diff --git a/indra/mac_crash_logger/mac_crash_logger.cpp b/indra/mac_crash_logger/mac_crash_logger.cpp index 95d4e65207d8930d114cf75eecb1ac70426b18f6..54e41a1954d927894dc394d2112841e2550903d0 100644 --- a/indra/mac_crash_logger/mac_crash_logger.cpp +++ b/indra/mac_crash_logger/mac_crash_logger.cpp @@ -49,7 +49,7 @@ int main(int argc, char **argv) { // return NSApplicationMain(argc, (const char **)argv); } - app.mainLoop(); + app.frame(); app.cleanup(); LL_INFOS() << "Crash reporter finished normally." << LL_ENDL; diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt index 24eb3947b489f074ada8bcbf5feb938527d3de4a..1eadce825e580dc0bc84ba9bc0818d1e8a2c4c35 100644 --- a/indra/media_plugins/CMakeLists.txt +++ b/indra/media_plugins/CMakeLists.txt @@ -4,15 +4,15 @@ add_subdirectory(base) if (LINUX) add_subdirectory(gstreamer010) + add_subdirectory(libvlc) endif (LINUX) -if (WINDOWS OR DARWIN) - add_subdirectory(quicktime) +if (DARWIN) add_subdirectory(cef) -endif (WINDOWS OR DARWIN) + add_subdirectory(libvlc) +endif (DARWIN) if (WINDOWS) - add_subdirectory(winmmshim) + add_subdirectory(cef) + add_subdirectory(libvlc) endif (WINDOWS) - -### add_subdirectory(example) diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt index 7367b9e5e654911c75a0bf8a9fca789a1c260378..70c81d40236562776d3ff3893ce68897724e1d2f 100644 --- a/indra/media_plugins/base/CMakeLists.txt +++ b/indra/media_plugins/base/CMakeLists.txt @@ -28,13 +28,13 @@ include_directories(SYSTEM ### media_plugin_base -if(NOT WORD_SIZE EQUAL 32) +if(NOT ADDRESS_SIZE EQUAL 32) if(WINDOWS) - add_definitions(/FIXED:NO) + ##add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) -endif(NOT WORD_SIZE EQUAL 32) +endif(NOT ADDRESS_SIZE EQUAL 32) set(media_plugin_base_SOURCE_FILES media_plugin_base.cpp diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index db471c7906c9900b9a4e77e06c475126d6fc7243..1c41fadcaf15bb9a2f2abda26d46133265922b44 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -34,22 +34,18 @@ include_directories(SYSTEM ### media_plugin_cef -if(NOT WORD_SIZE EQUAL 32) +if(NOT ADDRESS_SIZE EQUAL 32) if(WINDOWS) - add_definitions(/FIXED:NO) + ##add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) -endif(NOT WORD_SIZE EQUAL 32) +endif(NOT ADDRESS_SIZE EQUAL 32) set(media_plugin_cef_SOURCE_FILES media_plugin_cef.cpp ) -set(media_plugin_cef_HEADER_FILES - volume_catcher.h - ) - set (media_plugin_cef_LINK_LIBRARIES ${LLPLUGIN_LIBRARIES} ${MEDIA_PLUGIN_BASE_LIBRARIES} @@ -58,22 +54,6 @@ set (media_plugin_cef_LINK_LIBRARIES ${PLUGIN_API_WINDOWS_LIBRARIES}) -# Select which VolumeCatcher implementation to use -if (LINUX) - message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n" - " Please create a volume_catcher implementation for this platform.") - -elseif (DARWIN) - list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher.cpp) - find_library(CORESERVICES_LIBRARY CoreServices) - find_library(AUDIOUNIT_LIBRARY AudioUnit) - list(APPEND media_plugin_cef_LINK_LIBRARIES - ${CORESERVICES_LIBRARY} # for Component Manager calls - ${AUDIOUNIT_LIBRARY} # for AudioUnit calls - ) -elseif (WINDOWS) - list(APPEND media_plugin_cef_SOURCE_FILES windows_volume_catcher.cpp) -endif (LINUX) set_source_files_properties(${media_plugin_cef_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) @@ -97,8 +77,8 @@ if (WINDOWS) set_target_properties( media_plugin_cef PROPERTIES - LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /LTCG /NODEFAULTLIB:LIBCMT" - LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD" + LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /LTCG /NODEFAULTLIB:LIBCMT /IGNORE:4099" + LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD /IGNORE:4099" ) endif (WINDOWS) diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 8d9d1dd975e12b8fe7e1ee8a66d32a8863343872..eaba71a6ad018f43792e3a9eadc822a315efcd66 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -39,7 +39,7 @@ #include "boost/function.hpp" #include "boost/bind.hpp" #include "llCEFLib.h" -#include "volume_catcher.h" +//#include "volume_catcher.h" //////////////////////////////////////////////////////////////////////////////// // @@ -99,7 +99,11 @@ class MediaPluginCEF : std::string mPickedFile; LLCEFLib* mLLCEFLib; - VolumeCatcher mVolumeCatcher; + U8 *mPopupBuffer; + U32 mPopupW; + U32 mPopupH; + U32 mPopupX; + U32 mPopupY; }; //////////////////////////////////////////////////////////////////////////////// @@ -127,12 +131,19 @@ MediaPluginBase(host_send_func, host_user_data) mCookiePath = ""; mPickedFile = ""; mLLCEFLib = new LLCEFLib(); + + mPopupBuffer = NULL; + mPopupW = 0; + mPopupH = 0; + mPopupX = 0; + mPopupY = 0; } //////////////////////////////////////////////////////////////////////////////// // MediaPluginCEF::~MediaPluginCEF() { + delete[] mPopupBuffer; } //////////////////////////////////////////////////////////////////////////////// @@ -155,20 +166,28 @@ void MediaPluginCEF::postDebugMessage(const std::string& msg) // void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup) { - if (mPixels && pixels) + if( is_popup ) + { + delete mPopupBuffer; + mPopupBuffer = NULL; + mPopupH = 0; + mPopupW = 0; + mPopupX = 0; + mPopupY = 0; + } + + if( mPixels && pixels ) { if (is_popup) { - for (int line = 0; line < height; ++line) + if( width > 0 && height> 0 ) { - int inverted_y = mHeight - y - height; - int src = line * width * mDepth; - int dst = (inverted_y + line) * mWidth * mDepth + x * mDepth; - - if (dst + width * mDepth < mWidth * mHeight * mDepth) - { - memcpy(mPixels + dst, pixels + src, width * mDepth); - } + mPopupBuffer = new U8[ width * height * mDepth ]; + memcpy( mPopupBuffer, pixels, width * height * mDepth ); + mPopupH = height; + mPopupW = width; + mPopupX = x; + mPopupY = mHeight - y - height; } } else @@ -177,6 +196,23 @@ void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, { memcpy(mPixels, pixels, mWidth * mHeight * mDepth); } + if( mPopupBuffer && mPopupH && mPopupW ) + { + U32 bufferSize = mWidth * mHeight * mDepth; + U32 popupStride = mPopupW * mDepth; + U32 bufferStride = mWidth * mDepth; + int dstY = mPopupY; + + int src = 0; + int dst = dstY * mWidth * mDepth + mPopupX * mDepth; + + for( int line = 0; dst + popupStride < bufferSize && line < mPopupH; ++line ) + { + memcpy( mPixels + dst, mPopupBuffer + src, popupStride ); + src += popupStride; + dst += bufferStride; + } + } } setDirty(0, 0, mWidth, mHeight); @@ -394,7 +430,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { mLLCEFLib->update(); - mVolumeCatcher.pump(); // this seems bad but unless the state changes (it won't until we figure out // how to get CEF to tell us if copy/cut/paste is available) then this function // will return immediately @@ -463,6 +498,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string) LLCEFLib::LLCEFLibSettings settings; settings.initial_width = 1024; settings.initial_height = 1024; + // The LLCEFLibSettings struct in the Windows 32-bit + // llceflib's build 500907 does not have a page_zoom_factor + // member. Set below. + //settings.page_zoom_factor = message_in.getValueReal("factor"); settings.plugins_enabled = mPluginsEnabled; settings.media_stream_enabled = false; // MAINT-6060 - WebRTC media removed until we can add granualrity/query UI settings.javascript_enabled = mJavascriptEnabled; @@ -479,6 +518,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string) // if this fails, the media system in viewer will put up a message } + // now we can set page zoom factor + mLLCEFLib->setPageZoom(message_in.getValueReal("factor")); + // Plugin gets to decide the texture parameters to use. mDepth = 4; LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); @@ -559,6 +601,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string) S32 x = message_in.getValueS32("x"); S32 y = message_in.getValueS32("y"); + y = mHeight - y; + // only even send left mouse button events to LLCEFLib // (partially prompted by crash in OS X CEF when sending right button events) // we catch the right click in viewer and display our own context menu anyway @@ -879,7 +923,6 @@ void MediaPluginCEF::checkEditState() void MediaPluginCEF::setVolume(F32 vol) { - mVolumeCatcher.setVolume(vol); } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/media_plugins/cef/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp index 0cfb810906b578e4ae3466b32ca0a8c808dd9132..6953ad3ab8a03aaf34ad6a876513cc83a10759ff 100644 --- a/indra/media_plugins/cef/windows_volume_catcher.cpp +++ b/indra/media_plugins/cef/windows_volume_catcher.cpp @@ -31,55 +31,25 @@ #include "llsingleton.h" class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl> { -friend LLSingleton<VolumeCatcherImpl>; + LLSINGLETON(VolumeCatcherImpl); + // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. + ~VolumeCatcherImpl(); + public: void setVolume(F32 volume); void setPan(F32 pan); private: - // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. - VolumeCatcherImpl(); - ~VolumeCatcherImpl(); - - typedef void (WINAPI *set_volume_func_t)(F32); - typedef void (WINAPI *set_mute_func_t)(bool); - - set_volume_func_t mSetVolumeFunc; - set_mute_func_t mSetMuteFunc; - - // tests if running on Vista, 7, 8 + once in CTOR - bool isWindowsVistaOrHigher(); - F32 mVolume; F32 mPan; bool mSystemIsVistaOrHigher; }; -bool VolumeCatcherImpl::isWindowsVistaOrHigher() -{ - OSVERSIONINFO osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osvi); - return osvi.dwMajorVersion >= 6; -} - VolumeCatcherImpl::VolumeCatcherImpl() : mVolume(1.0f), // default volume is max mPan(0.f) // default pan is centered { - mSystemIsVistaOrHigher = isWindowsVistaOrHigher(); - - if ( ! mSystemIsVistaOrHigher ) - { - HMODULE handle = ::LoadLibrary(L"winmm.dll"); - if(handle) - { - mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume"); - mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute"); - } - } } VolumeCatcherImpl::~VolumeCatcherImpl() @@ -90,26 +60,12 @@ void VolumeCatcherImpl::setVolume(F32 volume) { mVolume = volume; - if ( mSystemIsVistaOrHigher ) - { - // set both left/right to same volume - // TODO: use pan value to set independently - DWORD left_channel = (DWORD)(mVolume * 65535.0f); - DWORD right_channel = (DWORD)(mVolume * 65535.0f); - DWORD hw_volume = left_channel << 16 | right_channel; - ::waveOutSetVolume(NULL, hw_volume); - } - else - { - if (mSetMuteFunc) - { - mSetMuteFunc(volume == 0.f); - } - if (mSetVolumeFunc) - { - mSetVolumeFunc(mVolume); - } - } + // set both left/right to same volume + // TODO: use pan value to set independently + DWORD left_channel = (DWORD)(mVolume * 65535.0f); + DWORD right_channel = (DWORD)(mVolume * 65535.0f); + DWORD hw_volume = left_channel << 16 | right_channel; + ::waveOutSetVolume(NULL, hw_volume); } void VolumeCatcherImpl::setPan(F32 pan) diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt index 171645ef0467e068197fd9df71dde2745235971e..d2a17b1d76727eb1a5950367ac54c0a08ce3c18b 100644 --- a/indra/media_plugins/example/CMakeLists.txt +++ b/indra/media_plugins/example/CMakeLists.txt @@ -32,13 +32,13 @@ include_directories(SYSTEM ### media_plugin_example -if(NOT WORD_SIZE EQUAL 32) +if(NOT ADDRESS_SIZE EQUAL 32) if(WINDOWS) - add_definitions(/FIXED:NO) + ##add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) -endif(NOT WORD_SIZE EQUAL 32) +endif(NOT ADDRESS_SIZE EQUAL 32) set(media_plugin_example_SOURCE_FILES media_plugin_example.cpp diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt index 447f6e06895ec7d5cbf69ab85bd03513664e178d..6d18814b1e8a44fe828ea5b3f6416867da8deb43 100644 --- a/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -33,13 +33,13 @@ include_directories(SYSTEM ### media_plugin_gstreamer010 -if(NOT WORD_SIZE EQUAL 32) +if(NOT ADDRESS_SIZE EQUAL 32) if(WINDOWS) - add_definitions(/FIXED:NO) + ##add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) -endif(NOT WORD_SIZE EQUAL 32) +endif(NOT ADDRESS_SIZE EQUAL 32) set(media_plugin_gstreamer010_SOURCE_FILES media_plugin_gstreamer010.cpp diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..72159f9f69dc7b6fabd4fa2edfd05da094c19a48 --- /dev/null +++ b/indra/media_plugins/libvlc/CMakeLists.txt @@ -0,0 +1,96 @@ +# -*- cmake -*- + +project(media_plugin_libvlc) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLPlugin) +include(LLMath) +include(LLRender) +include(LLWindow) +include(Linking) +include(PluginAPI) +include(MediaPluginBase) +include(OpenGL) + +include(LibVLCPlugin) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} + ${VLC_INCLUDE_DIR} +) +include_directories(SYSTEM + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ) + + +### media_plugin_libvlc + +if(NOT ADDRESS_SIZE EQUAL 32) + if(WINDOWS) + ##add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif(NOT ADDRESS_SIZE EQUAL 32) + +set(media_plugin_libvlc_SOURCE_FILES + media_plugin_libvlc.cpp + ) + +add_library(media_plugin_libvlc + SHARED + ${media_plugin_libvlc_SOURCE_FILES} +) + +target_link_libraries(media_plugin_libvlc + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${VLC_PLUGIN_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES} +) + +add_dependencies(media_plugin_libvlc + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} +##${LLCOMMON_LIBRARIES} + # Just say 'llcommon' here. LLCOMMON_LIBRARIES is specified for use in + # target_link_libraries: it includes several Boost libraries, which are + # absolutely NOT dependencies in the sense intended here. Those Boost + # library macros, in turn, specify 'debug' and 'optimized' and a different + # library name for each, producing several wordy errors: + # Policy CMP0046 is not set: Error on non-existent dependency in + # add_dependencies. + # Really, the only dependency we should mention from LLCOMMON_LIBRARIES is + # llcommon itself. + llcommon +) + +if (WINDOWS) + set_target_properties( + media_plugin_libvlc + PROPERTIES + LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /LTCG /NODEFAULTLIB:LIBCMT" + ) +endif (WINDOWS) + +if (DARWIN) + # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name + set_target_properties( + media_plugin_libvlc + PROPERTIES + PREFIX "" + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_NAME_DIR "@executable_path" + LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" + ) + +endif (DARWIN) diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..048e7675f8a6006d010db3376af99b224dc0ffb8 --- /dev/null +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -0,0 +1,625 @@ +/** +* @file media_plugin_libvlc.cpp +* @brief LibVLC plugin for LLMedia API plugin system +* +* @cond +* $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 +*/ + +#include "linden_common.h" + +#include "llgl.h" +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#include "vlc/vlc.h" +#include "vlc/libvlc_version.h" + +//////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginLibVLC : + public MediaPluginBase +{ +public: + MediaPluginLibVLC(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginLibVLC(); + + /*virtual*/ void receiveMessage(const char* message_string); + +private: + bool init(); + + void initVLC(); + void playMedia(); + void resetVLC(); + void setVolume(const F64 volume); + void updateTitle(const char* title); + + static void* lock(void* data, void** p_pixels); + static void unlock(void* data, void* id, void* const* raw_pixels); + static void display(void* data, void* id); + + /*virtual*/ void setDirty(int left, int top, int right, int bottom) /* override, but that is not supported in gcc 4.6 */; + + static void eventCallbacks(const libvlc_event_t* event, void* ptr); + + libvlc_instance_t* mLibVLC; + libvlc_media_t* mLibVLCMedia; + libvlc_media_player_t* mLibVLCMediaPlayer; + + struct mLibVLCContext + { + unsigned char* texture_pixels; + libvlc_media_player_t* mp; + MediaPluginLibVLC* parent; + }; + struct mLibVLCContext mLibVLCCallbackContext; + + std::string mURL; + F64 mCurVolume; + + bool mIsLooping; + + float mCurTime; + float mDuration; + EStatus mVlcStatus; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginLibVLC::MediaPluginLibVLC(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : +MediaPluginBase(host_send_func, host_user_data) +{ + mTextureWidth = 0; + mTextureHeight = 0; + mWidth = 0; + mHeight = 0; + mDepth = 4; + mPixels = 0; + + mLibVLC = 0; + mLibVLCMedia = 0; + mLibVLCMediaPlayer = 0; + + mCurVolume = 0.0; + + mIsLooping = false; + + mCurTime = 0.0; + mDuration = 0.0; + + mURL = std::string(); + + mVlcStatus = STATUS_NONE; + setStatus(STATUS_NONE); +} + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginLibVLC::~MediaPluginLibVLC() +{ +} + +///////////////////////////////////////////////////////////////////////////////// +// +void* MediaPluginLibVLC::lock(void* data, void** p_pixels) +{ + struct mLibVLCContext* context = (mLibVLCContext*)data; + + *p_pixels = context->texture_pixels; + + return NULL; +} + +///////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::unlock(void* data, void* id, void* const* raw_pixels) +{ + // nothing to do here for the moment + // we *could* modify pixels here to, for example, Y flip, but this is done with + // a VLC video filter transform. +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::display(void* data, void* id) +{ + struct mLibVLCContext* context = (mLibVLCContext*)data; + + context->parent->setDirty(0, 0, context->parent->mWidth, context->parent->mHeight); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::initVLC() +{ + char const* vlc_argv[] = + { + "--no-xlib", + "--video-filter=transform{type=vflip}", // MAINT-6578 Y flip textures in plugin vs client + }; + +#if LL_DARWIN + setenv("VLC_PLUGIN_PATH", ".", 1); +#endif + + int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); + mLibVLC = libvlc_new(vlc_argc, vlc_argv); + + if (!mLibVLC) + { + // for the moment, if this fails, the plugin will fail and + // the media sub-system will tell the viewer something went wrong. + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::resetVLC() +{ + libvlc_media_player_stop(mLibVLCMediaPlayer); + libvlc_media_player_release(mLibVLCMediaPlayer); + libvlc_release(mLibVLC); +} + +//////////////////////////////////////////////////////////////////////////////// +// *virtual* +void MediaPluginLibVLC::setDirty(int left, int top, int right, int bottom) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); + + message.setValueS32("left", left); + message.setValueS32("top", top); + message.setValueS32("right", right); + message.setValueS32("bottom", bottom); + + message.setValueReal("current_time", mCurTime); + message.setValueReal("duration", mDuration); + message.setValueReal("current_rate", 1.0f); + + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) +{ + MediaPluginLibVLC* parent = (MediaPluginLibVLC*)ptr; + if (parent == 0) + { + return; + } + + switch (event->type) + { + case libvlc_MediaPlayerOpening: + parent->mVlcStatus = STATUS_LOADING; + break; + + case libvlc_MediaPlayerPlaying: + parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f; + parent->mVlcStatus = STATUS_PLAYING; + break; + + case libvlc_MediaPlayerPaused: + parent->mVlcStatus = STATUS_PAUSED; + break; + + case libvlc_MediaPlayerStopped: + parent->mVlcStatus = STATUS_DONE; + break; + + case libvlc_MediaPlayerEndReached: + parent->mVlcStatus = STATUS_DONE; + break; + + case libvlc_MediaPlayerEncounteredError: + parent->mVlcStatus = STATUS_ERROR; + break; + + case libvlc_MediaPlayerTimeChanged: + parent->mCurTime = (float)libvlc_media_player_get_time(parent->mLibVLCMediaPlayer) / 1000.0f; + break; + + case libvlc_MediaPlayerPositionChanged: + break; + + case libvlc_MediaPlayerLengthChanged: + parent->mDuration = (float)libvlc_media_get_duration(parent->mLibVLCMedia) / 1000.0f; + break; + + case libvlc_MediaPlayerTitleChanged: + { + char* title = libvlc_media_get_meta(parent->mLibVLCMedia, libvlc_meta_Title); + if (title) + { + parent->updateTitle(title); + } + } + break; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::playMedia() +{ + if (mURL.length() == 0) + { + return; + } + + if (mLibVLCMediaPlayer) + { + // stop listening to events while we reset things + libvlc_event_manager_t* em = libvlc_media_player_event_manager(mLibVLCMediaPlayer); + if (em) + { + libvlc_event_detach(em, libvlc_MediaPlayerOpening, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerPlaying, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerPaused, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerStopped, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerEndReached, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerEncounteredError, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerTimeChanged, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerPositionChanged, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerLengthChanged, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerTitleChanged, eventCallbacks, NULL); + }; + + libvlc_media_player_stop(mLibVLCMediaPlayer); + libvlc_media_player_release(mLibVLCMediaPlayer); + + mLibVLCMediaPlayer = 0; + } + + if (mLibVLCMedia) + { + libvlc_media_release(mLibVLCMedia); + + mLibVLCMedia = 0; + } + + mLibVLCMedia = libvlc_media_new_location(mLibVLC, mURL.c_str()); + if (!mLibVLCMedia) + { + mLibVLCMediaPlayer = 0; + setStatus(STATUS_ERROR); + return; + } + + mLibVLCMediaPlayer = libvlc_media_player_new_from_media(mLibVLCMedia); + if (!mLibVLCMediaPlayer) + { + setStatus(STATUS_ERROR); + return; + } + + // listen to events + libvlc_event_manager_t* em = libvlc_media_player_event_manager(mLibVLCMediaPlayer); + if (em) + { + libvlc_event_attach(em, libvlc_MediaPlayerOpening, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerPlaying, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerPaused, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerStopped, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerEndReached, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerEncounteredError, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerPositionChanged, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerLengthChanged, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerTitleChanged, eventCallbacks, this); + } + + mLibVLCCallbackContext.parent = this; + mLibVLCCallbackContext.texture_pixels = mPixels; + mLibVLCCallbackContext.mp = mLibVLCMediaPlayer; + + // Send a "navigate begin" event. + // This is really a browser message but the QuickTime plugin did it and + // the media system relies on this message to update internal state so we must send it too + // Note: see "navigate_complete" message below too + // https://jira.secondlife.com/browse/MAINT-6528 + LLPluginMessage message_begin(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); + message_begin.setValue("uri", mURL); + message_begin.setValueBoolean("history_back_available", false); + message_begin.setValueBoolean("history_forward_available", false); + sendMessage(message_begin); + + // volume level gets set before VLC is initialized (thanks media system) so we have to record + // it in mCurVolume and set it again here so that volume levels are correctly initialized + setVolume(mCurVolume); + + setStatus(STATUS_LOADED); + + libvlc_video_set_callbacks(mLibVLCMediaPlayer, lock, unlock, display, &mLibVLCCallbackContext); + libvlc_video_set_format(mLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth); + + // note this relies on the "set_loop" message arriving before the "start" (play) one + // but that appears to always be the case + if (mIsLooping) + { + libvlc_media_add_option(mLibVLCMedia, "input-repeat=-1"); + } + + libvlc_media_player_play(mLibVLCMediaPlayer); + + // send a "location_changed" message - this informs the media system + // that a new URL is the 'current' one and is used extensively. + // Again, this is really a browser message but we will use it here. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); + message.setValue("uri", mURL); + sendMessage(message); + + // Send a "navigate complete" event. + // This is really a browser message but the QuickTime plugin did it and + // the media system relies on this message to update internal state so we must send it too + // Note: see "navigate_begin" message above too + // https://jira.secondlife.com/browse/MAINT-6528 + LLPluginMessage message_complete(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); + message_complete.setValue("uri", mURL); + message_complete.setValueS32("result_code", 200); + message_complete.setValue("result_string", "OK"); + sendMessage(message_complete); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::updateTitle(const char* title) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", title); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::setVolume(const F64 volume) +{ + mCurVolume = volume; + + if (mLibVLCMediaPlayer) + { + int result = libvlc_audio_set_volume(mLibVLCMediaPlayer, (int)(volume * 100)); + if (result != 0) + { + // volume wasn't set but not much to be done here + } + } + else + { + // volume change was requested but VLC wasn't ready. + // that's okay thought because we saved the value in mCurVolume and + // the next volume change after the VLC system is initilzied will set it + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::receiveMessage(const char* message_string) +{ + LLPluginMessage message_in; + + if (message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if (message_name == "init") + { + initVLC(); + + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; + message.setValueLLSD("versions", versions); + + std::ostringstream s; + s << "LibVLC plugin "; + s << LIBVLC_VERSION_MAJOR; + s << "."; + s << LIBVLC_VERSION_MINOR; + s << "."; + s << LIBVLC_VERSION_REVISION; + + message.setValue("plugin_version", s.str()); + sendMessage(message); + } + else if (message_name == "idle") + { + setStatus(mVlcStatus); + } + else if (message_name == "cleanup") + { + resetVLC(); + } + else if (message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if (message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + if (mPixels == iter->second.mAddress) + { + libvlc_media_player_stop(mLibVLCMediaPlayer); + libvlc_media_player_release(mLibVLCMediaPlayer); + mLibVLCMediaPlayer = 0; + + mPixels = NULL; + mTextureSegmentName.clear(); + } + mSharedSegments.erase(iter); + } + else + { + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if (message_name == "init") + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("default_width", 1024); + message.setValueS32("default_height", 1024); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueU32("format", GL_BGRA_EXT); + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", true); + sendMessage(message); + } + else if (message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + if (!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + mPixels = (unsigned char*)iter->second.mAddress; + mWidth = width; + mHeight = height; + mTextureWidth = texture_width; + mTextureHeight = texture_height; + + playMedia(); + }; + }; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + } + else if (message_name == "load_uri") + { + mURL = message_in.getValue("uri"); + playMedia(); + } + } + else + if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if (message_name == "stop") + { + if (mLibVLCMediaPlayer) + { + libvlc_media_player_stop(mLibVLCMediaPlayer); + } + } + else if (message_name == "start") + { + if (mLibVLCMediaPlayer) + { + libvlc_media_player_play(mLibVLCMediaPlayer); + } + } + else if (message_name == "pause") + { + if (mLibVLCMediaPlayer) + { + libvlc_media_player_set_pause(mLibVLCMediaPlayer, 1); + } + } + else if (message_name == "seek") + { + if (mDuration > 0) + { + F64 normalized_offset = message_in.getValueReal("time") / mDuration; + libvlc_media_player_set_position(mLibVLCMediaPlayer, normalized_offset); + } + } + else if (message_name == "set_loop") + { + mIsLooping = true; + } + else if (message_name == "set_volume") + { + // volume comes in 0 -> 1.0 + F64 volume = message_in.getValueReal("volume"); + setVolume(volume); + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool MediaPluginLibVLC::init() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", "LibVLC Plugin"); + sendMessage(message); + + return true; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, + void* host_user_data, + LLPluginInstance::sendMessageFunction *plugin_send_func, + void **plugin_user_data) +{ + MediaPluginLibVLC* self = new MediaPluginLibVLC(host_send_func, host_user_data); + *plugin_send_func = MediaPluginLibVLC::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} diff --git a/indra/media_plugins/quicktime/CMakeLists.txt b/indra/media_plugins/quicktime/CMakeLists.txt deleted file mode 100644 index c5615145be1e05d3b1650d83b758c59b8213848a..0000000000000000000000000000000000000000 --- a/indra/media_plugins/quicktime/CMakeLists.txt +++ /dev/null @@ -1,90 +0,0 @@ -# -*- cmake -*- - -project(media_plugin_quicktime) - -include(00-Common) -include(LLCommon) -include(LLImage) -include(LLPlugin) -include(LLMath) -include(LLRender) -include(LLWindow) -include(Linking) -include(PluginAPI) -include(MediaPluginBase) -include(OpenGL) -include(QuickTimePlugin) -include(Boost) - -include_directories( - ${LLPLUGIN_INCLUDE_DIRS} - ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} -) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) - -if (DARWIN) - include(CMakeFindFrameworks) - find_library(CARBON_LIBRARY Carbon) -endif (DARWIN) - - -### media_plugin_quicktime - -set(media_plugin_quicktime_SOURCE_FILES - media_plugin_quicktime.cpp - ) - -add_library(media_plugin_quicktime - SHARED - ${media_plugin_quicktime_SOURCE_FILES} -) - -target_link_libraries(media_plugin_quicktime - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${QUICKTIME_LIBRARY} - ${PLUGIN_API_WINDOWS_LIBRARIES} -) - -if (WINDOWS) - set_target_properties( - media_plugin_quicktime - PROPERTIES - LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT" - LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD" - ) -endif (WINDOWS) - -if (QUICKTIME) - - add_definitions(-DLL_QUICKTIME_ENABLED=1) - - if (DARWIN) - # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name - set_target_properties( - media_plugin_quicktime - PROPERTIES - PREFIX "" - BUILD_WITH_INSTALL_RPATH 1 - INSTALL_NAME_DIR "@executable_path" - LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" - ) - -# We use a bunch of deprecated system APIs. - set_source_files_properties( - media_plugin_quicktime.cpp PROPERTIES - COMPILE_FLAGS -Wno-deprecated-declarations - ) - find_library(CARBON_LIBRARY Carbon) - target_link_libraries(media_plugin_quicktime ${CARBON_LIBRARY}) - endif (DARWIN) -endif (QUICKTIME) - diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp deleted file mode 100644 index 7ef5a0fe44ed4b14321c70ba1ff3a198b3dd51c0..0000000000000000000000000000000000000000 --- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ /dev/null @@ -1,1084 +0,0 @@ -/** - * @file media_plugin_quicktime.cpp - * @brief QuickTime plugin for LLMedia API plugin system - * - * @cond - * $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 - */ - -#include "linden_common.h" - -#include "llgl.h" - -#include "llplugininstance.h" -#include "llpluginmessage.h" -#include "llpluginmessageclasses.h" -#include "media_plugin_base.h" - -#if LL_QUICKTIME_ENABLED - -#if defined(LL_DARWIN) -#include <QuickTime/QuickTime.h> -#elif defined(LL_WINDOWS) -#include "llwin32headers.h" -#include "MacTypes.h" -#include "QTML.h" -#include "Movies.h" -#include "QDoffscreen.h" -#include "FixMath.h" -#include "QTLoadLibraryUtils.h" -#endif - - - -// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint -//////////////////////////////////////////////////////////////////////////////// -// -class MediaPluginQuickTime : public MediaPluginBase -{ -public: - MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); - ~MediaPluginQuickTime(); - - /* virtual */ void receiveMessage(const char *message_string); - -private: - - int mNaturalWidth; - int mNaturalHeight; - Movie mMovieHandle; - GWorldPtr mGWorldHandle; - ComponentInstance mMovieController; - int mCurVolume; - bool mMediaSizeChanging; - bool mIsLooping; - std::string mMovieTitle; - bool mReceivedTitle; - const int mMinWidth; - const int mMaxWidth; - const int mMinHeight; - const int mMaxHeight; - F64 mPlayRate; - std::string mNavigateURL; - - enum ECommand { - COMMAND_NONE, - COMMAND_STOP, - COMMAND_PLAY, - COMMAND_FAST_FORWARD, - COMMAND_FAST_REWIND, - COMMAND_PAUSE, - COMMAND_SEEK, - }; - ECommand mCommand; - - // Override this to add current time and duration to the message - /*virtual*/ void setDirty(int left, int top, int right, int bottom) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); - - message.setValueS32("left", left); - message.setValueS32("top", top); - message.setValueS32("right", right); - message.setValueS32("bottom", bottom); - - if(mMovieHandle) - { - message.setValueReal("current_time", getCurrentTime()); - message.setValueReal("duration", getDuration()); - message.setValueReal("current_rate", Fix2X(GetMovieRate(mMovieHandle))); - } - - sendMessage(message); - } - - - static Rect rectFromSize(int width, int height) - { - Rect result; - - - result.left = 0; - result.top = 0; - result.right = width; - result.bottom = height; - - return result; - } - - Fixed getPlayRate(void) - { - Fixed result; - if(mPlayRate == 0.0f) - { - // Default to the movie's preferred rate - result = GetMoviePreferredRate(mMovieHandle); - if(result == 0) - { - // Don't return a 0 play rate, ever. - std::cerr << "Movie's preferred rate is 0, forcing to 1.0." << std::endl; - result = X2Fix(1.0f); - } - } - else - { - result = X2Fix(mPlayRate); - } - - return result; - } - - void load( const std::string url ) - { - - if ( url.empty() ) - return; - - // Stop and unload any existing movie before starting another one. - unload(); - - setStatus(STATUS_LOADING); - - //In case std::string::c_str() makes a copy of the url data, - //make sure there is memory to hold it before allocating memory for handle. - //if fails, NewHandleClear(...) should return NULL. - const char* url_string = url.c_str() ; - Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) ); - - if ( NULL == handle || noErr != MemError() || NULL == *handle ) - { - setStatus(STATUS_ERROR); - return; - } - - BlockMove( url_string, *handle, ( Size )( url.length() + 1 ) ); - - OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType ); - DisposeHandle( handle ); - if ( noErr != err ) - { - setStatus(STATUS_ERROR); - return; - }; - - mNavigateURL = url; - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); - message.setValue("uri", mNavigateURL); - sendMessage(message); - - // do pre-roll actions (typically fired for streaming movies but not always) - PrePrerollMovie( mMovieHandle, 0, getPlayRate(), moviePrePrerollCompleteCallback, ( void * )this ); - - Rect movie_rect = rectFromSize(mWidth, mHeight); - - // make a new movie controller - mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie ); - - // movie controller - MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this ); - - SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize ); - - // function that gets called when a frame is drawn - SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this ); - - setStatus(STATUS_LOADED); - - sizeChanged(); - }; - - bool unload() - { - // new movie and have to get title again - mReceivedTitle = false; - - if ( mMovieHandle ) - { - StopMovie( mMovieHandle ); - if ( mMovieController ) - { - MCMovieChanged( mMovieController, mMovieHandle ); - }; - }; - - if ( mMovieController ) - { - MCSetActionFilterWithRefCon( mMovieController, NULL, (long)this ); - DisposeMovieController( mMovieController ); - mMovieController = NULL; - }; - - if ( mMovieHandle ) - { - SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, nil, ( long )this ); - DisposeMovie( mMovieHandle ); - mMovieHandle = NULL; - }; - - mGWorldHandle = NULL; - - setStatus(STATUS_NONE); - - return true; - } - - bool navigateTo( const std::string url ) - { - unload(); - load( url ); - - return true; - }; - - bool sizeChanged() - { - if ( ! mMovieHandle ) - return false; - - // Check to see whether the movie's natural size has updated - { - int width, height; - getMovieNaturalSize(&width, &height); - if((width != 0) && (height != 0) && ((width != mNaturalWidth) || (height != mNaturalHeight))) - { - mNaturalWidth = width; - mNaturalHeight = height; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); - message.setValue("name", mTextureSegmentName); - message.setValueS32("width", width); - message.setValueS32("height", height); - sendMessage(message); - //std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl; - } - } - - - // sanitize destination size - Rect dest_rect = rectFromSize(mWidth, mHeight); - - // media depth won't change - int depth_bits = mDepth * 8; - long rowbytes = mDepth * mTextureWidth; - - if(mPixels != NULL) - { - // We have pixels. Set up a GWorld pointing at the texture. - OSErr result = QTNewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes); - if ( noErr != result ) - { - // TODO: unrecoverable?? throw exception? return something? - return false; - } - } - else - { - // We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally. - Rect tempRect = rectFromSize(1, 1); - OSErr result = QTNewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0); - if ( noErr != result ) - { - // TODO: unrecoverable?? throw exception? return something? - return false; - } - } - - SetMovieGWorld( mMovieHandle, mGWorldHandle, NULL ); - - // Set up the movie display matrix - { - // scale movie to fit rect and invert vertically to match opengl image format - MatrixRecord transform; - SetIdentityMatrix( &transform ); // transforms are additive so start from identify matrix - double scaleX = (double) mWidth / mNaturalWidth; - double scaleY = -1.0 * (double) mHeight / mNaturalHeight; - double centerX = mWidth / 2.0; - double centerY = mHeight / 2.0; - ScaleMatrix( &transform, X2Fix( scaleX ), X2Fix( scaleY ), X2Fix( centerX ), X2Fix( centerY ) ); - SetMovieMatrix( mMovieHandle, &transform ); - } - - // update movie controller - if ( mMovieController ) - { - MCSetControllerPort( mMovieController, mGWorldHandle ); - MCPositionController( mMovieController, &dest_rect, &dest_rect, - mcTopLeftMovie | mcPositionDontInvalidate ); - MCMovieChanged( mMovieController, mMovieHandle ); - } - - - // Emit event with size change so the calling app knows about it too - // TODO: - //LLMediaEvent event( this ); - //mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); - - return true; - } - static Boolean mcActionFilterCallBack( MovieController mc, short action, void *params, long ref ) - { - Boolean result = false; - - MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; - - switch( action ) - { - // handle window resizing - case mcActionControllerSizeChanged: - // Ensure that the movie draws correctly at the new size - self->sizeChanged(); - break; - - // Block any movie controller actions that open URLs. - case mcActionLinkToURL: - case mcActionGetNextURL: - case mcActionLinkToURLExtended: - // Prevent the movie controller from handling the message - result = true; - break; - - default: - break; - }; - - return result; - }; - - static OSErr movieDrawingCompleteCallback( Movie call_back_movie, long ref ) - { - MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; - - // IMPORTANT: typically, a consumer who is observing this event will set a flag - // when this event is fired then render later. Be aware that the media stream - // can change during this period - dimensions, depth, format etc. - //LLMediaEvent event( self ); -// self->updateQuickTime(); - // TODO ^^^ - - - if ( self->mWidth > 0 && self->mHeight > 0 ) - self->setDirty( 0, 0, self->mWidth, self->mHeight ); - - return noErr; - }; - - static void moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref ) - { - MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; - - // TODO: - //LLMediaEvent event( self ); - //self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event ); - - // Send a "navigate complete" event. - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); - message.setValue("uri", self->mNavigateURL); - message.setValueS32("result_code", 200); - message.setValue("result_string", "OK"); - self->sendMessage(message); - }; - - - void rewind() - { - GoToBeginningOfMovie( mMovieHandle ); - MCMovieChanged( mMovieController, mMovieHandle ); - }; - - bool processState() - { - if ( mCommand == COMMAND_PLAY ) - { - if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING || mStatus == STATUS_DONE ) - { - long state = GetMovieLoadState( mMovieHandle ); - - if ( state >= kMovieLoadStatePlaythroughOK ) - { - // if the movie is at the end (generally because it reached it naturally) - // and we play is requested, jump back to the start of the movie. - // note: this is different from having loop flag set. - if ( IsMovieDone( mMovieHandle ) ) - { - Fixed rate = X2Fix( 0.0 ); - MCDoAction( mMovieController, mcActionPlay, (void*)rate ); - rewind(); - }; - - MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() ); - MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); - setStatus(STATUS_PLAYING); - mCommand = COMMAND_NONE; - }; - }; - } - else - if ( mCommand == COMMAND_STOP ) - { - if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED || mStatus == STATUS_DONE ) - { - if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) - { - Fixed rate = X2Fix( 0.0 ); - MCDoAction( mMovieController, mcActionPlay, (void*)rate ); - rewind(); - - setStatus(STATUS_LOADED); - mCommand = COMMAND_NONE; - }; - }; - } - else - if ( mCommand == COMMAND_PAUSE ) - { - if ( mStatus == STATUS_PLAYING ) - { - if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) - { - Fixed rate = X2Fix( 0.0 ); - MCDoAction( mMovieController, mcActionPlay, (void*)rate ); - setStatus(STATUS_PAUSED); - mCommand = COMMAND_NONE; - }; - }; - }; - - return true; - }; - - void play(F64 rate) - { - mPlayRate = rate; - mCommand = COMMAND_PLAY; - }; - - void stop() - { - mCommand = COMMAND_STOP; - }; - - void pause() - { - mCommand = COMMAND_PAUSE; - }; - - void getMovieNaturalSize(int *movie_width, int *movie_height) - { - Rect rect; - - GetMovieNaturalBoundsRect( mMovieHandle, &rect ); - - int width = ( rect.right - rect.left ); - int height = ( rect.bottom - rect.top ); - - // make sure width and height fall in valid range - if ( width < mMinWidth ) - width = mMinWidth; - - if ( width > mMaxWidth ) - width = mMaxWidth; - - if ( height < mMinHeight ) - height = mMinHeight; - - if ( height > mMaxHeight ) - height = mMaxHeight; - - // return the new rect - *movie_width = width; - *movie_height = height; - } - - void updateQuickTime(int milliseconds) - { - if ( ! mMovieHandle ) - return; - - if ( ! mMovieController ) - return; - - // this wasn't required in 1.xx viewer but we have to manually - // work the Windows message pump now - #if defined( LL_WINDOWS ) - MSG msg; - while ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) - { - GetMessage( &msg, NULL, 0, 0 ); - TranslateMessage( &msg ); - DispatchMessage( &msg ); - }; - #endif - - MCIdle( mMovieController ); - - if ( ! mGWorldHandle ) - return; - - if ( mMediaSizeChanging ) - return; - - // update state machine - processState(); - - // see if title arrived and if so, update member variable with contents - checkTitle(); - - // QT call to see if we are at the end - can't do with controller - if ( IsMovieDone( mMovieHandle ) ) - { - // special code for looping - need to rewind at the end of the movie - if ( mIsLooping ) - { - // go back to start - rewind(); - - if ( mMovieController ) - { - // kick off new play - MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() ); - - // set the volume - MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); - }; - } - else - { - if(mStatus == STATUS_PLAYING) - { - setStatus(STATUS_DONE); - } - } - } - - }; - - void seek( F64 time ) - { - if ( mMovieController ) - { - TimeRecord when; - when.scale = GetMovieTimeScale( mMovieHandle ); - when.base = 0; - - // 'time' is in (floating point) seconds. The timebase time will be in 'units', where - // there are 'scale' units per second. - SInt64 raw_time = ( SInt64 )( time * (double)( when.scale ) ); - - when.value.hi = ( SInt32 )( raw_time >> 32 ); - when.value.lo = ( SInt32 )( ( raw_time & 0x00000000FFFFFFFF ) ); - - MCDoAction( mMovieController, mcActionGoToTime, &when ); - }; - }; - - F64 getLoadedDuration() - { - TimeValue duration; - if(GetMaxLoadedTimeInMovie( mMovieHandle, &duration ) != noErr) - { - // If GetMaxLoadedTimeInMovie returns an error, return the full duration of the movie. - duration = GetMovieDuration( mMovieHandle ); - } - TimeValue scale = GetMovieTimeScale( mMovieHandle ); - - return (F64)duration / (F64)scale; - }; - - F64 getDuration() - { - TimeValue duration = GetMovieDuration( mMovieHandle ); - TimeValue scale = GetMovieTimeScale( mMovieHandle ); - - return (F64)duration / (F64)scale; - }; - - F64 getCurrentTime() - { - TimeValue curr_time = GetMovieTime( mMovieHandle, 0 ); - TimeValue scale = GetMovieTimeScale( mMovieHandle ); - - return (F64)curr_time / (F64)scale; - }; - - void setVolume( F64 volume ) - { - mCurVolume = (short)(volume * ( double ) 0x100 ); - - if ( mMovieController ) - { - MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); - }; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - void update(int milliseconds = 0) - { - updateQuickTime(milliseconds); - }; - - //////////////////////////////////////////////////////////////////////////////// - // - void mouseDown( int x, int y ) - { - }; - - //////////////////////////////////////////////////////////////////////////////// - // - void mouseUp( int x, int y ) - { - }; - - //////////////////////////////////////////////////////////////////////////////// - // - void mouseMove( int x, int y ) - { - }; - - //////////////////////////////////////////////////////////////////////////////// - // - void keyPress( unsigned char key ) - { - }; - - //////////////////////////////////////////////////////////////////////////////// - // Grab movie title into mMovieTitle - should be called repeatedly - // until it returns true since movie title takes a while to become - // available. - const bool getMovieTitle() - { - // grab meta data from movie - QTMetaDataRef media_data_ref; - OSErr result = QTCopyMovieMetaData( mMovieHandle, &media_data_ref ); - if ( noErr != result ) - return false; - - // look up "Display Name" in meta data - OSType meta_data_key = kQTMetaDataCommonKeyDisplayName; - QTMetaDataItem item = kQTMetaDataItemUninitialized; - result = (OSErr)QTMetaDataGetNextItem( media_data_ref, kQTMetaDataStorageFormatWildcard, - 0, kQTMetaDataKeyFormatCommon, - (const UInt8 *)&meta_data_key, - sizeof( meta_data_key ), &item ); - if ( noErr != result ) - return false; - - // find the size of the title - ByteCount size; - result = (OSErr)QTMetaDataGetItemValue( media_data_ref, item, NULL, 0, &size ); - if ( noErr != result || size <= 0 /*|| size > 1024 FIXME: arbitrary limit */ ) - return false; - - // allocate some space and grab it - UInt8* item_data = new UInt8[ size + 1 ]; - memset( item_data, 0, ( size + 1 ) * sizeof( UInt8 ) ); - result = (OSErr)QTMetaDataGetItemValue( media_data_ref, item, item_data, size, NULL ); - if ( noErr != result ) - { - delete [] item_data; - return false; - }; - - // save it - if ( strlen( (char*)item_data ) ) - mMovieTitle = std::string( (char* )item_data ); - else - mMovieTitle = ""; - - // clean up - delete [] item_data; - - return true; - }; - - // called regularly to see if title changed - void checkTitle() - { - // we did already receive title so keep checking - if ( ! mReceivedTitle ) - { - // grab title from movie meta data - if ( getMovieTitle() ) - { - // pass back to host application - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); - message.setValue("name", mMovieTitle ); - sendMessage( message ); - - // stop looking once we find a title for this movie. - // TODO: this may to be reset if movie title changes - // during playback but this is okay for now - mReceivedTitle = true; - }; - }; - }; -}; - -MediaPluginQuickTime::MediaPluginQuickTime( - LLPluginInstance::sendMessageFunction host_send_func, - void *host_user_data ) : - MediaPluginBase(host_send_func, host_user_data), - mMinWidth( 0 ), - mMaxWidth( 2048 ), - mMinHeight( 0 ), - mMaxHeight( 2048 ) -{ -// std::cerr << "MediaPluginQuickTime constructor" << std::endl; - - mNaturalWidth = -1; - mNaturalHeight = -1; - mMovieHandle = 0; - mGWorldHandle = 0; - mMovieController = 0; - mCurVolume = 0x99; - mMediaSizeChanging = false; - mIsLooping = false; - mMovieTitle = std::string(); - mReceivedTitle = false; - mCommand = COMMAND_NONE; - mPlayRate = 0.0f; - mStatus = STATUS_NONE; -} - -MediaPluginQuickTime::~MediaPluginQuickTime() -{ -// std::cerr << "MediaPluginQuickTime destructor" << std::endl; - - ExitMovies(); - -#ifdef LL_WINDOWS - TerminateQTML(); -// std::cerr << "QuickTime closing down" << std::endl; -#endif -} - - -void MediaPluginQuickTime::receiveMessage(const char *message_string) -{ -// std::cerr << "MediaPluginQuickTime::receiveMessage: received message: \"" << message_string << "\"" << std::endl; - LLPluginMessage message_in; - - if(message_in.parse(message_string) >= 0) - { - std::string message_class = message_in.getClass(); - std::string message_name = message_in.getName(); - if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) - { - if(message_name == "init") - { - LLPluginMessage message("base", "init_response"); - LLSD versions = LLSD::emptyMap(); - versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; - // Normally a plugin would only specify one of these two subclasses, but this is a demo... - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; - message.setValueLLSD("versions", versions); - - #ifdef LL_WINDOWS - - // QuickTime 7.6.4 has an issue (that was not present in 7.6.2) with initializing QuickTime - // according to this article: http://lists.apple.com/archives/QuickTime-API/2009/Sep/msg00097.html - // The solution presented there appears to work. - QTLoadLibrary("qtcf.dll"); - - // main initialization for QuickTime - only required on Windows - OSErr result = InitializeQTML( 0L ); - if ( result != noErr ) - { - //TODO: If no QT on Windows, this fails - respond accordingly. - } - else - { - //std::cerr << "QuickTime initialized" << std::endl; - }; - #endif - - // required for both Windows and Mac - EnterMovies(); - - std::string plugin_version = "QuickTime media plugin, QuickTime version "; - - long version = 0; - Gestalt( gestaltQuickTimeVersion, &version ); - std::ostringstream codec( "" ); - codec << std::hex << version << std::dec; - plugin_version += codec.str(); - message.setValue("plugin_version", plugin_version); - sendMessage(message); - } - else if(message_name == "idle") - { - // no response is necessary here. - F64 time = message_in.getValueReal("time"); - - // Convert time to milliseconds for update() - update((int)(time * 1000.0f)); - } - else if(message_name == "cleanup") - { - // TODO: clean up here - LLPluginMessage message("base", "goodbye"); - sendMessage(message); - } - else if(message_name == "shm_added") - { - SharedSegmentInfo info; - info.mAddress = message_in.getValuePointer("address"); - info.mSize = (size_t)message_in.getValueS32("size"); - std::string name = message_in.getValue("name"); -// std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory added, name: " << name -// << ", size: " << info.mSize -// << ", address: " << info.mAddress -// << std::endl; - - mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - - } - else if(message_name == "shm_remove") - { - std::string name = message_in.getValue("name"); - -// std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory remove, name = " << name << std::endl; - - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - if(mPixels == iter->second.mAddress) - { - // This is the currently active pixel buffer. Make sure we stop drawing to it. - mPixels = NULL; - mTextureSegmentName.clear(); - - // Make sure the movie GWorld is no longer pointed at the shared segment. - sizeChanged(); - } - mSharedSegments.erase(iter); - } - else - { -// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown shared memory region!" << std::endl; - } - - // Send the response so it can be cleaned up. - LLPluginMessage message("base", "shm_remove_response"); - message.setValue("name", name); - sendMessage(message); - } - else - { -// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown base message: " << message_name << std::endl; - } - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) - { - if(message_name == "init") - { - // This is the media init message -- all necessary data for initialization should have been received. - - // Plugin gets to decide the texture parameters to use. - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - #if defined(LL_WINDOWS) - // Values for Windows - mDepth = 3; - message.setValueU32("format", GL_RGB); - message.setValueU32("type", GL_UNSIGNED_BYTE); - - // We really want to pad the texture width to a multiple of 32 bytes, but since we're using 3-byte pixels, it doesn't come out even. - // Padding to a multiple of 3*32 guarantees it'll divide out properly. - message.setValueU32("padding", 32 * 3); - #else - // Values for Mac - mDepth = 4; - message.setValueU32("format", GL_BGRA_EXT); - #ifdef __BIG_ENDIAN__ - message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV ); - #else - message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8); - #endif - - // Pad texture width to a multiple of 32 bytes, to line up with cache lines. - message.setValueU32("padding", 32); - #endif - message.setValueS32("depth", mDepth); - message.setValueU32("internalformat", GL_RGB); - message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. - message.setValueBoolean("allow_downsample", true); - sendMessage(message); - } - else if(message_name == "size_change") - { - std::string name = message_in.getValue("name"); - S32 width = message_in.getValueS32("width"); - S32 height = message_in.getValueS32("height"); - S32 texture_width = message_in.getValueS32("texture_width"); - S32 texture_height = message_in.getValueS32("texture_height"); - - //std::cerr << "---->Got size change instruction from application with name: " << name << " - size is " << width << " x " << height << std::endl; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); - message.setValue("name", name); - message.setValueS32("width", width); - message.setValueS32("height", height); - message.setValueS32("texture_width", texture_width); - message.setValueS32("texture_height", texture_height); - sendMessage(message); - - if(!name.empty()) - { - // Find the shared memory region with this name - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { -// std::cerr << "%%% Got size change, new size is " << width << " by " << height << std::endl; -// std::cerr << "%%%% texture size is " << texture_width << " by " << texture_height << std::endl; - - mPixels = (unsigned char*)iter->second.mAddress; - mTextureSegmentName = name; - mWidth = width; - mHeight = height; - - mTextureWidth = texture_width; - mTextureHeight = texture_height; - - mMediaSizeChanging = false; - - sizeChanged(); - - update(); - }; - }; - } - else if(message_name == "load_uri") - { - std::string uri = message_in.getValue("uri"); - load( uri ); - sendStatus(); - } - else if(message_name == "mouse_event") - { - std::string event = message_in.getValue("event"); - S32 x = message_in.getValueS32("x"); - S32 y = message_in.getValueS32("y"); - - if(event == "down") - { - mouseDown(x, y); - } - else if(event == "up") - { - mouseUp(x, y); - } - else if(event == "move") - { - mouseMove(x, y); - }; - }; - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) - { - if(message_name == "stop") - { - stop(); - } - else if(message_name == "start") - { - F64 rate = 0.0; - if(message_in.hasValue("rate")) - { - rate = message_in.getValueReal("rate"); - } - play(rate); - } - else if(message_name == "pause") - { - pause(); - } - else if(message_name == "seek") - { - F64 time = message_in.getValueReal("time"); - seek(time); - } - else if(message_name == "set_loop") - { - bool loop = message_in.getValueBoolean("loop"); - mIsLooping = loop; - } - else if(message_name == "set_volume") - { - F64 volume = message_in.getValueReal("volume"); - setVolume(volume); - } - } - else - { -// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown message class: " << message_class << std::endl; - }; - }; -} - -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) -{ - MediaPluginQuickTime *self = new MediaPluginQuickTime(host_send_func, host_user_data); - *plugin_send_func = MediaPluginQuickTime::staticReceiveMessage; - *plugin_user_data = (void*)self; - - return 0; -} - -#else // LL_QUICKTIME_ENABLED - -// Stubbed-out class with constructor/destructor (necessary or windows linker -// will just think its dead code and optimize it all out) -class MediaPluginQuickTime : public MediaPluginBase -{ -public: - MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); - ~MediaPluginQuickTime(); - /* virtual */ void receiveMessage(const char *message_string); -}; - -MediaPluginQuickTime::MediaPluginQuickTime( - LLPluginInstance::sendMessageFunction host_send_func, - void *host_user_data ) : - MediaPluginBase(host_send_func, host_user_data) -{ - // no-op -} - -MediaPluginQuickTime::~MediaPluginQuickTime() -{ - // no-op -} - -void MediaPluginQuickTime::receiveMessage(const char *message_string) -{ - // no-op -} - -// We're building without quicktime enabled. Just refuse to initialize. -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) -{ - return -1; -} - -#endif // LL_QUICKTIME_ENABLED diff --git a/indra/media_plugins/winmmshim/CMakeLists.txt b/indra/media_plugins/winmmshim/CMakeLists.txt deleted file mode 100644 index 6890589892eef183a14b709242dcbff815010bb5..0000000000000000000000000000000000000000 --- a/indra/media_plugins/winmmshim/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -# -*- cmake -*- - -project(winmm_shim) - -### winmm_shim -# *HACK - override msvcrt implementation (intialized on 00-Common) to be -# statically linked for winmm.dll this relies on vc taking the last flag on -# the command line -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MT") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") - -set(winmm_shim_SOURCE_FILES - forwarding_api.cpp - winmm_shim.cpp - ) - -set(winmm_shim_HEADER_FILES - forwarding_api.h - winmm.def - ) - -list(APPEND winmm_shim_SOURCE_FILES ${winmm_shim_HEADER_FILES}) - -add_library(winmm_shim - SHARED - ${winmm_shim_SOURCE_FILES} -) - -if (WINDOWS) - set_target_properties( - winmm_shim - PROPERTIES - LINK_FLAGS "/MANIFEST:NO" - OUTPUT_NAME "winmm" - ) -endif (WINDOWS) diff --git a/indra/media_plugins/winmmshim/forwarding_api.cpp b/indra/media_plugins/winmmshim/forwarding_api.cpp deleted file mode 100644 index 33f0675028188bc924f7a75eef849c7740fac549..0000000000000000000000000000000000000000 --- a/indra/media_plugins/winmmshim/forwarding_api.cpp +++ /dev/null @@ -1,1627 +0,0 @@ -/** - * @file forwarding_api.cpp - * @brief forwards winmm API calls to real winmm.dll - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "forwarding_api.h" - -CloseDriver_type CloseDriver_orig; -OpenDriver_type OpenDriver_orig; -SendDriverMessage_type SendDriverMessage_orig; -DrvGetModuleHandle_type DrvGetModuleHandle_orig; -GetDriverModuleHandle_type GetDriverModuleHandle_orig; -DefDriverProc_type DefDriverProc_orig; -DriverCallback_type DriverCallback_orig; -mmsystemGetVersion_type mmsystemGetVersion_orig; -sndPlaySoundA_type sndPlaySoundA_orig; -sndPlaySoundW_type sndPlaySoundW_orig; -PlaySoundA_type PlaySoundA_orig; -PlaySoundW_type PlaySoundW_orig; -waveOutGetNumDevs_type waveOutGetNumDevs_orig; -waveOutGetDevCapsA_type waveOutGetDevCapsA_orig; -waveOutGetDevCapsW_type waveOutGetDevCapsW_orig; -waveOutGetVolume_type waveOutGetVolume_orig; -waveOutSetVolume_type waveOutSetVolume_orig; -waveOutGetErrorTextA_type waveOutGetErrorTextA_orig; -waveOutGetErrorTextW_type waveOutGetErrorTextW_orig; -waveOutOpen_type waveOutOpen_orig; -waveOutClose_type waveOutClose_orig; -waveOutPrepareHeader_type waveOutPrepareHeader_orig; -waveOutUnprepareHeader_type waveOutUnprepareHeader_orig; -waveOutWrite_type waveOutWrite_orig; -waveOutPause_type waveOutPause_orig; -waveOutRestart_type waveOutRestart_orig; -waveOutReset_type waveOutReset_orig; -waveOutBreakLoop_type waveOutBreakLoop_orig; -waveOutGetPosition_type waveOutGetPosition_orig; -waveOutGetPitch_type waveOutGetPitch_orig; -waveOutSetPitch_type waveOutSetPitch_orig; -waveOutGetPlaybackRate_type waveOutGetPlaybackRate_orig; -waveOutSetPlaybackRate_type waveOutSetPlaybackRate_orig; -waveOutGetID_type waveOutGetID_orig; -waveOutMessage_type waveOutMessage_orig; -waveInGetNumDevs_type waveInGetNumDevs_orig; -waveInGetDevCapsA_type waveInGetDevCapsA_orig; -waveInGetDevCapsW_type waveInGetDevCapsW_orig; -waveInGetErrorTextA_type waveInGetErrorTextA_orig; -waveInGetErrorTextW_type waveInGetErrorTextW_orig; -waveInOpen_type waveInOpen_orig; -waveInClose_type waveInClose_orig; -waveInPrepareHeader_type waveInPrepareHeader_orig; -waveInUnprepareHeader_type waveInUnprepareHeader_orig; -waveInAddBuffer_type waveInAddBuffer_orig; -waveInStart_type waveInStart_orig; -waveInStop_type waveInStop_orig; -waveInReset_type waveInReset_orig; -waveInGetPosition_type waveInGetPosition_orig; -waveInGetID_type waveInGetID_orig; -waveInMessage_type waveInMessage_orig; -midiOutGetNumDevs_type midiOutGetNumDevs_orig; -midiStreamOpen_type midiStreamOpen_orig; -midiStreamClose_type midiStreamClose_orig; -midiStreamProperty_type midiStreamProperty_orig; -midiStreamPosition_type midiStreamPosition_orig; -midiStreamOut_type midiStreamOut_orig; -midiStreamPause_type midiStreamPause_orig; -midiStreamRestart_type midiStreamRestart_orig; -midiStreamStop_type midiStreamStop_orig; -midiConnect_type midiConnect_orig; -midiDisconnect_type midiDisconnect_orig; -midiOutGetDevCapsA_type midiOutGetDevCapsA_orig; -midiOutGetDevCapsW_type midiOutGetDevCapsW_orig; -midiOutGetVolume_type midiOutGetVolume_orig; -midiOutSetVolume_type midiOutSetVolume_orig; -midiOutGetErrorTextA_type midiOutGetErrorTextA_orig; -midiOutGetErrorTextW_type midiOutGetErrorTextW_orig; -midiOutOpen_type midiOutOpen_orig; -midiOutClose_type midiOutClose_orig; -midiOutPrepareHeader_type midiOutPrepareHeader_orig; -midiOutUnprepareHeader_type midiOutUnprepareHeader_orig; -midiOutShortMsg_type midiOutShortMsg_orig; -midiOutLongMsg_type midiOutLongMsg_orig; -midiOutReset_type midiOutReset_orig; -midiOutCachePatches_type midiOutCachePatches_orig; -midiOutCacheDrumPatches_type midiOutCacheDrumPatches_orig; -midiOutGetID_type midiOutGetID_orig; -midiOutMessage_type midiOutMessage_orig; -midiInGetNumDevs_type midiInGetNumDevs_orig; -midiInGetDevCapsA_type midiInGetDevCapsA_orig; -midiInGetDevCapsW_type midiInGetDevCapsW_orig; -midiInGetErrorTextA_type midiInGetErrorTextA_orig; -midiInGetErrorTextW_type midiInGetErrorTextW_orig; -midiInOpen_type midiInOpen_orig; -midiInClose_type midiInClose_orig; -midiInPrepareHeader_type midiInPrepareHeader_orig; -midiInUnprepareHeader_type midiInUnprepareHeader_orig; -midiInAddBuffer_type midiInAddBuffer_orig; -midiInStart_type midiInStart_orig; -midiInStop_type midiInStop_orig; -midiInReset_type midiInReset_orig; -midiInGetID_type midiInGetID_orig; -midiInMessage_type midiInMessage_orig; -auxGetNumDevs_type auxGetNumDevs_orig; -auxGetDevCapsA_type auxGetDevCapsA_orig; -auxGetDevCapsW_type auxGetDevCapsW_orig; -auxSetVolume_type auxSetVolume_orig; -auxGetVolume_type auxGetVolume_orig; -auxOutMessage_type auxOutMessage_orig; -mixerGetNumDevs_type mixerGetNumDevs_orig; -mixerGetDevCapsA_type mixerGetDevCapsA_orig; -mixerGetDevCapsW_type mixerGetDevCapsW_orig; -mixerOpen_type mixerOpen_orig; -mixerClose_type mixerClose_orig; -mixerMessage_type mixerMessage_orig; -mixerGetLineInfoA_type mixerGetLineInfoA_orig; -mixerGetLineInfoW_type mixerGetLineInfoW_orig; -mixerGetID_type mixerGetID_orig; -mixerGetLineControlsA_type mixerGetLineControlsA_orig; -mixerGetLineControlsW_type mixerGetLineControlsW_orig; -mixerGetControlDetailsA_type mixerGetControlDetailsA_orig; -mixerGetControlDetailsW_type mixerGetControlDetailsW_orig; -mixerSetControlDetails_type mixerSetControlDetails_orig; -mmGetCurrentTask_type mmGetCurrentTask_orig; -mmTaskBlock_type mmTaskBlock_orig; -mmTaskCreate_type mmTaskCreate_orig; -mmTaskSignal_type mmTaskSignal_orig; -mmTaskYield_type mmTaskYield_orig; -timeGetSystemTime_type timeGetSystemTime_orig; -timeGetTime_type timeGetTime_orig; -timeSetEvent_type timeSetEvent_orig; -timeKillEvent_type timeKillEvent_orig; -timeGetDevCaps_type timeGetDevCaps_orig; -timeBeginPeriod_type timeBeginPeriod_orig; -timeEndPeriod_type timeEndPeriod_orig; -joyGetNumDevs_type joyGetNumDevs_orig; -joyConfigChanged_type joyConfigChanged_orig; -joyGetDevCapsA_type joyGetDevCapsA_orig; -joyGetDevCapsW_type joyGetDevCapsW_orig; -joyGetPos_type joyGetPos_orig; -joyGetPosEx_type joyGetPosEx_orig; -joyGetThreshold_type joyGetThreshold_orig; -joyReleaseCapture_type joyReleaseCapture_orig; -joySetCapture_type joySetCapture_orig; -joySetThreshold_type joySetThreshold_orig; -mmioStringToFOURCCA_type mmioStringToFOURCCA_orig; -mmioStringToFOURCCW_type mmioStringToFOURCCW_orig; -mmioInstallIOProcA_type mmioInstallIOProcA_orig; -mmioInstallIOProcW_type mmioInstallIOProcW_orig; -mmioOpenA_type mmioOpenA_orig; -mmioOpenW_type mmioOpenW_orig; -mmioRenameA_type mmioRenameA_orig; -mmioRenameW_type mmioRenameW_orig; -mmioClose_type mmioClose_orig; -mmioRead_type mmioRead_orig; -mmioWrite_type mmioWrite_orig; -mmioSeek_type mmioSeek_orig; -mmioGetInfo_type mmioGetInfo_orig; -mmioSetInfo_type mmioSetInfo_orig; -mmioSetBuffer_type mmioSetBuffer_orig; -mmioFlush_type mmioFlush_orig; -mmioAdvance_type mmioAdvance_orig; -mmioSendMessage_type mmioSendMessage_orig; -mmioDescend_type mmioDescend_orig; -mmioAscend_type mmioAscend_orig; -mmioCreateChunk_type mmioCreateChunk_orig; -mciSendCommandA_type mciSendCommandA_orig; -mciSendCommandW_type mciSendCommandW_orig; -mciSendStringA_type mciSendStringA_orig; -mciSendStringW_type mciSendStringW_orig; -mciGetDeviceIDA_type mciGetDeviceIDA_orig; -mciGetDeviceIDW_type mciGetDeviceIDW_orig; -mciGetDeviceIDFromElementIDA_type mciGetDeviceIDFromElementIDA_orig; -mciGetDeviceIDFromElementIDW_type mciGetDeviceIDFromElementIDW_orig; -mciGetDriverData_type mciGetDriverData_orig; -mciGetErrorStringA_type mciGetErrorStringA_orig; -mciGetErrorStringW_type mciGetErrorStringW_orig; -mciSetDriverData_type mciSetDriverData_orig; -mciDriverNotify_type mciDriverNotify_orig; -mciDriverYield_type mciDriverYield_orig; -mciSetYieldProc_type mciSetYieldProc_orig; -mciFreeCommandResource_type mciFreeCommandResource_orig; -mciGetCreatorTask_type mciGetCreatorTask_orig; -mciGetYieldProc_type mciGetYieldProc_orig; -mciLoadCommandResource_type mciLoadCommandResource_orig; -mciExecute_type mciExecute_orig; - -// grab pointers to function calls in the real DLL -void init_function_pointers(HMODULE winmm_handle) -{ - CloseDriver_orig = (CloseDriver_type)::GetProcAddress(winmm_handle, "CloseDriver"); - OpenDriver_orig = (OpenDriver_type)::GetProcAddress(winmm_handle, "OpenDriver"); - SendDriverMessage_orig = (SendDriverMessage_type)::GetProcAddress(winmm_handle, "SendDriverMessage"); - DrvGetModuleHandle_orig = (DrvGetModuleHandle_type)::GetProcAddress(winmm_handle, "DrvGetModuleHandle"); - GetDriverModuleHandle_orig = (GetDriverModuleHandle_type)::GetProcAddress(winmm_handle, "GetDriverModuleHandle"); - DefDriverProc_orig = (DefDriverProc_type)::GetProcAddress(winmm_handle, "DefDriverProc"); - DriverCallback_orig = (DriverCallback_type)::GetProcAddress(winmm_handle, "DriverCallback"); - mmsystemGetVersion_orig = (mmsystemGetVersion_type)::GetProcAddress(winmm_handle, "mmsystemGetVersion"); - sndPlaySoundA_orig = (sndPlaySoundA_type)::GetProcAddress(winmm_handle, "sndPlaySoundA"); - sndPlaySoundW_orig = (sndPlaySoundW_type)::GetProcAddress(winmm_handle, "sndPlaySoundW"); - PlaySoundA_orig = (PlaySoundA_type)::GetProcAddress(winmm_handle, "PlaySoundA"); - PlaySoundW_orig = (PlaySoundW_type)::GetProcAddress(winmm_handle, "PlaySoundW"); - waveOutGetNumDevs_orig = (waveOutGetNumDevs_type)::GetProcAddress(winmm_handle, "waveOutGetNumDevs"); - waveOutGetDevCapsA_orig = (waveOutGetDevCapsA_type)::GetProcAddress(winmm_handle, "waveOutGetDevCapsA"); - waveOutGetDevCapsW_orig = (waveOutGetDevCapsW_type)::GetProcAddress(winmm_handle, "waveOutGetDevCapsW"); - waveOutGetVolume_orig = (waveOutGetVolume_type)::GetProcAddress(winmm_handle, "waveOutGetVolume"); - waveOutSetVolume_orig = (waveOutSetVolume_type)::GetProcAddress(winmm_handle, "waveOutSetVolume"); - waveOutGetErrorTextA_orig = (waveOutGetErrorTextA_type)::GetProcAddress(winmm_handle, "waveOutGetErrorTextA"); - waveOutGetErrorTextW_orig = (waveOutGetErrorTextW_type)::GetProcAddress(winmm_handle, "waveOutGetErrorTextW"); - waveOutOpen_orig = (waveOutOpen_type)::GetProcAddress(winmm_handle, "waveOutOpen"); - waveOutClose_orig = (waveOutClose_type)::GetProcAddress(winmm_handle, "waveOutClose"); - waveOutPrepareHeader_orig = (waveOutPrepareHeader_type)::GetProcAddress(winmm_handle, "waveOutPrepareHeader"); - waveOutUnprepareHeader_orig = (waveOutUnprepareHeader_type)::GetProcAddress(winmm_handle, "waveOutUnprepareHeader"); - waveOutWrite_orig = (waveOutWrite_type)::GetProcAddress(winmm_handle, "waveOutWrite"); - waveOutPause_orig = (waveOutPause_type)::GetProcAddress(winmm_handle, "waveOutPause"); - waveOutRestart_orig = (waveOutRestart_type)::GetProcAddress(winmm_handle, "waveOutRestart"); - waveOutReset_orig = (waveOutReset_type)::GetProcAddress(winmm_handle, "waveOutReset"); - waveOutBreakLoop_orig = (waveOutBreakLoop_type)::GetProcAddress(winmm_handle, "waveOutBreakLoop"); - waveOutGetPosition_orig = (waveOutGetPosition_type)::GetProcAddress(winmm_handle, "waveOutGetPosition"); - waveOutGetPitch_orig = (waveOutGetPitch_type)::GetProcAddress(winmm_handle, "waveOutGetPitch"); - waveOutSetPitch_orig = (waveOutSetPitch_type)::GetProcAddress(winmm_handle, "waveOutSetPitch"); - waveOutGetPlaybackRate_orig = (waveOutGetPlaybackRate_type)::GetProcAddress(winmm_handle, "waveOutGetPlaybackRate"); - waveOutSetPlaybackRate_orig = (waveOutSetPlaybackRate_type)::GetProcAddress(winmm_handle, "waveOutSetPlaybackRate"); - waveOutGetID_orig = (waveOutGetID_type)::GetProcAddress(winmm_handle, "waveOutGetID"); - waveOutMessage_orig = (waveOutMessage_type)::GetProcAddress(winmm_handle, "waveOutMessage"); - waveInGetNumDevs_orig = (waveInGetNumDevs_type)::GetProcAddress(winmm_handle, "waveInGetNumDevs"); - waveInGetDevCapsA_orig = (waveInGetDevCapsA_type)::GetProcAddress(winmm_handle, "waveInGetDevCapsA"); - waveInGetDevCapsW_orig = (waveInGetDevCapsW_type)::GetProcAddress(winmm_handle, "waveInGetDevCapsW"); - waveInGetErrorTextA_orig = (waveInGetErrorTextA_type)::GetProcAddress(winmm_handle, "waveInGetErrorTextA"); - waveInGetErrorTextW_orig = (waveInGetErrorTextW_type)::GetProcAddress(winmm_handle, "waveInGetErrorTextW"); - waveInOpen_orig = (waveInOpen_type)::GetProcAddress(winmm_handle, "waveInOpen"); - waveInClose_orig = (waveInClose_type)::GetProcAddress(winmm_handle, "waveInClose"); - waveInPrepareHeader_orig = (waveInPrepareHeader_type)::GetProcAddress(winmm_handle, "waveInPrepareHeader"); - waveInUnprepareHeader_orig = (waveInUnprepareHeader_type)::GetProcAddress(winmm_handle, "waveInUnprepareHeader"); - waveInAddBuffer_orig = (waveInAddBuffer_type)::GetProcAddress(winmm_handle, "waveInAddBuffer"); - waveInStart_orig = (waveInStart_type)::GetProcAddress(winmm_handle, "waveInStart"); - waveInStop_orig = (waveInStop_type)::GetProcAddress(winmm_handle, "waveInStop"); - waveInReset_orig = (waveInReset_type)::GetProcAddress(winmm_handle, "waveInReset"); - waveInGetPosition_orig = (waveInGetPosition_type)::GetProcAddress(winmm_handle, "waveInGetPosition"); - waveInGetID_orig = (waveInGetID_type)::GetProcAddress(winmm_handle, "waveInGetID"); - waveInMessage_orig = (waveInMessage_type)::GetProcAddress(winmm_handle, "waveInMessage"); - midiOutGetNumDevs_orig = (midiOutGetNumDevs_type)::GetProcAddress(winmm_handle, "midiOutGetNumDevs"); - midiStreamOpen_orig = (midiStreamOpen_type)::GetProcAddress(winmm_handle, "midiStreamOpen"); - midiStreamClose_orig = (midiStreamClose_type)::GetProcAddress(winmm_handle, "midiStreamClose"); - midiStreamProperty_orig = (midiStreamProperty_type)::GetProcAddress(winmm_handle, "midiStreamProperty"); - midiStreamPosition_orig = (midiStreamPosition_type)::GetProcAddress(winmm_handle, "midiStreamPosition"); - midiStreamOut_orig = (midiStreamOut_type)::GetProcAddress(winmm_handle, "midiStreamOut"); - midiStreamPause_orig = (midiStreamPause_type)::GetProcAddress(winmm_handle, "midiStreamPause"); - midiStreamRestart_orig = (midiStreamRestart_type)::GetProcAddress(winmm_handle, "midiStreamRestart"); - midiStreamStop_orig = (midiStreamStop_type)::GetProcAddress(winmm_handle, "midiStreamStop"); - midiConnect_orig = (midiConnect_type)::GetProcAddress(winmm_handle, "midiConnect"); - midiDisconnect_orig = (midiDisconnect_type)::GetProcAddress(winmm_handle, "midiDisconnect"); - midiOutGetDevCapsA_orig = (midiOutGetDevCapsA_type)::GetProcAddress(winmm_handle, "midiOutGetDevCapsA"); - midiOutGetDevCapsW_orig = (midiOutGetDevCapsW_type)::GetProcAddress(winmm_handle, "midiOutGetDevCapsW"); - midiOutGetVolume_orig = (midiOutGetVolume_type)::GetProcAddress(winmm_handle, "midiOutGetVolume"); - midiOutSetVolume_orig = (midiOutSetVolume_type)::GetProcAddress(winmm_handle, "midiOutSetVolume"); - midiOutGetErrorTextA_orig = (midiOutGetErrorTextA_type)::GetProcAddress(winmm_handle, "midiOutGetErrorTextA"); - midiOutGetErrorTextW_orig = (midiOutGetErrorTextW_type)::GetProcAddress(winmm_handle, "midiOutGetErrorTextW"); - midiOutOpen_orig = (midiOutOpen_type)::GetProcAddress(winmm_handle, "midiOutOpen"); - midiOutClose_orig = (midiOutClose_type)::GetProcAddress(winmm_handle, "midiOutClose"); - midiOutPrepareHeader_orig = (midiOutPrepareHeader_type)::GetProcAddress(winmm_handle, "midiOutPrepareHeader"); - midiOutUnprepareHeader_orig = (midiOutUnprepareHeader_type)::GetProcAddress(winmm_handle, "midiOutUnprepareHeader"); - midiOutShortMsg_orig = (midiOutShortMsg_type)::GetProcAddress(winmm_handle, "midiOutShortMsg"); - midiOutLongMsg_orig = (midiOutLongMsg_type)::GetProcAddress(winmm_handle, "midiOutLongMsg"); - midiOutReset_orig = (midiOutReset_type)::GetProcAddress(winmm_handle, "midiOutReset"); - midiOutCachePatches_orig = (midiOutCachePatches_type)::GetProcAddress(winmm_handle, "midiOutCachePatches"); - midiOutCacheDrumPatches_orig = (midiOutCacheDrumPatches_type)::GetProcAddress(winmm_handle, "midiOutCacheDrumPatches"); - midiOutGetID_orig = (midiOutGetID_type)::GetProcAddress(winmm_handle, "midiOutGetID"); - midiOutMessage_orig = (midiOutMessage_type)::GetProcAddress(winmm_handle, "midiOutMessage"); - midiInGetNumDevs_orig = (midiInGetNumDevs_type)::GetProcAddress(winmm_handle, "midiInGetNumDevs"); - midiInGetDevCapsA_orig = (midiInGetDevCapsA_type)::GetProcAddress(winmm_handle, "midiInGetDevCapsA"); - midiInGetDevCapsW_orig = (midiInGetDevCapsW_type)::GetProcAddress(winmm_handle, "midiInGetDevCapsW"); - midiInGetErrorTextA_orig = (midiInGetErrorTextA_type)::GetProcAddress(winmm_handle, "midiInGetErrorTextA"); - midiInGetErrorTextW_orig = (midiInGetErrorTextW_type)::GetProcAddress(winmm_handle, "midiInGetErrorTextW"); - midiInOpen_orig = (midiInOpen_type)::GetProcAddress(winmm_handle, "midiInOpen"); - midiInClose_orig = (midiInClose_type)::GetProcAddress(winmm_handle, "midiInClose"); - midiInPrepareHeader_orig = (midiInPrepareHeader_type)::GetProcAddress(winmm_handle, "midiInPrepareHeader"); - midiInUnprepareHeader_orig = (midiInUnprepareHeader_type)::GetProcAddress(winmm_handle, "midiInUnprepareHeader"); - midiInAddBuffer_orig = (midiInAddBuffer_type)::GetProcAddress(winmm_handle, "midiInAddBuffer"); - midiInStart_orig = (midiInStart_type)::GetProcAddress(winmm_handle, "midiInStart"); - midiInStop_orig = (midiInStop_type)::GetProcAddress(winmm_handle, "midiInStop"); - midiInReset_orig = (midiInReset_type)::GetProcAddress(winmm_handle, "midiInReset"); - midiInGetID_orig = (midiInGetID_type)::GetProcAddress(winmm_handle, "midiInGetID"); - midiInMessage_orig = (midiInMessage_type)::GetProcAddress(winmm_handle, "midiInMessage"); - auxGetNumDevs_orig = (auxGetNumDevs_type)::GetProcAddress(winmm_handle, "auxGetNumDevs"); - auxGetDevCapsA_orig = (auxGetDevCapsA_type)::GetProcAddress(winmm_handle, "auxGetDevCapsA"); - auxGetDevCapsW_orig = (auxGetDevCapsW_type)::GetProcAddress(winmm_handle, "auxGetDevCapsW"); - auxSetVolume_orig = (auxSetVolume_type)::GetProcAddress(winmm_handle, "auxSetVolume"); - auxGetVolume_orig = (auxGetVolume_type)::GetProcAddress(winmm_handle, "auxGetVolume"); - auxOutMessage_orig = (auxOutMessage_type)::GetProcAddress(winmm_handle, "auxOutMessage"); - mixerGetNumDevs_orig = (mixerGetNumDevs_type)::GetProcAddress(winmm_handle, "mixerGetNumDevs"); - mixerGetDevCapsA_orig = (mixerGetDevCapsA_type)::GetProcAddress(winmm_handle, "mixerGetDevCapsA"); - mixerGetDevCapsW_orig = (mixerGetDevCapsW_type)::GetProcAddress(winmm_handle, "mixerGetDevCapsW"); - mixerOpen_orig = (mixerOpen_type)::GetProcAddress(winmm_handle, "mixerOpen"); - mixerClose_orig = (mixerClose_type)::GetProcAddress(winmm_handle, "mixerClose"); - mixerMessage_orig = (mixerMessage_type)::GetProcAddress(winmm_handle, "mixerMessage"); - mixerGetLineInfoA_orig = (mixerGetLineInfoA_type)::GetProcAddress(winmm_handle, "mixerGetLineInfoA"); - mixerGetLineInfoW_orig = (mixerGetLineInfoW_type)::GetProcAddress(winmm_handle, "mixerGetLineInfoW"); - mixerGetID_orig = (mixerGetID_type)::GetProcAddress(winmm_handle, "mixerGetID"); - mixerGetLineControlsA_orig = (mixerGetLineControlsA_type)::GetProcAddress(winmm_handle, "mixerGetLineControlsA"); - mixerGetLineControlsW_orig = (mixerGetLineControlsW_type)::GetProcAddress(winmm_handle, "mixerGetLineControlsW"); - mixerGetControlDetailsA_orig = (mixerGetControlDetailsA_type)::GetProcAddress(winmm_handle, "mixerGetControlDetailsA"); - mixerGetControlDetailsW_orig = (mixerGetControlDetailsW_type)::GetProcAddress(winmm_handle, "mixerGetControlDetailsW"); - mixerSetControlDetails_orig = (mixerSetControlDetails_type)::GetProcAddress(winmm_handle, "mixerSetControlDetails"); - mmGetCurrentTask_orig = (mmGetCurrentTask_type)::GetProcAddress(winmm_handle, "mmGetCurrentTask"); - mmTaskBlock_orig = (mmTaskBlock_type)::GetProcAddress(winmm_handle, "mmTaskBlock"); - mmTaskCreate_orig = (mmTaskCreate_type)::GetProcAddress(winmm_handle, "mmTaskCreate"); - mmTaskSignal_orig = (mmTaskSignal_type)::GetProcAddress(winmm_handle, "mmTaskSignal"); - mmTaskYield_orig = (mmTaskYield_type)::GetProcAddress(winmm_handle, "mmTaskYield"); - timeGetSystemTime_orig = (timeGetSystemTime_type)::GetProcAddress(winmm_handle, "timeGetSystemTime"); - timeGetTime_orig = (timeGetTime_type)::GetProcAddress(winmm_handle, "timeGetTime"); - timeSetEvent_orig = (timeSetEvent_type)::GetProcAddress(winmm_handle, "timeSetEvent"); - timeKillEvent_orig = (timeKillEvent_type)::GetProcAddress(winmm_handle, "timeKillEvent"); - timeGetDevCaps_orig = (timeGetDevCaps_type)::GetProcAddress(winmm_handle, "timeGetDevCaps"); - timeBeginPeriod_orig = (timeBeginPeriod_type)::GetProcAddress(winmm_handle, "timeBeginPeriod"); - timeEndPeriod_orig = (timeEndPeriod_type)::GetProcAddress(winmm_handle, "timeEndPeriod"); - joyGetNumDevs_orig = (joyGetNumDevs_type)::GetProcAddress(winmm_handle, "joyGetNumDevs"); - joyConfigChanged_orig = (joyConfigChanged_type)::GetProcAddress(winmm_handle, "joyConfigChanged"); - joyGetDevCapsA_orig = (joyGetDevCapsA_type)::GetProcAddress(winmm_handle, "joyGetDevCapsA"); - joyGetDevCapsW_orig = (joyGetDevCapsW_type)::GetProcAddress(winmm_handle, "joyGetDevCapsW"); - joyGetPos_orig = (joyGetPos_type)::GetProcAddress(winmm_handle, "joyGetPos"); - joyGetPosEx_orig = (joyGetPosEx_type)::GetProcAddress(winmm_handle, "joyGetPosEx"); - joyGetThreshold_orig = (joyGetThreshold_type)::GetProcAddress(winmm_handle, "joyGetThreshold"); - joyReleaseCapture_orig = (joyReleaseCapture_type)::GetProcAddress(winmm_handle, "joyReleaseCapture"); - joySetCapture_orig = (joySetCapture_type)::GetProcAddress(winmm_handle, "joySetCapture"); - joySetThreshold_orig = (joySetThreshold_type)::GetProcAddress(winmm_handle, "joySetThreshold"); - mciDriverNotify_orig = (mciDriverNotify_type)::GetProcAddress(winmm_handle, "mciDriverNotify"); - mciDriverYield_orig = (mciDriverYield_type)::GetProcAddress(winmm_handle, "mciDriverYield"); - mmioStringToFOURCCA_orig = (mmioStringToFOURCCA_type)::GetProcAddress(winmm_handle, "mmioStringToFOURCCA"); - mmioStringToFOURCCW_orig = (mmioStringToFOURCCW_type)::GetProcAddress(winmm_handle, "mmioStringToFOURCCW"); - mmioInstallIOProcA_orig = (mmioInstallIOProcA_type)::GetProcAddress(winmm_handle, "mmioInstallIOProcA"); - mmioInstallIOProcW_orig = (mmioInstallIOProcW_type)::GetProcAddress(winmm_handle, "mmioInstallIOProcW"); - mmioOpenA_orig = (mmioOpenA_type)::GetProcAddress(winmm_handle, "mmioOpenA"); - mmioOpenW_orig = (mmioOpenW_type)::GetProcAddress(winmm_handle, "mmioOpenW"); - mmioRenameA_orig = (mmioRenameA_type)::GetProcAddress(winmm_handle, "mmioRenameA"); - mmioRenameW_orig = (mmioRenameW_type)::GetProcAddress(winmm_handle, "mmioRenameW"); - mmioClose_orig = (mmioClose_type)::GetProcAddress(winmm_handle, "mmioClose"); - mmioRead_orig = (mmioRead_type)::GetProcAddress(winmm_handle, "mmioRead"); - mmioWrite_orig = (mmioWrite_type)::GetProcAddress(winmm_handle, "mmioWrite"); - mmioSeek_orig = (mmioSeek_type)::GetProcAddress(winmm_handle, "mmioSeek"); - mmioGetInfo_orig = (mmioGetInfo_type)::GetProcAddress(winmm_handle, "mmioGetInfo"); - mmioSetInfo_orig = (mmioSetInfo_type)::GetProcAddress(winmm_handle, "mmioSetInfo"); - mmioSetBuffer_orig = (mmioSetBuffer_type)::GetProcAddress(winmm_handle, "mmioSetBuffer"); - mmioFlush_orig = (mmioFlush_type)::GetProcAddress(winmm_handle, "mmioFlush"); - mmioAdvance_orig = (mmioAdvance_type)::GetProcAddress(winmm_handle, "mmioAdvance"); - mmioSendMessage_orig = (mmioSendMessage_type)::GetProcAddress(winmm_handle, "mmioSendMessage"); - mmioDescend_orig = (mmioDescend_type)::GetProcAddress(winmm_handle, "mmioDescend"); - mmioAscend_orig = (mmioAscend_type)::GetProcAddress(winmm_handle, "mmioAscend"); - mmioCreateChunk_orig = (mmioCreateChunk_type)::GetProcAddress(winmm_handle, "mmioCreateChunk"); - mciSendCommandA_orig = (mciSendCommandA_type)::GetProcAddress(winmm_handle, "mciSendCommandA"); - mciSendCommandW_orig = (mciSendCommandW_type)::GetProcAddress(winmm_handle, "mciSendCommandW"); - mciSendStringA_orig = (mciSendStringA_type)::GetProcAddress(winmm_handle, "mciSendStringA"); - mciSendStringW_orig = (mciSendStringW_type)::GetProcAddress(winmm_handle, "mciSendStringW"); - mciGetDeviceIDA_orig = (mciGetDeviceIDA_type)::GetProcAddress(winmm_handle, "mciGetDeviceIDA"); - mciGetDeviceIDW_orig = (mciGetDeviceIDW_type)::GetProcAddress(winmm_handle, "mciGetDeviceIDW"); - mciGetDeviceIDFromElementIDA_orig = (mciGetDeviceIDFromElementIDA_type)::GetProcAddress(winmm_handle, "mciGetDeviceIDFromElementIDA"); - mciGetDeviceIDFromElementIDW_orig = (mciGetDeviceIDFromElementIDW_type)::GetProcAddress(winmm_handle, "mciGetDeviceIDFromElementIDW"); - mciGetDriverData_orig = (mciGetDriverData_type)::GetProcAddress(winmm_handle, "mciGetDriverData"); - mciGetErrorStringA_orig = (mciGetErrorStringA_type)::GetProcAddress(winmm_handle, "mciGetErrorStringA"); - mciGetErrorStringW_orig = (mciGetErrorStringW_type)::GetProcAddress(winmm_handle, "mciGetErrorStringW"); - mciSetDriverData_orig = (mciSetDriverData_type)::GetProcAddress(winmm_handle, "mciSetDriverData"); - mciSetYieldProc_orig = (mciSetYieldProc_type)::GetProcAddress(winmm_handle, "mciSetYieldProc"); - mciFreeCommandResource_orig = (mciFreeCommandResource_type)::GetProcAddress(winmm_handle, "mciFreeCommandResource"); - mciGetCreatorTask_orig = (mciGetCreatorTask_type)::GetProcAddress(winmm_handle, "mciGetCreatorTask"); - mciGetYieldProc_orig = (mciGetYieldProc_type)::GetProcAddress(winmm_handle, "mciGetYieldProc"); - mciLoadCommandResource_orig = (mciLoadCommandResource_type)::GetProcAddress(winmm_handle, "mciLoadCommandResource"); - mciExecute_orig = (mciExecute_type)::GetProcAddress(winmm_handle, "mciExecute"); -} - -extern "C" { - LRESULT WINAPI CloseDriver( HDRVR hDriver, LPARAM lParam1, LPARAM lParam2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"CloseDriver\n"); - return CloseDriver_orig( hDriver, lParam1, lParam2); - } - - HDRVR WINAPI OpenDriver( LPCWSTR szDriverName, LPCWSTR szSectionName, LPARAM lParam2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"OpenDriver\n"); - return OpenDriver_orig( szDriverName, szSectionName, lParam2); - } - - LRESULT WINAPI SendDriverMessage( HDRVR hDriver, UINT message, LPARAM lParam1, LPARAM lParam2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"SendDriverMessage\n"); - return SendDriverMessage_orig( hDriver, message, lParam1, lParam2); - } - - HMODULE WINAPI DrvGetModuleHandle( HDRVR hDriver) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"DrvGetModuleHandle\n"); - return DrvGetModuleHandle_orig( hDriver); - } - - HMODULE WINAPI GetDriverModuleHandle( HDRVR hDriver) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"GetDriverModuleHandle\n"); - return GetDriverModuleHandle_orig( hDriver); - } - - LRESULT WINAPI DefDriverProc( DWORD_PTR dwDriverIdentifier, HDRVR hdrvr, UINT uMsg, LPARAM lParam1, LPARAM lParam2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"DefDriverProc\n"); - return DefDriverProc_orig( dwDriverIdentifier, hdrvr, uMsg, lParam1, lParam2); - } - - BOOL WINAPI DriverCallback( DWORD dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"DriverCallback\n"); - return DriverCallback_orig(dwCallBack, dwFlags, hdrvr, msg, dwUser, dwParam1, dwParam2); - } - - UINT WINAPI mmsystemGetVersion(void) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmsystemGetVersion\n"); - return mmsystemGetVersion_orig(); - } - - BOOL WINAPI sndPlaySoundA( LPCSTR pszSound, UINT fuSound) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"sndPlaySoundA\n"); - return sndPlaySoundA_orig( pszSound, fuSound); - } - - BOOL WINAPI sndPlaySoundW( LPCWSTR pszSound, UINT fuSound) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"sndPlaySoundW\n"); - return sndPlaySoundW_orig( pszSound, fuSound); - } - - BOOL WINAPI PlaySoundA( LPCSTR pszSound, HMODULE hmod, DWORD fdwSound) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"PlaySoundA\n"); - return PlaySoundA_orig( pszSound, hmod, fdwSound); - } - - BOOL WINAPI PlaySoundW( LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"PlaySoundW\n"); - return PlaySoundW_orig( pszSound, hmod, fdwSound); - } - - UINT WINAPI waveOutGetNumDevs(void) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutGetNumDevs\n"); - return waveOutGetNumDevs_orig(); - } - - MMRESULT WINAPI waveOutGetDevCapsA( UINT_PTR uDeviceID, LPWAVEOUTCAPSA pwoc, UINT cbwoc) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutGetDevCapsA\n"); - return waveOutGetDevCapsA_orig( uDeviceID, pwoc, cbwoc); - } - - MMRESULT WINAPI waveOutGetDevCapsW( UINT_PTR uDeviceID, LPWAVEOUTCAPSW pwoc, UINT cbwoc) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutGetDevCapsW\n"); - return waveOutGetDevCapsW_orig( uDeviceID, pwoc, cbwoc); - } - - - MMRESULT WINAPI waveOutGetVolume( HWAVEOUT hwo, LPDWORD pdwVolume) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutGetVolume\n"); - return waveOutGetVolume_orig( hwo, pdwVolume); - } - - MMRESULT WINAPI waveOutSetVolume( HWAVEOUT hwo, DWORD dwVolume) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutSetVolume\n"); - return waveOutSetVolume_orig( hwo, dwVolume); - } - - MMRESULT WINAPI waveOutGetErrorTextA( MMRESULT mmrError, LPSTR pszText, UINT cchText) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutGetErrorTextA\n"); - return waveOutGetErrorTextA_orig( mmrError, pszText, cchText); - } - - MMRESULT WINAPI waveOutGetErrorTextW( MMRESULT mmrError, LPWSTR pszText, UINT cchText) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutGetErrorTextW\n"); - return waveOutGetErrorTextW_orig( mmrError, pszText, cchText); - } - - //MMRESULT WINAPI waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) - //{ - // //OutputDebugString(L"waveOutGetErrorTextW\n"); - // return waveOutOpen_orig( phwo, uDeviceID, pwfx, dwCallback, dwInstance, fdwOpen); - //} - - //MMRESULT WINAPI waveOutClose( HWAVEOUT hwo) - //{ - // //OutputDebugString(L"waveOutGetErrorTextW\n"); - // return waveOutClose_orig( hwo ); - //} - - MMRESULT WINAPI waveOutPrepareHeader( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutPrepareHeader\n"); - return waveOutPrepareHeader_orig( hwo, pwh, cbwh); - } - - MMRESULT WINAPI waveOutUnprepareHeader( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutUnprepareHeader\n"); - return waveOutUnprepareHeader_orig( hwo, pwh, cbwh); - } - - - //MMRESULT WINAPI waveOutWrite( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) - //{ - // //OutputDebugString(L"waveOutUnprepareHeader\n"); - // return waveOutWrite_orig( hwo, pwh, cbwh); - //} - - MMRESULT WINAPI waveOutPause( HWAVEOUT hwo) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutPause\n"); - return waveOutPause_orig( hwo); - } - - MMRESULT WINAPI waveOutRestart( HWAVEOUT hwo) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutRestart\n"); - return waveOutRestart_orig( hwo); - } - - MMRESULT WINAPI waveOutReset( HWAVEOUT hwo) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutReset\n"); - return waveOutReset_orig( hwo); - } - - MMRESULT WINAPI waveOutBreakLoop( HWAVEOUT hwo) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutBreakLoop\n"); - return waveOutBreakLoop_orig( hwo); - } - - MMRESULT WINAPI waveOutGetPosition( HWAVEOUT hwo, LPMMTIME pmmt, UINT cbmmt) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutGetPosition\n"); - return waveOutGetPosition_orig( hwo, pmmt, cbmmt); - } - - MMRESULT WINAPI waveOutGetPitch( HWAVEOUT hwo, LPDWORD pdwPitch) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutGetPitch\n"); - return waveOutGetPitch_orig( hwo, pdwPitch); - } - - MMRESULT WINAPI waveOutSetPitch( HWAVEOUT hwo, DWORD dwPitch) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutSetPitch\n"); - return waveOutSetPitch_orig( hwo, dwPitch); - } - - MMRESULT WINAPI waveOutGetPlaybackRate( HWAVEOUT hwo, LPDWORD pdwRate) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutGetPlaybackRate\n"); - return waveOutGetPlaybackRate_orig( hwo, pdwRate); - } - - MMRESULT WINAPI waveOutSetPlaybackRate( HWAVEOUT hwo, DWORD dwRate) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutSetPlaybackRate\n"); - return waveOutSetPlaybackRate_orig( hwo, dwRate); - } - - MMRESULT WINAPI waveOutGetID( HWAVEOUT hwo, LPUINT puDeviceID) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutGetID\n"); - return waveOutGetID_orig( hwo, puDeviceID); - } - - MMRESULT WINAPI waveOutMessage( HWAVEOUT hwo, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveOutMessage\n"); - return waveOutMessage_orig( hwo, uMsg, dw1, dw2); - } - - UINT WINAPI waveInGetNumDevs(void) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInGetNumDevs\n"); - return waveInGetNumDevs_orig(); - } - - MMRESULT WINAPI waveInGetDevCapsA( UINT_PTR uDeviceID, LPWAVEINCAPSA pwic, UINT cbwic) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInGetDevCapsA\n"); - return waveInGetDevCapsA_orig( uDeviceID, pwic, cbwic); - } - - MMRESULT WINAPI waveInGetDevCapsW( UINT_PTR uDeviceID, LPWAVEINCAPSW pwic, UINT cbwic) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInGetDevCapsW\n"); - return waveInGetDevCapsW_orig( uDeviceID, pwic, cbwic); - } - - MMRESULT WINAPI waveInGetErrorTextA(MMRESULT mmrError, LPSTR pszText, UINT cchText) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInGetErrorTextA\n"); - return waveInGetErrorTextA_orig(mmrError, pszText, cchText); - } - - MMRESULT WINAPI waveInGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInGetErrorTextW\n"); - return waveInGetErrorTextW_orig(mmrError, pszText, cchText); - } - - MMRESULT WINAPI waveInOpen( LPHWAVEIN phwi, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInOpen\n"); - return waveInOpen_orig(phwi, uDeviceID, pwfx, dwCallback, dwInstance, fdwOpen); - } - - MMRESULT WINAPI waveInClose( HWAVEIN hwi) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInClose\n"); - return waveInClose_orig( hwi); - } - - MMRESULT WINAPI waveInPrepareHeader( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInPrepareHeader\n"); - return waveInPrepareHeader_orig( hwi, pwh, cbwh); - } - - MMRESULT WINAPI waveInUnprepareHeader( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInUnprepareHeader\n"); - return waveInUnprepareHeader_orig( hwi, pwh, cbwh); - } - - MMRESULT WINAPI waveInAddBuffer( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInAddBuffer\n"); - return waveInAddBuffer_orig( hwi, pwh, cbwh); - } - - MMRESULT WINAPI waveInStart( HWAVEIN hwi) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInStart\n"); - return waveInStart_orig( hwi); - } - - MMRESULT WINAPI waveInStop( HWAVEIN hwi) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInStop\n"); - return waveInStop_orig(hwi); - } - - MMRESULT WINAPI waveInReset( HWAVEIN hwi) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInReset\n"); - return waveInReset_orig(hwi); - } - - MMRESULT WINAPI waveInGetPosition( HWAVEIN hwi, LPMMTIME pmmt, UINT cbmmt) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInGetPosition\n"); - return waveInGetPosition_orig( hwi, pmmt, cbmmt); - } - - MMRESULT WINAPI waveInGetID( HWAVEIN hwi, LPUINT puDeviceID) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInGetID\n"); - return waveInGetID_orig( hwi, puDeviceID); - } - - MMRESULT WINAPI waveInMessage( HWAVEIN hwi, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"waveInMessage\n"); - return waveInMessage_orig( hwi, uMsg, dw1, dw2); - } - - UINT WINAPI midiOutGetNumDevs(void) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutGetNumDevs\n"); - return midiOutGetNumDevs_orig(); - } - - MMRESULT WINAPI midiStreamOpen( LPHMIDISTRM phms, LPUINT puDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiStreamOpen\n"); - return midiStreamOpen_orig( phms, puDeviceID, cMidi, dwCallback, dwInstance, fdwOpen); - } - - MMRESULT WINAPI midiStreamClose( HMIDISTRM hms) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiStreamClose\n"); - return midiStreamClose_orig( hms); - } - - MMRESULT WINAPI midiStreamProperty( HMIDISTRM hms, LPBYTE lppropdata, DWORD dwProperty) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiStreamProperty\n"); - return midiStreamProperty_orig( hms, lppropdata, dwProperty); - } - - MMRESULT WINAPI midiStreamPosition( HMIDISTRM hms, LPMMTIME lpmmt, UINT cbmmt) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiStreamPosition\n"); - return midiStreamPosition_orig( hms, lpmmt, cbmmt); - } - - MMRESULT WINAPI midiStreamOut( HMIDISTRM hms, LPMIDIHDR pmh, UINT cbmh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiStreamOut\n"); - return midiStreamOut_orig( hms, pmh, cbmh); - } - - MMRESULT WINAPI midiStreamPause( HMIDISTRM hms) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiStreamPause\n"); - return midiStreamPause_orig( hms); - } - - MMRESULT WINAPI midiStreamRestart( HMIDISTRM hms) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiStreamRestart\n"); - return midiStreamRestart_orig( hms); - } - - MMRESULT WINAPI midiStreamStop( HMIDISTRM hms) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiStreamStop\n"); - return midiStreamStop_orig( hms); - } - - MMRESULT WINAPI midiConnect( HMIDI hmi, HMIDIOUT hmo, LPVOID pReserved) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiConnect\n"); - return midiConnect_orig( hmi, hmo, pReserved); - } - - MMRESULT WINAPI midiDisconnect( HMIDI hmi, HMIDIOUT hmo, LPVOID pReserved) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiDisconnect\n"); - return midiDisconnect_orig( hmi, hmo, pReserved); - } - - MMRESULT WINAPI midiOutGetDevCapsA( UINT_PTR uDeviceID, LPMIDIOUTCAPSA pmoc, UINT cbmoc) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutGetDevCapsA\n"); - return midiOutGetDevCapsA_orig( uDeviceID, pmoc, cbmoc); - } - - MMRESULT WINAPI midiOutGetDevCapsW( UINT_PTR uDeviceID, LPMIDIOUTCAPSW pmoc, UINT cbmoc) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutGetDevCapsW\n"); - return midiOutGetDevCapsW_orig( uDeviceID, pmoc, cbmoc); - } - - MMRESULT WINAPI midiOutGetVolume( HMIDIOUT hmo, LPDWORD pdwVolume) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutGetVolume\n"); - return midiOutGetVolume_orig( hmo, pdwVolume); - } - - MMRESULT WINAPI midiOutSetVolume( HMIDIOUT hmo, DWORD dwVolume) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutSetVolume\n"); - return midiOutSetVolume_orig( hmo, dwVolume); - } - - MMRESULT WINAPI midiOutGetErrorTextA( MMRESULT mmrError, LPSTR pszText, UINT cchText) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutGetErrorTextA\n"); - return midiOutGetErrorTextA_orig( mmrError, pszText, cchText); - } - - MMRESULT WINAPI midiOutGetErrorTextW( MMRESULT mmrError, LPWSTR pszText, UINT cchText) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutGetErrorTextW\n"); - return midiOutGetErrorTextW_orig( mmrError, pszText, cchText); - } - - MMRESULT WINAPI midiOutOpen( LPHMIDIOUT phmo, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutOpen\n"); - return midiOutOpen_orig(phmo, uDeviceID, dwCallback, dwInstance, fdwOpen); - } - - MMRESULT WINAPI midiOutClose( HMIDIOUT hmo) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutClose\n"); - return midiOutClose_orig( hmo); - } - - MMRESULT WINAPI midiOutPrepareHeader( HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutPrepareHeader\n"); - return midiOutPrepareHeader_orig( hmo, pmh, cbmh); - } - - MMRESULT WINAPI midiOutUnprepareHeader(HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutUnprepareHeader\n"); - return midiOutUnprepareHeader_orig(hmo, pmh, cbmh); - } - - MMRESULT WINAPI midiOutShortMsg( HMIDIOUT hmo, DWORD dwMsg) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutShortMsg\n"); - return midiOutShortMsg_orig( hmo, dwMsg); - } - - MMRESULT WINAPI midiOutLongMsg(HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutLongMsg\n"); - return midiOutLongMsg_orig(hmo, pmh, cbmh); - } - - MMRESULT WINAPI midiOutReset( HMIDIOUT hmo) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutReset\n"); - return midiOutReset_orig( hmo); - } - - MMRESULT WINAPI midiOutCachePatches( HMIDIOUT hmo, UINT uBank, LPWORD pwpa, UINT fuCache) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutCachePatches\n"); - return midiOutCachePatches_orig( hmo, uBank, pwpa, fuCache); - } - - MMRESULT WINAPI midiOutCacheDrumPatches( HMIDIOUT hmo, UINT uPatch, LPWORD pwkya, UINT fuCache) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutCacheDrumPatches\n"); - return midiOutCacheDrumPatches_orig( hmo, uPatch, pwkya, fuCache); - } - - MMRESULT WINAPI midiOutGetID( HMIDIOUT hmo, LPUINT puDeviceID) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutGetID\n"); - return midiOutGetID_orig( hmo, puDeviceID); - } - - MMRESULT WINAPI midiOutMessage( HMIDIOUT hmo, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiOutMessage\n"); - return midiOutMessage_orig( hmo, uMsg, dw1, dw2); - } - - UINT WINAPI midiInGetNumDevs(void) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInGetNumDevs\n"); - return midiInGetNumDevs_orig(); - } - - MMRESULT WINAPI midiInGetDevCapsA( UINT_PTR uDeviceID, LPMIDIINCAPSA pmic, UINT cbmic) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInGetDevCapsA\n"); - return midiInGetDevCapsA_orig( uDeviceID, pmic, cbmic); - } - - MMRESULT WINAPI midiInGetDevCapsW( UINT_PTR uDeviceID, LPMIDIINCAPSW pmic, UINT cbmic) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInGetDevCapsW\n"); - return midiInGetDevCapsW_orig( uDeviceID, pmic, cbmic); - } - - MMRESULT WINAPI midiInGetErrorTextA( MMRESULT mmrError, LPSTR pszText, UINT cchText) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInGetErrorTextA\n"); - return midiInGetErrorTextA_orig( mmrError, pszText, cchText); - } - - MMRESULT WINAPI midiInGetErrorTextW( MMRESULT mmrError, LPWSTR pszText, UINT cchText) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInGetErrorTextW\n"); - return midiInGetErrorTextW_orig( mmrError, pszText, cchText); - } - - MMRESULT WINAPI midiInOpen( LPHMIDIIN phmi, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInOpen\n"); - return midiInOpen_orig(phmi, uDeviceID, dwCallback, dwInstance, fdwOpen); - } - - MMRESULT WINAPI midiInClose( HMIDIIN hmi) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInClose\n"); - return midiInClose_orig( hmi); - } - - MMRESULT WINAPI midiInPrepareHeader( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInPrepareHeader\n"); - return midiInPrepareHeader_orig( hmi, pmh, cbmh); - } - - MMRESULT WINAPI midiInUnprepareHeader( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInUnprepareHeader\n"); - return midiInUnprepareHeader_orig( hmi, pmh, cbmh); - } - - MMRESULT WINAPI midiInAddBuffer( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInAddBuffer\n"); - return midiInAddBuffer_orig( hmi, pmh, cbmh); - } - - MMRESULT WINAPI midiInStart( HMIDIIN hmi) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInStart\n"); - return midiInStart_orig( hmi); - } - - MMRESULT WINAPI midiInStop( HMIDIIN hmi) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInStop\n"); - return midiInStop_orig(hmi); - } - - MMRESULT WINAPI midiInReset( HMIDIIN hmi) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInReset\n"); - return midiInReset_orig( hmi); - } - - MMRESULT WINAPI midiInGetID( HMIDIIN hmi, LPUINT puDeviceID) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInGetID\n"); - return midiInGetID_orig( hmi, puDeviceID); - } - - MMRESULT WINAPI midiInMessage( HMIDIIN hmi, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"midiInMessage\n"); - return midiInMessage_orig( hmi, uMsg, dw1, dw2); - } - - UINT WINAPI auxGetNumDevs(void) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"auxGetNumDevs\n"); - return auxGetNumDevs_orig(); - } - - MMRESULT WINAPI auxGetDevCapsA( UINT_PTR uDeviceID, LPAUXCAPSA pac, UINT cbac) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"auxGetDevCapsA\n"); - return auxGetDevCapsA_orig( uDeviceID, pac, cbac); - } - - MMRESULT WINAPI auxGetDevCapsW( UINT_PTR uDeviceID, LPAUXCAPSW pac, UINT cbac) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"auxGetDevCapsW\n"); - return auxGetDevCapsW_orig( uDeviceID, pac, cbac); - } - - MMRESULT WINAPI auxSetVolume( UINT uDeviceID, DWORD dwVolume) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"auxSetVolume\n"); - return auxSetVolume_orig( uDeviceID, dwVolume); - } - - MMRESULT WINAPI auxGetVolume( UINT uDeviceID, LPDWORD pdwVolume) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"auxGetVolume\n"); - return auxGetVolume_orig( uDeviceID, pdwVolume); - } - - MMRESULT WINAPI auxOutMessage( UINT uDeviceID, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"auxOutMessage\n"); - return auxOutMessage_orig( uDeviceID, uMsg, dw1, dw2); - } - - UINT WINAPI mixerGetNumDevs(void) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerGetNumDevs\n"); - return mixerGetNumDevs_orig(); - } - - MMRESULT WINAPI mixerGetDevCapsA( UINT_PTR uMxId, LPMIXERCAPSA pmxcaps, UINT cbmxcaps) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerGetDevCapsA\n"); - return mixerGetDevCapsA_orig( uMxId, pmxcaps, cbmxcaps); - } - - MMRESULT WINAPI mixerGetDevCapsW( UINT_PTR uMxId, LPMIXERCAPSW pmxcaps, UINT cbmxcaps) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerGetDevCapsW\n"); - return mixerGetDevCapsW_orig( uMxId, pmxcaps, cbmxcaps); - } - - MMRESULT WINAPI mixerOpen( LPHMIXER phmx, UINT uMxId, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerOpen\n"); - return mixerOpen_orig( phmx, uMxId, dwCallback, dwInstance, fdwOpen); - } - - MMRESULT WINAPI mixerClose( HMIXER hmx) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerClose\n"); - return mixerClose_orig( hmx); - } - - DWORD WINAPI mixerMessage( HMIXER hmx, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerMessage\n"); - return mixerMessage_orig( hmx, uMsg, dwParam1, dwParam2); - } - - MMRESULT WINAPI mixerGetLineInfoA( HMIXEROBJ hmxobj, LPMIXERLINEA pmxl, DWORD fdwInfo) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerGetLineInfoA\n"); - return mixerGetLineInfoA_orig( hmxobj, pmxl, fdwInfo); - } - - MMRESULT WINAPI mixerGetLineInfoW( HMIXEROBJ hmxobj, LPMIXERLINEW pmxl, DWORD fdwInfo) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerGetLineInfoW\n"); - return mixerGetLineInfoW_orig( hmxobj, pmxl, fdwInfo); - } - - MMRESULT WINAPI mixerGetID( HMIXEROBJ hmxobj, UINT FAR *puMxId, DWORD fdwId) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerGetID\n"); - return mixerGetID_orig( hmxobj, puMxId, fdwId); - } - - MMRESULT WINAPI mixerGetLineControlsA( HMIXEROBJ hmxobj, LPMIXERLINECONTROLSA pmxlc, DWORD fdwControls) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerGetLineControlsA\n"); - return mixerGetLineControlsA_orig( hmxobj, pmxlc, fdwControls); - } - - MMRESULT WINAPI mixerGetLineControlsW( HMIXEROBJ hmxobj, LPMIXERLINECONTROLSW pmxlc, DWORD fdwControls) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerGetLineControlsW\n"); - return mixerGetLineControlsW_orig( hmxobj, pmxlc, fdwControls); - } - - MMRESULT WINAPI mixerGetControlDetailsA( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerGetControlDetailsA\n"); - return mixerGetControlDetailsA_orig( hmxobj, pmxcd, fdwDetails); - } - - MMRESULT WINAPI mixerGetControlDetailsW( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerGetControlDetailsW\n"); - return mixerGetControlDetailsW_orig( hmxobj, pmxcd, fdwDetails); - } - - MMRESULT WINAPI mixerSetControlDetails( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mixerSetControlDetails\n"); - return mixerSetControlDetails_orig( hmxobj, pmxcd, fdwDetails); - } - - DWORD WINAPI mmGetCurrentTask(void) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmGetCurrentTask\n"); - return mmGetCurrentTask_orig(); - } - - void WINAPI mmTaskBlock(DWORD val) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmTaskBlock\n"); - return mmTaskBlock_orig(val); - } - - UINT WINAPI mmTaskCreate(LPTASKCALLBACK a, HANDLE* b, DWORD_PTR c) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmTaskCreate\n"); - return mmTaskCreate_orig(a, b, c); - } - - BOOL WINAPI mmTaskSignal(DWORD a) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmTaskSignal\n"); - return mmTaskSignal_orig(a); - } - - VOID WINAPI mmTaskYield() - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmTaskYield\n"); - mmTaskYield_orig(); - } - - MMRESULT WINAPI timeGetSystemTime( LPMMTIME pmmt, UINT cbmmt) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"timeGetSystemTime\n"); - return timeGetSystemTime_orig( pmmt, cbmmt); - } - - DWORD WINAPI timeGetTime(void) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"timeGetTime\n"); - return timeGetTime_orig(); - } - - MMRESULT WINAPI timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD_PTR dwUser, UINT fuEvent) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"timeSetEvent\n"); - return timeSetEvent_orig(uDelay, uResolution, fptc, dwUser, fuEvent); - } - - MMRESULT WINAPI timeKillEvent( UINT uTimerID) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"timeKillEvent\n"); - return timeKillEvent_orig( uTimerID); - } - - MMRESULT WINAPI timeGetDevCaps( LPTIMECAPS ptc, UINT cbtc) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"timeGetDevCaps\n"); - return timeGetDevCaps_orig( ptc, cbtc); - } - - MMRESULT WINAPI timeBeginPeriod( UINT uPeriod) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"timeBeginPeriod\n"); - return timeBeginPeriod_orig( uPeriod); - } - - MMRESULT WINAPI timeEndPeriod( UINT uPeriod) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"timeEndPeriod\n"); - return timeEndPeriod_orig( uPeriod); - } - - UINT WINAPI joyGetNumDevs(void) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"joyGetNumDevs\n"); - return joyGetNumDevs_orig(); - } - - MMRESULT WINAPI joyConfigChanged(DWORD dwFlags) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"joyConfigChanged\n"); - return joyConfigChanged_orig(dwFlags); - } - - MMRESULT WINAPI joyGetDevCapsA( UINT_PTR uJoyID, LPJOYCAPSA pjc, UINT cbjc) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"joyGetDevCapsA\n"); - return joyGetDevCapsA_orig( uJoyID, pjc, cbjc); - } - - MMRESULT WINAPI joyGetDevCapsW( UINT_PTR uJoyID, LPJOYCAPSW pjc, UINT cbjc) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"joyGetDevCapsW\n"); - return joyGetDevCapsW_orig( uJoyID, pjc, cbjc); - } - - MMRESULT WINAPI joyGetPos( UINT uJoyID, LPJOYINFO pji) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"joyGetPos\n"); - return joyGetPos_orig( uJoyID, pji); - } - - MMRESULT WINAPI joyGetPosEx( UINT uJoyID, LPJOYINFOEX pji) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"joyGetPosEx\n"); - return joyGetPosEx_orig( uJoyID, pji); - } - - MMRESULT WINAPI joyGetThreshold( UINT uJoyID, LPUINT puThreshold) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"joyGetThreshold\n"); - return joyGetThreshold_orig( uJoyID, puThreshold); - } - - MMRESULT WINAPI joyReleaseCapture( UINT uJoyID) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"joyReleaseCapture\n"); - return joyReleaseCapture_orig( uJoyID); - } - - MMRESULT WINAPI joySetCapture( HWND hwnd, UINT uJoyID, UINT uPeriod, BOOL fChanged) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"joySetCapture\n"); - return joySetCapture_orig(hwnd, uJoyID, uPeriod, fChanged); - } - - MMRESULT WINAPI joySetThreshold( UINT uJoyID, UINT uThreshold) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"joySetThreshold\n"); - return joySetThreshold_orig( uJoyID, uThreshold); - } - - BOOL WINAPI mciDriverNotify(HANDLE hwndCallback, MCIDEVICEID uDeviceID, UINT uStatus) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciDriverNotify\n"); - return mciDriverNotify_orig(hwndCallback, uDeviceID, uStatus); - } - - UINT WINAPI mciDriverYield(UINT uDeviceID) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciDriverYield\n"); - return mciDriverYield_orig(uDeviceID); - } - - FOURCC WINAPI mmioStringToFOURCCA( LPCSTR sz, UINT uFlags) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioStringToFOURCCA\n"); - return mmioStringToFOURCCA_orig( sz, uFlags); - } - - FOURCC WINAPI mmioStringToFOURCCW( LPCWSTR sz, UINT uFlags) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioStringToFOURCCW\n"); - return mmioStringToFOURCCW_orig( sz, uFlags); - } - - LPMMIOPROC WINAPI mmioInstallIOProcA( FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioInstallIOProcA\n"); - return mmioInstallIOProcA_orig( fccIOProc, pIOProc, dwFlags); - } - - LPMMIOPROC WINAPI mmioInstallIOProcW( FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioInstallIOProcW\n"); - return mmioInstallIOProcW_orig( fccIOProc, pIOProc, dwFlags); - } - - HMMIO WINAPI mmioOpenA( LPSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioOpenA\n"); - return mmioOpenA_orig( pszFileName, pmmioinfo, fdwOpen); - } - - HMMIO WINAPI mmioOpenW( LPWSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioOpenW\n"); - return mmioOpenW_orig( pszFileName, pmmioinfo, fdwOpen); - } - - MMRESULT WINAPI mmioRenameA( LPCSTR pszFileName, LPCSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioRenameA\n"); - return mmioRenameA_orig( pszFileName, pszNewFileName, pmmioinfo, fdwRename); - } - - MMRESULT WINAPI mmioRenameW( LPCWSTR pszFileName, LPCWSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioRenameW\n"); - return mmioRenameW_orig( pszFileName, pszNewFileName, pmmioinfo, fdwRename); - } - - MMRESULT WINAPI mmioClose( HMMIO hmmio, UINT fuClose) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioClose\n"); - return mmioClose_orig( hmmio, fuClose); - } - - LONG WINAPI mmioRead( HMMIO hmmio, HPSTR pch, LONG cch) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioRead\n"); - return mmioRead_orig( hmmio, pch, cch); - } - - LONG WINAPI mmioWrite( HMMIO hmmio, const char _huge* pch, LONG cch) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioWrite\n"); - return mmioWrite_orig( hmmio, pch, cch); - } - - LONG WINAPI mmioSeek( HMMIO hmmio, LONG lOffset, int iOrigin) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioSeek\n"); - return mmioSeek_orig(hmmio, lOffset, iOrigin); - } - - MMRESULT WINAPI mmioGetInfo( HMMIO hmmio, LPMMIOINFO pmmioinfo, UINT fuInfo) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioGetInfo\n"); - return mmioGetInfo_orig( hmmio, pmmioinfo, fuInfo); - } - - MMRESULT WINAPI mmioSetInfo( HMMIO hmmio, LPCMMIOINFO pmmioinfo, UINT fuInfo) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioSetInfo\n"); - return mmioSetInfo_orig( hmmio, pmmioinfo, fuInfo); - } - - MMRESULT WINAPI mmioSetBuffer( HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT fuBuffer) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioSetBuffer\n"); - return mmioSetBuffer_orig(hmmio, pchBuffer, cchBuffer, fuBuffer); - } - - MMRESULT WINAPI mmioFlush( HMMIO hmmio, UINT fuFlush) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioFlush\n"); - return mmioFlush_orig( hmmio, fuFlush); - } - - MMRESULT WINAPI mmioAdvance( HMMIO hmmio, LPMMIOINFO pmmioinfo, UINT fuAdvance) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioAdvance\n"); - return mmioAdvance_orig( hmmio, pmmioinfo, fuAdvance); - } - - LRESULT WINAPI mmioSendMessage( HMMIO hmmio, UINT uMsg, LPARAM lParam1, LPARAM lParam2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioSendMessage\n"); - return mmioSendMessage_orig(hmmio, uMsg, lParam1, lParam2); - } - - MMRESULT WINAPI mmioDescend( HMMIO hmmio, LPMMCKINFO pmmcki, const MMCKINFO FAR* pmmckiParent, UINT fuDescend) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioDescend\n"); - return mmioDescend_orig(hmmio, pmmcki, pmmckiParent, fuDescend); - } - - MMRESULT WINAPI mmioAscend( HMMIO hmmio, LPMMCKINFO pmmcki, UINT fuAscend) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioAscend\n"); - return mmioAscend_orig( hmmio, pmmcki, fuAscend); - } - - MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, LPMMCKINFO pmmcki, UINT fuCreate) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mmioCreateChunk\n"); - return mmioCreateChunk_orig(hmmio, pmmcki, fuCreate); - } - - MCIERROR WINAPI mciSendCommandA( MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciSendCommandA\n"); - return mciSendCommandA_orig( mciId, uMsg, dwParam1, dwParam2); - } - - MCIERROR WINAPI mciSendCommandW( MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciSendCommandW\n"); - return mciSendCommandW_orig( mciId, uMsg, dwParam1, dwParam2); - } - - MCIERROR WINAPI mciSendStringA( LPCSTR lpstrCommand, LPSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciSendStringA\n"); - return mciSendStringA_orig( lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback); - } - - MCIERROR WINAPI mciSendStringW( LPCWSTR lpstrCommand, LPWSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciSendStringW\n"); - return mciSendStringW_orig( lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback); - } - - MCIDEVICEID WINAPI mciGetDeviceIDA( LPCSTR pszDevice) - { - //OutputDebugString(L"mciGetDeviceIDA\n"); - return mciGetDeviceIDA_orig( pszDevice); - } - - MCIDEVICEID WINAPI mciGetDeviceIDW( LPCWSTR pszDevice) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciGetDeviceIDW\n"); - return mciGetDeviceIDW_orig( pszDevice); - } - - MCIDEVICEID WINAPI mciGetDeviceIDFromElementIDA( DWORD dwElementID, LPCSTR lpstrType ) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciGetDeviceIDFromElementIDA\n"); - return mciGetDeviceIDFromElementIDA_orig( dwElementID, lpstrType ); - } - - MCIDEVICEID WINAPI mciGetDeviceIDFromElementIDW( DWORD dwElementID, LPCWSTR lpstrType ) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciGetDeviceIDFromElementIDW\n"); - return mciGetDeviceIDFromElementIDW_orig( dwElementID, lpstrType ); - } - - DWORD_PTR WINAPI mciGetDriverData(UINT uDeviceID) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciGetDriverData\n"); - return mciGetDriverData_orig(uDeviceID); - } - - BOOL WINAPI mciGetErrorStringA( MCIERROR mcierr, LPSTR pszText, UINT cchText) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciGetErrorStringA\n"); - return mciGetErrorStringA_orig( mcierr, pszText, cchText); - } - - BOOL WINAPI mciGetErrorStringW( MCIERROR mcierr, LPWSTR pszText, UINT cchText) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciGetErrorStringW\n"); - return mciGetErrorStringW_orig( mcierr, pszText, cchText); - } - - BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD_PTR dwData) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciSetDriverData_type\n"); - return mciSetDriverData_orig( uDeviceID, dwData ); - } - - BOOL WINAPI mciSetYieldProc( MCIDEVICEID mciId, YIELDPROC fpYieldProc, DWORD dwYieldData) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciSetYieldProc\n"); - return mciSetYieldProc_orig(mciId, fpYieldProc, dwYieldData); - } - - BOOL WINAPI mciFreeCommandResource(UINT uTable) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciFreeCommandResource\n"); - return mciFreeCommandResource_orig(uTable); - } - - HTASK WINAPI mciGetCreatorTask( MCIDEVICEID mciId) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciGetCreatorTask\n"); - return mciGetCreatorTask_orig( mciId); - } - - YIELDPROC WINAPI mciGetYieldProc( MCIDEVICEID mciId, LPDWORD pdwYieldData) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciGetYieldProc\n"); - return mciGetYieldProc_orig( mciId, pdwYieldData); - } - - UINT WINAPI mciLoadCommandResource(HANDLE hInstance, LPCWSTR lpResName, UINT uType) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciLoadCommandResource"); - return mciLoadCommandResource_orig(hInstance, lpResName, uType); - } - - - BOOL WINAPI mciExecute(LPCSTR pszCommand) - { - ll_winmm_shim_initialize(); - //OutputDebugString(L"mciExecute\n"); - return mciExecute_orig(pszCommand); - } -} diff --git a/indra/media_plugins/winmmshim/forwarding_api.h b/indra/media_plugins/winmmshim/forwarding_api.h deleted file mode 100644 index 1418fc9e1da2c4a639f8244d03d68a1878eb1db2..0000000000000000000000000000000000000000 --- a/indra/media_plugins/winmmshim/forwarding_api.h +++ /dev/null @@ -1,390 +0,0 @@ -/** - * @file forwarding_api.h - * @brief forwards winmm API calls to real winmm.dll - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -// this turns off __declspec(dllimport) for the functions declared in mmsystem.h -#define _WINMM_ -#include <windows.h> -#include <mmsystem.h> - -void init_function_pointers(HMODULE winmm_handle); -void ll_winmm_shim_initialize(); - -typedef VOID (*LPTASKCALLBACK)(DWORD_PTR dwInst); - -typedef LRESULT (WINAPI *CloseDriver_type)( HDRVR hDriver, LPARAM lParam1, LPARAM lParam2); -extern CloseDriver_type CloseDriver_orig; -typedef HDRVR (WINAPI *OpenDriver_type)( LPCWSTR szDriverName, LPCWSTR szSectionName, LPARAM lParam2); -extern OpenDriver_type OpenDriver_orig; -typedef LRESULT (WINAPI *SendDriverMessage_type)( HDRVR hDriver, UINT message, LPARAM lParam1, LPARAM lParam2); -extern SendDriverMessage_type SendDriverMessage_orig; -typedef HMODULE (WINAPI *DrvGetModuleHandle_type)( HDRVR hDriver); -extern DrvGetModuleHandle_type DrvGetModuleHandle_orig; -typedef HMODULE (WINAPI *GetDriverModuleHandle_type)( HDRVR hDriver); -extern GetDriverModuleHandle_type GetDriverModuleHandle_orig; -typedef LRESULT (WINAPI *DefDriverProc_type)( DWORD_PTR dwDriverIdentifier, HDRVR hdrvr, UINT uMsg, LPARAM lParam1, LPARAM lParam2); -extern DefDriverProc_type DefDriverProc_orig; -typedef BOOL (WINAPI *DriverCallback_type)(DWORD dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2); -extern DriverCallback_type DriverCallback_orig; -typedef UINT (WINAPI *mmsystemGetVersion_type)(void); -extern mmsystemGetVersion_type mmsystemGetVersion_orig; -typedef BOOL (WINAPI *sndPlaySoundA_type)( LPCSTR pszSound, UINT fuSound); -extern sndPlaySoundA_type sndPlaySoundA_orig; -typedef BOOL (WINAPI *sndPlaySoundW_type)( LPCWSTR pszSound, UINT fuSound); -extern sndPlaySoundW_type sndPlaySoundW_orig; -typedef BOOL (WINAPI *PlaySoundA_type)( LPCSTR pszSound, HMODULE hmod, DWORD fdwSound); -extern PlaySoundA_type PlaySoundA_orig; -typedef BOOL (WINAPI *PlaySoundW_type)( LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound); -extern PlaySoundW_type PlaySoundW_orig; -typedef UINT (WINAPI *waveOutGetNumDevs_type)(void); -extern waveOutGetNumDevs_type waveOutGetNumDevs_orig; -typedef MMRESULT (WINAPI *waveOutGetDevCapsA_type)( UINT_PTR uDeviceID, LPWAVEOUTCAPSA pwoc, UINT cbwoc); -extern waveOutGetDevCapsA_type waveOutGetDevCapsA_orig; -typedef MMRESULT (WINAPI *waveOutGetDevCapsW_type)( UINT_PTR uDeviceID, LPWAVEOUTCAPSW pwoc, UINT cbwoc); -extern waveOutGetDevCapsW_type waveOutGetDevCapsW_orig; -typedef MMRESULT (WINAPI *waveOutGetVolume_type)( HWAVEOUT hwo, LPDWORD pdwVolume); -extern waveOutGetVolume_type waveOutGetVolume_orig; -typedef MMRESULT (WINAPI *waveOutSetVolume_type)( HWAVEOUT hwo, DWORD dwVolume); -extern waveOutSetVolume_type waveOutSetVolume_orig; -typedef MMRESULT (WINAPI *waveOutGetErrorTextA_type)( MMRESULT mmrError, LPSTR pszText, UINT cchText); -extern waveOutGetErrorTextA_type waveOutGetErrorTextA_orig; -typedef MMRESULT (WINAPI *waveOutGetErrorTextW_type)( MMRESULT mmrError, LPWSTR pszText, UINT cchText); -extern waveOutGetErrorTextW_type waveOutGetErrorTextW_orig; -typedef MMRESULT (WINAPI *waveOutOpen_type)( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen); -extern waveOutOpen_type waveOutOpen_orig; -typedef MMRESULT (WINAPI *waveOutClose_type)( HWAVEOUT hwo); -extern waveOutClose_type waveOutClose_orig; -typedef MMRESULT (WINAPI *waveOutPrepareHeader_type)( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh); -extern waveOutPrepareHeader_type waveOutPrepareHeader_orig; -typedef MMRESULT (WINAPI *waveOutUnprepareHeader_type)( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh); -extern waveOutUnprepareHeader_type waveOutUnprepareHeader_orig; -typedef MMRESULT (WINAPI *waveOutWrite_type)( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh); -extern waveOutWrite_type waveOutWrite_orig; -typedef MMRESULT (WINAPI *waveOutPause_type)( HWAVEOUT hwo); -extern waveOutPause_type waveOutPause_orig; -typedef MMRESULT (WINAPI *waveOutRestart_type)( HWAVEOUT hwo); -extern waveOutRestart_type waveOutRestart_orig; -typedef MMRESULT (WINAPI *waveOutReset_type)( HWAVEOUT hwo); -extern waveOutReset_type waveOutReset_orig; -typedef MMRESULT (WINAPI *waveOutBreakLoop_type)( HWAVEOUT hwo); -extern waveOutBreakLoop_type waveOutBreakLoop_orig; -typedef MMRESULT (WINAPI *waveOutGetPosition_type)( HWAVEOUT hwo, LPMMTIME pmmt, UINT cbmmt); -extern waveOutGetPosition_type waveOutGetPosition_orig; -typedef MMRESULT (WINAPI *waveOutGetPitch_type)( HWAVEOUT hwo, LPDWORD pdwPitch); -extern waveOutGetPitch_type waveOutGetPitch_orig; -typedef MMRESULT (WINAPI *waveOutSetPitch_type)( HWAVEOUT hwo, DWORD dwPitch); -extern waveOutSetPitch_type waveOutSetPitch_orig; -typedef MMRESULT (WINAPI *waveOutGetPlaybackRate_type)( HWAVEOUT hwo, LPDWORD pdwRate); -extern waveOutGetPlaybackRate_type waveOutGetPlaybackRate_orig; -typedef MMRESULT (WINAPI *waveOutSetPlaybackRate_type)( HWAVEOUT hwo, DWORD dwRate); -extern waveOutSetPlaybackRate_type waveOutSetPlaybackRate_orig; -typedef MMRESULT (WINAPI *waveOutGetID_type)( HWAVEOUT hwo, LPUINT puDeviceID); -extern waveOutGetID_type waveOutGetID_orig; -typedef MMRESULT (WINAPI *waveOutMessage_type)( HWAVEOUT hwo, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2); -extern waveOutMessage_type waveOutMessage_orig; -typedef UINT (WINAPI *waveInGetNumDevs_type)(void); -extern waveInGetNumDevs_type waveInGetNumDevs_orig; -typedef MMRESULT (WINAPI *waveInGetDevCapsA_type)( UINT_PTR uDeviceID, LPWAVEINCAPSA pwic, UINT cbwic); -extern waveInGetDevCapsA_type waveInGetDevCapsA_orig; -typedef MMRESULT (WINAPI *waveInGetDevCapsW_type)( UINT_PTR uDeviceID, LPWAVEINCAPSW pwic, UINT cbwic); -extern waveInGetDevCapsW_type waveInGetDevCapsW_orig; -typedef MMRESULT (WINAPI *waveInGetErrorTextA_type)(MMRESULT mmrError, LPSTR pszText, UINT cchText); -extern waveInGetErrorTextA_type waveInGetErrorTextA_orig; -typedef MMRESULT (WINAPI *waveInGetErrorTextW_type)(MMRESULT mmrError, LPWSTR pszText, UINT cchText); -extern waveInGetErrorTextW_type waveInGetErrorTextW_orig; -typedef MMRESULT (WINAPI *waveInOpen_type)( LPHWAVEIN phwi, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen); -extern waveInOpen_type waveInOpen_orig; -typedef MMRESULT (WINAPI *waveInClose_type)( HWAVEIN hwi); -extern waveInClose_type waveInClose_orig; -typedef MMRESULT (WINAPI *waveInPrepareHeader_type)( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh); -extern waveInPrepareHeader_type waveInPrepareHeader_orig; -typedef MMRESULT (WINAPI *waveInUnprepareHeader_type)( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh); -extern waveInUnprepareHeader_type waveInUnprepareHeader_orig; -typedef MMRESULT (WINAPI *waveInAddBuffer_type)( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh); -extern waveInAddBuffer_type waveInAddBuffer_orig; -typedef MMRESULT (WINAPI *waveInStart_type)( HWAVEIN hwi); -extern waveInStart_type waveInStart_orig; -typedef MMRESULT (WINAPI *waveInStop_type)( HWAVEIN hwi); -extern waveInStop_type waveInStop_orig; -typedef MMRESULT (WINAPI *waveInReset_type)( HWAVEIN hwi); -extern waveInReset_type waveInReset_orig; -typedef MMRESULT (WINAPI *waveInGetPosition_type)( HWAVEIN hwi, LPMMTIME pmmt, UINT cbmmt); -extern waveInGetPosition_type waveInGetPosition_orig; -typedef MMRESULT (WINAPI *waveInGetID_type)( HWAVEIN hwi, LPUINT puDeviceID); -extern waveInGetID_type waveInGetID_orig; -typedef MMRESULT (WINAPI *waveInMessage_type)( HWAVEIN hwi, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2); -extern waveInMessage_type waveInMessage_orig; -typedef UINT (WINAPI *midiOutGetNumDevs_type)(void); -extern midiOutGetNumDevs_type midiOutGetNumDevs_orig; -typedef MMRESULT (WINAPI *midiStreamOpen_type)( LPHMIDISTRM phms, LPUINT puDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen); -extern midiStreamOpen_type midiStreamOpen_orig; -typedef MMRESULT (WINAPI *midiStreamClose_type)( HMIDISTRM hms); -extern midiStreamClose_type midiStreamClose_orig; -typedef MMRESULT (WINAPI *midiStreamProperty_type)( HMIDISTRM hms, LPBYTE lppropdata, DWORD dwProperty); -extern midiStreamProperty_type midiStreamProperty_orig; -typedef MMRESULT (WINAPI *midiStreamPosition_type)( HMIDISTRM hms, LPMMTIME lpmmt, UINT cbmmt); -extern midiStreamPosition_type midiStreamPosition_orig; -typedef MMRESULT (WINAPI *midiStreamOut_type)( HMIDISTRM hms, LPMIDIHDR pmh, UINT cbmh); -extern midiStreamOut_type midiStreamOut_orig; -typedef MMRESULT (WINAPI *midiStreamPause_type)( HMIDISTRM hms); -extern midiStreamPause_type midiStreamPause_orig; -typedef MMRESULT (WINAPI *midiStreamRestart_type)( HMIDISTRM hms); -extern midiStreamRestart_type midiStreamRestart_orig; -typedef MMRESULT (WINAPI *midiStreamStop_type)( HMIDISTRM hms); -extern midiStreamStop_type midiStreamStop_orig; -typedef MMRESULT (WINAPI *midiConnect_type)( HMIDI hmi, HMIDIOUT hmo, LPVOID pReserved); -extern midiConnect_type midiConnect_orig; -typedef MMRESULT (WINAPI *midiDisconnect_type)( HMIDI hmi, HMIDIOUT hmo, LPVOID pReserved); -extern midiDisconnect_type midiDisconnect_orig; -typedef MMRESULT (WINAPI *midiOutGetDevCapsA_type)( UINT_PTR uDeviceID, LPMIDIOUTCAPSA pmoc, UINT cbmoc); -extern midiOutGetDevCapsA_type midiOutGetDevCapsA_orig; -typedef MMRESULT (WINAPI *midiOutGetDevCapsW_type)( UINT_PTR uDeviceID, LPMIDIOUTCAPSW pmoc, UINT cbmoc); -extern midiOutGetDevCapsW_type midiOutGetDevCapsW_orig; -typedef MMRESULT (WINAPI *midiOutGetVolume_type)( HMIDIOUT hmo, LPDWORD pdwVolume); -extern midiOutGetVolume_type midiOutGetVolume_orig; -typedef MMRESULT (WINAPI *midiOutSetVolume_type)( HMIDIOUT hmo, DWORD dwVolume); -extern midiOutSetVolume_type midiOutSetVolume_orig; -typedef MMRESULT (WINAPI *midiOutGetErrorTextA_type)( MMRESULT mmrError, LPSTR pszText, UINT cchText); -extern midiOutGetErrorTextA_type midiOutGetErrorTextA_orig; -typedef MMRESULT (WINAPI *midiOutGetErrorTextW_type)( MMRESULT mmrError, LPWSTR pszText, UINT cchText); -extern midiOutGetErrorTextW_type midiOutGetErrorTextW_orig; -typedef MMRESULT (WINAPI *midiOutOpen_type)( LPHMIDIOUT phmo, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen); -extern midiOutOpen_type midiOutOpen_orig; -typedef MMRESULT (WINAPI *midiOutClose_type)( HMIDIOUT hmo); -extern midiOutClose_type midiOutClose_orig; -typedef MMRESULT (WINAPI *midiOutPrepareHeader_type)( HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh); -extern midiOutPrepareHeader_type midiOutPrepareHeader_orig; -typedef MMRESULT (WINAPI *midiOutUnprepareHeader_type)(HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh); -extern midiOutUnprepareHeader_type midiOutUnprepareHeader_orig; -typedef MMRESULT (WINAPI *midiOutShortMsg_type)( HMIDIOUT hmo, DWORD dwMsg); -extern midiOutShortMsg_type midiOutShortMsg_orig; -typedef MMRESULT (WINAPI *midiOutLongMsg_type)(HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh); -extern midiOutLongMsg_type midiOutLongMsg_orig; -typedef MMRESULT (WINAPI *midiOutReset_type)( HMIDIOUT hmo); -extern midiOutReset_type midiOutReset_orig; -typedef MMRESULT (WINAPI *midiOutCachePatches_type)( HMIDIOUT hmo, UINT uBank, LPWORD pwpa, UINT fuCache); -extern midiOutCachePatches_type midiOutCachePatches_orig; -typedef MMRESULT (WINAPI *midiOutCacheDrumPatches_type)( HMIDIOUT hmo, UINT uPatch, LPWORD pwkya, UINT fuCache); -extern midiOutCacheDrumPatches_type midiOutCacheDrumPatches_orig; -typedef MMRESULT (WINAPI *midiOutGetID_type)( HMIDIOUT hmo, LPUINT puDeviceID); -extern midiOutGetID_type midiOutGetID_orig; -typedef MMRESULT (WINAPI *midiOutMessage_type)( HMIDIOUT hmo, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2); -extern midiOutMessage_type midiOutMessage_orig; -typedef UINT (WINAPI *midiInGetNumDevs_type)(void); -extern midiInGetNumDevs_type midiInGetNumDevs_orig; -typedef MMRESULT (WINAPI *midiInGetDevCapsA_type)( UINT_PTR uDeviceID, LPMIDIINCAPSA pmic, UINT cbmic); -extern midiInGetDevCapsA_type midiInGetDevCapsA_orig; -typedef MMRESULT (WINAPI *midiInGetDevCapsW_type)( UINT_PTR uDeviceID, LPMIDIINCAPSW pmic, UINT cbmic); -extern midiInGetDevCapsW_type midiInGetDevCapsW_orig; -typedef MMRESULT (WINAPI *midiInGetErrorTextA_type)( MMRESULT mmrError, LPSTR pszText, UINT cchText); -extern midiInGetErrorTextA_type midiInGetErrorTextA_orig; -typedef MMRESULT (WINAPI *midiInGetErrorTextW_type)( MMRESULT mmrError, LPWSTR pszText, UINT cchText); -extern midiInGetErrorTextW_type midiInGetErrorTextW_orig; -typedef MMRESULT (WINAPI *midiInOpen_type)( LPHMIDIIN phmi, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen); -extern midiInOpen_type midiInOpen_orig; -typedef MMRESULT (WINAPI *midiInClose_type)( HMIDIIN hmi); -extern midiInClose_type midiInClose_orig; -typedef MMRESULT (WINAPI *midiInPrepareHeader_type)( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh); -extern midiInPrepareHeader_type midiInPrepareHeader_orig; -typedef MMRESULT (WINAPI *midiInUnprepareHeader_type)( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh); -extern midiInUnprepareHeader_type midiInUnprepareHeader_orig; -typedef MMRESULT (WINAPI *midiInAddBuffer_type)( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh); -extern midiInAddBuffer_type midiInAddBuffer_orig; -typedef MMRESULT (WINAPI *midiInStart_type)( HMIDIIN hmi); -extern midiInStart_type midiInStart_orig; -typedef MMRESULT (WINAPI *midiInStop_type)( HMIDIIN hmi); -extern midiInStop_type midiInStop_orig; -typedef MMRESULT (WINAPI *midiInReset_type)( HMIDIIN hmi); -extern midiInReset_type midiInReset_orig; -typedef MMRESULT (WINAPI *midiInGetID_type)( HMIDIIN hmi, LPUINT puDeviceID); -extern midiInGetID_type midiInGetID_orig; -typedef MMRESULT (WINAPI *midiInMessage_type)( HMIDIIN hmi, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2); -extern midiInMessage_type midiInMessage_orig; -typedef UINT (WINAPI *auxGetNumDevs_type)(void); -extern auxGetNumDevs_type auxGetNumDevs_orig; -typedef MMRESULT (WINAPI *auxGetDevCapsA_type)( UINT_PTR uDeviceID, LPAUXCAPSA pac, UINT cbac); -extern auxGetDevCapsA_type auxGetDevCapsA_orig; -typedef MMRESULT (WINAPI *auxGetDevCapsW_type)( UINT_PTR uDeviceID, LPAUXCAPSW pac, UINT cbac); -extern auxGetDevCapsW_type auxGetDevCapsW_orig; -typedef MMRESULT (WINAPI *auxSetVolume_type)( UINT uDeviceID, DWORD dwVolume); -extern auxSetVolume_type auxSetVolume_orig; -typedef MMRESULT (WINAPI *auxGetVolume_type)( UINT uDeviceID, LPDWORD pdwVolume); -extern auxGetVolume_type auxGetVolume_orig; -typedef MMRESULT (WINAPI *auxOutMessage_type)( UINT uDeviceID, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2); -extern auxOutMessage_type auxOutMessage_orig; -typedef UINT (WINAPI *mixerGetNumDevs_type)(void); -extern mixerGetNumDevs_type mixerGetNumDevs_orig; -typedef MMRESULT (WINAPI *mixerGetDevCapsA_type)( UINT_PTR uMxId, LPMIXERCAPSA pmxcaps, UINT cbmxcaps); -extern mixerGetDevCapsA_type mixerGetDevCapsA_orig; -typedef MMRESULT (WINAPI *mixerGetDevCapsW_type)( UINT_PTR uMxId, LPMIXERCAPSW pmxcaps, UINT cbmxcaps); -extern mixerGetDevCapsW_type mixerGetDevCapsW_orig; -typedef MMRESULT (WINAPI *mixerOpen_type)( LPHMIXER phmx, UINT uMxId, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen); -extern mixerOpen_type mixerOpen_orig; -typedef MMRESULT (WINAPI *mixerClose_type)( HMIXER hmx); -extern mixerClose_type mixerClose_orig; -typedef DWORD (WINAPI *mixerMessage_type)( HMIXER hmx, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2); -extern mixerMessage_type mixerMessage_orig; -typedef MMRESULT (WINAPI *mixerGetLineInfoA_type)( HMIXEROBJ hmxobj, LPMIXERLINEA pmxl, DWORD fdwInfo); -extern mixerGetLineInfoA_type mixerGetLineInfoA_orig; -typedef MMRESULT (WINAPI *mixerGetLineInfoW_type)( HMIXEROBJ hmxobj, LPMIXERLINEW pmxl, DWORD fdwInfo); -extern mixerGetLineInfoW_type mixerGetLineInfoW_orig; -typedef MMRESULT (WINAPI *mixerGetID_type)( HMIXEROBJ hmxobj, UINT FAR *puMxId, DWORD fdwId); -extern mixerGetID_type mixerGetID_orig; -typedef MMRESULT (WINAPI *mixerGetLineControlsA_type)( HMIXEROBJ hmxobj, LPMIXERLINECONTROLSA pmxlc, DWORD fdwControls); -extern mixerGetLineControlsA_type mixerGetLineControlsA_orig; -typedef MMRESULT (WINAPI *mixerGetLineControlsW_type)( HMIXEROBJ hmxobj, LPMIXERLINECONTROLSW pmxlc, DWORD fdwControls); -extern mixerGetLineControlsW_type mixerGetLineControlsW_orig; -typedef MMRESULT (WINAPI *mixerGetControlDetailsA_type)( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails); -extern mixerGetControlDetailsA_type mixerGetControlDetailsA_orig; -typedef MMRESULT (WINAPI *mixerGetControlDetailsW_type)( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails); -extern mixerGetControlDetailsW_type mixerGetControlDetailsW_orig; -typedef MMRESULT (WINAPI *mixerSetControlDetails_type)( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails); -extern mixerSetControlDetails_type mixerSetControlDetails_orig; -typedef DWORD (WINAPI *mmGetCurrentTask_type)(void); -extern mmGetCurrentTask_type mmGetCurrentTask_orig; -typedef void (WINAPI *mmTaskBlock_type)(DWORD); -extern mmTaskBlock_type mmTaskBlock_orig; -typedef UINT (WINAPI *mmTaskCreate_type)(LPTASKCALLBACK, HANDLE*, DWORD_PTR); -extern mmTaskCreate_type mmTaskCreate_orig; -typedef BOOL (WINAPI *mmTaskSignal_type)(DWORD); -extern mmTaskSignal_type mmTaskSignal_orig; -typedef VOID (WINAPI *mmTaskYield_type)(VOID); -extern mmTaskYield_type mmTaskYield_orig; -typedef MMRESULT (WINAPI *timeGetSystemTime_type)( LPMMTIME pmmt, UINT cbmmt); -extern timeGetSystemTime_type timeGetSystemTime_orig; -typedef DWORD (WINAPI *timeGetTime_type)(void); -extern timeGetTime_type timeGetTime_orig; -typedef MMRESULT (WINAPI *timeSetEvent_type)( UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD_PTR dwUser, UINT fuEvent); -extern timeSetEvent_type timeSetEvent_orig; -typedef MMRESULT (WINAPI *timeKillEvent_type)( UINT uTimerID); -extern timeKillEvent_type timeKillEvent_orig; -typedef MMRESULT (WINAPI *timeGetDevCaps_type)( LPTIMECAPS ptc, UINT cbtc); -extern timeGetDevCaps_type timeGetDevCaps_orig; -typedef MMRESULT (WINAPI *timeBeginPeriod_type)( UINT uPeriod); -extern timeBeginPeriod_type timeBeginPeriod_orig; -typedef MMRESULT (WINAPI *timeEndPeriod_type)( UINT uPeriod); -extern timeEndPeriod_type timeEndPeriod_orig; -typedef UINT (WINAPI *joyGetNumDevs_type)(void); -extern joyGetNumDevs_type joyGetNumDevs_orig; -typedef MMRESULT (WINAPI *joyConfigChanged_type)(DWORD dwFlags); -extern joyConfigChanged_type joyConfigChanged_orig; -typedef MMRESULT (WINAPI *joyGetDevCapsA_type)( UINT_PTR uJoyID, LPJOYCAPSA pjc, UINT cbjc); -extern joyGetDevCapsA_type joyGetDevCapsA_orig; -typedef MMRESULT (WINAPI *joyGetDevCapsW_type)( UINT_PTR uJoyID, LPJOYCAPSW pjc, UINT cbjc); -extern joyGetDevCapsW_type joyGetDevCapsW_orig; -typedef MMRESULT (WINAPI *joyGetPos_type)( UINT uJoyID, LPJOYINFO pji); -extern joyGetPos_type joyGetPos_orig; -typedef MMRESULT (WINAPI *joyGetPosEx_type)( UINT uJoyID, LPJOYINFOEX pji); -extern joyGetPosEx_type joyGetPosEx_orig; -typedef MMRESULT (WINAPI *joyGetThreshold_type)( UINT uJoyID, LPUINT puThreshold); -extern joyGetThreshold_type joyGetThreshold_orig; -typedef MMRESULT (WINAPI *joyReleaseCapture_type)( UINT uJoyID); -extern joyReleaseCapture_type joyReleaseCapture_orig; -typedef MMRESULT (WINAPI *joySetCapture_type)( HWND hwnd, UINT uJoyID, UINT uPeriod, BOOL fChanged); -extern joySetCapture_type joySetCapture_orig; -typedef MMRESULT (WINAPI *joySetThreshold_type)( UINT uJoyID, UINT uThreshold); -extern joySetThreshold_type joySetThreshold_orig; -typedef BOOL(WINAPI *mciDriverNotify_type)(HANDLE hwndCallback, MCIDEVICEID uDeviceID, UINT uStatus); -extern mciDriverNotify_type mciDriverNotify_orig; -typedef UINT (WINAPI *mciDriverYield_type)(UINT uDeviceID); -extern mciDriverYield_type mciDriverYield_orig; -typedef FOURCC (WINAPI *mmioStringToFOURCCA_type)( LPCSTR sz, UINT uFlags); -extern mmioStringToFOURCCA_type mmioStringToFOURCCA_orig; -typedef FOURCC (WINAPI *mmioStringToFOURCCW_type)( LPCWSTR sz, UINT uFlags); -extern mmioStringToFOURCCW_type mmioStringToFOURCCW_orig; -typedef LPMMIOPROC (WINAPI *mmioInstallIOProcA_type)( FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags); -extern mmioInstallIOProcA_type mmioInstallIOProcA_orig; -typedef LPMMIOPROC (WINAPI *mmioInstallIOProcW_type)( FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags); -extern mmioInstallIOProcW_type mmioInstallIOProcW_orig; -typedef HMMIO (WINAPI *mmioOpenA_type)( LPSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen); -extern mmioOpenA_type mmioOpenA_orig; -typedef HMMIO (WINAPI *mmioOpenW_type)( LPWSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen); -extern mmioOpenW_type mmioOpenW_orig; -typedef MMRESULT (WINAPI *mmioRenameA_type)( LPCSTR pszFileName, LPCSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename); -extern mmioRenameA_type mmioRenameA_orig; -typedef MMRESULT (WINAPI *mmioRenameW_type)( LPCWSTR pszFileName, LPCWSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename); -extern mmioRenameW_type mmioRenameW_orig; -typedef MMRESULT (WINAPI *mmioClose_type)( HMMIO hmmio, UINT fuClose); -extern mmioClose_type mmioClose_orig; -typedef LONG (WINAPI *mmioRead_type)( HMMIO hmmio, HPSTR pch, LONG cch); -extern mmioRead_type mmioRead_orig; -typedef LONG (WINAPI *mmioWrite_type)( HMMIO hmmio, const char _huge* pch, LONG cch); -extern mmioWrite_type mmioWrite_orig; -typedef LONG (WINAPI *mmioSeek_type)( HMMIO hmmio, LONG lOffset, int iOrigin); -extern mmioSeek_type mmioSeek_orig; -typedef MMRESULT (WINAPI *mmioGetInfo_type)( HMMIO hmmio, LPMMIOINFO pmmioinfo, UINT fuInfo); -extern mmioGetInfo_type mmioGetInfo_orig; -typedef MMRESULT (WINAPI *mmioSetInfo_type)( HMMIO hmmio, LPCMMIOINFO pmmioinfo, UINT fuInfo); -extern mmioSetInfo_type mmioSetInfo_orig; -typedef MMRESULT (WINAPI *mmioSetBuffer_type)( HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT fuBuffer); -extern mmioSetBuffer_type mmioSetBuffer_orig; -typedef MMRESULT (WINAPI *mmioFlush_type)( HMMIO hmmio, UINT fuFlush); -extern mmioFlush_type mmioFlush_orig; -typedef MMRESULT (WINAPI *mmioAdvance_type)( HMMIO hmmio, LPMMIOINFO pmmioinfo, UINT fuAdvance); -extern mmioAdvance_type mmioAdvance_orig; -typedef LRESULT (WINAPI *mmioSendMessage_type)( HMMIO hmmio, UINT uMsg, LPARAM lParam1, LPARAM lParam2); -extern mmioSendMessage_type mmioSendMessage_orig; -typedef MMRESULT (WINAPI *mmioDescend_type)( HMMIO hmmio, LPMMCKINFO pmmcki, const MMCKINFO FAR* pmmckiParent, UINT fuDescend); -extern mmioDescend_type mmioDescend_orig; -typedef MMRESULT (WINAPI *mmioAscend_type)( HMMIO hmmio, LPMMCKINFO pmmcki, UINT fuAscend); -extern mmioAscend_type mmioAscend_orig; -typedef MMRESULT (WINAPI *mmioCreateChunk_type)(HMMIO hmmio, LPMMCKINFO pmmcki, UINT fuCreate); -extern mmioCreateChunk_type mmioCreateChunk_orig; -typedef MCIERROR (WINAPI *mciSendCommandA_type)( MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2); -extern mciSendCommandA_type mciSendCommandA_orig; -typedef MCIERROR (WINAPI *mciSendCommandW_type)( MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2); -extern mciSendCommandW_type mciSendCommandW_orig; -typedef MCIERROR (WINAPI *mciSendStringA_type)( LPCSTR lpstrCommand, LPSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback); -extern mciSendStringA_type mciSendStringA_orig; -typedef MCIERROR (WINAPI *mciSendStringW_type)( LPCWSTR lpstrCommand, LPWSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback); -extern mciSendStringW_type mciSendStringW_orig; -typedef MCIDEVICEID (WINAPI *mciGetDeviceIDA_type)( LPCSTR pszDevice); -extern mciGetDeviceIDA_type mciGetDeviceIDA_orig; -typedef MCIDEVICEID (WINAPI *mciGetDeviceIDW_type)( LPCWSTR pszDevice); -extern mciGetDeviceIDW_type mciGetDeviceIDW_orig; -typedef MCIDEVICEID (WINAPI *mciGetDeviceIDFromElementIDA_type)( DWORD dwElementID, LPCSTR lpstrType ); -extern mciGetDeviceIDFromElementIDA_type mciGetDeviceIDFromElementIDA_orig; -typedef MCIDEVICEID (WINAPI *mciGetDeviceIDFromElementIDW_type)( DWORD dwElementID, LPCWSTR lpstrType ); -extern mciGetDeviceIDFromElementIDW_type mciGetDeviceIDFromElementIDW_orig; -typedef DWORD_PTR (WINAPI *mciGetDriverData_type)(UINT uDeviceID); -extern mciGetDriverData_type mciGetDriverData_orig; -typedef BOOL (WINAPI *mciGetErrorStringA_type)( MCIERROR mcierr, LPSTR pszText, UINT cchText); -extern mciGetErrorStringA_type mciGetErrorStringA_orig; -typedef BOOL (WINAPI *mciGetErrorStringW_type)( MCIERROR mcierr, LPWSTR pszText, UINT cchText); -extern mciGetErrorStringW_type mciGetErrorStringW_orig; -typedef BOOL (WINAPI *mciSetDriverData_type)(UINT uDeviceID, DWORD_PTR dwData); -extern mciSetDriverData_type mciSetDriverData_orig; -typedef BOOL (WINAPI *mciSetYieldProc_type)( MCIDEVICEID mciId, YIELDPROC fpYieldProc, DWORD dwYieldData); -extern mciSetYieldProc_type mciSetYieldProc_orig; -typedef BOOL (WINAPI *mciFreeCommandResource_type)(UINT uTable); -extern mciFreeCommandResource_type mciFreeCommandResource_orig; -typedef HTASK (WINAPI *mciGetCreatorTask_type)( MCIDEVICEID mciId); -extern mciGetCreatorTask_type mciGetCreatorTask_orig; -typedef YIELDPROC (WINAPI *mciGetYieldProc_type)( MCIDEVICEID mciId, LPDWORD pdwYieldData); -extern mciGetYieldProc_type mciGetYieldProc_orig; -typedef UINT (WINAPI *mciLoadCommandResource_type)(HANDLE hInstance, LPCWSTR lpResName, UINT uType); -extern mciLoadCommandResource_type mciLoadCommandResource_orig; -typedef BOOL (WINAPI *mciExecute_type)(LPCSTR pszCommand); -extern mciExecute_type mciExecute_orig; diff --git a/indra/media_plugins/winmmshim/winmm.def b/indra/media_plugins/winmmshim/winmm.def deleted file mode 100755 index c55a2845f8b50aa0e4a9e7a059ff9666f9df980c..0000000000000000000000000000000000000000 --- a/indra/media_plugins/winmmshim/winmm.def +++ /dev/null @@ -1,218 +0,0 @@ -; -; winmm.def -; -; Exports for WINMM DLL -; - -LIBRARY WINMM -EXPORTS -CloseDriver -DefDriverProc -DriverCallback -DrvGetModuleHandle -GetDriverModuleHandle -;MigrateAllDrivers -;MigrateSoundEvents -;NotifyCallbackData -OpenDriver -;PlaySound -PlaySoundA -PlaySoundW -SendDriverMessage -;WOW32DriverCallback -;WOW32ResolveMultiMediaHandle -;WOWAppExit -;WinmmLogoff -;WinmmLogon -;aux32Message -auxGetDevCapsA -auxGetDevCapsW -auxGetNumDevs -auxGetVolume -auxOutMessage -auxSetVolume -;gfxAddGfx -;gfxBatchChange -;gfxCreateGfxFactoriesList -;gfxCreateZoneFactoriesList -;gfxDestroyDeviceInterfaceList -;gfxEnumerateGfxs -;gfxLogoff -;gfxLogon -;gfxModifyGfx -;gfxOpenGfx -;gfxRemoveGfx -;joy32Message -joyConfigChanged -joyGetDevCapsA -joyGetDevCapsW -joyGetNumDevs -joyGetPos -joyGetPosEx -joyGetThreshold -joyReleaseCapture -joySetCapture -joySetThreshold -;mci32Message -mciDriverNotify -mciDriverYield -mciExecute -mciFreeCommandResource -mciGetCreatorTask -mciGetDeviceIDA -mciGetDeviceIDFromElementIDA -mciGetDeviceIDFromElementIDW -mciGetDeviceIDW -mciGetDriverData -mciGetErrorStringA -mciGetErrorStringW -mciGetYieldProc -mciLoadCommandResource -mciSendCommandA -mciSendCommandW -mciSendStringA -mciSendStringW -mciSetDriverData -mciSetYieldProc -;mid32Message -midiConnect -midiDisconnect -midiInAddBuffer -midiInClose -midiInGetDevCapsA -midiInGetDevCapsW -midiInGetErrorTextA -midiInGetErrorTextW -midiInGetID -midiInGetNumDevs -midiInMessage -midiInOpen -midiInPrepareHeader -midiInReset -midiInStart -midiInStop -midiInUnprepareHeader -midiOutCacheDrumPatches -midiOutCachePatches -midiOutClose -midiOutGetDevCapsA -midiOutGetDevCapsW -midiOutGetErrorTextA -midiOutGetErrorTextW -midiOutGetID -midiOutGetNumDevs -midiOutGetVolume -midiOutLongMsg -midiOutMessage -midiOutOpen -midiOutPrepareHeader -midiOutReset -midiOutSetVolume -midiOutShortMsg -midiOutUnprepareHeader -midiStreamClose -midiStreamOpen -midiStreamOut -midiStreamPause -midiStreamPosition -midiStreamProperty -midiStreamRestart -midiStreamStop -mixerClose -mixerGetControlDetailsA -mixerGetControlDetailsW -mixerGetDevCapsA -mixerGetDevCapsW -mixerGetID -mixerGetLineControlsA -mixerGetLineControlsW -mixerGetLineInfoA -mixerGetLineInfoW -mixerGetNumDevs -mixerMessage -mixerOpen -mixerSetControlDetails -;mmDrvInstall -mmGetCurrentTask -mmTaskBlock -mmTaskCreate -mmTaskSignal -mmTaskYield -mmioAdvance -mmioAscend -mmioClose -mmioCreateChunk -mmioDescend -mmioFlush -mmioGetInfo -mmioInstallIOProcA -mmioInstallIOProcW -mmioOpenA -mmioOpenW -mmioRead -mmioRenameA -mmioRenameW -mmioSeek -mmioSendMessage -mmioSetBuffer -mmioSetInfo -mmioStringToFOURCCA -mmioStringToFOURCCW -mmioWrite -mmsystemGetVersion -;mod32Message -;mxd32Message -sndPlaySoundA -sndPlaySoundW -;tid32Message -timeBeginPeriod -timeEndPeriod -timeGetDevCaps -timeGetSystemTime -timeGetTime -timeKillEvent -timeSetEvent -waveInAddBuffer -waveInClose -waveInGetDevCapsA -waveInGetDevCapsW -waveInGetErrorTextA -waveInGetErrorTextW -waveInGetID -waveInGetNumDevs -waveInGetPosition -waveInMessage -waveInOpen -waveInPrepareHeader -waveInReset -waveInStart -waveInStop -waveInUnprepareHeader -waveOutBreakLoop -waveOutClose -waveOutGetDevCapsA -waveOutGetDevCapsW -waveOutGetErrorTextA -waveOutGetErrorTextW -waveOutGetID -waveOutGetNumDevs -waveOutGetPitch -waveOutGetPlaybackRate -waveOutGetPosition -waveOutGetVolume -waveOutMessage -waveOutOpen -waveOutPause -waveOutPrepareHeader -waveOutReset -waveOutRestart -waveOutSetPitch -waveOutSetPlaybackRate -waveOutSetVolume -waveOutUnprepareHeader -waveOutWrite -;wid32Message -;winmmSetDebugLevel -;wod32Message -setPluginVolume -setPluginMute \ No newline at end of file diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp deleted file mode 100644 index 78f7a9b0dab5797a21b7a3c6a294540c0efb500f..0000000000000000000000000000000000000000 --- a/indra/media_plugins/winmmshim/winmm_shim.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/** - * @file winmmshim.cpp - * @brief controls volume level of process by intercepting calls to winmm.dll - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010-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$ - */ -#include "forwarding_api.h" -#include <xmmintrin.h> -#include <map> -#include <math.h> - -using std::wstring; - -static float sVolumeLevel = 1.f; // Could be covered by critical section, -static bool sMute = false; // not needed with atomicity and alignment. -static CRITICAL_SECTION sCriticalSection; - -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - if (ul_reason_for_call == DLL_PROCESS_ATTACH) - { - InitializeCriticalSection(&sCriticalSection); - } - return TRUE; -} - -void ll_winmm_shim_initialize(){ - static volatile bool initialized = false; - - // do this only once using double-check locking - if (!initialized) - { - EnterCriticalSection(&sCriticalSection); - if (!initialized) - { // bind to original winmm.dll - TCHAR system_path[MAX_PATH]; - TCHAR dll_path[MAX_PATH]; - ::GetSystemDirectory(system_path, MAX_PATH); - - // grab winmm.dll from system path, where it should live - wsprintf(dll_path, "%s\\winmm.dll", system_path); - HMODULE winmm_handle = ::LoadLibrary(dll_path); - - if (winmm_handle != NULL) - { // we have a dll, let's get out pointers! - init_function_pointers(winmm_handle); - ::OutputDebugStringA("WINMM_SHIM.DLL: real winmm.dll initialized successfully\n"); - initialized = true; // Last thing after completing setup - } - else - { - // failed to initialize real winmm.dll - ::OutputDebugStringA("WINMM_SHIM.DLL: Failed to initialize real winmm.dll\n"); - } - } - LeaveCriticalSection(&sCriticalSection); - } -} - - -extern "C" -{ - // tracks the requested format for a given waveout buffer - struct WaveOutFormat - { - WaveOutFormat(int bits_per_sample) - : mBitsPerSample(bits_per_sample) - {} - int mBitsPerSample; - }; - typedef std::map<HWAVEOUT, WaveOutFormat*> wave_out_map_t; - static wave_out_map_t sWaveOuts; // Covered by sCriticalSection - - MMRESULT WINAPI waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) - { - ll_winmm_shim_initialize(); - if (pwfx->wFormatTag != WAVE_FORMAT_PCM - || (pwfx->wBitsPerSample != 8 && pwfx->wBitsPerSample != 16)) - { // uncompressed 8 and 16 bit sound are the only types we support - return WAVERR_BADFORMAT; - } - - MMRESULT result = waveOutOpen_orig(phwo, uDeviceID, pwfx, dwCallback, dwInstance, fdwOpen); - if (result == MMSYSERR_NOERROR - && ((fdwOpen & WAVE_FORMAT_QUERY) == 0)) // not just querying for format support - { // remember the requested bits per sample, and associate with the given handle - WaveOutFormat* wave_outp = new WaveOutFormat(pwfx->wBitsPerSample); - EnterCriticalSection(&sCriticalSection); - sWaveOuts.insert(std::make_pair(*phwo, wave_outp)); - LeaveCriticalSection(&sCriticalSection); - } - return result; - } - - MMRESULT WINAPI waveOutClose( HWAVEOUT hwo) - { - ll_winmm_shim_initialize(); - EnterCriticalSection(&sCriticalSection); - wave_out_map_t::iterator found_it = sWaveOuts.find(hwo); - if (found_it != sWaveOuts.end()) - { // forget what we know about this handle - delete found_it->second; - sWaveOuts.erase(found_it); - } - LeaveCriticalSection(&sCriticalSection); - return waveOutClose_orig(hwo); - } - - MMRESULT WINAPI waveOutWrite( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) - { - ll_winmm_shim_initialize(); - MMRESULT result = MMSYSERR_NOERROR; - - if (sMute) - { // zero out the audio buffer when muted - memset(pwh->lpData, 0, pwh->dwBufferLength); - } - else if (sVolumeLevel != 1.f) - { // need to apply volume level - int bits_per_sample(0); - - EnterCriticalSection(&sCriticalSection); - wave_out_map_t::iterator found_it = sWaveOuts.find(hwo); - if (found_it != sWaveOuts.end()) - { - bits_per_sample = found_it->second->mBitsPerSample; - } - LeaveCriticalSection(&sCriticalSection); - if (bits_per_sample) - { - switch (bits_per_sample) - { - case 8: - { - char volume = (char)(sVolumeLevel * 127.f); - for (unsigned int i = 0; i < pwh->dwBufferLength; i++) - { - // unsigned multiply doesn't use most significant bit, so shift by 7 bits - // to get resulting value back into 8 bits - pwh->lpData[i] = (pwh->lpData[i] * volume) >> 7; - } - break; - } - case 16: - { - short volume_16 = (short)(sVolumeLevel * 32767.f); - - // copy volume level 4 times into 64 bit MMX register - __m64 volume_64 = _mm_set_pi16(volume_16, volume_16, volume_16, volume_16); - __m64* sample_64; - __m64* last_sample_64 = (__m64*)(pwh->lpData + pwh->dwBufferLength - sizeof(__m64)); - // for everything that can be addressed in 64 bit multiples... - for (sample_64 = (__m64*)pwh->lpData; - sample_64 <= last_sample_64; - ++sample_64) - { - //...multiply the samples by the volume... - __m64 scaled_sample = _mm_mulhi_pi16(*sample_64, volume_64); - // ...and shift left 1 bit since an unsigned multiple loses the most significant bit - // 0x7FFF * 0x7FFF = 0x3fff0001 - // 0x3fff0001 << 1 = 0x7ffe0002 - // notice that the LSB is always 0...should consider dithering - *sample_64 = _mm_slli_pi16(scaled_sample, 1); - } - - // the captain has turned off the MMX sign, you are now free to use floating point registers - _mm_empty(); - - // finish remaining samples that didn't fit into 64 bit register - for (short* sample_16 = (short*)sample_64; - sample_16 < (short*)(pwh->lpData + pwh->dwBufferLength); - ++sample_16) - { - *sample_16 = (*sample_16 * volume_16) >> 15; - } - - break; - } - default: - // don't do anything - break; - } - } - } - return waveOutWrite_orig( hwo, pwh, cbwh); - } - - void WINAPI setPluginVolume(float volume) - { - sVolumeLevel = volume; - } - - void WINAPI setPluginMute(bool mute) - { - sMute = mute; - } -} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 999165528a529d3a7fa888ab22055623d6481641..394a9c85783dd0a6b59036523259d7d986d6e155 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -13,7 +13,6 @@ include(DragDrop) include(EXPAT) include(FMODEX) include(GLOD) -include(GooglePerfTools) include(Hunspell) include(JsonCpp) include(LLAppearance) @@ -248,7 +247,6 @@ set(viewer_SOURCE_FILES llfloaterimsession.cpp llfloaterimcontainer.cpp llfloaterinspect.cpp - llfloaterinventory.cpp llfloaterjoystick.cpp llfloaterlagmeter.cpp llfloaterland.cpp @@ -262,7 +260,9 @@ set(viewer_SOURCE_FILES llfloatermodeluploadbase.cpp llfloaternamedesc.cpp llfloaternotificationsconsole.cpp - llfloaternotificationstabbed.cpp + llfloaternotificationstabbed.cpp + llfloateroutfitphotopreview.cpp + llfloateroutfitsnapshot.cpp llfloaterobjectweights.cpp llfloateropenobject.cpp llfloaterpathfindingcharacters.cpp @@ -403,6 +403,7 @@ set(viewer_SOURCE_FILES llnotificationscripthandler.cpp llnotificationstorage.cpp llnotificationtiphandler.cpp + lloutfitgallery.cpp lloutfitslist.cpp lloutfitobserver.cpp lloutputmonitorctrl.cpp @@ -533,6 +534,7 @@ set(viewer_SOURCE_FILES llsidepaneliteminfo.cpp llsidepaneltaskinfo.cpp llsidetraypanelcontainer.cpp + llskinningutil.cpp llsky.cpp llslurl.cpp llsnapshotlivepreview.cpp @@ -864,7 +866,6 @@ set(viewer_HEADER_FILES llfloaterimsession.h llfloaterimcontainer.h llfloaterinspect.h - llfloaterinventory.h llfloaterjoystick.h llfloaterlagmeter.h llfloaterland.h @@ -878,7 +879,9 @@ set(viewer_HEADER_FILES llfloatermodeluploadbase.h llfloaternamedesc.h llfloaternotificationsconsole.h - llfloaternotificationstabbed.h + llfloaternotificationstabbed.h + llfloateroutfitphotopreview.h + llfloateroutfitsnapshot.h llfloaterobjectweights.h llfloateropenobject.h llfloaterpathfindingcharacters.h @@ -1009,6 +1012,7 @@ set(viewer_HEADER_FILES llnotificationlistview.h llnotificationmanager.h llnotificationstorage.h + lloutfitgallery.h lloutfitslist.h lloutfitobserver.h lloutputmonitorctrl.h @@ -1137,9 +1141,11 @@ set(viewer_HEADER_FILES llsidepaneliteminfo.h llsidepaneltaskinfo.h llsidetraypanelcontainer.h + llskinningutil.h llsky.h llslurl.h llsnapshotlivepreview.h + llsnapshotmodel.h llspatialpartition.h llspeakers.h llspeakingindicatormanager.h @@ -1424,7 +1430,7 @@ if (WINDOWS) set(ICON_PATH "project") set(VIEWER_MACOSX_PHASE "a") endif() - message("Copying icons for ${ICON_PATH}") + message(STATUS "Copying icons for ${ICON_PATH}") execute_process( COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/icons/${ICON_PATH}/secondlife.ico" @@ -1675,7 +1681,7 @@ if (WINDOWS) set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES # *TODO -reenable this once we get server usage sorted out - LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_LINK_FLAGS} /LARGEADDRESSAWARE" + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE" LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO /LARGEADDRESSAWARE" LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF /LARGEADDRESSAWARE" ) @@ -1695,20 +1701,8 @@ if (WINDOWS) # In the meantime, if you have any ideas on how to easily maintain one list, either here or in viewer_manifest.py # and have the build deps get tracked *please* tell me about it. - if(USE_TCMALLOC) - # Configure a var for tcmalloc location, if used. - # Note the need to specify multiple names explicitly. - set(GOOGLE_PERF_TOOLS_SOURCE - ${SHARED_LIB_STAGING_DIR}/Release/libtcmalloc_minimal.dll - ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libtcmalloc_minimal.dll - ${SHARED_LIB_STAGING_DIR}/Debug/libtcmalloc_minimal-debug.dll - ) - endif(USE_TCMALLOC) - - set(COPY_INPUT_DEPENDENCIES # The following commented dependencies are determined at variably at build time. Can't do this here. - #${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libtcmalloc_minimal.dll => None ... Skipping libtcmalloc_minimal.dll ${CMAKE_SOURCE_DIR}/../etc/message.xml ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/llcommon.dll @@ -1747,9 +1741,10 @@ if (WINDOWS) ${ARCH_PREBUILT_DIRS_RELEASE}/ssleay32.dll ${ARCH_PREBUILT_DIRS_DEBUG}/libeay32.dll ${ARCH_PREBUILT_DIRS_DEBUG}/ssleay32.dll + ${viewer_APPSETTINGS_FILES} SLPlugin - media_plugin_quicktime media_plugin_cef + media_plugin_libvlc winmm_shim windows-crash-logger ) @@ -1827,7 +1822,7 @@ add_custom_target(compile_w_viewer_update_manager ALL DEPENDS ${CMAKE_CFG_INTDIR --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} --grid=${GRID} - --channel=${VIEWER_CHANNEL} + "--channel=${VIEWER_CHANNEL}" --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --source=${CMAKE_CURRENT_SOURCE_DIR} --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat @@ -1890,7 +1885,7 @@ add_custom_target(compile_w_viewer_update_manager ALL DEPENDS ${CMAKE_CFG_INTDIR --artwork=${ARTWORK_DIR} --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} - --channel=${VIEWER_CHANNEL} + "--channel=${VIEWER_CHANNEL}" --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} @@ -2000,7 +1995,6 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLLOGIN_LIBRARIES} ${LLPHYSICS_LIBRARIES} ${LLPHYSICSEXTENSIONS_LIBRARIES} - ${TCMALLOC_LIBRARIES} ${LLAPPEARANCE_LIBRARIES} ) @@ -2016,6 +2010,7 @@ if (LINUX) linux-crash-logger SLPlugin media_plugin_gstreamer010 + media_plugin_libvlc llcommon ) @@ -2028,7 +2023,7 @@ if (LINUX) --artwork=${ARTWORK_DIR} --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} - --channel=${VIEWER_CHANNEL} + "--channel=${VIEWER_CHANNEL}" --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged @@ -2056,7 +2051,7 @@ if (LINUX) --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged --grid=${GRID} - --channel=${VIEWER_CHANNEL} + "--channel=${VIEWER_CHANNEL}" --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --source=${CMAKE_CURRENT_SOURCE_DIR} DEPENDS @@ -2117,7 +2112,7 @@ if (DARWIN) --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app --grid=${GRID} - --channel=${VIEWER_CHANNEL} + "--channel=${VIEWER_CHANNEL}" --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --source=${CMAKE_CURRENT_SOURCE_DIR} DEPENDS @@ -2125,7 +2120,7 @@ if (DARWIN) ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_cef mac-crash-logger) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef mac-crash-logger) add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger) if (ENABLE_SIGNING) @@ -2146,11 +2141,10 @@ if (DARWIN) --artwork=${ARTWORK_DIR} --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} - --channel=${VIEWER_CHANNEL} --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app --grid=${GRID} - --channel=${VIEWER_CHANNEL} + "--channel=${VIEWER_CHANNEL}" --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --source=${CMAKE_CURRENT_SOURCE_DIR} --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched @@ -2167,9 +2161,10 @@ endif (INSTALL) if (PACKAGE) set(SYMBOL_SEARCH_DIRS "") + # Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh if (WINDOWS) list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") - set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-windows.tar.bz2") + set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-windows-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2") # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe") set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}") @@ -2182,15 +2177,14 @@ if (PACKAGE) list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}") list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}") list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}") - list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}") - set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2") + set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2") set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger") set(VIEWER_EXE_GLOBS "'Second Life' mac-crash-logger") set(VIEWER_LIB_GLOB "*.dylib") endif (DARWIN) if (LINUX) list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged") - set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux.tar.bz2") + set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2") set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin") set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin") set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*") diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index d13e837c8ecbbe09e8fe5676e097167fe79812fc..831446cbd27a6de403344b21c9fa93a25357f43d 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -4.0.6 +5.1.0 diff --git a/indra/newview/app_settings/anim.ini b/indra/newview/app_settings/anim.ini index 63c84e544db9134850205ed7bf9a29ec90e4694a..c24d2749ef90981257d4bf43c05d5426c022f86c 100644 --- a/indra/newview/app_settings/anim.ini +++ b/indra/newview/app_settings/anim.ini @@ -1,87 +1,2 @@ Translations 1.0 -[hip] - relativepos = firstkey - relativerot = firstkey - outname = mPelvis - frame = 0 1 0, 0 0 1, 1 0 0 - -[abdomen] - outname = mTorso - frame = 0 1 0, 0 0 1, 1 0 0 - -[chest] - outname = mChest - frame = 0 1 0, 0 0 1, 1 0 0 - -[neckDummy] - ignore = true - frame = 0 1 0, 0 0 1, 1 0 0 - -[neck] - outname = mNeck - frame = 0 1 0, 0 0 1, 1 0 0 - -[head] - outname = mHead - frame = 0 1 0, 0 0 1, 1 0 0 - -[figureHair] - ignore = true - frame = 0 1 0, 0 0 1, 1 0 0 - -[lCollar] - outname = mCollarLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lShldr] - outname = mShoulderLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lForeArm] - outname = mElbowLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lHand] - outname = mWristLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[rCollar] - outname = mCollarRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rShldr] - outname = mShoulderRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rForeArm] - outname = mElbowRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rHand] - outname = mWristRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[lThigh] - outname = mHipLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lShin] - outname = mKneeLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lFoot] - outname = mAnkleLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[rThigh] - outname = mHipRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rShin] - outname = mKneeRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rFoot] - outname = mAnkleRight - frame = 0 1 0, 0 0 1, 1 0 0 \ No newline at end of file diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index a0d3dc0f998ace803f3c6dbc614f1213e2d7694b..9bc0a7c70142365f29126c67a38aae447ea8e500 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -282,4 +282,14 @@ is_running_function="Floater.IsOpen" is_running_parameters="camera" /> + <command name="reporter" + available_in_toybox="true" + icon="Command_Report_Abuse_Icon" + label_ref="Command_Report_Abuse_Label" + tooltip_ref="Command_Report_Abuse_Tooltip" + execute_function="Floater.ToggleOrBringToFront" + execute_parameters="reporter" + is_running_function="Floater.IsOpen" + is_running_parameters="reporter" + /> </commands> diff --git a/indra/newview/app_settings/keywords_lsl_default.xml b/indra/newview/app_settings/keywords_lsl_default.xml index ddd287faf4b27c2237cf7ee7c12d6dfe5d5cf565..d641883d5ac4026c5c338b1d328866846ef92b04 100644 --- a/indra/newview/app_settings/keywords_lsl_default.xml +++ b/indra/newview/app_settings/keywords_lsl_default.xml @@ -528,7 +528,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>27</integer> + <integer>26</integer> <key>tooltip</key> <string>Attach to the avatar's lower upper leg.</string> </map> @@ -678,6 +678,141 @@ <key>tooltip</key> <string>Attach to the avatar's right upper leg.</string> </map> + <key>ATTACH_LHAND_RING1</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>41</integer> + <key>tooltip</key> + <string>Attach to the avatar's left ring finger.</string> + </map> + <key>ATTACH_RHAND_RING1</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>42</integer> + <key>tooltip</key> + <string>Attach to the avatar's right ring finger.</string> + </map> + <key>ATTACH_TAIL_BASE</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>43</integer> + <key>tooltip</key> + <string>Attach to the avatar's tail base.</string> + </map> + <key>ATTACH_TAIL_TIP</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>44</integer> + <key>tooltip</key> + <string>Attach to the avatar's tail tip.</string> + </map> + <key>ATTACH_LWING</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>45</integer> + <key>tooltip</key> + <string>Attach to the avatar's left wing.</string> + </map> + <key>ATTACH_RWING</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>46</integer> + <key>tooltip</key> + <string>Attach to the avatar's right wing.</string> + </map> + <key>ATTACH_FACE_JAW</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>47</integer> + <key>tooltip</key> + <string>Attach to the avatar's jaw.</string> + </map> + <key>ATTACH_FACE_LEAR</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>48</integer> + <key>tooltip</key> + <string>Attach to the avatar's left ear (extended).</string> + </map> + <key>ATTACH_FACE_REAR</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>49</integer> + <key>tooltip</key> + <string>Attach to the avatar's right ear (extended).</string> + </map> + <key>ATTACH_FACE_LEYE</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>50</integer> + <key>tooltip</key> + <string>Attach to the avatar's left eye (extended).</string> + </map> + <key>ATTACH_FACE_REYE</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>51</integer> + <key>tooltip</key> + <string>Attach to the avatar's right eye (extended).</string> + </map> + <key>ATTACH_FACE_TONGUE</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>52</integer> + <key>tooltip</key> + <string>Attach to the avatar's tongue.</string> + </map> + <key>ATTACH_GROIN</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>53</integer> + <key>tooltip</key> + <string>Attach to the avatar's groin.</string> + </map> + <key>ATTACH_HIND_LFOOT</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>54</integer> + <key>tooltip</key> + <string>Attach to the avatar's left hind foot.</string> + </map> + <key>ATTACH_HIND_RFOOT</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>55</integer> + <key>tooltip</key> + <string>Attach to the avatar's right hind foot.</string> + </map> <key>AVOID_CHARACTERS</key> <map> <key>type</key> @@ -809,7 +944,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>6</integer> + <integer>5</integer> <key>tooltip</key> <string/> </map> @@ -818,7 +953,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>22</integer> + <integer>21</integer> <key>tooltip</key> <string/> </map> @@ -872,7 +1007,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>2048</integer> + <string>0x800</string> <key>tooltip</key> <string/> </map> @@ -1463,9 +1598,9 @@ <key>type</key> <string>float</string> <key>value</key> - <real>0.01745329</real> + <real>0.017453293</real> <key>tooltip</key> - <string>0.01745329 - Number of radians per degree. + <string>0.017453293 - Number of radians per degree. You can use this to convert degrees to radians by multiplying the degrees by this number.</string> </map> <key>DENSITY</key> @@ -1482,7 +1617,7 @@ <key>type</key> <string>string</string> <key>value</key> - <string>0x0A0x0A0x0A</string> + <string>\\n\\n\\n</string> <key>tooltip</key> <string>Indicates the last line of a notecard was read.</string> </map> @@ -2299,7 +2434,7 @@ <key>NULL_KEY</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>00000000-0000-0000-0000-000000000000</uuid> <key>tooltip</key> @@ -2395,6 +2530,15 @@ <key>tooltip</key> <string>Gets the object's name.</string> </map> + <key>OBJECT_OMEGA</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>29</integer> + <key>tooltip</key> + <string>Gets an object's angular velocity.</string> + </map> <key>OBJECT_OWNER</key> <map> <key>type</key> @@ -2404,6 +2548,15 @@ <key>tooltip</key> <string>Gets an object's owner's key. If id is group owned, a NULL_KEY is returned.</string> </map> + <key>OBJECT_PRIM_COUNT</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>30</integer> + <key>tooltip</key> + <string>Gets the prim count of the object. The script and target object must be owned by the same owner</string> + </map> <key>OBJECT_PATHFINDING_TYPE</key> <map> <key>type</key> @@ -2494,6 +2647,15 @@ <key>tooltip</key> <string/> </map> + <key>OBJECT_REZZER_KEY</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>32</integer> + <key>tooltip</key> + <string/> + </map> <key>OBJECT_ROOT</key> <map> <key>type</key> @@ -2566,6 +2728,15 @@ <key>tooltip</key> <string>Returns boolean, detailing if temporary is enabled or disabled on the object.</string> </map> + <key>OBJECT_TOTAL_INVENTORY_COUNT</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>31</integer> + <key>tooltip</key> + <string>Gets the total inventory count of the object. The script and target object must be owned by the same owner</string> + </map> <key>OBJECT_TOTAL_SCRIPT_COUNT</key> <map> <key>type</key> @@ -3052,6 +3223,33 @@ <key>tooltip</key> <string/> </map> + <key>PASS_ALWAYS</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <string>1</string> + <key>tooltip</key> + <string>Always pass the event.</string> + </map> + <key>PASS_NEVER</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <string>2</string> + <key>tooltip</key> + <string>Always pass the event.</string> + </map> + <key>PASS_IF_NOT_HANDLED</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <string>0</string> + <key>tooltip</key> + <string>Pass the event if there is no script handling the event in the prim.</string> + </map> <key>PASSIVE</key> <map> <key>type</key> @@ -4387,6 +4585,24 @@ <key>tooltip</key> <string/> </map> + <key>PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>5</integer> + <key>tooltip</key> + <string/> + </map> + <key>PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA</key> + <map> + <key>type</key> + <string>integer</string> + <key>value</key> + <integer>9</integer> + <key>tooltip</key> + <string/> + </map> <key>PSYS_PART_BF_SOURCE_ALPHA</key> <map> <key>type</key> @@ -4536,7 +4752,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>19</integer> + <integer>7</integer> <key>tooltip</key> <string>Age in seconds of a particle at which it dies.</string> </map> @@ -5061,7 +5277,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>2</integer> + <integer>0</integer> <key>tooltip</key> <string/> </map> @@ -5295,7 +5511,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>64</integer> + <string>0x40</string> <key>tooltip</key> <string>Controls whether the object can be grabbed.\nA grab is the default action when in third person, and is available as the hand tool in build mode. This is useful for physical objects that you don't want other people to be able to trivially disturb. The default is FALSE</string> </map> @@ -5304,7 +5520,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>1024</integer> + <string>0x400</string> <key>tooltip</key> <string>Prevent click-and-drag movement on all prims in the object.</string> </map> @@ -5500,7 +5716,7 @@ <key>TEXTURE_BLANK</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>5748decc-f629-461c-9a36-a35a221fe21f</uuid> <key>tooltip</key> @@ -5509,7 +5725,7 @@ <key>TEXTURE_DEFAULT</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>89556747-24cb-43ed-920b-47caed15465f</uuid> <key>tooltip</key> @@ -5518,7 +5734,7 @@ <key>TEXTURE_MEDIA</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>8b5fec65-8d8d-9dc5-cda8-8fdf2716e361</uuid> <key>tooltip</key> @@ -5527,7 +5743,7 @@ <key>TEXTURE_PLYWOOD</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>89556747-24cb-43ed-920b-47caed15465f</uuid> <key>tooltip</key> @@ -5536,7 +5752,7 @@ <key>TEXTURE_TRANSPARENT</key> <map> <key>type</key> - <string>key</string> + <string>string</string> <key>value</key> <uuid>8dcd4a48-2d37-4909-9f78-f7a9eb4ef903</uuid> <key>tooltip</key> @@ -5956,7 +6172,7 @@ <key>type</key> <string>integer</string> <key>value</key> - <integer>35</integer> + <integer>31</integer> <key>tooltip</key> <string>The timescale for exponential decay of the linear motors magnitude.</string> </map> @@ -6204,15 +6420,6 @@ <key>tooltip</key> <string>An attempted write data to the key-value store failed due to the data quota being met.</string> </map> - <key>LSL_XP_ERROR_REQUEST_PERM_TIMEOUT</key> - <map> - <key>type</key> - <string>integer</string> - <key>value</key> - <integer>18</integer> - <key>tooltip</key> - <string>The request for experience permissions was ignored and timed out.</string> - </map> <key>XP_ERROR_RETRY_UPDATE</key> <map> <key>type</key> @@ -6562,30 +6769,43 @@ <key>experience_permissions</key> <map> <key>arguments</key> - <map> - <key>agent_id</key> - <map> + <array> + <map> + <key>agent_id</key> + <map> <key>type</key> <string>key</string> <key>tooltip</key> <string>ID of the agent approving permission for the Experience.</string> - </map> - </map> + </map> + </map> + </array> </map> <key>experience_permissions_denied</key> <map> <key>arguments</key> - <map> - <key>agent_id</key> - <map> + <array> + <map> + <key>agent_id</key> + <map> <key>type</key> <string>key</string> <key>tooltip</key> <string>ID of the agent denying permission for the Experience.</string> - </map> - </map> + </map> + </map> + <map> + <key>Reason</key> + <map> + <key>type</key> + <string>integer</string> + <key>tooltip</key> + <string>One of the XP_ERROR_... constants describing the reason why the Experience permissions were denied for the agent.</string> + </map> + </map> + </array> <key>tooltip</key> - <string>One of the XP_ERROR_... constants describing the reason why the Experience permissions were denied for the agent.</string> + <string>Describes why the Experience permissions were denied for the agent.</string> </map> <key>http_request</key> <map> @@ -7281,15 +7501,17 @@ <key>return</key> <string>integer</string> <key>arguments</key> - <map> - <key>AgentID</key> - <map> + <array> + <map> + <key>AgentID</key> + <map> <key>type</key> <string>key</string> <key>tooltip</key> <string></string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Returns TRUE if the agent is in the Experience and the Experience can run in the current location. @@ -8035,7 +8257,8 @@ <key>return</key> <string>key</string> <key>arguments</key> - <map> + <array> + <map> <key>Key</key> <map> <key>type</key> @@ -8043,6 +8266,8 @@ <key>tooltip</key> <string></string> </map> + </map> + <map> <key>Value</key> <map> <key>type</key> @@ -8050,7 +8275,8 @@ <key>tooltip</key> <string></string> </map> - </map> + </map> + </array> <key>tooltip</key> <string> Starts an asychronous transaction to create a key-value pair. Will fail with XP_ERROR_STORAGE_EXCEPTION if the key already exists. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value passed to the function. @@ -8148,15 +8374,17 @@ <key>return</key> <string>key</string> <key>arguments</key> - <map> - <key>Key</key> - <map> + <array> + <map> + <key>Key</key> + <map> <key>type</key> <string>string</string> <key>tooltip</key> <string></string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Starts an asychronous transaction to delete a key-value pair. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. @@ -9549,15 +9777,17 @@ <key>return</key> <string>list</string> <key>arguments</key> - <map> - <key>ExperienceID</key> - <map> + <array> + <map> + <key>ExperienceID</key> + <map> <key>type</key> <string>key</string> <key>tooltip</key> <string>May be NULL_KEY to retrieve the details for the script's Experience</string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Returns a list with the following Experience properties: [Experience Name, Owner ID, Group ID, Experience ID, State, State Message]. State is an integer corresponding to one of the constants XP_ERROR_... and State Message is the string returned by llGetExperienceErrorMessage for that integer. @@ -9572,15 +9802,17 @@ <key>return</key> <string>string</string> <key>arguments</key> - <map> - <key>Error</key> - <map> + <array> + <map> + <key>Error</key> + <map> <key>type</key> <string>integer</string> <key>tooltip</key> <string>An Experience error code to translate.</string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Returns a string describing the error code passed or the string corresponding with XP_ERROR_UNKNOWN_ERROR if the value is not a valid Experience error code. @@ -9930,7 +10162,7 @@ <key>Parameters</key> <map> <key>type</key> - <string>integer</string> + <string>list</string> <key>tooltip</key> <string>A list of PRIM_* property constants to return values of.</string> </map> @@ -10021,7 +10253,7 @@ <key>Parameters</key> <map> <key>type</key> - <string>integer</string> + <string>list</string> <key>tooltip</key> <string>PRIM_* flags.</string> </map> @@ -10782,7 +11014,7 @@ <key>sleep</key> <real>0.0</real> <key>return</key> - <string>void</string> + <string>float</string> <key>arguments</key> <undef/> <key>tooltip</key> @@ -11390,7 +11622,7 @@ <key>sleep</key> <real>0.0</real> <key>return</key> - <string>void</string> + <string>integer</string> <key>arguments</key> <array> <map> @@ -11937,22 +12169,26 @@ <key>return</key> <string>key</string> <key>arguments</key> - <map> - <key>First</key> - <map> + <array> + <map> + <key>First</key> + <map> <key>type</key> - <string>string</string> + <string>integer</string> <key>tooltip</key> <string>Index of the first key to return.</string> - </map> - <key>Count</key> - <map> + </map> + </map> + <map> + <key>Count</key> + <map> <key>type</key> - <string>string</string> + <string>integer</string> <key>tooltip</key> <string>The number of keys to return.</string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Starts an asychronous transaction the request a number of keys from the data store. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. The error XP_ERROR_KEY_NOT_FOUND is returned if First is greater than or equal to the number of keys in the data store. In the success case the subsequent items will be the keys requested. The number of keys returned may be less than requested if the return value is too large or if there is not enough keys remaining. The order keys are returned is not guaranteed but is stable between subsequent calls as long as no keys are added or removed. Because the keys are returned in a comma-delimited list it is not recommended to use commas in key names if this function is used. @@ -11981,7 +12217,7 @@ <key>Rules</key> <map> <key>type</key> - <string>integer</string> + <string>list</string> <key>tooltip</key> <string>Particle system rules list in the format [ rule1, data1, rule2, data2 . . . ruleN, dataN ]</string> </map> @@ -13141,6 +13377,15 @@ <string/> </map> </map> + <map> + <key>Bounce</key> + <map> + <key>type</key> + <string>integer</string> + <key>tooltip</key> + <string/> + </map> + </map> <map> <key>Texture</key> <map> @@ -13159,6 +13404,15 @@ <string/> </map> </map> + <map> + <key>Bounce_Offset</key> + <map> + <key>type</key> + <string>float</string> + <key>tooltip</key> + <string/> + </map> + </map> </array> <key>tooltip</key> <string>Make a fountain of particles. Deprecated: Use llParticleSystem instead.\nMake a fountain of particles using texture from the objects inventory. Deprecated: Use llParticleSystem instead.</string> @@ -13959,7 +14213,7 @@ <key>sleep</key> <real>0.0</real> <key>return</key> - <string>void</string> + <string>float</string> <key>arguments</key> <array> <map> @@ -14098,7 +14352,8 @@ <key>return</key> <string>key</string> <key>arguments</key> - <map> + <array> + <map> <key>Key</key> <map> <key>type</key> @@ -14106,7 +14361,8 @@ <key>tooltip</key> <string></string> </map> - </map> + </map> + </array> <key>tooltip</key> <string> Starts an asychronous transaction to retrieve the value associated with the key given. Will fail with XP_ERROR_KEY_NOT_FOUND if the key does not exist. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. @@ -14148,7 +14404,7 @@ <key>Text</key> <map> <key>type</key> - <string>integer</string> + <string>string</string> <key>tooltip</key> <string>Message to be transmitted.</string> </map> @@ -14541,22 +14797,26 @@ <key>return</key> <string>void</string> <key>arguments</key> - <map> - <key>AvatarID</key> - <map> + <array> + <map> + <key>AgentID</key> + <map> <key>type</key> <string>key</string> <key>tooltip</key> <string/> - </map> - <key>unused</key> - <map> + </map> + </map> + <map> + <key>unused</key> + <map> <key>type</key> <string>string</string> <key>tooltip</key> <string>Not used, should be ""</string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Ask the agent for permission to participate in an experience. This request is similar to llRequestPermissions with the following permissions: PERMISSION_TAKE_CONTROLS, PERMISSION_TRIGGER_ANIMATION, PERMISSION_ATTACH, PERMISSION_TRACK_CAMERA, PERMISSION_CONTROL_CAMERA and PERMISSION_TELEPORT. However, unlike llRequestPermissions the decision to allow or block the request is persistent and applies to all scripts using the experience grid wide. Subsequent calls to llRequestExperiencePermissions from scripts in the experience will receive the same response automatically with no user interaction. One of experience_permissions or experience_permissions_denied will be generated in response to this call. Outstanding permission requests will be lost if the script is derezzed, moved to another region or reset. @@ -17363,7 +17623,7 @@ <key>ParameterValue</key> <map> <key>type</key> - <string>float</string> + <string>rotation</string> <key>tooltip</key> <string/> </map> @@ -17418,7 +17678,7 @@ <key>ParameterValue</key> <map> <key>type</key> - <string>float</string> + <string>vector</string> <key>tooltip</key> <string/> </map> @@ -18487,36 +18747,44 @@ <key>return</key> <string>key</string> <key>arguments</key> - <map> - <key>Key</key> - <map> + <array> + <map> + <key>Key</key> + <map> <key>type</key> <string>string</string> <key>tooltip</key> <string></string> - </map> - <key>Value</key> - <map> + </map> + </map> + <map> + <key>Value</key> + <map> <key>type</key> <string>string</string> <key>tooltip</key> <string></string> - </map> - <key>Checked</key> - <map> + </map> + </map> + <map> + <key>Checked</key> + <map> <key>type</key> <string>integer</string> <key>tooltip</key> <string></string> - </map> - <key>OriginalValue</key> - <map> + </map> + </map> + <map> + <key>OriginalValue</key> + <map> <key>type</key> <string>string</string> <key>tooltip</key> <string></string> - </map> - </map> + </map> + </map> + </array> <key>tooltip</key> <string> Starts an asychronous transaction to update the value associated with the key given. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. If Checked is 1 the existing value in the data store must match the OriginalValue passed or XP_ERROR_RETRY_UPDATE will be returned. If Checked is 0 the key will be created if necessary. @@ -18868,31 +19136,8 @@ <key>tooltip</key> <string>Returns the largest multiplicative uniform scale factor that can be successfully applied (via llScaleByFactor()) to the object without violating prim size or linkability rules.</string> </map> - <key>llScaleByFactor</key> - <map> - <key>energy</key> - <real>10.0</real> - <key>sleep</key> - <real>0.0</real> - <key>return</key> - <string>float</string> - <key>arguments</key> - <array> - <map> - <key>Factor</key> - <map> - <key>type</key> - <string>float</string> - <key>tooltip</key> - <string/> - </map> - </map> - </array> - <key>tooltip</key> - <string>Tries to uniformly scale the object by a multiplicative factor. Returns TRUE on success or FALSE on failure.</string> - </map> </map> <key>llsd-lsl-syntax-version</key> - <integer>2</integer> + <integer>2</integer><!-- increment only when the file format changes, not just the content --> </map> </llsd> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4912f27e7010296c5740cf5fad9930711b89fab6..7a897172c25b90401a72959103ce11e00501a469 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -137,6 +137,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>AdvanceOutfitSnapshot</key> + <map> + <key>Comment</key> + <string>Display advanced parameter settings in outfit snaphot interface</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>AgentPause</key> <map> <key>Comment</key> @@ -2034,11 +2045,11 @@ <key>Comment</key> <string>Size (in bytes) for each coroutine stack</string> <key>Persist</key> - <integer>0</integer> + <integer>1</integer> <key>Type</key> <string>S32</string> <key>Value</key> - <integer>262144</integer> + <integer>524288</integer> </map> <key>CrashOnStartup</key> <map> @@ -2193,6 +2204,17 @@ <string>String</string> <key>Value</key> <string /> + </map> + <key>DebugAvatarJoints</key> + <map> + <key>Comment</key> + <string>List of joints to emit additional debugging info about.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string /> </map> <key>DebugAvatarRezTime</key> <map> @@ -3514,6 +3536,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>IncludeEnhancedSkeleton</key> + <map> + <key>Comment</key> + <string>Include extended skeleton joints when rendering skinned meshes.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>MinObjectsForUnlinkConfirm</key> <map> <key>Comment</key> @@ -3701,6 +3734,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>QueueInventoryFetchTimeout</key> + <map> + <key>Comment</key> + <string>Max time llcompilequeue will wait for inventory fetch to complete (in seconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>300.0</real> + </map> <key>FindLandArea</key> <map> <key>Comment</key> @@ -4493,28 +4537,6 @@ <key>Value</key> <string>http://search.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> </map> - <key>WebProfileURL</key> - <map> - <key>Comment</key> - <string>URL for Web Profiles</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>https://my.secondlife.com/[AGENT_NAME]</string> - </map> - <key>WebProfileNonProductionURL</key> - <map> - <key>Comment</key> - <string>URL for Web Profiles on Non-Production grids</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>https://my-demo.secondlife.com/[AGENT_NAME]</string> - </map> <key>HighResSnapshot</key> <map> <key>Comment</key> @@ -4859,7 +4881,7 @@ <key>InventoryTrashMaxCapacity</key> <map> <key>Comment</key> - <string>Maximum capacity of the Trash folder. User will ve offered to clean it up when exceeded.</string> + <string>Maximum capacity of the Trash folder. User will be offered to clean it up when exceeded.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -5241,6 +5263,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>LastAppearanceTab</key> + <map> + <key>Comment</key> + <string>Last selected tab in appearance floater</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>LastMediaSettingsTab</key> <map> <key>Comment</key> @@ -6332,17 +6365,6 @@ <key>Value</key> <integer>512</integer> </map> - <key>MemProfiling</key> - <map> - <key>Comment</key> - <string>You want to use tcmalloc's memory profiling options.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>MenuAccessKeyTime</key> <map> <key>Comment</key> @@ -6407,7 +6429,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>0</integer> </map> <key>MeshUploadLogXML</key> <map> @@ -6606,6 +6628,17 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> + </map> + <key>MuteListLimit</key> + <map> + <key>Comment</key> + <string>Maximum number of entries in the mute list</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>1000</integer> </map> <key>MyOutfitsAutofill</key> <map> @@ -7929,6 +7962,17 @@ <key>Value</key> <integer>100000</integer> </map> + <key>PrimTextMaxDrawDistance</key> + <map> + <key>Comment</key> + <string>Maximum draw distance beyond which PRIM_TEXT won't be rendered</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>64.0</real> + </map> <key>ProbeHardwareOnStartup</key> <map> <key>Comment</key> @@ -10013,28 +10057,28 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderUseFarClip</key> - <map> - <key>Comment</key> - <string>If false, frustum culling will ignore far clip plane.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>RenderUseImpostors</key> - <map> - <key>Comment</key> + <key>RenderUseFarClip</key> + <map> + <key>Comment</key> + <string>If false, frustum culling will ignore far clip plane.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>RenderUseImpostors</key> + <map> + <key>Comment</key> <string>OBSOLETE and UNUSED. See RenderAvatarMaxNonImpostors and RenderAvatarMaxComplexity.</string> - <key>Persist</key> + <key>Persist</key> <integer>0</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> <integer>0</integer> - </map> + </map> <key>RenderAutoMuteByteLimit</key> <map> <key>Comment</key> @@ -10081,6 +10125,17 @@ <key>Value</key> <integer>10</integer> </map> + <key>ComplexityChangesPopUpDelay</key> + <map> + <key>Comment</key> + <string>Delay before viewer will show avatar complexity notice again</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>300</integer> + </map> <key>RenderAvatarMaxComplexity</key> <map> <key>Comment</key> @@ -10093,6 +10148,50 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderHUDObjectsWarning</key> + <map> + <key>Comment</key> + <string>Viewer will warn user about HUD containing to many objects if objects count is above this value</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>1000</integer> + </map> + <key>RenderHUDTexturesWarning</key> + <map> + <key>Comment</key> + <string>Viewer will warn user about HUD containing to many textures if texture count is above this value</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>200</integer> + </map> + <key>RenderHUDOversizedTexturesWarning</key> + <map> + <key>Comment</key> + <string>How many textures with size 1024 * 1024 or bigger HUD can contain before notifying user</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>6</integer> + </map> + <key>RenderHUDTexturesMemoryWarning</key> + <map> + <key>Comment</key> + <string>Viewer will warn user about HUD textures using memory above this value (in bytes)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>32000000</integer> + </map> <key>RenderAutoMuteSurfaceAreaLimit</key> <map> <key>Comment</key> @@ -12781,6 +12880,17 @@ <key>Value</key> <real>1.0</real> </map> + <key>LastSystemUIScaleFactor</key> + <map> + <key>Comment</key> + <string>Size of system UI during last run. On Windows 100% (96 DPI) system setting is 1.0 UI size</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1.0</real> + </map> <key>UIScrollbarSize</key> <map> <key>Comment</key> @@ -13276,6 +13386,17 @@ <key>Value</key> <string>1</string> </map> + <key>UpdaterShowReleaseNotes</key> + <map> + <key>Comment</key> + <string>Enables displaying of the Release notes in a web floater after update.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>UploadBakedTexOld</key> <map> <key>Comment</key> @@ -14464,6 +14585,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>LogWearableAssetSave</key> + <map> + <key>Comment</key> + <string>Save copy of saved wearables to log dir</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>LogTextureDownloadsToViewerLog</key> <map> <key>Comment</key> @@ -14614,6 +14746,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>OutfitGallerySortByName</key> + <map> + <key>Comment</key> + <string>Always sort outfits by name in Outfit Gallery</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>OutfitOperationsTimeout</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index fd6b1b5b3f032bfad6fd1d9819f355db2e40ac62..eee13fb28e87b73164935290ced150892a438294 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -242,6 +242,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>PreviousScreenshotForReport</key> + <map> + <key>Comment</key> + <string>Use Previous Screenshot for Abuse report</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <!-- Settings below are for back compatibility only. They are not used in current viewer anymore. But they can't be removed to avoid influence on previous versions of the viewer in case of settings are not used or default value @@ -251,7 +262,7 @@ <key>LogChat</key> <map> <key>Comment</key> - <string>Log Chat</string> + <string>Obsolete - this setting is no longer used and has no effect.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -262,7 +273,7 @@ <key>LogChatIM</key> <map> <key>Comment</key> - <string>Log Incoming Instant Messages with Chat</string> + <string>Obsolete - this setting is no longer used and has no effect.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -273,7 +284,7 @@ <key>LogChatTimestamp</key> <map> <key>Comment</key> - <string>Log Timestamp of Chat</string> + <string>Obsolete - this setting is no longer used and has no effect.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -281,6 +292,7 @@ <key>Value</key> <integer>0</integer> </map> + <!-- End of back compatibility settings --> <key>TranslatingEnabled</key> <map> <key>Comment</key> @@ -336,6 +348,5 @@ <key>Value</key> <integer>1</integer> </map> - <!-- End of back compatibility settings --> </map> </llsd> diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 3060307b2113920734afcb18b7afca250ec86cde..90bf2851c9e0f49534f19e18a07c6ecdefb66c91 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -24,8 +24,7 @@ ATTRIBUTE vec4 weight4; -uniform mat3 matrixPalette[52]; -uniform vec3 translationPalette[52]; +uniform mat3x4 matrixPalette[MAX_JOINTS_PER_MESH_OBJECT]; mat4 getObjectSkinnedTransform() { @@ -34,8 +33,8 @@ mat4 getObjectSkinnedTransform() vec4 w = fract(weight4); vec4 index = floor(weight4); - index = min(index, vec4(51.0)); - index = max(index, vec4( 0.0)); + index = min(index, vec4(MAX_JOINTS_PER_MESH_OBJECT-1)); + index = max(index, vec4( 0.0)); w *= 1.0/(w.x+w.y+w.z+w.w); @@ -43,16 +42,16 @@ mat4 getObjectSkinnedTransform() int i2 = int(index.y); int i3 = int(index.z); int i4 = int(index.w); - - mat3 mat = matrixPalette[i1]*w.x; - mat += matrixPalette[i2]*w.y; - mat += matrixPalette[i3]*w.z; - mat += matrixPalette[i4]*w.w; - vec3 trans = translationPalette[i1]*w.x; - trans += translationPalette[i2]*w.y; - trans += translationPalette[i3]*w.z; - trans += translationPalette[i4]*w.w; + mat3 mat = mat3(matrixPalette[i1])*w.x; + mat += mat3(matrixPalette[i2])*w.y; + mat += mat3(matrixPalette[i3])*w.z; + mat += mat3(matrixPalette[i4])*w.w; + + vec3 trans = vec3(matrixPalette[i1][0].w,matrixPalette[i1][1].w,matrixPalette[i1][2].w)*w.x; + trans += vec3(matrixPalette[i2][0].w,matrixPalette[i2][1].w,matrixPalette[i2][2].w)*w.y; + trans += vec3(matrixPalette[i3][0].w,matrixPalette[i3][1].w,matrixPalette[i3][2].w)*w.z; + trans += vec3(matrixPalette[i4][0].w,matrixPalette[i4][1].w,matrixPalette[i4][2].w)*w.w; mat4 ret; @@ -65,10 +64,8 @@ mat4 getObjectSkinnedTransform() #ifdef IS_AMD_CARD // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. - mat3 dummy1 = matrixPalette[0]; - vec3 dummy2 = translationPalette[0]; - mat3 dummy3 = matrixPalette[51]; - vec3 dummy4 = translationPalette[51]; + mat3x4 dummy1 = matrixPalette[0]; + mat3x4 dummy2 = matrixPalette[MAX_JOINTS_PER_MESH_OBJECT-1]; #endif } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl index b9ddbc8e1ce1786bcd49e4872d9af71cb35c5d5f..89181828536bb6dd06eb76a5022abaf53d73f95d 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl @@ -43,12 +43,12 @@ void default_lighting() { vec4 color = texture2D(diffuseMap,vary_texcoord0.xy); + color *= vertex_color; + if (color.a < minimum_alpha) { discard; } - - color.rgb *= vertex_color.rgb; color.rgb = atmosLighting(color.rgb); diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 7f7eaed38a13d9e945d4d740be6df4a6ad4efb78..90f06746c9fd733a6bd369c08a922409852b804d 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="US-ASCII" standalone="yes"?> <linden_avatar - version="1.0" wearable_definition_version="22"> + version="2.0" wearable_definition_version="22"> <!-- The wearable_definition_version is checked during asset upload. --> <!-- If you increment it, check indra/lib/python/indra/assetutil.py. --> <skeleton @@ -11,6 +11,7 @@ pie_slice="2" name="Chest" joint="mChest" + location="ATTACH_CHEST" position="0.15 0 -0.1" rotation="0 90 90" visible_in_first_person="true" /> @@ -21,6 +22,7 @@ pie_slice="2" name="Skull" joint="mHead" + location="ATTACH_HEAD" position="0 0 0.15" rotation="0 0 90" visible_in_first_person="false" /> @@ -31,6 +33,7 @@ pie_slice="3" name="Left Shoulder" joint="mCollarLeft" + location="ATTACH_LSHOULDER" position="0 0 0.08" rotation="0 0 0" visible_in_first_person="true" /> @@ -41,6 +44,7 @@ pie_slice="1" name="Right Shoulder" joint="mCollarRight" + location="ATTACH_RSHOULDER" position="0 0 0.08" rotation="0 0 0" visible_in_first_person="true"/> @@ -50,6 +54,7 @@ group="4" name="Left Hand" joint="mWristLeft" + location="ATTACH_LHAND" position="0 0.08 -0.02" rotation="0 0 0" visible_in_first_person="true" @@ -60,6 +65,7 @@ group="0" name="Right Hand" joint="mWristRight" + location="ATTACH_RHAND" position="0 -0.08 -0.02" rotation="0 0 0" visible_in_first_person="true" @@ -71,6 +77,7 @@ pie_slice="6" name="Left Foot" joint="mFootLeft" + location="ATTACH_LFOOT" position="0 0.0 0.0" rotation="0 0 0" visible_in_first_person="true"/> @@ -81,6 +88,7 @@ pie_slice="6" name="Right Foot" joint="mFootRight" + location="ATTACH_RFOOT" position="0 0.0 0.0" rotation="0 0 0" visible_in_first_person="true"/> @@ -91,6 +99,7 @@ pie_slice="7" name="Spine" joint="mChest" + location="ATTACH_BACK" position="-0.15 0 -0.1" rotation="0 -90 90" visible_in_first_person="true" /> @@ -101,6 +110,7 @@ pie_slice="6" name="Pelvis" joint="mPelvis" + location="ATTACH_PELVIS" position="0 0 -0.15" rotation="0 0 0" visible_in_first_person="true" /> @@ -111,6 +121,7 @@ pie_slice="6" name="Mouth" joint="mHead" + location="ATTACH_MOUTH" position="0.12 0 0.001" rotation="0 0 0" visible_in_first_person="false"/> @@ -121,6 +132,7 @@ pie_slice="7" name="Chin" joint="mHead" + location="ATTACH_CHIN" position="0.12 0 -0.04" rotation="0 0 0" visible_in_first_person="false" /> @@ -131,6 +143,7 @@ pie_slice="4" name="Left Ear" joint="mHead" + location="ATTACH_LEAR" position="0.015 0.08 0.017" rotation="0 0 0" visible_in_first_person="false" /> @@ -141,6 +154,7 @@ pie_slice="0" name="Right Ear" joint="mHead" + location="ATTACH_REAR" position="0.015 -0.08 0.017" rotation="0 0 0" visible_in_first_person="false" /> @@ -151,6 +165,7 @@ pie_slice="3" name="Left Eyeball" joint="mEyeLeft" + location="ATTACH_LEYE" position="0 0 0" rotation="0 0 0" visible_in_first_person="false"/> @@ -161,6 +176,7 @@ pie_slice="1" name="Right Eyeball" joint="mEyeRight" + location="ATTACH_REYE" position="0 0 0" rotation="0 0 0" visible_in_first_person="false" /> @@ -171,6 +187,7 @@ pie_slice="5" name="Nose" joint="mHead" + location="ATTACH_NOSE" position="0.1 0 0.05" rotation="0 0 0" visible_in_first_person="false"/> @@ -181,6 +198,7 @@ pie_slice="0" name="R Upper Arm" joint="mShoulderRight" + location="ATTACH_RUARM" position="0.01 -0.13 0.01" rotation="0 0 0" visible_in_first_person="true" /> @@ -191,6 +209,7 @@ pie_slice="7" name="R Forearm" joint="mElbowRight" + location="ATTACH_RLARM" position="0 -0.12 0" rotation="0 0 0" visible_in_first_person="true"/> @@ -201,6 +220,7 @@ pie_slice="4" name="L Upper Arm" joint="mShoulderLeft" + location="ATTACH_LUARM" position="0.01 0.15 -0.01" rotation="0 0 0" visible_in_first_person="true" /> @@ -211,6 +231,7 @@ pie_slice="5" name="L Forearm" joint="mElbowLeft" + location="ATTACH_LLARM" position="0 0.113 0" rotation="0 0 0" visible_in_first_person="true" /> @@ -221,6 +242,7 @@ pie_slice="1" name="Right Hip" joint="mHipRight" + location="ATTACH_RHIP" position="0 0 0" rotation="0 0 0" visible_in_first_person="true" /> @@ -231,6 +253,7 @@ pie_slice="0" name="R Upper Leg" joint="mHipRight" + location="ATTACH_RULEG" position="-0.017 0.041 -0.310" rotation="0 0 0" visible_in_first_person="true" /> @@ -241,6 +264,7 @@ pie_slice="7" name="R Lower Leg" joint="mKneeRight" + location="ATTACH_RLLEG" position="-0.044 -0.007 -0.262" rotation="0 0 0" visible_in_first_person="true" /> @@ -251,6 +275,7 @@ pie_slice="3" name="Left Hip" joint="mHipLeft" + location="ATTACH_LHIP" position="0 0 0" rotation="0 0 0" visible_in_first_person="true" /> @@ -261,6 +286,7 @@ pie_slice="4" name="L Upper Leg" joint="mHipLeft" + location="ATTACH_LULEG" position="-0.019 -0.034 -0.310" rotation="0 0 0" visible_in_first_person="true"/> @@ -271,6 +297,7 @@ pie_slice="5" name="L Lower Leg" joint="mKneeLeft" + location="ATTACH_LLLEG" position="-0.044 -0.007 -0.261" rotation="0 0 0" visible_in_first_person="true" /> @@ -281,6 +308,7 @@ pie_slice="5" name="Stomach" joint="mPelvis" + location="ATTACH_BELLY" position="0.092 0.0 0.088" rotation="0 0 0" visible_in_first_person="true" /> @@ -291,6 +319,7 @@ pie_slice="3" name="Left Pec" joint="mTorso" + location="ATTACH_LEFT_PEC" position="0.104 0.082 0.247" rotation="0 0 0" visible_in_first_person="true" /> @@ -301,15 +330,17 @@ pie_slice="1" name="Right Pec" joint="mTorso" + location="ATTACH_RIGHT_PEC" position="0.104 -0.082 0.247" rotation="0 0 0" visible_in_first_person="true" /> <attachment_point id="31" - group="8" + group="9" name="Center 2" joint="mScreen" + location="ATTACH_HUD_CENTER_2" position="0 0 0" rotation="0 0 0" hud="true" @@ -318,9 +349,10 @@ <attachment_point id="32" - group="8" + group="9" name="Top Right" joint="mScreen" + location="ATTACH_HUD_TOP_RIGHT" position="0 -0.5 0.5" rotation="0 0 0" hud="true" @@ -329,9 +361,10 @@ <attachment_point id="33" - group="8" + group="9" name="Top" joint="mScreen" + location="ATTACH_HUD_TOP_CENTER" position="0 0 0.5" rotation="0 0 0" hud="true" @@ -340,9 +373,10 @@ <attachment_point id="34" - group="8" + group="9" name="Top Left" joint="mScreen" + location="ATTACH_HUD_TOP_LEFT" position="0 0.5 0.5" rotation="0 0 0" hud="true" @@ -351,9 +385,10 @@ <attachment_point id="35" - group="8" + group="9" name="Center" joint="mScreen" + location="ATTACH_HUD_CENTER_1" position="0 0 0" rotation="0 0 0" hud="true" @@ -362,9 +397,10 @@ <attachment_point id="36" - group="8" + group="9" name="Bottom Left" joint="mScreen" + location="ATTACH_HUD_BOTTOM_LEFT" position="0 0.5 -0.5" rotation="0 0 0" hud="true" @@ -373,9 +409,10 @@ <attachment_point id="37" - group="8" + group="9" name="Bottom" joint="mScreen" + location="ATTACH_HUD_BOTTOM" position="0 0 -0.5" rotation="0 0 0" hud="true" @@ -384,9 +421,10 @@ <attachment_point id="38" - group="8" + group="9" name="Bottom Right" joint="mScreen" + location="ATTACH_HUD_BOTTOM_RIGHT" position="0 -0.5 -0.5" rotation="0 0 0" hud="true" @@ -399,6 +437,7 @@ pie_slice="1" name="Neck" joint="mNeck" + location="ATTACH_NECK" position="0 0 0" rotation="0 0 0" visible_in_first_person="true" /> @@ -409,10 +448,180 @@ pie_slice="2" name="Avatar Center" joint="mRoot" + location="ATTACH_AVATAR_CENTER" position="0 0 0" rotation="0 0 0" visible_in_first_person="true" /> - + + <!-- BENTO ADDITIONS --> + + <attachment_point + id="41" + group="8" + pie_slice="0" + name="Left Ring Finger" + joint="mHandRing1Left" + location="ATTACH_LHAND_RING1" + position="-0.006 0.019 -0.002" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="42" + group="8" + pie_slice="1" + name="Right Ring Finger" + joint="mHandRing1Right" + location="ATTACH_RHAND_RING1" + position="-0.006 -0.019 -0.002" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="43" + group="8" + pie_slice="2" + name="Tail Base" + joint="mTail1" + location="ATTACH_TAIL_BASE" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="44" + group="8" + pie_slice="3" + name="Tail Tip" + joint="mTail6" + location="ATTACH_TAIL_TIP" + position="-0.025 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="45" + group="8" + pie_slice="4" + name="Left Wing" + joint="mWing4Left" + location="ATTACH_LWING" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="46" + group="8" + pie_slice="5" + name="Right Wing" + joint="mWing4Right" + location="ATTACH_RWING" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="47" + group="8" + pie_slice="6" + name="Jaw" + joint="mFaceJaw" + location="ATTACH_FACE_JAW" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="48" + group="8" + pie_slice="7" + name="Alt Left Ear" + joint="mFaceEar1Left" + location="ATTACH_FACE_LEAR" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="49" + group="8" + pie_slice="8" + name="Alt Right Ear" + joint="mFaceEar1Right" + location="ATTACH_FACE_REAR" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="50" + group="8" + pie_slice="9" + name="Alt Left Eye" + joint="mFaceEyeAltLeft" + location="ATTACH_FACE_LEYE" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="51" + group="8" + pie_slice="10" + name="Alt Right Eye" + joint="mFaceEyeAltRight" + location="ATTACH_FACE_REYE" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="52" + group="8" + pie_slice="11" + name="Tongue" + joint="mFaceTongueTip" + location="ATTACH_FACE_TONGUE" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="53" + group="8" + pie_slice="12" + name="Groin" + joint="mGroin" + location="ATTACH_GROIN" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="54" + group="8" + pie_slice="13" + name="Left Hind Foot" + joint="mHindLimb4Left" + location="ATTACH_HIND_LFOOT" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="55" + group="8" + pie_slice="14" + name="Right Hind Foot" + joint="mHindLimb4Right" + location="ATTACH_HIND_RFOOT" + position="0.000 0.000 0.000" + rotation="0 0 0" + visible_in_first_person="true"/> + + <!-- END BENTO --> + <param id="32" group="1" @@ -460,8 +669,12 @@ scale="0 0 .05" /> <bone - name="mPelvis" - scale="0 0 0" /> + name="mSpine3" + scale="0 0 .05" /> + + <bone + name="mSpine4" + scale="0 0 .05" /> <bone name="mHipLeft" @@ -478,6 +691,29 @@ <bone name="mKneeRight" scale=".05 .05 .1" /> + + <bone + name="mHindLimb1Left" + scale=".05 .05 0" /> + + <bone + name="mHindLimb1Right" + scale=".05 .05 0" /> + + <bone + name="mHindLimb2Left" + scale=".05 .05 .1" /> + + <bone + name="mHindLimb2Right" + scale=".05 .05 .1" /> + + <bone name="mWingsRoot" scale="0 0 0" offset="0 0 0" /> + + <bone name="mWing1Right" scale="0 0 0" offset="-0.05 0 0" /> + + <bone name="mWing1Left" scale="0 0 0" offset="-0.05 0 0" /> + </param_skeleton> </param> @@ -533,8 +769,12 @@ scale="0 0 0.05" /> <bone - name="mPelvis" - scale="0 0 0" /> + name="mSpine3" + scale="0 0 0.05" /> + + <bone + name="mSpine4" + scale="0 0 0.05" /> <bone name="mHipLeft" @@ -551,6 +791,96 @@ <bone name="mKneeRight" scale="0 0 0.1" /> + + <bone + name="mHindLimb1Left" + scale="0 0 0.1" /> + + <bone + name="mHindLimb1Right" + scale="0 0 0.1" /> + + <bone + name="mHindLimb2Left" + scale="0 0 0.1" /> + + <bone + name="mHindLimb2Right" + scale="0 0 0.1" /> + + <bone + name="mWing1Left" + scale="0 0 0" + offset="0 0 0" /> + <bone + name="mWing2Left" + scale="0 0 0" + offset="-0.015 0.015 0" /> + <bone + name="mWing3Left" + scale="0 0 0" + offset="-0.025 0.025 0" /> + <bone + name="mWing4Left" + scale="0 0 0" + offset="-0.03 0.03 0" /> + <bone + name="mWing4FanLeft" + scale="0 0 0" + offset="-0.03 0.03 0" /> + + <bone + name="mWing1Right" + scale="0 0 0" + offset="0 0 0" /> + <bone + name="mWing2Right" + scale="0 0 0" + offset="-0.015 -0.015 0" /> + <bone + name="mWing3Right" + scale="0 0 0" + offset="-0.025 -0.025 0" /> + <bone + name="mWing4Right" + scale="0 0 0" + offset="-0.03 -0.03 0" /> + <bone + name="mWing4FanRight" + scale="0 0 0" + offset="-0.03 -0.03 0" /> + + <bone + name="mTail1" + scale ="0 0 0" + offset="-0.02 0 0" /> + + <bone + name="mTail2" + scale ="0 0 0" + offset="-0.02 0 0" /> + + <bone + name="mTail3" + scale ="0 0 0" + offset="-0.02 0 0" /> + + <bone + name="mTail4" + scale ="0 0 0" + offset="-0.02 0 0" /> + + <bone + name="mTail5" + scale ="0 0 0" + offset="-0.02 0 0" /> + + <bone + name="mTail6" + scale ="0 0 0" + offset="-0.02 0 0" /> + + </param_skeleton> </param> @@ -605,10 +935,26 @@ name="mTorso" scale="0.1 0.1 0" /> + <bone + name="mSpine3" + scale="0.1 0.1 0" /> + + <bone + name="mSpine4" + scale="0.1 0.1 0" /> + <bone name="mPelvis" scale="0.1 0.1 0" /> + <bone + name="mSpine1" + scale="0.1 0.1 0" /> + + <bone + name="mSpine2" + scale="0.1 0.1 0" /> + <bone name="mHipLeft" scale="0.13 0.13 0" /> @@ -624,6 +970,37 @@ <bone name="mKneeRight" scale="0.12 0.12 0" /> + + <bone + name="mHindLimbsRoot" + scale="0.1 0.1 0" /> + + <bone + name="mHindLimb1Left" + scale="0.13 0.13 0" /> + + <bone + name="mHindLimb1Right" + scale="0.13 0.13 0" /> + + <bone + name="mHindLimb2Left" + scale="0.12 0.12 0" /> + + <bone + name="mHindLimb2Right" + scale="0.12 0.12 0" /> + + <bone name="mTail1" scale="0.05 0.1 0.1" /> + <bone name="mTail2" scale="0.05 0.1 0.1" /> + <bone name="mTail3" scale="0.05 0.1 0.1" /> + <bone name="mTail4" scale="0.05 0.1 0.1" /> + <bone name="mTail5" scale="0.05 0.1 0.1" /> + <bone name="mTail6" scale="0.05 0.1 0.1" /> + + <bone name="mWing1Right" scale="0.0 0.0 0.0" offset="-0.01 -0.01 0" /> + <bone name="mWing1Left" scale="0.0 0.0 0.0" offset="-0.01 0.01 0" /> + </param_skeleton> </param> @@ -662,6 +1039,17 @@ <bone name="mChest" scale="0.02 0.08 0" /> + + <bone + name="mWing1Right" + scale="0.0 0.0 0.0" + offset="0 -0.02 0" /> + + <bone + name="mWing1Left" + scale="0.0 0.0 0.0" + offset="0 0.02 0" /> + </param_skeleton> </param> @@ -669,7 +1057,7 @@ id="37" group="0" name="Hip Width" - label="Hip Width" + label="Hip Width" wearable="shape" edit_group="shape_legs" edit_group_order="3" @@ -684,6 +1072,14 @@ name="mPelvis" scale="0 0.1 0" /> + <bone + name="mSpine1" + scale="0 0.1 0" /> + + <bone + name="mSpine2" + scale="0 0.1 0" /> + <bone name="mHipLeft" scale="0 0 0" @@ -693,6 +1089,25 @@ name="mHipRight" scale="0 0 0" offset="0 -.004 0" /> + + <bone + name="mHindLimbsRoot" + scale="0 0.1 0" /> + + <bone + name="mHindLimb1Left" + scale="0 0 0" + offset="0 .004 0" /> + + <bone + name="mHindLimb1Right" + scale="0 0 0" + offset="0 -.004 0" /> + + <bone name="mTail1" scale="0.0 0.05 0" /> + <bone name="mTail2" scale="0.0 0.02 0" /> + <bone name="mTail3" scale="0.0 0.01 0" /> + </param_skeleton> </param> @@ -712,7 +1127,19 @@ <bone name="mPelvis" scale="0 0 0.3" /> - </param_skeleton> + + <bone + name="mHindLimbsRoot" + scale="0 0 0.3" /> + + <bone + name="mSpine1" + scale="0 0 0.3" /> + + <bone + name="mSpine2" + scale="0 0 0.3" /> + </param_skeleton> </param> <param @@ -732,10 +1159,26 @@ name="mTorso" scale="0 0 .3" /> + <bone + name="mSpine3" + scale="0 0 .3" /> + + <bone + name="mSpine4" + scale="0 0 .3" /> + <bone name="mPelvis" scale="0 0 .1" /> + <bone + name="mSpine1" + scale="0 0 .1" /> + + <bone + name="mSpine2" + scale="0 0 .1" /> + <bone name="mHipLeft" scale="0 0 -.1" /> @@ -751,6 +1194,26 @@ <bone name="mKneeLeft" scale="0 0 -.05" /> + + <bone + name="mHindLimbsRoot" + scale="0 0 .1" /> + + <bone + name="mHindLimb1Left" + scale="0 0 -.1" /> + + <bone + name="mHindLimb1Right" + scale="0 0 -.1" /> + + <bone + name="mHindLimb2Right" + scale="0 0 -.05" /> + + <bone + name="mHindLimb2Left" + scale="0 0 -.05" /> </param_skeleton> </param> @@ -774,6 +1237,78 @@ name="mEyeRight" scale="0 0 0" offset="0 -.009 0" /> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0 " + offset="0 .0090 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0 " + offset="0 -.0090 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0 " + offset="0 .0090 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0 " + offset="0 -.0090 0" /> + + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0 " + offset="0 .0090 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0 " + offset="0 -.0090 0" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0 " + offset="0 .0090 0" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0 " + offset="0 -.0090 0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0 " + offset="0 .0090 0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0 " + offset="0 -.0090 0" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0 " + offset="0 .005 0" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0 " + offset="0 -.005 0" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0 " + offset="0 .008 0" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0 " + offset="0 -.008 0" /> + </param_skeleton> </param> @@ -797,32 +1332,183 @@ name="mEyeRight" scale="0 0 0" offset="0 0 -.004" /> - </param_skeleton> - </param> - <param - id="772" - group="1" - name="EyeBone_Head_Elongate" - wearable="shape" - edit_group="shape_eyes" - label_min="Eyes Short Head" - label_max="Eyes Long Head" - value_min="-1" - value_max="1"> - <param_skeleton> - <bone - name="mEyeLeft" + <bone + name="mFaceEyeAltLeft" scale="0 0 0" - offset=".016 0 0" /> + offset="0 0 .004" /> - <bone - name="mEyeRight" + <bone + name="mFaceEyeAltRight" scale="0 0 0" - offset=".016 0 0" /> - </param_skeleton> - </param> + offset="0 0 -.004" /> + + <bone + name="mFaceNoseRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceNoseLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEar1Left" + scale="0 0 0" + offset="0 0 .004" /> + <bone + name="mFaceEar1Right" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceLipUpperLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceLipUpperRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceLipLowerLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceLipLowerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceLipCornerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceLipCornerLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceCheekLowerLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceCheekLowerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceCheekUpperLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceCheekUpperRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0" + offset="0 0 -.004" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0" + offset="0 0 0.004" /> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceForeheadRight" + scale="0 0 0" + offset="0 0 -.004" /> + + </param_skeleton> + </param> + + <param + id="772" + group="1" + name="EyeBone_Head_Elongate" + wearable="shape" + edit_group="shape_eyes" + label_min="Eyes Short Head" + label_max="Eyes Long Head" + value_min="-1" + value_max="1"> + <param_skeleton> + <bone + name="mEyeLeft" + scale="0 0 0" + offset=".016 0 0" /> + <bone + name="mEyeRight" + scale="0 0 0" + offset=".016 0 0" /> + + </param_skeleton> + </param> + <param id="768" group="1" @@ -843,6 +1529,80 @@ name="mEyeRight" scale="0 0 0" offset=".005 0 0" /> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0 " + offset=".005 0 0" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0 " + offset=".002 0 0" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0 " + offset=".002 0 0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0 " + offset=".001 0 0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0 " + offset=".001 0 0" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0 " + offset=".0013 0 0" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0 " + offset=".0013 0 0" /> + + + + </param_skeleton> </param> @@ -850,7 +1610,7 @@ id="655" group="1" name="Head Size" - label="Head Size" + label="Head Size" wearable="shape" edit_group="shape_head" label_min="Small Head" @@ -859,6 +1619,36 @@ value_min="-.25" value_max=".10"> <param_skeleton> + + <bone + name = "mFaceTeethLower" + scale = "1 1 1" + offset = "0 0 0" /> + + <bone + name = "mFaceTeethUpper" + scale = "1 1 1" + offset = "0 0 0" /> + + <bone + name = "mFaceEyecornerInnerLeft" + scale = "1 1 1" + offset = "0 0 0" /> + + <bone + name = "mFaceEyecornerInnerRight" + scale = "1 1 1" + offset = "0 0 0" /> + + <bone + name = "mFaceNoseBridge" + scale = "1 1 1" + offset = "0 0 0" /> + + <bone + name = "mFaceNoseBase" + scale = "1 1 1" + offset = "0 0 0" /> <bone name="mSkull" scale="1 1 1" @@ -869,6 +1659,11 @@ scale="1 1 1" offset="0 0 0" /> + <bone + name="mFaceRoot" + scale="1 1 1" + offset="0 0 0" /> + <bone name="mEyeLeft" scale="1 1 1" @@ -878,2485 +1673,4274 @@ name="mEyeRight" scale="1 1 1" offset="0 0 0" /> - </param_skeleton> - </param> - - <param - id="197" - group="1" - wearable="shoes" - name="Shoe_Heels" - edit_group="shoes" - label_min="No Heels" - label_max="High Heels" - value_min="0" - value_max="1"> - <param_skeleton> + <bone - name="mFootRight" - scale="0 0 0" - offset="0 0 -.08" /> + name="mFaceEyeAltLeft" + scale="1 1 1" + offset="0 0 -0.001" /> <bone - name="mFootLeft" - scale="0 0 0" - offset="0 0 -.08" /> - </param_skeleton> - </param> - - <param - id="502" - group="1" - wearable="shoes" - name="Shoe_Platform" - edit_group="shoes" - label_min="No Heels" - label_max="High Heels" - value_min="0" - value_max="1"> - <param_skeleton> + name="mFaceEyeAltRight" + scale="1 1 1" + offset="0 0 -0.001" /> + <bone - name="mFootRight" - scale="0 0 0" - offset="0 0 -.07" /> + name="mFaceForeheadLeft" + scale="1 1 1" + offset="0 0 0" /> <bone - name="mFootLeft" - scale="0 0 0" - offset="0 0 -.07" /> - </param_skeleton> - </param> + name="mFaceForeheadCenter" + scale="1 1 1" + offset="0 0 0" /> - <param - id="675" - group="0" - name="Hand Size" - wearable="shape" - edit_group="shape_torso" - edit_group_order="10" - label_min="Small Hands" - label_max="Large Hands" - value_min="-.3" - value_max=".3" - camera_elevation=".1" - camera_distance="1.4" - camera_angle="0"> - <param_skeleton> <bone - name="mWristRight" + name="mFaceForeheadRight" scale="1 1 1" offset="0 0 0" /> <bone - name="mWristLeft" + name="mFaceEyebrowOuterLeft" scale="1 1 1" offset="0 0 0" /> - </param_skeleton> - </param> - <param - id="683" - group="0" - name="Neck Thickness" - wearable="shape" - edit_group="shape_torso" - edit_group_order="2" - label_min="Skinny Neck" - label_max="Thick Neck" - value_min="-.4" - value_max=".2" - value_default="-.15" - camera_elevation=".3" - camera_distance=".8" - camera_angle="15"> - <param_skeleton> <bone - name="mNeck" - scale="1 1 0" + name="mFaceEyebrowCenterLeft" + scale="1 1 1" offset="0 0 0" /> - </param_skeleton> - </param> - <param - id="689" - group="1" - wearable="shape" - name="EyeBone_Big_Eyes" - edit_group="shape_eyes" - label_min="Eyes Back" - label_max="Eyes Forward" - value_min="-1" - value_max="1"> - <param_skeleton> <bone - name="mEyeLeft" - scale="0 0 0" - offset="-.005 0 0" /> + name="mFaceEyebrowInnerLeft" + scale="1 1 1" + offset="0 0 0" /> <bone - name="mEyeRight" - scale="0 0 0" - offset="-.005 0 0" /> - </param_skeleton> - </param> - - <param - id="692" - group="0" - name="Leg Length" - wearable="shape" - edit_group="shape_legs" - edit_group_order="2" - label_min="Short Legs" - label_max="Long Legs" - value_min="-1" - value_max="1" - camera_distance="2.5"> + name="mFaceEyebrowOuterRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceNoseLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceNoseCenter" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceNoseRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceCheekLowerLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceCheekUpperLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceCheekLowerRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceCheekUpperRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceTongueBase" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceTongueTip" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceJaw" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceJawShaper" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceChin" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipUpperLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipUpperCenter" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipUpperRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipCornerLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipCornerRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipLowerLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mFaceLipLowerCenter" + scale="1 1 1" + offset="0 0 0" /> + <bone + name="mFaceLipLowerRight" + scale="1 1 1" + offset="0 0 0" /> + + </param_skeleton> + </param> + + <param + id="197" + group="1" + wearable="shoes" + name="Shoe_Heels" + edit_group="shoes" + label_min="No Heels" + label_max="High Heels" + value_min="0" + value_max="1"> <param_skeleton> <bone - name="mHipLeft" - scale="0 0 .2" /> + name="mFootRight" + scale="0 0 0" + offset="0 0 -.08" /> <bone - name="mHipRight" - scale="0 0 .2" /> + name="mFootLeft" + scale="0 0 0" + offset="0 0 -.08" /> <bone - name="mKneeRight" - scale="0 0 .2" /> + name="mHindLimb4Left" + scale="0 0 0" + offset="0 0 -.08" /> <bone - name="mKneeLeft" - scale="0 0 .2" /> + name="mHindLimb4Right" + scale="0 0 0" + offset="0 0 -.08" /> + </param_skeleton> </param> <param - id="693" + id="502" + group="1" + wearable="shoes" + name="Shoe_Platform" + edit_group="shoes" + label_min="No Heels" + label_max="High Heels" + value_min="0" + value_max="1"> + <param_skeleton> + <bone + name="mFootRight" + scale="0 0 0" + offset="0 0 -.07" /> + + <bone + name="mFootLeft" + scale="0 0 0" + offset="0 0 -.07" /> + + <bone + name="mHindLimb4Left" + scale="0 0 0" + offset="0 0 -.07" /> + + <bone + name="mHindLimb4Right" + scale="0 0 0" + offset="0 0 -.07" /> + + </param_skeleton> + </param> + + <param + id="675" group="0" - name="Arm Length" + name="Hand Size" wearable="shape" edit_group="shape_torso" - edit_group_order="9" - label_min="Short Arms" - label_max="Long arms" - value_min="-1" - value_max="1" - value_default=".6" - camera_distance="1.5"> + edit_group_order="10" + label_min="Small Hands" + label_max="Large Hands" + value_min="-.3" + value_max=".3" + camera_elevation=".1" + camera_distance="1.4" + camera_angle="0"> <param_skeleton> <bone - name="mShoulderLeft" - scale="0 .2 0" /> + name="mWristRight" + scale="1 1 1" + offset="0 0 0" /> <bone - name="mShoulderRight" - scale="0 .2 0" /> + name="mWristLeft" + scale="1 1 1" + offset="0 0 0" /> - <bone - name="mElbowRight" - scale="0 .3 0" /> + <bone name = "mHandThumb1Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandThumb2Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandThumb3Right" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandIndex1Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandIndex2Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandIndex3Right" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandMiddle1Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandMiddle2Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandMiddle3Right" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandRing1Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandRing2Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandRing3Right" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandPinky1Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandPinky2Right" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandPinky3Right" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandThumb1Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandThumb2Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandThumb3Left" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandIndex1Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandIndex2Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandIndex3Left" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandMiddle1Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandMiddle2Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandMiddle3Left" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandRing1Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandRing2Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandRing3Left" scale = "1 1 1" offset = "0 0 0" /> + + <bone name = "mHandPinky1Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandPinky2Left" scale = "1 1 1" offset = "0 0 0" /> + <bone name = "mHandPinky3Left" scale = "1 1 1" offset = "0 0 0" /> - <bone - name="mElbowLeft" - scale="0 .3 0" /> </param_skeleton> </param> <param - id="756" + id="683" group="0" - name="Neck Length" + name="Neck Thickness" wearable="shape" edit_group="shape_torso" - edit_group_order="3" - label_min="Short Neck" - label_max="Long Neck" - value_min="-1" - value_max="1" - value_default="0" + edit_group_order="2" + label_min="Skinny Neck" + label_max="Thick Neck" + value_min="-.4" + value_max=".2" + value_default="-.15" camera_elevation=".3" camera_distance=".8" camera_angle="15"> <param_skeleton> <bone name="mNeck" - scale="0 0 .5" /> + scale="1 1 0" + offset="0 0 0" /> </param_skeleton> - </param> - <param - id="11001" - group="0" - name="Hover" - wearable="shape" - edit_group="shape_body" - edit_group_order="4" - label_min="Lower" - label_max="Higher" - value_min="-2" - value_max="2" - value_default="0" - camera_distance="2.5"> - <param_skeleton /> </param> - </skeleton> - - <mesh - type="hairMesh" - lod="0" - file_name="avatar_hair.llm" - min_pixel_width="320"> - <!-- begin morph targets --> <param - id="180" + id="689" group="1" - name="Hair_Volume" - label="Hair Volume" - show_simple="true" - wearable="hair" - clothing_morph="true" - edit_group="hair_style" - label_min="Less" - label_max="More" - value_min="0" - value_max="1.3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + wearable="shape" + name="EyeBone_Big_Eyes" + edit_group="shape_eyes" + label_min="Eyes Back" + label_max="Eyes Forward" + value_min="-1" + value_max="1"> + <param_skeleton> + + <bone + name="mEyeLeft" + scale="0 0 0" + offset="-.005 0 0" /> - <param - id="761" - group="1" - name="Hair_Volume_Small" - label="Hair Volume" - show_simple="true" - wearable="hair" - edit_group="hair_style" - label_min="Less" - label_max="More" - value_min="0" - value_max="1.3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + <bone + name="mEyeRight" + scale="0 0 0" + offset="-.005 0 0" /> + + +<bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="-.005 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="-.005 0 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0.3 0.7" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0.3 0.7" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0.3 0.7" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0.3 0.7" + offset=" 0 0 0" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0" + offset="-0.005 -0.008 0.0" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0" + offset="-0.005 0.008 0.0" /> + + </param_skeleton> </param> <param - id="181" + id="692" group="0" - name="Hair_Big_Front" - label="Big Hair Front" - wearable="hair" - edit_group="hair_style" - edit_group_order="5" - label_min="Less" - label_max="More" + name="Leg Length" + wearable="shape" + edit_group="shape_legs" + edit_group_order="2" + label_min="Short Legs" + label_max="Long Legs" value_min="-1" value_max="1" - value_default="0.14" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> + camera_distance="2.5"> + <param_skeleton> + <bone + name="mHipLeft" + scale="0 0 .2" /> + + <bone + name="mHipRight" + scale="0 0 .2" /> + + <bone + name="mKneeRight" + scale="0 0 .2" /> + + <bone + name="mKneeLeft" + scale="0 0 .2" /> + + <bone + name="mHindLimb1Left" + scale="0 0 .2" /> + + <bone + name="mHindLimb1Right" + scale="0 0 .2" /> + + <bone + name="mHindLimb2Right" + scale="0 0 .2" /> + + <bone + name="mHindLimb2Left" + scale="0 0 .2" /> + </param_skeleton> </param> <param - id="182" + id="693" group="0" - name="Hair_Big_Top" - label="Big Hair Top" - wearable="hair" - edit_group="hair_style" - edit_group_order="6" - label_min="Less" - label_max="More" + name="Arm Length" + wearable="shape" + edit_group="shape_torso" + edit_group_order="9" + label_min="Short Arms" + label_max="Long arms" value_min="-1" value_max="1" - value_default=".7" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> + value_default=".6" + camera_distance="1.5"> + <param_skeleton> + <bone + name="mShoulderLeft" + scale="0 .2 0" /> + + <bone + name="mShoulderRight" + scale="0 .2 0" /> + + <bone + name="mElbowRight" + scale="0 .3 0" /> + + <bone + name="mElbowLeft" + scale="0 .3 0" /> + </param_skeleton> </param> <param - id="183" + id="756" group="0" - name="Hair_Big_Back" - clothing_morph="true" - label="Big Hair Back" - wearable="hair" - edit_group="hair_style" - edit_group_order="7" - label_min="Less" - label_max="More" + name="Neck Length" + wearable="shape" + edit_group="shape_torso" + edit_group_order="3" + label_min="Short Neck" + label_max="Long Neck" value_min="-1" value_max="1" - value_default="0.05" - camera_elevation=".1" - camera_distance=".7" - camera_angle="90"> - <param_morph /> + value_default="0" + camera_elevation=".3" + camera_distance=".8" + camera_angle="15"> + <param_skeleton> + <bone + name="mNeck" + scale="0 0 .5" /> + </param_skeleton> </param> - + <param - id="184" + id="11001" group="0" - name="Hair_Spiked" - label="Spiked Hair" - show_simple="true" - wearable="hair" - clothing_morph="true" - edit_group="hair_style" - edit_group_order="15" - label_min="No Spikes" - label_max="Big Spikes" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + name="Hover" + wearable="shape" + edit_group="shape_body" + edit_group_order="4" + label_min="Lower" + label_max="Higher" + value_min="-2" + value_max="2" + value_default="0" + camera_distance="2.5"> + <param_skeleton /> </param> + + <param + id="30002" + group="1" + name="Nose_Big_Out" + value_min="-0.8" + value_max="2.5"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + offset = "0.0 0.0 0.0" + scale = "0.50 0.3 0.1" /> + <bone + name = "mFaceNoseLeft" + offset = "0 0 0" + scale = "0.0 0.3 0.0" /> + <bone + name = "mFaceNoseRight" + offset = "0 0 0" + scale = "0.0 0.3 0.0" /> + <bone + name = "mFaceNoseBridge" + offset = "0.006 0.0 0.0" + scale = "0.10 0.1 0.0" /> + </param_skeleton> + </param> + <param - id="140" - group="0" - name="Hair_Part_Middle" - label="Middle Part" - wearable="hair" - edit_group="hair_style" - edit_group_order="17" - label_min="No Part" - label_max="Part" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> + id="30004" + group="1" + name="Broad_Nostrils" + value_min="-.5" + value_max="1"> + <param_skeleton> + <bone + name = "mFaceNoseLeft" + offset = "0 0.005 0" + scale = "0.0 0.0 0.0" /> + <bone + name = "mFaceNoseRight" + offset = "0 -0.005 0" + scale = "0.0 0.0 0.0" /> + </param_skeleton> </param> - + <param - id="141" - group="0" - name="Hair_Part_Right" - label="Right Part" - wearable="hair" - edit_group="hair_style" - edit_group_order="18" - label_min="No Part" - label_max="Part" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> - </param> + id="30020" + group="1" + name="Bulbous_Nose" + value_min="-.5" + value_max="1.5" + > + <param_skeleton> + <bone + name = "mFaceNoseCenter" + offset = "0.0 0.0 0.0" + scale = "0.2 0.4 0.2" /> + <bone + name = "mFaceNoseLeft" + scale = "0 0.3 0" + offset = "0 0.0015 0" + /> + <bone + name = "mFaceNoseRight" + scale = "0 0.3 0" + offset = "0 -0.0015 0" + /> + + </param_skeleton> + </param> <param - id="142" - group="0" - name="Hair_Part_Left" - label="Left Part" - wearable="hair" - edit_group="hair_style" - edit_group_order="19" - label_min="No Part" - label_max="Part" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> + id="30517" + group="1" + name="Wide_Nose" + value_min="-.5" + value_max="1"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + offset = "0 0 0" + scale = "0.10 0.85 0.0" /> + <bone + name = "mFaceNoseLeft" + scale = "0 0 0" + offset = "0.001 0.013 0"/> + <bone + name = "mFaceNoseRight" + scale = "0 0 0" + offset = "0.001 -0.013 0" /> + </param_skeleton> </param> <param - id="143" - group="0" - name="Hair_Sides_Full" - label="Full Hair Sides" - show_simple="true" - wearable="hair" - edit_group="hair_style" - edit_group_order="11" - label_min="Mowhawk" - label_max="Full Sides" - value_min="-4" - value_max="1.5" - value_default="0.125" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + id="30656" + group="1" + name="Crooked_Nose" + value_min="-2" + value_max="2"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + scale = "0.0 0.00 0.0" + offset = "0.0 0.009 0.0" /> + + <bone + name = "mFaceNoseBase" + scale = "0.0 0.00 0.0" + offset = "0.0 0.007 0.0" /> + + <bone + name = "mFaceNoseLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.005 0.0"/> + + <bone + name = "mFaceNoseRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.005 0.0" /> + + <bone + name = "mFaceLipCornerLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.001 0.0" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.002 0.0" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.002 0.0" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.001 0.0" /> + + <bone + name = "mFaceEyebrowInnerRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.0008 0.0" /> + + <bone + name = "mFaceEyebrowInnerLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.0008 0.0" /> + + <bone + name = "mFaceNoseBridge" + scale = "0.0 0.00 0.0" + offset = "0.0 0.004 0.0" /> + + <bone + name = "mFaceTeethUpper" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceEyecornerInnerRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.001 0.0" /> + + <bone + name = "mFaceEyecornerInnerLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.001 0.0" /> + </param_skeleton> + </param> + <param - id="144" + id="30155" group="1" - name="Bangs_Front_Up" - label="Front Bangs Up" - wearable="hair" - edit_group="hair_style" - label_min="Bangs" - label_max="Bangs Up" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + name="Lip Width" + value_min="-0.9" + value_max="1.3" + value_default="0"> + <param_skeleton> + <bone + name = "mFaceLipCornerLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.005 0.0" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.003 0.0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceLipLowerRight" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.003 0.0" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.005 0.0" /> + + </param_skeleton> </param> <param - id="145" + id="30653" group="1" - clothing_morph="true" - name="Bangs_Front_Down" - label="Front Bangs Down" - wearable="hair" - edit_group="hair_style" - label_min="Bangs" - label_max="Bangs Down" - value_min="0" - value_max="5" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + name="Tall_Lips" + value_min="-1" + value_max="2"> + <param_skeleton> + <bone + name = "mFaceLipCornerLeft" + scale = "0.2 0.00 0.2" + offset = "-0.008 0.00 0.0" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0.2 0.00 0.2" + offset = "-0.009 0.00 0.0025" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0.2 0.00 0.2" + offset = "-0.009 0.00 0.0025" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0.2 0.00 0.2" + offset = "-0.009 0.00 0.0025" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0.2 0.00 0.2" + offset = "-0.008 0.00 0.0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0.2 0.00 0.2" + offset = "-0.008 0.00 -0.0015" /> + + <bone + name = "mFaceLipLowerCenter" + scale = "0.2 0.00 0.2" + offset = "-0.008 0.00 -0.0025" /> + <bone + name = "mFaceLipLowerRight" + scale = "0.2 0.00 0.2" + offset = "-0.008 0.00 -0.0015" /> + + </param_skeleton> + </param> + <param - id="146" + id="30505" group="1" - name="Bangs_Sides_Up" - label="Side Bangs Up" - wearable="hair" - edit_group="hair_style" - label_min="Side Bangs" - label_max="Side Bangs Up" + name="Lip_Thickness" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + value_max="0.7"> + <param_skeleton> + + <bone + name = "mFaceLipCornerLeft" + scale = "0.2 0.00 -0.6" + offset = "-0.01 0.00 0.0" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0.2 0.00 -0.6" + offset = "-0.012 0.00 -0.005" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0.2 0.00 -0.6" + offset = "-0.015 0.00 -0.005" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0.2 0.00 -0.6" + offset = "-0.012 0.00 -0.005" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0.2 0.00 -0.6" + offset = "-0.01 0.00 0.0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0.2 0.00 -0.6" + offset = "-0.01 0.00 0.008" /> + + <bone + name = "mFaceLipLowerCenter" + scale = "0.2 0.00 -0.6" + offset = "-0.01 0.00 0.008" /> + + <bone + name = "mFaceLipLowerRight" + scale = "0.2 0.00 -0.6" + offset = "-0.01 0.00 0.008" /> + </param_skeleton> + </param> + <param - id="147" + id="31505" group="1" - clothing_morph="true" - name="Bangs_Sides_Down" - label="Side Bangs Down" - wearable="hair" - edit_group="hair_style" - label_min="Side Bangs" - label_max="Side Bangs Down" + name="Lip_Thickness" value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + value_max="1"> + <param_skeleton> + + <bone + name = "mFaceLipCornerLeft" + scale = "0.2 0.00 0.1" + offset = "0.005 0.00 0.0" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0.2 0.00 0.4" + offset = "0.004 0.00 0.004" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0.2 0.00 0.4" + offset = "0.004 0.00 0.004" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0.2 0.00 0.4" + offset = "0.004 0.00 0.004" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0.2 0.00 0.1" + offset = "0.005 0.00 0.0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0.2 0.00 0.3" + offset = "0.006 0.00 -0.003" /> + + <bone + name = "mFaceLipLowerCenter" + scale = "0.2 0.00 0.3" + offset = "0.006 0.00 -0.003" /> + <bone + name = "mFaceLipLowerRight" + scale = "0.2 0.00 0.3" + offset = "0.006 0.00 -0.003" /> + + </param_skeleton> + </param> + <param - id="148" + id="30797" group="1" - name="Bangs_Back_Up" - label="Back Bangs Up" - wearable="hair" - edit_group="hair_style" - label_min="Back Bangs" - label_max="Back Bangs Up" + name="Fat_Upper_Lip" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> + value_max="1.5"> + <param_skeleton> + + <bone + name = "mFaceLipCornerLeft" + scale = "0 0 0" + offset = "-0.002 0.00 0.001" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0 0 0" + offset = "-0.002 0.00 0.001" /> + + <bone + name = "mFaceLipUpperLeft" + scale = " 0.1 0 0.6" + offset = "-0.004 0.00 0.006" /> + + <bone + name = "mFaceLipUpperCenter" + scale = " 0.1 0 0.4" + offset = "-0.004 0.00 0.003" /> + + <bone + name = "mFaceLipUpperRight" + scale = " 0.1 0 0.6" + offset = "-0.004 0.00 0.006" /> + + <bone + name = "mFaceLipLowerLeft" + scale = " 0 0 0" + offset = "-0.002 0.00 0.001" /> + + <bone + name = "mFaceLipLowerCenter" + scale = " 0 0 0" + offset = "-0.002 0.00 0.001" /> + + <bone + name = "mFaceLipLowerRight" + scale = " 0 0 0" + offset = "-0.002 0.00 0.001" /> + + </param_skeleton> </param> <param - id="149" + id="30798" group="1" - name="Bangs_Back_Down" - label="Back Bangs Down" - clothing_morph="true" - wearable="hair" - edit_group="hair_style" - label_min="Back Bangs" - label_max="Back Bangs Down" + name="Fat_Lower_Lip" value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> + value_max="1.5"> + <param_skeleton> + + <bone + name = "mFaceLipCornerLeft" + scale = "0 0 0" + offset = "-0.002 0.00 -0.002" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0 0 0" + offset = "-0.002 0.00 -0.002" /> + + <bone + name = "mFaceLipUpperLeft" + scale = " 0 0 0" + offset = "-0.002 0.00 -0.003" /> + + <bone + name = "mFaceLipUpperCenter" + scale = " 0 0 0" + offset = "-0.002 0.00 -0.003" /> + + <bone + name = "mFaceLipUpperRight" + scale = " 0 0 0" + offset = "-0.002 0.00 -0.003" /> + + <bone + name = "mFaceLipLowerLeft" + scale = " 0.1 0 0.25" + offset = "-0.005 0.00 -0.004" /> + + <bone + name = "mFaceLipLowerCenter" + scale = " 0.1 0 0.25" + offset = "-0.005 0.00 -0.004" /> + + <bone + name = "mFaceLipLowerRight" + scale = " 0.1 0 0.25" + offset = "-0.005 0.00 -0.004" /> + + </param_skeleton> </param> + + <param + id="30506" + group="1" + name="Mouth_Height" + value_min="-2" + value_max="2"> + <param_skeleton> + + <bone + name = "mFaceTeethUpper" + scale = "0.0 0.00 0.0" + offset = "0 0 -0.006" /> + + <bone + name = "mFaceTeethLower" + scale = "0.0 0.00 0.0" + offset = "0 0 -0.006" /> + + <bone + name = "mFaceNoseBase" + scale = "0.0 0.00 0.0" + offset = "0 0 -0.001" /> + </param_skeleton> + </param> + <param - id="171" + id="30658" group="1" - name="Hair_Front_Down" - label="Front Hair Down" - wearable="hair" - edit_group="hair_style" - label_min="Front Hair" - label_max="Front Hair Down" + name="Frown_Mouth" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + value_max="1.4"> + <param_skeleton> + <bone + name = "mFaceLipCornerLeft" + scale = "0 0 0" + offset = "0 0 -0.005" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0 0 0" + offset = "0 0 -0.005" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0 0 0" + offset = "0 0 0" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0 0 0" + offset = "0 0 0" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0 0 0" + offset = "0 0 0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0 0 0" + offset = "0 0 0.001" /> + + <bone + name = "mFaceLipLowerCenter" + scale = "0 0 0" + offset = "0 0 0.002" /> + + <bone + name = "mFaceLipLowerRight" + scale = "0 0 0" + offset = "0 0 0.001" /> + </param_skeleton> </param> <param - id="172" + id="30657" group="1" - name="Hair_Front_Up" - label="Front Hair Up" - wearable="hair" - edit_group="hair_style" - label_min="Front Hair" - label_max="Front Hair Up" + name="Smile_Mouth" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + value_max="1.4"> + <param_skeleton> + + <bone + name = "mFaceLipCornerLeft" + scale = "0 0 0" + offset = "0 0.005 0.002" /> + + <bone + name = "mFaceLipCornerRight" + scale = "0 0 0" + offset = "0 -0.005 0.002" /> + + <bone + name = "mFaceLipUpperLeft" + scale = "0 0 0" + offset = "0 0.002 0" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0 0 0" + offset = "0 0 -0.0005" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0 0 0" + offset = "0 -0.002 0" /> + + <bone + name = "mFaceLipLowerLeft" + scale = "0 0 0" + offset = "0 0.001 0" /> + + <bone + name = "mFaceLipLowerCenter" + scale = "0 0 0" + offset = "0 0 -0.001" /> + + <bone + name = "mFaceLipLowerRight" + scale = "0 0 0" + offset = "0 -0.001 0" /> + + </param_skeleton> </param> + +<param + id="30764" + group="1" + name="Lip_Cleft_Deep" + value_min="-1" + value_max="1.2"> + <param_skeleton> + + <bone + name = "mFaceLipUpperLeft" + scale = "0 0 0.3" + offset = "0 0 0.003" /> + + <bone + name = "mFaceLipUpperCenter" + scale = "0 0 -0.1" + offset = "0 0 -0.001" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0 0 0.3" + offset = "0 0 0.003" /> + + </param_skeleton> + </param> + +<param + id="30025" + group="1" + name="Wide_Lip_Cleft" + value_min="-.8" + value_max="1.5"> + <param_skeleton> + + <bone + name = "mFaceLipUpperLeft" + scale = "0 0.1 0" + offset = "0 0.0 0" /> + + <bone + name = "mFaceLipUpperRight" + scale = "0 0.1 0" + offset = "0 0.0 0" /> + <bone + name = "mFaceLipCornerRight" + scale = "0.0 0 0" + offset = "0 0.001 0" /> + + <bone + name = "mFaceLipCornerLeft" + scale = "0.0 0 0" + offset = "0 -0.001 0" /> + + </param_skeleton> + </param> + <param - id="173" + id="31663" group="1" - name="Hair_Sides_Down" - label="Sides Hair Down" - wearable="hair" - edit_group="hair_style" - label_min="Sides Hair" - label_max="Sides Hair Down" + name="Shift_Mouth" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + value_max="2"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.003 0.0" /> + + <bone + name = "mFaceNoseBase" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.004 0.0" /> + + <bone + name = "mFaceNoseLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.003 0.0"/> + + <bone + name = "mFaceNoseRight" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.003 0.0" /> + + <bone + name = "mFaceTeethUpper" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.006 0.0" /> + + <bone + name = "mFaceTeethLower" + scale = "0.0 0.00 0.0" + offset = "0.0 -0.006 0.0" /> + + + + </param_skeleton> </param> <param - id="174" + id="32663" group="1" - name="Hair_Sides_Up" - label="Sides Hair Up" - wearable="hair" - edit_group="hair_style" - label_min="Sides Hair" - label_max="Sides Hair Up" + name="Shift_Mouth" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + value_max="2"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceNoseBase" + scale = "0.0 0.00 0.0" + offset = "0.0 0.004 0.0" /> + + <bone + name = "mFaceNoseLeft" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0"/> + + <bone + name = "mFaceNoseRight" + scale = "0.0 0.00 0.0" + offset = "0.0 0.003 0.0" /> + + <bone + name = "mFaceTeethUpper" + scale = "0.0 0.00 0.0" + offset = "0.0 0.006 0.0" /> + + <bone + name = "mFaceTeethLower" + scale = "0.0 0.00 0.0" + offset = "0.0 0.006 0.0" /> + + + </param_skeleton> + </param> <param - id="175" + id="30035" group="1" - name="Hair_Back_Down" - label="Back Hair Down" - clothing_morph="true" - wearable="hair" - edit_group="hair_style" - label_min="Back Hair" - label_max="Back Hair Down" - value_min="0" - value_max="3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> + name="Big_Ears" + value_min="-1" + value_max="2"> + <param_skeleton> + <bone + name = "mFaceEar1Left" + scale = "0.55 0.55 0.55" + offset = "0.0 -0.002 0.001" /> + <bone + name = "mFaceEar1Right" + scale = "0.55 0.55 0.55" + offset = "0.0 0.002 0.001" /> + </param_skeleton> </param> - + <param - id="176" + id="30015" group="1" - name="Hair_Back_Up" - label="Back Hair Up" - wearable="hair" - edit_group="hair_style" - label_min="Back Hair" - label_max="Back Hair Up" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> + name="Ears_Out" + value_min="-.5" + value_max="1.5"> + <param_skeleton> + <!-- Place Holder. Can't do this unless we get rotation offset --> + <bone + name = "mFaceEar1Left" + offset = "0.0 -0.0 0.0" + scale = "0.0 0.0 0.0" /> + <bone + name = "mFaceEar1Right" + offset = "0.0 0.0 0.0" + scale = "0.0 0.0 0.0" /> + </param_skeleton> + </param> + + <param + id="30796" + group="1" + name="Pointy_Ears" + value_min="-.4" + value_max="3"> + <param_skeleton> + <bone + name = "mFaceEar2Left" + offset = "-0.0149 0.001 0.016" + scale = "0.0 0.0 0.0" /> + <bone + name = "mFaceEar2Right" + offset = "-0.0149 -0.001 0.016" + scale = "0.0 0.0 0.0" /> + </param_skeleton> </param> - + <param - id="177" - group="0" - name="Hair_Rumpled" - label="Rumpled Hair" - show_simple="true" - wearable="hair" - clothing_morph="true" - edit_group="hair_style" - edit_group_order="14.5" - label_min="Smooth Hair" - label_max="Rumpled Hair" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + id="30185" + group="1" + name="Deep_Chin" + value_min="-1" + value_max="1"> + <!-- used for the chin depth slider --> + <param_skeleton> + <bone + name = "mFaceChin" + offset = "0.0 0.00 -0.025" + scale = "0.0 0.0 0.0" /> + </param_skeleton> </param> - <param - id="178" + id="40185" group="1" - name="Hair_Swept_Back" - label="Swept Back Hair" - wearable="hair" - edit_group="hair_style" - label_min="NotHair" - label_max="Swept Back" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> + name="Deep_Chin" + value_min="-1" + value_max="1"> + <!-- used for the head shape slider --> + <param_skeleton> + <bone + name = "mFaceChin" + offset = "0.0 0.00 -0.02" + scale = "0.0 0.0 0.0" /> + </param_skeleton> </param> - + <param - id="179" + id="30760" group="1" - name="Hair_Swept_Forward" - label="Swept Forward Hair" - wearable="hair" - edit_group="hair_style" - label_min="Hair" - label_max="Swept Forward" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> + name="Jaw_Angle" + value_min="-1.2" + value_max="2" + value_default="0"> + <param_skeleton> + <bone + name = "mFaceJawShaper" + offset = "0.0 0.00 0.03" + scale = "0.0 0.0 0.0" /> + </param_skeleton> </param> - + + <param - id="190" + id="30665" group="1" - name="Hair_Tilt_Right" - label="Hair Tilted Right" - wearable="hair" - edit_group="hair_style" - label_min="Hair" - label_max="Tilt Right" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> - </param> + name="Jaw_Jut" + value_min="-2" + value_max="2"> + <param_skeleton> + + <bone + name = "mFaceTeethLower" + offset = "0.008 0 0" + scale = "0.0 0.0 0.0" /> + <bone + name = "mFaceChin" + offset = "0.008 0.00 0" + scale = "0.0 0.0 0.0" /> + + </param_skeleton> + </param> + <param - id="191" + id="30006" group="1" - name="Hair_Tilt_Left" - label="Hair Tilted Left" - wearable="hair" - edit_group="hair_style" - label_min="Hair" - label_max="Tilt Left" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> + name="Bulbous_Nose_Tip" + value_min="-1" + value_max="1.5"> + <param_skeleton> + <bone + name = "mFaceNoseCenter" + offset = "0.0 0.00 0.0" + scale = "0.1 0.1 0.1" /> + + </param_skeleton> </param> - + <param - id="192" - group="0" - name="Bangs_Part_Middle" - label="Part Bangs" - wearable="hair" - edit_group="hair_style" - edit_group_order="20" - label_min="No Part" - label_max="Part Bangs" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> + id="30007" + group="1" + name="Weak_Chin" + value_min="-.5" + value_max=".5"> + <param_skeleton> + <bone + name = "mFaceChin" + offset = "-0.06 0.00 0.01" + scale = "0.0 0.0 0.0" /> + + </param_skeleton> + </param> + + <param + id="40007" + group="1" + name="Weak_Chin" + value_min="-.5" + value_max=".5"> + <param_skeleton> + <bone + name = "mFaceChin" + offset = "-0.025 0.00 0.005" + scale = "0.0 0.0 0.0" /> + + </param_skeleton> + </param> + + <param + id="30008" + group="1" + name="Double_Chin" + value_min="-.5" + value_max="1.5"> + <param_skeleton> + <bone + name = "mFaceJawShaper" + offset = "0 0 0" + scale = "0.0 0.125 0.5" /> + </param_skeleton> </param> + + + <param + id="30024" + group="1" + name="Wide_Eyes" + value_min="-1.5" + value_max="2"> + <param_skeleton> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0.1 0.2" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0.1 0.2" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0.1 0.2" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0.1 0.2" + offset=" 0 0 0" /> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="0 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="0 0 0" /> + </param_skeleton> + </param> + <param - id="640" + id="30650" group="1" - name="Hair_Egg_Head" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" + name="Eyelid_Corner_Up" value_min="-1.3" - value_max="1"> - <param_morph /> + value_max="1.2"> + <param_skeleton> + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0" + offset="0 0 .004" /> + </param_skeleton> </param> + + <param + id="30880" + group="1" + name="Eyelid_Inner_Corner_Up" + value_min="-1.3" + value_max="1.2"> + <param_skeleton> + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0" + offset="0 0 .004" /> + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0" + offset="0 0 .004" /> + </param_skeleton> + </param> + <param - id="641" + id="30765" group="1" - name="Hair_Squash_Stretch_Head" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" - value_min="-.5" - value_max="1"> - <param_morph /> + name="Puffy_Lower_Lids" + value_min="-.3" + value_max="2.5"> + <param_skeleton> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0.05 0.05 0.05" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0.05 0.05 0.05" + offset="0 0 0" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0.05 0.05 0.05" + offset="0 0 0" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0.05 0.05 0.05" + offset="0 0 0" /> + + </param_skeleton> </param> <param - id="642" + id="31629" group="1" - name="Hair_Square_Head" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" + name="Forehead Angle" value_min="0" value_max="1"> - <param_morph /> - </param> + <param_skeleton> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0.08" + offset="0.02 0 0" /> + + <bone + name="mFaceForeheadCenter" + scale="0.01 0 0.08" + offset="0.002 0 0" /> + <bone + name="mFaceForeheadRight" + scale="0 0 0.08" + offset="0.02 0 0" /> + + </param_skeleton> + </param> + <param - id="643" + id="41629" group="1" - name="Hair_Round_Head" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" + name="Forehead Angle" value_min="0" value_max="1"> - <param_morph /> + <param_skeleton> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0.08" + offset="0.02 0 0" /> + + <bone + name="mFaceForeheadCenter" + scale="0.01 0 0.08" + offset="0.002 0 0" /> + + <bone + name="mFaceForeheadRight" + scale="0 0 0.08" + offset="0.02 0 0" /> + + </param_skeleton> + </param> + + <param + id="30647" + group="1" + name="Squash_Stretch_Head" + value_min="-0.5" + value_max="1" + value_default="0"> + <param_skeleton> + + <bone + name="mFaceRoot" + scale="0 -0.1 0.1" + offset="0 0 0" /> + + <bone + name="mFaceChin" + scale="0 -0.1 0.5" + offset="0 0 -0.005" /> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="0 0 -0.006" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0" + offset="0 -0.0053 -0.0047" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0" + offset="0 -0.0045 -0.0053" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0" + offset="0 -0.00225 -0.0048" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0" + offset="0 0.0053 -0.0047" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0" + offset="0 0.0045 -0.0053" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0" + offset="0 0.00225 -0.0048" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="0 -0.0042 -0.0035" /> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="0 0.0042 -0.0035" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0" + offset="0 -0.0039 -0.0032" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0" + offset="0 0.0039 -0.0032" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0" + offset="0 -0.0039 -0.0032" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0" + offset="0 0.0039 -0.0032" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0" + offset="0 -0.00225 -0.0032" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0" + offset="0 0.00225 -0.0032" /> + + <bone + name="mFaceNoseBridge" + scale="0 0 0" + offset="0 0 -0.002" /> + + <bone + name="mFaceNoseRight" + scale="0 0 0" + offset="0 -0.002 0" /> + + <bone + name="mFaceNoseLeft" + scale="0 0 0" + offset="0 0.002 0" /> + + <bone + name="mFaceNoseBase" + scale="0 0 0" + offset="0 0 0.002" /> + + <bone + name="mFaceCheekUpperRight" + scale="0 0 0" + offset="0 -0.003 0" /> + + <bone + name="mFaceCheekUpperLeft" + scale="0 0 0" + offset="0 0.003 0" /> + + <bone + name="mFaceCheekLowerRight" + scale="0 0 0" + offset="0 -0.003 0.0032" /> + + <bone + name="mFaceCheekLowerLeft" + scale="0 0 0" + offset="0 0.003 0.0032" /> + + <bone + name="mFaceTeethUpper" + scale="0 0 0" + offset="0 0 0.0032" /> + <bone + name="mFaceTeethLower" + scale="0 0 0" + offset="0 0 0.0016" /> + + </param_skeleton> </param> <param - id="644" + id="32629" group="1" - name="Hair_Forehead_Round" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" + name="Forehead Angle" value_min="0" value_max="1"> - <param_morph /> + <param_skeleton> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="-0.001 0 0.001" /> + + <bone + name="mFaceForeheadRight" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0" + offset="0 0 0.002" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0" + offset="0 0 0.002" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0" + offset="0 0 0.003" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0" + offset="0 0 0.003" /> + + </param_skeleton> </param> <param - id="645" + id="42629" group="1" - name="Hair_Forehead_Slant" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" + name="Forehead Angle" value_min="0" value_max="1"> - <param_morph /> + <param_skeleton> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="-0.001 0 0.001" /> + + <bone + name="mFaceForeheadRight" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0" + offset="0 0 0.002" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0" + offset="0 0 0.002" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0" + offset="0 0 0.003" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0" + offset="0 0 0.003" /> + + </param_skeleton> </param> <param - id="774" + id="30001" group="1" - name="Shear_Head_Hair" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" - value_min="-2" + name="Big_Brow" + value_min="-.3" value_max="2"> - <param_morph /> - </param> + <param_skeleton> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="0.007 0 0.001" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0.1 0 0" + offset="0.004 0 0" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0.1 0 0" + offset="0.004 0 0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0.1 0 0" + offset="0.004 0 0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0.1 0 0" + offset="0.004 0 0" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0" + offset="0.004 0 0" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0" + offset="0.004 0 0" /> + </param_skeleton> + </param> + <param - id="771" + id="30011" group="1" - name="Elongate_Head_Hair" - wearable="hair" - edit_group="hair_style" - cross_wearable="true" - value_min="-1" - value_max="1"> - <param_morph /> + name="Noble_Nose_Bridge" + value_min="-.5" + value_max="1.5"> + <param_skeleton> + + <bone + name="mFaceNoseBridge" + scale="0.15 0.01 0.7" + offset="0.009 0 -0.006" /> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="0.001 0 0" /> + + </param_skeleton> </param> <param - id="674" - group="0" - name="Hair_Shear_Back" - wearable="hair" - edit_group="hair_style" - edit_group_order="12" - label="Shear Back" - label_min="Full Back" - label_max="Sheared Back" - value_min="-1" - value_max="2" - value_default="-0.3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="100"> - <param_morph /> + id="30758" + group="1" + name="Lower_Bridge_Nose" + value_min="-1.5" + value_max="1.5"> + <param_skeleton> + + <bone + name="mFaceNoseBridge" + scale="0 0 0.2" + offset="0.0025 0 -0.001" /> + + <bone + name="mFaceNoseCenter" + scale="0 0 0" + offset="0.004 0 0.001" /> + + </param_skeleton> </param> <param - id="762" - group="0" - name="Hair_Shear_Front" - wearable="hair" - edit_group="hair_style" - edit_group_order="11.8" - label="Shear Front" - show_simple="true" - label_min="Full Front" - label_max="Sheared Front" - value_min="0" - value_max="3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="30"> - <param_morph /> - </param> + id="30027" + group="1" + name="Wide_Nose_Bridge" + value_min="-1.3" + value_max="1.2"> + <param_skeleton> + + <bone + name="mFaceNoseBridge" + scale="0 0.4 0" + offset="0 0 0" /> + </param_skeleton> + </param> + <param - id="754" - group="0" - name="Hair_Taper_Back" - wearable="hair" - edit_group="hair_style" - edit_group_order="14" - label="Taper Back" - label_min="Wide Back" - label_max="Narrow Back" + id="30759" + group="1" + name="Low_Septum_Nose" value_min="-1" - value_max="2" - value_default="0" - camera_elevation=".1" - camera_distance=".5" - camera_angle="160"> - <param_morph /> - </param> + value_max="1.5" + value_default="0.5"> + <param_skeleton> + <bone + name="mFaceNoseBase" + scale="0 0 0" + offset="0 0 -0.004" /> + + </param_skeleton> + + </param> + + <param - id="755" - group="0" - name="Hair_Taper_Front" - wearable="hair" - edit_group="hair_style" - edit_group_order="13" - label="Taper Front" - label_min="Wide Front" - label_max="Narrow Front" + id="30010" + group="1" + name="Sunken_Cheeks" value_min="-1.5" - value_max="1.5" - value_default="0.05" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + value_max="3"> + <param_skeleton> + + <bone + name="mFaceCheekLowerLeft" + scale="0 -0.12 0" + offset="0.0 0.0 0" /> + <bone + name="mFaceCheekLowerRight" + scale="0 -0.12 0" + offset="0 0 0" /> + + </param_skeleton> </param> <param - id="782" + id="30017" group="1" - clothing_morph="true" - name="Hair_Pigtails_Short" - wearable="hair" - edit_group="hair_style" - value_min="0" + name="Square_Jaw" + value_min="-0.5" value_max="1"> - <param_morph /> - </param> + <param_skeleton> + + <bone + name="mFaceChin" + scale="0.0 0.5 0.0" + offset="0.0 0.0 0.0" /> + + </param_skeleton> + </param> <param - id="783" + id="40017" group="1" - clothing_morph="true" - name="Hair_Pigtails_Med" - wearable="hair" - edit_group="hair_style" - value_min="0" + name="Square_Jaw" + value_min="-0.5" value_max="1"> - <param_morph /> - </param> + <param_skeleton> - <param - id="790" + <bone + name="mFaceJaw" + scale="0.0 0.5 0.0" + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceJawShaper" + scale="0.0 0.5 0.0" + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceLipLowerRight" + scale="0.0 0.0 0.0" + offset="0.0 0.0038 0.0" /> + + <bone + name="mFaceLipLowerLeft" + scale="0.0 0.0 0.0" + offset="0.0 -0.0038 0.0" /> + + </param_skeleton> + </param> + + + <param + id="30018" group="1" - clothing_morph="true" - name="Hair_Pigtails_Medlong" - wearable="hair" - edit_group="hair_style" - value_min="0" - value_max="1"> - <param_morph /> - </param> + name="Puffy_Upper_Cheeks" + value_min="-1.5" + value_max="2.5"> + <param_skeleton> + + <bone + name="mFaceCheekUpperLeft" + scale="0.15 0.1 0.1" + offset="0.002 0 0.0015" /> + + <bone + name="mFaceCheekUpperRight" + scale="0.15 0.1 0.1" + offset="0.002 0 0.0015" /> + </param_skeleton> + </param> + <param - id="784" + id="30021" group="1" - clothing_morph="true" - name="Hair_Pigtails_Long" - wearable="hair" - edit_group="hair_style" - value_min="0" - value_max="1"> - <param_morph /> + name="Upper_Eyelid_Fold" + value_min="-0.2" + value_max="1.3"> + <param_skeleton> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0" + offset="0 0 -.006" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0" + offset="0 0 -.006" /> + + </param_skeleton> </param> <param - id="786" + id="30023" group="1" - name="Hair_Ponytail_Short" - wearable="hair" - edit_group="hair_style" - value_min="0" - value_max="1"> - <param_morph /> + name="Baggy_Eyes" + value_min="-.5" + value_max="1.5"> + <param_skeleton> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 .5" + offset="0 0 -.001" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 .5" + offset="0 0 -.001" /> + + </param_skeleton> </param> <param - id="787" + id="30014" group="1" - name="Hair_Ponytail_Med" - wearable="hair" - edit_group="hair_style" - value_min="0" + name="High_Cheek_Bones" + value_min="-.5" value_max="1"> - <param_morph /> - </param> + <param_skeleton> + + <bone + name="mFaceCheekUpperLeft" + scale="0 0 0" + offset="0 0 0.02" /> + + <bone + name="mFaceCheekUpperRight" + scale="0 0 0" + offset="0 0 0.02" /> + </param_skeleton> + </param> + <param - id="788" + id="30019" group="1" - name="Hair_Ponytail_Long" - clothing_morph="true" - wearable="hair" - edit_group="hair_style" - value_min="0" + name="Upturned_Nose_Tip" + value_min="-1.5" value_max="1"> - <param_morph /> - </param> + <param_skeleton> - <!-- #end morph targets --> - </mesh> + <bone + name="mFaceNoseBase" + scale="0 0 0" + offset="0.001 0 -0.0015" /> - <mesh - type="hairMesh" - lod="1" - file_name="avatar_hair_1.llm" - min_pixel_width="160" - reference="avatar_hair.llm"> - </mesh> + <bone + name="mFaceNoseCenter" + scale="0 0 0" + offset="-0.002 0 0.004" /> - <mesh - type="hairMesh" - lod="2" - file_name="avatar_hair_2.llm" - min_pixel_width="80" - reference="avatar_hair.llm"> - </mesh> + <bone + name="mFaceNoseRight" + scale="0 0 0" + offset="0.001 0 -0.002" /> - <mesh - type="hairMesh" - lod="3" - file_name="avatar_hair_3.llm" - min_pixel_width="40" - reference="avatar_hair.llm"> - </mesh> + <bone + name="mFaceNoseLeft" + scale="0 0 0" + offset="0.001 0 -0.002" /> - <mesh - type="hairMesh" - lod="4" - file_name="avatar_hair_4.llm" - min_pixel_width="20" - reference="avatar_hair.llm"> - </mesh> + </param_skeleton> + </param> + + <param + id="30879" + group="1" + sex="male" + name="Male_Package" + value_min="-.5" + value_max="2"> + <param_skeleton> - <mesh - type="hairMesh" - lod="5" - file_name="avatar_hair_5.llm" - min_pixel_width="0" - reference="avatar_hair.llm"> - </mesh> + <bone + name = "mGroin" + offset = "0.0 0.0 0.0" + scale = ".5 .25 .1" /> + + </param_skeleton> + </param> + + <param + id="30193" + group="1" + name="Square_Head" + value_min="-1" + value_max="1"> + <param_skeleton> + + <bone + name="mFaceChin" + scale="0.0 -0.2 0.0" + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceRoot" + scale="0.0 0 0.0" + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceCheekLowerRight" + scale="0.0 -0.2 0.0" + offset="0.0 0 0.0" /> + + <bone + name="mFaceCheekLowerLeft" + scale="0.0 -0.2 0.0" + offset="0.0 0 0.0" /> + + <bone + name="mFaceForeheadRight" + scale="0.0 -1.0 0.0" + offset="0.0 0.01 -0.01" /> + + <bone + name="mFaceForeheadLeft" + scale="0.0 -1.0 0.0" + offset="0.0 -0.01 -0.01" /> + + <bone + name="mFaceJawShaper" + scale="0.0 -0.3 0.0" + offset="0.0 0 0" /> + + </param_skeleton> + </param> + + <param + id="30646" + group="1" + name="Egg_Head" + value_min="-1.3" + value_max="1" + value_default="0"> + <param_skeleton> - <mesh - type="headMesh" - lod="0" - file_name="avatar_head.llm" - min_pixel_width="320"> - <!-- - begin morph targets - ############# - tweakable morphs - ############# - --> + <bone + name="mFaceRoot" + scale="0 -0.07 0.07" + offset="0 0 -0.005" /> + + <bone + name="mFaceForeheadLeft" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name="mFaceForeheadCenter" + scale="0 0 0" + offset="-0.001 0 0.001" /> + + <bone + name="mFaceForeheadRight" + scale="0 0 0.2" + offset="-0.01 0 -0.01" /> + + <bone + name = "mFaceChin" + offset = "0.015 0.00 0.005" + scale = "0.0 0.0 0.0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="0 -0.0033 0.0025" /> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="0 0.0033 0.0025" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0" + offset="0 -0.0033 0.0025" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0" + offset="0 -0.0033 0.002" /> + + <bone + name="mFaceEyecornerInnerRight" + scale="0 0 0" + offset="0 -0.0017 0.0025" /> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0" + offset="0 -0.004 0.0014" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0" + offset="0 -0.00377 0.00061" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0" + offset="0 -0.00225 0.001" /> + + + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0" + offset="0 0.0033 0.0025" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0" + offset="0 0.0033 0.002" /> + + <bone + name="mFaceEyecornerInnerLeft" + scale="0 0 0" + offset="0 0.0017 0.0025" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0" + offset="0 0.004 0.0014" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0" + offset="0 0.00377 0.00061" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0" + offset="0 0.00225 0.001" /> + + <bone + name="mFaceLipLowerRight" + scale="0 0 0" + offset="0 0 0" /> + <bone + name="mFaceLipLowerCenter" + scale="0 0 0" + offset="0 0 0" /> + <bone + name="mFaceLipLowerLeft" + scale="0 0 0" + offset="0 0 0" /> + + <bone + name="mFaceTeethUpper" + scale="0 0 0" + offset="0 0 0.0075" /> + + <bone + name="mFaceTeethLower" + scale="0 0 0" + offset="0 0 0.0061" /> + + <bone + name="mFaceTongueBase" + scale="0 0 0" + offset="0 0 -0.00" /> + + <bone + name="mFaceCheekLowerRight" + scale="0 0 0" + offset="0 0 0.0085" /> + + <bone + name="mFaceCheekLowerLeft" + scale="0 0 0" + offset="0 0 0.0085" /> + + <bone + name="mFaceCheekUpperRight" + scale="0 0 0" + offset="0 0 0.005" /> + + <bone + name="mFaceCheekUpperLeft" + scale="0 0 0" + offset="0 0 0.005" /> + + <bone + name="mFaceNoseCenter" + scale="0 0 0" + offset="0 0 0.005" /> + + <bone + name="mFaceNoseRight" + scale="0 0 0" + offset="0 0 0.005" /> + + <bone + name="mFaceNoseLeft" + scale="0 0 0" + offset="0 0 0.005" /> + + <bone + name="mFaceNoseBase" + scale="0 0 0" + offset="0 0 0.006" /> + + <bone + name="mFaceJawShaper" + scale="0 0.2 0" + offset="0 0 0" /> + + </param_skeleton> + </param> + <param - id="1" - group="0" - name="Big_Brow" - label="Brow Size" - wearable="shape" - edit_group="shape_head" - edit_group_order="7" - label_min="Small" - label_max="Large" - value_min="-.3" - value_max="2" - camera_elevation=".1" - camera_distance=".4" - camera_angle="45"> - <param_morph /> + id="30689" + group="1" + name="EyeBone_Big_Eyes" + value_min="-1.1" + value_max="1.1"> + <param_skeleton> + + <!-- Experimental: Added Scale to the System eyes. From first look this affects only custom meshes. + | The result is: Custom eyes now scale in the same way as system eyes do + | Revert by setting scale to scale="0 0 0" for mEyeLeft and mEyeRight + --> + <bone + name="mEyeLeft" + scale="0.248 0.25 0.25" + offset="0 0 0" /> + + <bone + name="mEyeRight" + scale="0.248 0.25 0.25" + offset="0 0 0" /> + + <bone + name="mFaceEyeAltLeft" + scale="0.248 0.25 0.25" + offset="0 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0.248 0.25 0.25" + offset="0 0 0" /> + + </param_skeleton> </param> <param - id="2" - group="0" - name="Nose_Big_Out" - label="Nose Size" - wearable="shape" - edit_group="shape_nose" - edit_group_order="1" - label_min="Small" - label_max="Large" - show_simple="true" - value_min="-0.8" - value_max="2.5" - camera_elevation=".1" - camera_distance=".35" - camera_angle="50"> - <param_morph /> + id="30772" + group="1" + name="EyeBone_Head_Elongate" + value_min="-1" + value_max="1"> + <param_skeleton> + + <bone + name="mFaceRoot" + scale="0.25 0 0" + offset="0 0 0" /> + + <bone + name="mFaceEyeLidUpperLeft" + scale="0 0 0" + offset="-0.0038 0 0" /> + + <bone + name="mFaceEyeLidUpperRight" + scale="0 0 0" + offset="-0.0038 0 0" /> + + <bone + name="mFaceEyeLidLowerLeft" + scale="0 0 0" + offset="-0.0038 0 0" /> + + <bone + name="mFaceEyeLidLowerRight" + scale="0 0 0" + offset="-0.0038 0 0" /> + + <bone + name="mFaceNoseCenter" + scale="0 0 0" + offset=".01 0 0" /> + + <bone + name="mFaceNoseRight" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mFaceNoseLeft" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mFaceNoseBase" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mFaceLipUpperLeft" + scale="0 0 0" + offset="0.005 0 0" /> + + <bone + name="mFaceLipUpperCenter" + scale="0 0 0" + offset="0.005 0 0" /> + + <bone + name="mFaceLipUpperRight" + scale="0 0 0" + offset="0.005 0 0" /> + + <bone + name="mFaceLipCornerRight" + scale="0 0 0" + offset="0.005 0 0" /> + + <bone + name="mFaceLipCornerLeft" + scale="0 0 0" + offset="0.005 0 0" /> + + <bone + name="mFaceLipLowerLeft" + scale="0 0 0" + offset="0.01 0 0" /> + + <bone + name="mFaceLipLowerCenter" + scale="0 0 0" + offset="0.01 0 0" /> + + <bone + name="mFaceLipLowerRight" + scale="0 0 0" + offset="0.01 0 0" /> + + + <bone + name="mFaceCheekLowerLeft" + scale="0 0 0" + offset="0.007 0 0" /> + + <bone + name="mFaceCheekLowerRight" + scale="0 0 0" + offset="0.007 0 0" /> + + <bone + name="mFaceChin" + scale="0 0 0" + offset="0.014 0 0" /> + + <bone + name="mFaceTeethUpper" + scale="0.28 0 0" + offset="0 0 0" /> + <bone + name="mFaceTeethLower" + scale="0.28 0 0" + offset="0 0 0" /> + + <bone + name="mFaceTongueBase" + scale="0.3 0 0" + offset="0 0 0" /> + + <bone + name="mFaceTongueTip" + scale="0 0 0" + offset="0.004 0 0" /> + + </param_skeleton> </param> + + <param + id="31772" + group="1" + name="EyeBone_Head_Elongate" + value_min="0" + value_max="1"> + <param_skeleton> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="0.0058 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="0.0058 0 0" /> + </param_skeleton> + </param> + <param - id="4" - group="0" - name="Broad_Nostrils" - label="Nostril Width" - wearable="shape" - edit_group="shape_nose" - edit_group_order="3" - label_min="Narrow" - label_max="Broad" - value_min="-.5" + id="32772" + group="1" + name="EyeBone_Head_Elongate" + value_min="0" + value_max="1"> + <param_skeleton> + + <bone + name="mFaceEyeAltLeft" + scale="0 0 0" + offset="-0.0032 0 0" /> + + <bone + name="mFaceEyeAltRight" + scale="0 0 0" + offset="-0.0032 0 0" /> + + </param_skeleton> + </param> + + + <!-- Eye Brow sliders --> + + <param + id="30119" + group="1" + name="Eyebrow Size" + value_min="0" value_max="1" + value_default="0.5"> + + <param_skeleton> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0.5" + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0.5" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0.5" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0.5" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0.5" + offset="0 0 0" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0.5" + offset="0 0 0" /> + + </param_skeleton> + </param> + + <param + id="30031" + group="1" + name="Arced_Eyebrows" + value_min="0" + value_max="2" + value_default=".5"> + + <param_skeleton> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0 " + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0 " + offset="0.0 0.0 0.005" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0 " + offset="0.0 0.0 0.001" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0 " + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0 " + offset="0.0 0.0 0.005" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0 " + offset="0.0 0.0 0.001" /> + + </param_skeleton> + </param> + + <param + id="30757" + group="1" + name="Lower_Eyebrows" + value_min="-4" + value_max="2" + value_default="-1"> + + <param_skeleton> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0 " + offset="0.0 0.0 -0.001" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0 " + offset="0.0 0.0 -0.002" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0 " + offset="0.0 0.0 -0.001" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0 " + offset="0.0 0.0 -0.001" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0 " + offset="0.0 0.0 -0.002" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0 " + offset="0.0 0.0 -0.001" /> + + </param_skeleton> + </param> + + <param + id="30016" + group="1" + name="Pointy_Eyebrows" + value_min="-.5" + value_max="3"> + + <param_skeleton> + + <bone + name="mFaceEyebrowOuterRight" + scale="0 0 0 " + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceEyebrowCenterRight" + scale="0 0 0 " + offset="0.0 -0.001 0.0035" /> + + <bone + name="mFaceEyebrowInnerRight" + scale="0 0 0 " + offset="0.0 0.0 -0.002" /> + + <bone + name="mFaceEyebrowOuterLeft" + scale="0 0 0 " + offset="0.0 0.0 0.0" /> + + <bone + name="mFaceEyebrowCenterLeft" + scale="0 0 0 " + offset="0.0 0.001 0.0035" /> + + <bone + name="mFaceEyebrowInnerLeft" + scale="0 0 0 " + offset="0.0 0.0 -0.002" /> + + </param_skeleton> + </param> + + </skeleton> + + <mesh + type="hairMesh" + lod="0" + file_name="avatar_hair.llm" + min_pixel_width="320"> + <!-- begin morph targets --> + <param + id="180" + group="1" + name="Hair_Volume" + label="Hair Volume" + show_simple="true" + wearable="hair" + clothing_morph="true" + edit_group="hair_style" + label_min="Less" + label_max="More" + value_min="0" + value_max="1.3" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="759" - group="0" - name="Low_Septum_Nose" - label="Nostril Division" - wearable="shape" - edit_group="shape_nose" - edit_group_order="3.5" - label_min="High" - label_max="Low" - value_min="-1" - value_max="1.5" - value_default="0.5" + id="761" + group="1" + name="Hair_Volume_Small" + label="Hair Volume" + show_simple="true" + wearable="hair" + edit_group="hair_style" + label_min="Less" + label_max="More" + value_min="0" + value_max="1.3" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="517" + id="181" group="0" - name="Wide_Nose" - label="Nose Width" - wearable="shape" - edit_group="shape_nose" - edit_group_order="2" - label_min="Narrow" - label_max="Wide" - show_simple="true" - value_min="-.5" + name="Hair_Big_Front" + label="Big Hair Front" + wearable="hair" + edit_group="hair_style" + edit_group_order="5" + label_min="Less" + label_max="More" + value_min="-1" value_max="1" + value_default="0.14" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="90"> <param_morph /> </param> <param - id="5" + id="182" group="0" - name="Cleft_Chin" - label="Chin Cleft" - wearable="shape" - edit_group="shape_chin" + name="Hair_Big_Top" + label="Big Hair Top" + wearable="hair" + edit_group="hair_style" edit_group_order="6" - label_min="Round" - label_max="Cleft" - value_min="-.1" + label_min="Less" + label_max="More" + value_min="-1" value_max="1" - camera_elevation="0" - camera_distance=".28" - camera_angle="-20"> + value_default=".7" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> <param_morph /> </param> <param - id="6" + id="183" group="0" - name="Bulbous_Nose_Tip" - label="Nose Tip Shape" - wearable="shape" - edit_group="shape_nose" - edit_group_order="8" - label_min="Pointy" - label_max="Bulbous" - value_min="-.3" + name="Hair_Big_Back" + clothing_morph="true" + label="Big Hair Back" + wearable="hair" + edit_group="hair_style" + edit_group_order="7" + label_min="Less" + label_max="More" + value_min="-1" value_max="1" + value_default="0.05" camera_elevation=".1" - camera_distance=".35" - camera_angle="15"> + camera_distance=".7" + camera_angle="90"> <param_morph /> </param> <param - id="7" + id="184" group="0" - name="Weak_Chin" - label="Chin Angle" - wearable="shape" - edit_group="shape_chin" - edit_group_order="1" - label_min="Chin Out" - label_max="Chin In" - value_min="-.5" - value_max=".5" + name="Hair_Spiked" + label="Spiked Hair" + show_simple="true" + wearable="hair" + clothing_morph="true" + edit_group="hair_style" + edit_group_order="15" + label_min="No Spikes" + label_max="Big Spikes" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".4" - camera_angle="45"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="8" + id="140" group="0" - name="Double_Chin" - label="Chin-Neck" - wearable="shape" - edit_group="shape_chin" - edit_group_order="8" - label_min="Tight Chin" - label_max="Double Chin" - value_min="-.5" - value_max="1.5" - camera_elevation="-.1" - camera_distance=".3" - camera_angle="60"> + name="Hair_Part_Middle" + label="Middle Part" + wearable="hair" + edit_group="hair_style" + edit_group_order="17" + label_min="No Part" + label_max="Part" + value_min="0" + value_max="2" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> <param_morph /> </param> <param - id="10" + id="141" group="0" - name="Sunken_Cheeks" - label="Lower Cheeks" - wearable="shape" - edit_group="shape_head" - edit_group_order="9" - label_min="Well-Fed" - label_max="Sunken" - show_simple="true" - value_min="-1.5" - value_max="3" + name="Hair_Part_Right" + label="Right Part" + wearable="hair" + edit_group="hair_style" + edit_group_order="18" + label_min="No Part" + label_max="Part" + value_min="0" + value_max="2" camera_elevation=".1" - camera_distance=".4" - camera_angle="5"> + camera_distance=".5" + camera_angle="0"> <param_morph /> </param> <param - id="11" + id="142" group="0" - name="Noble_Nose_Bridge" - label="Upper Bridge" - wearable="shape" - edit_group="shape_nose" - edit_group_order="5" - label_min="Low" - label_max="High" - value_min="-.5" - value_max="1.5" + name="Hair_Part_Left" + label="Left Part" + wearable="hair" + edit_group="hair_style" + edit_group_order="19" + label_min="No Part" + label_max="Part" + value_min="0" + value_max="2" camera_elevation=".1" - camera_distance=".35" - camera_angle="70"> + camera_distance=".5" + camera_angle="0"> <param_morph /> </param> <param - id="758" + id="143" group="0" - name="Lower_Bridge_Nose" - label="Lower Bridge" - wearable="shape" - edit_group="shape_nose" - edit_group_order="5.5" - label_min="Low" - label_max="High" - value_min="-1.5" + name="Hair_Sides_Full" + label="Full Hair Sides" + show_simple="true" + wearable="hair" + edit_group="hair_style" + edit_group_order="11" + label_min="Mowhawk" + label_max="Full Sides" + value_min="-4" value_max="1.5" + value_default="0.125" camera_elevation=".1" - camera_distance=".35" - camera_angle="70"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="12" - group="0" - name="Jowls" - wearable="shape" - edit_group="shape_chin" - edit_group_order="5" - label_min="Less" - label_max="More" - value_min="-.5" - value_max="2.5" + id="144" + group="1" + name="Bangs_Front_Up" + label="Front Bangs Up" + wearable="hair" + edit_group="hair_style" + label_min="Bangs" + label_max="Bangs Up" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".4" - camera_angle="0"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="13" - group="0" - name="Cleft_Chin_Upper" - label="Upper Chin Cleft" - wearable="shape" - edit_group="shape_chin" - edit_group_order="7" - label_min="Round" - label_max="Cleft" + id="145" + group="1" + clothing_morph="true" + name="Bangs_Front_Down" + label="Front Bangs Down" + wearable="hair" + edit_group="hair_style" + label_min="Bangs" + label_max="Bangs Down" value_min="0" - value_max="1.5" - camera_elevation="0" - camera_distance=".28" - camera_angle="-20"> + value_max="5" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="14" - group="0" - name="High_Cheek_Bones" - label="Cheek Bones" - wearable="shape" - edit_group="shape_head" - edit_group_order="10" - label_min="Low" - label_max="High" - value_min="-.5" + id="146" + group="1" + name="Bangs_Sides_Up" + label="Side Bangs Up" + wearable="hair" + edit_group="hair_style" + label_min="Side Bangs" + label_max="Side Bangs Up" + value_min="0" value_max="1" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="15" - group="0" - name="Ears_Out" - label="Ear Angle" - wearable="shape" - edit_group="shape_ears" - edit_group_order="2" - label_min="In" - label_max="Out" - value_min="-.5" - value_max="1.5" + id="147" + group="1" + clothing_morph="true" + name="Bangs_Sides_Down" + label="Side Bangs Down" + wearable="hair" + edit_group="hair_style" + label_min="Side Bangs" + label_max="Side Bangs Down" + value_min="0" + value_max="2" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> - <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> <param - id="870" + id="148" group="1" - name="Pointy_Eyebrows" - label="Eyebrow Points" + name="Bangs_Back_Up" + label="Back Bangs Up" wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="4" - label_min="Smooth" - label_max="Pointy" - value_min="-.5" + edit_group="hair_style" + label_min="Back Bangs" + label_max="Back Bangs Up" + value_min="0" value_max="1" camera_elevation=".1" - camera_distance=".3"> - <param_morph /> - </param> - - <param - id="17" - group="0" - name="Square_Jaw" - label="Jaw Shape" - wearable="shape" - edit_group="shape_chin" - edit_group_order="2" - label_min="Pointy" - label_max="Square" - value_min="-.5" - value_max="1" - camera_distance=".3" - camera_elevation=".04" - camera_angle="-20"> + camera_distance=".5" + camera_angle="150"> <param_morph /> </param> <param - id="18" - group="0" - name="Puffy_Upper_Cheeks" - label="Upper Cheeks" - wearable="shape" - edit_group="shape_head" - edit_group_order="8" - label_min="Thin" - label_max="Puffy" - value_min="-1.5" - value_max="2.5" + id="149" + group="1" + name="Bangs_Back_Down" + label="Back Bangs Down" + clothing_morph="true" + wearable="hair" + edit_group="hair_style" + label_min="Back Bangs" + label_max="Back Bangs Down" + value_min="0" + value_max="2" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="150"> <param_morph /> </param> <param - id="19" - group="0" - name="Upturned_Nose_Tip" - label="Nose Tip Angle" - wearable="shape" - edit_group="shape_nose" - edit_group_order="7" - label_min="Downturned" - label_max="Upturned" - value_min="-1.5" + id="171" + group="1" + name="Hair_Front_Down" + label="Front Hair Down" + wearable="hair" + edit_group="hair_style" + label_min="Front Hair" + label_max="Front Hair Down" + value_min="0" value_max="1" camera_elevation=".1" - camera_distance=".35" - camera_angle="15"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="20" - group="0" - name="Bulbous_Nose" - label="Nose Thickness" - wearable="shape" - edit_group="shape_nose" - edit_group_order="4" - label_min="Thin Nose" - label_max="Bulbous Nose" - show_simple="true" - value_min="-.5" - value_max="1.5" + id="172" + group="1" + name="Hair_Front_Up" + label="Front Hair Up" + wearable="hair" + edit_group="hair_style" + label_min="Front Hair" + label_max="Front Hair Up" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".3"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="21" - group="0" - name="Upper_Eyelid_Fold" - label="Upper Eyelid Fold" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="5" - label_min="Uncreased" - label_max="Creased" - value_min="-0.2" - value_max="1.3" + id="173" + group="1" + name="Hair_Sides_Down" + label="Sides Hair Down" + wearable="hair" + edit_group="hair_style" + label_min="Sides Hair" + label_max="Sides Hair Down" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".35"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="22" - group="0" - name="Attached_Earlobes" - label="Attached Earlobes" - wearable="shape" - edit_group="shape_ears" - edit_group_order="3" - label_min="Unattached" - label_max="Attached" + id="174" + group="1" + name="Hair_Sides_Up" + label="Sides Hair Up" + wearable="hair" + edit_group="hair_style" + label_min="Sides Hair" + label_max="Sides Hair Up" value_min="0" value_max="1" camera_elevation=".1" - camera_distance=".3" - camera_angle="45"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="23" - group="0" - name="Baggy_Eyes" - label="Eye Bags" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="6" - label_min="Smooth" - label_max="Baggy" - value_min="-.5" - value_max="1.5" + id="175" + group="1" + name="Hair_Back_Down" + label="Back Hair Down" + clothing_morph="true" + wearable="hair" + edit_group="hair_style" + label_min="Back Hair" + label_max="Back Hair Down" + value_min="0" + value_max="3" camera_elevation=".1" - camera_distance=".35"> + camera_distance=".5" + camera_angle="150"> <param_morph /> </param> <param - id="765" - group="0" - name="Puffy_Lower_Lids" - label="Puffy Eyelids" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="6.1" - label_min="Flat" - label_max="Puffy" - value_min="-.3" - value_max="2.5" + id="176" + group="1" + name="Hair_Back_Up" + label="Back Hair Up" + wearable="hair" + edit_group="hair_style" + label_min="Back Hair" + label_max="Back Hair Up" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".35"> + camera_distance=".5" + camera_angle="150"> <param_morph /> </param> <param - id="24" + id="177" group="0" - name="Wide_Eyes" - label="Eye Opening" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="1.1" - label_min="Narrow" - label_max="Wide" - value_min="-1.5" - value_max="2" + name="Hair_Rumpled" + label="Rumpled Hair" show_simple="true" + wearable="hair" + clothing_morph="true" + edit_group="hair_style" + edit_group_order="14.5" + label_min="Smooth Hair" + label_max="Rumpled Hair" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".35"> + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="25" - group="0" - name="Wide_Lip_Cleft" - label="Lip Cleft" - wearable="shape" - edit_group="shape_mouth" - edit_group_order="6" - label_min="Narrow" - label_max="Wide" - value_min="-.8" - value_max="1.5" - camera_elevation="0" - camera_distance=".28"> + id="178" + group="1" + name="Hair_Swept_Back" + label="Swept Back Hair" + wearable="hair" + edit_group="hair_style" + label_min="NotHair" + label_max="Swept Back" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> <param_morph /> </param> <param - id="764" - group="0" - name="Lip_Cleft_Deep" - label="Lip Cleft Depth" - wearable="shape" - edit_group="shape_mouth" - edit_group_order="5.8" - label_min="Shallow" - label_max="Deep" - value_min="-.5" - value_max="1.2" - camera_elevation="0" - camera_distance=".28"> + id="179" + group="1" + name="Hair_Swept_Forward" + label="Swept Forward Hair" + wearable="hair" + edit_group="hair_style" + label_min="Hair" + label_max="Swept Forward" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> <param_morph /> </param> <param - id="26" + id="190" group="1" - wearable="shape" - name="Lips_Thin" - edit_group="driven" + name="Hair_Tilt_Right" + label="Hair Tilted Right" + wearable="hair" + edit_group="hair_style" + label_min="Hair" + label_max="Tilt Right" value_min="0" - value_max=".7"> + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> <param_morph /> </param> <param - id="27" + id="191" + group="1" + name="Hair_Tilt_Left" + label="Hair Tilted Left" + wearable="hair" + edit_group="hair_style" + label_min="Hair" + label_max="Tilt Left" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> + <param_morph /> + </param> + + <param + id="192" group="0" - name="Wide_Nose_Bridge" - label="Bridge Width" - wearable="shape" - edit_group="shape_nose" - edit_group_order="6" - label_min="Narrow" - label_max="Wide" - value_min="-1.3" - value_max="1.2" + name="Bangs_Part_Middle" + label="Part Bangs" + wearable="hair" + edit_group="hair_style" + edit_group_order="20" + label_min="No Part" + label_max="Part Bangs" + value_min="0" + value_max="1" camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> + camera_distance=".5" + camera_angle="0"> <param_morph /> </param> <param - id="28" + id="640" group="1" - name="Lips_Fat" - wearable="shape" - edit_group="driven" + name="Hair_Egg_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="-1.3" + value_max="1"> + <param_morph /> + </param> + + <param + id="641" + group="1" + name="Hair_Squash_Stretch_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="-.5" + value_max="1"> + <param_morph /> + </param> + + <param + id="642" + group="1" + name="Hair_Square_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" value_min="0" - value_max="2"> + value_max="1"> <param_morph /> </param> <param - id="29" + id="643" group="1" - name="Wide_Upper_Lip" - wearable="shape" - edit_group="driven" - value_min="-.7" - value_max="1.3"> + name="Hair_Round_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="0" + value_max="1"> <param_morph /> </param> <param - id="30" + id="644" group="1" - name="Wide_Lower_Lip" - wearable="shape" - edit_group="driven" - value_min="-.7" - value_max="1.3"> + name="Hair_Forehead_Round" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="0" + value_max="1"> <param_morph /> </param> - <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> <param - id="872" + id="645" group="1" - name="Arced_Eyebrows" - label="Eyebrow Arc" + name="Hair_Forehead_Slant" wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="3" - label_min="Flat" - label_max="Arced" + edit_group="hair_style" + cross_wearable="true" value_min="0" value_max="1"> <param_morph /> </param> - <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1--> <param - id="871" + id="774" group="1" - name="Lower_Eyebrows" - label="Eyebrow Height" - show_simple="true" + name="Shear_Head_Hair" wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="2.5" - label_min="Higher" - label_max="Lower" + edit_group="hair_style" + cross_wearable="true" value_min="-2" value_max="2"> <param_morph /> </param> <param - id="35" - group="0" - name="Big_Ears" - label="Ear Size" - wearable="shape" - edit_group="shape_ears" - edit_group_order="1" - label_min="Small" - label_max="Large" + id="771" + group="1" + name="Elongate_Head_Hair" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" value_min="-1" - value_max="2" - camera_elevation=".1" - camera_distance=".3" - camera_angle="45"> + value_max="1"> <param_morph /> </param> <param - id="796" + id="674" group="0" - name="Pointy_Ears" - label="Ear Tips" - wearable="shape" - edit_group="shape_ears" - edit_group_order="4" - label_min="Flat" - label_max="Pointy" - value_min="-.4" - value_max="3" + name="Hair_Shear_Back" + wearable="hair" + edit_group="hair_style" + edit_group_order="12" + label="Shear Back" + label_min="Full Back" + label_max="Sheared Back" + value_min="-1" + value_max="2" + value_default="-0.3" camera_elevation=".1" - camera_distance=".3" - camera_angle="45"> + camera_distance=".5" + camera_angle="100"> <param_morph /> </param> <param - id="185" + id="762" group="0" - name="Deep_Chin" - label="Chin Depth" - wearable="shape" - edit_group="shape_chin" - edit_group_order="3" - label_min="Shallow" - label_max="Deep" - value_min="-1" - value_max="1" + name="Hair_Shear_Front" + wearable="hair" + edit_group="hair_style" + edit_group_order="11.8" + label="Shear Front" + show_simple="true" + label_min="Full Front" + label_max="Sheared Front" + value_min="0" + value_max="3" camera_elevation=".1" - camera_distance=".4" + camera_distance=".5" camera_angle="30"> <param_morph /> </param> <param - id="186" - group="1" - name="Egg_Head" - label="Egg Head" - wearable="shape" - edit_group="shape_head" - label_min="Chin Heavy" - label_max="Forehead Heavy" - value_min="-1.3" - value_max="1" + id="754" + group="0" + name="Hair_Taper_Back" + wearable="hair" + edit_group="hair_style" + edit_group_order="14" + label="Taper Back" + label_min="Wide Back" + label_max="Narrow Back" + value_min="-1" + value_max="2" + value_default="0" camera_elevation=".1" camera_distance=".5" - camera_angle="20"> + camera_angle="160"> <param_morph /> </param> <param - id="187" - group="1" - name="Squash_Stretch_Head" - label="Squash/Stretch Head" - wearable="shape" - edit_group="shape_head" - label_min="Squash Head" - label_max="Stretch Head" - value_min="-.5" - value_max="1" + id="755" + group="0" + name="Hair_Taper_Front" + wearable="hair" + edit_group="hair_style" + edit_group_order="13" + label="Taper Front" + label_min="Wide Front" + label_max="Narrow Front" + value_min="-1.5" + value_max="1.5" + value_default="0.05" camera_elevation=".1" camera_distance=".5" camera_angle="20"> - <param_morph> - <volume_morph - name="HEAD" - scale="-0.008 -0.006 0.015"/> - </param_morph> + <param_morph /> </param> <param - id="188" + id="782" group="1" - name="Square_Head" - wearable="shape" - label_min="Less Square" - label_max="More Square" + clothing_morph="true" + name="Hair_Pigtails_Short" + wearable="hair" + edit_group="hair_style" value_min="0" - value_max=".7" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> + value_max="1"> <param_morph /> </param> <param - id="189" + id="783" group="1" - wearable="shape" - name="Round_Head" - label_min="Less Round" - label_max="More Round" + clothing_morph="true" + name="Hair_Pigtails_Med" + wearable="hair" + edit_group="hair_style" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> + value_max="1"> <param_morph /> </param> <param - id="194" + id="790" group="1" - name="Eye_Spread" - wearable="shape" - edit_group="shape_eyes" - label_min="Eyes Together" - label_max="Eyes Spread" - value_min="-2" - value_max="2"> + clothing_morph="true" + name="Hair_Pigtails_Medlong" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> <param_morph /> </param> <param - id="400" - sex="male" + id="784" group="1" - name="Displace_Hair_Facial" - label="Hair Thickess" + clothing_morph="true" + name="Hair_Pigtails_Long" wearable="hair" - edit_group="hair_facial" - label_min="Cropped Hair" - label_max="Bushy Hair" + edit_group="hair_style" value_min="0" - value_max="2"> + value_max="1"> <param_morph /> </param> <param - id="506" - group="0" - name="Mouth_Height" - wearable="shape" - label="Mouth Position" - show_simple="true" - edit_group="shape_mouth" - edit_group_order="4" - label_min="High" - label_max="Low" - value_min="-2" - value_max="2" - camera_distance=".3" - camera_elevation=".04"> + id="786" + group="1" + name="Hair_Ponytail_Short" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> <param_morph /> </param> <param - id="633" + id="787" group="1" - name="Fat_Head" - label="Fat Head" - wearable="shape" - edit_group="shape_body" - label_min="Skinny" - label_max="Fat" + name="Hair_Ponytail_Med" + wearable="hair" + edit_group="hair_style" value_min="0" - value_max="1" - camera_elevation=".3"> - <param_morph/> + value_max="1"> + <param_morph /> </param> <param - id="630" + id="788" group="1" - name="Forehead_Round" - label="Round Forehead" - wearable="shape" - label_min="Less" - label_max="More" + name="Hair_Ponytail_Long" + clothing_morph="true" + wearable="hair" + edit_group="hair_style" value_min="0" value_max="1"> <param_morph /> </param> + <!-- #end morph targets --> + </mesh> + + <mesh + type="hairMesh" + lod="1" + file_name="avatar_hair_1.llm" + min_pixel_width="160" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="2" + file_name="avatar_hair_2.llm" + min_pixel_width="80" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="3" + file_name="avatar_hair_3.llm" + min_pixel_width="40" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="4" + file_name="avatar_hair_4.llm" + min_pixel_width="20" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="5" + file_name="avatar_hair_5.llm" + min_pixel_width="0" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="headMesh" + lod="0" + file_name="avatar_head.llm" + min_pixel_width="320"> + <!-- + begin morph targets + ############# + tweakable morphs + ############# + --> <param - id="631" + id="20001" group="1" - name="Forehead_Slant" - label="Slanted Forehead" - wearable="shape" - label_min="Less" - label_max="More" - value_min="0" - value_max="1"> + name="Big_Brow" + value_min="-.3" + value_max="2"> <param_morph /> </param> <param - id="650" - group="0" - name="Eyelid_Corner_Up" - label="Outer Eye Corner" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="4" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".30"> + id="20002" + group="1" + name="Nose_Big_Out" + value_min="-0.8" + value_max="2.5"> <param_morph /> </param> <param - id="880" - group="0" - name="Eyelid_Inner_Corner_Up" - label="Inner Eye Corner" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="4.2" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".30"> + id="20517" + group="1" + name="Wide_Nose" + value_min="-.5" + value_max="1"> <param_morph /> </param> - <param - id="653" - group="0" - name="Tall_Lips" - wearable="shape" - label="Lip Fullness" - show_simple="true" - edit_group="shape_mouth" - edit_group_order="2" - label_min="Less Full" - label_max="More Full" - value_min="-1" - value_max="2" - camera_distance=".3" - camera_elevation=".04"> + id="20020" + group="1" + name="Bulbous_Nose" + value_min="-.5" + value_max="1.5"> <param_morph /> </param> - + <param - id="656" - group="0" + id="20656" + group="1" name="Crooked_Nose" - wearable="shape" - label="Crooked Nose" - edit_group="shape_nose" - edit_group_order="9" - label_min="Nose Left" - label_max="Nose Right" value_min="-2" - value_max="2" - camera_distance=".3" - camera_elevation=".04" - camera_angle="-20"> + value_max="2"> <param_morph /> </param> - + <param - id="657" + id="20004" group="1" - name="Smile_Mouth" - wearable="shape" - label="Mouth Corner" - edit_group="shape_mouth" - label_min="Corner Normal" - label_max="Corner Up" - value_min="0" - value_max="1.4" - camera_distance=".3" - camera_elevation=".04"> + name="Broad_Nostrils" + value_min="-.5" + value_max="1"> <param_morph /> </param> <param - id="658" + id="20653" group="1" - name="Frown_Mouth" - wearable="shape" - label="Mouth Corner" - edit_group="shape_mouth" - label_min="Corner Normal" - label_max="Corner Down" - value_min="0" - value_max="1.2" - camera_distance=".3" - camera_elevation=".04"> + name="Tall_Lips" + value_min="-1" + value_max="2"> <param_morph /> </param> - + <param - id="797" + id="20506" group="1" - name="Fat_Upper_Lip" - wearable="shape" - label="Fat Upper Lip" - edit_group="shape_mouth" - label_min="Normal Upper" - label_max="Fat Upper" - value_min="0" - value_max="1.5" - camera_distance=".3" - camera_elevation=".04"> + name="Mouth_Height" + value_min="-2" + value_max="2"> <param_morph /> </param> + + <param + id="20764" + group="1" + name="Lip_Cleft_Deep" + value_min="-.5" + value_max="1.2"> + <param_morph/> + </param> <param - id="798" + id="20025" group="1" - name="Fat_Lower_Lip" - wearable="shape" - label="Fat Lower Lip" - edit_group="shape_mouth" - label_min="Normal Lower" - label_max="Fat Lower" - value_min="0" - value_max="1.5" - camera_distance=".3" - camera_elevation=".04"> - <param_morph /> + name="Wide_Lip_Cleft" + value_min="-.8" + value_max="1.5"> + <param_morph/> </param> - + <param - id="660" + id="20663" group="1" - name="Shear_Head" - wearable="shape" - label="Shear Face" - edit_group="shape_head" - label_min="Shear Left" - label_max="Shear Right" + name="Shift_Mouth" value_min="-2" value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04"> + value_default="0"> <param_morph /> </param> - + <param - id="770" + id="20035" group="1" - name="Elongate_Head" - wearable="shape" - label="Shear Face" - edit_group="shape_head" - label_min="Flat Head" - label_max="Long Head" + name="Big_Ears" value_min="-1" - value_max="1" - value_default="0" - camera_distance=".5" - camera_elevation=".04"> - <param_morph> - <volume_morph - name="HEAD" - scale="0.02 0.0 0.0"/> - </param_morph> + value_max="2"> + <param_morph/> </param> - + <param - id="663" - group="0" - name="Shift_Mouth" - wearable="shape" - label="Shift Mouth" - edit_group="shape_mouth" - edit_group_order="7" - label_min="Shift Left" - label_max="Shift Right" - value_min="-2" - value_max="2" - value_default="0" - camera_distance=".35" - camera_elevation=".04" - camera_angle="-20"> - <param_morph /> + id="20015" + group="1" + name="Ears_Out" + value_min="-.5" + value_max="1.5"> + <param_morph/> </param> - + <param - id="664" - group="0" - name="Pop_Eye" - wearable="shape" - label="Eye Pop" - edit_group="shape_eyes" - edit_group_order="8" - label_min="Pop Right Eye" - label_max="Pop Left Eye" - value_min="-1.3" - value_max="1.3" - value_default="0" - camera_elevation=".1" - camera_distance=".35"> + id="20796" + group="1" + name="Pointy_Ears" + value_min="-.4" + value_max="3"> <param_morph /> </param> - + <param - id="760" - group="0" - name="Jaw_Angle" - wearable="shape" - label="Jaw Angle" - edit_group="shape_chin" - edit_group_order="3.5" - label_min="Low Jaw" - label_max="High Jaw" - value_min="-1.2" - value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04" - camera_angle="70"> + id="20185" + group="1" + name="Deep_Chin" + value_min="-1" + value_max="1"> <param_morph /> </param> - + <param - id="665" - group="0" + id="20665" + group="1" name="Jaw_Jut" - wearable="shape" - label="Jaw Jut" - edit_group="shape_chin" - edit_group_order="4" - label_min="Overbite" - label_max="Underbite" value_min="-2" - value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04" - camera_angle="70"> + value_max="2"> <param_morph /> </param> - + <param - id="686" + id="20024" group="1" - name="Head_Eyes_Big" - wearable="shape" - label="Eye Size" - edit_group="shape_eyes" - label_min="Beady Eyes" - label_max="Anime Eyes" - show_simple="true" - value_min="-2" - value_max="2" - value_default="0"> + name="Wide_Eyes" + value_min="-1.5" + value_max="2"> <param_morph /> </param> - + <param - id="767" + id="20650" group="1" - name="Bug_Eyed_Head" - wearable="shape" - label="Eye Depth" - edit_group="shape_eyes" - edit_group_order="4.5" - label_min="Sunken Eyes" - label_max="Bug Eyes" - value_min="-2" - value_max="2" - value_default="0"> + name="Eyelid_Corner_Up" + value_min="-1.3" + value_max="1.2"> <param_morph /> </param> - - <!-- - #Fat_Lips = Fat_Lips 34 1 0 1 - #Wide_Lips = Wide_Lips 35 1 0 1 - #Wide_Nose = Wide_Nose 36 1 0 1 - --> - <!-- - ############## - # Facial Expression morphs - ############## - --> + <param - id="300" + id="20765" group="1" - name="Express_Closed_Mouth" - value_default="1" - value_min="0" - value_max="1"> + name="Puffy_Lower_Lids" + value_min="-.3" + value_max="2.5"> <param_morph /> </param> <param - id="301" + id="20759" group="1" - name="Express_Tongue_Out" - value_min="0" - value_max="1"> + name="Low_Septum_Nose" + value_min="-1" + value_max="1.5" + value_default="0.5"> <param_morph /> </param> <param - id="302" - group="1" - name="Express_Surprise_Emote" - value_min="0" - value_max="1"> + id="5" + group="0" + name="Cleft_Chin" + label="Chin Cleft" + wearable="shape" + edit_group="shape_chin" + edit_group_order="6" + label_min="Round" + label_max="Cleft" + value_min="-.1" + value_max="1" + camera_elevation="0" + camera_distance=".28" + camera_angle="-20"> <param_morph /> </param> <param - id="303" + id="20006" group="1" - name="Express_Wink_Emote" - value_min="0" - value_max="1"> - <param_morph /> - </param> - - <param - id="304" - group="1" - name="Express_Embarrassed_Emote" - value_min="0" + name="Bulbous_Nose_Tip" + value_min="-.3" value_max="1"> <param_morph /> </param> <param - id="305" + id="20007" group="1" - name="Express_Shrug_Emote" - value_min="0" - value_max="1"> + name="Weak_Chin" + value_min="-.5" + value_max=".5"> <param_morph /> </param> <param - id="306" + id="20008" group="1" - name="Express_Kiss" - value_min="0" - value_max="1"> + name="Double_Chin" + value_min="-.5" + value_max="1.5"> <param_morph /> </param> <param - id="307" + id="20010" group="1" - name="Express_Bored_Emote" - value_min="0" - value_max="1"> + name="Sunken_Cheeks" + value_min="-1.5" + value_max="3"> <param_morph /> </param> <param - id="308" + id="20011" group="1" - name="Express_Repulsed_Emote" - value_min="0" - value_max="1"> + name="Noble_Nose_Bridge" + value_min="-.5" + value_max="1.5"> <param_morph /> </param> <param - id="309" + id="20758" group="1" - name="Express_Disdain" - value_min="0" - value_max="1"> + name="Lower_Bridge_Nose" + value_min="-1.5" + value_max="1.5"> <param_morph /> </param> <param - id="310" - group="1" - name="Express_Afraid_Emote" - value_min="0" - value_max="1"> + id="12" + group="0" + name="Jowls" + wearable="shape" + edit_group="shape_chin" + edit_group_order="5" + label_min="Less" + label_max="More" + value_min="-.5" + value_max="2.5" + camera_elevation=".1" + camera_distance=".4" + camera_angle="0"> <param_morph /> </param> <param - id="311" - group="1" - name="Express_Worry_Emote" + id="13" + group="0" + name="Cleft_Chin_Upper" + label="Upper Chin Cleft" + wearable="shape" + edit_group="shape_chin" + edit_group_order="7" + label_min="Round" + label_max="Cleft" value_min="0" - value_max="1"> + value_max="1.5" + camera_elevation="0" + camera_distance=".28" + camera_angle="-20"> <param_morph /> </param> <param - id="312" + id="20014" group="1" - name="Express_Cry_Emote" - value_min="0" + name="High_Cheek_Bones" + value_min="-.5" value_max="1"> <param_morph /> </param> + <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> <param - id="313" + id="870" group="1" - name="Express_Sad_Emote" - value_min="0" - value_max="1"> + name="Pointy_Eyebrows" + label="Eyebrow Points" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="4" + label_min="Smooth" + label_max="Pointy" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3"> <param_morph /> </param> <param - id="314" + id="20017" group="1" - name="Express_Anger_Emote" - value_min="0" + name="Square_Jaw" + value_min="-.5" value_max="1"> <param_morph /> </param> <param - id="315" + id="20018" group="1" - name="Express_Frown" - value_min="0" - value_max="1"> + name="Puffy_Upper_Cheeks" + value_min="-1.5" + value_max="2.5"> <param_morph /> </param> <param - id="316" + id="20019" group="1" - name="Express_Laugh_Emote" - value_min="0" + name="Upturned_Nose_Tip" + value_min="-1.5" value_max="1"> <param_morph /> </param> - + <param - id="317" + id="20021" group="1" - name="Express_Toothsmile" - value_min="0" - value_max="1"> + name="Upper_Eyelid_Fold" + value_min="-0.2" + value_max="1.3"> <param_morph /> </param> <param - id="318" - group="1" - name="Express_Smile" + id="22" + group="0" + name="Attached_Earlobes" + label="Attached Earlobes" + wearable="shape" + edit_group="shape_ears" + edit_group_order="3" + label_min="Unattached" + label_max="Attached" value_min="0" - value_max="1"> + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="45"> <param_morph /> </param> <param - id="632" + id="20023" group="1" - name="Express_Open_Mouth" - value_min="0" - value_max="1"> + name="Baggy_Eyes" + value_min="-.5" + value_max="1.5"> <param_morph /> </param> - <!-- - ############## - # Lipsync morphs - ############## - --> - <param - id="70" + id="26" group="1" - name="Lipsync_Aah" + wearable="shape" + name="Lips_Thin" + edit_group="driven" value_min="0" - value_max="1"> + value_max=".7"> <param_morph /> </param> <param - id="71" + id="20027" group="1" - name="Lipsync_Ooh" - value_min="0" - value_max="1"> + name="Wide_Nose_Bridge" + value_min="-1.3" + value_max="1.2"> <param_morph /> </param> - <!-- - ############## - # other morphs (not user controlled) - ############## - --> <param - id="40" + id="28" group="1" - name="Male_Head" + name="Lips_Fat" wearable="shape" edit_group="driven" value_min="0" - value_max="1"> + value_max="2"> <param_morph /> </param> <param - id="41" + id="29" group="1" - name="Old" - value_min="0" - value_max="1"> + name="Wide_Upper_Lip" + wearable="shape" + edit_group="driven" + value_min="-.7" + value_max="1.3"> <param_morph /> </param> - <!-- - ############## - # animatable morphs - ############## - --> <param - id="51" + id="30" group="1" - name="Furrowed_Eyebrows" - value_min="0" - value_max="1"> + name="Wide_Lower_Lip" + wearable="shape" + edit_group="driven" + value_min="-.7" + value_max="1.3"> <param_morph /> </param> + <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> <param - id="53" + id="872" group="1" - name="Surprised_Eyebrows" + name="Arced_Eyebrows" + label="Eyebrow Arc" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="3" + label_min="Flat" + label_max="Arced" value_min="0" value_max="1"> <param_morph /> </param> + <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1--> <param - id="54" + id="871" group="1" - name="Worried_Eyebrows" - value_min="0" - value_max="1"> + name="Lower_Eyebrows" + label="Eyebrow Height" + show_simple="true" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="2.5" + label_min="Higher" + label_max="Lower" + value_min="-2" + value_max="2"> <param_morph /> </param> <param - id="55" + id="186" group="1" - name="Frown_Mouth" - value_min="0" - value_max="1"> + name="Egg_Head" + label="Egg Head" + wearable="shape" + edit_group="shape_head" + label_min="Chin Heavy" + label_max="Forehead Heavy" + value_min="-1.3" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="57" + id="187" group="1" - name="Smile_Mouth" - value_min="0" - value_max="1"> - <param_morph /> - </param> + name="Squash_Stretch_Head" + label="Squash/Stretch Head" + wearable="shape" + edit_group="shape_head" + label_min="Squash Head" + label_max="Stretch Head" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph> + <volume_morph + name="HEAD" + scale="-0.008 -0.006 0.015"/> + </param_morph> + </param> <param - id="58" + id="188" group="1" - name="Blink_Left" + name="Square_Head" + wearable="shape" + label_min="Less Square" + label_max="More Square" value_min="0" - value_max="1"> + value_max=".7" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> <param_morph /> </param> <param - id="59" + id="189" group="1" - name="Blink_Right" + wearable="shape" + name="Round_Head" + label_min="Less Round" + label_max="More Round" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> + + <param + id="194" + group="1" + name="Eye_Spread" + wearable="shape" + edit_group="shape_eyes" + label_min="Eyes Together" + label_max="Eyes Spread" + value_min="-2" + value_max="2"> + <param_morph /> + </param> + + <param + id="400" + sex="male" + group="1" + name="Displace_Hair_Facial" + label="Hair Thickess" + wearable="hair" + edit_group="hair_facial" + label_min="Cropped Hair" + label_max="Bushy Hair" + value_min="0" + value_max="2"> + <param_morph /> + </param> + + <param + id="633" + group="1" + name="Fat_Head" + label="Fat Head" + wearable="shape" + edit_group="shape_body" + label_min="Skinny" + label_max="Fat" + value_min="0" + value_max="1" + camera_elevation=".3"> + <param_morph/> + </param> + + <param + id="630" + group="1" + name="Forehead_Round" + label="Round Forehead" + wearable="shape" + label_min="Less" + label_max="More" value_min="0" value_max="1"> <param_morph /> </param> - <!-- - #end morph targets - --> - </mesh> + <param + id="631" + group="1" + name="Forehead_Slant" + label="Slanted Forehead" + wearable="shape" + label_min="Less" + label_max="More" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <mesh - type="headMesh" - lod="1" - file_name="avatar_head_1.llm" - min_pixel_width="160" - reference="avatar_head.llm"> - </mesh> + <param + id="20880" + group="1" + name="Eyelid_Inner_Corner_Up" + value_min="-1.3" + value_max="1.2"> + <param_morph /> + </param> + + <param + id="657" + group="1" + name="Smile_Mouth" + wearable="shape" + label="Mouth Corner" + edit_group="shape_mouth" + label_min="Corner Normal" + label_max="Corner Up" + value_min="0" + value_max="1.4" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <mesh - type="headMesh" - lod="2" - file_name="avatar_head_2.llm" - min_pixel_width="80" - reference="avatar_head.llm"> - </mesh> + <param + id="658" + group="1" + name="Frown_Mouth" + wearable="shape" + label="Mouth Corner" + edit_group="shape_mouth" + label_min="Corner Normal" + label_max="Corner Down" + value_min="0" + value_max="1.2" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <mesh - type="headMesh" - lod="3" - file_name="avatar_head_3.llm" - min_pixel_width="40" - reference="avatar_head.llm"> - </mesh> + <param + id="797" + group="1" + name="Fat_Upper_Lip" + wearable="shape" + label="Fat Upper Lip" + edit_group="shape_mouth" + label_min="Normal Upper" + label_max="Fat Upper" + value_min="0" + value_max="1.5" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <mesh - type="headMesh" - lod="4" - file_name="avatar_head_4.llm" - min_pixel_width="0" - reference="avatar_head.llm"> - </mesh> + <param + id="798" + group="1" + name="Fat_Lower_Lip" + wearable="shape" + label="Fat Lower Lip" + edit_group="shape_mouth" + label_min="Normal Lower" + label_max="Fat Lower" + value_min="0" + value_max="1.5" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <mesh - type="eyelashMesh" - lod="0" - file_name="avatar_eyelashes.llm" - min_pixel_width="320"> <param - shared="1" id="660" group="1" name="Shear_Head" @@ -3374,7 +5958,6 @@ </param> <param - shared="1" id="770" group="1" name="Elongate_Head" @@ -3388,11 +5971,14 @@ value_default="0" camera_distance=".5" camera_elevation=".04"> - <param_morph /> + <param_morph> + <volume_morph + name="HEAD" + scale="0.02 0.0 0.0"/> + </param_morph> </param> <param - shared="1" id="664" group="0" name="Pop_Eye" @@ -3402,171 +5988,41 @@ edit_group_order="8" label_min="Pop Right Eye" label_max="Pop Left Eye" - value_min="-2" - value_max="2" + value_min="-1.3" + value_max="1.3" value_default="0" - camera_distance=".5" - camera_elevation=".04" - camera_angle="-20"> + camera_elevation=".1" + camera_distance=".35"> <param_morph /> </param> <param - shared="1" - id="21" - group="0" - name="Upper_Eyelid_Fold" - label="Upper Eyelid Fold" - wearable="shape" - edit_group="shape_eyes" - label_min="Uncreased" - label_max="Creased" - value_min="-0.2" - value_max="1.3" - camera_elevation=".1" - camera_distance=".35"> + id="20760" + group="1" + name="Jaw_Angle" + value_min="-1.2" + value_max="2" + value_default="0"> <param_morph /> </param> <param - shared="1" - id="24" - group="0" - name="Wide_Eyes" - label="Eye Opening" + id="686" + group="1" + name="Head_Eyes_Big" wearable="shape" - edit_group="shape_eyes" - label_min="Narrow" - label_max="Wide" - show_simple="true" - value_min="-1.5" - value_max="2" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> - </param> - - <param - shared="1" - id="186" - group="1" - name="Egg_Head" - label="Egg Head" - wearable="shape" - edit_group="shape_head" - label_min="Chin Heavy" - label_max="Forehead Heavy" - value_min="-1.3" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> - - <param - shared="1" - id="187" - group="1" - name="Squash_Stretch_Head" - label="Squash/Stretch Head" - wearable="shape" - edit_group="shape_head" - label_min="Squash Head" - label_max="Stretch Head" - value_min="-.5" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> - - <param - shared="1" - id="194" - group="1" - name="Eye_Spread" - edit_group="shape_eyes" - label_min="Eyes Together" - label_max="Eyes Spread" - value_min="-2" - value_max="2"> - <param_morph /> - </param> - - <param - id="518" - group="0" - name="Eyelashes_Long" - wearable="shape" - label="Eyelash Length" - edit_group="shape_eyes" - edit_group_order="7" - label_min="Short" - label_max="Long" - value_min="-.3" - value_max="1.5" - camera_elevation=".1" - camera_distance=".30" - camera_angle="-20"> - <param_morph /> - </param> - - <param - shared="1" - id="650" - group="0" - name="Eyelid_Corner_Up" - label="Outer Eye Corner" - wearable="shape" - edit_group="shape_eyes" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> - </param> - - - <param - shared="1" - id="880" - group="0" - name="Eyelid_Inner_Corner_Up" - label="Inner Eye Corner" - wearable="shape" - edit_group="shape_eyes" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> - </param> - - <param - shared="1" - id="686" - group="1" - name="Head_Eyes_Big" - wearable="shape" - label="Eye Size" + label="Eye Size" edit_group="shape_eyes" label_min="Beady Eyes" label_max="Anime Eyes" + show_simple="true" value_min="-2" value_max="2" - show_simple="true" value_default="0"> <param_morph /> </param> <param - shared="1" id="767" group="1" name="Bug_Eyed_Head" @@ -3582,13 +6038,27 @@ <param_morph /> </param> + <!-- + #Fat_Lips = Fat_Lips 34 1 0 1 + #Wide_Lips = Wide_Lips 35 1 0 1 + #Wide_Nose = Wide_Nose 36 1 0 1 + --> <!-- ############## # Facial Expression morphs ############## --> <param - shared="1" + id="300" + group="1" + name="Express_Closed_Mouth" + value_default="1" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param id="301" group="1" name="Express_Tongue_Out" @@ -3598,7 +6068,6 @@ </param> <param - shared="1" id="302" group="1" name="Express_Surprise_Emote" @@ -3608,7 +6077,6 @@ </param> <param - shared="1" id="303" group="1" name="Express_Wink_Emote" @@ -3618,7 +6086,6 @@ </param> <param - shared="1" id="304" group="1" name="Express_Embarrassed_Emote" @@ -3628,7 +6095,6 @@ </param> <param - shared="1" id="305" group="1" name="Express_Shrug_Emote" @@ -3638,7 +6104,6 @@ </param> <param - shared="1" id="306" group="1" name="Express_Kiss" @@ -3648,7 +6113,6 @@ </param> <param - shared="1" id="307" group="1" name="Express_Bored_Emote" @@ -3658,7 +6122,6 @@ </param> <param - shared="1" id="308" group="1" name="Express_Repulsed_Emote" @@ -3668,7 +6131,6 @@ </param> <param - shared="1" id="309" group="1" name="Express_Disdain" @@ -3678,7 +6140,6 @@ </param> <param - shared="1" id="310" group="1" name="Express_Afraid_Emote" @@ -3688,7 +6149,15 @@ </param> <param - shared="1" + id="311" + group="1" + name="Express_Worry_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param id="312" group="1" name="Express_Cry_Emote" @@ -3698,7 +6167,6 @@ </param> <param - shared="1" id="313" group="1" name="Express_Sad_Emote" @@ -3708,7 +6176,6 @@ </param> <param - shared="1" id="314" group="1" name="Express_Anger_Emote" @@ -3718,7 +6185,6 @@ </param> <param - shared="1" id="315" group="1" name="Express_Frown" @@ -3728,7 +6194,6 @@ </param> <param - shared="1" id="316" group="1" name="Express_Laugh_Emote" @@ -3738,7 +6203,6 @@ </param> <param - shared="1" id="317" group="1" name="Express_Toothsmile" @@ -3748,7 +6212,6 @@ </param> <param - shared="1" id="318" group="1" name="Express_Smile" @@ -3757,16 +6220,10 @@ <param_morph /> </param> - <!-- - ############## - # other morphs (not user controlled) - ############## - --> <param - shared="1" - id="41" + id="632" group="1" - name="Old" + name="Express_Open_Mouth" value_min="0" value_max="1"> <param_morph /> @@ -3774,835 +6231,584 @@ <!-- ############## - # animatable morphs + # Lipsync morphs ############## - --> + --> + <param - shared="1" - id="58" + id="70" group="1" - name="Blink_Left" + name="Lipsync_Aah" value_min="0" value_max="1"> <param_morph /> </param> <param - shared="1" - id="59" + id="71" group="1" - name="Blink_Right" + name="Lipsync_Ooh" value_min="0" value_max="1"> <param_morph /> </param> - </mesh> - <!-- - #headMesh2 = - #headMesh3 = - --> - <mesh - type="upperBodyMesh" - lod="0" - file_name="avatar_upper_body.llm" - min_pixel_width="320"> <!-- - #begin morph targets - ############# - # tweakable morphs - ############# + ############## + # other morphs (not user controlled) + ############## --> <param - id="104" + id="40" group="1" - name="Big_Belly_Torso" + name="Male_Head" wearable="shape" edit_group="driven" value_min="0" value_max="1"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.075 0.04 0.03" - pos="0.07 0 -0.07"/> - <volume_morph - name="PELVIS" - scale="0.075 0.04 0.03" - pos="0.07 0 -0.02"/> - </param_morph> + <param_morph /> </param> <param - id="626" - sex="female" + id="41" group="1" - name="Big_Chest" - label="Chest Size" - wearable="shape" - edit_group="shape_torso" - label_min="Small" - label_max="Large" + name="Old" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance="1" - camera_angle="15"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0273 0.0273 0.0273" - pos="0.038 0.024 -0.016"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0273 0.0273 0.0273" - pos="0.038 -0.024 -0.016"/> - </param_morph> + value_max="1"> + <param_morph /> </param> + <!-- + ############## + # animatable morphs + ############## + --> <param - id="627" - sex="female" + id="51" group="1" - name="Small_Chest" - label="Chest Size" - wearable="shape" - edit_group="shape_torso" - label_min="Large" - label_max="Small" + name="Furrowed_Eyebrows" value_min="0" - value_max="1" - camera_elevation="0" - camera_distance=".28"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="-0.05 0.0 0.0" - pos="-0.01 -0.01 -0.02"/> - <volume_morph - name="RIGHT_PEC" - scale="-0.05 0.0 0.0" - pos="-0.01 -0.01 -0.02"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="843" - sex="female" + id="53" group="1" - name="No_Chest" - label="Chest Size" - wearable="shape" - edit_group="shape_torso" - label_min="Some" - label_max="None" + name="Surprised_Eyebrows" value_min="0" - value_max="1" - camera_elevation="0" - camera_distance=".28"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="-0.051 0.0 0.0" - pos="-0.02 -0.01 -0.03"/> - <volume_morph - name="RIGHT_PEC" - scale="-0.051 0.0 0.0" - pos="-0.02 -0.01 -0.03"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="106" + id="54" group="1" - name="Muscular_Torso" - label="Torso Muscles" - show_simple="true" - wearable="shape" - edit_group="shape_torso" - label_min="Regular" - label_max="Muscular" + name="Worried_Eyebrows" value_min="0" - value_max="1.4" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="L_CLAVICLE" - scale="0.02 0.0 0.005" - pos="0.0 0 0.005"/> - <volume_morph - name="L_UPPER_ARM" - scale="0.015 0.0 0.005" - pos="0.015 0 0"/> - <volume_morph - name="L_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.005 0 0"/> - <volume_morph - name="R_CLAVICLE" - scale="0.02 0.0 0.005" - pos="0.0 0 0.005"/> - <volume_morph - name="R_UPPER_ARM" - scale="0.015 0.0 0.005" - pos="0.015 0 0"/> - <volume_morph - name="R_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.005 0 0"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="648" + id="55" group="1" - sex="female" - name="Scrawny_Torso" - label="Torso Muscles" - show_simple="true" - wearable="shape" - edit_group="shape_torso" - label_min="Regular" - label_max="Scrawny" + name="Frown_Mouth" value_min="0" - value_max="1.3" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.0 -0.01 0.0" - pos="0.0 0.0 0"/> - <volume_morph - name="UPPER_BACK" - scale="-0.01 -0.01 0.0" - pos="0.0 0.0 0"/> - <volume_morph - name="CHEST" - scale="-0.01 -0.01 0.0" - pos="0.01 0.0 0"/> - <volume_morph - name="L_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="L_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="L_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - <volume_morph - name="R_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="R_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="R_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="677" + id="57" group="1" - sex="male" - name="Scrawny_Torso_Male" - label="Torso Scrawny" - wearable="shape" - edit_group="shape_torso" - label_min="Regular" - label_max="Scrawny" + name="Smile_Mouth" value_min="0" - value_max="1.3" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="BELLY" - scale="-0.01 -0.01 0.0" - pos="0.01 0.0 0"/> - <volume_morph - name="UPPER_BACK" - scale="-0.01 -0.01 0.0" - pos="0.0 0.0 0"/> - <volume_morph - name="CHEST" - scale="-0.02 -0.02 0.0" - pos="0.01 0.0 0"/> - <volume_morph - name="L_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="L_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="L_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - <volume_morph - name="R_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="R_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="R_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="634" + id="58" group="1" - name="Fat_Torso" - label="Fat Torso" - wearable="shape" - edit_group="shape_body" - label_min="skinny" - label_max="fat" + name="Blink_Left" value_min="0" - value_max="1" - camera_elevation=".3"> - <param_morph> - <volume_morph - name="CHEST" - scale="0.02 0.03 0.03" - pos="0 0 -0.03"/> - <volume_morph - name="PELVIS" - scale="0.02 0.03 0.03" - pos="0 0 -0.03"/> - <volume_morph - name="UPPER_BACK" - scale="0.01 0.03 0.0" - pos="-0.03 0 0"/> - <volume_morph - name="LOWER_BACK" - scale="0.04 0.06 0.0" - pos="-0.06 0 0"/> - <volume_morph - name="LEFT_HANDLE" - pos="0.0 0.08 0.0"/> - <volume_morph - name="RIGHT_HANDLE" - pos="0.0 -0.08 0.0"/> - <volume_morph - name="LEFT_PEC" - scale="0.0367 0.0367 0.016" - pos="0.00 -0.005 -0.013"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0367 0.0367 0.016" - pos="0.00 0.005 -0.013"/> - <volume_morph - name="BELLY" - scale="0.09 0.08 0.07" - pos="0 0 -0.05"/> - <volume_morph - name="L_CLAVICLE" - scale="0.0 0.0 0.015"/> - <volume_morph - name="L_UPPER_ARM" - scale="0.02 0.0 0.02" - pos="0.0 0.0 -0.02"/> - <volume_morph - name="L_LOWER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="R_CLAVICLE" - scale="0.0 0.0 0.015"/> - <volume_morph - name="R_UPPER_ARM" - scale="0.02 0.0 0.02" - pos="0.0 0.0 -0.02"/> - <volume_morph - name="R_LOWER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="NECK" - scale="0.015 0.01 0.0"/> - <volume_morph - name="HEAD" - scale="0.0 0.0 0.01" - pos="0 0 -0.01"/> - </param_morph> + value_max="1"> + <param_morph /> </param> <param - id="507" - group="0" - sex="female" - name="Breast_Gravity" - label="Breast Buoyancy" - wearable="shape" - edit_group="shape_torso" - edit_group_order="7" - label_min="Less Gravity" - label_max="More Gravity" - value_default="0" - value_min="-1.5" - value_max="2" - camera_elevation=".3" - camera_distance=".8"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.004 0.0 -0.01"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.004 0.0 -0.01"/> - </param_morph> - </param> - - <param - id="628" + id="59" group="1" - name="Displace_Loose_Upperbody" - label="Shirt Fit" - wearable="shirt" - edit_group="driven" - clothing_morph="true" + name="Blink_Right" value_min="0" - value_max="1" - value_default="0"> + value_max="1"> <param_morph /> </param> + <!-- + #end morph targets + --> + </mesh> + + <mesh + type="headMesh" + lod="1" + file_name="avatar_head_1.llm" + min_pixel_width="160" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="headMesh" + lod="2" + file_name="avatar_head_2.llm" + min_pixel_width="80" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="headMesh" + lod="3" + file_name="avatar_head_3.llm" + min_pixel_width="40" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="headMesh" + lod="4" + file_name="avatar_head_4.llm" + min_pixel_width="0" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="eyelashMesh" + lod="0" + file_name="avatar_eyelashes.llm" + min_pixel_width="320"> <param - id="840" - group="0" - name="Shirtsleeve_flair" - label="Sleeve Looseness" - show_simple="true" - wearable="shirt" - edit_group="shirt" - edit_group_order="6" - clothing_morph="true" - label_min="Tight Sleeves" - label_max="Loose Sleeves" - value_min="0" - value_max="1.5" - camera_distance="1.8" - camera_angle="30" - camera_elevation="-.3"> + shared="1" + id="660" + group="1" + name="Shear_Head" + wearable="shape" + label="Shear Face" + edit_group="shape_head" + label_min="Shear Left" + label_max="Shear Right" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04"> <param_morph /> </param> <param - id="855" + shared="1" + id="770" group="1" - name="Love_Handles" + name="Elongate_Head" wearable="shape" - edit_group="driven" - value_default="0" + label="Shear Face" + edit_group="shape_head" + label_min="Flat Head" + label_max="Long Head" value_min="-1" - value_max="2"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.0 0.02 0.0"/> - <volume_morph - name="LOWER_BACK" - scale="0.0 0.02 0.0"/> - <volume_morph - name="LEFT_HANDLE" - pos="0.0 0.025 0.0"/> - <volume_morph - name="RIGHT_HANDLE" - pos="0.0 -0.025 0.0"/> - </param_morph> + value_max="1" + value_default="0" + camera_distance=".5" + camera_elevation=".04"> + <param_morph /> </param> <param - id="684" + shared="1" + id="664" group="0" - sex="female" - name="Breast_Female_Cleavage" - label="Breast Cleavage" + name="Pop_Eye" wearable="shape" - edit_group="shape_torso" + label="Eye Pop" + edit_group="shape_eyes" edit_group_order="8" - label_min="Separate" - label_max="Join" + label_min="Pop Right Eye" + label_max="Pop Left Eye" + value_min="-2" + value_max="2" value_default="0" - value_min="-.3" - value_max="1.3" - camera_elevation=".3" - camera_distance=".8"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 -0.026 0.0"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.026 0.0"/> - </param_morph> + camera_distance=".5" + camera_elevation=".04" + camera_angle="-20"> + <param_morph /> </param> - + <param - id="685" - group="0" - sex="male" - name="Chest_Male_No_Pecs" - label="Pectorals" + shared="1" + id="186" + group="1" + name="Egg_Head" + label="Egg Head" wearable="shape" - edit_group="shape_torso" - edit_group_order="5" - label_min="Big Pectorals" - label_max="Sunken Chest" - value_default="0" - value_min="-0.5" - value_max="1.1" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="-0.03 -0.024 -0.01"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="-0.03 0.024 -0.01"/> - </param_morph> + edit_group="shape_head" + label_min="Chin Heavy" + label_max="Forehead Heavy" + value_min="-1.3" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> </param> - <!-- ############# # - other morphs (not user controlled) - ############# --> <param - id="100" + shared="1" + id="187" group="1" - name="Male_Torso" - wearable="shape" - edit_group="driven" - label_min="Male_Torso" - value_min="0" - value_max="1"> - <param_morph> - <volume_morph - name="CHEST" - scale="0.03 0.04 0.02" - pos="-0.03 0 -0.01"/> - <volume_morph - name="BELLY" - scale="0.03 0.03 0.0" - pos="-0.03 0 0.02"/> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.008 -0.03 0.01"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.008 0.03 0.01"/> - <volume_morph - name="L_CLAVICLE" - scale="0.02 0.0 0.01" - pos="-0.02 0 0"/> - <volume_morph - name="L_UPPER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="L_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.0 0.0 -0.005"/> - <volume_morph - name="R_CLAVICLE" - scale="0.02 0.0 0.01" - pos="-0.02 0 0"/> - <volume_morph - name="R_UPPER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="R_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.0 0.0 -0.005"/> - <volume_morph - name="NECK" - scale="0.015 0.01 0.0"/> - <volume_morph - name="HEAD" - scale="0.0 0.0 0.01" - pos="0 0 -0.01"/> - </param_morph> + name="Squash_Stretch_Head" + label="Squash/Stretch Head" + wearable="shape" + edit_group="shape_head" + label_min="Squash Head" + label_max="Stretch Head" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> + + <param + shared="1" + id="194" + group="1" + name="Eye_Spread" + edit_group="shape_eyes" + label_min="Eyes Together" + label_max="Eyes Spread" + value_min="-2" + value_max="2"> + <param_morph /> + </param> + + <param + id="518" + group="0" + name="Eyelashes_Long" + wearable="shape" + label="Eyelash Length" + edit_group="shape_eyes" + edit_group_order="7" + label_min="Short" + label_max="Long" + value_min="-.3" + value_max="1.5" + camera_elevation=".1" + camera_distance=".30" + camera_angle="-20"> + <param_morph /> + </param> + + <param + shared="1" + id="686" + group="1" + name="Head_Eyes_Big" + wearable="shape" + label="Eye Size" + edit_group="shape_eyes" + label_min="Beady Eyes" + label_max="Anime Eyes" + value_min="-2" + value_max="2" + show_simple="true" + value_default="0"> + <param_morph /> + </param> + + <param + shared="1" + id="767" + group="1" + name="Bug_Eyed_Head" + wearable="shape" + label="Eye Depth" + edit_group="shape_eyes" + edit_group_order="4.5" + label_min="Sunken Eyes" + label_max="Bug Eyes" + value_min="-2" + value_max="2" + value_default="0"> + <param_morph /> + </param> + + <param + shared="1" + id="20021" + group="1" + name="Upper_Eyelid_Fold" + value_min="-0.2" + value_max="1.3"> + <param_morph /> + </param> + + <param + shared="1" + id="20024" + group="1" + name="Wide_Eyes" + value_min="-1.5" + value_max="2"> + <param_morph /> + </param> + + <param + shared="1" + id="20650" + group="1" + name="Eyelid_Corner_Up" + value_min="-1.3" + value_max="1.2"> + <param_morph /> </param> + <param + shared="1" + id="20880" + group="1" + name="Eyelid_Inner_Corner_Up" + value_min="-1.3" + value_max="1.2"> + <param_morph /> + </param> + <!-- ############## - # animatable morphs + # Facial Expression morphs ############## --> <param - id="101" + shared="1" + id="301" group="1" - name="Hands_Relaxed" + name="Express_Tongue_Out" value_min="0" value_max="1"> <param_morph /> </param> <param - id="102" + shared="1" + id="302" group="1" - name="Hands_Point" + name="Express_Surprise_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="103" + shared="1" + id="303" group="1" - name="Hands_Fist" + name="Express_Wink_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="666" + shared="1" + id="304" group="1" - name="Hands_Relaxed_L" + name="Express_Embarrassed_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="667" + shared="1" + id="305" group="1" - name="Hands_Point_L" + name="Express_Shrug_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="668" + shared="1" + id="306" group="1" - name="Hands_Fist_L" + name="Express_Kiss" value_min="0" value_max="1"> <param_morph /> </param> <param - id="669" + shared="1" + id="307" group="1" - name="Hands_Relaxed_R" + name="Express_Bored_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="670" + shared="1" + id="308" group="1" - name="Hands_Point_R" + name="Express_Repulsed_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="671" + shared="1" + id="309" group="1" - name="Hands_Fist_R" + name="Express_Disdain" value_min="0" value_max="1"> <param_morph /> </param> <param - id="672" + shared="1" + id="310" group="1" - name="Hands_Typing" + name="Express_Afraid_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="766" + shared="1" + id="312" group="1" - name="Hands_Salute_R" + name="Express_Cry_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="791" + shared="1" + id="313" group="1" - name="Hands_Peace_R" + name="Express_Sad_Emote" value_min="0" value_max="1"> <param_morph /> </param> <param - id="792" + shared="1" + id="314" group="1" - name="Hands_Spread_R" + name="Express_Anger_Emote" value_min="0" value_max="1"> <param_morph /> </param> - <!-- - ############# - # physics morphs (not user controlled) - ############# - --> <param - id="1200" + shared="1" + id="315" group="1" - sex="female" - name="Breast_Physics_UpDown_Driven" - wearable="physics" - edit_group="driven" - value_default="0" - value_min="-3" - value_max="3"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.0 -0.01"/> - </param_morph> + name="Express_Frown" + value_min="0" + value_max="1"> + <param_morph /> </param> <param - id="1201" + shared="1" + id="316" group="1" - sex="female" - name="Breast_Physics_InOut_Driven" - wearable="physics" - edit_group="driven" - value_default="0" - value_min="-1.25" - value_max="1.25"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 -0.026 0.0"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.026 -0.0"/> - </param_morph> + name="Express_Laugh_Emote" + value_min="0" + value_max="1"> + <param_morph /> </param> <param - id="1204" + shared="1" + id="317" group="1" - name="Belly_Physics_Torso_UpDown_Driven" - wearable="physics" - edit_group="driven" - value_default="0" - value_min="-1" + name="Express_Toothsmile" + value_min="0" value_max="1"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.0 0.0 0.0" - pos="0.0 0.0 0.05"/> - </param_morph> + <param_morph /> </param> <param - id="1207" + shared="1" + id="318" group="1" - name="Breast_Physics_LeftRight_Driven" - wearable="physics" - edit_group="driven" - value_default="0" - value_min="-2" - value_max="2"> - <param_morph> - <volume_morph - name="LEFT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.03 0.0"/> - <volume_morph - name="RIGHT_PEC" - scale="0.0 0.0 0.0" - pos="0.0 0.03 0.0"/> - </param_morph> + name="Express_Smile" + value_min="0" + value_max="1"> + <param_morph /> </param> <!-- - #end morph targets - --> - - </mesh> - - <mesh - type="upperBodyMesh" - lod="1" - file_name="avatar_upper_body_1.llm" - min_pixel_width="160" - reference="avatar_upper_body.llm"> - </mesh> - - <mesh - type="upperBodyMesh" - lod="2" - file_name="avatar_upper_body_2.llm" - min_pixel_width="80" - reference="avatar_upper_body.llm"> - </mesh> + ############## + # other morphs (not user controlled) + ############## + --> + <param + shared="1" + id="41" + group="1" + name="Old" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <mesh - type="upperBodyMesh" - lod="3" - file_name="avatar_upper_body_3.llm" - min_pixel_width="40" - reference="avatar_upper_body.llm"> - </mesh> + <!-- + ############## + # animatable morphs + ############## + --> + <param + shared="1" + id="58" + group="1" + name="Blink_Left" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <mesh - type="upperBodyMesh" - lod="4" - file_name="avatar_upper_body_4.llm" - min_pixel_width="0" - reference="avatar_upper_body.llm"> + <param + shared="1" + id="59" + group="1" + name="Blink_Right" + value_min="0" + value_max="1"> + <param_morph /> + </param> </mesh> <!-- - #upperBodyMesh2 = - #upperBodyMesh3 = + #headMesh2 = + #headMesh3 = --> <mesh - type="lowerBodyMesh" + type="upperBodyMesh" lod="0" - file_name="avatar_lower_body.llm" + file_name="avatar_upper_body.llm" min_pixel_width="320"> <!-- #begin morph targets @@ -4611,315 +6817,412 @@ ############# --> <param - id="156" + id="104" group="1" - name="Big_Belly_Legs" + name="Big_Belly_Torso" wearable="shape" edit_group="driven" value_min="0" value_max="1"> - <param_morph /> + <param_morph> + <volume_morph + name="BELLY" + scale="0.075 0.04 0.03" + pos="0.07 0 -0.07"/> + <volume_morph + name="PELVIS" + scale="0.075 0.04 0.03" + pos="0.07 0 -0.02"/> + </param_morph> </param> - <param - id="151" + id="626" + sex="female" group="1" - name="Big_Butt_Legs" - label="Butt Size" + name="Big_Chest" + label="Chest Size" wearable="shape" - edit_group="shape_legs" - label_min="Regular" + edit_group="shape_torso" + label_min="Small" label_max="Large" value_min="0" - value_max="1"> + value_max="1" + camera_elevation=".1" + camera_distance="1" + camera_angle="15"> <param_morph> <volume_morph - name="PELVIS" - scale="0.03 0.0 0.02" - pos="-0.03 0 -0.025"/> - </param_morph> + name="LEFT_PEC" + scale="0.0273 0.0273 0.0273" + pos="0.038 0.024 -0.016"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0273 0.0273 0.0273" + pos="0.038 -0.024 -0.016"/> + </param_morph> </param> <param - id="794" + id="627" + sex="female" group="1" - name="Small_Butt" - label="Butt Size" + name="Small_Chest" + label="Chest Size" wearable="shape" - edit_group="shape_legs" - label_min="Regular" + edit_group="shape_torso" + label_min="Large" label_max="Small" value_min="0" - value_max="1"> + value_max="1" + camera_elevation="0" + camera_distance=".28"> <param_morph> <volume_morph - name="PELVIS" - scale="-0.01 0.0 0.0" - pos="0.01 0 0.0"/> + name="LEFT_PEC" + scale="-0.05 0.0 0.0" + pos="-0.01 -0.01 -0.02"/> <volume_morph - name="BUTT" - scale="0.0 0.0886 0.0" - pos="0.03 0 0.0"/> - </param_morph> + name="RIGHT_PEC" + scale="-0.05 0.0 0.0" + pos="-0.01 0.01 -0.02"/> + </param_morph> </param> <param - id="152" + id="843" + sex="female" group="1" - name="Muscular_Legs" - label="Leg Muscles" - show_simple="true" + name="No_Chest" + label="Chest Size" wearable="shape" - edit_group="shape_legs" - label_min="Regular Muscles" - label_max="More Muscles" + edit_group="shape_torso" + label_min="Some" + label_max="None" value_min="0" - value_max="1.5" - camera_distance="1.3" - camera_elevation="-.5"> + value_max="1" + camera_elevation="0" + camera_distance=".28"> <param_morph> <volume_morph - name="L_UPPER_LEG" - scale="0.015 0.015 0.0" - pos="0.0 0 0.0"/> - <volume_morph - name="L_LOWER_LEG" - scale="0.01 0.01 0.0" - pos="0.0 0 0.0"/> - <volume_morph - name="R_UPPER_LEG" - scale="0.015 0.015 0.0" - pos="0.0 0 0.0"/> + name="LEFT_PEC" + scale="-0.051 0.0 0.0" + pos="-0.02 -0.01 -0.03"/> <volume_morph - name="R_LOWER_LEG" - scale="0.01 0.01 0.0" - pos="0.0 0 0.0"/> - </param_morph> + name="RIGHT_PEC" + scale="-0.051 0.0 0.0" + pos="-0.02 0.01 -0.03"/> + </param_morph> </param> <param - id="651" + id="106" group="1" - name="Scrawny_Legs" - label="Scrawny Leg" + name="Muscular_Torso" + label="Torso Muscles" + sex="male" + show_simple="true" wearable="shape" - edit_group="shape_legs" - label_min="Regular Muscles" - label_max="Less Muscles" + edit_group="shape_torso" + label_min="Regular" + label_max="Muscular" value_min="0" - value_max="1.5" - camera_distance="1.3" - camera_elevation="-.5"> + value_max="1.4" + camera_elevation=".3" + camera_distance="1.2"> <param_morph> <volume_morph - name="L_UPPER_LEG" - scale="-0.03 -0.03 0.0" - pos="0.0 0 0.0"/> + name="L_CLAVICLE" + scale="0.02 0.0 0.005" + pos="0.0 0 0.005"/> <volume_morph - name="L_LOWER_LEG" - scale="-0.015 -0.015 0.0" - pos="0.0 0 0.0"/> + name="L_UPPER_ARM" + scale="0.015 0.0 0.005" + pos="0.015 0 0"/> <volume_morph - name="R_UPPER_LEG" - scale="-0.03 -0.03 0.0" - pos="0.0 0 0.0"/> + name="L_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.005 0 0"/> <volume_morph - name="R_LOWER_LEG" - scale="-0.015 -0.015 0.0" - pos="0.0 0 0.0"/> + name="R_CLAVICLE" + scale="0.02 0.0 0.005" + pos="0.0 0 0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.015 0.0 0.005" + pos="0.015 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.005 0 0"/> </param_morph> </param> <param - id="853" - group="1" - name="Bowed_Legs" - label="Knee Angle" + id="107" + group="1" + name="Muscular_Torso" + label="Torso Muscles" + sex="female" + show_simple="true" wearable="shape" - value_min="-1" - value_max="1"> + edit_group="shape_torso" + label_min="Regular" + label_max="Muscular" + value_min="0" + value_max="1.4" + camera_elevation=".3" + camera_distance="1.2"> <param_morph> <volume_morph - name="L_UPPER_LEG" - pos="0.0 0.03 0.0"/> + name="L_CLAVICLE" + scale="0.02 0.0 0.005" + pos="0.0 0 0.005"/> <volume_morph - name="L_LOWER_LEG" - pos="0.0 0.03 0.0"/> + name="L_UPPER_ARM" + scale="0.015 0.0 0.005" + pos="0.015 0 0"/> <volume_morph - name="R_UPPER_LEG" - pos="0.0 -0.03 0.0"/> + name="L_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.005 0 0"/> <volume_morph - name="R_LOWER_LEG" - pos="0.0 -0.03 0.0"/> + name="R_CLAVICLE" + scale="0.02 0.0 0.005" + pos="0.0 0 0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.015 0.0 0.005" + pos="0.015 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.005 0 0"/> </param_morph> </param> <param - id="500" - group="1" - name="Shoe_Heel_Height" - label="Heel Height" - wearable="shoes" - edit_group="shoes" - label_min="Low Heels" - label_max="High Heels" - value_min="0" - value_max="1" - camera_distance="1.5" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="501" + id="648" group="1" - name="Shoe_Platform_Height" - label="Platform Height" - wearable="shoes" - edit_group="shoes" - label_min="Low Platforms" - label_max="High Platforms" + sex="female" + name="Scrawny_Torso" + label="Torso Muscles" + show_simple="true" + wearable="shape" + edit_group="shape_torso" + label_min="Regular" + label_max="Scrawny" value_min="0" - value_max="1" - camera_distance="1.5" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="508" - group="0" - name="Shoe_Platform_Width" - label="Platform Width" - wearable="shoes" - edit_group="shoes" - edit_group_order="7" - label_min="Narrow" - label_max="Wide" - value_min="-1" - value_max="2" - camera_angle="15" - camera_distance="1.5" - camera_elevation="-1"> - <param_morph /> + value_max="1.3" + camera_elevation=".3" + camera_distance="1.2"> + <param_morph> + <volume_morph + name="BELLY" + scale="0.0 -0.01 0.0" + pos="0.0 0.0 0"/> + <volume_morph + name="UPPER_BACK" + scale="-0.01 -0.01 0.0" + pos="0.0 0.0 0"/> + <volume_morph + name="CHEST" + scale="-0.01 -0.01 0.0" + pos="0.01 0.0 0"/> + <volume_morph + name="L_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="L_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="L_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + <volume_morph + name="R_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + </param_morph> </param> <param - id="509" + id="677" group="1" - name="Shoe_Heel_Point" - label="Heel Shape" - wearable="shoes" - edit_group="shoes" - label_min="Default Heels" - label_max="Pointy Heels" + sex="male" + name="Scrawny_Torso_Male" + label="Torso Scrawny" + wearable="shape" + edit_group="shape_torso" + label_min="Regular" + label_max="Scrawny" value_min="0" - value_max="1" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph /> + value_max="1.3" + camera_elevation=".3" + camera_distance="1.2"> + <param_morph> + <volume_morph + name="BELLY" + scale="-0.01 -0.01 0.0" + pos="0.01 0.0 0"/> + <volume_morph + name="UPPER_BACK" + scale="-0.01 -0.01 0.0" + pos="0.0 0.0 0"/> + <volume_morph + name="CHEST" + scale="-0.02 -0.02 0.0" + pos="0.01 0.0 0"/> + <volume_morph + name="L_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="L_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="L_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + <volume_morph + name="R_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + </param_morph> </param> <param - id="510" + id="634" group="1" - name="Shoe_Heel_Thick" - label="Heel Shape" - wearable="shoes" - edit_group="shoes" - label_min="default Heels" - label_max="Thick Heels" + name="Fat_Torso" + label="Fat Torso" + wearable="shape" + edit_group="shape_body" + label_min="skinny" + label_max="fat" value_min="0" value_max="1" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="511" - group="1" - name="Shoe_Toe_Point" - label="Toe Shape" - wearable="shoes" - edit_group="shoes" - label_min="Default Toe" - label_max="Pointy Toe" - value_min="0" - value_max="1" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="512" - group="1" - name="Shoe_Toe_Square" - label="Toe Shape" - wearable="shoes" - edit_group="shoes" - label_min="Default Toe" - label_max="Square Toe" - value_min="0" - value_max="1" - camera_distance="1.5" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="654" - group="0" - name="Shoe_Toe_Thick" - label="Toe Thickness" - wearable="shoes" - edit_group="shoes" - edit_group_order="5" - label_min="Flat Toe" - label_max="Thick Toe" - value_min="0" - value_max="2" - camera_angle="15" - camera_distance="1.5" - camera_elevation="-1"> - <param_morph /> + camera_elevation=".3"> + <param_morph> + <volume_morph + name="CHEST" + scale="0.02 0.03 0.03" + pos="0 0 -0.03"/> + <volume_morph + name="PELVIS" + scale="0.02 0.03 0.03" + pos="0 0 -0.03"/> + <volume_morph + name="UPPER_BACK" + scale="0.01 0.03 0.0" + pos="-0.03 0 0"/> + <volume_morph + name="LOWER_BACK" + scale="0.04 0.06 0.0" + pos="-0.06 0 0"/> + <volume_morph + name="LEFT_HANDLE" + pos="0.0 0.08 0.0"/> + <volume_morph + name="RIGHT_HANDLE" + pos="0.0 -0.08 0.0"/> + <volume_morph + name="LEFT_PEC" + scale="0.0367 0.0367 0.016" + pos="0.00 -0.005 -0.013"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0367 0.0367 0.016" + pos="0.00 0.005 -0.013"/> + <volume_morph + name="BELLY" + scale="0.09 0.08 0.07" + pos="0 0 -0.05"/> + <volume_morph + name="L_CLAVICLE" + scale="0.0 0.0 0.015"/> + <volume_morph + name="L_UPPER_ARM" + scale="0.02 0.0 0.02" + pos="0.0 0.0 -0.02"/> + <volume_morph + name="L_LOWER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="R_CLAVICLE" + scale="0.0 0.0 0.015"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.02 0.0 0.02" + pos="0.0 0.0 -0.02"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="NECK" + scale="0.015 0.01 0.0"/> + <volume_morph + name="HEAD" + scale="0.0 0.0 0.01" + pos="0 0 -0.01"/> + </param_morph> </param> <param - id="515" + id="507" group="0" - name="Foot_Size" - label="Foot Size" + sex="female" + name="Breast_Gravity" + label="Breast Buoyancy" wearable="shape" - edit_group="shape_legs" - edit_group_order="6" - label_min="Small" - label_max="Big" - value_min="-1" - value_max="3" - camera_angle="45" - camera_distance="1.1" - camera_elevation="-1"> + edit_group="shape_torso" + edit_group_order="7" + label_min="Less Gravity" + label_max="More Gravity" + value_default="0" + value_min="-1.5" + value_max="2" + camera_elevation=".3" + camera_distance=".8"> <param_morph> <volume_morph - name="L_FOOT" - scale="0.02 0.01 0.0" - pos="0.01 0 0"/> + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.004 0.0 -0.01"/> <volume_morph - name="R_FOOT" - scale="0.02 0.01 0.0" - pos="0.01 0 0"/> + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.004 0.0 -0.01"/> </param_morph> </param> - + <param - id="516" + id="628" group="1" - name="Displace_Loose_Lowerbody" - label="Pants Fit" - wearable="pants" + name="Displace_Loose_Upperbody" + label="Shirt Fit" + wearable="shirt" edit_group="driven" clothing_morph="true" value_min="0" @@ -4929,17 +7232,17 @@ </param> <param - id="625" + id="840" group="0" - name="Leg_Pantflair" - label="Cuff Flare" + name="Shirtsleeve_flair" + label="Sleeve Looseness" show_simple="true" - wearable="pants" - edit_group="pants" - edit_group_order="3" + wearable="shirt" + edit_group="shirt" + edit_group_order="6" clothing_morph="true" - label_min="Tight Cuffs" - label_max="Flared Cuffs" + label_min="Tight Sleeves" + label_max="Loose Sleeves" value_min="0" value_max="1.5" camera_distance="1.8" @@ -4949,2856 +7252,2906 @@ </param> <param - id="793" - group="1" - name="Leg_Longcuffs" - label="Longcuffs" - wearable="pants" - edit_group="driven" - clothing_morph="true" - value_min="0" - value_max="3" - value_default="0"> - <param_morph /> - </param> - - <param - id="638" - group="0" - name="Low_Crotch" - label="Pants Crotch" - wearable="pants" - clothing_morph="true" - edit_group="pants" - edit_group_order="4" - label_min="High and Tight" - label_max="Low and Loose" - value_min="0" - value_max="1.3" - camera_distance="1.2" - camera_angle="-20" - camera_elevation="-.3"> - <param_morph /> - </param> - - <param - id="635" + id="855" group="1" - name="Fat_Legs" - label="Fat Torso" + name="Love_Handles" wearable="shape" - edit_group="shape_body" - label_min="skinny" - label_max="fat" - value_min="0" - value_max="1"> + edit_group="driven" + value_default="0" + value_min="-1" + value_max="2"> <param_morph> <volume_morph - name="PELVIS" - scale="0.03 0.06 0.0"/> - <volume_morph - name="R_UPPER_LEG" - scale="0.02 0.02 0.0" - pos="0.0 -0.02 0.0"/> + name="BELLY" + scale="0.0 0.02 0.0"/> <volume_morph - name="R_LOWER_LEG" - scale="0.01 0.01 0.0"/> + name="LOWER_BACK" + scale="0.0 0.02 0.0"/> <volume_morph - name="L_UPPER_LEG" - scale="0.02 0.02 0.0" - pos="0.0 0.02 0.0"/> + name="LEFT_HANDLE" + pos="0.0 0.025 0.0"/> <volume_morph - name="L_LOWER_LEG" - scale="0.01 0.01 0.0"/> + name="RIGHT_HANDLE" + pos="0.0 -0.025 0.0"/> </param_morph> </param> <param - id="854" - group="1" - name="Saddlebags" + id="684" + group="0" + sex="female" + name="Breast_Female_Cleavage" + label="Breast Cleavage" wearable="shape" - edit_group="driven" - value_min="-.5" - value_max="3"> - <param_morph> - <volume_morph - name="PELVIS" - scale="0.0 0.025 0.0"/> - </param_morph> - + edit_group="shape_torso" + edit_group_order="8" + label_min="Separate" + label_max="Join" + value_default="0" + value_min="-.3" + value_max="1.3" + camera_elevation=".3" + camera_distance=".8"> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 -0.026 0.0"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.026 0.0"/> + </param_morph> </param> - + <param - id="879" + id="685" group="0" sex="male" - name="Male_Package" - label="Package" + name="Chest_Male_No_Pecs" + label="Pectorals" wearable="shape" - edit_group="shape_legs" - edit_group_order="4.6" - label_min="Coin Purse" - label_max="Duffle Bag" + edit_group="shape_torso" + edit_group_order="5" + label_min="Big Pectorals" + label_max="Sunken Chest" value_default="0" - value_min="-.5" - value_max="2" - camera_angle="60" - camera_distance=".6"> - <param_morph /> + value_min="-0.5" + value_max="1.1" + camera_elevation=".3" + camera_distance="1.2"> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="-0.03 -0.024 -0.01"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="-0.03 0.024 -0.01"/> + </param_morph> </param> - <!-- - ############# - # other morphs (not user controlled) - ############# - --> + <!-- ############# # + other morphs (not user controlled) + ############# --> <param - id="153" + id="100" group="1" - name="Male_Legs" - wearable="shape" + name="Male_Torso" + wearable="shape" edit_group="driven" + label_min="Male_Torso" value_min="0" value_max="1"> - <param_morph /> + <param_morph> + <volume_morph + name="CHEST" + scale="0.03 0.04 0.02" + pos="-0.03 0 -0.01"/> + <volume_morph + name="BELLY" + scale="0.03 0.03 0.0" + pos="-0.03 0 0.02"/> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.008 -0.03 0.01"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.008 0.03 0.01"/> + <volume_morph + name="L_CLAVICLE" + scale="0.02 0.0 0.01" + pos="-0.02 0 0"/> + <volume_morph + name="L_UPPER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="L_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.0 0.0 -0.005"/> + <volume_morph + name="R_CLAVICLE" + scale="0.02 0.0 0.01" + pos="-0.02 0 0"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.0 0.0 -0.005"/> + <volume_morph + name="NECK" + scale="0.015 0.01 0.0"/> + <volume_morph + name="HEAD" + scale="0.0 0.0 0.01" + pos="0 0 -0.01"/> + </param_morph> </param> <!-- - ############# - # physics morphs (not user controlled) - ############# + ############## + # animatable morphs + ############## --> <param - id="1202" + id="101" group="1" - name="Belly_Physics_Legs_UpDown_Driven" - wearable="physics" - cross_wearable="true" - edit_group="driven" - value_min="-1" + name="Hands_Relaxed" + value_min="0" value_max="1"> <param_morph /> </param> - <param - id="1205" + id="102" group="1" - name="Butt_Physics_UpDown_Driven" - wearable="physics" - cross_wearable="true" - edit_group="driven" - value_default="0" - value_min="-1" + name="Hands_Point" + value_min="0" value_max="1"> - <param_morph> - <volume_morph - name="BUTT" - pos="0.0 0.0 0.05"/> - </param_morph> + <param_morph /> </param> <param - id="1206" + id="103" group="1" - name="Butt_Physics_LeftRight_Driven" - wearable="physics" - cross_wearable="true" - edit_group="driven" - value_default="0" - value_min="-1" + name="Hands_Fist" + value_min="0" value_max="1"> - <param_morph> - <volume_morph - name="BUTT" - pos="0.0 0.05 0.0"/> - </param_morph> + <param_morph /> </param> - <!-- - #end morph targets - --> - - </mesh> - - <mesh - type="lowerBodyMesh" - lod="1" - file_name="avatar_lower_body_1.llm" - min_pixel_width="160" - reference="avatar_lower_body.llm"> - </mesh> - - <mesh - type="lowerBodyMesh" - lod="2" - file_name="avatar_lower_body_2.llm" - min_pixel_width="80" - reference="avatar_lower_body.llm"> - </mesh> - - <mesh - type="lowerBodyMesh" - lod="3" - file_name="avatar_lower_body_3.llm" - min_pixel_width="40" - reference="avatar_lower_body.llm"> - </mesh> - - <mesh - type="lowerBodyMesh" - lod="4" - file_name="avatar_lower_body_4.llm" - min_pixel_width="0" - reference="avatar_lower_body.llm"> - </mesh> - - <!-- - #lowerBodyMesh2 = - #lowerBodyMesh3 = - --> - <!-- - #eyeLidLeftMesh = - --> - <mesh - type="eyeBallLeftMesh" - lod="0" - file_name="avatar_eye.llm" - min_pixel_width="320"> - <!-- begin morph_params --> <param - id="679" + id="666" group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> + name="Hands_Relaxed_L" + value_min="0" + value_max="1"> <param_morph /> </param> <param - id="687" + id="667" group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> + name="Hands_Point_L" + value_min="0" + value_max="1"> <param_morph /> </param> - </mesh> - <mesh - type="eyeBallLeftMesh" - lod="1" - file_name="avatar_eye_1.llm" - min_pixel_width="80"> - <!-- begin morph_params --> <param - id="694" + id="668" group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> - <param_morph /> - </param> - - <param - id="695" - group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> - <param_morph /> - </param> - </mesh> - - <!-- - #eyeLidRightMesh = - --> - <mesh - type="eyeBallRightMesh" - lod="0" - file_name="avatar_eye.llm" - min_pixel_width="320"> - <!-- begin morph_params --> - <param - id="680" - group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> - <param_morph /> - </param> - - <param - id="688" - group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> + name="Hands_Fist_L" + value_min="0" + value_max="1"> <param_morph /> </param> - </mesh> - <mesh - type="eyeBallRightMesh" - lod="1" - file_name="avatar_eye_1.llm" - min_pixel_width="80"> - <!-- begin morph_params --> <param - id="681" + id="669" group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> + name="Hands_Relaxed_R" + value_min="0" + value_max="1"> <param_morph /> </param> <param - id="691" + id="670" group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> + name="Hands_Point_R" + value_min="0" + value_max="1"> <param_morph /> </param> - </mesh> - <mesh - type="skirtMesh" - lod="0" - file_name="avatar_skirt.llm" - min_pixel_width="320"> <param - id="845" + id="671" group="1" - name="skirt_poofy" - label="poofy skirt" - clothing_morph="true" - wearable="skirt" - edit_group="skirt" - label_min="less poofy" - label_max="more poofy" + name="Hands_Fist_R" value_min="0" - value_max="1.5"> + value_max="1"> <param_morph /> </param> <param - id="846" + id="672" group="1" - name="skirt_loose" - label="loose skirt" - clothing_morph="true" - wearable="skirt" - edit_group="skirt" - label_min="form fitting" - label_max="loose" + name="Hands_Typing" value_min="0" value_max="1"> <param_morph /> </param> <param - id="866" + id="766" group="1" - name="skirt_tight" - label="tight skirt" - clothing_morph="true" - wearable="skirt" - edit_group="skirt" - label_min="form fitting" - label_max="loose" + name="Hands_Salute_R" value_min="0" value_max="1"> <param_morph /> </param> <param - id="867" + id="791" group="1" - name="skirt_smallbutt" - label="tight skirt" - clothing_morph="false" - wearable="skirt" - edit_group="skirt" - cross_wearable="true" - label_min="form fitting" - label_max="loose" + name="Hands_Peace_R" value_min="0" value_max="1"> <param_morph /> </param> <param - id="848" - group="0" - name="skirt_bustle" - label="bustle skirt" - clothing_morph="true" - wearable="skirt" - edit_group_order="3" - edit_group="skirt" - label_min="no bustle" - label_max="more bustle" + id="792" + group="1" + name="Hands_Spread_R" value_min="0" - value_max="2" - value_default=".2" - camera_angle="100" - camera_distance="1.3" - camera_elevation="-.5"> + value_max="1"> <param_morph /> </param> + <!-- + ############# + # physics morphs (not user controlled) + ############# + --> <param - id="847" + id="1200" group="1" - name="skirt_bowlegs" - label="legs skirt" - wearable="skirt" + sex="female" + name="Breast_Physics_UpDown_Driven" + wearable="physics" edit_group="driven" - cross_wearable="true" - value_min="-1" - value_max="1" - value_default="0"> - <param_morph /> + value_default="0" + value_min="-3" + value_max="3"> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.0 -0.01"/> + </param_morph> </param> <param - id="852" + id="1201" group="1" - name="skirt_bigbutt" - wearable="skirt" + sex="female" + name="Breast_Physics_InOut_Driven" + wearable="physics" edit_group="driven" - cross_wearable="true" - label="bigbutt skirt" - label_min="less" - label_max="more" - value_min="0" - value_max="1"> - <param_morph /> + value_default="0" + value_min="-1.25" + value_max="1.25"> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 -0.026 0.0"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.026 -0.0"/> + </param_morph> </param> <param - id="849" + id="1204" group="1" - name="skirt_belly" - wearable="skirt" + name="Belly_Physics_Torso_UpDown_Driven" + wearable="physics" edit_group="driven" - cross_wearable="true" - label="big belly skirt" - value_min="0" + value_default="0" + value_min="-1" value_max="1"> - <param_morph /> - </param> - - <param - id="850" - group="1" - wearable="skirt" - edit_group="driven" - cross_wearable="true" - name="skirt_saddlebags" - value_min="-.5" - value_max="3"> - <param_morph /> + <param_morph> + <volume_morph + name="BELLY" + scale="0.0 0.0 0.0" + pos="0.0 0.0 0.05"/> + </param_morph> </param> <param - id="851" + id="1207" group="1" - name="skirt_chubby" - wearable="skirt" + name="Breast_Physics_LeftRight_Driven" + wearable="physics" edit_group="driven" - cross_wearable="true" - label_min="less" - label_max="more" - value_min="0" - value_max="1" - value_default="0"> - <param_morph /> - </param> - - <param - id="856" - group="1" - name="skirt_lovehandles" - wearable="skirt" - edit_group="driven" - cross_wearable="true" - label_min="less" - label_max="more" - value_min="-1" - value_max="2" - value_default="0"> - <param_morph /> - </param> - - <!-- - ############# - # other morphs (not user controlled) - ############# - --> - <param - id="857" - group="1" - name="skirt_male" - wearable="skirt" - edit_group="driven" - cross_wearable="true" - value_min="0" - value_max="1"> - <param_morph /> + value_default="0" + value_min="-2" + value_max="2"> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.03 0.0"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.03 0.0"/> + </param_morph> </param> <!-- - ############# - # physics morphs (not user controlled) - ############# - --> - <param - id="1203" - group="1" - name="Belly_Physics_Skirt_UpDown_Driven" - wearable="physics" - cross_wearable="true" - edit_group="driven" - value_default="0" - value_min="-1" - value_max="1"> - <param_morph /> - </param> + #end morph targets + --> </mesh> <mesh - type="skirtMesh" + type="upperBodyMesh" lod="1" - file_name="avatar_skirt_1.llm" + file_name="avatar_upper_body_1.llm" min_pixel_width="160" - reference="avatar_skirt.llm"> + reference="avatar_upper_body.llm"> </mesh> <mesh - type="skirtMesh" + type="upperBodyMesh" lod="2" - file_name="avatar_skirt_2.llm" + file_name="avatar_upper_body_2.llm" min_pixel_width="80" - reference="avatar_skirt.llm"> + reference="avatar_upper_body.llm"> </mesh> <mesh - type="skirtMesh" + type="upperBodyMesh" lod="3" - file_name="avatar_skirt_3.llm" + file_name="avatar_upper_body_3.llm" min_pixel_width="40" - reference="avatar_skirt.llm"> + reference="avatar_upper_body.llm"> </mesh> <mesh - type="skirtMesh" + type="upperBodyMesh" lod="4" - file_name="avatar_skirt_4.llm" + file_name="avatar_upper_body_4.llm" min_pixel_width="0" - reference="avatar_skirt.llm"> + reference="avatar_upper_body.llm"> </mesh> - <!-- =========================================================== --> - <global_color - name="skin_color"> + <!-- + #upperBodyMesh2 = + #upperBodyMesh3 = + --> + <mesh + type="lowerBodyMesh" + lod="0" + file_name="avatar_lower_body.llm" + min_pixel_width="320"> + <!-- + #begin morph targets + ############# + # tweakable morphs + ############# + --> <param - id="111" - group="0" - wearable="skin" - edit_group="skin_color" - edit_group_order="1" - name="Pigment" - show_simple="true" - label_min="Light" - label_max="Dark" + id="156" + group="1" + name="Big_Belly_Legs" + wearable="shape" + edit_group="driven" value_min="0" - value_max="1" - value_default=".5"> - <param_color> - <value - color="252, 215, 200, 255" /> - - <value - color="240, 177, 112, 255" /> - - <value - color="90, 40, 16, 255" /> - - <value - color="29, 9, 6, 255" /> - </param_color> + value_max="1"> + <param_morph /> </param> + <param - id="110" - group="0" - wearable="skin" - edit_group="skin_color" - edit_group_order="2" - name="Red Skin" - label="Ruddiness" - label_min="Pale" - label_max="Ruddy" + id="151" + group="1" + name="Big_Butt_Legs" + label="Butt Size" + wearable="shape" + edit_group="shape_legs" + label_min="Regular" + label_max="Large" value_min="0" - value_max="0.1"> - <param_color - operation="blend"> - <value - color="218, 41, 37, 255" /> - </param_color> + value_max="1"> + <param_morph> + <volume_morph + name="PELVIS" + scale="0.03 0.0 0.02" + pos="-0.03 0 -0.025"/> + </param_morph> </param> <param - id="108" - group="0" - wearable="skin" - edit_group="skin_color" - edit_group_order="3" - name="Rainbow Color" - show_simple="true" - label_min="None" - label_max="Wild" + id="794" + group="1" + name="Small_Butt" + label="Butt Size" + wearable="shape" + edit_group="shape_legs" + label_min="Regular" + label_max="Small" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color=" 0, 0, 0, 255" /> - - <value - color="255, 0, 255, 255" /> - - <value - color="255, 0, 0, 255" /> - - <value - color="255, 255, 0, 255" /> - - <value - color=" 0, 255, 0, 255" /> - - <value - color=" 0, 255, 255, 255" /> - - <value - color=" 0, 0, 255, 255" /> - - <value - color="255, 0, 255, 255" /> - </param_color> + value_max="1"> + <param_morph> + <volume_morph + name="PELVIS" + scale="-0.01 0.0 0.0" + pos="0.01 0 0.0"/> + <volume_morph + name="BUTT" + scale="0.0 0.0886 0.0" + pos="0.03 0 0.0"/> + </param_morph> </param> - </global_color> - <!-- =========================================================== --> - <global_color - name="hair_color"> <param - id="114" - group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="3" - name="Blonde Hair" + id="152" + group="1" + name="Muscular_Legs" + label="Leg Muscles" show_simple="true" - label_min="Black" - label_max="Blonde" + wearable="shape" + edit_group="shape_legs" + label_min="Regular Muscles" + label_max="More Muscles" value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="22, 6, 6, 255" /> - - <value - color="29, 9, 6, 255" /> - - <value - color="45, 21, 11, 255" /> - - <value - color="78, 39, 11, 255" /> - - <value - color="90, 53, 16, 255" /> - - <value - color="136, 92, 21, 255" /> - - <value - color="150, 106, 33, 255" /> - - <value - color="198, 156, 74, 255" /> + value_max="1.5" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph> + <volume_morph + name="L_UPPER_LEG" + scale="0.015 0.015 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="L_LOWER_LEG" + scale="0.01 0.01 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_UPPER_LEG" + scale="0.015 0.015 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_LOWER_LEG" + scale="0.01 0.01 0.0" + pos="0.0 0 0.0"/> + </param_morph> + </param> - <value - color="233, 192, 103, 255" /> + <param + id="651" + group="1" + name="Scrawny_Legs" + label="Scrawny Leg" + wearable="shape" + edit_group="shape_legs" + label_min="Regular Muscles" + label_max="Less Muscles" + value_min="0" + value_max="1.5" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph> + <volume_morph + name="L_UPPER_LEG" + scale="-0.03 -0.03 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="L_LOWER_LEG" + scale="-0.015 -0.015 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_UPPER_LEG" + scale="-0.03 -0.03 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_LOWER_LEG" + scale="-0.015 -0.015 0.0" + pos="0.0 0 0.0"/> + </param_morph> + </param> - <value - color="238, 205, 136, 255" /> - </param_color> + <param + id="853" + group="1" + name="Bowed_Legs" + label="Knee Angle" + wearable="shape" + value_min="-1" + value_max="1"> + <param_morph> + <volume_morph + name="L_UPPER_LEG" + pos="0.0 0.03 0.0"/> + <volume_morph + name="L_LOWER_LEG" + pos="0.0 0.03 0.0"/> + <volume_morph + name="R_UPPER_LEG" + pos="0.0 -0.03 0.0"/> + <volume_morph + name="R_LOWER_LEG" + pos="0.0 -0.03 0.0"/> + </param_morph> </param> <param - id="113" - group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="4" - name="Red Hair" - show_simple="true" - label_min="No Red" - label_max="Very Red" + id="500" + group="1" + name="Shoe_Heel_Height" + label="Heel Height" + wearable="shoes" + edit_group="shoes" + label_min="Low Heels" + label_max="High Heels" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="118, 47, 19, 255" /> - </param_color> + camera_distance="1.5" + camera_elevation="-.5"> + <param_morph /> </param> <param - id="115" - group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="1" - name="White Hair" - show_simple="true" - label_min="No White" - label_max="All White" + id="501" + group="1" + name="Shoe_Platform_Height" + label="Platform Height" + wearable="shoes" + edit_group="shoes" + label_min="Low Platforms" + label_max="High Platforms" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 255, 255, 255" /> - </param_color> + camera_distance="1.5" + camera_elevation="-.5"> + <param_morph /> </param> <param - id="112" + id="508" group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="2" - name="Rainbow Color" - show_simple="true" - label_min="None" - label_max="Wild" + name="Shoe_Platform_Width" + label="Platform Width" + wearable="shoes" + edit_group="shoes" + edit_group_order="7" + label_min="Narrow" + label_max="Wide" + value_min="-1" + value_max="2" + camera_angle="15" + camera_distance="1.5" + camera_elevation="-1"> + <param_morph /> + </param> + + <param + id="509" + group="1" + name="Shoe_Heel_Point" + label="Heel Shape" + wearable="shoes" + edit_group="shoes" + label_min="Default Heels" + label_max="Pointy Heels" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color=" 0, 0, 0, 255" /> - - <value - color="255, 0, 255, 255" /> - - <value - color="255, 0, 0, 255" /> - - <value - color="255, 255, 0, 255" /> - - <value - color=" 0, 255, 0, 255" /> - - <value - color=" 0, 255, 255, 255" /> - - <value - color=" 0, 0, 255, 255" /> - - <value - color="255, 0, 255, 255" /> - </param_color> + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> </param> - </global_color> - <!-- =========================================================== --> - <global_color - name="eye_color"> <param - id="99" - group="0" - wearable="eyes" - edit_group="eyes" - edit_group_order="1" - name="Eye Color" - show_simple="true" - label_min="Natural" - label_max="Unnatural" + id="510" + group="1" + name="Shoe_Heel_Thick" + label="Heel Shape" + wearable="shoes" + edit_group="shoes" + label_min="default Heels" + label_max="Thick Heels" value_min="0" value_max="1" - value_default="0" - camera_elevation=".1" - camera_distance=".3"> - <!-- default to natural brown eyes--> - <param_color> - <value - color="50, 25, 5, 255" /> + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> + </param> - <!-- natural dark brown eyes--> - <value - color="109, 55, 15, 255" /> - - <!-- natural brown eyes--> - <value - color="150, 93, 49, 255" /> - - <!-- natural light brown eyes--> - <value - color="152, 118, 25, 255" /> - - <!--natural hazel eyes--> - <value - color="95, 179, 107, 255" /> - - <!--natural green eyes--> - <value - color="87, 192, 191, 255" /> - - <!--natural aqua eyes--> - <value - color="95, 172, 179, 255" /> - - <!--natural blue eyes--> - <value - color="128, 128, 128, 255" /> - - <!--natural grey eyes--> - <value - color="0, 0, 0, 255" /> - - <!--black eyes--> - <value - color="255, 255, 0, 255" /> - - <!--bright yellow eyes--> - <value - color=" 0, 255, 0, 255" /> - - <!-- bright green eyes--> - <value - color=" 0, 255, 255, 255" /> + <param + id="511" + group="1" + name="Shoe_Toe_Point" + label="Toe Shape" + wearable="shoes" + edit_group="shoes" + label_min="Default Toe" + label_max="Pointy Toe" + value_min="0" + value_max="1" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> + </param> - <!-- bright cyan eyes--> - <value - color=" 0, 0, 255, 255" /> + <param + id="512" + group="1" + name="Shoe_Toe_Square" + label="Toe Shape" + wearable="shoes" + edit_group="shoes" + label_min="Default Toe" + label_max="Square Toe" + value_min="0" + value_max="1" + camera_distance="1.5" + camera_elevation="-.5"> + <param_morph /> + </param> - <!--bright blue eyes--> - <value - color="255, 0, 255, 255" /> + <param + id="654" + group="0" + name="Shoe_Toe_Thick" + label="Toe Thickness" + wearable="shoes" + edit_group="shoes" + edit_group_order="5" + label_min="Flat Toe" + label_max="Thick Toe" + value_min="0" + value_max="2" + camera_angle="15" + camera_distance="1.5" + camera_elevation="-1"> + <param_morph /> + </param> - <!-- bright violet eyes--> - <value - color="255, 0, 0, 255" /> + <param + id="515" + group="0" + name="Foot_Size" + label="Foot Size" + wearable="shape" + edit_group="shape_legs" + edit_group_order="6" + label_min="Small" + label_max="Big" + value_min="-1" + value_max="3" + camera_angle="45" + camera_distance="1.1" + camera_elevation="-1"> + <param_morph> + <volume_morph + name="L_FOOT" + scale="0.02 0.01 0.0" + pos="0.01 0 0"/> + <volume_morph + name="R_FOOT" + scale="0.02 0.01 0.0" + pos="0.01 0 0"/> + </param_morph> + </param> - <!--bright red eyes--> - </param_color> + <param + id="516" + group="1" + name="Displace_Loose_Lowerbody" + label="Pants Fit" + wearable="pants" + edit_group="driven" + clothing_morph="true" + value_min="0" + value_max="1" + value_default="0"> + <param_morph /> </param> <param - id="98" + id="625" group="0" - wearable="eyes" - edit_group="eyes" - edit_group_order="2" - name="Eye Lightness" + name="Leg_Pantflair" + label="Cuff Flare" show_simple="true" - label_min="Darker" - label_max="Lighter" + wearable="pants" + edit_group="pants" + edit_group_order="3" + clothing_morph="true" + label_min="Tight Cuffs" + label_max="Flared Cuffs" value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".3"> - <param_color> - <value - color="0, 0, 0, 0" /> + value_max="1.5" + camera_distance="1.8" + camera_angle="30" + camera_elevation="-.3"> + <param_morph /> + </param> - <value - color="255, 255, 255, 255" /> - </param_color> + <param + id="793" + group="1" + name="Leg_Longcuffs" + label="Longcuffs" + wearable="pants" + edit_group="driven" + clothing_morph="true" + value_min="0" + value_max="3" + value_default="0"> + <param_morph /> </param> - </global_color> - <!-- =========================================================== --> - <layer_set - body_region="hair" - width="512" - height="512" - clear_alpha="false"> - <layer - name="base" - global_color="hair_color" - write_all_channels="true"> - <texture - local_texture="hair_grain" /> - </layer> + <param + id="638" + group="0" + name="Low_Crotch" + label="Pants Crotch" + wearable="pants" + clothing_morph="true" + edit_group="pants" + edit_group_order="4" + label_min="High and Tight" + label_max="Low and Loose" + value_min="0" + value_max="1.3" + camera_distance="1.2" + camera_angle="-20" + camera_elevation="-.3"> + <param_morph /> + </param> - <layer - name="hair texture alpha layer" - visibility_mask="TRUE"> - <texture - local_texture="hair_grain" /> - </layer> + <param + id="635" + group="1" + name="Fat_Legs" + label="Fat Torso" + wearable="shape" + edit_group="shape_body" + label_min="skinny" + label_max="fat" + value_min="0" + value_max="1"> + <param_morph> + <volume_morph + name="PELVIS" + scale="0.03 0.06 0.0"/> + <volume_morph + name="R_UPPER_LEG" + scale="0.02 0.02 0.0" + pos="0.0 -0.02 0.0"/> + <volume_morph + name="R_LOWER_LEG" + scale="0.01 0.01 0.0"/> + <volume_morph + name="L_UPPER_LEG" + scale="0.02 0.02 0.0" + pos="0.0 0.02 0.0"/> + <volume_morph + name="L_LOWER_LEG" + scale="0.01 0.01 0.0"/> + </param_morph> + </param> - <layer - name="hair alpha" - visibility_mask="TRUE"> - <texture - local_texture="hair_alpha" /> - </layer> - - </layer_set> - <!-- =========================================================== --> + <param + id="854" + group="1" + name="Saddlebags" + wearable="shape" + edit_group="driven" + value_min="-.5" + value_max="3"> + <param_morph> + <volume_morph + name="PELVIS" + scale="0.0 0.025 0.0"/> + </param_morph> - <layer_set - body_region="head" - width="512" - height="512"> - <layer - name="head bump base" - fixed_color = "128,128,128,255" - render_pass="bump"> - </layer> + </param> - <layer - name="head bump definition" - render_pass="bump"> - + <param + id="20879" + group="1" + sex="male" + name="Male_Package" + value_min="-.5" + value_max="2"> + <param_morph /> + </param> - <texture - tga_file="bump_head_base.tga" - file_is_mask="FALSE"/> + <!-- + ############# + # other morphs (not user controlled) + ############# + --> + <param + id="153" + group="1" + name="Male_Legs" + wearable="shape" + edit_group="driven" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="873" - group="1" - wearable="skin" - edit_group="driven" - edit_group_order="12" - name="Bump base" - value_min="0" - value_max="1"> - <param_alpha - domain="0" /> - </param> - </layer> + <!-- + ############# + # physics morphs (not user controlled) + ############# + --> + <param + id="1202" + group="1" + name="Belly_Physics_Legs_UpDown_Driven" + wearable="physics" + cross_wearable="true" + edit_group="driven" + value_min="-1" + value_max="1"> + <param_morph /> + </param> - <layer - name="base" - global_color="skin_color"> - <texture - tga_file="head_skingrain.tga" /> - </layer> + + <param + id="1205" + group="1" + name="Butt_Physics_UpDown_Driven" + wearable="physics" + cross_wearable="true" + edit_group="driven" + value_default="0" + value_min="-1" + value_max="1"> + <param_morph> + <volume_morph + name="BUTT" + pos="0.0 0.0 0.05"/> + </param_morph> + </param> - <layer - name="headcolor"> - <texture - tga_file="head_color.tga" /> - </layer> + <param + id="1206" + group="1" + name="Butt_Physics_LeftRight_Driven" + wearable="physics" + cross_wearable="true" + edit_group="driven" + value_default="0" + value_min="-1" + value_max="1"> + <param_morph> + <volume_morph + name="BUTT" + pos="0.0 0.05 0.0"/> + </param_morph> + </param> - <layer - name="shadow"> - <texture - tga_file="head_shading_alpha.tga" - file_is_mask="TRUE" /> + <!-- + #end morph targets + --> - <param - id="158" - group="1" - wearable="skin" - name="Shading" - value_min="0" - value_max="1"> - <param_color> - <value - color="0, 0, 0, 0" /> + </mesh> - <value - color="0, 0, 0, 128" /> - </param_color> - </param> - </layer> + <mesh + type="lowerBodyMesh" + lod="1" + file_name="avatar_lower_body_1.llm" + min_pixel_width="160" + reference="avatar_lower_body.llm"> + </mesh> - <layer - name="highlight"> - <texture - tga_file="head_highlights_alpha.tga" -file_is_mask="TRUE" /> + <mesh + type="lowerBodyMesh" + lod="2" + file_name="avatar_lower_body_2.llm" + min_pixel_width="80" + reference="avatar_lower_body.llm"> + </mesh> + <mesh + type="lowerBodyMesh" + lod="3" + file_name="avatar_lower_body_3.llm" + min_pixel_width="40" + reference="avatar_lower_body.llm"> + </mesh> - <param - id="159" - group="1" - name="Shading" - wearable="skin" - value_min="0" - value_max="1"> - <param_color> - <value -color="255, 255, 255, 0" /> + <mesh + type="lowerBodyMesh" + lod="4" + file_name="avatar_lower_body_4.llm" + min_pixel_width="0" + reference="avatar_lower_body.llm"> + </mesh> + <!-- + #lowerBodyMesh2 = + #lowerBodyMesh3 = + --> + <!-- + #eyeLidLeftMesh = + --> + <mesh + type="eyeBallLeftMesh" + lod="0" + file_name="avatar_eye.llm" + min_pixel_width="320"> + <!-- begin morph_params --> + <param + id="679" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> - <value - color="255, 255, 255, 64" /> - </param_color> - </param> - </layer> - <layer - name="rosyface"> - <texture - tga_file="rosyface_alpha.tga" - file_is_mask="true" /> + <param + id="687" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> - <param - id="116" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="4" - name="Rosy Complexion" - label_min="Less Rosy" - label_max="More Rosy" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".07"> - <param_color> - <value - color="198, 71, 71, 0" /> - - <value - color="198, 71, 71, 255" /> - </param_color> - </param> - </layer> + <mesh + type="eyeBallLeftMesh" + lod="1" + file_name="avatar_eye_1.llm" + min_pixel_width="80"> + <!-- begin morph_params --> + <param + id="694" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> - <layer - name="lips"> - <texture - tga_file="lips_mask.tga" - file_is_mask="true" /> + <param + id="695" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> - <param - id="117" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="5" - name="Lip Pinkness" - label_min="Darker" - label_max="Pinker" - value_min="0" - value_max="1" - camera_distance=".25"> - <param_color> - <value - color="220, 115, 115, 0" /> + <!-- + #eyeLidRightMesh = + --> + <mesh + type="eyeBallRightMesh" + lod="0" + file_name="avatar_eye.llm" + min_pixel_width="320"> + <!-- begin morph_params --> + <param + id="680" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> - <value - color="220, 115, 115, 128" /> - </param_color> - </param> - </layer> + <param + id="688" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> - <layer - name="wrinkles_shading" - render_pass="bump" - fixed_color="0,0,0,100"> - <param - id="118" - group="1" - wearable="skin" - name="Wrinkles" - value_min="0" - value_max="1"> - <param_alpha - tga_file="bump_face_wrinkles.tga" - skip_if_zero="true" - domain="0.3" /> - </param> - </layer> + <mesh + type="eyeBallRightMesh" + lod="1" + file_name="avatar_eye_1.llm" + min_pixel_width="80"> + <!-- begin morph_params --> + <param + id="681" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> - <!--<layer - name="wrinkles_highlights" - fixed_color="255,255,255,64"> - <param - id="128" - group="1" - name="Wrinkles" - value_min="0" - value_max="1"> - <param_alpha - tga_file="head_wrinkles_highlights_alpha.tga" - skip_if_zero="true" - domain="0.3" /> - </param> - </layer>--> - <layer - name="freckles" - fixed_color="120,47,20,128"> - <param - id="165" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="2" - name="Freckles" - label_min="Less" - label_max="More" - value_min="0" - value_max="1" - camera_distance=".3" -camera_elevation=".07"> - <param_alpha - tga_file="freckles_alpha.tga" - skip_if_zero="true" -domain="0.5" /> - </param> - </layer> - <layer -name="eyebrowsbump" -render_pass="bump"> - <texture - tga_file="head_hair.tga" - file_is_mask="false" /> + <param + id="691" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> - <param - id="1000" - group="1" - wearable="hair" - edit_group="driven" - name="Eyebrow Size Bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="eyebrows_alpha.tga" - domain="0.1" /> - </param> + <mesh + type="skirtMesh" + lod="0" + file_name="avatar_skirt.llm" + min_pixel_width="320"> + <param + id="845" + group="1" + name="skirt_poofy" + label="poofy skirt" + clothing_morph="true" + wearable="skirt" + edit_group="skirt" + label_min="less poofy" + label_max="more poofy" + value_min="0" + value_max="1.5"> + <param_morph /> + </param> - <param - id="1002" - group="1" - wearable="hair" - edit_group="driven" - name="Eyebrow Density Bump" - value_min="0" - value_max="1"> - <param_color> - <value - color="255,255,255,0" /> + <param + id="846" + group="1" + name="skirt_loose" + label="loose skirt" + clothing_morph="true" + wearable="skirt" + edit_group="skirt" + label_min="form fitting" + label_max="loose" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <value - color="255,255,255,255" /> - </param_color> - </param> - </layer> - - <layer - name="eyebrows" - global_color="hair_color"> - <texture - tga_file="head_hair.tga" - file_is_mask="false" /> + <param + id="866" + group="1" + name="skirt_tight" + label="tight skirt" + clothing_morph="true" + wearable="skirt" + edit_group="skirt" + label_min="form fitting" + label_max="loose" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="1001" - group="1" - wearable="hair" - edit_group="hair_eyebrows" - name="Eyebrow Size" - show_simple="true" - value_min="0" - value_max="1" - value_default="0.5"> - <param_alpha - tga_file="eyebrows_alpha.tga" - domain="0.1" /> - </param> + <param + id="867" + group="1" + name="skirt_smallbutt" + label="tight skirt" + clothing_morph="false" + wearable="skirt" + edit_group="skirt" + cross_wearable="true" + label_min="form fitting" + label_max="loose" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="1003" - group="1" - wearable="hair" - edit_group="driven" - name="Eyebrow Density" - value_min="0" - value_max="1"> - <param_color - operation="multiply"> - <value - color="255,255,255,0" /> + <param + id="848" + group="0" + name="skirt_bustle" + label="bustle skirt" + clothing_morph="true" + wearable="skirt" + edit_group_order="3" + edit_group="skirt" + label_min="no bustle" + label_max="more bustle" + value_min="0" + value_max="2" + value_default=".2" + camera_angle="100" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> + </param> - <value - color="255,255,255,255" /> - </param_color> - </param> - </layer> + <param + id="847" + group="1" + name="skirt_bowlegs" + label="legs skirt" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + value_min="-1" + value_max="1" + value_default="0"> + <param_morph /> + </param> - <layer - name="lipstick"> - <param - id="700" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="2" - name="Lipstick Color" - label_min="Pink" - label_max="Black" - value_min="0" - value_max="1" - value_default=".25" - camera_distance=".25"> - <param_color> - <value - color="245,161,177,200" /> + <param + id="852" + group="1" + name="skirt_bigbutt" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label="bigbutt skirt" + label_min="less" + label_max="more" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <value - color="216,37,67,200" /> + <param + id="849" + group="1" + name="skirt_belly" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label="big belly skirt" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <value - color="178,48,76,200" /> + <param + id="850" + group="1" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + name="skirt_saddlebags" + value_min="-.5" + value_max="3"> + <param_morph /> + </param> - <value - color="68,0,11,200" /> + <param + id="851" + group="1" + name="skirt_chubby" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label_min="less" + label_max="more" + value_min="0" + value_max="1" + value_default="0"> + <param_morph /> + </param> - <value - color="252,207,184,200" /> + <param + id="856" + group="1" + name="skirt_lovehandles" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label_min="less" + label_max="more" + value_min="-1" + value_max="2" + value_default="0"> + <param_morph /> + </param> - <value - color="241,136,106,200" /> + <!-- + ############# + # other morphs (not user controlled) + ############# + --> + <param + id="857" + group="1" + name="skirt_male" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <value - color="208,110,85,200" /> + <!-- + ############# + # physics morphs (not user controlled) + ############# + --> + <param + id="1203" + group="1" + name="Belly_Physics_Skirt_UpDown_Driven" + wearable="physics" + cross_wearable="true" + edit_group="driven" + value_default="0" + value_min="-1" + value_max="1"> + <param_morph /> + </param> - <value - color="106,28,18,200" /> + </mesh> - <value - color="58,26,49,200" /> + <mesh + type="skirtMesh" + lod="1" + file_name="avatar_skirt_1.llm" + min_pixel_width="160" + reference="avatar_skirt.llm"> + </mesh> - <value - color="14,14,14,200" /> - </param_color> - </param> + <mesh + type="skirtMesh" + lod="2" + file_name="avatar_skirt_2.llm" + min_pixel_width="80" + reference="avatar_skirt.llm"> + </mesh> - <param - id="701" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="1" - name="Lipstick" - label_min="No Lipstick" - label_max="More Lipstick" - value_min="0" - value_max=".9" - value_default="0.0" - camera_distance=".25"> - <param_alpha - tga_file="lipstick_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - </layer> - - <layer - name="lipgloss" - fixed_color="255,255,255,190"> - <param - id="702" - name="Lipgloss" - label_min="No Lipgloss" - label_max="Glossy" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="3" - group="0" - value_min="0" - value_max="1" - camera_distance=".25"> - <param_alpha - tga_file="lipgloss_alpha.tga" - skip_if_zero="true" - domain="0.2" /> - </param> - </layer> + <mesh + type="skirtMesh" + lod="3" + file_name="avatar_skirt_3.llm" + min_pixel_width="40" + reference="avatar_skirt.llm"> + </mesh> - <layer - name="blush"> - <param - id="704" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="4" - name="Blush" - label_min="No Blush" - label_max="More Blush" - value_min="0" - value_max=".9" - value_default="0" - camera_distance=".3" - camera_elevation=".07" - camera_angle="20"> - <param_alpha - tga_file="blush_alpha.tga" - skip_if_zero="true" - domain="0.3" /> - </param> + <mesh + type="skirtMesh" + lod="4" + file_name="avatar_skirt_4.llm" + min_pixel_width="0" + reference="avatar_skirt.llm"> + </mesh> - <param - id="705" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="5" - name="Blush Color" - label_min="Pink" - label_max="Orange" - value_min="0" - value_max="1" - value_default=".5" - camera_distance=".3" - camera_elevation=".07" - camera_angle="20"> - <param_color> - <value - color="253,162,193,200" /> + <!-- =========================================================== --> + <global_color + name="skin_color"> + <param + id="111" + group="0" + wearable="skin" + edit_group="skin_color" + edit_group_order="1" + name="Pigment" + show_simple="true" + label_min="Light" + label_max="Dark" + value_min="0" + value_max="1" + value_default=".5"> + <param_color> + <value + color="252, 215, 200, 255" /> - <value - color="247,131,152,200" /> + <value + color="240, 177, 112, 255" /> - <value - color="213,122,140,200" /> + <value + color="90, 40, 16, 255" /> - <value - color="253,152,144,200" /> + <value + color="29, 9, 6, 255" /> + </param_color> + </param> - <value - color="236,138,103,200" /> + <param + id="110" + group="0" + wearable="skin" + edit_group="skin_color" + edit_group_order="2" + name="Red Skin" + label="Ruddiness" + label_min="Pale" + label_max="Ruddy" + value_min="0" + value_max="0.1"> + <param_color + operation="blend"> + <value + color="218, 41, 37, 255" /> + </param_color> + </param> - <value - color="195,128,122,200" /> + <param + id="108" + group="0" + wearable="skin" + edit_group="skin_color" + edit_group_order="3" + name="Rainbow Color" + show_simple="true" + label_min="None" + label_max="Wild" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color=" 0, 0, 0, 255" /> - <value - color="148,103,100,200" /> + <value + color="255, 0, 255, 255" /> - <value - color="168,95,62,200" /> - </param_color> - </param> + <value + color="255, 0, 0, 255" /> - <param - id="711" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="6" - name="Blush Opacity" - label_min="Clear" - label_max="Opaque" - value_min="0" - value_max="1" - value_default=".5" - camera_distance=".3" - camera_elevation=".07" - camera_angle="20"> - <param_color - operation="multiply"> - <value - color="255,255,255,0" /> + <value + color="255, 255, 0, 255" /> - <value - color="255,255,255,255" /> - </param_color> - </param> - </layer> + <value + color=" 0, 255, 0, 255" /> - <layer - name="Outer Eye Shadow"> - <param - id="708" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="11" - name="Out Shdw Color" - label_min="Light" - label_max="Dark" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".14"> - <param_color> - <value - color="252,247,246,255" /> + <value + color=" 0, 255, 255, 255" /> - <value - color="255,206,206,255" /> + <value + color=" 0, 0, 255, 255" /> - <value - color="233,135,149,255" /> + <value + color="255, 0, 255, 255" /> + </param_color> + </param> + </global_color> - <value - color="220,168,192,255" /> + <!-- =========================================================== --> + <global_color + name="hair_color"> + <param + id="114" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="3" + name="Blonde Hair" + show_simple="true" + label_min="Black" + label_max="Blonde" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color="0, 0, 0, 255" /> - <value - color="228,203,232,255" /> + <value + color="22, 6, 6, 255" /> - <value - color="255,234,195,255" /> + <value + color="29, 9, 6, 255" /> - <value - color="230,157,101,255" /> + <value + color="45, 21, 11, 255" /> - <value - color="255,147,86,255" /> + <value + color="78, 39, 11, 255" /> - <value - color="228,110,89,255" /> + <value + color="90, 53, 16, 255" /> - <value - color="228,150,120,255" /> + <value + color="136, 92, 21, 255" /> - <value - color="223,227,213,255" /> + <value + color="150, 106, 33, 255" /> - <value - color="96,116,87,255" /> + <value + color="198, 156, 74, 255" /> - <value - color="88,143,107,255" /> + <value + color="233, 192, 103, 255" /> - <value - color="194,231,223,255" /> + <value + color="238, 205, 136, 255" /> + </param_color> + </param> - <value - color="207,227,234,255" /> + <param + id="113" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="4" + name="Red Hair" + show_simple="true" + label_min="No Red" + label_max="Very Red" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color="0, 0, 0, 255" /> - <value - color="41,171,212,255" /> + <value + color="118, 47, 19, 255" /> + </param_color> + </param> - <value - color="180,137,130,255" /> + <param + id="115" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="1" + name="White Hair" + show_simple="true" + label_min="No White" + label_max="All White" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color="0, 0, 0, 255" /> - <value - color="173,125,105,255" /> + <value + color="255, 255, 255, 255" /> + </param_color> + </param> - <value - color="144,95,98,255" /> + <param + id="112" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="2" + name="Rainbow Color" + show_simple="true" + label_min="None" + label_max="Wild" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color=" 0, 0, 0, 255" /> - <value - color="115,70,77,255" /> + <value + color="255, 0, 255, 255" /> - <value - color="155,78,47,255" /> + <value + color="255, 0, 0, 255" /> - <value - color="239,239,239,255" /> + <value + color="255, 255, 0, 255" /> - <value - color="194,194,194,255" /> + <value + color=" 0, 255, 0, 255" /> - <value - color="120,120,120,255" /> + <value + color=" 0, 255, 255, 255" /> - <value - color="10,10,10,255" /> - </param_color> - </param> + <value + color=" 0, 0, 255, 255" /> - <param - id="706" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="12" - name="Out Shdw Opacity" - label_min="Clear" - label_max="Opaque" - value_min=".2" - value_max="1" - value_default=".6" - camera_distance=".3" - camera_elevation=".14"> - <param_color - operation="multiply"> - <value - color="255,255,255,0" /> + <value + color="255, 0, 255, 255" /> + </param_color> + </param> + </global_color> - <value - color="255,255,255,255" /> - </param_color> - </param> + <!-- =========================================================== --> + <global_color + name="eye_color"> + <param + id="99" + group="0" + wearable="eyes" + edit_group="eyes" + edit_group_order="1" + name="Eye Color" + show_simple="true" + label_min="Natural" + label_max="Unnatural" + value_min="0" + value_max="1" + value_default="0" + camera_elevation=".1" + camera_distance=".3"> + <!-- default to natural brown eyes--> + <param_color> + <value + color="50, 25, 5, 255" /> - <param - id="707" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="10" - name="Outer Shadow" - label_min="No Eyeshadow" - label_max="More Eyeshadow" - value_min="0" - value_max=".7" - camera_distance=".3" - camera_elevation=".14"> - <param_alpha - tga_file="eyeshadow_outer_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - </layer> + <!-- natural dark brown eyes--> + <value + color="109, 55, 15, 255" /> - <layer - name="Inner Eye Shadow"> - <param - id="712" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="8" - name="In Shdw Color" - label_min="Light" - label_max="Dark" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".14"> - <param_color> - <value - color="252,247,246,255" /> + <!-- natural brown eyes--> + <value + color="150, 93, 49, 255" /> - <value - color="255,206,206,255" /> + <!-- natural light brown eyes--> + <value + color="152, 118, 25, 255" /> - <value - color="233,135,149,255" /> + <!--natural hazel eyes--> + <value + color="95, 179, 107, 255" /> - <value - color="220,168,192,255" /> + <!--natural green eyes--> + <value + color="87, 192, 191, 255" /> - <value - color="228,203,232,255" /> + <!--natural aqua eyes--> + <value + color="95, 172, 179, 255" /> - <value - color="255,234,195,255" /> + <!--natural blue eyes--> + <value + color="128, 128, 128, 255" /> - <value - color="230,157,101,255" /> + <!--natural grey eyes--> + <value + color="0, 0, 0, 255" /> - <value - color="255,147,86,255" /> + <!--black eyes--> + <value + color="255, 255, 0, 255" /> - <value - color="228,110,89,255" /> + <!--bright yellow eyes--> + <value + color=" 0, 255, 0, 255" /> - <value - color="228,150,120,255" /> + <!-- bright green eyes--> + <value + color=" 0, 255, 255, 255" /> - <value - color="223,227,213,255" /> + <!-- bright cyan eyes--> + <value + color=" 0, 0, 255, 255" /> - <value - color="96,116,87,255" /> + <!--bright blue eyes--> + <value + color="255, 0, 255, 255" /> - <value - color="88,143,107,255" /> + <!-- bright violet eyes--> + <value + color="255, 0, 0, 255" /> - <value - color="194,231,223,255" /> + <!--bright red eyes--> + </param_color> + </param> - <value - color="207,227,234,255" /> + <param + id="98" + group="0" + wearable="eyes" + edit_group="eyes" + edit_group_order="2" + name="Eye Lightness" + show_simple="true" + label_min="Darker" + label_max="Lighter" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".3"> + <param_color> + <value + color="0, 0, 0, 0" /> - <value - color="41,171,212,255" /> + <value + color="255, 255, 255, 255" /> + </param_color> + </param> + </global_color> - <value - color="180,137,130,255" /> + <!-- =========================================================== --> + <layer_set + body_region="hair" + width="512" + height="512" + clear_alpha="false"> + <layer + name="base" + global_color="hair_color" + write_all_channels="true"> + <texture + local_texture="hair_grain" /> + </layer> - <value - color="173,125,105,255" /> + <layer + name="hair texture alpha layer" + visibility_mask="TRUE"> + <texture + local_texture="hair_grain" /> + </layer> - <value - color="144,95,98,255" /> + <layer + name="hair alpha" + visibility_mask="TRUE"> + <texture + local_texture="hair_alpha" /> + </layer> - <value - color="115,70,77,255" /> + </layer_set> + <!-- =========================================================== --> - <value - color="155,78,47,255" /> + <layer_set + body_region="head" + width="512" + height="512"> + <layer + name="head bump base" + fixed_color = "128,128,128,255" + render_pass="bump"> + </layer> + + <layer + name="head bump definition" + render_pass="bump"> + + + <texture + tga_file="bump_head_base.tga" + file_is_mask="FALSE"/> + + <param + id="873" + group="1" + wearable="skin" + edit_group="driven" + edit_group_order="12" + name="Bump base" + value_min="0" + value_max="1"> + <param_alpha + domain="0" /> + </param> + </layer> + + <layer + name="base" + global_color="skin_color"> + <texture + tga_file="head_skingrain.tga" /> + </layer> + + <layer + name="headcolor"> + <texture + tga_file="head_color.tga" /> + </layer> + + <layer + name="shadow"> + <texture + tga_file="head_shading_alpha.tga" + file_is_mask="TRUE" /> + <param + id="158" + group="1" + wearable="skin" + name="Shading" + value_min="0" + value_max="1"> + <param_color> <value - color="239,239,239,255" /> + color="0, 0, 0, 0" /> <value - color="194,194,194,255" /> + color="0, 0, 0, 128" /> + </param_color> + </param> + </layer> + + <layer + name="highlight"> + <texture + tga_file="head_highlights_alpha.tga" +file_is_mask="TRUE" /> + + <param + id="159" + group="1" + name="Shading" + wearable="skin" + value_min="0" + value_max="1"> + <param_color> <value - color="120,120,120,255" /> +color="255, 255, 255, 0" /> + <value - color="10,10,10,255" /> + color="255, 255, 255, 64" /> </param_color> </param> + </layer> + <layer + name="rosyface"> + <texture + tga_file="rosyface_alpha.tga" + file_is_mask="true" /> <param - id="713" + id="116" group="0" wearable="skin" - edit_group="skin_makeup" - edit_group_order="9" - name="In Shdw Opacity" - label_min="Clear" - label_max="Opaque" - value_min=".2" + edit_group="skin_facedetail" + edit_group_order="4" + name="Rosy Complexion" + label_min="Less Rosy" + label_max="More Rosy" + value_min="0" value_max="1" - value_default=".7" camera_distance=".3" - camera_elevation=".14"> - <param_color - operation="multiply"> + camera_elevation=".07"> + <param_color> <value - color="255,255,255,0" /> + color="198, 71, 71, 0" /> <value - color="255,255,255,255" /> + color="198, 71, 71, 255" /> </param_color> </param> + </layer> + + <layer + name="lips"> + <texture + tga_file="lips_mask.tga" + file_is_mask="true" /> <param - id="709" + id="117" group="0" wearable="skin" - edit_group="skin_makeup" - edit_group_order="7" - name="Inner Shadow" - label_min="No Eyeshadow" - label_max="More Eyeshadow" + edit_group="skin_facedetail" + edit_group_order="5" + name="Lip Pinkness" + label_min="Darker" + label_max="Pinker" value_min="0" value_max="1" - value_default="0" - camera_distance=".3" - camera_elevation=".14"> - <param_alpha - tga_file="eyeshadow_inner_alpha.tga" - skip_if_zero="true" - domain="0.2" /> + camera_distance=".25"> + <param_color> + <value + color="220, 115, 115, 0" /> + + <value + color="220, 115, 115, 128" /> + </param_color> </param> </layer> <layer - name="eyeliner" - fixed_color="0,0,0,200"> + name="wrinkles_shading" + render_pass="bump" + fixed_color="0,0,0,100"> <param - id="703" - group="0" + id="118" + group="1" wearable="skin" - edit_group="skin_makeup" - edit_group_order="13" - name="Eyeliner" - label_min="No Eyeliner" - label_max="Full Eyeliner" + name="Wrinkles" value_min="0" - value_max="1" - value_default="0.0" - camera_distance=".3" - camera_elevation=".14"> + value_max="1"> <param_alpha - tga_file="eyeliner_alpha.tga" + tga_file="bump_face_wrinkles.tga" skip_if_zero="true" - domain="0.1" /> + domain="0.3" /> </param> + </layer> + <!--<layer + name="wrinkles_highlights" + fixed_color="255,255,255,64"> + <param + id="128" + group="1" + name="Wrinkles" + value_min="0" + value_max="1"> + <param_alpha + tga_file="head_wrinkles_highlights_alpha.tga" + skip_if_zero="true" + domain="0.3" /> + </param> + </layer>--> + <layer + name="freckles" + fixed_color="120,47,20,128"> <param - id="714" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="14" - name="Eyeliner Color" - label_min="Dark Green" - label_max="Black" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".14"> - <param_color> - <value - color="24,98,40,250" /> - - <!-- dark green --> - <value - color="9,100,127,250" /> - - <!-- lt.aqua blue --> - <value - color="61,93,134,250" /> - - <!-- aqua --> - <value - color="70,29,27,250" /> - - <!-- dark brown --> - <value - color="115,75,65,250" /> - - <!-- lt. brown blue --> - <value - color="100,100,100,250" /> - - <!-- grey --> - <value - color="91,80,74,250" /> - - <!-- grey/brown --> - <value - color="112,42,76,250" /> - - <!-- plum --> - <value - color="14,14,14,250" /> - - <!-- black --> - </param_color> + id="165" + group="0" + wearable="skin" + edit_group="skin_facedetail" + edit_group_order="2" + name="Freckles" + label_min="Less" + label_max="More" + value_min="0" + value_max="1" + camera_distance=".3" +camera_elevation=".07"> + <param_alpha + tga_file="freckles_alpha.tga" + skip_if_zero="true" +domain="0.5" /> </param> </layer> - <layer - name="facialhair bump" - render_pass="bump"> +name="eyebrowsbump" +render_pass="bump"> <texture tga_file="head_hair.tga" file_is_mask="false" /> <param - id="1004" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Sideburns bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_sideburns_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1006" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Moustache bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_moustache_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1008" - sex="male" + id="1000" group="1" wearable="hair" edit_group="driven" - name="Soulpatch bump" + name="Eyebrow Size Bump" value_min="0" value_max="1"> <param_alpha - tga_file="facehair_soulpatch_alpha.tga" - skip_if_zero="true" + tga_file="eyebrows_alpha.tga" domain="0.1" /> </param> <param - id="1010" - sex="male" - group="1" - edit_group="driven" - wearable="hair" - name="Chin Curtains bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_chincurtains_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> - - <param - id="1012" + id="1002" group="1" - sex="male" wearable="hair" edit_group="driven" - name="5 O'Clock Shadow bump" + name="Eyebrow Density Bump" value_min="0" value_max="1"> <param_color> <value - color="255,255,255,255" /> + color="255,255,255,0" /> <value - color="255,255,255,0" /> + color="255,255,255,255" /> </param_color> </param> </layer> <layer - name="facialhair" + name="eyebrows" global_color="hair_color"> - <texture tga_file="head_hair.tga" file_is_mask="false" /> <param - id="1005" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Sideburns" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_sideburns_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1007" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Moustache" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_moustache_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1009" - sex="male" + id="1001" group="1" wearable="hair" - edit_group="driven" - name="Soulpatch" + edit_group="hair_eyebrows" + name="Eyebrow Size" + show_simple="true" value_min="0" - value_max="1"> + value_max="1" + value_default="0.5"> <param_alpha - tga_file="facehair_soulpatch_alpha.tga" - skip_if_zero="true" + tga_file="eyebrows_alpha.tga" domain="0.1" /> </param> <param - id="1011" - sex="male" + id="1003" group="1" wearable="hair" edit_group="driven" - name="Chin Curtains" + name="Eyebrow Density" value_min="0" value_max="1"> - <param_alpha - tga_file="facehair_chincurtains_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> - - <param - id="751" - group="1" - wearable="hair" - sex="male" - edit_group="hair_facial" - name="5 O'Clock Shadow" - label_min="Dense hair" - label_max="Shadow hair" - value_min="0" - value_max="1" - value_default="0.7" - camera_elevation=".1" - camera_distance=".3"> <param_color operation="multiply"> <value - color="255,255,255,255" /> + color="255,255,255,0" /> <value - color="255,255,255,30" /> + color="255,255,255,255" /> </param_color> </param> </layer> <layer - name="head_bodypaint"> - <texture - local_texture="head_bodypaint" /> - </layer> - <layer - name="eyelash alpha" - visibility_mask="TRUE"> - <texture - tga_file="head_alpha.tga" - file_is_mask="TRUE" /> - </layer> - <layer - name="head alpha" - visibility_mask="TRUE"> - <texture - local_texture="head_alpha" /> - </layer> - <layer - name="head_tattoo"> - <texture - local_texture="head_tattoo" /> + name="lipstick"> <param - id="1062" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_head_red" + id="700" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="2" + name="Lipstick Color" + label_min="Pink" + label_max="Black" value_min="0" value_max="1" - value_default="1"> + value_default=".25" + camera_distance=".25"> <param_color> <value - color="0, 0, 0, 255" /> + color="245,161,177,200" /> <value - color="255, 0, 0, 255" /> - </param_color> - </param> + color="216,37,67,200" /> - <param - id="1063" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_head_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="178,48,76,200" /> <value - color="0, 255, 0, 255" /> - </param_color> - </param> + color="68,0,11,200" /> - <param - id="1064" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_head_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="252,207,184,200" /> <value - color="0, 0, 255, 255" /> - </param_color> - </param> + color="241,136,106,200" /> - </layer> + <value + color="208,110,85,200" /> + <value + color="106,28,18,200" /> - </layer_set> + <value + color="58,26,49,200" /> - <!-- =========================================================== --> - <layer_set - body_region="upper_body" - width="512" - height="512"> - <layer - name="base_upperbody bump" - render_pass="bump" - fixed_color="128,128,128,255"> - </layer> - <layer - name="upperbody bump definition" - render_pass="bump"> - <texture - tga_file="bump_upperbody_base.tga" - file_is_mask="FALSE"/> + <value + color="14,14,14,200" /> + </param_color> + </param> <param - id="874" - group="1" + id="701" + group="0" wearable="skin" - edit_group="driven" - edit_group_order="20" - name="Bump upperdef" + edit_group="skin_makeup" + edit_group_order="1" + name="Lipstick" + label_min="No Lipstick" + label_max="More Lipstick" value_min="0" - value_max="1"> + value_max=".9" + value_default="0.0" + camera_distance=".25"> <param_alpha - domain="0" /> + tga_file="lipstick_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> </layer> <layer - name="base" - global_color="skin_color"> - <texture - tga_file="body_skingrain.tga" /> - </layer> - - <layer - name="nipples"> - <texture - tga_file="upperbody_color.tga" /> + name="lipgloss" + fixed_color="255,255,255,190"> + <param + id="702" + name="Lipgloss" + label_min="No Lipgloss" + label_max="Glossy" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="3" + group="0" + value_min="0" + value_max="1" + camera_distance=".25"> + <param_alpha + tga_file="lipgloss_alpha.tga" + skip_if_zero="true" + domain="0.2" /> + </param> </layer> <layer - name="shadow"> - <texture - tga_file="upperbody_shading_alpha.tga" - file_is_mask="TRUE" /> + name="blush"> + <param + id="704" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="4" + name="Blush" + label_min="No Blush" + label_max="More Blush" + value_min="0" + value_max=".9" + value_default="0" + camera_distance=".3" + camera_elevation=".07" + camera_angle="20"> + <param_alpha + tga_file="blush_alpha.tga" + skip_if_zero="true" + domain="0.3" /> + </param> <param - id="125" - group="1" - name="Shading" + id="705" + group="0" wearable="skin" + edit_group="skin_makeup" + edit_group_order="5" + name="Blush Color" + label_min="Pink" + label_max="Orange" value_min="0" - value_max="1"> + value_max="1" + value_default=".5" + camera_distance=".3" + camera_elevation=".07" + camera_angle="20"> <param_color> <value - color="0, 0, 0, 0" /> + color="253,162,193,200" /> <value - color="0, 0, 0, 128" /> + color="247,131,152,200" /> + + <value + color="213,122,140,200" /> + + <value + color="253,152,144,200" /> + + <value + color="236,138,103,200" /> + + <value + color="195,128,122,200" /> + + <value + color="148,103,100,200" /> + + <value + color="168,95,62,200" /> </param_color> </param> - </layer> - - <layer - name="highlight"> - <texture - tga_file="upperbody_highlights_alpha.tga" - file_is_mask="TRUE" /> <param - id="126" - group="1" + id="711" + group="0" wearable="skin" - name="Shading" + edit_group="skin_makeup" + edit_group_order="6" + name="Blush Opacity" + label_min="Clear" + label_max="Opaque" value_min="0" - value_max="1"> - <param_color> + value_max="1" + value_default=".5" + camera_distance=".3" + camera_elevation=".07" + camera_angle="20"> + <param_color + operation="multiply"> <value - color="255, 255, 255, 0" /> + color="255,255,255,0" /> <value - color="255, 255, 255, 64" /> + color="255,255,255,255" /> </param_color> </param> </layer> <layer - name="upper_bodypaint"> - <texture - local_texture="upper_bodypaint" /> - </layer> - - <layer - name="freckles upper" - fixed_color="120,47,20,128"> + name="Outer Eye Shadow"> <param - id="776" - group="1" - name="freckles upper" + id="708" + group="0" wearable="skin" - value_min="0" - value_max="1"> - <param_alpha - tga_file="upperbodyfreckles_alpha.tga" - skip_if_zero="true" - domain="0.6" /> - </param> - </layer> - - <layer - name="upper_tattoo"> - <texture - local_texture="upper_tattoo" /> - - <param - id="1065" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_upper_red" + edit_group="skin_makeup" + edit_group_order="11" + name="Out Shdw Color" + label_min="Light" + label_max="Dark" value_min="0" value_max="1" - value_default="1"> + camera_distance=".3" + camera_elevation=".14"> <param_color> <value - color="0, 0, 0, 255" /> + color="252,247,246,255" /> <value - color="255, 0, 0, 255" /> - </param_color> - </param> + color="255,206,206,255" /> - <param - id="1066" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_upper_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="233,135,149,255" /> <value - color="0, 255, 0, 255" /> - </param_color> - </param> + color="220,168,192,255" /> - <param - id="1067" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_upper_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="228,203,232,255" /> <value - color="0, 0, 255, 255" /> - </param_color> - </param> + color="255,234,195,255" /> - </layer> + <value + color="230,157,101,255" /> + <value + color="255,147,86,255" /> - <layer - name="upper_undershirt bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="upper_undershirt" - local_texture_alpha_only="true" /> + <value + color="228,110,89,255" /> - <param - id="1043" - group="1" - wearable="undershirt" - edit_group="driven" - name="Sleeve Length bump" - value_min=".01" - value_max="1" - value_default=".4"> - <param_alpha - tga_file="shirt_sleeve_alpha.tga" - multiply_blend="false" - domain="0.01" /> - </param> + <value + color="228,150,120,255" /> - <param - id="1045" - group="1" - wearable="undershirt" - edit_group="undershirt" - edit_group_order="2" - name="Bottom bump" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_bottom_alpha.tga" - multiply_blend="true" - domain="0.05" /> + <value + color="223,227,213,255" /> + + <value + color="96,116,87,255" /> + + <value + color="88,143,107,255" /> + + <value + color="194,231,223,255" /> + + <value + color="207,227,234,255" /> + + <value + color="41,171,212,255" /> + + <value + color="180,137,130,255" /> + + <value + color="173,125,105,255" /> + + <value + color="144,95,98,255" /> + + <value + color="115,70,77,255" /> + + <value + color="155,78,47,255" /> + + <value + color="239,239,239,255" /> + + <value + color="194,194,194,255" /> + + <value + color="120,120,120,255" /> + + <value + color="10,10,10,255" /> + </param_color> </param> <param - id="1047" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Front bump" - value_min="0" + id="706" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="12" + name="Out Shdw Opacity" + label_min="Clear" + label_max="Opaque" + value_min=".2" value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_collar_alpha.tga" - multiply_blend="true" - domain="0.05" /> + value_default=".6" + camera_distance=".3" + camera_elevation=".14"> + <param_color + operation="multiply"> + <value + color="255,255,255,0" /> + + <value + color="255,255,255,255" /> + </param_color> </param> <param - id="1049" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Back bump" + id="707" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="10" + name="Outer Shadow" + label_min="No Eyeshadow" + label_max="More Eyeshadow" value_min="0" - value_max="1" - value_default=".8"> + value_max=".7" + camera_distance=".3" + camera_elevation=".14"> <param_alpha - tga_file="shirt_collar_back_alpha.tga" - multiply_blend="true" + tga_file="eyeshadow_outer_alpha.tga" + skip_if_zero="true" domain="0.05" /> </param> </layer> <layer - name="upper_undershirt"> - <texture - local_texture="upper_undershirt" /> - + name="Inner Eye Shadow"> <param - id="821" + id="712" group="0" - wearable="undershirt" - edit_group="colorpicker" - name="undershirt_red" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="8" + name="In Shdw Color" + label_min="Light" + label_max="Dark" value_min="0" value_max="1" - value_default="1"> + camera_distance=".3" + camera_elevation=".14"> <param_color> <value - color="0, 0, 0, 255" /> + color="252,247,246,255" /> <value - color="255, 0, 0, 255" /> - </param_color> - </param> + color="255,206,206,255" /> - <param - id="822" - group="0" - wearable="undershirt" - edit_group="colorpicker" - name="undershirt_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="233,135,149,255" /> <value - color="0, 255, 0, 255" /> - </param_color> - </param> + color="220,168,192,255" /> - <param - id="823" - group="0" - wearable="undershirt" - edit_group="colorpicker" - name="undershirt_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> <value - color="0, 0, 0, 255" /> + color="228,203,232,255" /> <value - color="0, 0, 255, 255" /> - </param_color> - </param> + color="255,234,195,255" /> - <param - id="1042" - group="1" - wearable="undershirt" - edit_group="driven" - name="Sleeve Length" - value_min=".01" - value_max="1" - value_default=".4"> - <param_alpha - tga_file="shirt_sleeve_alpha.tga" - multiply_blend="false" - domain="0.01" /> - </param> + <value + color="230,157,101,255" /> - <param - id="1044" - group="1" - wearable="undershirt" - edit_group="driven" - name="Bottom" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_bottom_alpha.tga" - multiply_blend="true" - domain="0.05" /> + <value + color="255,147,86,255" /> + + <value + color="228,110,89,255" /> + + <value + color="228,150,120,255" /> + + <value + color="223,227,213,255" /> + + <value + color="96,116,87,255" /> + + <value + color="88,143,107,255" /> + + <value + color="194,231,223,255" /> + + <value + color="207,227,234,255" /> + + <value + color="41,171,212,255" /> + + <value + color="180,137,130,255" /> + + <value + color="173,125,105,255" /> + + <value + color="144,95,98,255" /> + + <value + color="115,70,77,255" /> + + <value + color="155,78,47,255" /> + + <value + color="239,239,239,255" /> + + <value + color="194,194,194,255" /> + + <value + color="120,120,120,255" /> + + <value + color="10,10,10,255" /> + </param_color> </param> <param - id="1046" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Front" - value_min="0" + id="713" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="9" + name="In Shdw Opacity" + label_min="Clear" + label_max="Opaque" + value_min=".2" value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_collar_alpha.tga" - multiply_blend="true" - domain="0.05" /> + value_default=".7" + camera_distance=".3" + camera_elevation=".14"> + <param_color + operation="multiply"> + <value + color="255,255,255,0" /> + + <value + color="255,255,255,255" /> + </param_color> </param> <param - id="1048" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Back" - label_min="Low" - label_max="High" + id="709" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="7" + name="Inner Shadow" + label_min="No Eyeshadow" + label_max="More Eyeshadow" value_min="0" value_max="1" - value_default=".8"> + value_default="0" + camera_distance=".3" + camera_elevation=".14"> <param_alpha - tga_file="shirt_collar_back_alpha.tga" - multiply_blend="true" - domain="0.05" /> + tga_file="eyeshadow_inner_alpha.tga" + skip_if_zero="true" + domain="0.2" /> </param> </layer> <layer - name="Nail Polish"> + name="eyeliner" + fixed_color="0,0,0,200"> <param - id="710" + id="703" group="0" wearable="skin" edit_group="skin_makeup" - edit_group_order="15" - name="Nail Polish" - label_min="No Polish" - label_max="Painted Nails" + edit_group_order="13" + name="Eyeliner" + label_min="No Eyeliner" + label_max="Full Eyeliner" value_min="0" value_max="1" value_default="0.0" - camera_distance="1.6" - camera_elevation="-.4" - camera_angle="70"> + camera_distance=".3" + camera_elevation=".14"> <param_alpha - tga_file="nailpolish_alpha.tga" + tga_file="eyeliner_alpha.tga" skip_if_zero="true" domain="0.1" /> </param> <param - id="715" + id="714" group="0" wearable="skin" edit_group="skin_makeup" - edit_group_order="16" - name="Nail Polish Color" - label_min="Pink" + edit_group_order="14" + name="Eyeliner Color" + label_min="Dark Green" label_max="Black" value_min="0" value_max="1" - camera_distance="1.6" - camera_elevation="-.4" - camera_angle="70"> + camera_distance=".3" + camera_elevation=".14"> <param_color> <value - color="255,187,200,255" /> + color="24,98,40,250" /> + <!-- dark green --> <value - color="194,102,127,255" /> + color="9,100,127,250" /> + <!-- lt.aqua blue --> <value - color="227,34,99,255" /> + color="61,93,134,250" /> + <!-- aqua --> <value - color="168,41,60,255" /> + color="70,29,27,250" /> + <!-- dark brown --> <value - color="97,28,59,255" /> + color="115,75,65,250" /> + <!-- lt. brown blue --> <value - color="234,115,93,255" /> + color="100,100,100,250" /> + <!-- grey --> <value - color="142,58,47,255" /> + color="91,80,74,250" /> + <!-- grey/brown --> <value - color="114,30,46,255" /> + color="112,42,76,250" /> + <!-- plum --> <value - color="14,14,14,255" /> + color="14,14,14,250" /> + + <!-- black --> </param_color> </param> </layer> <layer - name="upper_gloves bump" - render_pass="bump" - fixed_color="128,128,128,255"> + name="facialhair bump" + render_pass="bump"> <texture - local_texture="upper_gloves" - local_texture_alpha_only="true" /> + tga_file="head_hair.tga" + file_is_mask="false" /> <param - id="1059" + id="1004" + sex="male" group="1" - wearable="gloves" + wearable="hair" edit_group="driven" - name="Glove Length bump" - value_min=".01" - value_max="1" - value_default=".8"> + name="Sideburns bump" + value_min="0" + value_max="1"> <param_alpha - tga_file="glove_length_alpha.tga" - domain="0.01" /> + tga_file="facehair_sideburns_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> <param - id="1061" + id="1006" + sex="male" group="1" - wearable="gloves" + wearable="hair" edit_group="driven" - name="Glove Fingers bump" - value_min=".01" - value_max="1" - value_default="1"> + name="Moustache bump" + value_min="0" + value_max="1"> <param_alpha - tga_file="gloves_fingers_alpha.tga" - multiply_blend="true" - domain="0.01" /> + tga_file="facehair_moustache_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> - </layer> - - <layer - name="upper_gloves"> - <texture - local_texture="upper_gloves" /> <param - id="827" - group="0" - wearable="gloves" - edit_group="colorpicker" - name="gloves_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="829" - group="0" - wearable="gloves" - edit_group="colorpicker" - name="gloves_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="830" - group="0" - wearable="gloves" - edit_group="colorpicker" - name="gloves_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="1058" + id="1008" + sex="male" group="1" - wearable="gloves" + wearable="hair" edit_group="driven" - name="Glove Length" - value_min=".01" - value_max="1" - value_default=".8"> + name="Soulpatch bump" + value_min="0" + value_max="1"> <param_alpha - tga_file="glove_length_alpha.tga" - domain="0.01" /> + tga_file="facehair_soulpatch_alpha.tga" + skip_if_zero="true" + domain="0.1" /> </param> <param - id="1060" + id="1010" + sex="male" group="1" - wearable="gloves" edit_group="driven" - name="Glove Fingers" - value_min=".01" - value_max="1" - value_default="1"> + wearable="hair" + name="Chin Curtains bump" + value_min="0" + value_max="1"> <param_alpha - tga_file="gloves_fingers_alpha.tga" - multiply_blend="true" - domain="0.01" /> + tga_file="facehair_chincurtains_alpha.tga" + skip_if_zero="true" + domain="0.03" /> </param> - </layer> - - <layer - name="upper_clothes_shadow"> - <texture - local_texture="upper_shirt" /> <param - id="899" + id="1012" group="1" + sex="male" + wearable="hair" edit_group="driven" - wearable="shirt" - name="Upper Clothes Shading" + name="5 O'Clock Shadow bump" value_min="0" - value_max="1" - value_default="0"> + value_max="1"> <param_color> <value - color="0, 0, 0, 0" /> + color="255,255,255,255" /> <value - color="0, 0, 0, 80" /> + color="255,255,255,0" /> </param_color> </param> + </layer> - <param - id="900" - group="1" - wearable="shirt" - edit_group="driven" - name="Sleeve Length Shadow" - value_min="0.02" - value_max=".87" - value_default="0.02"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> + <layer + name="facialhair" + global_color="hair_color"> + + <texture + tga_file="head_hair.tga" + file_is_mask="false" /> <param - id="901" + id="1005" + sex="male" group="1" - wearable="shirt" + wearable="hair" edit_group="driven" - name="Shirt Shadow Bottom" - value_min="0.02" + name="Sideburns" + value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_bottom_alpha.tga" + tga_file="facehair_sideburns_alpha.tga" skip_if_zero="true" domain="0.05" /> </param> <param - id="902" + id="1007" + sex="male" group="1" - wearable="shirt" + wearable="hair" edit_group="driven" - name="Collar Front Shadow Height" - value_min="0.02" + name="Moustache" + value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" + tga_file="facehair_moustache_alpha.tga" skip_if_zero="true" - domain="0.02" /> + domain="0.05" /> </param> <param - id="903" + id="1009" + sex="male" group="1" - wearable="shirt" + wearable="hair" edit_group="driven" - name="Collar Back Shadow Height" - value_min="0.02" + name="Soulpatch" + value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" + tga_file="facehair_soulpatch_alpha.tga" skip_if_zero="true" - domain="0.02" /> - </param> - </layer> - - <layer - name="upper_shirt base bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="upper_shirt" - local_texture_alpha_only="true" /> - - <param - id="1029" - group="1" - wearable="shirt" - edit_group="driven" - name="Sleeve Length Cloth" - value_min="0" - value_max="0.85"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> + domain="0.1" /> </param> <param - id="1030" + id="1011" + sex="male" group="1" - wearable="shirt" + wearable="hair" edit_group="driven" - name="Shirt Bottom Cloth" + name="Chin Curtains" value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_bottom_alpha.tga" - domain="0.05" /> + tga_file="facehair_chincurtains_alpha.tga" + skip_if_zero="true" + domain="0.03" /> </param> <param - id="1031" + id="751" group="1" - wearable="shirt" - edit_group="driven" - name="Collar Front Height Cloth" + wearable="hair" + sex="male" + edit_group="hair_facial" + name="5 O'Clock Shadow" + label_min="Dense hair" + label_max="Shadow hair" value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> - </param> + value_max="1" + value_default="0.7" + camera_elevation=".1" + camera_distance=".3"> + <param_color + operation="multiply"> + <value + color="255,255,255,255" /> - <param - id="1032" - group="1" - wearable="shirt" - edit_group="driven" - name="Collar Back Height Cloth" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> + <value + color="255,255,255,30" /> + </param_color> </param> </layer> <layer - name="upper_clothes bump" - render_pass="bump"> - <texture - tga_file="bump_shirt_wrinkles.tga" /> - + name="head_bodypaint"> <texture - local_texture="upper_shirt" - local_texture_alpha_only="true" /> - - <param - id="868" - group="3" - wearable="shirt" - edit_group="shirt" - edit_group_order="8" - name="Shirt Wrinkles" + local_texture="head_bodypaint" /> + </layer> + <layer + name="eyelash alpha" + visibility_mask="TRUE"> + <texture + tga_file="head_alpha.tga" + file_is_mask="TRUE" /> + </layer> + <layer + name="head alpha" + visibility_mask="TRUE"> + <texture + local_texture="head_alpha" /> + </layer> + <layer + name="head_tattoo"> + <texture + local_texture="head_tattoo" /> + <param + id="1062" + group="1" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_head_red" value_min="0" value_max="1" - value_default="0"> + value_default="1"> <param_color> <value - color="255, 255, 255, 0" /> + color="0, 0, 0, 255" /> <value - color="255, 255, 255, 255" /> + color="255, 0, 0, 255" /> </param_color> </param> <param - id="1013" + id="1063" group="1" - wearable="shirt" - edit_group="driven" - name="Sleeve Length Cloth" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_head_green" value_min="0" - value_max="0.85"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="1014" + id="1064" group="1" - wearable="shirt" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_head_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> + + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="upper_body" + width="512" + height="512"> + <layer + name="base_upperbody bump" + render_pass="bump" + fixed_color="128,128,128,255"> + </layer> + <layer + name="upperbody bump definition" + render_pass="bump"> + <texture + tga_file="bump_upperbody_base.tga" + file_is_mask="FALSE"/> + + <param + id="874" + group="1" + wearable="skin" edit_group="driven" - name="Shirt Bottom Cloth" + edit_group_order="20" + name="Bump upperdef" value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_bottom_alpha.tga" - domain="0.05" /> + domain="0" /> + </param> + </layer> + + <layer + name="base" + global_color="skin_color"> + <texture + tga_file="body_skingrain.tga" /> + </layer> + + <layer + name="nipples"> + <texture + tga_file="upperbody_color.tga" /> + </layer> + + <layer + name="shadow"> + <texture + tga_file="upperbody_shading_alpha.tga" + file_is_mask="TRUE" /> + + <param + id="125" + group="1" + name="Shading" + wearable="skin" + value_min="0" + value_max="1"> + <param_color> + <value + color="0, 0, 0, 0" /> + + <value + color="0, 0, 0, 128" /> + </param_color> </param> + </layer> + + <layer + name="highlight"> + <texture + tga_file="upperbody_highlights_alpha.tga" + file_is_mask="TRUE" /> <param - id="1015" + id="126" group="1" - wearable="shirt" - edit_group="driven" - name="Collar Front Height Cloth" + wearable="skin" + name="Shading" value_min="0" value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 64" /> + </param_color> </param> + </layer> + + <layer + name="upper_bodypaint"> + <texture + local_texture="upper_bodypaint" /> + </layer> + <layer + name="freckles upper" + fixed_color="120,47,20,128"> <param - id="1016" + id="776" group="1" - wearable="shirt" - edit_group="driven" - name="Collar Back Height Cloth" + name="freckles upper" + wearable="skin" value_min="0" value_max="1"> <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> + tga_file="upperbodyfreckles_alpha.tga" + skip_if_zero="true" + domain="0.6" /> </param> </layer> <layer - name="upper_clothes"> + name="upper_tattoo"> <texture - local_texture="upper_shirt" /> + local_texture="upper_tattoo" /> <param - id="803" - group="0" - wearable="shirt" - edit_group="colorpicker" - name="shirt_red" + id="1065" + group="1" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_upper_red" value_min="0" value_max="1" value_default="1"> @@ -7812,11 +10165,11 @@ render_pass="bump"> </param> <param - id="804" - group="0" - wearable="shirt" - edit_group="colorpicker" - name="shirt_green" + id="1066" + group="1" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_upper_green" value_min="0" value_max="1" value_default="1"> @@ -7830,11 +10183,11 @@ render_pass="bump"> </param> <param - id="805" - group="0" - wearable="shirt" - edit_group="colorpicker" - name="shirt_blue" + id="1067" + group="1" + edit_group="colorpicker_driven" + wearable="tattoo" + name="tattoo_upper_blue" value_min="0" value_max="1" value_default="1"> @@ -7847,278 +10200,336 @@ render_pass="bump"> </param_color> </param> + </layer> + + + <layer + name="upper_undershirt bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="upper_undershirt" + local_texture_alpha_only="true" /> + <param - id="600" + id="1043" group="1" - wearable="shirt" + wearable="undershirt" edit_group="driven" - name="Sleeve Length Cloth" - value_min="0" - value_max="0.85" - value_default=".7"> + name="Sleeve Length bump" + value_min=".01" + value_max="1" + value_default=".4"> <param_alpha - multiply_blend="false" tga_file="shirt_sleeve_alpha.tga" + multiply_blend="false" domain="0.01" /> </param> <param - id="601" + id="1045" group="1" - wearable="shirt" - edit_group="driven" - name="Shirt Bottom Cloth" + wearable="undershirt" + edit_group="undershirt" + edit_group_order="2" + name="Bottom bump" value_min="0" value_max="1" value_default=".8"> <param_alpha - multiply_blend="true" tga_file="shirt_bottom_alpha.tga" + multiply_blend="true" domain="0.05" /> </param> <param - id="602" + id="1047" group="1" - wearable="shirt" + wearable="undershirt" edit_group="driven" - name="Collar Front Height Cloth" + name="Collar Front bump" value_min="0" value_max="1" value_default=".8"> <param_alpha - multiply_blend="true" tga_file="shirt_collar_alpha.tga" + multiply_blend="true" domain="0.05" /> </param> <param - id="778" + id="1049" group="1" - wearable="shirt" + wearable="undershirt" edit_group="driven" - name="Collar Back Height Cloth" + name="Collar Back bump" value_min="0" value_max="1" value_default=".8"> <param_alpha - multiply_blend="true" tga_file="shirt_collar_back_alpha.tga" + multiply_blend="true" domain="0.05" /> </param> </layer> <layer - name="upper_jacket base bump" - render_pass="bump" - fixed_color="128,128,128,255"> + name="upper_undershirt"> <texture - local_texture="upper_jacket" - local_texture_alpha_only="true" /> + local_texture="upper_undershirt" /> <param - id="1039" - group="1" - wearable="jacket" - edit_group="driven" - edit_group_order="1" - name="Jacket Sleeve Length bump" + id="821" + group="0" + wearable="undershirt" + edit_group="colorpicker" + name="undershirt_red" value_min="0" - value_max="1"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> - </param> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <param - id="1040" - group="1" - wearable="jacket" - edit_group="driven" - name="Jacket Collar Front bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="1041" - group="1" - wearable="jacket" - edit_group="driven" - edit_group_order="3.5" - name="Jacket Collar Back bump" + id="822" + group="0" + wearable="undershirt" + edit_group="colorpicker" + name="undershirt_green" value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> - </param> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <param - id="1037" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket bottom length upper bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="jacket_length_upper_alpha.tga" - domain="0.01" /> + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="1038" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket open upper bump" + id="823" + group="0" + wearable="undershirt" + edit_group="colorpicker" + name="undershirt_blue" value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="jacket_open_upper_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="upper_jacket bump" - render_pass="bump"> - <texture - tga_file="bump_shirt_wrinkles.tga" /> - - <texture - local_texture="upper_jacket" - local_texture_alpha_only="true" /> - - - <param - id="875" - group="1" - wearable="jacket" - name="jacket upper Wrinkles" - value_min="0" - value_max="1" - value_default="0"> + value_max="1" + value_default="1"> <param_color> <value - color="255, 255, 255, 0" /> + color="0, 0, 0, 255" /> <value - color="255, 255, 255, 255" /> + color="0, 0, 255, 255" /> </param_color> </param> <param - id="1019" + id="1042" group="1" - wearable="jacket" + wearable="undershirt" edit_group="driven" - edit_group_order="1" - name="Jacket Sleeve Length bump" - value_min="0" - value_max="1"> + name="Sleeve Length" + value_min=".01" + value_max="1" + value_default=".4"> <param_alpha - multiply_blend="false" tga_file="shirt_sleeve_alpha.tga" + multiply_blend="false" domain="0.01" /> </param> <param - id="1021" + id="1044" group="1" - wearable="jacket" + wearable="undershirt" edit_group="driven" - name="Jacket Collar Front bump" + name="Bottom" value_min="0" - value_max="1"> + value_max="1" + value_default=".8"> <param_alpha + tga_file="shirt_bottom_alpha.tga" multiply_blend="true" - tga_file="shirt_collar_alpha.tga" domain="0.05" /> </param> <param - id="1023" + id="1046" group="1" - wearable="jacket" + wearable="undershirt" edit_group="driven" - edit_group_order="3.5" - name="Jacket Collar Back bump" + name="Collar Front" value_min="0" - value_max="1"> + value_max="1" + value_default=".8"> <param_alpha + tga_file="shirt_collar_alpha.tga" multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" domain="0.05" /> </param> <param - id="1025" + id="1048" group="1" - wearable="jacket" + wearable="undershirt" edit_group="driven" - name="jacket bottom length upper bump" + name="Collar Back" + label_min="Low" + label_max="High" value_min="0" - value_max="1"> + value_max="1" + value_default=".8"> <param_alpha + tga_file="shirt_collar_back_alpha.tga" multiply_blend="true" - tga_file="jacket_length_upper_alpha.tga" - domain="0.01" /> + domain="0.05" /> </param> + </layer> + <layer + name="Nail Polish"> <param - id="1026" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket open upper bump" + id="710" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="15" + name="Nail Polish" + label_min="No Polish" + label_max="Painted Nails" value_min="0" - value_max="1"> + value_max="1" + value_default="0.0" + camera_distance="1.6" + camera_elevation="-.4" + camera_angle="70"> <param_alpha - multiply_blend="true" - tga_file="jacket_open_upper_alpha.tga" - domain="0.01" /> + tga_file="nailpolish_alpha.tga" + skip_if_zero="true" + domain="0.1" /> </param> - </layer> - - <layer - name="upper_jacket"> - <texture - local_texture="upper_jacket" /> <param - id="831" - group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="upper_jacket_red" + id="715" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="16" + name="Nail Polish Color" + label_min="Pink" + label_max="Black" value_min="0" value_max="1" - value_default="1"> + camera_distance="1.6" + camera_elevation="-.4" + camera_angle="70"> <param_color> <value - color="0, 0, 0, 255" /> + color="255,187,200,255" /> <value - color="255, 0, 0, 255" /> - </param_color> - </param> + color="194,102,127,255" /> + + <value + color="227,34,99,255" /> + + <value + color="168,41,60,255" /> + + <value + color="97,28,59,255" /> + + <value + color="234,115,93,255" /> + + <value + color="142,58,47,255" /> + + <value + color="114,30,46,255" /> + + <value + color="14,14,14,255" /> + </param_color> + </param> + </layer> + + <layer + name="upper_gloves bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="upper_gloves" + local_texture_alpha_only="true" /> <param - id="832" + id="1059" group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="upper_jacket_green" + wearable="gloves" + edit_group="driven" + name="Glove Length bump" + value_min=".01" + value_max="1" + value_default=".8"> + <param_alpha + tga_file="glove_length_alpha.tga" + domain="0.01" /> + </param> + + <param + id="1061" + group="1" + wearable="gloves" + edit_group="driven" + name="Glove Fingers bump" + value_min=".01" + value_max="1" + value_default="1"> + <param_alpha + tga_file="gloves_fingers_alpha.tga" + multiply_blend="true" + domain="0.01" /> + </param> + </layer> + + <layer + name="upper_gloves"> + <texture + local_texture="upper_gloves" /> + + <param + id="827" + group="0" + wearable="gloves" + edit_group="colorpicker" + name="gloves_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="829" + group="0" + wearable="gloves" + edit_group="colorpicker" + name="gloves_green" value_min="0" value_max="1" value_default="1"> @@ -8132,11 +10543,11 @@ render_pass="bump"> </param> <param - id="833" - group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="upper_jacket_blue" + id="830" + group="0" + wearable="gloves" + edit_group="colorpicker" + name="gloves_blue" value_min="0" value_max="1" value_default="1"> @@ -8150,320 +10561,282 @@ render_pass="bump"> </param> <param - id="1020" + id="1058" group="1" - edit_group="driven" - wearable="jacket" - name="jacket Sleeve Length" value_min="0" - value_max="1"> + wearable="gloves" + edit_group="driven" + name="Glove Length" + value_min=".01" + value_max="1" + value_default=".8"> <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" + tga_file="glove_length_alpha.tga" domain="0.01" /> </param> <param - id="1022" + id="1060" group="1" - wearable="jacket" + wearable="gloves" edit_group="driven" - name="jacket Collar Front" - value_min="0" - value_max="1"> + name="Glove Fingers" + value_min=".01" + value_max="1" + value_default="1"> <param_alpha + tga_file="gloves_fingers_alpha.tga" multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> + domain="0.01" /> </param> + </layer> + + <layer + name="upper_clothes_shadow"> + <texture + local_texture="upper_shirt" /> <param - id="1024" + id="899" group="1" - wearable="jacket" edit_group="driven" - edit_group_order="3.5" - name="jacket Collar Back" + wearable="shirt" + name="Upper Clothes Shading" value_min="0" + value_max="1" + value_default="0"> + <param_color> + <value + color="0, 0, 0, 0" /> + + <value + color="0, 0, 0, 80" /> + </param_color> + </param> + + <param + id="900" + group="1" + wearable="shirt" + edit_group="driven" + name="Sleeve Length Shadow" + value_min="0.02" + value_max=".87" + value_default="0.02"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + skip_if_zero="true" + domain="0.03" /> + </param> + + <param + id="901" + group="1" + wearable="shirt" + edit_group="driven" + name="Shirt Shadow Bottom" + value_min="0.02" value_max="1"> <param_alpha multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" + tga_file="shirt_bottom_alpha.tga" + skip_if_zero="true" domain="0.05" /> </param> <param - id="620" + id="902" group="1" - wearable="jacket" - edit_group="jacket" - name="bottom length upper" - label_min="hi cut" - label_max="low cut" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> + wearable="shirt" + edit_group="driven" + name="Collar Front Shadow Height" + value_min="0.02" + value_max="1"> <param_alpha multiply_blend="true" - tga_file="jacket_length_upper_alpha.tga" - domain="0.01" /> + tga_file="shirt_collar_alpha.tga" + skip_if_zero="true" + domain="0.02" /> </param> <param - id="622" + id="903" group="1" - wearable="jacket" - edit_group="jacket" - name="open upper" - label_min="closed" - label_max="open" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> + wearable="shirt" + edit_group="driven" + name="Collar Back Shadow Height" + value_min="0.02" + value_max="1"> <param_alpha multiply_blend="true" - tga_file="jacket_open_upper_alpha.tga" - domain="0.01" /> + tga_file="shirt_collar_back_alpha.tga" + skip_if_zero="true" + domain="0.02" /> </param> </layer> <layer - name="upper alpha" - visibility_mask="TRUE"> + name="upper_shirt base bump" + render_pass="bump" + fixed_color="128,128,128,255"> <texture - local_texture="upper_alpha" /> - </layer> + local_texture="upper_shirt" + local_texture_alpha_only="true" /> - </layer_set> - - <!-- =========================================================== --> - <layer_set - body_region="lower_body" - width="512" - height="512"> - <layer - name="lower body bump base" - fixed_color = "128,128,128,255" - render_pass="bump"> - </layer> - <layer - name="base_lowerbody bump" - render_pass="bump"> - <texture - tga_file="bump_lowerbody_base.tga" - file_is_mask="FALSE" /> + <param + id="1029" + group="1" + wearable="shirt" + edit_group="driven" + name="Sleeve Length Cloth" + value_min="0" + value_max="0.85"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> + </param> <param - id="878" + id="1030" group="1" - wearable="skin" + wearable="shirt" edit_group="driven" - edit_group_order="20" - name="Bump upperdef" + name="Shirt Bottom Cloth" value_min="0" value_max="1"> <param_alpha - domain="0" /> + multiply_blend="true" + tga_file="shirt_bottom_alpha.tga" + domain="0.05" /> </param> - </layer> - - <layer - name="base" - global_color="skin_color"> - <texture - tga_file="body_skingrain.tga" /> - </layer> - - <layer - name="shadow"> - <texture - tga_file="lowerbody_shading_alpha.tga" - file_is_mask="TRUE" /> <param - id="160" + id="1031" group="1" - name="Shading" - wearable="pants" - cross_wearable="true" + wearable="shirt" + edit_group="driven" + name="Collar Front Height Cloth" value_min="0" value_max="1"> - <param_color> - <value - color="0, 0, 0, 0" /> - - <value - color="0, 0, 0, 128" /> - </param_color> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> - </layer> - - <layer - name="highlight"> - <texture - tga_file="lowerbody_highlights_alpha.tga" - file_is_mask="TRUE" /> <param - id="161" + id="1032" group="1" - name="Shading" - wearable="skin" + wearable="shirt" + edit_group="driven" + name="Collar Back Height Cloth" value_min="0" value_max="1"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 64" /> - </param_color> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> </layer> <layer - name="toenails"> - <texture - tga_file="lowerbody_color.tga" /> - </layer> - - <layer - name="lower_bodypaint"> + name="upper_clothes bump" + render_pass="bump"> <texture - local_texture="lower_bodypaint" /> - </layer> - - <layer - name="freckles lower" - fixed_color="120,47,20,128"> - <param - id="777" - group="1" - name="freckles lower" - wearable="skin" - value_min="0" - value_max="1"> - <param_alpha - tga_file="bodyfreckles_alpha.tga" - skip_if_zero="true" - domain="0.6" /> - </param> - </layer> + tga_file="bump_shirt_wrinkles.tga" /> - <layer - name="lower_tattoo"> <texture - local_texture="lower_tattoo" /> + local_texture="upper_shirt" + local_texture_alpha_only="true" /> <param - id="1068" - group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_lower_red" + id="868" + group="3" + wearable="shirt" + edit_group="shirt" + edit_group_order="8" + name="Shirt Wrinkles" value_min="0" value_max="1" - value_default="1"> + value_default="0"> <param_color> <value - color="0, 0, 0, 255" /> + color="255, 255, 255, 0" /> <value - color="255, 0, 0, 255" /> + color="255, 255, 255, 255" /> </param_color> </param> <param - id="1069" + id="1013" group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_lower_green" + wearable="shirt" + edit_group="driven" + name="Sleeve Length Cloth" value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> + value_max="0.85"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> </param> <param - id="1070" + id="1014" group="1" - edit_group="colorpicker_driven" - wearable="tattoo" - name="tattoo_lower_blue" + wearable="shirt" + edit_group="driven" + name="Shirt Bottom Cloth" value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="shirt_bottom_alpha.tga" + domain="0.05" /> </param> - </layer> - - <layer - name="lower_underpants bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_underpants" - local_texture_alpha_only="true" /> - <param - id="1055" + id="1015" group="1" - wearable="underpants" - edit_group="underpants" - name="Pants Length" + wearable="shirt" + edit_group="driven" + name="Collar Front Height Cloth" value_min="0" - value_max="1" - value_default=".3"> + value_max="1"> <param_alpha - tga_file="pants_length_alpha.tga" - domain="0.01" /> + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="1057" + id="1016" group="1" - wearable="underpants" - edit_group="underpants" - name="Pants Waist" + wearable="shirt" + edit_group="driven" + name="Collar Back Height Cloth" value_min="0" - value_max="1" - value_default=".8"> + value_max="1"> <param_alpha - tga_file="pants_waist_alpha.tga" + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" domain="0.05" /> </param> </layer> <layer - name="lower_underpants"> + name="upper_clothes"> <texture - local_texture="lower_underpants" /> + local_texture="upper_shirt" /> <param - id="824" + id="803" group="0" - wearable="underpants" + wearable="shirt" edit_group="colorpicker" - name="underpants_red" + name="shirt_red" value_min="0" value_max="1" value_default="1"> @@ -8477,11 +10850,11 @@ render_pass="bump"> </param> <param - id="825" + id="804" group="0" - wearable="underpants" + wearable="shirt" edit_group="colorpicker" - name="underpants_green" + name="shirt_green" value_min="0" value_max="1" value_default="1"> @@ -8495,11 +10868,11 @@ render_pass="bump"> </param> <param - id="826" + id="805" group="0" - wearable="underpants" + wearable="shirt" edit_group="colorpicker" - name="underpants_blue" + name="shirt_blue" value_min="0" value_max="1" value_default="1"> @@ -8513,385 +10886,259 @@ render_pass="bump"> </param> <param - id="1054" + id="600" group="1" - wearable="underpants" + wearable="shirt" edit_group="driven" - name="Pants Length" + name="Sleeve Length Cloth" value_min="0" - value_max="1" - value_default=".3" - camera_distance="1.2" - camera_angle="30" - camera_elevation="-.3"> + value_max="0.85" + value_default=".7"> <param_alpha - tga_file="pants_length_alpha.tga" + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" domain="0.01" /> </param> <param - id="1056" + id="601" group="1" - wearable="underpants" + wearable="shirt" edit_group="driven" - name="Pants Waist" + name="Shirt Bottom Cloth" value_min="0" value_max="1" value_default=".8"> <param_alpha - tga_file="pants_waist_alpha.tga" + multiply_blend="true" + tga_file="shirt_bottom_alpha.tga" domain="0.05" /> </param> - </layer> - - <layer - name="lower_socks bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_socks" - local_texture_alpha_only="true" /> <param - id="1051" + id="602" group="1" - wearable="socks" + wearable="shirt" edit_group="driven" - name="Socks Length bump" + name="Collar Front Height Cloth" value_min="0" value_max="1" - value_default="0.35"> + value_default=".8"> <param_alpha - tga_file="shoe_height_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_socks"> - <texture - local_texture="lower_socks" /> - - <param - id="818" - group="0" - wearable="socks" - edit_group="colorpicker" - name="socks_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="819" - group="0" - wearable="socks" - edit_group="colorpicker" - name="socks_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="820" - group="0" - wearable="socks" - edit_group="colorpicker" - name="socks_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="1050" + id="778" group="1" - wearable="socks" + wearable="shirt" edit_group="driven" - name="Socks Length bump" + name="Collar Back Height Cloth" value_min="0" value_max="1" - value_default="0.35"> + value_default=".8"> <param_alpha - tga_file="shoe_height_alpha.tga" - domain="0.01" /> + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> </layer> <layer - name="lower_shoes bump" + name="upper_jacket base bump" render_pass="bump" fixed_color="128,128,128,255"> <texture - local_texture="lower_shoes" + local_texture="upper_jacket" local_texture_alpha_only="true" /> <param - id="1053" + id="1039" group="1" - wearable="shoes" + wearable="jacket" edit_group="driven" - name="Shoe Height bump" + edit_group_order="1" + name="Jacket Sleeve Length bump" value_min="0" - value_max="1" - value_default="0.1"> + value_max="1"> <param_alpha - tga_file="shoe_height_alpha.tga" + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" domain="0.01" /> </param> - </layer> - - <layer - name="lower_shoes"> - <texture - local_texture="lower_shoes" /> <param - id="812" - group="0" - wearable="shoes" - edit_group="colorpicker" - name="shoes_red" + id="1040" + group="1" + wearable="jacket" + edit_group="driven" + name="Jacket Collar Front bump" value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="813" - group="0" - wearable="shoes" - edit_group="colorpicker" - name="shoes_green" + id="1041" + group="1" + wearable="jacket" + edit_group="driven" + edit_group_order="3.5" + name="Jacket Collar Back bump" value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> <param - id="817" - group="0" - wearable="shoes" - edit_group="colorpicker" - name="shoes_blue" + id="1037" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket bottom length upper bump" value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="jacket_length_upper_alpha.tga" + domain="0.01" /> </param> <param - id="1052" + id="1038" group="1" - wearable="shoes" + wearable="jacket" edit_group="driven" - name="Shoe Height" + name="jacket open upper bump" value_min="0" - value_max="1" - value_default="0.1"> + value_max="1"> <param_alpha - tga_file="shoe_height_alpha.tga" + multiply_blend="true" + tga_file="jacket_open_upper_alpha.tga" domain="0.01" /> </param> </layer> <layer - name="lower_clothes_shadow"> + name="upper_jacket bump" + render_pass="bump"> <texture - local_texture="lower_pants" /> + tga_file="bump_shirt_wrinkles.tga" /> + + <texture + local_texture="upper_jacket" + local_texture_alpha_only="true" /> + <param - id="913" - group="1" - edit_group="driven" - wearable="pants" - name="Lower Clothes Shading" - value_min="0" - value_max="1" - value_default="0"> + id="875" + group="1" + wearable="jacket" + name="jacket upper Wrinkles" + value_min="0" + value_max="1" + value_default="0"> <param_color> <value - color="0, 0, 0, 0" /> + color="255, 255, 255, 0" /> <value - color="0, 0, 0, 80" /> + color="255, 255, 255, 255" /> </param_color> </param> <param - id="914" + id="1019" group="1" + wearable="jacket" edit_group="driven" - wearable="pants" - name="Waist Height Shadow" - value_min="0.02" + edit_group_order="1" + name="Jacket Sleeve Length bump" + value_min="0" value_max="1"> <param_alpha - tga_file="pants_waist_alpha.tga" - skip_if_zero="true" - domain="0.04" /> + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> </param> <param - id="915" - group="1" - edit_group="driven" - wearable="pants" - name="Pants Length Shadow" - value_min="0.02" - value_max="1"> - <param_alpha - tga_file="pants_length_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> - </layer> - - <layer - name="lower_pants base bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_pants" - local_texture_alpha_only="true" /> - - <param - id="1035" + id="1021" group="1" + wearable="jacket" edit_group="driven" - wearable="pants" - name="Waist Height Cloth" + name="Jacket Collar Front bump" value_min="0" value_max="1"> <param_alpha - tga_file="pants_waist_alpha.tga" + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" domain="0.05" /> </param> <param - id="1036" + id="1023" group="1" + wearable="jacket" edit_group="driven" - wearable="pants" - name="Pants Length Cloth" + edit_group_order="3.5" + name="Jacket Collar Back bump" value_min="0" value_max="1"> <param_alpha - tga_file="pants_length_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_pants bump" - render_pass="bump"> - <texture - tga_file="bump_pants_wrinkles.tga" /> - - <texture - local_texture="lower_pants" - local_texture_alpha_only="true" /> - - <param - id="869" - group="3" - wearable="pants" - edit_group="pants" - edit_group_order="6" - name="Pants Wrinkles" - value_min="0" - value_max="1" - value_default="0"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 255" /> - </param_color> + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> <param - id="1017" + id="1025" group="1" + wearable="jacket" edit_group="driven" - wearable="pants" - name="Waist Height Cloth" + name="jacket bottom length upper bump" value_min="0" value_max="1"> <param_alpha - tga_file="pants_waist_alpha.tga" - domain="0.05" /> + multiply_blend="true" + tga_file="jacket_length_upper_alpha.tga" + domain="0.01" /> </param> <param - id="1018" + id="1026" group="1" + wearable="jacket" edit_group="driven" - wearable="pants" - name="Pants Length Cloth" + name="jacket open upper bump" value_min="0" value_max="1"> <param_alpha - tga_file="pants_length_alpha.tga" + multiply_blend="true" + tga_file="jacket_open_upper_alpha.tga" domain="0.01" /> </param> </layer> <layer - name="lower_pants"> + name="upper_jacket"> <texture - local_texture="lower_pants" /> + local_texture="upper_jacket" /> <param - id="806" - group="0" - wearable="pants" - edit_group="colorpicker" - name="pants_red" + id="831" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="upper_jacket_red" value_min="0" value_max="1" value_default="1"> @@ -8905,11 +11152,11 @@ render_pass="bump"> </param> <param - id="807" - group="0" - wearable="pants" - edit_group="colorpicker" - name="pants_green" + id="832" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="upper_jacket_green" value_min="0" value_max="1" value_default="1"> @@ -8923,11 +11170,11 @@ render_pass="bump"> </param> <param - id="808" - group="0" - wearable="pants" - edit_group="colorpicker" - name="pants_blue" + id="833" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="upper_jacket_blue" value_min="0" value_max="1" value_default="1"> @@ -8941,140 +11188,222 @@ render_pass="bump"> </param> <param - id="614" - group="1" - edit_group="driven" - wearable="pants" - name="Waist Height Cloth" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="pants_waist_alpha.tga" - domain="0.05" /> - </param> - - <param - id="615" + id="1020" group="1" - edit_group="driven" - wearable="pants" - name="Pants Length Cloth" - value_min="0" - value_max="1" - value_default=".8"> + edit_group="driven" + wearable="jacket" + name="jacket Sleeve Length" value_min="0" + value_max="1"> <param_alpha - tga_file="pants_length_alpha.tga" + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" domain="0.01" /> </param> - </layer> - - <layer - name="lower_jacket base bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_jacket" - local_texture_alpha_only="true" /> <param - id="1033" + id="1022" group="1" wearable="jacket" edit_group="driven" - cross_wearable="true" - name="jacket bottom length lower bump" + name="jacket Collar Front" value_min="0" value_max="1"> <param_alpha - multiply_blend="false" - tga_file="jacket_length_lower_alpha.tga" - domain="0.01" /> + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="1034" + id="1024" group="1" wearable="jacket" edit_group="driven" - name="jacket open lower bump" + edit_group_order="3.5" + name="jacket Collar Back" value_min="0" value_max="1"> <param_alpha multiply_blend="true" - tga_file="jacket_open_lower_alpha.tga" - domain="0.01" /> + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> - </layer> - - <layer - name="lower_jacket bump" - render_pass="bump"> - <texture - tga_file="bump_pants_wrinkles.tga" /> - - <texture - local_texture="lower_jacket" - local_texture_alpha_only="true" /> - <param - id="876" + id="620" group="1" wearable="jacket" - name="jacket upper Wrinkles" + edit_group="jacket" + name="bottom length upper" + label_min="hi cut" + label_max="low cut" value_min="0" value_max="1" - value_default="0"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 255" /> - </param_color> - </param> - - <param - id="1027" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket bottom length lower bump" - value_min="0" - value_max="1"> + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> <param_alpha - multiply_blend="false" - tga_file="jacket_length_lower_alpha.tga" + multiply_blend="true" + tga_file="jacket_length_upper_alpha.tga" domain="0.01" /> </param> <param - id="1028" + id="622" group="1" wearable="jacket" - edit_group="driven" - name="jacket open lower bump" + edit_group="jacket" + name="open upper" + label_min="closed" + label_max="open" value_min="0" - value_max="1"> + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> <param_alpha multiply_blend="true" - tga_file="jacket_open_lower_alpha.tga" + tga_file="jacket_open_upper_alpha.tga" domain="0.01" /> </param> </layer> <layer - name="lower_jacket"> + name="upper alpha" + visibility_mask="TRUE"> <texture - local_texture="lower_jacket" /> + local_texture="upper_alpha" /> + </layer> - <param - id="809" - group="1" + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="lower_body" + width="512" + height="512"> + <layer + name="lower body bump base" + fixed_color = "128,128,128,255" + render_pass="bump"> + </layer> + <layer + name="base_lowerbody bump" + render_pass="bump"> + <texture + tga_file="bump_lowerbody_base.tga" + file_is_mask="FALSE" /> + + <param + id="878" + group="1" + wearable="skin" + edit_group="driven" + edit_group_order="20" + name="Bump upperdef" + value_min="0" + value_max="1"> + <param_alpha + domain="0" /> + </param> + </layer> + + <layer + name="base" + global_color="skin_color"> + <texture + tga_file="body_skingrain.tga" /> + </layer> + + <layer + name="shadow"> + <texture + tga_file="lowerbody_shading_alpha.tga" + file_is_mask="TRUE" /> + + <param + id="160" + group="1" + name="Shading" + wearable="pants" + cross_wearable="true" + value_min="0" + value_max="1"> + <param_color> + <value + color="0, 0, 0, 0" /> + + <value + color="0, 0, 0, 128" /> + </param_color> + </param> + </layer> + + <layer + name="highlight"> + <texture + tga_file="lowerbody_highlights_alpha.tga" + file_is_mask="TRUE" /> + + <param + id="161" + group="1" + name="Shading" + wearable="skin" + value_min="0" + value_max="1"> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 64" /> + </param_color> + </param> + </layer> + + <layer + name="toenails"> + <texture + tga_file="lowerbody_color.tga" /> + </layer> + + <layer + name="lower_bodypaint"> + <texture + local_texture="lower_bodypaint" /> + </layer> + + <layer + name="freckles lower" + fixed_color="120,47,20,128"> + <param + id="777" + group="1" + name="freckles lower" + wearable="skin" + value_min="0" + value_max="1"> + <param_alpha + tga_file="bodyfreckles_alpha.tga" + skip_if_zero="true" + domain="0.6" /> + </param> + </layer> + + <layer + name="lower_tattoo"> + <texture + local_texture="lower_tattoo" /> + + <param + id="1068" + group="1" edit_group="colorpicker_driven" - wearable="jacket" - name="lower_jacket_red" + wearable="tattoo" + name="tattoo_lower_red" value_min="0" value_max="1" value_default="1"> @@ -9088,11 +11417,11 @@ render_pass="bump"> </param> <param - id="810" + id="1069" group="1" edit_group="colorpicker_driven" - wearable="jacket" - name="lower_jacket_green" + wearable="tattoo" + name="tattoo_lower_green" value_min="0" value_max="1" value_default="1"> @@ -9106,11 +11435,11 @@ render_pass="bump"> </param> <param - id="811" + id="1070" group="1" edit_group="colorpicker_driven" - wearable="jacket" - name="lower_jacket_blue" + wearable="tattoo" + name="tattoo_lower_blue" value_min="0" value_max="1" value_default="1"> @@ -9123,101 +11452,56 @@ render_pass="bump"> </param_color> </param> + </layer> + + <layer + name="lower_underpants bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_underpants" + local_texture_alpha_only="true" /> + <param - id="621" + id="1055" group="1" - wearable="jacket" - edit_group="jacket" - name="bottom length lower" - label_min="hi cut" - label_max="low cut" + wearable="underpants" + edit_group="underpants" + name="Pants Length" value_min="0" value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> + value_default=".3"> <param_alpha - multiply_blend="false" - tga_file="jacket_length_lower_alpha.tga" + tga_file="pants_length_alpha.tga" domain="0.01" /> </param> <param - id="623" + id="1057" group="1" - wearable="jacket" - edit_group="jacket" - name="open lower" - label_min="open" - label_max="closed" + wearable="underpants" + edit_group="underpants" + name="Pants Waist" value_min="0" value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> + value_default=".8"> <param_alpha - multiply_blend="true" - tga_file="jacket_open_lower_alpha.tga" - domain="0.01" /> + tga_file="pants_waist_alpha.tga" + domain="0.05" /> </param> </layer> <layer - name="lower alpha" - visibility_mask="TRUE"> - <texture - local_texture="lower_alpha" /> - </layer> - - </layer_set> - - <!-- =========================================================== --> - <layer_set - body_region="eyes" - width="128" - height="128"> - <layer - name="whites"> - <texture - tga_file="eyewhite.tga" /> - </layer> - - <layer - name="iris" - global_color="eye_color"> - <texture - local_texture="eyes_iris" /> - </layer> - - <layer - name="eyes alpha" - visibility_mask="TRUE"> - <texture - local_texture="eyes_alpha" /> - </layer> - - </layer_set> - - <!-- =========================================================== --> - <layer_set - body_region="skirt" - width="512" - height="512" - clear_alpha="false"> - <layer - name="skirt_fabric" - write_all_channels="true"> + name="lower_underpants"> <texture - local_texture="skirt" /> + local_texture="lower_underpants" /> <param - id="921" + id="824" group="0" - wearable="skirt" + wearable="underpants" edit_group="colorpicker" - name="skirt_red" + name="underpants_red" value_min="0" value_max="1" value_default="1"> @@ -9231,11 +11515,11 @@ render_pass="bump"> </param> <param - id="922" + id="825" group="0" - wearable="skirt" + wearable="underpants" edit_group="colorpicker" - name="skirt_green" + name="underpants_green" value_min="0" value_max="1" value_default="1"> @@ -9249,11 +11533,11 @@ render_pass="bump"> </param> <param - id="923" + id="826" group="0" - wearable="skirt" + wearable="underpants" edit_group="colorpicker" - name="skirt_blue" + name="underpants_blue" value_min="0" value_max="1" value_default="1"> @@ -9265,123 +11549,1696 @@ render_pass="bump"> color="0, 0, 255, 255" /> </param_color> </param> - </layer> - <layer - name="skirt_fabric_alpha"> <param - id="858" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="1" - name="Skirt Length" - show_simple="true" - label_min="Short" - label_max="Long" - value_min=".01" + id="1054" + group="1" + wearable="underpants" + edit_group="driven" + name="Pants Length" + value_min="0" value_max="1" - value_default=".4" - simple_percent_min="40" - simple_percent_max="100" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="30"> + value_default=".3" + camera_distance="1.2" + camera_angle="30" + camera_elevation="-.3"> <param_alpha - tga_file="skirt_length_alpha.tga" - domain="0" - multiply_blend="true" /> + tga_file="pants_length_alpha.tga" + domain="0.01" /> </param> <param - id="859" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="4" - name="Slit Front" - label_min="Open Front" - label_max="Closed Front" + id="1056" + group="1" + wearable="underpants" + edit_group="driven" + name="Pants Waist" value_min="0" value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="30"> + value_default=".8"> <param_alpha - tga_file="skirt_slit_front_alpha.tga" - multiply_blend="true" - domain="0" /> + tga_file="pants_waist_alpha.tga" + domain="0.05" /> </param> + </layer> + + <layer + name="lower_socks bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_socks" + local_texture_alpha_only="true" /> <param - id="860" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="5" - name="Slit Back" - label_min="Open Back" - label_max="Closed Back" + id="1051" + group="1" + wearable="socks" + edit_group="driven" + name="Socks Length bump" value_min="0" value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="160"> + value_default="0.35"> <param_alpha - tga_file="skirt_slit_back_alpha.tga" - multiply_blend="true" - domain="0" /> + tga_file="shoe_height_alpha.tga" + domain="0.01" /> </param> + </layer> + + <layer + name="lower_socks"> + <texture + local_texture="lower_socks" /> <param - id="861" + id="818" group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="6" - name="Slit Left" - label_min="Open Left" - label_max="Closed Left" + wearable="socks" + edit_group="colorpicker" + name="socks_red" value_min="0" value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="30"> - <param_alpha - tga_file="skirt_slit_left_alpha.tga" - multiply_blend="true" - domain="0" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="862" + id="819" group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="7" - name="Slit Right" - label_min="Open Right" - label_max="Closed Right" + wearable="socks" + edit_group="colorpicker" + name="socks_green" value_min="0" value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="-30"> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="820" + group="0" + wearable="socks" + edit_group="colorpicker" + name="socks_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + <param + id="1050" + group="1" + wearable="socks" + edit_group="driven" + name="Socks Length bump" + value_min="0" + value_max="1" + value_default="0.35"> <param_alpha - tga_file="skirt_slit_right_alpha.tga" - multiply_blend="true" - domain="0" /> + tga_file="shoe_height_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_shoes bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_shoes" + local_texture_alpha_only="true" /> + + <param + id="1053" + group="1" + wearable="shoes" + edit_group="driven" + name="Shoe Height bump" + value_min="0" + value_max="1" + value_default="0.1"> + <param_alpha + tga_file="shoe_height_alpha.tga" + domain="0.01" /> </param> </layer> - </layer_set> + <layer + name="lower_shoes"> + <texture + local_texture="lower_shoes" /> + + <param + id="812" + group="0" + wearable="shoes" + edit_group="colorpicker" + name="shoes_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="813" + group="0" + wearable="shoes" + edit_group="colorpicker" + name="shoes_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="817" + group="0" + wearable="shoes" + edit_group="colorpicker" + name="shoes_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + <param + id="1052" + group="1" + wearable="shoes" + edit_group="driven" + name="Shoe Height" + value_min="0" + value_max="1" + value_default="0.1"> + <param_alpha + tga_file="shoe_height_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_clothes_shadow"> + <texture + local_texture="lower_pants" /> + + <param + id="913" + group="1" + edit_group="driven" + wearable="pants" + name="Lower Clothes Shading" + value_min="0" + value_max="1" + value_default="0"> + <param_color> + <value + color="0, 0, 0, 0" /> + + <value + color="0, 0, 0, 80" /> + </param_color> + </param> + + <param + id="914" + group="1" + edit_group="driven" + wearable="pants" + name="Waist Height Shadow" + value_min="0.02" + value_max="1"> + <param_alpha + tga_file="pants_waist_alpha.tga" + skip_if_zero="true" + domain="0.04" /> + </param> + + <param + id="915" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Shadow" + value_min="0.02" + value_max="1"> + <param_alpha + tga_file="pants_length_alpha.tga" + skip_if_zero="true" + domain="0.03" /> + </param> + </layer> + + <layer + name="lower_pants base bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_pants" + local_texture_alpha_only="true" /> + + <param + id="1035" + group="1" + edit_group="driven" + wearable="pants" + name="Waist Height Cloth" + value_min="0" + value_max="1"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> + </param> + + <param + id="1036" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Cloth" + value_min="0" + value_max="1"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_pants bump" + render_pass="bump"> + <texture + tga_file="bump_pants_wrinkles.tga" /> + + <texture + local_texture="lower_pants" + local_texture_alpha_only="true" /> + + <param + id="869" + group="3" + wearable="pants" + edit_group="pants" + edit_group_order="6" + name="Pants Wrinkles" + value_min="0" + value_max="1" + value_default="0"> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 255" /> + </param_color> + </param> + + <param + id="1017" + group="1" + edit_group="driven" + wearable="pants" + name="Waist Height Cloth" + value_min="0" + value_max="1"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> + </param> + + <param + id="1018" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Cloth" + value_min="0" + value_max="1"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_pants"> + <texture + local_texture="lower_pants" /> + + <param + id="806" + group="0" + wearable="pants" + edit_group="colorpicker" + name="pants_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="807" + group="0" + wearable="pants" + edit_group="colorpicker" + name="pants_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="808" + group="0" + wearable="pants" + edit_group="colorpicker" + name="pants_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + <param + id="614" + group="1" + edit_group="driven" + wearable="pants" + name="Waist Height Cloth" + value_min="0" + value_max="1" + value_default=".8"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> + </param> + + <param + id="615" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Cloth" + value_min="0" + value_max="1" + value_default=".8"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_jacket base bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_jacket" + local_texture_alpha_only="true" /> + + <param + id="1033" + group="1" + wearable="jacket" + edit_group="driven" + cross_wearable="true" + name="jacket bottom length lower bump" + value_min="0" + value_max="1"> + <param_alpha + multiply_blend="false" + tga_file="jacket_length_lower_alpha.tga" + domain="0.01" /> + </param> + + <param + id="1034" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket open lower bump" + value_min="0" + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_lower_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_jacket bump" + render_pass="bump"> + <texture + tga_file="bump_pants_wrinkles.tga" /> + + <texture + local_texture="lower_jacket" + local_texture_alpha_only="true" /> + + + <param + id="876" + group="1" + wearable="jacket" + name="jacket upper Wrinkles" + value_min="0" + value_max="1" + value_default="0"> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 255" /> + </param_color> + </param> + + <param + id="1027" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket bottom length lower bump" + value_min="0" + value_max="1"> + <param_alpha + multiply_blend="false" + tga_file="jacket_length_lower_alpha.tga" + domain="0.01" /> + </param> + + <param + id="1028" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket open lower bump" + value_min="0" + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_lower_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower_jacket"> + <texture + local_texture="lower_jacket" /> + + <param + id="809" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="lower_jacket_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="810" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="lower_jacket_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="811" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="lower_jacket_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + <param + id="621" + group="1" + wearable="jacket" + edit_group="jacket" + name="bottom length lower" + label_min="hi cut" + label_max="low cut" + value_min="0" + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_alpha + multiply_blend="false" + tga_file="jacket_length_lower_alpha.tga" + domain="0.01" /> + </param> + + <param + id="623" + group="1" + wearable="jacket" + edit_group="jacket" + name="open lower" + label_min="open" + label_max="closed" + value_min="0" + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_lower_alpha.tga" + domain="0.01" /> + </param> + </layer> + + <layer + name="lower alpha" + visibility_mask="TRUE"> + <texture + local_texture="lower_alpha" /> + </layer> + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="eyes" + width="128" + height="128"> + <layer + name="whites"> + <texture + tga_file="eyewhite.tga" /> + </layer> + + <layer + name="iris" + global_color="eye_color"> + <texture + local_texture="eyes_iris" /> + </layer> + + <layer + name="eyes alpha" + visibility_mask="TRUE"> + <texture + local_texture="eyes_alpha" /> + </layer> + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="skirt" + width="512" + height="512" + clear_alpha="false"> + <layer + name="skirt_fabric" + write_all_channels="true"> + <texture + local_texture="skirt" /> + + <param + id="921" + group="0" + wearable="skirt" + edit_group="colorpicker" + name="skirt_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="922" + group="0" + wearable="skirt" + edit_group="colorpicker" + name="skirt_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="923" + group="0" + wearable="skirt" + edit_group="colorpicker" + name="skirt_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + </layer> + + <layer + name="skirt_fabric_alpha"> + <param + id="858" + group="0" + wearable="skirt" + edit_group="skirt" + edit_group_order="1" + name="Skirt Length" + show_simple="true" + label_min="Short" + label_max="Long" + value_min=".01" + value_max="1" + value_default=".4" + simple_percent_min="40" + simple_percent_max="100" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="30"> + <param_alpha + tga_file="skirt_length_alpha.tga" + domain="0" + multiply_blend="true" /> + </param> + + <param + id="859" + group="0" + wearable="skirt" + edit_group="skirt" + edit_group_order="4" + name="Slit Front" + label_min="Open Front" + label_max="Closed Front" + value_min="0" + value_max="1" + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="30"> + <param_alpha + tga_file="skirt_slit_front_alpha.tga" + multiply_blend="true" + domain="0" /> + </param> + + <param + id="860" + group="0" + wearable="skirt" + edit_group="skirt" + edit_group_order="5" + name="Slit Back" + label_min="Open Back" + label_max="Closed Back" + value_min="0" + value_max="1" + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="160"> + <param_alpha + tga_file="skirt_slit_back_alpha.tga" + multiply_blend="true" + domain="0" /> + </param> + + <param + id="861" + group="0" + wearable="skirt" + edit_group="skirt" + edit_group_order="6" + name="Slit Left" + label_min="Open Left" + label_max="Closed Left" + value_min="0" + value_max="1" + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="30"> + <param_alpha + tga_file="skirt_slit_left_alpha.tga" + multiply_blend="true" + domain="0" /> + </param> + + <param + id="862" + group="0" + wearable="skirt" + edit_group="skirt" + edit_group_order="7" + name="Slit Right" + label_min="Open Right" + label_max="Closed Right" + value_min="0" + value_max="1" + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="-30"> + <param_alpha + tga_file="skirt_slit_right_alpha.tga" + multiply_blend="true" + domain="0" /> + </param> + </layer> + + </layer_set> + + <!-- =========================================================== --> + <driver_parameters> + + <param + id="2" + group="0" + name="Nose_Big_Out" + label="Nose Size" + wearable="shape" + edit_group="shape_nose" + edit_group_order="1" + label_min="Small" + label_max="Large" + show_simple="true" + value_min="-0.8" + value_max="2.5" + camera_elevation=".1" + camera_distance=".35" + camera_angle="50"> + <param_driver> + <driven + id="20002" /> + <driven + id="30002" /> + </param_driver> + </param> + + <param + id="4" + group="0" + name="Broad_Nostrils" + label="Nostril Width" + wearable="shape" + edit_group="shape_nose" + edit_group_order="3" + label_min="Narrow" + label_max="Broad" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20004" /> + <driven + id="30004" /> + </param_driver> + </param> + + <param + id="517" + group="0" + name="Wide_Nose" + label="Nose Width" + wearable="shape" + edit_group="shape_nose" + edit_group_order="2" + label_min="Narrow" + label_max="Wide" + show_simple="true" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20517" /> + <driven + id="30517" /> + </param_driver> + </param> + + <param + id="20" + group="0" + name="Bulbous_Nose" + label="Nose Thickness" + wearable="shape" + edit_group="shape_nose" + edit_group_order="4" + label_min="Thin Nose" + label_max="Bulbous Nose" + show_simple="true" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".3"> + <param_driver> + <driven + id="20020" /> + <driven + id="30020" /> + </param_driver> + </param> + + <param + id="656" + group="0" + name="Crooked_Nose" + wearable="shape" + label="Crooked Nose" + edit_group="shape_nose" + edit_group_order="9" + label_min="Nose Left" + label_max="Nose Right" + value_min="-2" + value_max="2" + camera_distance=".3" + camera_elevation=".04" + camera_angle="-20"> + <param_driver> + <driven + id="20656" /> + <driven + id="30656" /> + </param_driver> + </param> + + <param + id="653" + group="0" + name="Tall_Lips" + wearable="shape" + label="Lip Fullness" + show_simple="true" + edit_group="shape_mouth" + edit_group_order="2" + label_min="Less Full" + label_max="More Full" + value_min="-1" + value_max="2" + camera_distance=".3" + camera_elevation=".04"> + <param_driver> + <driven + id="20653" /> + <driven + id="30653" /> + </param_driver> + </param> + + <param + id="506" + group="0" + name="Mouth_Height" + wearable="shape" + label="Mouth Position" + show_simple="true" + edit_group="shape_mouth" + edit_group_order="4" + label_min="High" + label_max="Low" + value_min="-2" + value_max="2" + camera_distance=".3" + camera_elevation=".04"> + <param_driver> + <driven + id="20506" /> + <driven + id="30506" /> + </param_driver> + </param> + + <param + id="764" + group="0" + name="Lip_Cleft_Deep" + label="Lip Cleft Depth" + wearable="shape" + edit_group="shape_mouth" + edit_group_order="5.8" + label_min="Shallow" + label_max="Deep" + value_min="-.5" + value_max="1.2" + camera_elevation="0" + camera_distance=".28"> + <param_driver> + <driven + id="20764" /> + <driven + id="30764" /> + </param_driver> + </param> + + <param + id="25" + group="0" + name="Wide_Lip_Cleft" + label="Lip Cleft" + wearable="shape" + edit_group="shape_mouth" + edit_group_order="6" + label_min="Narrow" + label_max="Wide" + value_min="-.8" + value_max="1.5" + camera_elevation="0" + camera_distance=".28"> + <param_driver> + <driven + id="20025" /> + <driven + id="30025" /> + </param_driver> + </param> + + <param + id="663" + group="0" + name="Shift_Mouth" + wearable="shape" + label="Shift Mouth" + edit_group="shape_mouth" + edit_group_order="7" + label_min="Shift Left" + label_max="Shift Right" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".35" + camera_elevation=".04" + camera_angle="-20"> + <param_driver> + <driven + id="20663" /> + + <driven + id="31663" + min1="-2" + max1="-2" + max2="-2" + min2="0" /> + <driven + id="32663" + min1="0" + max1="2" + max2="2" + min2="2" /> + </param_driver> + </param> + + <param + id="35" + group="0" + name="Big_Ears" + label="Ear Size" + wearable="shape" + edit_group="shape_ears" + edit_group_order="1" + label_min="Small" + label_max="Large" + value_min="-1" + value_max="2" + camera_elevation=".1" + camera_distance=".3" + camera_angle="45"> + <param_driver> + <driven + id="20035" /> + <driven + id="30035" /> + </param_driver> + </param> + + <param + id="15" + group="0" + name="Ears_Out" + label="Ear Angle" + wearable="shape" + edit_group="shape_ears" + edit_group_order="2" + label_min="In" + label_max="Out" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20015" /> + <driven + id="30015" /> + </param_driver> + </param> + + <param + id="796" + group="0" + name="Pointy_Ears" + label="Ear Tips" + wearable="shape" + edit_group="shape_ears" + edit_group_order="4" + label_min="Flat" + label_max="Pointy" + value_min="-.4" + value_max="3" + camera_elevation=".1" + camera_distance=".3" + camera_angle="45"> + <param_driver> + <driven + id="20796" /> + <driven + id="30796" /> + </param_driver> + </param> + + <param + id="185" + group="0" + name="Deep_Chin" + label="Chin Depth" + wearable="shape" + edit_group="shape_chin" + edit_group_order="3" + label_min="Shallow" + label_max="Deep" + value_min="-1" + value_max="1" + camera_elevation=".1" + camera_distance=".4" + camera_angle="30"> + <param_driver> + <driven + id="20185" /> + <driven + id="30185" /> + </param_driver> + </param> + + <param + id="760" + group="0" + name="Jaw_Angle" + wearable="shape" + label="Jaw Angle" + edit_group="shape_chin" + edit_group_order="3.5" + label_min="Low Jaw" + label_max="High Jaw" + value_min="-1.2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04" + camera_angle="70"> + <param_driver> + <driven + id="20760" /> + <driven + id="30760" /> + </param_driver> + </param> + + + <param + id="665" + group="0" + name="Jaw_Jut" + wearable="shape" + label="Jaw Jut" + edit_group="shape_chin" + edit_group_order="4" + label_min="Overbite" + label_max="Underbite" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04" + camera_angle="70"> + <param_driver> + <driven + id="20665" /> + <driven + id="30665" /> + </param_driver> + </param> + + <param + id="6" + group="0" + name="Bulbous_Nose_Tip" + label="Nose Tip Shape" + wearable="shape" + edit_group="shape_nose" + edit_group_order="8" + label_min="Pointy" + label_max="Bulbous" + value_min="-.3" + value_max="1" + camera_elevation=".1" + camera_distance=".35" + camera_angle="15"> + <param_driver> + <driven + id="20006" /> + <driven + id="30006" /> + </param_driver> + </param> + + <param + id="7" + group="0" + name="Weak_Chin" + label="Chin Angle" + wearable="shape" + edit_group="shape_chin" + edit_group_order="1" + label_min="Chin Out" + label_max="Chin In" + value_min="-.5" + value_max=".5" + camera_elevation=".1" + camera_distance=".4" + camera_angle="45"> + <param_driver> + <driven + id="20007" /> + <driven + id="30007" /> + </param_driver> + </param> + + <param + id="8" + group="0" + name="Double_Chin" + label="Chin-Neck" + wearable="shape" + edit_group="shape_chin" + edit_group_order="8" + label_min="Tight Chin" + label_max="Double Chin" + value_min="-.5" + value_max="1.5" + camera_elevation="-.1" + camera_distance=".3" + camera_angle="60"> + <param_driver> + <driven + id="20008" /> + <driven + id="30008" /> + </param_driver> + </param> + + + <param + id="24" + group="0" + name="Wide_Eyes" + label="Eye Opening" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="1.1" + label_min="Narrow" + label_max="Wide" + value_min="-1.5" + value_max="2" + show_simple="true" + camera_elevation=".1" + camera_distance=".35"> + <param_driver> + <driven + id="20024" /> + <driven + id="30024" /> + </param_driver> + </param> + + <param + id="650" + group="0" + name="Eyelid_Corner_Up" + label="Outer Eye Corner" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="4" + label_min="Corner Down" + label_max="Corner Up" + value_min="-1.3" + value_max="1.2" + camera_elevation=".1" + camera_distance=".30"> + <param_driver> + <driven + id="20650" /> + <driven + id="30650" /> + </param_driver> + </param> + + <param + id="880" + group="0" + name="Eyelid_Inner_Corner_Up" + label="Inner Eye Corner" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="4.2" + label_min="Corner Down" + label_max="Corner Up" + value_min="-1.3" + value_max="1.2" + camera_elevation=".1" + camera_distance=".30"> + <param_driver> + <driven + id="20880" /> + <driven + id="30880" /> + </param_driver> + </param> + + <param + id="21" + group="0" + name="Upper_Eyelid_Fold" + label="Upper Eyelid Fold" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="5" + label_min="Uncreased" + label_max="Creased" + value_min="-0.2" + value_max="1.3" + camera_elevation=".1" + camera_distance=".35"> + <param_driver> + <driven + id="20021" /> + <driven + id="30021" /> + </param_driver> + </param> + + <param + id="23" + group="0" + name="Baggy_Eyes" + label="Eye Bags" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="6" + label_min="Smooth" + label_max="Baggy" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".35"> + <param_driver> + <driven + id="20023" /> + <driven + id="30023" /> + </param_driver> + </param> + + <param + id="765" + group="0" + name="Puffy_Lower_Lids" + label="Puffy Eyelids" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="6.1" + label_min="Flat" + label_max="Puffy" + value_min="-.3" + value_max="2.5" + camera_elevation=".1" + camera_distance=".35"> + <param_driver> + <driven + id="20765" /> + <driven + id="30765" /> + </param_driver> + </param> + + <param + id="1" + group="0" + name="Big_Brow" + label="Brow Size" + wearable="shape" + edit_group="shape_head" + edit_group_order="7" + label_min="Small" + label_max="Large" + value_min="-.3" + value_max="2" + camera_elevation=".1" + camera_distance=".4" + camera_angle="45"> + <param_driver> + <driven + id="20001" /> + <driven + id="30001" /> + </param_driver> + </param> + + <param + id="11" + group="0" + name="Noble_Nose_Bridge" + label="Upper Bridge" + wearable="shape" + edit_group="shape_nose" + edit_group_order="5" + label_min="Low" + label_max="High" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".35" + camera_angle="70"> + <param_driver> + <driven + id="20011" /> + <driven + id="30011" /> + </param_driver> + </param> + + <param + id="758" + group="0" + name="Lower_Bridge_Nose" + label="Lower Bridge" + wearable="shape" + edit_group="shape_nose" + edit_group_order="5.5" + label_min="Low" + label_max="High" + value_min="-1.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".35" + camera_angle="70"> + <param_driver> + <driven + id="20758" /> + <driven + id="30758" /> + </param_driver> + </param> + + <param + id="27" + group="0" + name="Wide_Nose_Bridge" + label="Bridge Width" + wearable="shape" + edit_group="shape_nose" + edit_group_order="6" + label_min="Narrow" + label_max="Wide" + value_min="-1.3" + value_max="1.2" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20027" /> + <driven + id="30027" /> + </param_driver> + </param> + + <param + id="759" + group="0" + name="Low_Septum_Nose" + label="Nostril Division" + wearable="shape" + edit_group="shape_nose" + edit_group_order="3.5" + label_min="High" + label_max="Low" + value_min="-1" + value_max="1.5" + value_default="0.5" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20759" /> + <driven + id="30759" /> + </param_driver> + </param> + - <!-- =========================================================== --> - <driver_parameters> + <param + id="10" + group="0" + name="Sunken_Cheeks" + label="Lower Cheeks" + wearable="shape" + edit_group="shape_head" + edit_group_order="9" + label_min="Well-Fed" + label_max="Sunken" + show_simple="true" + value_min="-1.5" + value_max="3" + camera_elevation=".1" + camera_distance=".4" + camera_angle="5"> + <param_driver> + <driven + id="20010" /> + <driven + id="30010" /> + </param_driver> + </param> + + <param + id="17" + group="0" + name="Square_Jaw" + label="Jaw Shape" + wearable="shape" + edit_group="shape_chin" + edit_group_order="2" + label_min="Pointy" + label_max="Square" + value_min="-.5" + value_max="1" + camera_distance=".3" + camera_elevation=".04" + camera_angle="-20"> + <param_driver> + <driven + id="20017" /> + <driven + id="30017" /> + </param_driver> + </param> + + <param + id="18" + group="0" + name="Puffy_Upper_Cheeks" + label="Upper Cheeks" + wearable="shape" + edit_group="shape_head" + edit_group_order="8" + label_min="Thin" + label_max="Puffy" + value_min="-1.5" + value_max="2.5" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20018" /> + <driven + id="30018" /> + </param_driver> + </param> + + <param + id="14" + group="0" + name="High_Cheek_Bones" + label="Cheek Bones" + wearable="shape" + edit_group="shape_head" + edit_group_order="10" + label_min="Low" + label_max="High" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_driver> + <driven + id="20014" /> + <driven + id="30014" /> + </param_driver> + </param> + + <param + id="19" + group="0" + name="Upturned_Nose_Tip" + label="Nose Tip Angle" + wearable="shape" + edit_group="shape_nose" + edit_group_order="7" + label_min="Downturned" + label_max="Upturned" + value_min="-1.5" + value_max="1" + camera_elevation=".1" + camera_distance=".35" + camera_angle="15"> + <param_driver> + <driven + id="20019" /> + <driven + id="30019" /> + </param_driver> + </param> <param id="828" @@ -9807,6 +13664,20 @@ render_pass="bump"> max1="1" max2="1" min2="1" /> + + <driven + id="30505" + min1="0" + max1="0" + max2="0" + min2=".5" /> + <driven + id="31505" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> </param> @@ -9817,8 +13688,8 @@ render_pass="bump"> edit_group="shape_mouth" edit_group_order="3.2" name="Lip Ratio" - label="Lip Ratio" - show_simple="true" + label="Lip Ratio" + show_simple="true" label_min="More Upper Lip" label_max="More Lower Lip" value_min="0" @@ -9841,6 +13712,21 @@ render_pass="bump"> max1="1" max2="1" min2="1" /> + + <driven + id="30797" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="30798" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> </param> @@ -9866,6 +13752,10 @@ render_pass="bump"> <driven id="30" /> + + <driven + id="30155" /> + </param_driver> </param> @@ -10076,6 +13966,10 @@ render_pass="bump"> max1="1" max2="1" min2="1" /> + + <driven + id="30193"/> + </param_driver> </param> @@ -10366,8 +14260,8 @@ render_pass="bump"> edit_group="hair_style" edit_group_order="16" name="Hair Tilt" - label_min="Hair Tilted Left" - label_max="Hair Tilted Right" + label_min="Left" + label_max="Right" value_min="0" value_max="1" value_default=".5" @@ -10548,6 +14442,21 @@ render_pass="bump"> max1="1" max2="1" min2="1" /> + + <driven + id="31629" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="32629" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> </param> @@ -10574,6 +14483,14 @@ render_pass="bump"> <driven id="186" /> + + <driven + min1="-1.3" + max1="-1.3" + max2="-1.3" + min2="1" + id="30646" /> + </param_driver> </param> @@ -10600,6 +14517,10 @@ render_pass="bump"> <driven id="187" /> + + <driven + id="30647" /> + </param_driver> </param> @@ -10630,7 +14551,7 @@ render_pass="bump"> min2=".5" /> <driven - id="106" + id="107" min1=".5" max1="1" max2="1" @@ -10758,8 +14679,23 @@ render_pass="bump"> min1=".5" max1="1" max2="1" + min2="1" /> + + <driven + id="30658" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="30657" + min1=".5" + max1="1" + max2="1" min2="1" /> </param_driver> + </param> <param @@ -10812,6 +14748,24 @@ render_pass="bump"> <driven id="772" /> + + <driven + id="30772" /> + + <driven + min1="0" + max1="0" + max2="0" + min2="0.45" + id="31772" /> + + <driven + min1="0.5" + max1="1" + max2="1" + min2="1" + id="32772" /> + </param_driver> </param> @@ -10822,7 +14776,7 @@ render_pass="bump"> edit_group="shape_head" edit_group_order="1" name="Head Size" - label="Head Size" + label="Head Size" label_min="Small Head" label_max="Big Head" show_simple="true" @@ -10856,16 +14810,17 @@ render_pass="bump"> edit_group="shape_eyes" edit_group_order="1" name="Eye Size" - label="Eye Size" + label="Eye Size" label_min="Beady Eyes" label_max="Anime Eyes" value_min="0" value_max="1" value_default=".5" - show_simple="true" + show_simple="true" camera_elevation=".1" camera_distance=".35"> <param_driver> + <driven id="686" /> @@ -10883,6 +14838,10 @@ render_pass="bump"> <driven id="689" /> + + <driven + id="30689" /> + </param_driver> </param> @@ -11168,6 +15127,31 @@ render_pass="bump"> </param_driver> </param> + <param + id="879" + group="0" + sex="male" + name="Male_Package" + label="Package" + wearable="shape" + edit_group="shape_legs" + edit_group_order="4.6" + label_min="Coin Purse" + label_max="Duffle Bag" + value_default="0" + value_min="-.5" + value_max="2" + camera_angle="60" + camera_distance=".6"> + <param_driver> + <driven + id="20879" /> + + <driven + id="30879" /> + </param_driver> + </param> + <param id="841" group="0" @@ -11302,6 +15286,10 @@ render_pass="bump"> <driven id="1001" /> + + <driven + id="30119" /> + </param_driver> </param> @@ -11766,6 +15754,8 @@ render_pass="bump"> <param_driver> <driven id="870" /> + <driven + id="30016"/> </param_driver> </param> @@ -11789,6 +15779,8 @@ render_pass="bump"> <param_driver> <driven id="871" /> + <driven + id="30757"/> </param_driver> </param> @@ -11811,6 +15803,8 @@ render_pass="bump"> <param_driver> <driven id="872" /> + <driven + id="30031"/> </param_driver> </param> diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml index 6b07bbc1d3d5fcbac2a50b2eb834f867d81de75d..2241a12545ffd942b86c3ed87422cdceb0ac0798 100644 --- a/indra/newview/character/avatar_skeleton.xml +++ b/indra/newview/character/avatar_skeleton.xml @@ -1,81 +1,232 @@ -<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> -<linden_skeleton version="1.0" num_bones="53" num_collision_volumes="26"> -<bone name="mPelvis" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 1.067015"> - <collision_volume name="PELVIS" pos = "-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17"/> - <collision_volume name="BUTT" pos = "-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1"/> - <bone name="mTorso" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.084073"> - <collision_volume name="BELLY" pos = "0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15"/> - <collision_volume name="LOWER_BACK" pos = "0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/> - <collision_volume name="LEFT_HANDLE" pos = "0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/> - <collision_volume name="RIGHT_HANDLE" pos = "0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/> - <bone name="mChest" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.015368 0.000000 0.204877"> - <collision_volume name="CHEST" pos = "0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2"/> - <collision_volume name="UPPER_BACK" pos = "0.0 0.0 0.017" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/> - <collision_volume name="LEFT_PEC" pos = "0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/> - <collision_volume name="RIGHT_PEC" pos = "0.119 -0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/> - <bone name="mNeck" pos="-0.010 0.000 0.251" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.009507 0.000000 0.251108"> - <collision_volume name="NECK" pos = "0.0 0 0.02" rot="0.000000 0.000000 0.000000" scale="0.05 0.06 0.08"/> - <bone name="mHead" pos="0.000 -0.000 0.076" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.000000 0.075630"> - <collision_volume name="HEAD" pos = "0.02 0 0.07" rot="0.000000 0.000000 0.000000" scale="0.11 0.09 0.12"/> - <bone name="mSkull" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.079000"> - </bone> - <bone name="mEyeRight" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" pivot="0.098466 -0.036000 0.079000"> - </bone> - <bone name="mEyeLeft" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.098461 0.036000 0.079000"> - </bone> - </bone> - </bone> - <bone name="mCollarLeft" pos="-0.021 0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.020927 0.084665 0.165396"> - <collision_volume name="L_CLAVICLE" pos = "0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05"/> - <bone name="mShoulderLeft" pos="0.000 0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.079000 -0.000000"> - <collision_volume name="L_UPPER_ARM" pos = "0.0 0.12 0.01" rot="-5.000000 0.00000 0.000000" scale="0.05 0.17 0.05"/> - <bone name="mElbowLeft" pos="0.000 0.248 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.248000 0.000000"> - <collision_volume name="L_LOWER_ARM" pos = "0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04"/> - <bone name="mWristLeft" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000000 0.204846 0.000000"> - <collision_volume name="L_HAND" pos = "0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03"/> - </bone> - </bone> - </bone> - </bone> - <bone name="mCollarRight" pos="-0.021 -0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.020927 -0.085000 0.165396"> - <collision_volume name="R_CLAVICLE" pos = "0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05"/> - <bone name="mShoulderRight" pos="0.000 -0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.079418 -0.000000"> - <collision_volume name="R_UPPER_ARM" pos = "0.0 -0.12 0.01" rot="5.000000 0.00000 0.000000" scale="0.05 0.17 0.05"/> - <bone name="mElbowRight" pos="0.000 -0.248 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.248000 -0.000000"> - <collision_volume name="R_LOWER_ARM" pos = "0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04"/> - <bone name="mWristRight" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000000 -0.205000 -0.000000"> - <collision_volume name="R_HAND" pos = "0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03"/> - </bone> - </bone> - </bone> - </bone> - </bone> - </bone> - <bone name="mHipRight" pos="0.034 -0.129 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.033620 -0.128806 -0.041086"> - <collision_volume name="R_UPPER_LEG" pos = "-0.02 0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32"/> - <bone name="mKneeRight" pos="-0.001 0.049 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000780 0.048635 -0.490922"> - <collision_volume name="R_LOWER_LEG" pos = "-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25"/> - <bone name="mAnkleRight" pos="-0.029 0.000 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.028869 0.000000 -0.468494"> - <collision_volume name="R_FOOT" pos = "0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05"/> - <bone name="mFootRight" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.111956 -0.000000 -0.060637"> - <bone name="mToeRight" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.105399 -0.010408 -0.000104"> - </bone> - </bone> - </bone> - </bone> - </bone> - <bone name="mHipLeft" pos="0.034 0.127 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.033757 0.126765 -0.040998"> - <collision_volume name="L_UPPER_LEG" pos = "-0.02 -0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32"/> - <bone name="mKneeLeft" pos="-0.001 -0.046 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000887 -0.045568 -0.491053"> - <collision_volume name="L_LOWER_LEG" pos = "-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25"/> - <bone name="mAnkleLeft" pos="-0.029 0.001 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.028887 0.001378 -0.468449"> - <collision_volume name="L_FOOT" pos = "0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05"/> - <bone name="mFootLeft" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.111956 -0.000000 -0.060620"> - <bone name="mToeLeft" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.105387 0.008270 0.000871"> - </bone> - </bone> - </bone> - </bone> - </bone> -</bone> -</linden_skeleton> \ No newline at end of file +<linden_skeleton num_bones="133" num_collision_volumes="26" version="2.0"> + <bone aliases="hip avatar_mPelvis" connected="false" end="0.000 0.000 0.084" group="Torso" name="mPelvis" pivot="0.000000 0.000000 1.067015" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.030 0.000 0.095" group="Collision" name="PELVIS" pos="-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17" support="base"/> + <collision_volume end="-0.100 0.000 0.000" group="Collision" name="BUTT" pos="-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1" support="base"/> + <bone connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="abdomen avatar_mTorso" connected="true" end="-0.015 0.000 0.205" group="Torso" name="mTorso" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.028 0.000 0.094" group="Collision" name="BELLY" pos="0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15" support="base"/> + <collision_volume end="0.000 0.100 0.000" group="Collision" name="LEFT_HANDLE" pos="0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/> + <collision_volume end="0.000 -0.100 0.000" group="Collision" name="RIGHT_HANDLE" pos="0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/> + <collision_volume end="-0.100 0.000 0.000" group="Collision" name="LOWER_BACK" pos="0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/> + <bone connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="chest avatar_mChest" connected="true" end="-0.010 0.000 0.250" group="Torso" name="mChest" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="-0.096 0.000 0.152" group="Collision" name="CHEST" pos="0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2" support="base"/> + <collision_volume end="0.080 0.000 -0.006" group="Collision" name="LEFT_PEC" pos="0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/> + <collision_volume end="0.080 0.000 -0.006" group="Collision" name="RIGHT_PEC" pos="0.119 -0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/> + <collision_volume end="-0.100 0.000 0.000" group="Collision" name="UPPER_BACK" pos="0.0 0.0 0.017" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/> + <bone aliases="neck avatar_mNeck" connected="true" end="0.000 0.000 0.077" group="Torso" name="mNeck" pivot="-0.009507 0.000000 0.251108" pos="-0.010 0.000 0.251" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.000 0.080" group="Collision" name="NECK" pos="0.0 0 0.02" rot="0.000000 0.000000 0.000000" scale="0.05 0.06 0.08" support="base"/> + <bone aliases="head avatar_mHead" connected="true" end="0.000 0.000 0.079" group="Torso" name="mHead" pivot="0.000000 -0.000000 0.075630" pos="0.000 -0.000 0.076" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.000 0.100" group="Collision" name="HEAD" pos="0.02 0 0.07" rot="0.000000 0.000000 0.000000" scale="0.11 0.09 0.12" support="base"/> + <bone aliases="figureHair avatar_mSkull" connected="false" end="0.000 0.000 0.033" group="Extra" name="mSkull" pivot="0.000000 0.000000 0.079000" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> + <bone aliases="avatar_mEyeRight" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeRight" pivot="0.098466 -0.036000 0.079000" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" support="base"/> + <bone aliases="avatar_mEyeLeft" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeLeft" pivot="0.098461 0.036000 0.079000" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> + <bone connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + <bone connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + <bone connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + <bone connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + <bone aliases="lCollar avatar_mCollarLeft" connected="false" end="0.000 0.079 0.000" group="Arms" name="mCollarLeft" pivot="-0.020927 0.084665 0.165396" pos="-0.021 0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.100 0.000" group="Collision" name="L_CLAVICLE" pos="0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05" support="base"/> + <bone aliases="lShldr avatar_mShoulderLeft" connected="true" end="0.000 0.247 0.000" group="Arms" name="mShoulderLeft" pivot="0.000000 0.079000 -0.000000" pos="0.000 0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.130 -0.003" group="Collision" name="L_UPPER_ARM" pos="0.0 0.12 0.01" rot="-5.000000 0.00000 0.000000" scale="0.05 0.17 0.05" support="base"/> + <bone aliases="lForeArm avatar_mElbowLeft" connected="true" end="0.000 0.205 0.000" group="Arms" name="mElbowLeft" pivot="0.000000 0.248000 0.000000" pos="0.000 0.248 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.100 -0.001" group="Collision" name="L_LOWER_ARM" pos="0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/> + <bone aliases="lHand avatar_mWristLeft" connected="true" end="0.000 0.060 0.000" group="Arms" name="mWristLeft" pivot="-0.000000 0.204846 0.000000" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.005 0.049 -0.001" group="Collision" name="L_HAND" pos="0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03" support="base"/> + <bone connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + <bone aliases="rCollar avatar_mCollarRight" connected="false" end="0.000 -0.079 0.000" group="Arms" name="mCollarRight" pivot="-0.020927 -0.085000 0.165396" pos="-0.021 -0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 -0.100 0.000" group="Collision" name="R_CLAVICLE" pos="0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05" support="base"/> + <bone aliases="rShldr avatar_mShoulderRight" connected="true" end="0.000 -0.247 0.000" group="Arms" name="mShoulderRight" pivot="0.000000 -0.079418 -0.000000" pos="0.000 -0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 -0.130 -0.003" group="Collision" name="R_UPPER_ARM" pos="0.0 -0.12 0.01" rot="5.000000 0.00000 0.000000" scale="0.05 0.17 0.05" support="base"/> + <bone aliases="rForeArm avatar_mElbowRight" connected="true" end="0.000 -0.205 0.000" group="Arms" name="mElbowRight" pivot="0.000000 -0.248000 -0.000000" pos="0.000 -0.248 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 -0.100 -0.001" group="Collision" name="R_LOWER_ARM" pos="0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/> + <bone aliases="rHand avatar_mWristRight" connected="true" end="0.000 -0.060 0.000" group="Arms" name="mWristRight" pivot="-0.000000 -0.205000 -0.000000" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.005 -0.049 -0.001" group="Collision" name="R_HAND" pos="0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03" support="base"/> + <bone connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + <bone connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + <bone connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + <bone connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + </bone> + <bone aliases="rThigh avatar_mHipRight" connected="false" end="-0.001 0.049 -0.491" group="Legs" name="mHipRight" pivot="0.033620 -0.128806 -0.041086" pos="0.034 -0.129 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.000 -0.200" group="Collision" name="R_UPPER_LEG" pos="-0.02 0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32" support="base"/> + <bone aliases="rShin avatar_mKneeRight" connected="true" end="-0.029 0.000 -0.469" group="Legs" name="mKneeRight" pivot="-0.000780 0.048635 -0.490922" pos="-0.001 0.049 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="-0.010 0.000 -0.150" group="Collision" name="R_LOWER_LEG" pos="-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25" support="base"/> + <bone aliases="rFoot avatar_mAnkleRight" connected="true" end="0.112 0.000 -0.061" group="Legs" name="mAnkleRight" pivot="-0.028869 0.000000 -0.468494" pos="-0.029 0.000 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.089 0.000 -0.026" group="Collision" name="R_FOOT" pos="0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05" support="base"/> + <bone aliases="avatar_mFootRight" connected="true" end="0.105 -0.010 0.000" group="Extra" name="mFootRight" pivot="0.111956 -0.000000 -0.060637" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <bone aliases="avatar_mToeRight" connected="false" end="0.020 0.000 0.000" group="Extra" name="mToeRight" pivot="0.105399 -0.010408 -0.000104" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> + </bone> + </bone> + </bone> + </bone> + <bone aliases="lThigh avatar_mHipLeft" connected="false" end="-0.001 -0.046 -0.491" group="Legs" name="mHipLeft" pivot="0.033757 0.126765 -0.040998" pos="0.034 0.127 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.000 0.000 -0.200" group="Collision" name="L_UPPER_LEG" pos="-0.02 -0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32" support="base"/> + <bone aliases="lShin avatar_mKneeLeft" connected="true" end="-0.029 0.001 -0.469" group="Legs" name="mKneeLeft" pivot="-0.000887 -0.045568 -0.491053" pos="-0.001 -0.046 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="-0.010 0.000 -0.150" group="Collision" name="L_LOWER_LEG" pos="-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25" support="base"/> + <bone aliases="lFoot avatar_mAnkleLeft" connected="true" end="0.112 0.000 -0.061" group="Legs" name="mAnkleLeft" pivot="-0.028887 0.001378 -0.468449" pos="-0.029 0.001 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <collision_volume end="0.089 0.000 -0.026" group="Collision" name="L_FOOT" pos="0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05" support="base"/> + <bone aliases="avatar_mFootLeft" connected="true" end="0.105 0.008 0.001" group="Extra" name="mFootLeft" pivot="0.111956 -0.000000 -0.060620" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> + <bone aliases="avatar_mToeLeft" connected="false" end="0.020 0.000 0.000" group="Extra" name="mToeLeft" pivot="0.105387 0.008270 0.000871" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> + </bone> + </bone> + </bone> + </bone> + <bone connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + </bone> + </bone> + <bone connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + <bone connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + </bone> + </bone> + </bone> + </bone> + </bone> +</linden_skeleton> diff --git a/indra/newview/installers/darwin/fix_application_icon_position.sh b/indra/newview/installers/darwin/fix_application_icon_position.sh index 618e34820ceb6c7f90787ab04c6225b11c657e04..62abcdd07ee0b83234cc1e96cebce6e6cfc9430a 100755 --- a/indra/newview/installers/darwin/fix_application_icon_position.sh +++ b/indra/newview/installers/darwin/fix_application_icon_position.sh @@ -1,17 +1,23 @@ -# just run this script each time after you change the installer's name to fix the icon misalignment #!/bin/bash -cp -r ../../../../build-darwin-i386/newview/*.dmg ~/Desktop/TempBuild.dmg -hdid ~/Desktop/TempBuild.dmg -open -a finder /Volumes/Second\ Life\ Installer -osascript dmg-cleanup.applescript -umount /Volumes/Second\ Life\ Installer/ -hdid ~/Desktop/TempBuild.dmg -open -a finder /Volumes/Second\ Life\ Installer -#cp /Volumes/Second\ Life\ Installer/.DS_Store ~/Desktop/_DS_Store +# just run this script each time after you change the installer's name to fix the icon misalignment +mydir="$(dirname "$0")" +# If there's more than one DMG in more than one build directory, pick the most +# recent one. +dmgfile="$(ls -t "$mydir/../../../../build-darwin-*/newview/*.dmg" | head -n 1)" +dmgwork="$HOME/Desktop/TempBuild.dmg" +mounted="/Volumes/Second Life Installer" +cp -r "$dmgfile" "$dmgwork" +hdid "$dmgwork" +open -a finder "$mounted" +osascript "$mydir/dmg-cleanup.applescript" +umount "$mounted"/ +hdid "$dmgwork" +open -a finder "$mounted" +#cp "$mounted"/.DS_Store ~/Desktop/_DS_Store #chflags nohidden ~/Desktop/_DS_Store -#cp ~/Desktop/_DS_Store ./firstlook-dmg/_DS_Store -#cp ~/Desktop/_DS_Store ./publicnightly-dmg/_DS_Store -#cp ~/Desktop/_DS_Store ./release-dmg/_DS_Store -#cp ~/Desktop/_DS_Store ./releasecandidate-dmg/_DS_Store -#umount /Volumes/Second\ Life\ Installer/ -#rm ~/Desktop/_DS_Store ~/Desktop/TempBuild.dmg +#cp ~/Desktop/_DS_Store "$mydir/firstlook-dmg/_DS_Store" +#cp ~/Desktop/_DS_Store "$mydir/publicnightly-dmg/_DS_Store" +#cp ~/Desktop/_DS_Store "$mydir/release-dmg/_DS_Store" +#cp ~/Desktop/_DS_Store "$mydir/releasecandidate-dmg/_DS_Store" +#umount "$mounted"/ +#rm ~/Desktop/_DS_Store "$dmgwork" diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index 92a5413adb519991dbe223b73d4e9b6db1174e3e..1dddf5296171cd8a73d9f64b01377f02df7f90df 100644 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -31,6 +31,8 @@ #include "llcoros.h" #include "lleventcoro.h" #include "llcorehttputil.h" +#include "llexception.h" +#include "stringize.h" #include <algorithm> #include <iterator> @@ -154,13 +156,11 @@ void LLAccountingCostManager::accountingCostCoro(std::string url, } while (false); } - catch (std::exception e) - { - LL_WARNS() << "Caught exception '" << e.what() << "'" << LL_ENDL; - } catch (...) { - LL_WARNS() << "Caught unknown exception." << LL_ENDL; + LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::instance().getName() + << "('" << url << "')")); + throw; } mPendingObjectQuota.clear(); diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h index f251ceffd47694742ea1cc671713a5b40ad61349..55e1d19f05f45a298f070bdc01c7108efe01d5bc 100644 --- a/indra/newview/llaccountingcostmanager.h +++ b/indra/newview/llaccountingcostmanager.h @@ -58,9 +58,9 @@ class LLAccountingCostObserver //=============================================================================== class LLAccountingCostManager : public LLSingleton<LLAccountingCostManager> { + LLSINGLETON(LLAccountingCostManager); + public: - //Ctor - LLAccountingCostManager(); //Store an object that will be eventually fetched void addObject( const LLUUID& objectID ); //Request quotas for object list diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index d933537d2e63d5dd57c4c7bf35168bfb292bbb8b..cfb09d329b055104f824a6a2e48cf42d9776adc5 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3191,7 +3191,7 @@ void LLAgent::initOriginGlobal(const LLVector3d &origin_global) } BOOL LLAgent::leftButtonGrabbed() const -{ +{ const BOOL camera_mouse_look = gAgentCamera.cameraMouselook(); return (!camera_mouse_look && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0) || (camera_mouse_look && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0) @@ -3199,13 +3199,6 @@ BOOL LLAgent::leftButtonGrabbed() const || (camera_mouse_look && mControlsTakenPassedOnCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0); } -BOOL LLAgent::leftButtonBlocked() const -{ - const BOOL camera_mouse_look = gAgentCamera.cameraMouselook(); - return (!camera_mouse_look && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0) - || (camera_mouse_look && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0); -} - BOOL LLAgent::rotateGrabbed() const { return (mControlsTakenCount[CONTROL_YAW_POS_INDEX] > 0) @@ -3663,14 +3656,7 @@ BOOL LLAgent::anyControlGrabbed() const BOOL LLAgent::isControlGrabbed(S32 control_index) const { - if (gAgent.mControlsTakenCount[control_index] > 0) - return TRUE; - return gAgent.mControlsTakenPassedOnCount[control_index] > 0; -} - -BOOL LLAgent::isControlBlocked(S32 control_index) const -{ - return mControlsTakenCount[control_index] > 0; + return mControlsTakenCount[control_index] > 0; } void LLAgent::forceReleaseControls() @@ -3895,11 +3881,17 @@ void LLAgent::handleTeleportFinished() mIsMaturityRatingChangingDuringTeleport = false; } - // Init SLM Marketplace connection so we know which UI should be used for the user as a merchant - // Note: Eventually, all merchant will be migrated to the new SLM system and there will be no reason to show the old UI at all. - // Note: Some regions will not support the SLM cap for a while so we need to do that check for each teleport. - // *TODO : Suppress that line from here once the whole grid migrated to SLM and move it to idle_startup() (llstartup.cpp) - check_merchant_status(); + if (mRegionp) + { + if (mRegionp->capabilitiesReceived()) + { + onCapabilitiesReceivedAfterTeleport(); + } + else + { + mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport)); + } + } } void LLAgent::handleTeleportFailed() @@ -3931,6 +3923,14 @@ void LLAgent::handleTeleportFailed() } } +/*static*/ +void LLAgent::onCapabilitiesReceivedAfterTeleport() +{ + + check_merchant_status(); +} + + void LLAgent::teleportRequest( const U64& region_handle, const LLVector3& pos_local, @@ -4176,6 +4176,8 @@ void LLAgent::setTeleportState(ETeleportState state) void LLAgent::stopCurrentAnimations() { + LL_DEBUGS("Avatar") << "Stopping current animations" << LL_ENDL; + // This function stops all current overriding animations on this // avatar, propagating this change back to the server. if (isAgentAvatarValid()) @@ -4193,6 +4195,7 @@ void LLAgent::stopCurrentAnimations() // don't cancel a ground-sit anim, as viewers // use this animation's status in // determining whether we're sitting. ick. + LL_DEBUGS("Avatar") << "sit or do-not-disturb animation will not be stopped" << LL_ENDL; } else { @@ -4222,8 +4225,7 @@ void LLAgent::stopCurrentAnimations() // re-assert at least the default standing animation, because // viewers get confused by avs with no associated anims. - sendAnimationRequest(ANIM_AGENT_STAND, - ANIM_REQUEST_START); + sendAnimationRequest(ANIM_AGENT_STAND, ANIM_REQUEST_START); } } diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 3a533c2cba7564b981020476845af74eaab26ebd..b5da5e9062e2a25d75d223e75372b4b326a664f9 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -444,8 +444,7 @@ class LLAgent : public LLOldEvents::LLObservable // Grab //-------------------------------------------------------------------- public: - BOOL leftButtonGrabbed() const; - BOOL leftButtonBlocked() const; + BOOL leftButtonGrabbed() const; BOOL rotateGrabbed() const; BOOL forwardGrabbed() const; BOOL backwardGrabbed() const; @@ -462,9 +461,8 @@ class LLAgent : public LLOldEvents::LLObservable BOOL controlFlagsDirty() const; void enableControlFlagReset(); void resetControlFlags(); - BOOL anyControlGrabbed() const; // True if a script has taken over any control - BOOL isControlGrabbed(S32 control_index) const; // True if a script has taken over a control - BOOL isControlBlocked(S32 control_index) const; // Control should be ignored or won't be passed + BOOL anyControlGrabbed() const; // True iff a script has taken over a control + BOOL isControlGrabbed(S32 control_index) const; // Send message to simulator to force grabbed controls to be // released, in case of a poorly written script. void forceReleaseControls(); @@ -676,6 +674,8 @@ class LLAgent : public LLOldEvents::LLObservable void handleTeleportFinished(); void handleTeleportFailed(); + static void onCapabilitiesReceivedAfterTeleport(); + //-------------------------------------------------------------------- // Teleport State //-------------------------------------------------------------------- diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index fa16f02c16cc154e0c0214871b9b1bda4c204dad..e335eabd1af7bf29e8d2aa217228e6affc5f2386 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1448,6 +1448,7 @@ void LLAgentCamera::updateCamera() diff.mV[VZ] = 0.f; } + // SL-315 gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff); gAgentAvatarp->mRoot->updateWorldMatrixChildren(); @@ -2144,6 +2145,7 @@ void LLAgentCamera::changeCameraToFollow(BOOL animate) if (isAgentAvatarValid()) { + // SL-315 gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero); gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE ); gAgentAvatarp->startMotion( ANIM_AGENT_BREATHE_ROT ); @@ -2184,6 +2186,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) { if (!gAgentAvatarp->isSitting()) { + // SL-315 gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero); } gAgentAvatarp->startMotion(ANIM_AGENT_BODY_NOISE); diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h index abf7027ed22cadd79cc0a5c0ca4526415a796c5a..f981e08ff7715c6b7d60e602a9a2873d6b7db27f 100644 --- a/indra/newview/llagentpicksinfo.h +++ b/indra/newview/llagentpicksinfo.h @@ -36,14 +36,12 @@ struct LLAvatarPicks; */ class LLAgentPicksInfo : public LLSingleton<LLAgentPicksInfo> { + LLSINGLETON(LLAgentPicksInfo); + virtual ~LLAgentPicksInfo(); + class LLAgentPicksObserver; public: - - LLAgentPicksInfo(); - - virtual ~LLAgentPicksInfo(); - /** * Requests number of picks from server. * diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index b76a66ab392f9cb5bdabd7a84e6dccff2dd29dc2..170e4063a1524b22d1eb62d69490194db116526b 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -62,23 +62,37 @@ using namespace LLAvatarAppearanceDefines; /////////////////////////////////////////////////////////////////////////////// -// Callback to wear and start editing an item that has just been created. -void wear_and_edit_cb(const LLUUID& inv_item) +void set_default_permissions(LLViewerInventoryItem* item) { - if (inv_item.isNull()) return; - - LLViewerInventoryItem* item = gInventory.getItem(inv_item); - if (!item) return; - - LLPermissions perm = item->getPermissions(); + llassert(item); + LLPermissions perm = item->getPermissions(); + if (perm.getMaskNextOwner() != LLFloaterPerms::getNextOwnerPerms("Wearables") + || perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Wearables") + || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Wearables")) + { perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables")); perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables")); perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables")); + item->setPermissions(perm); item->updateServer(FALSE); - gInventory.updateItem(item); - gInventory.notifyObservers(); + } +} + +// Callback to wear and start editing an item that has just been created. +void wear_and_edit_cb(const LLUUID& inv_item) +{ + if (inv_item.isNull()) return; + + LLViewerInventoryItem* item = gInventory.getItem(inv_item); + if (!item) return; + + set_default_permissions(item); + + // item was just created, update even if permissions did not changed + gInventory.updateItem(item); + gInventory.notifyObservers(); // Request editing the item after it gets worn. gAgentWearables.requestEditingWearable(inv_item); @@ -94,13 +108,8 @@ void wear_cb(const LLUUID& inv_item) LLViewerInventoryItem* item = gInventory.getItem(inv_item); if (item) { - LLPermissions perm = item->getPermissions(); - perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables")); - perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables")); - perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables")); - item->setPermissions(perm); + set_default_permissions(item); - item->updateServer(FALSE); gInventory.updateItem(item); gInventory.notifyObservers(); } @@ -253,6 +262,7 @@ void LLAgentWearables::AddWearableToAgentInventoryCallback::fire(const LLUUID& i { LLAppearanceMgr::instance().addCOFItemLink(inv_item, new LLUpdateAppearanceAndEditWearableOnDestroy(inv_item), mDescription); + editWearable(inv_item); } } @@ -423,7 +433,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type, // old_wearable may still be referred to by other inventory items. Revert // unsaved changes so other inventory items aren't affected by the changes // that were just saved. - old_wearable->revertValues(); + old_wearable->revertValuesWithoutUpdate(); } void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index) @@ -1364,6 +1374,30 @@ void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array // LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL; } +std::vector<LLViewerObject*> LLAgentWearables::getTempAttachments() +{ + llvo_vec_t temp_attachs; + 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; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *objectp = (*attachment_iter); + if (objectp && objectp->isTempAttachment()) + { + temp_attachs.push_back(objectp); + } + } + } + } + return temp_attachs; +} + void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove) { if (!isAgentAvatarValid()) return; diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 100448202080c8a2f6ecdfae5dd086e01dc4a5b5..27102629104216d6e612d21cc484914c0b68fe83 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -38,6 +38,7 @@ #include "llviewerinventory.h" #include "llavatarappearancedefines.h" #include "llwearabledata.h" +#include "llinitdestroyclass.h" class LLInventoryItem; class LLVOAvatarSelf; @@ -185,6 +186,8 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>, public LLWearable static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array); static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array); + static llvo_vec_t getTempAttachments(); + //-------------------------------------------------------------------- // Signals //-------------------------------------------------------------------- diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp index 49291ea5642e33d88c1a31661a11a199868d657d..c1f898284a8ab582d6f434f38c8998a637bff4e0 100644 --- a/indra/newview/llappcorehttp.cpp +++ b/indra/newview/llappcorehttp.cpp @@ -30,6 +30,8 @@ #include "llappviewer.h" #include "llviewercontrol.h" +#include "llexception.h" +#include "stringize.h" #include <openssl/x509_vfy.h> #include <openssl/ssl.h> @@ -534,7 +536,7 @@ LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url, // somewhat clumsy, as we may run into errors that do not map directly to curl // error codes. Should be refactored with login refactoring, perhaps. result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_CACERT); - result.setMessage(cert_exception.getMessage()); + result.setMessage(cert_exception.what()); LLPointer<LLCertificate> cert = cert_exception.getCert(); cert->ref(); // adding an extra ref here result.setErrorData(cert.get()); @@ -544,13 +546,14 @@ LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url, catch (LLCertException &cert_exception) { result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_PEER_CERTIFICATE); - result.setMessage(cert_exception.getMessage()); + result.setMessage(cert_exception.what()); LLPointer<LLCertificate> cert = cert_exception.getCert(); cert->ref(); // adding an extra ref here result.setErrorData(cert.get()); } catch (...) { + LOG_UNHANDLED_EXCEPTION(STRINGIZE("('" << url << "')")); // any other odd error, we just handle as a connect error. result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_CONNECT_ERROR); } diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 549df80fa1a501a268d77f1f948d58d26022ab50..8188c6c3f99ca935900ad44e1b95a8aeec23d142 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -48,16 +48,19 @@ - (void) applicationDidFinishLaunching:(NSNotification *)notification { frameTimer = nil; - + [self languageUpdated]; - + if (initViewer()) { - frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES]; + // Set up recurring calls to oneFrame (repeating timer with timeout 0) + // until applicationShouldTerminate. + frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self + selector:@selector(oneFrame) userInfo:nil repeats:YES]; } else { - handleQuit(); + exit(0); } - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil]; // [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; @@ -96,22 +99,29 @@ - (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender { - if (!runMainLoop()) + // run one frame to assess state + if (!pumpMainLoop()) { + // pumpMainLoop() returns true when done, false if it wants to be + // called again. Since it returned false, do not yet cancel + // frameTimer. handleQuit(); return NSTerminateCancel; } else { + // pumpMainLoop() returned true: it's done. Okay, done with frameTimer. [frameTimer release]; cleanupViewer(); return NSTerminateNow; } } -- (void) mainLoop +- (void) oneFrame { - bool appExiting = runMainLoop(); + bool appExiting = pumpMainLoop(); if (appExiting) { + // Once pumpMainLoop() reports that we're done, cancel frameTimer: + // stop the repetitive calls. [frameTimer release]; [[NSApplication sharedApplication] terminate:self]; } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index a1d97863210ef2ff418009298d6b30ddf317972e..fc4be98fbd46ed01bc812c58e76fe3a6c3f3c2cb 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include <boost/lexical_cast.hpp> +#include <boost/foreach.hpp> #include "llaccordionctrltab.h" #include "llagent.h" #include "llagentcamera.h" @@ -856,7 +857,7 @@ void LLWearableHoldingPattern::onAllComplete() // attachments, even those that are not being removed. This is // needed to get joint positions all slammed down to their // pre-attachment states. - gAgentAvatarp->clearAttachmentPosOverrides(); + gAgentAvatarp->clearAttachmentOverrides(); if (objects_to_remove.size() || items_to_add.size()) { @@ -879,7 +880,7 @@ void LLWearableHoldingPattern::onAllComplete() ++it) { LLViewerObject *objectp = *it; - gAgentAvatarp->addAttachmentPosOverridesForObject(objectp); + gAgentAvatarp->addAttachmentOverridesForObject(objectp); } // Add new attachments to match those requested. @@ -1517,6 +1518,26 @@ void LLAppearanceMgr::replaceCurrentOutfit(const LLUUID& new_outfit) wearInventoryCategory(cat, false, false); } +// Remove existing photo link from outfit folder. +void LLAppearanceMgr::removeOutfitPhoto(const LLUUID& outfit_id) +{ + LLInventoryModel::cat_array_t sub_cat_array; + LLInventoryModel::item_array_t outfit_item_array; + gInventory.collectDescendents( + outfit_id, + sub_cat_array, + outfit_item_array, + LLInventoryModel::EXCLUDE_TRASH); + BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array) + { + LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem(); + if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE) + { + gInventory.removeItem(outfit_item->getUUID()); + } + } +} + // Open outfit renaming dialog. void LLAppearanceMgr::renameOutfit(const LLUUID& outfit_id) { @@ -1854,15 +1875,15 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id) return false; } - // Check whether the outfit contains any wearables we aren't wearing already (STORM-702). + // Check whether the outfit contains any wearables LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true); + LLFindWearables is_wearable; gInventory.collectDescendentsIf(outfit_cat_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, - is_worn); + is_wearable); return items.size() > 0; } @@ -2945,6 +2966,16 @@ void LLAppearanceMgr::updateIsDirty() gInventory.collectDescendentsIf(base_outfit, outfit_cats, outfit_items, LLInventoryModel::EXCLUDE_TRASH, collector); + for (U32 i = 0; i < outfit_items.size(); ++i) + { + LLViewerInventoryItem* linked_item = outfit_items.at(i)->getLinkedItem(); + if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE) + { + outfit_items.erase(outfit_items.begin() + i); + break; + } + } + if(outfit_items.size() != cof_items.size()) { LL_DEBUGS("Avatar") << "item count different - base " << outfit_items.size() << " cof " << cof_items.size() << LL_ENDL; @@ -3092,6 +3123,14 @@ void appearance_mgr_update_dirty_state() { if (LLAppearanceMgr::instanceExists()) { + LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance(); + LLUUID image_id = app_mgr.getOutfitImage(); + if(image_id.notNull()) + { + LLPointer<LLInventoryCallback> cb = NULL; + link_inventory_object(app_mgr.getBaseOutfitUUID(), image_id, cb); + } + LLAppearanceMgr::getInstance()->updateIsDirty(); LLAppearanceMgr::getInstance()->setOutfitLocked(false); gAgentWearables.notifyLoadingFinished(); @@ -3101,7 +3140,21 @@ void appearance_mgr_update_dirty_state() void update_base_outfit_after_ordering() { LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance(); - + LLInventoryModel::cat_array_t sub_cat_array; + LLInventoryModel::item_array_t outfit_item_array; + gInventory.collectDescendents(app_mgr.getBaseOutfitUUID(), + sub_cat_array, + outfit_item_array, + LLInventoryModel::EXCLUDE_TRASH); + BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array) + { + LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem(); + if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE) + { + app_mgr.setOutfitImage(linked_item->getLinkedUUID()); + } + } + LLPointer<LLInventoryCallback> dirty_state_updater = new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state); @@ -3357,9 +3410,21 @@ LLSD LLAppearanceMgr::dumpCOF() const return result; } +// static +void LLAppearanceMgr::onIdle(void *) +{ + LLAppearanceMgr* mgr = LLAppearanceMgr::getInstance(); + if (mgr->mRerequestAppearanceBake) + { + mgr->requestServerAppearanceUpdate(); + } +} + void LLAppearanceMgr::requestServerAppearanceUpdate() { - if (!mOutstandingAppearanceBakeRequest) + // Workaround: we shouldn't request update from server prior to uploading all attachments, but it is + // complicated to check for pending attachment uploads, so we are just waiting for uploads to complete + if (!mOutstandingAppearanceBakeRequest && gAssetStorage->getNumPendingUploads() == 0) { mRerequestAppearanceBake = false; LLCoprocedureManager::CoProcedure_t proc = boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this, _1); @@ -3367,13 +3432,14 @@ void LLAppearanceMgr::requestServerAppearanceUpdate() } else { + // Shedule update mRerequestAppearanceBake = true; } } void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter) { - mRerequestAppearanceBake = false; + BoolSetter outstanding(mOutstandingAppearanceBakeRequest); if (!gAgent.getRegion()) { LL_WARNS("Avatar") << "Region not set, cannot request server appearance update" << LL_ENDL; @@ -3405,8 +3471,6 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd bool bRetry; do { - BoolSetter outstanding(mOutstandingAppearanceBakeRequest); - // If we have already received an update for this or higher cof version, // put a warning in the log and cancel the request. S32 cofVersion = getCOFVersion(); @@ -3424,13 +3488,13 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd } else { - if (cofVersion < lastRcv) + if (cofVersion <= lastRcv) { LL_WARNS("Avatar") << "Have already received update for cof version " << lastRcv << " but requesting for " << cofVersion << LL_ENDL; return; } - if (lastReq > cofVersion) + if (lastReq >= cofVersion) { LL_WARNS("Avatar") << "Request already in flight for cof version " << lastReq << " but requesting for " << cofVersion << LL_ENDL; @@ -3450,7 +3514,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd LL_WARNS("Avatar") << "Forcing version failure on COF Baking" << LL_ENDL; } - LL_INFOS() << "Requesting bake for COF version " << cofVersion << LL_ENDL; + LL_INFOS("Avatar") << "Requesting bake for COF version " << cofVersion << LL_ENDL; LLSD postData; if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate")) @@ -3518,12 +3582,6 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd } } while (bRetry); - - if (mRerequestAppearanceBake) - { // A bake request came in while this one was still outstanding. - // Requeue ourself for a later request. - requestServerAppearanceUpdate(); - } } /*static*/ @@ -3889,7 +3947,6 @@ LLAppearanceMgr::LLAppearanceMgr(): mAttachmentInvLinkEnabled(false), mOutfitIsDirty(false), mOutfitLocked(false), - mInFlightCounter(0), mInFlightTimer(), mIsInUpdateAppearanceFromCOF(false), mOutstandingAppearanceBakeRequest(false), @@ -3904,6 +3961,7 @@ LLAppearanceMgr::LLAppearanceMgr(): "OutfitOperationsTimeout"))); gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle, NULL); + gIdleCallbacks.addFunction(&LLAppearanceMgr::onIdle, NULL); //sheduling appearance update requests } LLAppearanceMgr::~LLAppearanceMgr() @@ -3916,6 +3974,10 @@ void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val) LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << LL_ENDL; mAttachmentInvLinkEnabled = val; } +boost::signals2::connection LLAppearanceMgr::setAttachmentsChangedCallback(attachments_changed_callback_t cb) +{ + return mAttachmentsChangeSignal.connect(cb); +} void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg) { @@ -3942,6 +4004,8 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id) gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); LLAttachmentsMgr::instance().onAttachmentArrived(item_id); + + mAttachmentsChangeSignal(); } void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id) @@ -3962,6 +4026,8 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id) { //LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL; } + + mAttachmentsChangeSignal(); } BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 7069da735294761b697ba00e6c937f4389456f14..166c663feb3f0eec7d1490d888f9a3f2b2a49377 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -42,9 +42,10 @@ class LLOutfitUnLockTimer; class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr> { + LLSINGLETON(LLAppearanceMgr); + ~LLAppearanceMgr(); LOG_CLASS(LLAppearanceMgr); - friend class LLSingleton<LLAppearanceMgr>; friend class LLOutfitUnLockTimer; public: @@ -61,6 +62,7 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr> void changeOutfit(bool proceed, const LLUUID& category, bool append); void replaceCurrentOutfit(const LLUUID& new_outfit); void renameOutfit(const LLUUID& outfit_id); + void removeOutfitPhoto(const LLUUID& outfit_id); void takeOffOutfit(const LLUUID& cat_id); void addCategoryToCurrentOutfit(const LLUUID& cat_id); S32 findExcessOrDuplicateItems(const LLUUID& cat_id, @@ -184,6 +186,9 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr> void wearBaseOutfit(); + void setOutfitImage(const LLUUID& image_id) {mCOFImageID = image_id;} + LLUUID getOutfitImage() {return mCOFImageID;} + // Overrides the base outfit with the content from COF // @return false if there is no base outfit bool updateBaseOutfit(); @@ -220,11 +225,15 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr> bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; } + static void onIdle(void *); void requestServerAppearanceUpdate(); void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; } std::string getAppearanceServiceURL() const; + typedef boost::function<void ()> attachments_changed_callback_t; + typedef boost::signals2::signal<void ()> attachments_changed_signal_t; + boost::signals2::connection setAttachmentsChangedCallback(attachments_changed_callback_t cb); private: @@ -233,10 +242,6 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr> static void debugAppearanceUpdateCOF(const LLSD& content); std::string mAppearanceServiceURL; - -protected: - LLAppearanceMgr(); - ~LLAppearanceMgr(); private: @@ -264,10 +269,13 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr> * to avoid unsynchronized outfit state or performing duplicate operations. */ bool mOutfitLocked; - S32 mInFlightCounter; LLTimer mInFlightTimer; static bool mActive; + attachments_changed_signal_t mAttachmentsChangeSignal; + + LLUUID mCOFImageID; + std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer; // Set of temp attachment UUIDs that should be removed diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index cf783b9f2fa13afa753e59cc60a17fe0e7f2b871..7c9d37a64c4460b00972d5bd3c4fae84bed6e183 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -98,6 +98,7 @@ #include "llscenemonitor.h" #include "llavatarrenderinfoaccountant.h" #include "lllocalbitmaps.h" +#include "llskinningutil.h" // Linden library includes #include "llavatarnamecache.h" @@ -121,15 +122,20 @@ #include "llleap.h" #include "stringize.h" #include "llcoros.h" +#include "llexception.h" #if !LL_LINUX #include "cef/llceflib.h" -#endif +#if LL_WINDOWS +#include "vlc/libvlc_version.h" +#endif // LL_WINDOWS +#endif // LL_LINUX // Third party library includes #include <boost/bind.hpp> #include <boost/foreach.hpp> #include <boost/algorithm/string.hpp> #include <boost/regex.hpp> +#include <boost/throw_exception.hpp> #if LL_WINDOWS # include <share.h> // For _SH_DENYWR in processMarkerFiles @@ -200,8 +206,9 @@ #include "llcommandlineparser.h" #include "llfloatermemleak.h" #include "llfloaterreg.h" +#include "llfloateroutfitsnapshot.h" #include "llfloatersnapshot.h" -#include "llfloaterinventory.h" +#include "llsidepanelinventory.h" // includes for idle() idleShutdown() #include "llviewercontrol.h" @@ -226,11 +233,11 @@ #include "llsecapi.h" #include "llmachineid.h" #include "llmainlooprepeater.h" +#include "llcleanup.h" #include "llcoproceduremanager.h" #include "llviewereventrecorder.h" - // *FIX: These extern globals should be cleaned up. // The globals either represent state/config/resource-storage of either // this app, or another 'component' of the viewer. App globals should be @@ -287,7 +294,7 @@ S32 gLastExecDuration = -1; // (<0 indicates unknown) # define LL_PLATFORM_KEY "mac" #elif LL_LINUX # define LL_PLATFORM_KEY "lnx" -#else +else # error "Unknown Platform" #endif const char* gPlatform = LL_PLATFORM_KEY; @@ -378,6 +385,7 @@ const char* const VIEWER_WINDOW_CLASSNAME = "Second Life"; */ class LLDeferredTaskList: public LLSingleton<LLDeferredTaskList> { + LLSINGLETON_EMPTY_CTOR(LLDeferredTaskList); LOG_CLASS(LLDeferredTaskList); friend class LLAppViewer; @@ -689,7 +697,8 @@ LLAppViewer::LLAppViewer() mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)), mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)), mFastTimerLogThread(NULL), - mSettingsLocationList(NULL) + mSettingsLocationList(NULL), + mIsFirstRun(false) { if(NULL != sInstance) { @@ -723,7 +732,7 @@ LLAppViewer::LLAppViewer() LLAppViewer::~LLAppViewer() { delete mSettingsLocationList; - LLViewerEventRecorder::instance().~LLViewerEventRecorder(); + LLViewerEventRecorder::deleteSingleton(); destroyMainloopTimeout(); @@ -759,9 +768,6 @@ bool LLAppViewer::init() // // Start of the application // -#ifdef LL_DARWIN - mMainLoopInitialized = false; -#endif // initialize LLWearableType translation bridge. // Memory will be cleaned up in ::cleanupClass() @@ -789,6 +795,9 @@ bool LLAppViewer::init() LL_INFOS("InitInfo") << "Configuration initialized." << LL_ENDL ; + // initialize skinning util + LLSkinningUtil::initClass(); + //set the max heap size. initMaxHeapSize() ; LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize")); @@ -907,7 +916,7 @@ bool LLAppViewer::init() // 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)); + 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); @@ -1104,17 +1113,23 @@ bool LLAppViewer::init() #if LL_WINDOWS if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion()) { + std::string url; if (gGLManager.mIsIntel) { - LLNotificationsUtil::add("IntelOldDriver"); + url = LLTrans::getString("IntelDriverPage"); } else if (gGLManager.mIsNVIDIA) { - LLNotificationsUtil::add("NVIDIAOldDriver"); + url = LLTrans::getString("NvidiaDriverPage"); } else if (gGLManager.mIsATI) { - LLNotificationsUtil::add("AMDOldDriver"); + url = LLTrans::getString("AMDDriverPage"); + } + + if (!url.empty()) + { + LLNotificationsUtil::add("OldGPUDriver", LLSD().with("URL", url)); } } #endif @@ -1202,6 +1217,25 @@ bool LLAppViewer::init() boost::bind(&LLControlGroup::getU32, boost::ref(gSavedSettings), _1), boost::bind(&LLControlGroup::declareU32, boost::ref(gSavedSettings), _1, _2, _3, LLControlVariable::PERSIST_ALWAYS)); + showReleaseNotesIfRequired(); + + /*----------------------------------------------------------------------*/ + // 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); + + // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. + + LLVoiceChannel::initClass(); + LLVoiceClient::getInstance()->init(gServicePump); + LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); + + joystick = LLViewerJoystick::getInstance(); + joystick->setNeedsReset(true); + /*----------------------------------------------------------------------*/ + return true; } @@ -1276,299 +1310,266 @@ static LLTrace::BlockTimerStatHandle FTM_AGENT_UPDATE("Update"); // externally visible timers LLTrace::BlockTimerStatHandle FTM_FRAME("Frame"); -bool LLAppViewer::mainLoop() +bool LLAppViewer::frame() { -#ifdef LL_DARWIN - if (!mMainLoopInitialized) -#endif - { - LL_INFOS() << "Entering main_loop" << LL_ENDL; - mMainloopTimeout = new LLWatchdogTimeout(); - - //------------------------------------------- - // Run main loop until time to quit - //------------------------------------------- - - // Create IO Pump to use for HTTP Requests. - gServicePump = new LLPumpIO(gAPRPoolp); - - // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. - - LLVoiceChannel::initClass(); - LLVoiceClient::getInstance()->init(gServicePump); - LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); - - joystick = LLViewerJoystick::getInstance(); - joystick->setNeedsReset(true); - -#ifdef LL_DARWIN - // Ensure that this section of code never gets called again on OS X. - mMainLoopInitialized = true; -#endif - } - // As we do not (yet) send data on the mainloop LLEventPump that varies - // with each frame, no need to instantiate a new LLSD event object each - // time. Obviously, if that changes, just instantiate the LLSD at the - // point of posting. - LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); - - LLSD newFrame; - + LLSD newFrame; + LLTimer frameTimer,idleTimer; LLTimer debugTime; - + //LLPrivateMemoryPoolTester::getInstance()->run(false) ; //LLPrivateMemoryPoolTester::getInstance()->run(true) ; //LLPrivateMemoryPoolTester::destroy() ; - // Handle messages -#ifdef LL_DARWIN - if (!LLApp::isExiting()) -#else - while (!LLApp::isExiting()) -#endif + LL_RECORD_BLOCK_TIME(FTM_FRAME); + LLTrace::BlockTimer::processTimes(); + LLTrace::get_frame_recording().nextPeriod(); + LLTrace::BlockTimer::logStats(); + + LLTrace::get_thread_recorder()->pullFromChildren(); + + //clear call stack records + LL_CLEAR_CALLSTACKS(); + + //check memory availability information + checkMemory() ; + + try { - LL_RECORD_BLOCK_TIME(FTM_FRAME); - LLTrace::BlockTimer::processTimes(); - LLTrace::get_frame_recording().nextPeriod(); - LLTrace::BlockTimer::logStats(); + pingMainloopTimeout("Main:MiscNativeWindowEvents"); - LLTrace::get_thread_recorder()->pullFromChildren(); + if (gViewerWindow) + { + LL_RECORD_BLOCK_TIME(FTM_MESSAGES); + gViewerWindow->getWindow()->processMiscNativeEvents(); + } - //clear call stack records - LL_CLEAR_CALLSTACKS(); + pingMainloopTimeout("Main:GatherInput"); - //check memory availability information - checkMemory() ; + if (gViewerWindow) + { + LL_RECORD_BLOCK_TIME(FTM_MESSAGES); + if (!restoreErrorTrap()) + { + LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL; + } + + gViewerWindow->getWindow()->gatherInput(); + } + +#if 1 && !LL_RELEASE_FOR_DOWNLOAD + // once per second debug info + if (debugTime.getElapsedTimeF32() > 1.f) + { + debugTime.reset(); + } - try +#endif + //memory leaking simulation + LLFloaterMemLeak* mem_leak_instance = + LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); + if(mem_leak_instance) { - pingMainloopTimeout("Main:MiscNativeWindowEvents"); + mem_leak_instance->idle() ; + } + + // canonical per-frame event + mainloop.post(newFrame); - if (gViewerWindow) + if (!LLApp::isExiting()) + { + 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 ((gHeadlessClient || gViewerWindow->getWindow()->getVisible()) + && gViewerWindow->getActive() + && !gViewerWindow->getWindow()->getMinimized() + && LLStartUp::getStartupState() == STATE_STARTED + && (gHeadlessClient || !gViewerWindow->getShowProgress()) + && !gFocusMgr.focusLocked()) { - LL_RECORD_BLOCK_TIME(FTM_MESSAGES); - gViewerWindow->getWindow()->processMiscNativeEvents(); + joystick->scanJoystick(); + gKeyboard->scanKeyboard(); } - - pingMainloopTimeout("Main:GatherInput"); - - if (gViewerWindow) + + // Update state based on messages, user input, object idle. { - LL_RECORD_BLOCK_TIME(FTM_MESSAGES); - if (!restoreErrorTrap()) - { - LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL; - } + pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! + + LL_RECORD_BLOCK_TIME(FTM_IDLE); + idle(); - gViewerWindow->getWindow()->gatherInput(); + resumeMainloopTimeout(); } -#if 1 && !LL_RELEASE_FOR_DOWNLOAD - // once per second debug info - if (debugTime.getElapsedTimeF32() > 1.f) + if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) { - debugTime.reset(); + pauseMainloopTimeout(); + saveFinalSnapshot(); + disconnectViewer(); + resumeMainloopTimeout(); } - -#endif - //memory leaking simulation - LLFloaterMemLeak* mem_leak_instance = - LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); - if(mem_leak_instance) - { - mem_leak_instance->idle() ; - } - // canonical per-frame event - mainloop.post(newFrame); - - if (!LLApp::isExiting()) + // Render scene. + // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18 + if (!LLApp::isExiting() && !gHeadlessClient) { - 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 ((gHeadlessClient || gViewerWindow->getWindow()->getVisible()) - && gViewerWindow->getActive() - && !gViewerWindow->getWindow()->getMinimized() - && LLStartUp::getStartupState() == STATE_STARTED - && (gHeadlessClient || !gViewerWindow->getShowProgress()) - && !gFocusMgr.focusLocked()) - { - joystick->scanJoystick(); - gKeyboard->scanKeyboard(); - } + pingMainloopTimeout("Main:Display"); + gGLActive = TRUE; + display(); + pingMainloopTimeout("Main:Snapshot"); + LLFloaterSnapshot::update(); // take snapshots + LLFloaterOutfitSnapshot::update(); + gGLActive = FALSE; + } + } - // Update state based on messages, user input, object idle. - { - pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! - - LL_RECORD_BLOCK_TIME(FTM_IDLE); - idle(); + pingMainloopTimeout("Main:Sleep"); - resumeMainloopTimeout(); - } - - if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) - { - pauseMainloopTimeout(); - saveFinalSnapshot(); - disconnectViewer(); - resumeMainloopTimeout(); - } + pauseMainloopTimeout(); - // Render scene. - // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18 - if (!LLApp::isExiting() && !gHeadlessClient) + // Sleep and run background threads + { + LL_RECORD_BLOCK_TIME(FTM_SLEEP); + + // yield some time to the os based on command line option + if(mYieldTime >= 0) + { + LL_RECORD_BLOCK_TIME(FTM_YIELD); + ms_sleep(mYieldTime); + } + + // yield cooperatively when not running as foreground window + if ( (gViewerWindow && !gViewerWindow->getWindow()->getVisible()) + || !gFocusMgr.getAppHasFocus()) + { + // Sleep if we're not rendering, or the window is minimized. + S32 milliseconds_to_sleep = llclamp(gSavedSettings.getS32("BackgroundYieldTime"), 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) { - pingMainloopTimeout("Main:Display"); - gGLActive = TRUE; - display(); - pingMainloopTimeout("Main:Snapshot"); - LLFloaterSnapshot::update(); // take snapshots - gGLActive = FALSE; + ms_sleep(milliseconds_to_sleep); + // also pause worker threads during this wait period + LLAppViewer::getTextureCache()->pause(); + LLAppViewer::getImageDecodeThread()->pause(); } } - - pingMainloopTimeout("Main:Sleep"); - pauseMainloopTimeout(); + if (mRandomizeFramerate) + { + ms_sleep(rand() % 200); + } - // Sleep and run background threads + if (mPeriodicSlowFrame + && (gFrameCount % 10 == 0)) { - LL_RECORD_BLOCK_TIME(FTM_SLEEP); - - // yield some time to the os based on command line option - if(mYieldTime >= 0) - { - LL_RECORD_BLOCK_TIME(FTM_YIELD); - ms_sleep(mYieldTime); - } + LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL; + ms_sleep(500); + } + + const F64Milliseconds max_idle_time = llmin(.005f*10.f*(F32Milliseconds)gFrameTimeSeconds, F32Milliseconds(5)); // 5 ms a second + idleTimer.reset(); + S32 total_work_pending = 0; + S32 total_io_pending = 0; + while(1) + { + S32 work_pending = 0; + S32 io_pending = 0; + F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); + + work_pending += updateTextureThreads(max_time); - // yield cooperatively when not running as foreground window - if ( (gViewerWindow && !gViewerWindow->getWindow()->getVisible()) - || !gFocusMgr.getAppHasFocus()) { - // Sleep if we're not rendering, or the window is minimized. - S32 milliseconds_to_sleep = llclamp(gSavedSettings.getS32("BackgroundYieldTime"), 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) - { - ms_sleep(milliseconds_to_sleep); - // also pause worker threads during this wait period - LLAppViewer::getTextureCache()->pause(); - LLAppViewer::getImageDecodeThread()->pause(); - } + LL_RECORD_BLOCK_TIME(FTM_VFS); + io_pending += LLVFSThread::updateClass(1); } - - if (mRandomizeFramerate) { - ms_sleep(rand() % 200); + LL_RECORD_BLOCK_TIME(FTM_LFS); + io_pending += LLLFSThread::updateClass(1); } - if (mPeriodicSlowFrame - && (gFrameCount % 10 == 0)) + if (io_pending > 1000) { - LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL; - ms_sleep(500); + ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up } - const F64Milliseconds max_idle_time = llmin(.005f*10.f*(F32Milliseconds)gFrameTimeSeconds, F32Milliseconds(5)); // 5 ms a second - idleTimer.reset(); - S32 total_work_pending = 0; - S32 total_io_pending = 0; - while(1) - { - S32 work_pending = 0; - S32 io_pending = 0; - F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); - - work_pending += updateTextureThreads(max_time); - - { - LL_RECORD_BLOCK_TIME(FTM_VFS); - io_pending += LLVFSThread::updateClass(1); - } - { - LL_RECORD_BLOCK_TIME(FTM_LFS); - io_pending += LLLFSThread::updateClass(1); - } - - if (io_pending > 1000) - { - ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up - } - - total_work_pending += work_pending ; - total_io_pending += io_pending ; - - if (!work_pending || idleTimer.getElapsedTimeF64() >= max_idle_time) - { - break; - } - } - gMeshRepo.update() ; + total_work_pending += work_pending ; + total_io_pending += io_pending ; - if(!total_work_pending) //pause texture fetching threads if nothing to process. + if (!work_pending || idleTimer.getElapsedTimeF64() >= max_idle_time) { - LLAppViewer::getTextureCache()->pause(); - LLAppViewer::getImageDecodeThread()->pause(); - LLAppViewer::getTextureFetch()->pause(); + break; } - if(!total_io_pending) //pause file threads if nothing to process. - { - LLVFSThread::sLocal->pause(); - LLLFSThread::sLocal->pause(); - } + } + gMeshRepo.update() ; + + if(!total_work_pending) //pause texture fetching threads if nothing to process. + { + LLAppViewer::getTextureCache()->pause(); + LLAppViewer::getImageDecodeThread()->pause(); + LLAppViewer::getTextureFetch()->pause(); + } + if(!total_io_pending) //pause file threads if nothing to process. + { + LLVFSThread::sLocal->pause(); + LLLFSThread::sLocal->pause(); + } - //texture fetching debugger - if(LLTextureFetchDebugger::isEnabled()) + //texture fetching debugger + if(LLTextureFetchDebugger::isEnabled()) + { + LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = + LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); + if(tex_fetch_debugger_instance) { - LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = - LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); - if(tex_fetch_debugger_instance) - { - tex_fetch_debugger_instance->idle() ; - } + tex_fetch_debugger_instance->idle() ; } + } - if ((LLStartUp::getStartupState() >= STATE_CLEANUP) && - (frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD)) - { - gFrameStalls++; - } - frameTimer.reset(); + if ((LLStartUp::getStartupState() >= STATE_CLEANUP) && + (frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD)) + { + gFrameStalls++; + } + frameTimer.reset(); - resumeMainloopTimeout(); - - pingMainloopTimeout("Main:End"); - } + resumeMainloopTimeout(); + + pingMainloopTimeout("Main:End"); } - catch(std::bad_alloc) - { - LLMemory::logMemoryInfo(TRUE) ; + } + catch (const LLContinueError&) + { + LOG_UNHANDLED_EXCEPTION(""); + } + catch(std::bad_alloc) + { + LLMemory::logMemoryInfo(TRUE) ; - //stop memory leaking simulation - LLFloaterMemLeak* mem_leak_instance = - LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); - if(mem_leak_instance) - { - mem_leak_instance->stop() ; - LL_WARNS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL ; - } - else - { - //output possible call stacks to log file. - LLError::LLCallStacks::print() ; + //stop memory leaking simulation + 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 + { + //output possible call stacks to log file. + LLError::LLCallStacks::print() ; - LL_ERRS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL ; - } + LL_ERRS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL ; } } + catch (...) + { + CRASH_ON_UNHANDLED_EXCEPTION(""); + } if (LLApp::isExiting()) { @@ -1582,7 +1583,7 @@ bool LLAppViewer::mainLoop() catch(std::bad_alloc) { LL_WARNS() << "Bad memory allocation when saveFinalSnapshot() is called!" << LL_ENDL ; - + //stop memory leaking simulation LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); @@ -1591,16 +1592,20 @@ bool LLAppViewer::mainLoop() mem_leak_instance->stop() ; } } + catch (...) + { + CRASH_ON_UNHANDLED_EXCEPTION("saveFinalSnapshot()"); + } } - + delete gServicePump; - + destroyMainloopTimeout(); - + LL_INFOS() << "Exiting main_loop" << LL_ENDL; } - return LLApp::isExiting(); + return ! LLApp::isRunning(); } S32 LLAppViewer::updateTextureThreads(F32 max_time) @@ -1726,7 +1731,7 @@ bool LLAppViewer::cleanup() gTransferManager.cleanup(); #endif - LLLocalBitmapMgr::cleanupClass(); + SUBSYSTEM_CLEANUP(LLLocalBitmapMgr); // Note: this is where gWorldMap used to be deleted. @@ -1835,11 +1840,11 @@ bool LLAppViewer::cleanup() LLViewerObject::cleanupVOClasses(); - LLAvatarAppearance::cleanupClass(); + SUBSYSTEM_CLEANUP(LLAvatarAppearance); - LLAvatarAppearance::cleanupClass(); + SUBSYSTEM_CLEANUP(LLAvatarAppearance); - LLPostProcess::cleanupClass(); + SUBSYSTEM_CLEANUP(LLPostProcess); LLTracker::cleanupInstance(); @@ -1865,12 +1870,12 @@ bool LLAppViewer::cleanup() //end_messaging_system(); - LLFollowCamMgr::cleanupClass(); - //LLVolumeMgr::cleanupClass(); + SUBSYSTEM_CLEANUP(LLFollowCamMgr); + //SUBSYSTEM_CLEANUP(LLVolumeMgr); LLPrimitive::cleanupVolumeManager(); - LLWorldMapView::cleanupClass(); - LLFolderViewItem::cleanupClass(); - LLUI::cleanupClass(); + SUBSYSTEM_CLEANUP(LLWorldMapView); + SUBSYSTEM_CLEANUP(LLFolderViewItem); + SUBSYSTEM_CLEANUP(LLUI); // // Shut down the VFS's AFTER the decode manager cleans up (since it cleans up vfiles). @@ -1879,7 +1884,7 @@ bool LLAppViewer::cleanup() // LL_INFOS() << "Cleaning up VFS" << LL_ENDL; - LLVFile::cleanupClass(); + SUBSYSTEM_CLEANUP(LLVFile); LL_INFOS() << "Saving Data" << LL_ENDL; @@ -1982,9 +1987,9 @@ bool LLAppViewer::cleanup() // Non-LLCurl libcurl library mAppCoreHttp.cleanup(); - LLFilePickerThread::cleanupClass(); + SUBSYSTEM_CLEANUP(LLFilePickerThread); - //MUST happen AFTER LLCurl::cleanupClass + //MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl) delete sTextureCache; sTextureCache = NULL; delete sTextureFetch; @@ -2008,22 +2013,22 @@ bool LLAppViewer::cleanup() gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name)); } - LLMetricPerformanceTesterBasic::cleanClass() ; + SUBSYSTEM_CLEANUP(LLMetricPerformanceTesterBasic) ; LL_INFOS() << "Cleaning up Media and Textures" << LL_ENDL; //Note: - //LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown() + //SUBSYSTEM_CLEANUP(LLViewerMedia) has to be put before gTextureList.shutdown() //because some new image might be generated during cleaning up media. --bao - LLViewerMedia::cleanupClass(); - LLViewerParcelMedia::cleanupClass(); + SUBSYSTEM_CLEANUP(LLViewerMedia); + SUBSYSTEM_CLEANUP(LLViewerParcelMedia); gTextureList.shutdown(); // shutdown again in case a callback added something LLUIImageList::getInstance()->cleanUp(); // This should eventually be done in LLAppViewer - LLImage::cleanupClass(); - LLVFSThread::cleanupClass(); - LLLFSThread::cleanupClass(); + SUBSYSTEM_CLEANUP(LLImage); + SUBSYSTEM_CLEANUP(LLVFSThread); + SUBSYSTEM_CLEANUP(LLLFSThread); #ifndef LL_RELEASE_FOR_DOWNLOAD LL_INFOS() << "Auditing VFS" << LL_ENDL; @@ -2066,10 +2071,10 @@ bool LLAppViewer::cleanup() LL_INFOS() << "File launched." << LL_ENDL; } LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL; - LLProxy::cleanupClass(); + SUBSYSTEM_CLEANUP(LLProxy); LLCore::LLHttp::cleanup(); - LLWearableType::cleanupClass(); + SUBSYSTEM_CLEANUP(LLWearableType); LLMainLoopRepeater::instance().stop(); @@ -2081,10 +2086,34 @@ bool LLAppViewer::cleanup() LLError::LLCallStacks::cleanup(); removeMarkerFiles(); - - LL_INFOS() << "Goodbye!" << LL_ENDL; - removeDumpDir(); + // It's not at first obvious where, in this long sequence, generic cleanup + // calls OUGHT to go. So let's say this: as we migrate cleanup from + // explicit hand-placed calls into the generic mechanism, eventually + // all cleanup will get subsumed into the generic calls. So the calls you + // still see above are calls that MUST happen before the generic cleanup + // kicks in. + + // This calls every remaining LLSingleton's cleanupSingleton() method. + // This method should perform any cleanup that might take significant + // realtime, or might throw an exception. + LLSingletonBase::cleanupAll(); + + // This calls every remaining LLSingleton's deleteSingleton() method. + // No class destructor should perform any cleanup that might take + // significant realtime, or throw an exception. + // LLSingleton machinery includes a last-gasp implicit deleteAll() call, + // so this explicit call shouldn't strictly be necessary. However, by the + // time the runtime engages that implicit call, it may already have + // destroyed things like std::cerr -- so the implicit deleteAll() refrains + // from logging anything. Since both cleanupAll() and deleteAll() call + // their respective cleanup methods in computed dependency order, it's + // probably useful to be able to log that order. + LLSingletonBase::deleteAll(); + + LL_INFOS() << "Goodbye!" << LL_ENDL; + + removeDumpDir(); // return 0; return true; @@ -2465,7 +2494,10 @@ bool LLAppViewer::initConfiguration() if (gSavedSettings.getBOOL("FirstRunThisInstall")) { - // Note that the "FirstRunThisInstall" settings is currently unused. + // 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); } @@ -2904,7 +2936,8 @@ bool LLAppViewer::initWindow() .min_width(gSavedSettings.getU32("MinWindowWidth")) .min_height(gSavedSettings.getU32("MinWindowHeight")) .fullscreen(gSavedSettings.getBOOL("FullScreen")) - .ignore_pixel_depth(ignorePixelDepth); + .ignore_pixel_depth(ignorePixelDepth) + .first_run(mIsFirstRun); gViewerWindow = new LLViewerWindow(window_params); @@ -3037,6 +3070,7 @@ LLSD LLAppViewer::getViewerInfo() const info["VIEWER_VERSION"] = version; info["VIEWER_VERSION_STR"] = LLVersionInfo::getVersion(); info["CHANNEL"] = LLVersionInfo::getChannel(); + info["ADDRESS_SIZE"] = ADDRESS_SIZE; std::string build_config = LLVersionInfo::getBuildConfig(); if (build_config != "Release") { @@ -3087,6 +3121,26 @@ LLSD LLAppViewer::getViewerInfo() const info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION)); + // Settings + + LLRect window_rect = gViewerWindow->getWindowRectRaw(); + info["WINDOW_WIDTH"] = window_rect.getWidth(); + info["WINDOW_HEIGHT"] = window_rect.getHeight(); + info["FONT_SIZE_ADJUSTMENT"] = gSavedSettings.getF32("FontScreenDPI"); + info["UI_SCALE"] = gSavedSettings.getF32("UIScaleFactor"); + info["DRAW_DISTANCE"] = gSavedSettings.getF32("RenderFarClip"); + info["NET_BANDWITH"] = gSavedSettings.getF32("ThrottleBandwidthKBPS"); + info["LOD_FACTOR"] = gSavedSettings.getF32("RenderVolumeLODFactor"); + info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance"); + info["GPU_SHADERS"] = gSavedSettings.getBOOL("RenderDeferred") ? "Enabled" : "Disabled"; + info["TEXTURE_MEMORY"] = gSavedSettings.getS32("TextureMemory"); + + LLSD substitution; + substitution["datetime"] = (S32)(gVFS ? gVFS->creationTime() : 0); + info["VFS_TIME"] = LLTrans::getString("AboutTime", substitution); + + // Libraries + info["J2C_VERSION"] = LLImageJ2C::getEngineInfo(); bool want_fullname = true; info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : LLSD(); @@ -3106,6 +3160,19 @@ LLSD LLAppViewer::getViewerInfo() const info["LLCEFLIB_VERSION"] = LLCEFLIB_VERSION; #else info["LLCEFLIB_VERSION"] = "Undefined"; + +#endif + +#if LL_WINDOWS + std::ostringstream ver_codec; + ver_codec << LIBVLC_VERSION_MAJOR; + ver_codec << "."; + ver_codec << LIBVLC_VERSION_MINOR; + ver_codec << "."; + ver_codec << LIBVLC_VERSION_REVISION; + info["LIBVLC_VERSION"] = ver_codec.str(); +#else + info["LIBVLC_VERSION"] = "Undefined"; #endif S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN); @@ -3193,7 +3260,9 @@ std::string LLAppViewer::getViewerInfoString() const { support << "\n" << LLTrans::getString("AboutDriver", args); } - support << "\n" << LLTrans::getString("AboutLibs", args); + support << "\n" << LLTrans::getString("AboutOGL", args); + support << "\n\n" << LLTrans::getString("AboutSettings", args); + support << "\n\n" << LLTrans::getString("AboutLibs", args); if (info.has("COMPILER")) { support << "\n" << LLTrans::getString("AboutCompiler", args); @@ -5244,12 +5313,15 @@ void LLAppViewer::disconnectViewer() } saveNameCache(); - LLExperienceCache *expCache = LLExperienceCache::getIfExists(); - if (expCache) - expCache->cleanup(); + if (LLExperienceCache::instanceExists()) + { + // TODO: LLExperienceCache::cleanup() logic should be moved to + // cleanupSingleton(). + LLExperienceCache::instance().cleanup(); + } // close inventory interface, close all windows - LLFloaterInventory::cleanup(); + LLSidepanelInventory::cleanup(); gAgentWearables.cleanup(); gAgentCamera.cleanup(); @@ -5310,8 +5382,7 @@ void LLAppViewer::forceErrorInfiniteLoop() void LLAppViewer::forceErrorSoftwareException() { LL_WARNS() << "Forcing a deliberate exception" << LL_ENDL; - // *FIX: Any way to insure it won't be handled? - throw; + LLTHROW(LLException("User selected Force Software Exception")); } void LLAppViewer::forceErrorDriverCrash() @@ -5427,6 +5498,20 @@ void LLAppViewer::handleLoginComplete() mSavePerAccountSettings=true; } +/** +* Check if user is running a new version of the viewer. +* Display the Release Notes if it's not overriden by the "UpdaterShowReleaseNotes" setting. +*/ +void LLAppViewer::showReleaseNotesIfRequired() +{ + if (LLVersionInfo::getChannelAndVersion() != gLastRunVersion + && gSavedSettings.getBOOL("UpdaterShowReleaseNotes") + && !gSavedSettings.getBOOL("FirstLoginThisInstall")) + { + LLSD info(getViewerInfo()); + LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]); + } +} //virtual void LLAppViewer::setMasterSystemAudioMute(bool mute) { @@ -5458,7 +5543,6 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle) } } - /** * Attempts to start a multi-threaded metrics report to be sent back to * the grid for consumption. @@ -5476,6 +5560,11 @@ void LLAppViewer::metricsSend(bool enable_reporting) { std::string caps_url = regionp->getCapability("ViewerMetrics"); + if (gSavedSettings.getBOOL("QAModeMetrics")) + { + dump_sequential_xml("metric_asset_stats",gViewerAssetStats->asLLSD(true)); + } + // Make a copy of the main stats to send into another thread. // Receiving thread takes ownership. LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStats)); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 35d85a9fb1aa9efb308e09734c1de801b09db2fd..91d79c4260e9d50b17807853bfef8949e911c90d 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -78,7 +78,7 @@ class LLAppViewer : public LLApp // virtual bool init(); // Override to do application initialization virtual bool cleanup(); // Override to do application cleanup - virtual bool mainLoop(); // Override for the application main loop. Needs to at least gracefully notice the QUITTING state and exit. + virtual bool frame(); // Override for application body logic // Application control void flushVFSIO(); // waits for vfs transfers to complete @@ -252,6 +252,8 @@ class LLAppViewer : public LLApp void sendLogoutRequest(); void disconnectViewer(); + + void showReleaseNotesIfRequired(); // *FIX: the app viewer class should be some sort of singleton, no? // Perhaps its child class is the singleton and this should be an abstract base. @@ -281,7 +283,6 @@ class LLAppViewer : public LLApp std::string mSerialNumber; bool mPurgeCache; bool mPurgeOnExit; - bool mMainLoopInitialized; LLViewerJoystick* joystick; bool mSavedFinalSnapshot; diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index f5742b29cf09c414ceed55fa749e385810f489ce..6f32aab851ebb2c451490f037ce80637faf0185b 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -95,10 +95,8 @@ int main( int argc, char **argv ) } // Run the application main loop - if(!LLApp::isQuitting()) - { - viewer_app_ptr->mainLoop(); - } + while (! viewer_app_ptr->frame()) + {} if (!LLApp::isError()) { diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index ca219fda59bc971fbcdba41e6731e868057e8fac..bb3bcf2886e2f59312332d717edb2a900aa5c1d7 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -117,12 +117,17 @@ void handleQuit() LLAppViewer::instance()->userQuit(); } -bool runMainLoop() +// This function is called pumpMainLoop() rather than runMainLoop() because +// it passes control to the viewer's main-loop logic for a single frame. Like +// LLAppViewer::frame(), it returns 'true' when it's done. Until then, it +// expects to be called again by the timer in LLAppDelegate +// (llappdelegate-objc.mm). +bool pumpMainLoop() { bool ret = LLApp::isQuitting(); if (!ret && gViewerAppPtr != NULL) { - ret = gViewerAppPtr->mainLoop(); + ret = gViewerAppPtr->frame(); } else { ret = true; } @@ -255,7 +260,7 @@ bool LLAppViewerMacOSX::restoreErrorTrap() unsigned int reset_count = 0; #define SET_SIG(S) sigaction(SIGABRT, &act, &old_act); \ - if((unsigned int)act.sa_sigaction != (unsigned int) old_act.sa_sigaction) \ + if(act.sa_sigaction != old_act.sa_sigaction) \ ++reset_count; // Synchronous signals SET_SIG(SIGABRT) diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 6d879f6416ddf4d41b72c0d6d86b5205c45ccf4e..c81733d107f59fb247f5387fa311f1753e5ae3cf 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -231,6 +231,8 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, DWORD heap_enable_lfh_error[MAX_HEAPS]; S32 num_heaps = 0; + LLWindowWin32::setDPIAwareness(); + #if WINDOWS_CRT_MEM_CHECKS && !INCLUDE_VLD _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); // dump memory leaks on exit #elif 0 @@ -317,10 +319,8 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, } // Run the application main loop - if(!LLApp::isQuitting()) - { - viewer_app_ptr->mainLoop(); - } + while (! viewer_app_ptr->frame()) + {} if (!LLApp::isError()) { @@ -330,33 +330,33 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, // app cleanup if there was a problem. // #if WINDOWS_CRT_MEM_CHECKS - LL_INFOS() << "CRT Checking memory:" << LL_ENDL; - if (!_CrtCheckMemory()) - { - LL_WARNS() << "_CrtCheckMemory() failed at prior to cleanup!" << LL_ENDL; - } - else - { - LL_INFOS() << " No corruption detected." << LL_ENDL; - } + LL_INFOS() << "CRT Checking memory:" << LL_ENDL; + if (!_CrtCheckMemory()) + { + LL_WARNS() << "_CrtCheckMemory() failed at prior to cleanup!" << LL_ENDL; + } + else + { + LL_INFOS() << " No corruption detected." << LL_ENDL; + } #endif - - gGLActive = TRUE; - viewer_app_ptr->cleanup(); - + gGLActive = TRUE; + + viewer_app_ptr->cleanup(); + #if WINDOWS_CRT_MEM_CHECKS - LL_INFOS() << "CRT Checking memory:" << LL_ENDL; - if (!_CrtCheckMemory()) - { - LL_WARNS() << "_CrtCheckMemory() failed after cleanup!" << LL_ENDL; - } - else - { - LL_INFOS() << " No corruption detected." << LL_ENDL; - } + LL_INFOS() << "CRT Checking memory:" << LL_ENDL; + if (!_CrtCheckMemory()) + { + LL_WARNS() << "_CrtCheckMemory() failed after cleanup!" << LL_ENDL; + } + else + { + LL_INFOS() << " No corruption detected." << LL_ENDL; + } #endif - + } delete viewer_app_ptr; viewer_app_ptr = NULL; @@ -558,7 +558,7 @@ bool LLAppViewerWin32::initHardwareTest() // Do driver verification and initialization based on DirectX // hardware polling and driver versions // - if (FALSE == gSavedSettings.getBOOL("NoHardwareProbe")) + if (TRUE == gSavedSettings.getBOOL("ProbeHardwareOnStartup") && FALSE == gSavedSettings.getBOOL("NoHardwareProbe")) { // per DEV-11631 - disable hardware probing for everything // but vram. diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h index bb7d35edbcb740fab527b167831093b0f2a9acb5..a4ef762e8b1b07a02efb185426c766b31739cfd1 100644 --- a/indra/newview/llattachmentsmgr.h +++ b/indra/newview/llattachmentsmgr.h @@ -62,6 +62,9 @@ class LLViewerInventoryItem; //-------------------------------------------------------------------------------- class LLAttachmentsMgr: public LLSingleton<LLAttachmentsMgr> { + LLSINGLETON(LLAttachmentsMgr); + virtual ~LLAttachmentsMgr(); + public: // Stores info for attachments that will be requested during idle. struct AttachmentsInfo @@ -72,9 +75,6 @@ class LLAttachmentsMgr: public LLSingleton<LLAttachmentsMgr> }; typedef std::deque<AttachmentsInfo> attachments_vec_t; - LLAttachmentsMgr(); - virtual ~LLAttachmentsMgr(); - void addAttachmentRequest(const LLUUID& item_id, const U8 attachment_pt, const BOOL add); diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h index 9eecc2d9814911608793d5195a72a7e202e1cdaf..23cc3136468575a3ce1dce365cc4cb525c94c28e 100644 --- a/indra/newview/llautoreplace.h +++ b/indra/newview/llautoreplace.h @@ -191,6 +191,7 @@ class LLAutoReplaceSettings */ class LLAutoReplace : public LLSingleton<LLAutoReplace> { + LLSINGLETON(LLAutoReplace); public: /// Callback that provides the hook for use in text entry methods void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text); @@ -202,8 +203,6 @@ class LLAutoReplace : public LLSingleton<LLAutoReplace> void setSettings(const LLAutoReplaceSettings& settings); private: - friend class LLSingleton<LLAutoReplace>; - LLAutoReplace(); /*virtual*/ void initSingleton(); LLAutoReplaceSettings mSettings; ///< configuration information diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index a6e745448a98c921cd4a1aa46238d01b18251426..36e95c07f4d3ae2edd2d14b85395987b287e02c2 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -689,6 +689,8 @@ namespace action_give_inventory struct LLShareInfo : public LLSingleton<LLShareInfo> { + LLSINGLETON_EMPTY_CTOR(LLShareInfo); + public: std::vector<LLAvatarName> mAvatarNames; uuid_vec_t mAvatarUuids; }; @@ -950,15 +952,22 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList(); if (inventory_selected.empty()) return false; // nothing selected + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); bool can_share = true; std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin(); const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end(); for (; it != it_end; ++it) { - LLViewerInventoryCategory* inv_cat = gInventory.getCategory(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID()); - // any category can be offered. + LLUUID cat_id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID(); + LLViewerInventoryCategory* inv_cat = gInventory.getCategory(cat_id); + // any category can be offered if it's not in trash. if (inv_cat) { + if ((cat_id == trash_id) || gInventory.isObjectDescendentOf(cat_id, trash_id)) + { + can_share = false; + break; + } continue; } diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h index 5b5720f4ac8fd74887b723c5feefe9d36e940ae8..a1dacd1a270a201a13038786c9c71c489f221604 100644 --- a/indra/newview/llavatariconctrl.h +++ b/indra/newview/llavatariconctrl.h @@ -37,6 +37,8 @@ class LLAvatarName; class LLAvatarIconIDCache: public LLSingleton<LLAvatarIconIDCache> { + LLSINGLETON(LLAvatarIconIDCache); + public: struct LLAvatarIconIDCacheItem { @@ -46,10 +48,6 @@ class LLAvatarIconIDCache: public LLSingleton<LLAvatarIconIDCache> bool expired(); }; - LLAvatarIconIDCache() - : mFilename("avatar_icons_cache.txt") - {} - void load (); void save (); @@ -64,6 +62,11 @@ class LLAvatarIconIDCache: public LLSingleton<LLAvatarIconIDCache> std::map<LLUUID,LLAvatarIconIDCacheItem> mCache;//we cache only LLUID and time }; +inline +LLAvatarIconIDCache::LLAvatarIconIDCache() + : mFilename("avatar_icons_cache.txt") +{} + namespace LLAvatarIconCtrlEnums { enum ESymbolPos diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index 1dcd2c9b907b674a1f80d1f442914d408bba0e9c..d5c5c75c6914d7a8942a5da13470af7a5ea0c0a8 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -187,13 +187,12 @@ class LLAvatarPropertiesObserver class LLAvatarPropertiesProcessor : public LLSingleton<LLAvatarPropertiesProcessor> { -public: - - LLAvatarPropertiesProcessor(); + LLSINGLETON(LLAvatarPropertiesProcessor); virtual ~LLAvatarPropertiesProcessor(); +public: void addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer); - + void removeObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer); // Request various types of avatar data. Duplicate requests will be diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index 5431daca32e4ffab26234f4453ecc73afa15aeca..7413dbed20049131d5a6728f0c5be8f778248675 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -354,7 +354,7 @@ void LLAvatarRenderInfoAccountant::resetRenderInfoScanTimer() // are returned for a new LLViewerRegion, and is the earliest time to get render info void LLAvatarRenderInfoAccountant::scanNewRegion(const LLUUID& region_id) { - LL_INFOS("AvatarRenderInfo") << region_id << LL_ENDL; + LL_DEBUGS("AvatarRenderInfo") << region_id << LL_ENDL; // Reset the global timer so it will scan regions on the next call to ::idle LLAvatarRenderInfoAccountant::getInstance()->resetRenderInfoScanTimer(); diff --git a/indra/newview/llavatarrenderinfoaccountant.h b/indra/newview/llavatarrenderinfoaccountant.h index 870ef4f394ac44870ad4b09472bad2e883422084..6b5fa7bc35d21c7b95ebabc06e66c9dd893f0beb 100644 --- a/indra/newview/llavatarrenderinfoaccountant.h +++ b/indra/newview/llavatarrenderinfoaccountant.h @@ -38,13 +38,13 @@ class LLViewerRegion; // that is sent to or fetched from regions. class LLAvatarRenderInfoAccountant : public LLSingleton<LLAvatarRenderInfoAccountant> { + LLSINGLETON(LLAvatarRenderInfoAccountant); + ~LLAvatarRenderInfoAccountant(); + private: LOG_CLASS(LLAvatarRenderInfoAccountant); public: - LLAvatarRenderInfoAccountant(); - ~LLAvatarRenderInfoAccountant(); - void sendRenderInfoToRegion(LLViewerRegion * regionp); void getRenderInfoFromRegion(LLViewerRegion * regionp); diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp index 24934fdb73c8008e910a60b7029816b3d43871db..94584a623b95b56b202b16fd3cc9c720d3bc565a 100644 --- a/indra/newview/llavatarrendernotifier.cpp +++ b/indra/newview/llavatarrendernotifier.cpp @@ -38,6 +38,7 @@ #include "llnotifications.h" #include "llnotificationsutil.h" #include "llnotificationtemplate.h" +#include "llslurl.h" #include "lltimer.h" #include "llvoavatarself.h" #include "llviewercontrol.h" @@ -51,6 +52,11 @@ static const F32 RENDER_ALLOWED_CHANGE_PCT = 0.1; // wait seconds before processing over limit updates after last complexity change static const U32 OVER_LIMIT_UPDATE_DELAY = 70; +static const U32 WARN_HUD_OBJECTS_LIMIT = 1000; +static const U32 WARN_HUD_TEXTURES_LIMIT = 200; +static const U32 WARN_HUD_OVERSIZED_TEXTURES_LIMIT = 6; +static const U32 WARN_HUD_TEXTURE_MEMORY_LIMIT = 32000000; // in bytes + LLAvatarRenderNotifier::LLAvatarRenderNotifier() : mAgentsCount(0), @@ -264,3 +270,220 @@ void LLAvatarRenderNotifier::updateNotificationAgent(U32 agentComplexity) } } +// LLHUDRenderNotifier + +static const char* e_hud_messages[] = +{ + "hud_render_textures_warning", + "hud_render_cramped_warning", + "hud_render_heavy_textures_warning", + "hud_render_cost_warning", + "hud_render_memory_warning", +}; + +LLHUDRenderNotifier::LLHUDRenderNotifier() : +mReportedHUDWarning(WARN_NONE) +{ +} + +LLHUDRenderNotifier::~LLHUDRenderNotifier() +{ +} + +void LLHUDRenderNotifier::updateNotificationHUD(hud_complexity_list_t complexity) +{ + if (!isAgentAvatarValid() || !gAgentWearables.areWearablesLoaded()) + { + // data not ready. + return; + } + + // TODO: + // Find a way to show message with list of issues, but without making it too large + // and intrusive. + + LLHUDComplexity new_total_complexity; + LLHUDComplexity report_complexity; + + hud_complexity_list_t::iterator iter = complexity.begin(); + hud_complexity_list_t::iterator end = complexity.end(); + EWarnLevel warning_level = WARN_NONE; + for (; iter != end; ++iter) + { + LLHUDComplexity object_complexity = *iter; + EWarnLevel object_level = getWarningType(object_complexity, report_complexity); + if (object_level >= 0) + { + warning_level = object_level; + report_complexity = object_complexity; + } + new_total_complexity.objectsCost += object_complexity.objectsCost; + new_total_complexity.objectsCount += object_complexity.objectsCount; + new_total_complexity.texturesCost += object_complexity.texturesCost; + new_total_complexity.texturesCount += object_complexity.texturesCount; + new_total_complexity.largeTexturesCount += object_complexity.largeTexturesCount; + new_total_complexity.texturesMemoryTotal += object_complexity.texturesMemoryTotal; + } + + if (mHUDPopUpDelayTimer.hasExpired() || isNotificationVisible()) + { + if (warning_level >= 0) + { + // Display info about most complex HUD object + // make sure it shown only once unless object's complexity or object itself changed + if (mReportedHUDComplexity.objectId != report_complexity.objectId + || mReportedHUDWarning != warning_level) + { + displayHUDNotification(warning_level, report_complexity.objectId, report_complexity.objectName, report_complexity.jointName); + mReportedHUDComplexity = report_complexity; + mReportedHUDWarning = warning_level; + } + } + else + { + // Check if total complexity is above threshold and above previous warning + // Show warning with highest importance (5m delay between warnings by default) + if (!mReportedHUDComplexity.objectId.isNull()) + { + mReportedHUDComplexity.reset(); + mReportedHUDWarning = WARN_NONE; + } + + warning_level = getWarningType(new_total_complexity, mReportedHUDComplexity); + if (warning_level >= 0 && mReportedHUDWarning != warning_level) + { + displayHUDNotification(warning_level); + } + mReportedHUDComplexity = new_total_complexity; + mReportedHUDWarning = warning_level; + } + } + else if (warning_level >= 0) + { + LL_DEBUGS("HUDdetail") << "HUD individual warning postponed" << LL_ENDL; + } + + if (mLatestHUDComplexity.objectsCost != new_total_complexity.objectsCost + || mLatestHUDComplexity.objectsCount != new_total_complexity.objectsCount + || mLatestHUDComplexity.texturesCost != new_total_complexity.texturesCost + || mLatestHUDComplexity.texturesCount != new_total_complexity.texturesCount + || mLatestHUDComplexity.largeTexturesCount != new_total_complexity.largeTexturesCount + || mLatestHUDComplexity.texturesMemoryTotal != new_total_complexity.texturesMemoryTotal) + { + LL_INFOS("HUDdetail") << "HUD textures count: " << new_total_complexity.texturesCount + << " HUD textures cost: " << new_total_complexity.texturesCost + << " Large textures: " << new_total_complexity.largeTexturesCount + << " HUD objects cost: " << new_total_complexity.objectsCost + << " HUD objects count: " << new_total_complexity.objectsCount << LL_ENDL; + + mLatestHUDComplexity = new_total_complexity; + } +} + +bool LLHUDRenderNotifier::isNotificationVisible() +{ + return mHUDNotificationPtr != NULL && mHUDNotificationPtr->isActive(); +} + +// private static +LLHUDRenderNotifier::EWarnLevel LLHUDRenderNotifier::getWarningType(LLHUDComplexity object_complexity, LLHUDComplexity cmp_complexity) +{ + static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U); // ties max HUD cost to avatar cost + static LLCachedControl<U32> max_objects_count(gSavedSettings, "RenderHUDObjectsWarning", WARN_HUD_OBJECTS_LIMIT); + static LLCachedControl<U32> max_textures_count(gSavedSettings, "RenderHUDTexturesWarning", WARN_HUD_TEXTURES_LIMIT); + static LLCachedControl<U32> max_oversized_count(gSavedSettings, "RenderHUDOversizedTexturesWarning", WARN_HUD_OVERSIZED_TEXTURES_LIMIT); + static LLCachedControl<U32> max_texture_memory(gSavedSettings, "RenderHUDTexturesMemoryWarning", WARN_HUD_TEXTURE_MEMORY_LIMIT); + + if (cmp_complexity.texturesMemoryTotal < object_complexity.texturesMemoryTotal + && object_complexity.texturesMemoryTotal > (F64Bytes)max_texture_memory) + { + // Note: Memory might not be accurate since texture is still loading or discard level changes + + LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " memory usage over limit, " + << " was " << cmp_complexity.texturesMemoryTotal + << " is " << object_complexity.texturesMemoryTotal << LL_ENDL; + + return WARN_MEMORY; + } + else if ((cmp_complexity.objectsCost < object_complexity.objectsCost + || cmp_complexity.texturesCost < object_complexity.texturesCost) + && max_render_cost > 0 + && object_complexity.objectsCost + object_complexity.texturesCost > max_render_cost) + { + LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " complexity over limit," + << " HUD textures cost: " << object_complexity.texturesCost + << " HUD objects cost: " << object_complexity.objectsCost << LL_ENDL; + + return WARN_COST; + } + else if (cmp_complexity.largeTexturesCount < object_complexity.largeTexturesCount + && object_complexity.largeTexturesCount > max_oversized_count) + { + LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " contains to many large textures: " + << object_complexity.largeTexturesCount << LL_ENDL; + + return WARN_HEAVY; + } + else if (cmp_complexity.texturesCount < object_complexity.texturesCount + && object_complexity.texturesCount > max_textures_count) + { + LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " contains too many textures: " + << object_complexity.texturesCount << LL_ENDL; + + return WARN_CRAMPED; + } + else if (cmp_complexity.objectsCount < object_complexity.objectsCount + && object_complexity.objectsCount > max_objects_count) + { + LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " contains too many objects: " + << object_complexity.objectsCount << LL_ENDL; + + return WARN_TEXTURES; + } + return WARN_NONE; +} + +void LLHUDRenderNotifier::displayHUDNotification(EWarnLevel warn_type, LLUUID obj_id, std::string obj_name, std::string joint_name) +{ + static LLCachedControl<U32> pop_up_delay(gSavedSettings, "ComplexityChangesPopUpDelay", 300); + static LLCachedControl<U32> expire_delay(gSavedSettings, "ShowMyComplexityChanges", 20); + LLDate expire_date(LLDate::now().secondsSinceEpoch() + expire_delay); + + // Since we need working "ignoretext" there is no other way but to + // use single notification while constructing it from multiple pieces + LLSD reason_args; + if (obj_id.isNull()) + { + reason_args["HUD_DETAILS"] = LLTrans::getString("hud_description_total"); + } + else + { + if (obj_name.empty()) + { + LL_WARNS("HUDdetail") << "Object name not assigned" << LL_ENDL; + } + if (joint_name.empty()) + { + std::string verb = "select?name=" + LLURI::escape(obj_name); + reason_args["HUD_DETAILS"] = LLSLURL("inventory", obj_id, verb.c_str()).getSLURLString(); + } + else + { + LLSD object_args; + std::string verb = "select?name=" + LLURI::escape(obj_name); + object_args["OBJ_NAME"] = LLSLURL("inventory", obj_id, verb.c_str()).getSLURLString(); + object_args["JNT_NAME"] = LLTrans::getString(joint_name); + reason_args["HUD_DETAILS"] = LLTrans::getString("hud_name_with_joint", object_args); + } + } + + LLSD msg_args; + msg_args["HUD_REASON"] = LLTrans::getString(e_hud_messages[warn_type], reason_args); + + mHUDNotificationPtr = LLNotifications::instance().add(LLNotification::Params() + .name("HUDComplexityWarning") + .expiry(expire_date) + .substitutions(msg_args)); + mHUDPopUpDelayTimer.resetWithExpiry(pop_up_delay); +} + diff --git a/indra/newview/llavatarrendernotifier.h b/indra/newview/llavatarrendernotifier.h index 2a2704de28550719508abf44421039b50cbbcc34..ec17b3d9e62117bdeaadb9db4016dd8ba662b051 100644 --- a/indra/newview/llavatarrendernotifier.h +++ b/indra/newview/llavatarrendernotifier.h @@ -33,13 +33,43 @@ class LLViewerRegion; +struct LLHUDComplexity +{ + LLHUDComplexity() + { + reset(); + } + void reset() + { + objectId = LLUUID::null; + objectName = ""; + objectsCost = 0; + objectsCount = 0; + texturesCost = 0; + texturesCount = 0; + largeTexturesCount = 0; + texturesMemoryTotal = (F64Bytes)0; + } + LLUUID objectId; + std::string objectName; + std::string jointName; + U32 objectsCost; + U32 objectsCount; + U32 texturesCost; + U32 texturesCount; + U32 largeTexturesCount; + F64Bytes texturesMemoryTotal; +}; + +typedef std::list<LLHUDComplexity> hud_complexity_list_t; + // Class to notify user about drastic changes in agent's render weights or if other agents // reported that user's agent is too 'heavy' for their settings class LLAvatarRenderNotifier : public LLSingleton<LLAvatarRenderNotifier> { -public: - LLAvatarRenderNotifier(); + LLSINGLETON(LLAvatarRenderNotifier); +public: void displayNotification(bool show_over_limit); bool isNotificationVisible(); @@ -81,4 +111,36 @@ class LLAvatarRenderNotifier : public LLSingleton<LLAvatarRenderNotifier> S32 mLastOutfitRezStatus; }; +// Class to notify user about heavy set of HUD +class LLHUDRenderNotifier : public LLSingleton<LLHUDRenderNotifier> +{ + LLSINGLETON(LLHUDRenderNotifier); + ~LLHUDRenderNotifier(); + +public: + void updateNotificationHUD(hud_complexity_list_t complexity); + bool isNotificationVisible(); + +private: + enum EWarnLevel + { + WARN_NONE = -1, + WARN_TEXTURES = 0, // least important + WARN_CRAMPED, + WARN_HEAVY, + WARN_COST, + WARN_MEMORY, //most important + }; + + LLNotificationPtr mHUDNotificationPtr; + + static EWarnLevel getWarningType(LLHUDComplexity object_complexity, LLHUDComplexity cmp_complexity); + void displayHUDNotification(EWarnLevel warn_type, LLUUID obj_id = LLUUID::null, std::string object_name = "", std::string joint_name = ""); + + LLHUDComplexity mReportedHUDComplexity; + EWarnLevel mReportedHUDWarning; + LLHUDComplexity mLatestHUDComplexity; + LLFrameTimer mHUDPopUpDelayTimer; +}; + #endif /* ! defined(LL_llavatarrendernotifier_H) */ diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h index a5de8a53271dc434fa5cae04ad7ee59d1ce47705..8b9d0dda8b6ca2158b3e90bdec497039bc397fe6 100644 --- a/indra/newview/llchannelmanager.h +++ b/indra/newview/llchannelmanager.h @@ -43,6 +43,9 @@ namespace LLNotificationsUI */ class LLChannelManager : public LLSingleton<LLChannelManager> { + LLSINGLETON(LLChannelManager); + virtual ~LLChannelManager(); + public: @@ -65,9 +68,6 @@ class LLChannelManager : public LLSingleton<LLChannelManager> } }; - LLChannelManager(); - virtual ~LLChannelManager(); - // On LoginCompleted - show StartUp toast void onLoginCompleted(); // removes a channel intended for the startup toast and allows other channels to show their toasts diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 00fa6dd9798793d036595787ecfdfc65d3520fe0..54c6c985d6b5d2c040601916e13d7de7558ec262 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -311,7 +311,8 @@ LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel) } else if (mesg[0] == '/' && mesg[1] - && LLStringOps::isDigit(mesg[1])) + && (LLStringOps::isDigit(mesg[1]) + || (mesg[1] == '-' && mesg[2] && LLStringOps::isDigit(mesg[2])))) { // This a special "/20" speak on a channel S32 pos = 0; @@ -325,7 +326,7 @@ LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel) channel_string.push_back(c); pos++; } - while(c && pos < 64 && LLStringOps::isDigit(c)); + while(c && pos < 64 && (LLStringOps::isDigit(c) || (pos == 1 && c == '-'))); // Move the pointer forward to the first non-whitespace char // Check isspace before looping, so we can handle "/33foo" diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index cfc62c07b6e073a8ee36e930cb74ec6fcd465a1c..f5721fb34842729f648a3f3f93b1e49a95fd551f 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -240,6 +240,32 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification) } } + S32 chars_in_line = mMsgText->getRect().getWidth() / messageFont->getWidth("c"); + S32 max_lines = notification["available_height"].asInteger() / (mMsgText->getTextPixelHeight() + 4); + S32 new_line_chars = std::count(messageText.begin(), messageText.end(), '\n'); + S32 lines_count = (messageText.size() - new_line_chars) / chars_in_line + new_line_chars + 1; + + //Remove excessive chars if message is not fit in available height. MAINT-6891 + if(lines_count > max_lines) + { + while(lines_count > max_lines) + { + std::size_t nl_pos = messageText.rfind('\n'); + if (nl_pos != std::string::npos) + { + nl_pos = nl_pos > messageText.length() - chars_in_line? nl_pos : messageText.length() - chars_in_line; + messageText.erase(messageText.begin() + nl_pos, messageText.end()); + } + else + { + messageText.erase(messageText.end() - chars_in_line, messageText.end()); + } + new_line_chars = std::count(messageText.begin(), messageText.end(), '\n'); + lines_count = (messageText.size() - new_line_chars) / chars_in_line + new_line_chars; + } + messageText += " ..."; + } + //append text { LLStyle::Params style_params; diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp index 254e3f61a81a8763829cda1ca716c64d2e36a8a9..c4f959bfa9c03f27d59ef26ec23b92dfab65d520 100644 --- a/indra/newview/llchicletbar.cpp +++ b/indra/newview/llchicletbar.cpp @@ -38,7 +38,7 @@ namespace const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel"; } -LLChicletBar::LLChicletBar(const LLSD&) +LLChicletBar::LLChicletBar() : mChicletPanel(NULL), mToolbarStack(NULL) { diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h index 956c82cb77026036fbd0cc486d46fc51a8833828..6c521dc1d504f176b0f3cfc367ed10ece092af14 100644 --- a/indra/newview/llchicletbar.h +++ b/indra/newview/llchicletbar.h @@ -38,8 +38,9 @@ class LLChicletBar : public LLSingleton<LLChicletBar> , public LLPanel { + LLSINGLETON(LLChicletBar); LOG_CLASS(LLChicletBar); - friend class LLSingleton<LLChicletBar>; + public: BOOL postBuild(); @@ -82,8 +83,6 @@ class LLChicletBar void fitWithTopInfoBar(); protected: - LLChicletBar(const LLSD& key = LLSD()); - LLChicletPanel* mChicletPanel; LLLayoutStack* mToolbarStack; }; diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index 1819fc74ee1ae6c30c614e457e635f75d7e92c2c..90a5483dc98f2686d779b4851ed51d5945681f53 100644 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -26,6 +26,7 @@ #include "llviewerprecompiledheaders.h" #include "llcommandlineparser.h" +#include "llexception.h" // *NOTE: The boost::lexical_cast generates // the warning C4701(local used with out assignment) in VC7.1. @@ -50,6 +51,7 @@ #include "llsdserialize.h" #include "llerror.h" #include "stringize.h" +#include "llexception.h" #include <string> #include <set> #include <iostream> @@ -98,14 +100,14 @@ namespace bool gPastLastOption = false; } -class LLCLPError : public std::logic_error { +class LLCLPError : public LLException { public: - LLCLPError(const std::string& what) : std::logic_error(what) {} + LLCLPError(const std::string& what) : LLException(what) {} }; -class LLCLPLastOption : public std::logic_error { +class LLCLPLastOption : public LLException { public: - LLCLPLastOption(const std::string& what) : std::logic_error(what) {} + LLCLPLastOption(const std::string& what) : LLException(what) {} }; class LLCLPValue : public po::value_semantic_codecvt_helper<char> @@ -202,17 +204,17 @@ class LLCLPValue : public po::value_semantic_codecvt_helper<char> { if(gPastLastOption) { - throw(LLCLPLastOption("Don't parse no more!")); + LLTHROW(LLCLPLastOption("Don't parse no more!")); } // Error checks. Needed? if (!value_store.empty() && !is_composing()) { - throw(LLCLPError("Non composing value with multiple occurences.")); + LLTHROW(LLCLPError("Non composing value with multiple occurences.")); } if (new_tokens.size() < min_tokens() || new_tokens.size() > max_tokens()) { - throw(LLCLPError("Illegal number of tokens specified.")); + LLTHROW(LLCLPError("Illegal number of tokens specified.")); } if(value_store.empty()) @@ -466,7 +468,7 @@ onevalue(const std::string& option, { // What does it mean when the user specifies a command-line switch // that requires a value, but omits the value? Complain. - throw LLCLPError(STRINGIZE("No value specified for --" << option << "!")); + LLTHROW(LLCLPError(STRINGIZE("No value specified for --" << option << "!"))); } else if (value.size() > 1) { @@ -484,9 +486,9 @@ void badvalue(const std::string& option, // If the user passes an unusable value for a command-line switch, it // seems like a really bad idea to just ignore it, even with a log // warning. - throw LLCLPError(STRINGIZE("Invalid value specified by command-line switch '" << option - << "' for variable '" << varname << "' of type " << type - << ": '" << value << "'")); + LLTHROW(LLCLPError(STRINGIZE("Invalid value specified by command-line switch '" << option + << "' for variable '" << varname << "' of type " << type + << ": '" << value << "'"))); } template <typename T> diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 219bcf0eb03b0da021bcac4bb7c6329b034bf243..76e16f5a1fffef3ac7445260f02268a28a2773a9 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -62,6 +62,59 @@ #include "llviewerassetupload.h" #include "llcorehttputil.h" +namespace +{ + + const std::string QUEUE_EVENTPUMP_NAME("ScriptActionQueue"); + + // ObjectIventoryFetcher is an adapter between the LLVOInventoryListener::inventoryChanged + // callback mechanism and the LLEventPump coroutine architecture allowing the + // coroutine to wait for the inventory event. + class ObjectInventoryFetcher: public LLVOInventoryListener + { + public: + typedef boost::shared_ptr<ObjectInventoryFetcher> ptr_t; + + ObjectInventoryFetcher(LLEventPump &pump, LLViewerObject* object, void* user_data) : + mPump(pump), + LLVOInventoryListener() + { + registerVOInventoryListener(object, this); + } + + virtual void inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data); + + void fetchInventory() + { + requestVOInventory(); + } + + const LLInventoryObject::object_list_t & getInventoryList() const { return mInventoryList; } + + private: + LLInventoryObject::object_list_t mInventoryList; + LLEventPump & mPump; + }; + + class HandleScriptUserData + { + public: + HandleScriptUserData(const std::string &pumpname) : + mPumpname(pumpname) + { } + + const std::string &getPumpName() const { return mPumpname; } + + private: + std::string mPumpname; + }; + + +} + // *NOTE$: A minor specialization of LLScriptAssetUpload, it does not require a buffer // (and does not save a buffer to the vFS) and it finds the compile queue window and // displays a compiling message. @@ -93,7 +146,7 @@ class LLQueuedScriptAssetUpload : public LLScriptAssetUpload queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(message, ADD_BOTTOM); } - return LLSD().with("success", LLSD::Boolean(true)); + return LLSDMap("success", LLSD::Boolean(true)); } @@ -149,47 +202,6 @@ BOOL LLFloaterScriptQueue::postBuild() return TRUE; } -// This is the callback method for the viewer object currently being -// worked on. -// NOT static, virtual! -void LLFloaterScriptQueue::inventoryChanged(LLViewerObject* viewer_object, - LLInventoryObject::object_list_t* inv, - S32, - void* q_id) -{ - LL_INFOS() << "LLFloaterScriptQueue::inventoryChanged() for object " - << viewer_object->getID() << LL_ENDL; - - //Remove this listener from the object since its - //listener callback is now being executed. - - //We remove the listener here because the function - //removeVOInventoryListener removes the listener from a ViewerObject - //which it internally stores. - - //If we call this further down in the function, calls to handleInventory - //and nextObject may update the internally stored viewer object causing - //the removal of the incorrect listener from an incorrect object. - - //Fixes SL-6119:Recompile scripts fails to complete - removeVOInventoryListener(); - - if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) ) - { - handleInventory(viewer_object, inv); - } - else - { - // something went wrong... - // note that we're not working on this one, and move onto the - // next object in the list. - LL_WARNS() << "No inventory for " << mCurrentObjectID - << LL_ENDL; - nextObject(); - } -} - - // static void LLFloaterScriptQueue::onCloseBtn(void* user_data) { @@ -197,9 +209,10 @@ void LLFloaterScriptQueue::onCloseBtn(void* user_data) self->closeFloater(); } -void LLFloaterScriptQueue::addObject(const LLUUID& id) +void LLFloaterScriptQueue::addObject(const LLUUID& id, std::string name) { - mObjectIDs.push_back(id); + ObjectData obj = { id, name }; + mObjectList.push_back(obj); } BOOL LLFloaterScriptQueue::start() @@ -208,7 +221,7 @@ BOOL LLFloaterScriptQueue::start() LLStringUtil::format_map_t args; args["[START]"] = mStartString; - args["[COUNT]"] = llformat ("%d", mObjectIDs.size()); + args["[COUNT]"] = llformat ("%d", mObjectList.size()); buffer = getString ("Starting", args); getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); @@ -216,74 +229,24 @@ BOOL LLFloaterScriptQueue::start() return startQueue(); } -BOOL LLFloaterScriptQueue::isDone() const +void LLFloaterScriptQueue::addProcessingMessage(const std::string &message, const LLSD &args) { - return (mCurrentObjectID.isNull() && (mObjectIDs.size() == 0)); -} + std::string buffer(LLTrans::getString(message, args)); -// go to the next object. If no objects left, it falls out silently -// and waits to be killed by the window being closed. -BOOL LLFloaterScriptQueue::nextObject() -{ - U32 count; - BOOL successful_start = FALSE; - do - { - count = mObjectIDs.size(); - LL_INFOS() << "LLFloaterScriptQueue::nextObject() - " << count - << " objects left to process." << LL_ENDL; - mCurrentObjectID.setNull(); - if(count > 0) - { - successful_start = popNext(); - } - LL_INFOS() << "LLFloaterScriptQueue::nextObject() " - << (successful_start ? "successful" : "unsuccessful") - << LL_ENDL; - } while((mObjectIDs.size() > 0) && !successful_start); - if(isDone() && !mDone) - { - mDone = true; - getChild<LLScrollListCtrl>("queue output")->addSimpleElement(getString("Done"), ADD_BOTTOM); - getChildView("close")->setEnabled(TRUE); - } - return successful_start; + getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); } -// returns true if the queue has started, otherwise false. This -// method pops the top object off of the queue. -BOOL LLFloaterScriptQueue::popNext() +void LLFloaterScriptQueue::addStringMessage(const std::string &message) { - // get the first element off of the container, and attempt to get - // the inventory. - BOOL rv = FALSE; - S32 count = mObjectIDs.size(); - if(mCurrentObjectID.isNull() && (count > 0)) - { - mCurrentObjectID = mObjectIDs.at(0); - LL_INFOS() << "LLFloaterScriptQueue::popNext() - mCurrentID: " - << mCurrentObjectID << LL_ENDL; - mObjectIDs.erase(mObjectIDs.begin()); - LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID); - if(obj) - { - LL_INFOS() << "LLFloaterScriptQueue::popNext() requesting inv for " - << mCurrentObjectID << LL_ENDL; - LLUUID* id = new LLUUID(getKey().asUUID()); - registerVOInventoryListener(obj,id); - requestVOInventory(); - rv = TRUE; - } - } - return rv; + getChild<LLScrollListCtrl>("queue output")->addSimpleElement(message, ADD_BOTTOM); } -BOOL LLFloaterScriptQueue::startQueue() + +BOOL LLFloaterScriptQueue::isDone() const { - return nextObject(); + return (mCurrentObjectID.isNull() && (mObjectList.size() == 0)); } - ///---------------------------------------------------------------------------- /// Class LLFloaterCompileQueue ///---------------------------------------------------------------------------- @@ -293,7 +256,6 @@ LLFloaterCompileQueue::LLFloaterCompileQueue(const LLSD& key) setTitle(LLTrans::getString("CompileQueueTitle")); setStartString(LLTrans::getString("CompileQueueStart")); -// mUploadQueue = new LLAssetUploadQueue(new LLCompileFloaterUploadQueueSupplier(key.asUUID())); } LLFloaterCompileQueue::~LLFloaterCompileQueue() @@ -306,7 +268,6 @@ void LLFloaterCompileQueue::experienceIdsReceived( const LLSD& content ) { mExperienceIds.insert(it->asUUID()); } - nextObject(); } BOOL LLFloaterCompileQueue::hasExperience( const LLUUID& id ) const @@ -314,188 +275,256 @@ BOOL LLFloaterCompileQueue::hasExperience( const LLUUID& id ) const return mExperienceIds.find(id) != mExperienceIds.end(); } +// //Attempt to record this asset ID. If it can not be inserted into the set +// //then it has already been processed so return false. -void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object, - LLInventoryObject::object_list_t* inv) +void LLFloaterCompileQueue::handleHTTPResponse(std::string pumpName, const LLSD &expresult) { - // find all of the lsl, leaving off duplicates. We'll remove - // all matching asset uuids on compilation success. + LLEventPumps::instance().post(pumpName, expresult); +} - typedef std::multimap<LLUUID, LLPointer<LLInventoryItem> > uuid_item_map; - uuid_item_map asset_item_map; +// *TODO: handleSCriptRetrieval is passed into the VFS via a legacy C function pointer +// future project would be to convert these to C++ callables (std::function<>) so that +// we can use bind and remove the userData parameter. +// +void LLFloaterCompileQueue::handleScriptRetrieval(LLVFS *vfs, const LLUUID& assetId, + LLAssetType::EType type, void* userData, S32 status, LLExtStat extStatus) +{ + LLSD result(LLSD::emptyMap()); - LLInventoryObject::object_list_t::const_iterator it = inv->begin(); - LLInventoryObject::object_list_t::const_iterator end = inv->end(); - for ( ; it != end; ++it) - { - if((*it)->getType() == LLAssetType::AT_LSL_TEXT) - { - LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); - // Check permissions before allowing the user to retrieve data. - if (item->getPermissions().allowModifyBy(gAgent.getID(), gAgent.getGroupID()) && - item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID()) ) - { - LLPointer<LLViewerInventoryItem> script = new LLViewerInventoryItem(item); - mCurrentScripts.push_back(script); - asset_item_map.insert(std::make_pair(item->getAssetUUID(), item)); - } - } - } + result["asset_id"] = assetId; + if (status) + { + result["error"] = status; + + if (status == LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE) + { + result["message"] = LLTrans::getString("CompileQueueProblemDownloading") + (":"); + result["alert"] = LLTrans::getString("CompileQueueScriptNotFound"); + } + else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) + { + result["message"] = LLTrans::getString("CompileQueueInsufficientPermFor") + (":"); + result["alert"] = LLTrans::getString("CompileQueueInsufficientPermDownload"); + } + else + { + result["message"] = LLTrans::getString("CompileQueueUnknownFailure"); + } + } - if (asset_item_map.empty()) - { - // There are no scripts in this object. move on. - nextObject(); - } - else - { - // request all of the assets. - uuid_item_map::iterator iter; - for(iter = asset_item_map.begin(); iter != asset_item_map.end(); iter++) - { - LLInventoryItem *itemp = iter->second; - LLScriptQueueData* datap = new LLScriptQueueData(getKey().asUUID(), - viewer_object->getID(), itemp); - - LLExperienceCache::instance().fetchAssociatedExperience(itemp->getParentUUID(), itemp->getUUID(), - boost::bind(&LLFloaterCompileQueue::requestAsset, datap, _1)); - } - } -} + LLEventPumps::instance().post(((HandleScriptUserData *)userData)->getPumpName(), result); +} -void LLFloaterCompileQueue::requestAsset( LLScriptQueueData* datap, const LLSD& experience ) +/*static*/ +void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID parent) { - LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", datap->mQueueID); - if(!queue) - { - delete datap; - return; - } - if(experience.has(LLExperienceCache::EXPERIENCE_ID)) - { - datap->mExperienceId=experience[LLExperienceCache::EXPERIENCE_ID].asUUID(); - if(!queue->hasExperience(datap->mExperienceId)) - { - std::string buffer = LLTrans::getString("CompileNoExperiencePerm", LLSD::emptyMap() - .with("SCRIPT", datap->mItem->getName()) - .with("EXPERIENCE", experience[LLExperienceCache::NAME].asString())); - - queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); - queue->removeItemByItemID(datap->mItem->getUUID()); - delete datap; - return; - } - } - //LL_INFOS() << "ITEM NAME 2: " << names.get(i) << LL_ENDL; - gAssetStorage->getInvItemAsset(datap->mHost, - gAgent.getID(), - gAgent.getSessionID(), - datap->mItem->getPermissions().getOwner(), - datap->mTaskId, - datap->mItem->getUUID(), - datap->mItem->getAssetUUID(), - datap->mItem->getType(), - LLFloaterCompileQueue::scriptArrived, - (void*)datap); + LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", parent); + if (!queue) + return; + + queue->experienceIdsReceived(result["experience_ids"]); + + // getDerived handle gets a handle that can be resolved to a parent class of the derived object. + LLHandle<LLFloaterScriptQueue> hFloater(queue->getDerivedHandle<LLFloaterScriptQueue>()); + + // note subtle difference here: getDerivedHandle in this case is for an LLFloaterCompileQueue + fnQueueAction_t fn = boost::bind(LLFloaterCompileQueue::processScript, + queue->getDerivedHandle<LLFloaterCompileQueue>(), _1, _2, _3); + + + LLCoros::instance().launch("ScriptQueueCompile", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro, + queue->mStartString, + hFloater, + queue->mObjectList, + fn)); + } -/*static*/ -void LLFloaterCompileQueue::finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, std::string scriptName, LLUUID queueId) +/// This is a utility function to be bound and called from objectScriptProcessingQueueCoro. +/// Do not call directly. It may throw a LLCheckedHandle<>::Stale exception. +bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloater, + const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump) { + LLSD result; + LLCheckedHandle<LLFloaterCompileQueue> floater(hfloater); + // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. + // which is caught in objectScriptProcessingQueueCoro + bool monocompile = floater->mMono; + F32 fetch_timeout = gSavedSettings.getF32("QueueInventoryFetchTimeout"); + + + // Initial test to see if we can (or should) attempt to compile the script. + LLInventoryItem *item = dynamic_cast<LLInventoryItem *>(inventory); - LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", LLSD(queueId)); - if (queue) + if (!item) { - // Bytecode save completed - if (response["compiled"]) - { - std::string message = std::string("Compilation of \"") + scriptName + std::string("\" succeeded"); + LL_WARNS("SCRIPTQ") << "item retrieved is not an LLInventoryItem." << LL_ENDL; + return true; + } - queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(message, ADD_BOTTOM); - LL_INFOS() << message << LL_ENDL; + if (!item->getPermissions().allowModifyBy(gAgent.getID(), gAgent.getGroupID()) || + !item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID())) + { + std::string buffer = "Skipping: " + item->getName() + "(Permissions)"; + floater->addStringMessage(buffer); + return true; + } + + // Attempt to retrieve the experience + LLUUID experienceId; + { + LLExperienceCache::instance().fetchAssociatedExperience(inventory->getParentUUID(), inventory->getUUID(), + boost::bind(&LLFloaterCompileQueue::handleHTTPResponse, pump.getName(), _1)); + + result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, + LLSDMap("timeout", LLSD::Boolean(true))); + + if (result.has("timeout")) + { // A timeout filed in the result will always be true if present. + LLStringUtil::format_map_t args; + args["[OBJECT_NAME]"] = inventory->getName(); + std::string buffer = floater->getString("Timeout", args); + floater->addStringMessage(buffer); + return true; } - else + + if (result.has(LLExperienceCache::EXPERIENCE_ID)) { - LLSD compile_errors = response["errors"]; - for (LLSD::array_const_iterator line = compile_errors.beginArray(); - line < compile_errors.endArray(); line++) + experienceId = result[LLExperienceCache::EXPERIENCE_ID].asUUID(); + if (!floater->hasExperience(experienceId)) { - std::string str = line->asString(); - str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); - - queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(str, ADD_BOTTOM); + floater->addProcessingMessage("CompileNoExperiencePerm", + LLSDMap("SCRIPT", inventory->getName()) + ("EXPERIENCE", result[LLExperienceCache::NAME].asString())); + return true; } - LL_INFOS() << response["errors"] << LL_ENDL; } } + + { + HandleScriptUserData userData(pump.getName()); + + + // request the asset + gAssetStorage->getInvItemAsset(LLHost(), + gAgent.getID(), + gAgent.getSessionID(), + item->getPermissions().getOwner(), + object->getID(), + item->getUUID(), + item->getAssetUUID(), + item->getType(), + &LLFloaterCompileQueue::handleScriptRetrieval, + &userData); + + result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, + LLSDMap("timeout", LLSD::Boolean(true))); + } + + if (result.has("timeout")) + { // A timeout filed in the result will always be true if present. + LLStringUtil::format_map_t args; + args["[OBJECT_NAME]"] = inventory->getName(); + std::string buffer = floater->getString("Timeout", args); + floater->addStringMessage(buffer); + return true; + } + + if (result.has("error")) + { + LL_WARNS("SCRIPTQ") << "Inventory fetch returned with error. Code: " << result["error"].asString() << LL_ENDL; + std::string buffer = result["message"].asString() + " " + inventory->getName(); + floater->addStringMessage(buffer); + + if (result.has("alert")) + { + LLSD args; + args["MESSAGE"] = result["alert"].asString(); + LLNotificationsUtil::add("SystemMessage", args); + } + return true; + } + + LLUUID assetId = result["asset_id"]; + + std::string url = object->getRegion()->getCapability("UpdateScriptTask"); + + { + LLResourceUploadInfo::ptr_t uploadInfo(new LLQueuedScriptAssetUpload(object->getID(), + inventory->getUUID(), + assetId, + monocompile ? LLScriptAssetUpload::MONO : LLScriptAssetUpload::LSL2, + true, + inventory->getName(), + LLUUID(), + experienceId, + boost::bind(&LLFloaterCompileQueue::handleHTTPResponse, pump.getName(), _4))); + + LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); + } + + result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, LLSDMap("timeout", LLSD::Boolean(true))); + + if (result.has("timeout")) + { // A timeout filed in the result will always be true if present. + LLStringUtil::format_map_t args; + args["[OBJECT_NAME]"] = inventory->getName(); + std::string buffer = floater->getString("Timeout", args); + floater->addStringMessage(buffer); + return true; + } + + // Bytecode save completed + if (result["compiled"]) + { + std::string buffer = std::string("Compilation of \"") + inventory->getName() + std::string("\" succeeded"); + + floater->addStringMessage(buffer); + LL_INFOS() << buffer << LL_ENDL; + } + else + { + LLSD compile_errors = result["errors"]; + std::string buffer = std::string("Compilation of \"") + inventory->getName() + std::string("\" failed:"); + floater->addStringMessage(buffer); + for (LLSD::array_const_iterator line = compile_errors.beginArray(); + line < compile_errors.endArray(); line++) + { + std::string str = line->asString(); + str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); + + floater->addStringMessage(str); + } + LL_INFOS() << result["errors"] << LL_ENDL; + } + + return true; } -// This is the callback for when each script arrives -// static -void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status) +bool LLFloaterCompileQueue::startQueue() { - LL_INFOS() << "LLFloaterCompileQueue::scriptArrived()" << LL_ENDL; - LLScriptQueueData* data = (LLScriptQueueData*)user_data; - if(!data) - { - return; - } - LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID); - - std::string buffer; - if(queue && (0 == status)) - { - LLViewerObject* object = gObjectList.findObject(data->mTaskId); - if (object) + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + std::string lookup_url = region->getCapability("GetCreatorExperiences"); + if (!lookup_url.empty()) { - std::string url = object->getRegion()->getCapability("UpdateScriptTask"); - std::string scriptName = data->mItem->getName(); - - LLBufferedAssetUploadInfo::taskUploadFinish_f proc = boost::bind(&LLFloaterCompileQueue::finishLSLUpload, _1, _2, _3, _4, - scriptName, data->mQueueID); + LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t success = + boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, _1, getKey().asUUID()); - LLResourceUploadInfo::ptr_t uploadInfo(new LLQueuedScriptAssetUpload(data->mTaskId, data->mItem->getUUID(), asset_id, - (queue->mMono) ? LLScriptAssetUpload::MONO : LLScriptAssetUpload::LSL2, - true, scriptName, data->mQueueID, data->mExperienceId, proc)); + LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t failure = + boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, LLSD(), getKey().asUUID()); - LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); + LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(lookup_url, + success, failure); + return TRUE; } - } - else - { - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ) - { - LLSD args; - args["MESSAGE"] = LLTrans::getString("CompileQueueScriptNotFound"); - LLNotificationsUtil::add("SystemMessage", args); - - buffer = LLTrans::getString("CompileQueueProblemDownloading") + (": ") + data->mItem->getName(); - } - else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) - { - LLSD args; - args["MESSAGE"] = LLTrans::getString("CompileQueueInsufficientPermDownload"); - LLNotificationsUtil::add("SystemMessage", args); - - buffer = LLTrans::getString("CompileQueueInsufficientPermFor") + (": ") + data->mItem->getName(); - } - else - { - buffer = LLTrans::getString("CompileQueueUnknownFailure") + (" ") + data->mItem->getName(); - } - - LL_WARNS() << "Problem downloading script asset." << LL_ENDL; - if(queue) queue->removeItemByItemID(data->mItem->getUUID()); - } - if(queue && (buffer.size() > 0)) - { - queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); - } - delete data; + } + + return true; } @@ -514,40 +543,46 @@ LLFloaterResetQueue::~LLFloaterResetQueue() { } -void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj, - LLInventoryObject::object_list_t* inv) +/// This is a utility function to be bound and called from objectScriptProcessingQueueCoro. +/// Do not call directly. It may throw a LLCheckedHandle<>::Stale exception. +bool LLFloaterResetQueue::resetObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, + const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump) { - // find all of the lsl, leaving off duplicates. We'll remove - // all matching asset uuids on compilation success. - - LLInventoryObject::object_list_t::const_iterator it = inv->begin(); - LLInventoryObject::object_list_t::const_iterator end = inv->end(); - for ( ; it != end; ++it) - { - if((*it)->getType() == LLAssetType::AT_LSL_TEXT) - { - LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); - - if (object) - { - LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); - std::string buffer; - buffer = getString("Resetting") + (": ") + item->getName(); - getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM); - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ScriptReset); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_Script); - msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID()); - msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID()); - msg->sendReliable(object->getRegion()->getHost()); - } - } - } + LLCheckedHandle<LLFloaterScriptQueue> floater(hfloater); + // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. + // which is caught in objectScriptProcessingQueueCoro + + std::string buffer; + buffer = floater->getString("Resetting") + (": ") + inventory->getName(); + floater->addStringMessage(buffer); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ScriptReset); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_Script); + msg->addUUIDFast(_PREHASH_ObjectID, object->getID()); + msg->addUUIDFast(_PREHASH_ItemID, inventory->getUUID()); + msg->sendReliable(object->getRegion()->getHost()); + + return true; +} - nextObject(); +bool LLFloaterResetQueue::startQueue() +{ + // Bind the resetObjectScripts method into a QueueAction function and pass it + // into the object queue processing coroutine. + fnQueueAction_t fn = boost::bind(LLFloaterResetQueue::resetObjectScripts, + getDerivedHandle<LLFloaterScriptQueue>(), _1, _2, _3); + + LLCoros::instance().launch("ScriptResetQueue", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro, + mStartString, + getDerivedHandle<LLFloaterScriptQueue>(), + mObjectList, + fn)); + + return true; } ///---------------------------------------------------------------------------- @@ -565,44 +600,48 @@ LLFloaterRunQueue::~LLFloaterRunQueue() { } -void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj, - LLInventoryObject::object_list_t* inv) +/// This is a utility function to be bound and called from objectScriptProcessingQueueCoro. +/// Do not call directly. It may throw a LLCheckedHandle<>::Stale exception. +bool LLFloaterRunQueue::runObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, + const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump) { - // find all of the lsl, leaving off duplicates. We'll remove - // all matching asset uuids on compilation success. - LLInventoryObject::object_list_t::const_iterator it = inv->begin(); - LLInventoryObject::object_list_t::const_iterator end = inv->end(); - for ( ; it != end; ++it) - { - if((*it)->getType() == LLAssetType::AT_LSL_TEXT) - { - LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); - - if (object) - { - LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); - LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); - std::string buffer; - buffer = getString("Running") + (": ") + item->getName(); - list->addSimpleElement(buffer, ADD_BOTTOM); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_SetScriptRunning); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_Script); - msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID()); - msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID()); - msg->addBOOLFast(_PREHASH_Running, TRUE); - msg->sendReliable(object->getRegion()->getHost()); - } - } - } + LLCheckedHandle<LLFloaterScriptQueue> floater(hfloater); + // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. + // which is caught in objectScriptProcessingQueueCoro + + std::string buffer; + buffer = floater->getString("Running") + (": ") + inventory->getName(); + floater->addStringMessage(buffer); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_SetScriptRunning); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_Script); + msg->addUUIDFast(_PREHASH_ObjectID, object->getID()); + msg->addUUIDFast(_PREHASH_ItemID, inventory->getUUID()); + msg->addBOOLFast(_PREHASH_Running, TRUE); + msg->sendReliable(object->getRegion()->getHost()); + + return true; +} - nextObject(); +bool LLFloaterRunQueue::startQueue() +{ + LLHandle<LLFloaterScriptQueue> hFloater(getDerivedHandle<LLFloaterScriptQueue>()); + fnQueueAction_t fn = boost::bind(LLFloaterRunQueue::runObjectScripts, hFloater, _1, _2, _3); + + LLCoros::instance().launch("ScriptRunQueue", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro, + mStartString, + hFloater, + mObjectList, + fn)); + + return true; } + ///---------------------------------------------------------------------------- /// Class LLFloaterNotRunQueue ///---------------------------------------------------------------------------- @@ -618,96 +657,155 @@ LLFloaterNotRunQueue::~LLFloaterNotRunQueue() { } -void LLFloaterCompileQueue::removeItemByItemID(const LLUUID& asset_id) +/// This is a utility function to be bound and called from objectScriptProcessingQueueCoro. +/// Do not call directly. It may throw a LLCheckedHandle<>::Stale exception. +bool LLFloaterNotRunQueue::stopObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, + const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump) { - LL_INFOS() << "LLFloaterCompileQueue::removeItemByAssetID()" << LL_ENDL; - for(S32 i = 0; i < mCurrentScripts.size(); ) - { - if(asset_id == mCurrentScripts.at(i)->getUUID()) - { - vector_replace_with_last(mCurrentScripts, mCurrentScripts.begin() + i); - } - else - { - ++i; - } - } - if(mCurrentScripts.empty()) - { - nextObject(); - } + LLCheckedHandle<LLFloaterScriptQueue> floater(hfloater); + // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. + // which is caught in objectScriptProcessingQueueCoro + + std::string buffer; + buffer = floater->getString("NotRunning") + (": ") + inventory->getName(); + floater->addStringMessage(buffer); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_SetScriptRunning); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_Script); + msg->addUUIDFast(_PREHASH_ObjectID, object->getID()); + msg->addUUIDFast(_PREHASH_ItemID, inventory->getUUID()); + msg->addBOOLFast(_PREHASH_Running, FALSE); + msg->sendReliable(object->getRegion()->getHost()); + + return true; } -BOOL LLFloaterCompileQueue::startQueue() +bool LLFloaterNotRunQueue::startQueue() { - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - std::string lookup_url=region->getCapability("GetCreatorExperiences"); - if(!lookup_url.empty()) - { - LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t success = - boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, _1, getKey().asUUID()); + LLHandle<LLFloaterScriptQueue> hFloater(getDerivedHandle<LLFloaterScriptQueue>()); - LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t failure = - boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, LLSD(), getKey().asUUID()); + fnQueueAction_t fn = boost::bind(&LLFloaterNotRunQueue::stopObjectScripts, hFloater, _1, _2, _3); + LLCoros::instance().launch("ScriptQueueNotRun", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro, + mStartString, + hFloater, + mObjectList, + fn)); - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(lookup_url, - success, failure); - return TRUE; - } - } - return nextObject(); + return true; } -/*static*/ -void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID parent) +///---------------------------------------------------------------------------- +/// Local function definitions +///---------------------------------------------------------------------------- +void ObjectInventoryFetcher::inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, S32 serial_num, void* user_data) { - LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", parent); - if (!queue) - return; + mInventoryList.clear(); + mInventoryList.assign(inventory->begin(), inventory->end()); + + mPump.post(LLSDMap("changed", LLSD::Boolean(true))); - queue->experienceIdsReceived(result["experience_ids"]); } -void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj, - LLInventoryObject::object_list_t* inv) +void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, LLHandle<LLFloaterScriptQueue> hfloater, + object_data_list_t objectList, fnQueueAction_t func) { - // find all of the lsl, leaving off duplicates. We'll remove - // all matching asset uuids on compilation success. - LLInventoryObject::object_list_t::const_iterator it = inv->begin(); - LLInventoryObject::object_list_t::const_iterator end = inv->end(); - for ( ; it != end; ++it) - { - if((*it)->getType() == LLAssetType::AT_LSL_TEXT) - { - LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); - - if (object) - { - LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); - LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); - std::string buffer; - buffer = getString("NotRunning") + (": ") +item->getName(); - list->addSimpleElement(buffer, ADD_BOTTOM); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_SetScriptRunning); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_Script); - msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID()); - msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID()); - msg->addBOOLFast(_PREHASH_Running, FALSE); - msg->sendReliable(object->getRegion()->getHost()); - } - } - } + LLCoros::set_consuming(true); + LLCheckedHandle<LLFloaterScriptQueue> floater(hfloater); + // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. + // This is expected if the dialog closes. + LLEventMailDrop maildrop(QUEUE_EVENTPUMP_NAME, true); + F32 fetch_timeout = gSavedSettings.getF32("QueueInventoryFetchTimeout"); - nextObject(); -} -///---------------------------------------------------------------------------- -/// Local function definitions -///---------------------------------------------------------------------------- + try + { + for (object_data_list_t::iterator itObj(objectList.begin()); (itObj != objectList.end()); ++itObj) + { + bool firstForObject = true; + LLUUID object_id = (*itObj).mObjectId; + LL_INFOS("SCRIPTQ") << "Next object in queue with ID=" << object_id.asString() << LL_ENDL; + + LLPointer<LLViewerObject> obj = gObjectList.findObject(object_id); + LLInventoryObject::object_list_t inventory; + if (obj) + { + ObjectInventoryFetcher::ptr_t fetcher(new ObjectInventoryFetcher(maildrop, obj, NULL)); + + fetcher->fetchInventory(); + + LLStringUtil::format_map_t args; + args["[OBJECT_NAME]"] = (*itObj).mObjectName; + floater->addStringMessage(floater->getString("LoadingObjInv", args)); + + LLSD result = llcoro::suspendUntilEventOnWithTimeout(maildrop, fetch_timeout, + LLSDMap("timeout", LLSD::Boolean(true))); + + if (result.has("timeout")) + { // A timeout filed in the result will always be true if present. + LL_WARNS("SCRIPTQ") << "Unable to retrieve inventory for object " << object_id.asString() << + ". Skipping to next object." << LL_ENDL; + + LLStringUtil::format_map_t args; + args["[OBJECT_NAME]"] = (*itObj).mObjectName; + floater->addStringMessage(floater->getString("Timeout", args)); + + continue; + } + + inventory.assign(fetcher->getInventoryList().begin(), fetcher->getInventoryList().end()); + } + else + { + LL_WARNS("SCRIPTQ") << "Unable to retrieve object with ID of " << object_id << + ". Skipping to next." << LL_ENDL; + continue; + } + + // TODO: Get the name of the object we are looking at here so that we can display it below. + //std::string objName = (dynamic_cast<LLInventoryObject *>(obj.get()))->getName(); + LL_DEBUGS("SCRIPTQ") << "Object has " << inventory.size() << " items." << LL_ENDL; + + for (LLInventoryObject::object_list_t::iterator itInv = inventory.begin(); + itInv != inventory.end(); ++itInv) + { + floater.check(); + + // note, we have a smart pointer to the obj above... but if we didn't we'd check that + // it still exists here. + + if (((*itInv)->getType() == LLAssetType::AT_LSL_TEXT)) + { + LL_DEBUGS("SCRIPTQ") << "Inventory item " << (*itInv)->getUUID().asString() << "\"" << (*itInv)->getName() << "\"" << LL_ENDL; + if (firstForObject) + { + //floater->addStringMessage(objName + ":"); + firstForObject = false; + } + + if (!func(obj, (*itInv), maildrop)) + { + continue; + } + } + + // no other explicit suspension point in this loop. func(...) MIGHT suspend + // but offers no guarantee of doing so. + llcoro::suspend(); + } + } + + floater->addStringMessage("Done"); + floater->getChildView("close")->setEnabled(TRUE); + } + catch (LLCheckedHandleBase::Stale &) + { + // This is expected. It means that floater has been closed before + // processing was completed. + LL_DEBUGS("SCRIPTQ") << "LLExeceptionStaleHandle caught! Floater has most likely been closed." << LL_ENDL; + } +} diff --git a/indra/newview/llcompilequeue.h b/indra/newview/llcompilequeue.h index 46bcb9746b001b87e8ac3a078cf88108a0a2a5ce..1b3d8f83a0bb0f3a3ab24fc315ff18270cb6963d 100644 --- a/indra/newview/llcompilequeue.h +++ b/indra/newview/llcompilequeue.h @@ -37,6 +37,8 @@ #include "llviewerinventory.h" +#include "llevents.h" + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFloaterScriptQueue // @@ -48,7 +50,7 @@ // scripts manipulated. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLFloaterScriptQueue : public LLFloater, public LLVOInventoryListener +class LLFloaterScriptQueue : public LLFloater/*, public LLVOInventoryListener*/ { public: LLFloaterScriptQueue(const LLSD& key); @@ -59,34 +61,23 @@ class LLFloaterScriptQueue : public LLFloater, public LLVOInventoryListener void setMono(bool mono) { mMono = mono; } // addObject() accepts an object id. - void addObject(const LLUUID& id); + void addObject(const LLUUID& id, std::string name); // start() returns TRUE if the queue has started, otherwise FALSE. BOOL start(); -protected: - // This is the callback method for the viewer object currently - // being worked on. - /*virtual*/ void inventoryChanged(LLViewerObject* obj, - LLInventoryObject::object_list_t* inv, - S32 serial_num, - void* queue); - - // This is called by inventoryChanged - virtual void handleInventory(LLViewerObject* viewer_obj, - LLInventoryObject::object_list_t* inv) = 0; + void addProcessingMessage(const std::string &message, const LLSD &args); + void addStringMessage(const std::string &message); + std::string getStartString() const { return mStartString; } + +protected: static void onCloseBtn(void* user_data); // returns true if this is done BOOL isDone() const; - virtual BOOL startQueue(); - - // go to the next object. If no objects left, it falls out - // silently and waits to be killed by the deleteIfDone() callback. - BOOL nextObject(); - BOOL popNext(); + virtual bool startQueue() = 0; void setStartString(const std::string& s) { mStartString = s; } @@ -96,12 +87,23 @@ class LLFloaterScriptQueue : public LLFloater, public LLVOInventoryListener LLButton* mCloseBtn; // Object Queue - std::vector<LLUUID> mObjectIDs; + struct ObjectData + { + LLUUID mObjectId; + std::string mObjectName; + }; + typedef std::vector<ObjectData> object_data_list_t; + + object_data_list_t mObjectList; LLUUID mCurrentObjectID; bool mDone; std::string mStartString; bool mMono; + + typedef boost::function<bool(const LLPointer<LLViewerObject> &, LLInventoryObject*, LLEventPump &)> fnQueueAction_t; + static void objectScriptProcessingQueueCoro(std::string action, LLHandle<LLFloaterScriptQueue> hfloater, object_data_list_t objectList, fnQueueAction_t func); + }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -122,8 +124,6 @@ class LLFloaterCompileQueue : public LLFloaterScriptQueue { friend class LLFloaterReg; public: - // remove any object in mScriptScripts with the matching uuid. - void removeItemByItemID(const LLUUID& item_id); void experienceIdsReceived( const LLSD& content ); BOOL hasExperience(const LLUUID& id)const; @@ -132,27 +132,17 @@ class LLFloaterCompileQueue : public LLFloaterScriptQueue LLFloaterCompileQueue(const LLSD& key); virtual ~LLFloaterCompileQueue(); - // This is called by inventoryChanged - virtual void handleInventory(LLViewerObject* viewer_obj, - LLInventoryObject::object_list_t* inv); - - static void requestAsset(struct LLScriptQueueData* datap, const LLSD& experience); + virtual bool startQueue(); + static bool processScript(LLHandle<LLFloaterCompileQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump); - static void finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, std::string scriptName, LLUUID queueId); - - // This is the callback for when each script arrives - static void scriptArrived(LLVFS *vfs, const LLUUID& asset_id, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status); - - virtual BOOL startQueue(); -protected: - LLViewerInventoryItem::item_array_t mCurrentScripts; + //bool checkAssetId(const LLUUID &assetId); + static void handleHTTPResponse(std::string pumpName, const LLSD &expresult); + static void handleScriptRetrieval(LLVFS *vfs, const LLUUID& assetId, LLAssetType::EType type, void* userData, S32 status, LLExtStat extStatus); private: static void processExperienceIdResults(LLSD result, LLUUID parent); - + //uuid_list_t mAssetIds; // list of asset IDs processed. uuid_list_t mExperienceIds; }; @@ -169,9 +159,9 @@ class LLFloaterResetQueue : public LLFloaterScriptQueue LLFloaterResetQueue(const LLSD& key); virtual ~LLFloaterResetQueue(); - // This is called by inventoryChanged - virtual void handleInventory(LLViewerObject* viewer_obj, - LLInventoryObject::object_list_t* inv); + static bool resetObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump); + + virtual bool startQueue(); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -186,10 +176,10 @@ class LLFloaterRunQueue : public LLFloaterScriptQueue protected: LLFloaterRunQueue(const LLSD& key); virtual ~LLFloaterRunQueue(); - - // This is called by inventoryChanged - virtual void handleInventory(LLViewerObject* viewer_obj, - LLInventoryObject::object_list_t* inv); + + static bool runObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump); + + virtual bool startQueue(); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -205,9 +195,9 @@ class LLFloaterNotRunQueue : public LLFloaterScriptQueue LLFloaterNotRunQueue(const LLSD& key); virtual ~LLFloaterNotRunQueue(); - // This is called by inventoryChanged - virtual void handleInventory(LLViewerObject* viewer_obj, - LLInventoryObject::object_list_t* inv); + static bool stopObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump); + + virtual bool startQueue(); }; #endif // LL_LLCOMPILEQUEUE_H diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index 05c7e6caa5ddf93287d507b1ed0b6bd2c6f4e180..4e69896b693b48d3a5aa250ce454b8aa1724bdb3 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -448,7 +448,12 @@ bool LLConversationLog::moveLog(const std::string &originDirectory, const std::s std::string LLConversationLog::getFileName() { std::string filename = "conversation"; - return gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename) + ".log"; + std::string log_address = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename); + if (!log_address.empty()) + { + log_address += ".log"; + } + return log_address; } bool LLConversationLog::saveToFile(const std::string& filename) diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h index 62f08144b9e94d763072393e49f637cca5a1092d..035cbcb9451e7eb41be8747176b15ece750f84eb 100644 --- a/indra/newview/llconversationlog.h +++ b/indra/newview/llconversationlog.h @@ -109,7 +109,7 @@ class LLConversation class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObserver { - friend class LLSingleton<LLConversationLog>; + LLSINGLETON(LLConversationLog); public: void removeConversation(const LLConversation& conversation); @@ -157,7 +157,6 @@ class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObse private: - LLConversationLog(); virtual ~LLConversationLog() { if (mAvatarNameCacheConnection.connected()) diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index b18e543f0a41cf9a84e7e693caaf4eb1930de4a8..15a8aacd3733475576b4130d3e8e9cf7525d0a3a 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -303,7 +303,7 @@ BOOL LLConversationViewSession::handleMouseUp( S32 x, S32 y, MASK mask ) LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem()); LLUUID session_id = item? item->getUUID() : LLUUID(); LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id); - if(!session_floater->hasFocus()) + if(session_floater && !session_floater->hasFocus()) { session_floater->setFocus(true); } @@ -458,6 +458,11 @@ void LLConversationViewSession::refresh() } } } + + if (mSpeakingIndicator) + { + mSpeakingIndicator->setShowParticipantsSpeaking(mIsInActiveVoiceChannel); + } requestArrange(); // Do the regular upstream refresh LLFolderViewFolder::refresh(); diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h index 3d2144960da160d3429ec6b039f7db70f554911a..04db9d5dacedeaa6675f69fafbb19a590dc1ae02 100644 --- a/indra/newview/lldaycyclemanager.h +++ b/indra/newview/lldaycyclemanager.h @@ -40,6 +40,7 @@ */ class LLDayCycleManager : public LLSingleton<LLDayCycleManager> { + LLSINGLETON_EMPTY_CTOR(LLDayCycleManager); LOG_CLASS(LLDayCycleManager); public: @@ -66,7 +67,6 @@ class LLDayCycleManager : public LLSingleton<LLDayCycleManager> boost::signals2::connection setModifyCallback(const modify_signal_t::slot_type& cb); private: - friend class LLSingleton<LLDayCycleManager>; /*virtual*/ void initSingleton(); void loadAllPresets(); diff --git a/indra/newview/lldeferredsounds.h b/indra/newview/lldeferredsounds.h index bf1eb629570b8be297fc82325821094e8d05444b..33f02b35215b2e219df508369e62b561b9569fb6 100644 --- a/indra/newview/lldeferredsounds.h +++ b/indra/newview/lldeferredsounds.h @@ -33,7 +33,7 @@ struct SoundData; class LLDeferredSounds : public LLSingleton<LLDeferredSounds> { -private: + LLSINGLETON_EMPTY_CTOR(LLDeferredSounds); std::vector<SoundData> soundVector; public: //Add sounds to be played once progress bar is hidden (such as after teleport or loading screen) diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp index 7836e2cb94e578251a6804a544db9cc2a2d51d09..7d2712eec708f611338e0bae252facb0a078f8a8 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.cpp +++ b/indra/newview/lldonotdisturbnotificationstorage.cpp @@ -69,8 +69,7 @@ BOOL LLDoNotDisturbNotificationStorageTimer::tick() } LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage() - : LLSingleton<LLDoNotDisturbNotificationStorage>() - , LLNotificationStorage("") + : LLNotificationStorage("") , mDirty(false) { nameToPayloadParameterMap[toastName] = "SESSION_ID"; diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h index 6e68b0d1be1013bec70431a7f010bda5e33ddb53..e6cb7835e311b4277df3daf26c2363c3e8d29b62 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.h +++ b/indra/newview/lldonotdisturbnotificationstorage.h @@ -47,14 +47,14 @@ class LLDoNotDisturbNotificationStorageTimer : public LLEventTimer class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotificationStorage>, public LLNotificationStorage { + LLSINGLETON(LLDoNotDisturbNotificationStorage); + ~LLDoNotDisturbNotificationStorage(); + LOG_CLASS(LLDoNotDisturbNotificationStorage); public: static const char * toastName; static const char * offerName; - LLDoNotDisturbNotificationStorage(); - ~LLDoNotDisturbNotificationStorage(); - void initialize(); bool getDirty(); void resetDirty(); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 84ead0bdde2cc992afd791cc8188277e31c4bfbe..60056ac21dd4dc9dacf4e7bffb008122fd724388 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -401,7 +401,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) if ((params.mVertexBuffer->getTypeMask() & mask) != mask) { //FIXME! - LL_WARNS() << "Missing required components, skipping render batch." << LL_ENDL; + LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask + << " present: " << (params.mVertexBuffer->getTypeMask() & mask) + << ". Skipping render batch." << LL_ENDL; continue; } diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 4c16c542d6a947ef25a9dca4777fde1f2cfa4903..499cf76bffe384fa463faecfd4344f3122609fa4 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "lldrawpoolavatar.h" +#include "llskinningutil.h" #include "llrender.h" #include "llvoavatar.h" @@ -56,8 +57,6 @@ static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK; static U32 sBufferUsage = GL_STREAM_DRAW_ARB; static U32 sShaderLevel = 0; -#define JOINT_COUNT 52 - LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL; BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE; BOOL LLDrawPoolAvatar::sSkipTransparent = FALSE; @@ -1461,7 +1460,13 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) } } -void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) +void LLDrawPoolAvatar::getRiggedGeometry( + LLFace* face, + LLPointer<LLVertexBuffer>& buffer, + U32 data_mask, + const LLMeshSkinInfo* skin, + LLVolume* volume, + const LLVolumeFace& vol_face) { face->setGeomIndex(0); face->setIndicesIndex(0); @@ -1470,7 +1475,8 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer> face->setTextureIndex(255); if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) - { //make a new buffer + { + // make a new buffer if (sShaderLevel > 0) { buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); @@ -1482,7 +1488,8 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer> buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true); } else - { //resize existing buffer + { + //resize existing buffer buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices); } @@ -1496,9 +1503,9 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer> m = m.inverse().transpose(); F32 mat3[] = - { m.m[0], m.m[1], m.m[2], - m.m[4], m.m[5], m.m[6], - m.m[8], m.m[9], m.m[10] }; + { m.m[0], m.m[1], m.m[2], + m.m[4], m.m[5], m.m[6], + m.m[8], m.m[9], m.m[10] }; LLMatrix3 mat_normal(mat3); @@ -1525,25 +1532,36 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer> { face->clearState(LLFace::TEXTURE_ANIM); } - - face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); buffer->flush(); } -void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) +void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( + LLVOAvatar* avatar, + LLFace* face, + const LLMeshSkinInfo* skin, + LLVolume* volume, + const LLVolumeFace& vol_face) { - LLVector4a* weight = vol_face.mWeights; - if (!weight) + LLVector4a* weights = vol_face.mWeights; + if (!weights) { return; } + // FIXME ugly const cast + LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin)); LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer(); LLDrawable* drawable = face->getDrawable(); U32 data_mask = face->getRiggedVertexBufferDataMask(); + + if (!vol_face.mWeightsScrubbed) + { + LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); + vol_face.mWeightsScrubbed = TRUE; + } if (buffer.isNull() || buffer->getTypeMask() != data_mask || @@ -1595,62 +1613,22 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; //build matrix palette - LLMatrix4a mp[JOINT_COUNT]; - LLMatrix4* mat = (LLMatrix4*) mp; - - U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT); - for (U32 j = 0; j < count; ++j) - { - LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); - if (!joint) - { - joint = avatar->getJoint("mPelvis"); - } - if (joint) - { - mat[j] = skin->mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); - } - } + LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + U32 count = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); + LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); + const U32 max_joints = LLSkinningUtil::getMaxJointCount(); for (U32 j = 0; j < buffer->getNumVerts(); ++j) { LLMatrix4a final_mat; - final_mat.clear(); - - S32 idx[4]; - - LLVector4 wght; - - F32 scale = 0.f; - for (U32 k = 0; k < 4; k++) - { - F32 w = weight[j][k]; - - idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)JOINT_COUNT-1); - - wght[k] = w - floorf(w); - scale += wght[k]; - } - // This is enforced in unpackVolumeFaces() - llassert(scale>0.f); - wght *= 1.f/scale; - - for (U32 k = 0; k < 4; k++) - { - F32 w = wght[k]; - - LLMatrix4a src; - src.setMul(mp[idx[k]], w); - - final_mat.add(src); - } - + LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints); LLVector4a& v = vol_face.mPositions[j]; + LLVector4a t; LLVector4a dst; bind_shape_matrix.affineTransform(v, t); @@ -1728,64 +1706,43 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) if (buff) { if (sShaderLevel > 0) - { //upload matrix palette to shader - LLMatrix4 mat[JOINT_COUNT]; - - U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT); + { + // upload matrix palette to shader + LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + U32 count = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); - for (U32 i = 0; i < count; ++i) - { - LLJoint* joint = avatar->getJoint(skin->mJointNames[i]); - if (!joint) - { - joint = avatar->getJoint("mPelvis"); - } - if (joint) - { - mat[i] = skin->mInvBindMatrix[i]; - mat[i] *= joint->getWorldMatrix(); - } - } - stop_glerror(); - F32 mp[JOINT_COUNT*9]; - - F32 transp[JOINT_COUNT*3]; + F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12]; for (U32 i = 0; i < count; ++i) { - F32* m = (F32*) mat[i].mMatrix; + F32* m = (F32*) mat[i].mMatrix[0].getF32ptr(); - U32 idx = i*9; + 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+3] = m[4]; - mp[idx+4] = m[5]; - mp[idx+5] = m[6]; - - mp[idx+6] = m[8]; - mp[idx+7] = m[9]; - mp[idx+8] = m[10]; - - idx = i*3; + mp[idx+4] = m[4]; + mp[idx+5] = m[5]; + mp[idx+6] = m[6]; + mp[idx+7] = m[13]; - transp[idx+0] = m[12]; - transp[idx+1] = m[13]; - transp[idx+2] = m[14]; + mp[idx+8] = m[8]; + mp[idx+9] = m[9]; + mp[idx+10] = m[10]; + mp[idx+11] = m[14]; } - LLDrawPoolAvatar::sVertexProgram->uniformMatrix3fv(LLViewerShaderMgr::AVATAR_MATRIX, + LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, count, FALSE, (GLfloat*) mp); - LLDrawPoolAvatar::sVertexProgram->uniform3fv(LLShaderMgr::AVATAR_TRANSLATION, count, transp); - - stop_glerror(); } else diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp index a626ad1bffa7b9220cb290ce369c7d806a86d8bb..c58a21d0c842e6bf95d7fb971aee71ddfdfc2f2c 100644 --- a/indra/newview/llenvmanager.cpp +++ b/indra/newview/llenvmanager.cpp @@ -35,6 +35,22 @@ #include "llwaterparammanager.h" #include "llwlhandlers.h" #include "llwlparammanager.h" +#include "lltrans.h" + +std::string LLWLParamKey::toString() const +{ + switch (scope) + { + case SCOPE_LOCAL: + return name + std::string(" (") + LLTrans::getString("Local") + std::string(")"); + break; + case SCOPE_REGION: + return name + std::string(" (") + LLTrans::getString("Region") + std::string(")"); + break; + default: + return name + " (?)"; + } +} std::string LLEnvPrefs::getWaterPresetName() const { @@ -609,10 +625,15 @@ bool LLEnvManagerNew::useRegionSky() return true; } - // *TODO: Support fixed sky from region. - - // Otherwise apply region day cycle. + // Otherwise apply region day cycle/skies. LL_DEBUGS("Windlight") << "Applying region sky" << LL_ENDL; + + // *TODO: Support fixed sky from region. Just do sky reset for now. + if (region_settings.getSkyMap().size() == 1) + { + // Region is set to fixed sky. Reset. + useSkyParams(region_settings.getSkyMap().beginMap()->second); + } return useDayCycleParams( region_settings.getWLDayCycle(), LLEnvKey::SCOPE_REGION, diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h index c7877303fc1a507ed2b234b781d950b5706edade..54bbf85e867bcffdf1e7bf06e49c70cd68c4bd4d 100644 --- a/indra/newview/llenvmanager.h +++ b/indra/newview/llenvmanager.h @@ -48,6 +48,87 @@ struct LLEnvKey } EScope; }; +struct LLWLParamKey : LLEnvKey +{ +public: + // scope and source of a param set (WL sky preset) + std::string name; + EScope scope; + + // for conversion from LLSD + static const int NAME_IDX = 0; + static const int SCOPE_IDX = 1; + + inline LLWLParamKey(const std::string& n, EScope s) + : name(n), scope(s) + { + } + + inline LLWLParamKey(LLSD llsd) + : name(llsd[NAME_IDX].asString()), scope(EScope(llsd[SCOPE_IDX].asInteger())) + { + } + + inline LLWLParamKey() // NOT really valid, just so std::maps can return a default of some sort + : name(""), scope(SCOPE_LOCAL) + { + } + + inline LLWLParamKey(std::string& stringVal) + { + size_t len = stringVal.length(); + if (len > 0) + { + name = stringVal.substr(0, len - 1); + scope = (EScope) atoi(stringVal.substr(len - 1, len).c_str()); + } + } + + inline std::string toStringVal() const + { + std::stringstream str; + str << name << scope; + return str.str(); + } + + inline LLSD toLLSD() const + { + LLSD llsd = LLSD::emptyArray(); + llsd.append(LLSD(name)); + llsd.append(LLSD(scope)); + return llsd; + } + + inline void fromLLSD(const LLSD& llsd) + { + name = llsd[NAME_IDX].asString(); + scope = EScope(llsd[SCOPE_IDX].asInteger()); + } + + inline bool operator <(const LLWLParamKey other) const + { + if (name < other.name) + { + return true; + } + else if (name > other.name) + { + return false; + } + else + { + return scope < other.scope; + } + } + + inline bool operator ==(const LLWLParamKey other) const + { + return (name == other.name) && (scope == other.scope); + } + + std::string toString() const; +}; + class LLEnvironmentSettings { public: @@ -162,14 +243,13 @@ class LLEnvPrefs */ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew> { + LLSINGLETON(LLEnvManagerNew); LOG_CLASS(LLEnvManagerNew); public: typedef boost::signals2::signal<void()> prefs_change_signal_t; typedef boost::signals2::signal<void()> region_settings_change_signal_t; typedef boost::signals2::signal<void(bool)> region_settings_applied_signal_t; - LLEnvManagerNew(); - // getters to access user env. preferences bool getUseRegionSettings() const; bool getUseDayCycle() const; @@ -231,7 +311,6 @@ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew> void onRegionSettingsApplyResponse(bool ok); private: - friend class LLSingleton<LLEnvManagerNew>; /*virtual*/ void initSingleton(); void loadUserPrefs(); diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h index fcfbd1ce7db2c9c0abd88ae6c33353948ac52141..e7a6a2a725c9f1d04407e4aaf52a3ef914132d30 100644 --- a/indra/newview/llestateinfomodel.h +++ b/indra/newview/llestateinfomodel.h @@ -38,6 +38,7 @@ class LLMessageSystem; */ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel> { + LLSINGLETON(LLEstateInfoModel); LOG_CLASS(LLEstateInfoModel); public: @@ -73,11 +74,8 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel> protected: typedef std::vector<std::string> strings_t; - friend class LLSingleton<LLEstateInfoModel>; friend class LLDispatchEstateUpdateInfo; - LLEstateInfoModel(); - /// refresh model with data from the incoming server message void update(const strings_t& strings); diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index 7178042b326f1192f2e101238ef046519ce329b3..5e0f3ab7f948f1b2659f623216f2b2419fd96410 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -40,12 +40,14 @@ #include "llcorehttputil.h" #include "lleventfilter.h" +#include "boost/make_shared.hpp" + namespace LLEventPolling { namespace Details { - class LLEventPollImpl + class LLEventPollImpl: public boost::enable_shared_from_this<LLEventPollImpl> { public: LLEventPollImpl(const LLHost &sender); @@ -113,7 +115,7 @@ namespace Details { std::string coroname = LLCoros::instance().launch("LLEventPollImpl::eventPollCoro", - boost::bind(&LLEventPollImpl::eventPollCoro, this, url)); + boost::bind(&LLEventPollImpl::eventPollCoro, this->shared_from_this(), url)); LL_INFOS("LLEventPollImpl") << coroname << " with url '" << url << LL_ENDL; } } @@ -142,7 +144,7 @@ namespace Details int errorCount = 0; int counter = mCounter; // saved on the stack for logging. - LL_INFOS("LLEventPollImpl") << " <" << counter << "> entering coroutine." << LL_ENDL; + LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> entering coroutine." << LL_ENDL; mAdapter = httpAdapter; @@ -170,7 +172,7 @@ namespace Details { if (status == LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT)) { // A standard timeout response we get this when there are no events. - LL_INFOS("LLEventPollImpl") << "All is very quiet on target server. It may have gone idle?" << LL_ENDL; + LL_DEBUGS("LLEventPollImpl") << "All is very quiet on target server. It may have gone idle?" << LL_ENDL; errorCount = 0; continue; } @@ -264,7 +266,7 @@ namespace Details } } } - LL_INFOS("LLEventPollImpl") << " <" << counter << "> Leaving coroutine." << LL_ENDL; + LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> Leaving coroutine." << LL_ENDL; } } @@ -273,8 +275,7 @@ namespace Details LLEventPoll::LLEventPoll(const std::string& poll_url, const LLHost& sender): mImpl() { - mImpl = boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl> - (new LLEventPolling::Details::LLEventPollImpl(sender)); + mImpl = boost::make_shared<LLEventPolling::Details::LLEventPollImpl>(sender); mImpl->start(poll_url); } diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h index e2afd9226bcf9cbb0163bc1401b19a64992426b6..65766dbb2a8bd6eb1268e2a6ad38695896ecd6c8 100644 --- a/indra/newview/lleventpoll.h +++ b/indra/newview/lleventpoll.h @@ -27,12 +27,6 @@ #ifndef LL_LLEVENTPOLL_H #define LL_LLEVENTPOLL_H -#include "boost/move/unique_ptr.hpp" - -namespace boost -{ - using ::boost::movelib::unique_ptr; // move unique_ptr into the boost namespace. -} class LLHost; @@ -57,7 +51,7 @@ class LLEventPoll private: - boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl> mImpl; + boost::shared_ptr<LLEventPolling::Details::LLEventPollImpl> mImpl; }; diff --git a/indra/newview/llexperiencelog.h b/indra/newview/llexperiencelog.h index ac227db336c5ac761b76da771feda8ce57af7a83..09e0cd8821bd6fd3ae96a52f17f052c16b726300 100644 --- a/indra/newview/llexperiencelog.h +++ b/indra/newview/llexperiencelog.h @@ -33,6 +33,7 @@ class LLExperienceLog : public LLSingleton<LLExperienceLog> { + LLSINGLETON(LLExperienceLog); public: typedef boost::signals2::signal<void(LLSD&)> callback_signal_t; @@ -62,7 +63,6 @@ class LLExperienceLog : public LLSingleton<LLExperienceLog> void setEventsToSave(LLSD new_events){mEventsToSave = new_events; } bool isNotExpired(std::string& date); protected: - LLExperienceLog(); void handleExperienceMessage(LLSD& message); @@ -81,7 +81,6 @@ class LLExperienceLog : public LLSingleton<LLExperienceLog> bool mNotifyNewEvent; friend class LLExperienceLogDispatchHandler; - friend class LLSingleton<LLExperienceLog>; }; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index de349a03d4cafe9878c5e53bbae42b2335995c00..50a4925c37f8e5fc6841bc52b4edb555d63457ca 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -573,6 +573,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) 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); @@ -2132,7 +2133,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector4a src; U32 vec[4]; - vec[0] = vec[1] = vec[2] = vec[3] = color.mAll; + vec[0] = vec[1] = vec[2] = vec[3] = color.asRGBA(); src.loadua((F32*) vec); @@ -2168,7 +2169,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLColor4U glow4u = LLColor4U(0,0,0,glow); - U32 glow32 = glow4u.mAll; + U32 glow32 = glow4u.asRGBA(); U32 vec[4]; vec[0] = vec[1] = vec[2] = vec[3] = glow32; diff --git a/indra/newview/llfacebookconnect.h b/indra/newview/llfacebookconnect.h index 2a2cdb54991d432344412720500b5f2a9bb1b353..7fd4070f54dfeb872b98ffc0b2e322fe3d9e44f7 100644 --- a/indra/newview/llfacebookconnect.h +++ b/indra/newview/llfacebookconnect.h @@ -43,6 +43,8 @@ class LLEventPump; */ class LLFacebookConnect : public LLSingleton<LLFacebookConnect> { + LLSINGLETON(LLFacebookConnect); + ~LLFacebookConnect() {}; LOG_CLASS(LLFacebookConnect); public: enum EConnectionState @@ -86,10 +88,7 @@ class LLFacebookConnect : public LLSingleton<LLFacebookConnect> void openFacebookWeb(std::string url); private: - friend class LLSingleton<LLFacebookConnect>; - LLFacebookConnect(); - ~LLFacebookConnect() {}; std::string getFacebookConnectURL(const std::string& route = "", bool include_read_from_master = false); EConnectionState mConnectionState; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 4a059fdc6788efcffa2f0e2dcbd498af9fd6e509..a69b3b7dc70fa8bc25d60eaa946ddd1112940b25 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -238,7 +238,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) { return TRUE; } - else if (mHoverBarIndex == -1) + else if (mHoverBarIndex < 0) { mHoverBarIndex = 0; } @@ -260,7 +260,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) { hover_bar = &bar; if (bar.mTimeBlock->getTreeNode().mCollapsed) - { + { // stop on first collapsed BlockTimerStatHandle, since we can't select any children break; } @@ -904,7 +904,8 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target base[label]["Samples"].asInteger()); } - exportCharts(baseline, target); + // This currently crashes, possibly due to a race condition in shutdown: + // exportCharts(baseline, target); os.flush(); os.close(); diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 2115f77cf3138bf470843576f58beeeeaeb9c4fe..cac32c7f2a6dfce51212e59a0e7e6cf08b28d753 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -34,6 +34,7 @@ #include "llinventoryobserver.h" #include "llinventorymodel.h" #include "llviewerinventory.h" +#include "llinitdestroyclass.h" class LLMenuItemCallGL; class LLToggleableMenu; @@ -173,6 +174,7 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage> , public LLDestroyClass<LLFavoritesOrderStorage> { + LLSINGLETON(LLFavoritesOrderStorage); LOG_CLASS(LLFavoritesOrderStorage); public: /** @@ -221,10 +223,6 @@ class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage> std::map<LLUUID,std::string> mFavoriteNames; private: - friend class LLSingleton<LLFavoritesOrderStorage>; - LLFavoritesOrderStorage() : mIsDirty(false), mUpdateRequired(false){ load(); } - ~LLFavoritesOrderStorage() {} - /** * Removes sort indexes for items which are not in Favorites bar for now. */ @@ -274,4 +272,10 @@ class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage> }; }; + +inline +LLFavoritesOrderStorage::LLFavoritesOrderStorage() : + mIsDirty(false), mUpdateRequired(false) +{ load(); } + #endif // LL_LLFAVORITESBARCTRL_H diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 7f1c981a3c71a949b1b473051d3c45d9f9073bef..d4ba230feb24e60ead6609a40c539e332fef5657 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -809,3 +809,62 @@ void LLFeatureManager::applyBaseMasks() 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()); + + loadGPUClass(); + 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; + + applyBaseMasks(); + 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() << "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() << "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/llfeaturemanager.h b/indra/newview/llfeaturemanager.h index 12ea691b491f0363ab19d6f62b98c1b69e253481..54bd07329a9541fd8ea5176610724c99fb31ea44 100644 --- a/indra/newview/llfeaturemanager.h +++ b/indra/newview/llfeaturemanager.h @@ -97,20 +97,10 @@ class LLFeatureList class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManager> { -public: - LLFeatureManager() - : LLFeatureList("default"), - - mInited(FALSE), - mTableVersion(0), - mSafe(FALSE), - mGPUClass(GPU_CLASS_UNKNOWN), - mExpectedGLVersion(0.f), - mGPUSupported(FALSE) - { - } + LLSINGLETON(LLFeatureManager); ~LLFeatureManager() {cleanupFeatureTables();} +public: // initialize this by loading feature table and gpu table void init(); @@ -157,7 +147,9 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag // load the dynamic GPU/feature table from a website void fetchHTTPTables(); - + + LLSD getRecommendedSettingsMap(); + protected: bool loadGPUClass(); @@ -179,5 +171,17 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag BOOL mGPUSupported; }; +inline +LLFeatureManager::LLFeatureManager() +: LLFeatureList("default"), + + mInited(FALSE), + mTableVersion(0), + mSafe(FALSE), + mGPUClass(GPU_CLASS_UNKNOWN), + mExpectedGLVersion(0.f), + mGPUSupported(FALSE) +{ +} #endif // LL_LLFEATUREMANAGER_H diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp index a29ccf2b6ddccd6cd3d396fc64705dd018142e5e..f2af9b530061f1febd67dbbc28898b6f399a29f8 100644 --- a/indra/newview/llfilteredwearablelist.cpp +++ b/indra/newview/llfilteredwearablelist.cpp @@ -93,4 +93,9 @@ void LLFilteredWearableListManager::populateList() mWearableList->refreshList(item_array); } +void LLFilteredWearableListManager::holdProgress() +{ + mWearableList->setForceRefresh(false); +} + // EOF diff --git a/indra/newview/llfilteredwearablelist.h b/indra/newview/llfilteredwearablelist.h index c21458ca98a67001d3db4c6ae46469c647809cd2..f44ab1466f486422709d4239a5e1cdcae74eb8a9 100644 --- a/indra/newview/llfilteredwearablelist.h +++ b/indra/newview/llfilteredwearablelist.h @@ -56,6 +56,11 @@ class LLFilteredWearableListManager : public LLInventoryObserver */ void populateList(); + /** + * Drop operation + */ + void holdProgress(); + private: LLInventoryItemsList* mWearableList; LLInventoryCollectFunctor* mCollector; diff --git a/indra/newview/llflickrconnect.h b/indra/newview/llflickrconnect.h index 0155804da0f95e766822374b5e416435de6a9728..43cadca708957bcc170c502ef55e760435222e7c 100644 --- a/indra/newview/llflickrconnect.h +++ b/indra/newview/llflickrconnect.h @@ -43,6 +43,8 @@ class LLEventPump; */ class LLFlickrConnect : public LLSingleton<LLFlickrConnect> { + LLSINGLETON(LLFlickrConnect); + ~LLFlickrConnect() {}; LOG_CLASS(LLFlickrConnect); public: enum EConnectionState @@ -80,10 +82,7 @@ class LLFlickrConnect : public LLSingleton<LLFlickrConnect> void openFlickrWeb(std::string url); private: - friend class LLSingleton<LLFlickrConnect>; - LLFlickrConnect(); - ~LLFlickrConnect() {}; std::string getFlickrConnectURL(const std::string& route = "", bool include_read_from_master = false); EConnectionState mConnectionState; diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 0d262e73ef7abc34eadc7fcafe41e949bcd5a489..de2d595fb10f9b4fa9c8919374b27b807d46f3a7 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -100,6 +100,7 @@ class LLFloaterAbout static bool callbackCheckUpdate(LLSD const & event); static void startFetchServerReleaseNotes(); + static void fetchServerReleaseNotesCoro(const std::string& cap_url); static void handleServerReleaseNotes(LLSD results); }; @@ -213,35 +214,62 @@ void LLFloaterAbout::startFetchServerReleaseNotes() // an URL suitable for external browsers in the "Location:" HTTP header. std::string cap_url = region->getCapability("ServerReleaseNotes"); - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(cap_url, - &LLFloaterAbout::handleServerReleaseNotes, &LLFloaterAbout::handleServerReleaseNotes); + LLCoros::instance().launch("fetchServerReleaseNotesCoro", boost::bind(&LLFloaterAbout::fetchServerReleaseNotesCoro, cap_url)); } +/*static*/ +void LLFloaterAbout::fetchServerReleaseNotesCoro(const std::string& cap_url) +{ + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("fetchServerReleaseNotesCoro", LLCore::HttpRequest::DEFAULT_POLICY_ID)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + + httpOpts->setWantHeaders(true); + httpOpts->setFollowRedirects(false); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, cap_url, httpOpts); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + handleServerReleaseNotes(httpResults); + } + else + { + handleServerReleaseNotes(result); + } +} + /*static*/ void LLFloaterAbout::handleServerReleaseNotes(LLSD results) { -// LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about"); -// if (floater_about) -// { - LLSD http_headers; - if (results.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS)) - { - LLSD http_results = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - http_headers = http_results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS]; - } - else - { - http_headers = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS]; - } - - std::string location = http_headers[HTTP_IN_HEADER_LOCATION].asString(); - if (location.empty()) - { - location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL"); - } - LLAppViewer::instance()->setServerReleaseNotesURL(location); -// } + LLSD http_headers; + if (results.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS)) + { + LLSD http_results = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + http_headers = http_results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS]; + } + else + { + http_headers = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS]; + } + + std::string location = http_headers[HTTP_IN_HEADER_LOCATION].asString(); + if (location.empty()) + { + location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL"); + } + LLAppViewer::instance()->setServerReleaseNotesURL(location); + + LLFloaterAbout* floater_about = LLFloaterReg::findTypedInstance<LLFloaterAbout>("sl_about"); + if (floater_about) + { + floater_about->setSupportText(location); + } } class LLFloaterAboutListener: public LLEventAPI diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 72892b47a492dd38623550c86fa88acfb6200598..c394eb815b91c3790342c82bd45c9a5d85ffee00 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -55,6 +55,8 @@ //#include "llsdserialize.h" +static const U32 AVATAR_PICKER_SEARCH_TIMEOUT = 180U; + //put it back as a member once the legacy path is out? static std::map<LLUUID, LLAvatarName> sAvatarNameMap; @@ -463,10 +465,13 @@ void LLFloaterAvatarPicker::findCoro(std::string url, LLUUID queryID, std::strin LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy)); LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL; - LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + httpOpts->setTimeout(AVATAR_PICKER_SEARCH_TIMEOUT); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts); LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); @@ -497,37 +502,39 @@ void LLFloaterAvatarPicker::find() url.reserve(128); // avoid a memory allocation or two LLViewerRegion* region = gAgent.getRegion(); - url = region->getCapability("AvatarPickerSearch"); - // Prefer use of capabilities to search on both SLID and display name - if (!url.empty()) + if(region) { - // capability urls don't end in '/', but we need one to parse - // query parameters correctly - if (url.size() > 0 && url[url.size()-1] != '/') + url = region->getCapability("AvatarPickerSearch"); + // Prefer use of capabilities to search on both SLID and display name + if (!url.empty()) { - url += "/"; - } - url += "?page_size=100&names="; - std::replace(text.begin(), text.end(), '.', ' '); - url += LLURI::escape(text); - LL_INFOS() << "avatar picker " << url << LL_ENDL; + // capability urls don't end in '/', but we need one to parse + // query parameters correctly + if (url.size() > 0 && url[url.size()-1] != '/') + { + url += "/"; + } + url += "?page_size=100&names="; + std::replace(text.begin(), text.end(), '.', ' '); + url += LLURI::escape(text); + LL_INFOS() << "avatar picker " << url << LL_ENDL; - LLCoros::instance().launch("LLFloaterAvatarPicker::findCoro", - boost::bind(&LLFloaterAvatarPicker::findCoro, url, mQueryID, getKey().asString())); - } - else - { - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("AvatarPickerRequest"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->addUUID("QueryID", mQueryID); // not used right now - msg->nextBlock("Data"); - msg->addString("Name", text); - gAgent.sendReliableMessage(); + LLCoros::instance().launch("LLFloaterAvatarPicker::findCoro", + boost::bind(&LLFloaterAvatarPicker::findCoro, url, mQueryID, getKey().asString())); + } + else + { + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("AvatarPickerRequest"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + msg->addUUID("QueryID", mQueryID); // not used right now + msg->nextBlock("Data"); + msg->addString("Name", text); + gAgent.sendReliableMessage(); + } } - getChild<LLScrollListCtrl>("SearchResults")->deleteAllItems(); getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("searching")); diff --git a/indra/newview/llfloaterbeacons.cpp b/indra/newview/llfloaterbeacons.cpp index 316294a477408d700e5019d709b79232e7327aa0..cf38a004994bda5bf1b3eecf4ccc8726fa9e3f98 100644 --- a/indra/newview/llfloaterbeacons.cpp +++ b/indra/newview/llfloaterbeacons.cpp @@ -66,13 +66,13 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl) std::string name = check->getName(); if(name == "touch_only") { - LLPipeline::toggleRenderScriptedTouchBeacons(NULL); + LLPipeline::toggleRenderScriptedTouchBeacons(); // Don't allow both to be ON at the same time. Toggle the other one off if both now on. if ( - LLPipeline::getRenderScriptedTouchBeacons(NULL) && - LLPipeline::getRenderScriptedBeacons(NULL) ) + LLPipeline::getRenderScriptedTouchBeacons() && + LLPipeline::getRenderScriptedBeacons() ) { - LLPipeline::setRenderScriptedBeacons(FALSE); + LLPipeline::setRenderScriptedBeacons(false); getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(FALSE)); getChild<LLCheckBoxCtrl>("scripted")->setValue(FALSE); getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline @@ -81,13 +81,13 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl) } else if(name == "scripted") { - LLPipeline::toggleRenderScriptedBeacons(NULL); + LLPipeline::toggleRenderScriptedBeacons(); // Don't allow both to be ON at the same time. Toggle the other one off if both now on. if ( - LLPipeline::getRenderScriptedTouchBeacons(NULL) && - LLPipeline::getRenderScriptedBeacons(NULL) ) + LLPipeline::getRenderScriptedTouchBeacons() && + LLPipeline::getRenderScriptedBeacons() ) { - LLPipeline::setRenderScriptedTouchBeacons(FALSE); + LLPipeline::setRenderScriptedTouchBeacons(false); getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(FALSE)); getChild<LLCheckBoxCtrl>("touch_only")->setValue(FALSE); getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline @@ -100,13 +100,13 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl) else if(name == "moapbeacon") LLPipeline::setRenderMOAPBeacons(check->get()); else if(name == "highlights") { - LLPipeline::toggleRenderHighlights(NULL); + LLPipeline::toggleRenderHighlights(); // Don't allow both to be OFF at the same time. Toggle the other one on if both now off. if ( - !LLPipeline::getRenderBeacons(NULL) && - !LLPipeline::getRenderHighlights(NULL) ) + !LLPipeline::getRenderBeacons() && + !LLPipeline::getRenderHighlights() ) { - LLPipeline::setRenderBeacons(TRUE); + LLPipeline::setRenderBeacons(true); getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(TRUE)); getChild<LLCheckBoxCtrl>("beacons")->setValue(TRUE); getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline @@ -115,13 +115,13 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl) } else if(name == "beacons") { - LLPipeline::toggleRenderBeacons(NULL); + LLPipeline::toggleRenderBeacons(); // Don't allow both to be OFF at the same time. Toggle the other one on if both now off. if ( - !LLPipeline::getRenderBeacons(NULL) && - !LLPipeline::getRenderHighlights(NULL) ) + !LLPipeline::getRenderBeacons() && + !LLPipeline::getRenderHighlights() ) { - LLPipeline::setRenderHighlights(TRUE); + LLPipeline::setRenderHighlights(true); getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(TRUE)); getChild<LLCheckBoxCtrl>("highlights")->setValue(TRUE); getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp index 957c91b2263eb4f16e74ccfc2197671711158d4c..33e4c7cd5fded23519bdd09ae71354cab3e104c0 100644 --- a/indra/newview/llfloaterbump.cpp +++ b/indra/newview/llfloaterbump.cpp @@ -184,7 +184,7 @@ void LLFloaterBump::onScrollListRightClicked(LLUICtrl* ctrl, S32 x, S32 y) std::string mute_msg = (LLMuteList::getInstance()->isMuted(mItemUUID, mNames[mItemUUID])) ? "UnmuteAvatar" : "MuteAvatar"; mPopupMenu->getChild<LLUICtrl>("Avatar Mute")->setValue(LLTrans::getString(mute_msg)); - mPopupMenu->setItemEnabled(std::string("Zoom In"), (BOOL)gObjectList.findObject(mItemUUID)); + mPopupMenu->setItemEnabled(std::string("Zoom In"), bool(gObjectList.findObject(mItemUUID))); ((LLContextMenu*)mPopupMenu)->show(x, y); LLMenuGL::showPopup(ctrl, mPopupMenu, x, y); diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index b32ac860aaa57299fec019a6e4fde0061e77026c..4607b4ac411d5fb04ec7c4c92a29a9e8077d43a6 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -44,7 +44,6 @@ #include "llinventorymodel.h" // for gInventory #include "llfirstuse.h" #include "llfloaterreg.h" -#include "llfloaterinventory.h" // for LLInventoryIcon::getIcon #include "llnotificationsutil.h" #include "llselectmgr.h" #include "llscrolllistctrl.h" diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp index e21a8594bc0e4f37c3087a65dab274c874807f2b..91436e52fe663962ab0328b636740e4add4d3390 100644 --- a/indra/newview/llfloaterbuycurrency.cpp +++ b/indra/newview/llfloaterbuycurrency.cpp @@ -280,7 +280,7 @@ void LLFloaterBuyCurrencyUI::onClickCancel() void LLFloaterBuyCurrencyUI::onClickErrorWeb() { - LLWeb::loadURLExternal(mManager.errorURI()); + LLWeb::loadURL(mManager.errorURI()); closeFloater(); // Update L$ balance LLStatusBar::sendMoneyBalanceRequest(); diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index e5df417ca9f89d5d8174c6e61d9be7fd3c4f33a4..5f606ec326073c1e4b824898b5bac9eea72af48a 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -178,6 +178,12 @@ void LLFloaterBvhPreview::setAnimCallbacks() getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1)); } +std::map <std::string, std::string> LLFloaterBvhPreview::getJointAliases() +{ + LLPointer<LLVOAvatar> av = (LLVOAvatar*)mAnimPreview->getDummyAvatar(); + return av->getJointAliases(); +} + //----------------------------------------------------------------------------- // postBuild() //----------------------------------------------------------------------------- @@ -215,6 +221,8 @@ BOOL LLFloaterBvhPreview::postBuild() getChildView("bad_animation_text")->setVisible(FALSE); + mAnimPreview = new LLPreviewAnimation(256, 256); + std::string exten = gDirUtilp->getExtension(mFilename); if (exten == "bvh") { @@ -241,8 +249,11 @@ BOOL LLFloaterBvhPreview::postBuild() file_buffer[file_size] = '\0'; LL_INFOS() << "Loading BVH file " << mFilename << LL_ENDL; ELoadStatus load_status = E_ST_OK; - S32 line_number = 0; - loaderp = new LLBVHLoader(file_buffer, load_status, line_number); + S32 line_number = 0; + + std::map<std::string, std::string> joint_alias_map = getJointAliases(); + + loaderp = new LLBVHLoader(file_buffer, load_status, line_number, joint_alias_map); std::string status = getString(STATUS[load_status]); if(load_status == E_ST_NO_XLT_FILE) @@ -266,8 +277,6 @@ BOOL LLFloaterBvhPreview::postBuild() mTransactionID.generate(); mMotionID = mTransactionID.makeAssetID(gAgent.getSecureSessionID()); - mAnimPreview = new LLPreviewAnimation(256, 256); - // motion will be returned, but it will be in a load-pending state, as this is a new motion // this motion will not request an asset transfer until next update, so we have a chance to // load the keyframe data locally @@ -280,9 +289,12 @@ BOOL LLFloaterBvhPreview::postBuild() LLDataPackerBinaryBuffer dp(buffer, buffer_size); // pass animation data through memory buffer + LL_INFOS("BVH") << "Serializing loaderp" << LL_ENDL; loaderp->serialize(dp); dp.reset(); + LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL; BOOL success = motionp && motionp->deserialize(dp); + LL_INFOS("BVH") << "Done" << LL_ENDL; delete []buffer; @@ -992,7 +1004,7 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata) { std::string name = floaterp->getChild<LLUICtrl>("name_form")->getValue().asString(); std::string desc = floaterp->getChild<LLUICtrl>("description_form")->getValue().asString(); - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); LLResourceUploadInfo::ptr_t assetUpdloadInfo(new LLResourceUploadInfo( floaterp->mTransactionID, LLAssetType::AT_ANIMATION, diff --git a/indra/newview/llfloaterbvhpreview.h b/indra/newview/llfloaterbvhpreview.h index b81cc6e3a51649cbdadeeeef78ad9db0e8bcef88..20d15d96033b35bf4d5c0e383c4a5d74dcd08253 100644 --- a/indra/newview/llfloaterbvhpreview.h +++ b/indra/newview/llfloaterbvhpreview.h @@ -109,7 +109,9 @@ class LLFloaterBvhPreview : public LLFloaterNameDesc S32 status, LLExtStat ext_status); private: void setAnimCallbacks() ; - + std::map <std::string, std::string> getJointAliases(); + + protected: void draw(); void resetMotion(); diff --git a/indra/newview/llfloaterfacebook.cpp b/indra/newview/llfloaterfacebook.cpp index da85d378b2657462b47280a52a7e2c7e16dc85c4..b1d6d8be822630b349a4ad88d7d1d9d3328d5c7a 100644 --- a/indra/newview/llfloaterfacebook.cpp +++ b/indra/newview/llfloaterfacebook.cpp @@ -87,7 +87,7 @@ S32 compute_jpeg_quality(S32 width, S32 height) { F32 target_compression_ratio = (F32)(width * height * 3) / (F32)(TARGET_DATA_SIZE); S32 quality = (S32)(110.0f - (2.0f * target_compression_ratio)); - return llclamp(quality,MIN_QUALITY,MAX_QUALITY); + return llclamp(quality, MIN_QUALITY, MAX_QUALITY); } /////////////////////////// @@ -95,52 +95,52 @@ S32 compute_jpeg_quality(S32 width, S32 height) /////////////////////////// LLFacebookStatusPanel::LLFacebookStatusPanel() : - mMessageTextEditor(NULL), - mPostButton(NULL), + mMessageTextEditor(NULL), + mPostButton(NULL), mCancelButton(NULL), - mAccountCaptionLabel(NULL), - mAccountNameLabel(NULL), - mPanelButtons(NULL), - mConnectButton(NULL), - mDisconnectButton(NULL) + mAccountCaptionLabel(NULL), + mAccountNameLabel(NULL), + mPanelButtons(NULL), + mConnectButton(NULL), + mDisconnectButton(NULL) { - mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLFacebookStatusPanel::onConnect, this)); - mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLFacebookStatusPanel::onDisconnect, this)); + mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLFacebookStatusPanel::onConnect, this)); + mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLFacebookStatusPanel::onDisconnect, this)); - setVisibleCallback(boost::bind(&LLFacebookStatusPanel::onVisibilityChange, this, _2)); + setVisibleCallback(boost::bind(&LLFacebookStatusPanel::onVisibilityChange, this, _2)); - mCommitCallbackRegistrar.add("SocialSharing.SendStatus", boost::bind(&LLFacebookStatusPanel::onSend, this)); + mCommitCallbackRegistrar.add("SocialSharing.SendStatus", boost::bind(&LLFacebookStatusPanel::onSend, this)); } BOOL LLFacebookStatusPanel::postBuild() { - mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label"); - mAccountNameLabel = getChild<LLTextBox>("account_name_label"); - mPanelButtons = getChild<LLUICtrl>("panel_buttons"); - mConnectButton = getChild<LLUICtrl>("connect_btn"); - mDisconnectButton = getChild<LLUICtrl>("disconnect_btn"); + mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label"); + mAccountNameLabel = getChild<LLTextBox>("account_name_label"); + mPanelButtons = getChild<LLUICtrl>("panel_buttons"); + mConnectButton = getChild<LLUICtrl>("connect_btn"); + mDisconnectButton = getChild<LLUICtrl>("disconnect_btn"); - mMessageTextEditor = getChild<LLUICtrl>("status_message"); - mPostButton = getChild<LLUICtrl>("post_status_btn"); - mCancelButton = getChild<LLUICtrl>("cancel_status_btn"); + mMessageTextEditor = getChild<LLUICtrl>("status_message"); + mPostButton = getChild<LLUICtrl>("post_status_btn"); + mCancelButton = getChild<LLUICtrl>("cancel_status_btn"); - return LLPanel::postBuild(); + return LLPanel::postBuild(); } void LLFacebookStatusPanel::draw() { - LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState(); + LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState(); - //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress - bool disconnecting = connection_state == LLFacebookConnect::FB_DISCONNECTING; - mDisconnectButton->setEnabled(!disconnecting); + //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress + bool disconnecting = connection_state == LLFacebookConnect::FB_DISCONNECTING; + mDisconnectButton->setEnabled(!disconnecting); - //Disable the 'connect' button when a connection is in progress - bool connecting = connection_state == LLFacebookConnect::FB_CONNECTION_IN_PROGRESS; - mConnectButton->setEnabled(!connecting); + //Disable the 'connect' button when a connection is in progress + bool connecting = connection_state == LLFacebookConnect::FB_CONNECTION_IN_PROGRESS; + mConnectButton->setEnabled(!connecting); if (mMessageTextEditor && mPostButton && mCancelButton) - { + { bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing()); std::string message = mMessageTextEditor->getValue().asString(); mMessageTextEditor->setEnabled(no_ongoing_connection); @@ -148,175 +148,175 @@ void LLFacebookStatusPanel::draw() mPostButton->setEnabled(no_ongoing_connection && !message.empty()); } - LLPanel::draw(); + LLPanel::draw(); } void LLFacebookStatusPanel::onSend() { - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel"); // just in case it is already listening - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookStatusPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectStateChange, this, _1)); - - // Connect to Facebook if necessary and then post - if (LLFacebookConnect::instance().isConnected()) - { - sendStatus(); - } - else - { - LLFacebookConnect::instance().checkConnectionToFacebook(true); - } + LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel"); // just in case it is already listening + LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookStatusPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectStateChange, this, _1)); + + // Connect to Facebook if necessary and then post + if (LLFacebookConnect::instance().isConnected()) + { + sendStatus(); + } + else + { + LLFacebookConnect::instance().checkConnectionToFacebook(true); + } } bool LLFacebookStatusPanel::onFacebookConnectStateChange(const LLSD& data) { - switch (data.get("enum").asInteger()) - { - case LLFacebookConnect::FB_CONNECTED: - sendStatus(); - break; - - case LLFacebookConnect::FB_POSTED: - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel"); - clearAndClose(); - break; - } - - return false; + switch (data.get("enum").asInteger()) + { + case LLFacebookConnect::FB_CONNECTED: + sendStatus(); + break; + + case LLFacebookConnect::FB_POSTED: + LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel"); + clearAndClose(); + break; + } + + return false; } bool LLFacebookStatusPanel::onFacebookConnectAccountStateChange(const LLSD& data) { - if(LLFacebookConnect::instance().isConnected()) - { - //In process of disconnecting so leave the layout as is - if(data.get("enum").asInteger() != LLFacebookConnect::FB_DISCONNECTING) - { - showConnectedLayout(); - } - } - else - { - showDisconnectedLayout(); - } - - return false; + if (LLFacebookConnect::instance().isConnected()) + { + //In process of disconnecting so leave the layout as is + if (data.get("enum").asInteger() != LLFacebookConnect::FB_DISCONNECTING) + { + showConnectedLayout(); + } + } + else + { + showDisconnectedLayout(); + } + + return false; } void LLFacebookStatusPanel::sendStatus() { - std::string message = mMessageTextEditor->getValue().asString(); - if (!message.empty()) - { - LLFacebookConnect::instance().updateStatus(message); - } + std::string message = mMessageTextEditor->getValue().asString(); + if (!message.empty()) + { + LLFacebookConnect::instance().updateStatus(message); + } } void LLFacebookStatusPanel::onVisibilityChange(BOOL visible) { - if(visible) - { - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel"); - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectAccountStateChange, this, _1)); - - LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel"); - LLEventPumps::instance().obtain("FacebookConnectInfo").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectInfoChange, this)); - - //Connected - if(LLFacebookConnect::instance().isConnected()) - { - showConnectedLayout(); - } - //Check if connected (show disconnected layout in meantime) - else - { - showDisconnectedLayout(); - } + if (visible) + { + LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel"); + LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectAccountStateChange, this, _1)); + + LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel"); + LLEventPumps::instance().obtain("FacebookConnectInfo").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectInfoChange, this)); + + //Connected + if (LLFacebookConnect::instance().isConnected()) + { + showConnectedLayout(); + } + //Check if connected (show disconnected layout in meantime) + else + { + showDisconnectedLayout(); + } if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) || (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED)) { LLFacebookConnect::instance().checkConnectionToFacebook(); } - } - else - { - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel"); - LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel"); - } + } + else + { + LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel"); + LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel"); + } } bool LLFacebookStatusPanel::onFacebookConnectInfoChange() { - LLSD info = LLFacebookConnect::instance().getInfo(); - std::string clickable_name; + LLSD info = LLFacebookConnect::instance().getInfo(); + std::string clickable_name; - //Strings of format [http://www.somewebsite.com Click Me] become clickable text - if(info.has("link") && info.has("name")) - { - clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]"; - } + //Strings of format [http://www.somewebsite.com Click Me] become clickable text + if (info.has("link") && info.has("name")) + { + clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]"; + } - mAccountNameLabel->setText(clickable_name); + mAccountNameLabel->setText(clickable_name); - return false; + return false; } void LLFacebookStatusPanel::showConnectButton() { - if(!mConnectButton->getVisible()) - { - mConnectButton->setVisible(TRUE); - mDisconnectButton->setVisible(FALSE); - } + if (!mConnectButton->getVisible()) + { + mConnectButton->setVisible(TRUE); + mDisconnectButton->setVisible(FALSE); + } } void LLFacebookStatusPanel::hideConnectButton() { - if(mConnectButton->getVisible()) - { - mConnectButton->setVisible(FALSE); - mDisconnectButton->setVisible(TRUE); - } + if (mConnectButton->getVisible()) + { + mConnectButton->setVisible(FALSE); + mDisconnectButton->setVisible(TRUE); + } } void LLFacebookStatusPanel::showDisconnectedLayout() { - mAccountCaptionLabel->setText(getString("facebook_disconnected")); - mAccountNameLabel->setText(std::string("")); - showConnectButton(); + mAccountCaptionLabel->setText(getString("facebook_disconnected")); + mAccountNameLabel->setText(std::string("")); + showConnectButton(); } void LLFacebookStatusPanel::showConnectedLayout() { - LLFacebookConnect::instance().loadFacebookInfo(); + LLFacebookConnect::instance().loadFacebookInfo(); - mAccountCaptionLabel->setText(getString("facebook_connected")); - hideConnectButton(); + mAccountCaptionLabel->setText(getString("facebook_connected")); + hideConnectButton(); } void LLFacebookStatusPanel::onConnect() { - LLFacebookConnect::instance().checkConnectionToFacebook(true); + LLFacebookConnect::instance().checkConnectionToFacebook(true); - //Clear only the facebook browser cookies so that the facebook login screen appears - LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com"); + //Clear only the facebook browser cookies so that the facebook login screen appears + LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com"); } void LLFacebookStatusPanel::onDisconnect() { - LLFacebookConnect::instance().disconnectFromFacebook(); + LLFacebookConnect::instance().disconnectFromFacebook(); - LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com"); + LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com"); } void LLFacebookStatusPanel::clearAndClose() { - mMessageTextEditor->setValue(""); + mMessageTextEditor->setValue(""); - LLFloater* floater = getParentByType<LLFloater>(); - if (floater) - { - floater->closeFloater(); - } + LLFloater* floater = getParentByType<LLFloater>(); + if (floater) + { + floater->closeFloater(); + } } /////////////////////////// @@ -324,89 +324,89 @@ void LLFacebookStatusPanel::clearAndClose() /////////////////////////// LLFacebookPhotoPanel::LLFacebookPhotoPanel() : -mResolutionComboBox(NULL), -mRefreshBtn(NULL), -mBtnPreview(NULL), -mWorkingLabel(NULL), -mThumbnailPlaceholder(NULL), -mCaptionTextBox(NULL), -mPostButton(NULL), -mBigPreviewFloater(NULL), -mQuality(MAX_QUALITY) + mResolutionComboBox(NULL), + mRefreshBtn(NULL), + mBtnPreview(NULL), + mWorkingLabel(NULL), + mThumbnailPlaceholder(NULL), + mCaptionTextBox(NULL), + mPostButton(NULL), + mBigPreviewFloater(NULL), + mQuality(MAX_QUALITY) { - mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLFacebookPhotoPanel::onSend, this)); - mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLFacebookPhotoPanel::onClickNewSnapshot, this)); - mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLFacebookPhotoPanel::onClickBigPreview, this)); + mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLFacebookPhotoPanel::onSend, this)); + mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLFacebookPhotoPanel::onClickNewSnapshot, this)); + mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLFacebookPhotoPanel::onClickBigPreview, this)); } LLFacebookPhotoPanel::~LLFacebookPhotoPanel() { - if(mPreviewHandle.get()) - { - mPreviewHandle.get()->die(); - } + if (mPreviewHandle.get()) + { + mPreviewHandle.get()->die(); + } } BOOL LLFacebookPhotoPanel::postBuild() { - setVisibleCallback(boost::bind(&LLFacebookPhotoPanel::onVisibilityChange, this, _2)); - - mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox"); - mResolutionComboBox->setValue("[i1200,i630]"); // hardcoded defaults ftw! - mResolutionComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE)); - mFilterComboBox = getChild<LLUICtrl>("filters_combobox"); - mFilterComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE)); - mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn"); - mBtnPreview = getChild<LLButton>("big_preview_btn"); + setVisibleCallback(boost::bind(&LLFacebookPhotoPanel::onVisibilityChange, this, _2)); + + mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox"); + mResolutionComboBox->setValue("[i1200,i630]"); // hardcoded defaults ftw! + mResolutionComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE)); + mFilterComboBox = getChild<LLUICtrl>("filters_combobox"); + mFilterComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE)); + mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn"); + mBtnPreview = getChild<LLButton>("big_preview_btn"); mWorkingLabel = getChild<LLUICtrl>("working_lbl"); - mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder"); - mCaptionTextBox = getChild<LLUICtrl>("photo_caption"); - mPostButton = getChild<LLUICtrl>("post_photo_btn"); - mCancelButton = getChild<LLUICtrl>("cancel_photo_btn"); - mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview")); + mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder"); + mCaptionTextBox = getChild<LLUICtrl>("photo_caption"); + mPostButton = getChild<LLUICtrl>("post_photo_btn"); + mCancelButton = getChild<LLUICtrl>("cancel_photo_btn"); + mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview")); - // Update filter list + // Update filter list std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList(); - LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox); + LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox); for (U32 i = 0; i < filter_list.size(); i++) - { + { filterbox->add(filter_list[i]); } - return LLPanel::postBuild(); + return LLPanel::postBuild(); } // virtual S32 LLFacebookPhotoPanel::notify(const LLSD& info) { - if (info.has("snapshot-updating")) - { + if (info.has("snapshot-updating")) + { // Disable the Post button and whatever else while the snapshot is not updated // updateControls(); - return 1; - } - - if (info.has("snapshot-updated")) - { + return 1; + } + + if (info.has("snapshot-updated")) + { // Enable the send/post/save buttons. updateControls(); - - // The refresh button is initially hidden. We show it after the first update, - // i.e. after snapshot is taken - LLUICtrl * refresh_button = getRefreshBtn(); - if (!refresh_button->getVisible()) - { - refresh_button->setVisible(true); - } - return 1; - } - - return 0; + + // The refresh button is initially hidden. We show it after the first update, + // i.e. after snapshot is taken + LLUICtrl * refresh_button = getRefreshBtn(); + if (!refresh_button->getVisible()) + { + refresh_button->setVisible(true); + } + return 1; + } + + return 0; } void LLFacebookPhotoPanel::draw() -{ - LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get()); +{ + LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get()); // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts) bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing()); @@ -416,98 +416,98 @@ void LLFacebookPhotoPanel::draw() mFilterComboBox->setEnabled(no_ongoing_connection); mRefreshBtn->setEnabled(no_ongoing_connection); mBtnPreview->setEnabled(no_ongoing_connection); - + // Reassign the preview floater if we have the focus and the preview exists if (hasFocus() && isPreviewVisible()) { attachPreview(); } - + // Toggle the button state as appropriate bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>())); - mBtnPreview->setToggleState(preview_active); - + mBtnPreview->setToggleState(preview_active); + // Display the thumbnail if one is available - if (previewp && previewp->getThumbnailImage()) - { - const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect(); - const S32 thumbnail_w = previewp->getThumbnailWidth(); - const S32 thumbnail_h = previewp->getThumbnailHeight(); - - // calc preview offset within the preview rect - const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2 ; - const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ; - S32 offset_x = thumbnail_rect.mLeft + local_offset_x; - S32 offset_y = thumbnail_rect.mBottom + local_offset_y; - - gGL.matrixMode(LLRender::MM_MODELVIEW); - // Apply floater transparency to the texture unless the floater is focused. - F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); - LLColor4 color = LLColor4::white; - gl_draw_scaled_image(offset_x, offset_y, - thumbnail_w, thumbnail_h, - previewp->getThumbnailImage(), color % alpha); - } + if (previewp && previewp->getThumbnailImage()) + { + const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect(); + const S32 thumbnail_w = previewp->getThumbnailWidth(); + const S32 thumbnail_h = previewp->getThumbnailHeight(); + + // calc preview offset within the preview rect + const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2; + const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2; + S32 offset_x = thumbnail_rect.mLeft + local_offset_x; + S32 offset_y = thumbnail_rect.mBottom + local_offset_y; + + gGL.matrixMode(LLRender::MM_MODELVIEW); + // Apply floater transparency to the texture unless the floater is focused. + F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + LLColor4 color = LLColor4::white; + gl_draw_scaled_image(offset_x, offset_y, + thumbnail_w, thumbnail_h, + previewp->getThumbnailImage(), color % alpha); + } // Update the visibility of the working (computing preview) label mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate())); - + // Enable Post if we have a preview to send and no on going connection being processed mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate())); - + // Draw the rest of the panel on top of it - LLPanel::draw(); + LLPanel::draw(); } LLSnapshotLivePreview* LLFacebookPhotoPanel::getPreviewView() { - LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get(); - return previewp; + LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get(); + return previewp; } void LLFacebookPhotoPanel::onVisibilityChange(BOOL visible) { - if (visible) - { - if (mPreviewHandle.get()) - { - LLSnapshotLivePreview* preview = getPreviewView(); - if(preview) - { - LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL; - preview->updateSnapshot(TRUE); - } - } - else - { - LLRect full_screen_rect = getRootView()->getRect(); - LLSnapshotLivePreview::Params p; - p.rect(full_screen_rect); - LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); - mPreviewHandle = previewp->getHandle(); + if (visible) + { + if (mPreviewHandle.get()) + { + LLSnapshotLivePreview* preview = getPreviewView(); + if (preview) + { + LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL; + preview->updateSnapshot(TRUE); + } + } + else + { + LLRect full_screen_rect = getRootView()->getRect(); + LLSnapshotLivePreview::Params p; + p.rect(full_screen_rect); + LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); + mPreviewHandle = previewp->getHandle(); mQuality = MAX_QUALITY; previewp->setContainer(this); - previewp->setSnapshotType(previewp->SNAPSHOT_WEB); - previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG); - previewp->setSnapshotQuality(mQuality, false); + previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB); + previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_JPEG); + previewp->setSnapshotQuality(mQuality, false); previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode - previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect()); + previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect()); - updateControls(); - } - } + updateControls(); + } + } } void LLFacebookPhotoPanel::onClickNewSnapshot() { - LLSnapshotLivePreview* previewp = getPreviewView(); - if (previewp) - { - previewp->updateSnapshot(TRUE); - } + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) + { + previewp->updateSnapshot(TRUE); + } } void LLFacebookPhotoPanel::onClickBigPreview() @@ -541,167 +541,167 @@ void LLFacebookPhotoPanel::attachPreview() void LLFacebookPhotoPanel::onSend() { - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel"); // just in case it is already listening - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookPhotoPanel", boost::bind(&LLFacebookPhotoPanel::onFacebookConnectStateChange, this, _1)); - - // Connect to Facebook if necessary and then post - if (LLFacebookConnect::instance().isConnected()) - { - sendPhoto(); - } - else - { - LLFacebookConnect::instance().checkConnectionToFacebook(true); - } + LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel"); // just in case it is already listening + LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookPhotoPanel", boost::bind(&LLFacebookPhotoPanel::onFacebookConnectStateChange, this, _1)); + + // Connect to Facebook if necessary and then post + if (LLFacebookConnect::instance().isConnected()) + { + sendPhoto(); + } + else + { + LLFacebookConnect::instance().checkConnectionToFacebook(true); + } } bool LLFacebookPhotoPanel::onFacebookConnectStateChange(const LLSD& data) { - switch (data.get("enum").asInteger()) - { - case LLFacebookConnect::FB_CONNECTED: - sendPhoto(); - break; - - case LLFacebookConnect::FB_POSTED: - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel"); - clearAndClose(); - break; - } - - return false; + switch (data.get("enum").asInteger()) + { + case LLFacebookConnect::FB_CONNECTED: + sendPhoto(); + break; + + case LLFacebookConnect::FB_POSTED: + LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel"); + clearAndClose(); + break; + } + + return false; } void LLFacebookPhotoPanel::sendPhoto() { - // Get the caption - std::string caption = mCaptionTextBox->getValue().asString(); + // Get the caption + std::string caption = mCaptionTextBox->getValue().asString(); - // Get the image - LLSnapshotLivePreview* previewp = getPreviewView(); - - // Post to Facebook - LLFacebookConnect::instance().sharePhoto(previewp->getFormattedImage(), caption); + // Get the image + LLSnapshotLivePreview* previewp = getPreviewView(); - updateControls(); + // Post to Facebook + LLFacebookConnect::instance().sharePhoto(previewp->getFormattedImage(), caption); + + updateControls(); } void LLFacebookPhotoPanel::clearAndClose() { - mCaptionTextBox->setValue(""); + mCaptionTextBox->setValue(""); - LLFloater* floater = getParentByType<LLFloater>(); - if (floater) - { - floater->closeFloater(); + LLFloater* floater = getParentByType<LLFloater>(); + if (floater) + { + floater->closeFloater(); if (mBigPreviewFloater) { mBigPreviewFloater->closeOnFloaterOwnerClosing(floater); } - } + } } void LLFacebookPhotoPanel::updateControls() { - LLSnapshotLivePreview* previewp = getPreviewView(); - BOOL got_snap = previewp && previewp->getSnapshotUpToDate(); - - // *TODO: Separate maximum size for Web images from postcards - LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL; - - updateResolution(FALSE); + LLSnapshotLivePreview* previewp = getPreviewView(); + BOOL got_snap = previewp && previewp->getSnapshotUpToDate(); + + // *TODO: Separate maximum size for Web images from postcards + LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL; + + updateResolution(FALSE); } void LLFacebookPhotoPanel::updateResolution(BOOL do_update) { - LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox); - LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox); + LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox); + LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox); - std::string sdstring = combobox->getSelectedValue(); - LLSD sdres; - std::stringstream sstream(sdstring); - LLSDSerialize::fromNotation(sdres, sstream, sdstring.size()); + std::string sdstring = combobox->getSelectedValue(); + LLSD sdres; + std::stringstream sstream(sdstring); + LLSDSerialize::fromNotation(sdres, sstream, sdstring.size()); - S32 width = sdres[0]; - S32 height = sdres[1]; + S32 width = sdres[0]; + S32 height = sdres[1]; // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : ""); - LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get()); - if (previewp && combobox->getCurrentIndex() >= 0) - { - S32 original_width = 0 , original_height = 0 ; - previewp->getSize(original_width, original_height) ; - - if (width == 0 || height == 0) - { - // take resolution from current window size - LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL; - previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()); - } - else - { - // use the resolution from the selected pre-canned drop-down choice - LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL; - previewp->setSize(width, height); - } - - checkAspectRatio(width); - - previewp->getSize(width, height); - + LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get()); + if (previewp && combobox->getCurrentIndex() >= 0) + { + S32 original_width = 0, original_height = 0; + previewp->getSize(original_width, original_height); + + if (width == 0 || height == 0) + { + // take resolution from current window size + LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL; + previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()); + } + else + { + // use the resolution from the selected pre-canned drop-down choice + LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL; + previewp->setSize(width, height); + } + + checkAspectRatio(width); + + previewp->getSize(width, height); + // Recompute quality setting mQuality = compute_jpeg_quality(width, height); previewp->setSnapshotQuality(mQuality, false); - - if (original_width != width || original_height != height) - { - previewp->setSize(width, height); - if (do_update) - { + + if (original_width != width || original_height != height) + { + previewp->setSize(width, height); + if (do_update) + { previewp->updateSnapshot(TRUE); - updateControls(); - } - } + updateControls(); + } + } // Get the old filter, compare to the current one "filter_name" and set if changed std::string original_filter = previewp->getFilter(); - if (original_filter != filter_name) - { + if (original_filter != filter_name) + { previewp->setFilter(filter_name); - if (do_update) - { + if (do_update) + { previewp->updateSnapshot(FALSE, TRUE); - updateControls(); - } - } - } + updateControls(); + } + } + } } void LLFacebookPhotoPanel::checkAspectRatio(S32 index) { - LLSnapshotLivePreview *previewp = getPreviewView() ; - - BOOL keep_aspect = FALSE; - - if (0 == index) // current window size - { - keep_aspect = TRUE; - } - else // predefined resolution - { - keep_aspect = FALSE; - } - - if (previewp) - { - previewp->mKeepAspectRatio = keep_aspect; - } + LLSnapshotLivePreview *previewp = getPreviewView(); + + BOOL keep_aspect = FALSE; + + if (0 == index) // current window size + { + keep_aspect = TRUE; + } + else // predefined resolution + { + keep_aspect = FALSE; + } + + if (previewp) + { + previewp->mKeepAspectRatio = keep_aspect; + } } LLUICtrl* LLFacebookPhotoPanel::getRefreshBtn() { - return mRefreshBtn; + return mRefreshBtn; } //////////////////////// @@ -712,21 +712,21 @@ LLFacebookCheckinPanel::LLFacebookCheckinPanel() : mMapUrl(""), mReloadingMapTexture(false) { - mCommitCallbackRegistrar.add("SocialSharing.SendCheckin", boost::bind(&LLFacebookCheckinPanel::onSend, this)); + mCommitCallbackRegistrar.add("SocialSharing.SendCheckin", boost::bind(&LLFacebookCheckinPanel::onSend, this)); } BOOL LLFacebookCheckinPanel::postBuild() { // Keep pointers to widgets so we don't traverse the UI hierarchy too often - mPostButton = getChild<LLUICtrl>("post_place_btn"); - mCancelButton = getChild<LLUICtrl>("cancel_place_btn"); - mMessageTextEditor = getChild<LLUICtrl>("place_caption"); + mPostButton = getChild<LLUICtrl>("post_place_btn"); + mCancelButton = getChild<LLUICtrl>("cancel_place_btn"); + mMessageTextEditor = getChild<LLUICtrl>("place_caption"); mMapLoadingIndicator = getChild<LLUICtrl>("map_loading_indicator"); mMapPlaceholder = getChild<LLIconCtrl>("map_placeholder"); mMapDefault = getChild<LLIconCtrl>("map_default"); mMapCheckBox = getChild<LLCheckBoxCtrl>("add_place_view_cb"); - - return LLPanel::postBuild(); + + return LLPanel::postBuild(); } void LLFacebookCheckinPanel::draw() @@ -767,101 +767,101 @@ void LLFacebookCheckinPanel::draw() // This will hide/show the loading indicator and/or tile underneath mMapDefault->setVisible(!(mMapCheckBox->get())); - LLPanel::draw(); + LLPanel::draw(); } void LLFacebookCheckinPanel::onSend() { - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel"); // just in case it is already listening - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookCheckinPanel", boost::bind(&LLFacebookCheckinPanel::onFacebookConnectStateChange, this, _1)); - - // Connect to Facebook if necessary and then post - if (LLFacebookConnect::instance().isConnected()) - { - sendCheckin(); - } - else - { - LLFacebookConnect::instance().checkConnectionToFacebook(true); - } + LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel"); // just in case it is already listening + LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookCheckinPanel", boost::bind(&LLFacebookCheckinPanel::onFacebookConnectStateChange, this, _1)); + + // Connect to Facebook if necessary and then post + if (LLFacebookConnect::instance().isConnected()) + { + sendCheckin(); + } + else + { + LLFacebookConnect::instance().checkConnectionToFacebook(true); + } } bool LLFacebookCheckinPanel::onFacebookConnectStateChange(const LLSD& data) { - switch (data.get("enum").asInteger()) - { - case LLFacebookConnect::FB_CONNECTED: - sendCheckin(); - break; - - case LLFacebookConnect::FB_POSTED: - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel"); - clearAndClose(); - break; - } - - return false; + switch (data.get("enum").asInteger()) + { + case LLFacebookConnect::FB_CONNECTED: + sendCheckin(); + break; + + case LLFacebookConnect::FB_POSTED: + LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel"); + clearAndClose(); + break; + } + + return false; } void LLFacebookCheckinPanel::sendCheckin() { - // Get the location SLURL - LLSLURL slurl; - LLAgentUI::buildSLURL(slurl); - std::string slurl_string = slurl.getSLURLString(); - - // Use a valid http:// URL if the scheme is secondlife:// - LLURI slurl_uri(slurl_string); - if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME) - { - slurl_string = DEFAULT_CHECKIN_LOCATION_URL; - } - - // Add query parameters so Google Analytics can track incoming clicks! - slurl_string += DEFAULT_CHECKIN_QUERY_PARAMETERS; - - // Get the region name - std::string region_name(""); + // Get the location SLURL + LLSLURL slurl; + LLAgentUI::buildSLURL(slurl); + std::string slurl_string = slurl.getSLURLString(); + + // Use a valid http:// URL if the scheme is secondlife:// + LLURI slurl_uri(slurl_string); + if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME) + { + slurl_string = DEFAULT_CHECKIN_LOCATION_URL; + } + + // Add query parameters so Google Analytics can track incoming clicks! + slurl_string += DEFAULT_CHECKIN_QUERY_PARAMETERS; + + // Get the region name + std::string region_name(""); LLViewerRegion *regionp = gAgent.getRegion(); if (regionp) { region_name = regionp->getName(); } - - // Get the region description - std::string description; - LLAgentUI::buildLocationString(description, LLAgentUI::LOCATION_FORMAT_NORMAL_COORDS, gAgent.getPositionAgent()); - - // Optionally add the region map view - bool add_map_view = mMapCheckBox->getValue().asBoolean(); + + // Get the region description + std::string description; + LLAgentUI::buildLocationString(description, LLAgentUI::LOCATION_FORMAT_NORMAL_COORDS, gAgent.getPositionAgent()); + + // Optionally add the region map view + bool add_map_view = mMapCheckBox->getValue().asBoolean(); std::string map_url = (add_map_view ? get_map_url() : DEFAULT_CHECKIN_ICON_URL); - - // Get the caption - std::string caption = mMessageTextEditor->getValue().asString(); - // Post to Facebook - LLFacebookConnect::instance().postCheckin(slurl_string, region_name, description, map_url, caption); + // Get the caption + std::string caption = mMessageTextEditor->getValue().asString(); + + // Post to Facebook + LLFacebookConnect::instance().postCheckin(slurl_string, region_name, description, map_url, caption); } void LLFacebookCheckinPanel::clearAndClose() { - mMessageTextEditor->setValue(""); + mMessageTextEditor->setValue(""); - LLFloater* floater = getParentByType<LLFloater>(); - if (floater) - { - floater->closeFloater(); - } + LLFloater* floater = getParentByType<LLFloater>(); + if (floater) + { + floater->closeFloater(); + } } /////////////////////////// //LLFacebookFriendsPanel////// /////////////////////////// -LLFacebookFriendsPanel::LLFacebookFriendsPanel() : -mFriendsStatusCaption(NULL), -mSecondLifeFriends(NULL), -mSuggestedFriends(NULL) +LLFacebookFriendsPanel::LLFacebookFriendsPanel() : + mFriendsStatusCaption(NULL), + mSecondLifeFriends(NULL), + mSuggestedFriends(NULL) { } @@ -872,55 +872,55 @@ LLFacebookFriendsPanel::~LLFacebookFriendsPanel() BOOL LLFacebookFriendsPanel::postBuild() { - mFriendsStatusCaption = getChild<LLTextBox>("facebook_friends_status"); + mFriendsStatusCaption = getChild<LLTextBox>("facebook_friends_status"); + + mSecondLifeFriends = getChild<LLAvatarList>("second_life_friends"); + mSecondLifeFriends->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu); - mSecondLifeFriends = getChild<LLAvatarList>("second_life_friends"); - mSecondLifeFriends->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu); - - mSuggestedFriends = getChild<LLAvatarList>("suggested_friends"); - mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu); - - setVisibleCallback(boost::bind(&LLFacebookFriendsPanel::updateFacebookList, this, _2)); + mSuggestedFriends = getChild<LLAvatarList>("suggested_friends"); + mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu); + + setVisibleCallback(boost::bind(&LLFacebookFriendsPanel::updateFacebookList, this, _2)); LLAvatarTracker::instance().addObserver(this); - - return LLPanel::postBuild(); + + return LLPanel::postBuild(); } bool LLFacebookFriendsPanel::updateSuggestedFriendList() { - const LLAvatarTracker& av_tracker = LLAvatarTracker::instance(); - uuid_vec_t& second_life_friends = mSecondLifeFriends->getIDs(); - second_life_friends.clear(); - uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs(); - suggested_friends.clear(); - - //Add suggested friends - LLSD friends = LLFacebookConnect::instance().getContent(); - for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i) - { - LLUUID agent_id = (*i).asUUID(); - if (agent_id.notNull()) - { - bool second_life_buddy = av_tracker.isBuddy(agent_id); - if (second_life_buddy) - { - second_life_friends.push_back(agent_id); - } - else - { - //FB+SL but not SL friend - suggested_friends.push_back(agent_id); - } - } - } - - //Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display) - mSecondLifeFriends->setDirty(true, !mSecondLifeFriends->filterHasMatches()); - mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches()); - showFriendsAccordionsIfNeeded(); - - return false; + const LLAvatarTracker& av_tracker = LLAvatarTracker::instance(); + uuid_vec_t& second_life_friends = mSecondLifeFriends->getIDs(); + second_life_friends.clear(); + uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs(); + suggested_friends.clear(); + + //Add suggested friends + LLSD friends = LLFacebookConnect::instance().getContent(); + for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i) + { + LLUUID agent_id = (*i).asUUID(); + if (agent_id.notNull()) + { + bool second_life_buddy = av_tracker.isBuddy(agent_id); + if (second_life_buddy) + { + second_life_friends.push_back(agent_id); + } + else + { + //FB+SL but not SL friend + suggested_friends.push_back(agent_id); + } + } + } + + //Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display) + mSecondLifeFriends->setDirty(true, !mSecondLifeFriends->filterHasMatches()); + mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches()); + showFriendsAccordionsIfNeeded(); + + return false; } void LLFacebookFriendsPanel::showFriendsAccordionsIfNeeded() @@ -949,15 +949,15 @@ void LLFacebookFriendsPanel::showFriendsAccordionsIfNeeded() { // We have something in the lists, hide the explanatory text mFriendsStatusCaption->setVisible(false); - + // Show the lists LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion"); accordion->setVisible(true); - + // Expand and show accordions if needed, else - hide them getChild<LLAccordionCtrlTab>("tab_second_life_friends")->setVisible(mSecondLifeFriends->filterHasMatches()); getChild<LLAccordionCtrlTab>("tab_suggested_friends")->setVisible(mSuggestedFriends->filterHasMatches()); - + // Rearrange accordions accordion->arrange(); } @@ -965,56 +965,56 @@ void LLFacebookFriendsPanel::showFriendsAccordionsIfNeeded() void LLFacebookFriendsPanel::changed(U32 mask) { - if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE)) - { + if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE)) + { LLFacebookConnect::instance().loadFacebookFriends(); - updateFacebookList(true); - } + updateFacebookList(true); + } } void LLFacebookFriendsPanel::updateFacebookList(bool visible) { - if (visible) - { + if (visible) + { // We want this to be called to fetch the friends list once a connection is established - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookFriendsPanel"); - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::onConnectedToFacebook, this, _1)); - + LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookFriendsPanel"); + LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::onConnectedToFacebook, this, _1)); + // We then want this to be called to update the displayed lists once the list of friends is received - LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLFacebookFriendsPanel"); // just in case it is already listening - LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::updateSuggestedFriendList, this)); - - // Try to connect to Facebook + LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLFacebookFriendsPanel"); // just in case it is already listening + LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::updateSuggestedFriendList, this)); + + // Try to connect to Facebook if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) || (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED)) { LLFacebookConnect::instance().checkConnectionToFacebook(); } - // Loads FB friends - if (LLFacebookConnect::instance().isConnected()) - { - LLFacebookConnect::instance().loadFacebookFriends(); - } + // Loads FB friends + if (LLFacebookConnect::instance().isConnected()) + { + LLFacebookConnect::instance().loadFacebookFriends(); + } // Sort the FB friends and update the lists - updateSuggestedFriendList(); - } + updateSuggestedFriendList(); + } } bool LLFacebookFriendsPanel::onConnectedToFacebook(const LLSD& data) { - LLSD::Integer connection_state = data.get("enum").asInteger(); - - if (connection_state == LLFacebookConnect::FB_CONNECTED) - { - LLFacebookConnect::instance().loadFacebookFriends(); - } - else if (connection_state == LLFacebookConnect::FB_NOT_CONNECTED) - { - updateSuggestedFriendList(); - } - - return false; + LLSD::Integer connection_state = data.get("enum").asInteger(); + + if (connection_state == LLFacebookConnect::FB_CONNECTED) + { + LLFacebookConnect::instance().loadFacebookFriends(); + } + else if (connection_state == LLFacebookConnect::FB_NOT_CONNECTED) + { + updateSuggestedFriendList(); + } + + return false; } //////////////////////// @@ -1027,7 +1027,7 @@ LLFloaterFacebook::LLFloaterFacebook(const LLSD& key) : LLFloater(key), mStatusLoadingText(NULL), mStatusLoadingIndicator(NULL) { - mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterFacebook::onCancel, this)); + mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterFacebook::onCancel, this)); } void LLFloaterFacebook::onClose(bool app_quitting) @@ -1037,7 +1037,7 @@ void LLFloaterFacebook::onClose(bool app_quitting) { big_preview_floater->closeOnFloaterOwnerClosing(this); } - LLFloater::onClose(app_quitting); + LLFloater::onClose(app_quitting); } void LLFloaterFacebook::onCancel() @@ -1053,24 +1053,24 @@ void LLFloaterFacebook::onCancel() BOOL LLFloaterFacebook::postBuild() { // Keep tab of the Photo Panel - mFacebookPhotoPanel = static_cast<LLFacebookPhotoPanel*>(getChild<LLUICtrl>("panel_facebook_photo")); + mFacebookPhotoPanel = static_cast<LLFacebookPhotoPanel*>(getChild<LLUICtrl>("panel_facebook_photo")); // Connection status widgets mStatusErrorText = getChild<LLTextBox>("connection_error_text"); mStatusLoadingText = getChild<LLTextBox>("connection_loading_text"); mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator"); - return LLFloater::postBuild(); + return LLFloater::postBuild(); } void LLFloaterFacebook::showPhotoPanel() { - LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mFacebookPhotoPanel->getParent()); - if (!parent) - { - LL_WARNS() << "Cannot find panel container" << LL_ENDL; - return; - } - - parent->selectTabPanel(mFacebookPhotoPanel); + LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mFacebookPhotoPanel->getParent()); + if (!parent) + { + LL_WARNS() << "Cannot find panel container" << LL_ENDL; + return; + } + + parent->selectTabPanel(mFacebookPhotoPanel); } void LLFloaterFacebook::draw() @@ -1082,7 +1082,7 @@ void LLFloaterFacebook::draw() mStatusLoadingIndicator->setVisible(false); LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState(); std::string status_text; - + switch (connection_state) { case LLFacebookConnect::FB_NOT_CONNECTED: @@ -1105,7 +1105,7 @@ void LLFloaterFacebook::draw() status_text = LLTrans::getString("SocialFacebookPosting"); mStatusLoadingText->setValue(status_text); mStatusLoadingIndicator->setVisible(true); - break; + break; case LLFacebookConnect::FB_CONNECTION_FAILED: // Error connecting to the service mStatusErrorText->setVisible(true); @@ -1118,21 +1118,21 @@ void LLFloaterFacebook::draw() status_text = LLTrans::getString("SocialFacebookErrorPosting"); mStatusErrorText->setValue(status_text); break; - case LLFacebookConnect::FB_DISCONNECTING: - // Disconnecting loading indicator - mStatusLoadingText->setVisible(true); - status_text = LLTrans::getString("SocialFacebookDisconnecting"); - mStatusLoadingText->setValue(status_text); - mStatusLoadingIndicator->setVisible(true); - break; - case LLFacebookConnect::FB_DISCONNECT_FAILED: - // Error disconnecting from the service - mStatusErrorText->setVisible(true); - status_text = LLTrans::getString("SocialFacebookErrorDisconnecting"); - mStatusErrorText->setValue(status_text); - break; + case LLFacebookConnect::FB_DISCONNECTING: + // Disconnecting loading indicator + mStatusLoadingText->setVisible(true); + status_text = LLTrans::getString("SocialFacebookDisconnecting"); + mStatusLoadingText->setValue(status_text); + mStatusLoadingIndicator->setVisible(true); + break; + case LLFacebookConnect::FB_DISCONNECT_FAILED: + // Error disconnecting from the service + mStatusErrorText->setVisible(true); + status_text = LLTrans::getString("SocialFacebookErrorDisconnecting"); + mStatusErrorText->setValue(status_text); + break; } } - LLFloater::draw(); + LLFloater::draw(); } diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp index cd132b843dd2c19bbbb7d152316c254de4511ed5..15b7c7fafadde6599a58386eed1312ef84f41499 100644 --- a/indra/newview/llfloaterflickr.cpp +++ b/indra/newview/llfloaterflickr.cpp @@ -238,8 +238,8 @@ void LLFlickrPhotoPanel::onVisibilityChange(BOOL visible) mPreviewHandle = previewp->getHandle(); previewp->setContainer(this); - previewp->setSnapshotType(previewp->SNAPSHOT_WEB); - previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG); + previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB); + previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_PNG); previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index d842106146e0b3198bd1b5deaf1eabe7f487b86c..b840d37c4d99fe0af8612c5452365468e760d6bf 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -328,7 +328,7 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur element["columns"][0]["font"]["name"] = "SANSSERIF"; element["columns"][0]["font"]["style"] = font_style; - std::string key_string = LLKeyboard::stringFromKey(gesture->mKey); + std::string key_string; std::string buffer; if (gesture->mKey == KEY_NONE) @@ -338,6 +338,7 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur } else { + key_string = LLKeyboard::stringFromKey(gesture->mKey); buffer = LLKeyboard::stringFromAccelerator(gesture->mMask, gesture->mKey); } diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 15b67b905d036b596a7006f7f466d1932ff8c34f..7039e48e74a328b8f466092fab12e84b6941f4c1 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -101,7 +101,7 @@ LLFloaterIMContainer::~LLFloaterIMContainer() gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed()); gSavedPerAccountSettings.setBOOL("ConversationsParticipantListCollapsed", !isParticipantListExpanded()); - if (!LLSingleton<LLIMMgr>::destroyed()) + if (LLIMMgr::instanceExists()) { LLIMMgr::getInstance()->removeSessionObserver(this); } diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 7a989806a1ff2ff1ead578d21ddd1b3e6e55afc3..e9af22d3364bbe1e6bddcd92cc2b4a123e20ee84 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -282,7 +282,7 @@ void LLFloaterIMNearbyChat::onTearOffClicked() LLFloaterIMSessionTab::onTearOffClicked(); // see CHUI-170: Save torn-off state of the nearby chat between sessions - BOOL in_the_multifloater = (BOOL)getHost(); + bool in_the_multifloater(getHost()); gSavedPerAccountSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater); } @@ -798,7 +798,8 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32* } else if (mesg[0] == '/' && mesg[1] - && LLStringOps::isDigit(mesg[1])) + && (LLStringOps::isDigit(mesg[1]) + || (mesg[1] == '-' && mesg[2] && LLStringOps::isDigit(mesg[2])))) { // This a special "/20" speak on a channel S32 pos = 0; @@ -812,7 +813,7 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel_string.push_back(c); pos++; } - while(c && pos < 64 && LLStringOps::isDigit(c)); + while(c && pos < 64 && (LLStringOps::isDigit(c) || (pos==1 && c =='-'))); // Move the pointer forward to the first non-whitespace char // Check isspace before looping, so we can handle "/33foo" @@ -837,19 +838,36 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32* void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) { - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ChatFromViewer); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ChatData); - msg->addStringFast(_PREHASH_Message, utf8_out_text); - msg->addU8Fast(_PREHASH_Type, type); - msg->addS32("Channel", channel); - - gAgent.sendReliableMessage(); - - add(LLStatViewer::CHAT_COUNT, 1); + LLMessageSystem* msg = gMessageSystem; + + if (channel >= 0) + { + msg->newMessageFast(_PREHASH_ChatFromViewer); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ChatData); + msg->addStringFast(_PREHASH_Message, utf8_out_text); + msg->addU8Fast(_PREHASH_Type, type); + msg->addS32("Channel", channel); + + } + else + { + // Hack: ChatFromViewer doesn't allow negative channels + msg->newMessage("ScriptDialogReply"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgentID); + msg->addUUID("SessionID", gAgentSessionID); + msg->nextBlock("Data"); + msg->addUUID("ObjectID", gAgentID); + msg->addS32("ChatChannel", channel); + msg->addS32("ButtonIndex", 0); + msg->addString("ButtonLabel", utf8_out_text); + } + + gAgent.sendReliableMessage(); + add(LLStatViewer::CHAT_COUNT, 1); } class LLChatCommandHandler : public LLCommandHandler diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index 9fd731ed5630e823b5df16b85086e93f09ce8670..4cd91c53d85508cac022b6becdc6f551eb6f4ba6 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -285,6 +285,14 @@ void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat) if(mStopProcessing) return; + if (mFloaterSnapRegion == NULL) + { + mFloaterSnapRegion = gViewerWindow->getRootView()->getChildView("floater_snap_region"); + } + LLRect channel_rect; + mFloaterSnapRegion->localRectToOtherView(mFloaterSnapRegion->getLocalRect(), &channel_rect, gFloaterView); + chat["available_height"] = channel_rect.getHeight() - channel_rect.mBottom - gSavedSettings.getS32("ToastGap") - 110;; + /* find last toast and check ID */ @@ -380,7 +388,7 @@ void LLFloaterIMNearbyChatScreenChannel::arrangeToasts() setFollows(FOLLOWS_ALL); } - LLRect toast_rect; + LLRect toast_rect; updateRect(); LLRect channel_rect; diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp deleted file mode 100644 index 9b9b90e5219481452c72e69553fd56d7f2c04c03..0000000000000000000000000000000000000000 --- a/indra/newview/llfloaterinventory.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @file llfloaterinventory.cpp - * @brief Implementation of the inventory view and associated stuff. - * - * $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 "llfloaterinventory.h" - -#include "llagentcamera.h" -//#include "llfirstuse.h" -#include "llfloaterreg.h" -#include "llinventorymodel.h" -#include "llpanelmaininventory.h" -#include "llresmgr.h" -#include "llviewerfoldertype.h" -#include "lltransientfloatermgr.h" - -///---------------------------------------------------------------------------- -/// LLFloaterInventory -///---------------------------------------------------------------------------- - -LLFloaterInventory::LLFloaterInventory(const LLSD& key) - : LLFloater(key) -{ - LLTransientFloaterMgr::getInstance()->addControlView(this); -} - -LLFloaterInventory::~LLFloaterInventory() -{ - LLTransientFloaterMgr::getInstance()->removeControlView(this); -} - -BOOL LLFloaterInventory::postBuild() -{ - mPanelMainInventory = findChild<LLPanelMainInventory>("Inventory Panel"); - return TRUE; -} - -LLInventoryPanel* LLFloaterInventory::getPanel() -{ - if (mPanelMainInventory) - return mPanelMainInventory->getPanel(); - return NULL; -} - -// static -LLFloaterInventory* LLFloaterInventory::showAgentInventory() -{ - // Hack to generate semi-unique key for each inventory floater. - static S32 instance_num = 0; - instance_num = (instance_num + 1) % S32_MAX; - - LLFloaterInventory* iv = NULL; - if (!gAgentCamera.cameraMouselook()) - { - iv = LLFloaterReg::showTypedInstance<LLFloaterInventory>("inventory", LLSD(instance_num)); - } - return iv; -} - -// static -void LLFloaterInventory::cleanup() -{ - 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();) - { - LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter++); - if (iv) - { - iv->destroy(); - } - } -} - -void LLFloaterInventory::onOpen(const LLSD& key) -{ - //LLFirstUse::useInventory(); -} - -void LLFloaterInventory::onClose(bool app_quitting) -{ - LLFloater::onClose(app_quitting); - if (mKey.asInteger() > 1) - { - destroy(); - } -} diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h deleted file mode 100644 index 823c4903b42d1b2672abccc64179bd78d4f6d837..0000000000000000000000000000000000000000 --- a/indra/newview/llfloaterinventory.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file llfloaterinventory.h - * @brief LLFloaterInventory, LLInventoryFolder, and LLInventoryItem - * 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$ - */ - -#ifndef LL_LLFLOATERINVENTORY_H -#define LL_LLFLOATERINVENTORY_H - -#include "llfloater.h" -#include "llfoldertype.h" - -class LLInventoryPanel; -class LLPanelMainInventory; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFloaterInventory -// -// This deals with the buttons and views used to navigate as -// well as controlling the behavior of the overall object. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLFloaterInventory : public LLFloater -{ -public: - LLFloaterInventory(const LLSD& key); - ~LLFloaterInventory(); - - BOOL postBuild(); - - // This method makes sure that an inventory view exists, is - // visible, and has focus. The view chosen is returned. - static LLFloaterInventory* showAgentInventory(); - - // Final cleanup, destroy all open inventory views. - static void cleanup(); - - // Inherited functionality - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); - - LLInventoryPanel* getPanel(); - LLPanelMainInventory* getMainInventoryPanel() { return mPanelMainInventory;} -private: - LLPanelMainInventory* mPanelMainInventory; -}; - -#endif // LL_LLFLOATERINVENTORY_H - - - diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 333ff863e591ba9325d3b88cd7c503b32a35b036..fc2da772f347700277e6045c01f3226733f21b43 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -119,7 +119,7 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask) LLVector3d pos_global = mMap->viewPosToGlobal(x, y); - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance(); if (world_map) { diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ffeebfd25613a51c94479e3d30c64cc6d64b236e..c654817849078b9f2edb93c6e60fa687a20b8efb 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -42,7 +42,6 @@ #include "llcombobox.h" #include "lldatapacker.h" #include "lldrawable.h" -#include "lldrawpoolavatar.h" #include "llrender.h" #include "llface.h" #include "lleconomy.h" @@ -54,6 +53,7 @@ #include "llmeshrepository.h" #include "llnotificationsutil.h" #include "llsdutil_math.h" +#include "llskinningutil.h" #include "lltextbox.h" #include "lltoolmgr.h" #include "llui.h" @@ -298,6 +298,7 @@ BOOL LLFloaterModelPreview::postBuild() childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); + childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); childSetTextArg("status", "[STATUS]", getString("status_idle")); @@ -311,6 +312,7 @@ BOOL LLFloaterModelPreview::postBuild() childSetCommitCallback("upload_skin", onUploadSkinCommit, this); childSetCommitCallback("upload_joints", onUploadJointsCommit, this); + childSetCommitCallback("lock_scale_if_joint_position", onUploadJointsCommit, this); childSetCommitCallback("import_scale", onImportScaleCommit, this); childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this); @@ -323,6 +325,7 @@ BOOL LLFloaterModelPreview::postBuild() childDisable("upload_skin"); childDisable("upload_joints"); + childDisable("lock_scale_if_joint_position"); initDecompControls(); @@ -488,11 +491,21 @@ void LLFloaterModelPreview::onClickCalculateBtn() bool upload_skinweights = childGetValue("upload_skin").asBoolean(); bool upload_joint_positions = childGetValue("upload_joints").asBoolean(); + bool lock_scale_if_joint_position = childGetValue("lock_scale_if_joint_position").asBoolean(); + + if (upload_joint_positions) + { + // Diagnostic message showing list of joints for which joint offsets are defined. + // FIXME - given time, would be much better to put this in the UI, in updateStatusMessages(). + mModelPreview->getPreviewAvatar()->showAttachmentOverrides(); + } mUploadModelUrl.clear(); gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, - childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mUploadModelUrl, false, + childGetValue("upload_textures").asBoolean(), + upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, + mUploadModelUrl, false, getWholeModelFeeObserverHandle()); toggleCalculateButton(false); @@ -1184,13 +1197,13 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex(NULL) , mLodsQuery() +, mLodsWithParsingError() , mPelvisZOffset( 0.0f ) , mLegacyRigValid( false ) , mRigValidJointUpload( false ) , mPhysicsSearchLOD( LLModel::LOD_PHYSICS ) , mResetJoints( false ) , mModelNoErrors( true ) -, mRigParityWithScene( false ) , mLastJointUpdate( false ) { mNeedsUpdate = TRUE; @@ -1317,9 +1330,10 @@ U32 LLModelPreview::calcResourceCost() decomp, mFMP->childGetValue("upload_skin").asBoolean(), mFMP->childGetValue("upload_joints").asBoolean(), + mFMP->childGetValue("lock_scale_if_joint_position").asBoolean(), TRUE, - FALSE, - instance.mModel->mSubmodelID); + FALSE, + instance.mModel->mSubmodelID); num_hulls += decomp.mHull.size(); for (U32 i = 0; i < decomp.mHull.size(); ++i) @@ -1644,27 +1658,23 @@ void LLModelPreview::rebuildUploadData() } -void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions) +void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position) { if (!mLODFile[LLModel::LOD_HIGH].empty()) { std::string filename = mLODFile[LLModel::LOD_HIGH]; - - std::string::size_type i = filename.rfind("."); - if (i != std::string::npos) - { - filename.replace(i, filename.size()-1, ".slm"); - saveUploadData(filename, save_skinweights, save_joint_positions); + std::string slm_filename; + + if (LLModelLoader::getSLMFilename(filename, slm_filename)) + { + saveUploadData(slm_filename, save_skinweights, save_joint_positions, lock_scale_if_joint_position); } } } -void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions) +void LLModelPreview::saveUploadData(const std::string& filename, + bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position) { - if (!gSavedSettings.getBOOL("MeshImportUseSLM")) - { - return; - } std::set<LLPointer<LLModel> > meshes; std::map<LLModel*, std::string> mesh_binary; @@ -1704,7 +1714,9 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw instance.mLOD[LLModel::LOD_LOW], instance.mLOD[LLModel::LOD_IMPOSTOR], decomp, - save_skinweights, save_joint_positions, + save_skinweights, + save_joint_positions, + lock_scale_if_joint_position, FALSE, TRUE, instance.mModel->mSubmodelID); data["mesh"][instance.mModel->mLocalID] = str.str(); @@ -1731,6 +1743,20 @@ void LLModelPreview::clearModel(S32 lod) mScene[lod].clear(); } +void LLModelPreview::getJointAliases( JointMap& joint_map) +{ + // Get all standard skeleton joints from the preview avatar. + LLVOAvatar *av = getPreviewAvatar(); + + //Joint names and aliases come from avatar_skeleton.xml + + joint_map = av->getJointAliases(); + for (S32 i = 0; i < av->mNumCollisionVolumes; i++) + { + joint_map[av->mCollisionVolumes[i].getName()] = av->mCollisionVolumes[i].getName(); + } +} + void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable_slm) { assert_main_thread(); @@ -1755,8 +1781,8 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable // this is the initial file picking. Close the whole floater // if we don't have a base model to show for high LOD. mFMP->closeFloater(false); - mLoading = false; } + mLoading = false; return; } @@ -1773,6 +1799,9 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable clearGLODGroup(); } + std::map<std::string, std::string> joint_alias_map; + getJointAliases(joint_alias_map); + mModelLoader = new LLDAELoader( filename, lod, @@ -1783,6 +1812,8 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable this, mJointTransformMap, mJointsFromNode, + joint_alias_map, + LLSkinningUtil::getMaxJointCount(), gSavedSettings.getU32("ImporterModelLimit"), gSavedSettings.getBOOL("ImporterPreprocessDAE")); @@ -1792,6 +1823,12 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable } else { + // For MAINT-6647, we have set force_disable_slm to true, + // which means this code path will never be taken. Trying to + // re-use SLM files has never worked properly; in particular, + // it tends to force the UI into strange checkbox options + // which cannot be altered. + //only try to load from slm if viewer is configured to do so and this is the //initial model load (not an LoD or physics shape) mModelLoader->mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mUploadData.empty(); @@ -1902,9 +1939,16 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) { mLoading = false ; mModelLoader = NULL; + mLodsWithParsingError.push_back(loaded_lod); return ; } + mLodsWithParsingError.erase(std::remove(mLodsWithParsingError.begin(), mLodsWithParsingError.end(), loaded_lod), mLodsWithParsingError.end()); + if(mLodsWithParsingError.empty()) + { + mFMP->childEnable( "calculate_btn" ); + } + // Copy determinations about rig so UI will reflect them // setRigValidForJointPositionUpload(mModelLoader->isRigValidForJointPositionUpload()); @@ -1919,6 +1963,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) bool skin_weights = false; bool joint_positions = false; + bool lock_scale_if_joint_position = false; for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) { //for each LoD @@ -1966,6 +2011,10 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) { joint_positions = true; } + if (list_iter->mModel->mSkinInfo.mLockScaleIfJointPosition) + { + lock_scale_if_joint_position = true; + } } } } @@ -1989,6 +2038,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) mViewOption["show_joint_positions"] = true; fmp->childSetValue("upload_joints", true); } + + if (lock_scale_if_joint_position) + { + fmp->enableViewOption("lock_scale_if_joint_position"); + mViewOption["lock_scale_if_joint_position"] = true; + fmp->childSetValue("lock_scale_if_joint_position", true); + } } //copy high lod to base scene for LoD generation @@ -2114,7 +2170,11 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) if (!mBaseModel.empty()) { const std::string& model_name = mBaseModel[0]->getName(); - mFMP->getChild<LLUICtrl>("description_form")->setValue(model_name); + LLLineEditor* description_form = mFMP->getChild<LLLineEditor>("description_form"); + if (description_form->getText().empty()) + { + description_form->setText(model_name); + } } } refresh(); @@ -2639,17 +2699,7 @@ void LLModelPreview::updateStatusMessages() setLoadState( LLModelLoader::ERROR_MATERIALS ); mFMP->childDisable( "calculate_btn" ); } - - int refFaceCnt = 0; - int modelFaceCnt = 0; - - if (!lod_model->matchMaterialOrder(model_high_lod, refFaceCnt, modelFaceCnt ) ) - { - setLoadState( LLModelLoader::ERROR_MATERIALS ); - mFMP->childDisable( "calculate_btn" ); - } - - if (lod_model) + else { //for each model in the lod S32 cur_tris = 0; @@ -3307,14 +3357,17 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) LLVector3 pos(vf.mPositions[i].getF32ptr()); const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos); + llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this LLVector4 w(0,0,0,0); for (U32 i = 0; i < weight_list.size(); ++i) { - F32 wght = llmin(weight_list[i].mWeight, 0.999999f); + F32 wght = llclamp(weight_list[i].mWeight, 0.001f, 0.999f); F32 joint = (F32) weight_list[i].mJointIdx; w.mV[i] = joint + wght; + llassert(w.mV[i]-(S32)w.mV[i]>0.0f); // because weights are non-zero, and range of wt values + //should not cause floating point precision issues. } *(weights_strider++) = w; @@ -3367,19 +3420,6 @@ void LLModelPreview::update() } } -//----------------------------------------------------------------------------- -// getTranslationForJointOffset() -//----------------------------------------------------------------------------- -LLVector3 LLModelPreview::getTranslationForJointOffset( std::string joint ) -{ - LLMatrix4 jointTransform; - if ( mJointTransformMap.find( joint ) != mJointTransformMap.end() ) - { - jointTransform = mJointTransformMap[joint]; - return jointTransform.getTranslation(); - } - return LLVector3(0.0f,0.0f,0.0f); -} //----------------------------------------------------------------------------- // createPreviewAvatar //----------------------------------------------------------------------------- @@ -3509,6 +3549,7 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget ) pTarget->setVolumeFaceData( faceCnt+1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices() ); } + //----------------------------------------------------------------------------- // render() //----------------------------------------------------------------------------- @@ -3591,7 +3632,7 @@ BOOL LLModelPreview::render() } } - if (has_skin_weights) + if (has_skin_weights && lodsReady()) { //model has skin weights, enable view options for skin weights and joint positions if (fmp && isLegacyRigValid() ) { @@ -3627,7 +3668,17 @@ BOOL LLModelPreview::render() mFMP->childSetValue("upload_joints", false); upload_joints = false; } - + + if (upload_skin && upload_joints) + { + mFMP->childEnable("lock_scale_if_joint_position"); + } + else + { + mFMP->childDisable("lock_scale_if_joint_position"); + mFMP->childSetValue("lock_scale_if_joint_position", false); + } + //Only enable joint offsets if it passed the earlier critiquing if ( isRigValidForJointPositionUpload() ) { @@ -4002,20 +4053,6 @@ BOOL LLModelPreview::render() LLVector3::z_axis, // up target_pos); // point of interest - if (joint_positions) - { - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - if (shader) - { - gDebugProgram.bind(); - } - getPreviewAvatar()->renderCollisionVolumes(); - if (shader) - { - shader->bind(); - } - } - for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) { for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) @@ -4040,58 +4077,32 @@ BOOL LLModelPreview::render() //quick 'n dirty software vertex skinning //build matrix palette - - LLMatrix4 mat[64]; - for (U32 j = 0; j < model->mSkinInfo.mJointNames.size(); ++j) - { - LLJoint* joint = getPreviewAvatar()->getJoint(model->mSkinInfo.mJointNames[j]); - if (joint) - { - mat[j] = model->mSkinInfo.mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); - } - } + LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + const LLMeshSkinInfo *skin = &model->mSkinInfo; + U32 count = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, + skin, getPreviewAvatar()); + LLMatrix4a bind_shape_matrix; + bind_shape_matrix.loadu(skin->mBindShapeMatrix); + U32 max_joints = LLSkinningUtil::getMaxJointCount(); for (U32 j = 0; j < buffer->getNumVerts(); ++j) { - LLMatrix4 final_mat; - final_mat.mMatrix[0][0] = final_mat.mMatrix[1][1] = final_mat.mMatrix[2][2] = final_mat.mMatrix[3][3] = 0.f; - - LLVector4 wght; - S32 idx[4]; - - F32 scale = 0.f; - for (U32 k = 0; k < 4; k++) - { - F32 w = weight[j].mV[k]; - - idx[k] = (S32) floorf(w); - wght.mV[k] = w - floorf(w); - scale += wght.mV[k]; - } - - wght *= 1.f/scale; - - for (U32 k = 0; k < 4; k++) - { - F32* src = (F32*) mat[idx[k]].mMatrix; - F32* dst = (F32*) final_mat.mMatrix; - - F32 w = wght.mV[k]; - - for (U32 l = 0; l < 16; l++) - { - dst[l] += src[l]*w; - } - } + LLMatrix4a final_mat; + F32 *wptr = weight[j].mV; + LLSkinningUtil::getPerVertexSkinMatrix(wptr, mat, true, final_mat, max_joints); //VECTORIZE THIS - LLVector3 v(face.mPositions[j].getF32ptr()); + LLVector4a& v = face.mPositions[j]; - v = v * model->mSkinInfo.mBindShapeMatrix; - v = v * final_mat; + LLVector4a t; + LLVector4a dst; + bind_shape_matrix.affineTransform(v, t); + final_mat.affineTransform(t, dst); - position[j] = v; + position[j][0] = dst[0]; + position[j][1] = dst[1]; + position[j][2] = dst[2]; } llassert(model->mMaterialList.size() > i); @@ -4125,6 +4136,22 @@ BOOL LLModelPreview::render() } } } + + if (joint_positions) + { + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + if (shader) + { + gDebugProgram.bind(); + } + getPreviewAvatar()->renderCollisionVolumes(); + getPreviewAvatar()->renderBones(); + if (shader) + { + shader->bind(); + } + } + } } @@ -4245,11 +4272,17 @@ void LLFloaterModelPreview::onUpload(void* user_data) bool upload_skinweights = mp->childGetValue("upload_skin").asBoolean(); bool upload_joint_positions = mp->childGetValue("upload_joints").asBoolean(); + bool lock_scale_if_joint_position = mp->childGetValue("lock_scale_if_joint_position").asBoolean(); - mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions); + if (gSavedSettings.getBOOL("MeshImportUseSLM")) + { + mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions, lock_scale_if_joint_position); + } gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, - mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mp->mUploadModelUrl, + mp->childGetValue("upload_textures").asBoolean(), + upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, + mp->mUploadModelUrl, true, LLHandle<LLWholeModelFeeObserver>(), mp->getWholeModelUploadObserverHandle()); } @@ -4261,7 +4294,14 @@ void LLFloaterModelPreview::refresh() } //static -void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ) +void LLModelPreview::textureLoadedCallback( + BOOL success, + LLViewerFetchedTexture *src_vi, + LLImageRaw* src, + LLImageRaw* src_aux, + S32 discard_level, + BOOL final, + void* userdata ) { LLModelPreview* preview = (LLModelPreview*) userdata; preview->refresh(); @@ -4517,4 +4557,12 @@ void LLFloaterModelPreview::setPermissonsErrorStatus(S32 status, const std::stri LLNotificationsUtil::add("MeshUploadPermError"); } +bool LLFloaterModelPreview::isModelLoading() +{ + if(mModelPreview) + { + return mModelPreview->mLoading; + } + return false; +} diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index a73ca502608fb89cd35384252229278c53a06b04..0b2b7db2b6757b0288d2157c01bf35500976b2b4 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -115,6 +115,8 @@ class LLFloaterModelPreview : public LLFloaterModelUploadBase void enableViewOption(const std::string& option); void disableViewOption(const std::string& option); + bool isModelLoading(); + // shows warning message if agent has no permissions to upload model /*virtual*/ void onPermissionsReceived(const LLSD& result); @@ -260,6 +262,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex virtual BOOL needsRender() { return mNeedsUpdate; } void setPreviewLOD(S32 lod); void clearModel(S32 lod); + void getJointAliases(JointMap& joint_map); void loadModel(std::string filename, S32 lod, bool force_disable_slm = false); void loadModelCallback(S32 lod); bool lodsReady() { return !mGenLOD && mLodsQuery.empty(); } @@ -269,8 +272,8 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex void restoreNormals(); U32 calcResourceCost(); void rebuildUploadData(); - void saveUploadData(bool save_skinweights, bool save_joint_poisitions); - void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions); + void saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position); + void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position); void clearIncompatible(S32 lod); void updateStatusMessages(); void updateLodControls(S32 lod); @@ -300,13 +303,10 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex void setLoadState( U32 state ) { mLoadState = state; } U32 getLoadState() { return mLoadState; } - void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } - const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } - LLVector3 getTranslationForJointOffset( std::string joint ); - static bool sIgnoreLoadedCallback; std::vector<S32> mLodsQuery; + std::vector<S32> mLodsWithParsingError; protected: @@ -352,7 +352,6 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex bool mLoading; U32 mLoadState; bool mResetJoints; - bool mRigParityWithScene; bool mModelNoErrors; std::map<std::string, bool> mViewOption; @@ -410,7 +409,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex bool mLastJointUpdate; - JointSet mJointsFromNode; + JointNameSet mJointsFromNode; JointTransformMap mJointTransformMap; LLPointer<LLVOAvatar> mPreviewAvatar; diff --git a/indra/newview/llfloatermodeluploadbase.cpp b/indra/newview/llfloatermodeluploadbase.cpp index 0fe97fd610f9b41579f09906c2e3325772aa734e..7cdfd56d9ab86e165458aaf22ea14fe1fb8a1c2c 100644 --- a/indra/newview/llfloatermodeluploadbase.cpp +++ b/indra/newview/llfloatermodeluploadbase.cpp @@ -80,6 +80,7 @@ void LLFloaterModelUploadBase::requestAgentUploadPermissionsCoro(std::string url if (!observer) { LL_WARNS("MeshUploadFlag") << "Unable to get observer after call to '" << url << "' aborting." << LL_ENDL; + return; } if (!status) diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp index 4a5732aecfed578cf0ab0f6d72a16d2f38274b99..c9a689281ea9bc1d2c56264fdd1070f6fa606886 100644 --- a/indra/newview/llfloaternamedesc.cpp +++ b/indra/newview/llfloaternamedesc.cpp @@ -123,7 +123,7 @@ BOOL LLFloaterNameDesc::postBuild() // Cancel button getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnCancel, this)); - getChild<LLUICtrl>("ok_btn")->setLabelArg("[AMOUNT]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() )); + getChild<LLUICtrl>("ok_btn")->setLabelArg("[AMOUNT]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload() )); setDefaultBtn("ok_btn"); @@ -162,7 +162,7 @@ void LLFloaterNameDesc::onBtnOK( ) getChildView("ok_btn")->setEnabled(FALSE); // don't allow inadvertent extra uploads LLAssetStorage::LLStoreAssetCallback callback = NULL; - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). if (can_afford_transaction(expected_upload_cost)) { diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp index feaeef4ad0d35385cfae3a1cb535bb9e53ba5371..ed1ad4426f3599b976daef0d961bc4c696f3de7c 100644 --- a/indra/newview/llfloaterobjectweights.cpp +++ b/indra/newview/llfloaterobjectweights.cpp @@ -145,6 +145,14 @@ void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel) { S32 rezzed_prims = parcel->getSimWidePrimCount(); S32 total_capacity = parcel->getSimWideMaxPrimCapacity(); + // Can't have more than region max tasks, regardless of parcel + // object bonus factor. + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + if (region) + { + S32 max_tasks_per_region = (S32)region->getMaxTasks(); + total_capacity = llmin(total_capacity, max_tasks_per_region); + } mRezzedOnLand->setText(llformat("%d", rezzed_prims)); mRemainingCapacity->setText(llformat("%d", total_capacity - rezzed_prims)); diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index ef746d308db8c3550b92fdf713d76ef81d4e1e9c..2a1749bd42bd872394a3bef23b48eb4bc9b82aa0 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -39,7 +39,6 @@ #include "lltextbox.h" #include "llinventorybridge.h" -#include "llfloaterinventory.h" #include "llinventorymodel.h" #include "llinventorypanel.h" #include "llpanelobjectinventory.h" diff --git a/indra/newview/llfloateroutfitphotopreview.cpp b/indra/newview/llfloateroutfitphotopreview.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6c39db730c33c40b0f86a3d0a2661d6a9c24368f --- /dev/null +++ b/indra/newview/llfloateroutfitphotopreview.cpp @@ -0,0 +1,289 @@ +/** + * @file llfloateroutfitphotopreview.cpp + * @brief LLFloaterOutfitPhotoPreview 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$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwindow.h" + +#include "llfloateroutfitphotopreview.h" + +#include "llagent.h" +#include "llappearancemgr.h" +#include "llbutton.h" +#include "llcombobox.h" +#include "llfilepicker.h" +#include "llfloaterreg.h" +#include "llimagetga.h" +#include "llimagepng.h" +#include "llinventory.h" +#include "llinventorymodel.h" +#include "llnotificationsutil.h" +#include "llresmgr.h" +#include "lltrans.h" +#include "lltextbox.h" +#include "lltextureview.h" +#include "llui.h" +#include "llviewerinventory.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" +#include "lluictrlfactory.h" +#include "llviewerwindow.h" +#include "lllineeditor.h" + +const S32 MAX_OUTFIT_PHOTO_WIDTH = 256; +const S32 MAX_OUTFIT_PHOTO_HEIGHT = 256; + +const S32 CLIENT_RECT_VPAD = 4; + +LLFloaterOutfitPhotoPreview::LLFloaterOutfitPhotoPreview(const LLSD& key) + : LLPreview(key), + mUpdateDimensions(TRUE), + mImage(NULL), + mOutfitID(LLUUID()), + mImageOldBoostLevel(LLGLTexture::BOOST_NONE), + mExceedLimits(FALSE) +{ + updateImageID(); +} + +LLFloaterOutfitPhotoPreview::~LLFloaterOutfitPhotoPreview() +{ + LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; + + if (mImage.notNull()) + { + mImage->setBoostLevel(mImageOldBoostLevel); + mImage = NULL; + } +} + +// virtual +BOOL LLFloaterOutfitPhotoPreview::postBuild() +{ + getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterOutfitPhotoPreview::onOkBtn, this)); + getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterOutfitPhotoPreview::onCancelBtn, this)); + + return LLPreview::postBuild(); +} + +void LLFloaterOutfitPhotoPreview::draw() +{ + updateDimensions(); + + LLPreview::draw(); + + if (!isMinimized()) + { + LLGLSUIDefault gls_ui; + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + const LLRect& border = mClientRect; + LLRect interior = mClientRect; + interior.stretch( -PREVIEW_BORDER_WIDTH ); + + // ...border + gl_rect_2d( border, LLColor4(0.f, 0.f, 0.f, 1.f)); + gl_rect_2d_checkerboard( interior ); + + if ( mImage.notNull() ) + { + // Draw the texture + gGL.diffuseColor3f( 1.f, 1.f, 1.f ); + gl_draw_scaled_image(interior.mLeft, + interior.mBottom, + interior.getWidth(), + interior.getHeight(), + mImage); + + // Pump the texture priority + F32 pixel_area = (F32)(interior.getWidth() * interior.getHeight() ); + mImage->addTextureStats( pixel_area ); + + S32 int_width = interior.getWidth(); + S32 int_height = interior.getHeight(); + mImage->setKnownDrawSize(int_width, int_height); + } + } + +} + +// virtual +void LLFloaterOutfitPhotoPreview::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLPreview::reshape(width, height, called_from_parent); + + LLRect dim_rect(getChildView("dimensions")->getRect()); + + S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE; + + S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD; + + LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0); + client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD); + client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ; + + S32 client_width = client_rect.getWidth(); + S32 client_height = client_width; + + if(client_height > client_rect.getHeight()) + { + client_height = client_rect.getHeight(); + client_width = client_height; + } + mClientRect.setLeftTopAndSize(client_rect.getCenterX() - (client_width / 2), client_rect.getCenterY() + (client_height / 2), client_width, client_height); + +} + + +void LLFloaterOutfitPhotoPreview::updateDimensions() +{ + if (!mImage) + { + return; + } + if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0) + { + return; + } + + if (mAssetStatus != PREVIEW_ASSET_LOADED) + { + mAssetStatus = PREVIEW_ASSET_LOADED; + mUpdateDimensions = TRUE; + } + + getChild<LLUICtrl>("dimensions")->setTextArg("[WIDTH]", llformat("%d", mImage->getFullWidth())); + getChild<LLUICtrl>("dimensions")->setTextArg("[HEIGHT]", llformat("%d", mImage->getFullHeight())); + + if ((mImage->getFullWidth() <= MAX_OUTFIT_PHOTO_WIDTH) && (mImage->getFullHeight() <= MAX_OUTFIT_PHOTO_HEIGHT)) + { + getChild<LLButton>("ok_btn")->setEnabled(TRUE); + mExceedLimits = FALSE; + } + else + { + mExceedLimits = TRUE; + LLStringUtil::format_map_t args; + args["MAX_WIDTH"] = llformat("%d", MAX_OUTFIT_PHOTO_WIDTH); + args["MAX_HEIGHT"] = llformat("%d", MAX_OUTFIT_PHOTO_HEIGHT); + std::string label = getString("exceed_limits", args); + getChild<LLUICtrl>("notification")->setValue(label); + getChild<LLUICtrl>("notification")->setColor(LLColor4::yellow); + getChild<LLButton>("ok_btn")->setEnabled(FALSE); + } + + if (mUpdateDimensions) + { + mUpdateDimensions = FALSE; + + reshape(getRect().getWidth(), getRect().getHeight()); + gFloaterView->adjustToFitScreen(this, FALSE); + } +} + +void LLFloaterOutfitPhotoPreview::loadAsset() +{ + if (mImage.notNull()) + { + mImage->setBoostLevel(mImageOldBoostLevel); + } + mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mImageOldBoostLevel = mImage->getBoostLevel(); + mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + mImage->forceToSaveRawImage(0) ; + mAssetStatus = PREVIEW_ASSET_LOADING; + mUpdateDimensions = TRUE; + updateDimensions(); +} + +LLPreview::EAssetStatus LLFloaterOutfitPhotoPreview::getAssetStatus() +{ + if (mImage.notNull() && (mImage->getFullWidth() * mImage->getFullHeight() > 0)) + { + mAssetStatus = PREVIEW_ASSET_LOADED; + } + return mAssetStatus; +} + +void LLFloaterOutfitPhotoPreview::updateImageID() +{ + const LLViewerInventoryItem *item = static_cast<const LLViewerInventoryItem*>(getItem()); + if(item) + { + mImageID = item->getAssetUUID(); + LLPermissions perm(item->getPermissions()); + } + else + { + mImageID = mItemUUID; + } + +} + +/* virtual */ +void LLFloaterOutfitPhotoPreview::setObjectID(const LLUUID& object_id) +{ + mObjectUUID = object_id; + + const LLUUID old_image_id = mImageID; + + updateImageID(); + if (mImageID != old_image_id) + { + mAssetStatus = PREVIEW_ASSET_UNLOADED; + loadAsset(); + } + refreshFromItem(); +} + +void LLFloaterOutfitPhotoPreview::setOutfitID(const LLUUID& outfit_id) +{ + mOutfitID = outfit_id; + LLViewerInventoryCategory* outfit_folder = gInventory.getCategory(mOutfitID); + if(outfit_folder && !mExceedLimits) + { + getChild<LLUICtrl>("notification")->setValue( getString("photo_confirmation")); + getChild<LLUICtrl>("notification")->setTextArg("[OUTFIT]", outfit_folder->getName()); + getChild<LLUICtrl>("notification")->setColor(LLColor4::white); + } + +} + +void LLFloaterOutfitPhotoPreview::onOkBtn() +{ + if(mOutfitID.notNull() && getItem()) + { + LLAppearanceMgr::instance().removeOutfitPhoto(mOutfitID); + LLPointer<LLInventoryCallback> cb = NULL; + link_inventory_object(mOutfitID, LLConstPointer<LLInventoryObject>(getItem()), cb); + } + closeFloater(); +} + +void LLFloaterOutfitPhotoPreview::onCancelBtn() +{ + closeFloater(); +} diff --git a/indra/newview/llfloateroutfitphotopreview.h b/indra/newview/llfloateroutfitphotopreview.h new file mode 100644 index 0000000000000000000000000000000000000000..a1e7b58abe613ab0445753ec249fa5f1670da1a1 --- /dev/null +++ b/indra/newview/llfloateroutfitphotopreview.h @@ -0,0 +1,77 @@ +/** + * @file llfloateroutfitphotopreview.h + * @brief LLFloaterOutfitPhotoPreview 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$ + */ + +#ifndef LL_LLFLOATEROUTFITPHOTOPREVIEW_H +#define LL_LLFLOATEROUTFITPHOTOPREVIEW_H + +#include "llpreview.h" +#include "llbutton.h" +#include "llframetimer.h" +#include "llviewertexture.h" + +class LLComboBox; +class LLImageRaw; + +class LLFloaterOutfitPhotoPreview : public LLPreview +{ +public: + LLFloaterOutfitPhotoPreview(const LLSD& key); + ~LLFloaterOutfitPhotoPreview(); + + virtual void draw(); + + virtual void loadAsset(); + virtual EAssetStatus getAssetStatus(); + + virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + + /*virtual*/ void setObjectID(const LLUUID& object_id); + + void setOutfitID(const LLUUID& outfit_id); + void onOkBtn(); + void onCancelBtn(); + +protected: + void init(); + /* virtual */ BOOL postBuild(); + +private: + void updateImageID(); // set what image is being uploaded. + void updateDimensions(); + LLUUID mImageID; + LLUUID mOutfitID; + LLPointer<LLViewerFetchedTexture> mImage; + S32 mImageOldBoostLevel; + + // This is stored off in a member variable, because the save-as + // button and drag and drop functionality need to know. + BOOL mUpdateDimensions; + + BOOL mExceedLimits; + + LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ; +}; +#endif // LL_LLFLOATEROUTFITPHOTOPREVIEW_H diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d80793f9e4286ad707ab79bfaa1e6ff1af0b43b4 --- /dev/null +++ b/indra/newview/llfloateroutfitsnapshot.cpp @@ -0,0 +1,377 @@ +/** + * @file llfloateroutfitsnapshot.cpp + * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2016, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 "llfloatersnapshot.h" +#include "llfloateroutfitsnapshot.h" + +#include "llagent.h" +#include "llfacebookconnect.h" +#include "llfloaterreg.h" +#include "llfloaterfacebook.h" +#include "llfloaterflickr.h" +#include "llfloatertwitter.h" +#include "llimagefiltersmanager.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llpostcard.h" +#include "llresmgr.h" // LLLocale +#include "llsdserialize.h" +#include "llsidetraypanelcontainer.h" +#include "llspinctrl.h" +#include "llviewercontrol.h" +#include "lltoolfocus.h" +#include "lltoolmgr.h" +#include "llwebprofile.h" + +///---------------------------------------------------------------------------- +/// Local function declarations, constants, enums, and typedefs +///---------------------------------------------------------------------------- +LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL; + +const S32 OUTFIT_SNAPSHOT_WIDTH = 256; +const S32 OUTFIT_SNAPSHOT_HEIGHT = 256; + +static LLDefaultChildRegistry::Register<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view"); + +///---------------------------------------------------------------------------- +/// Class LLFloaterOutfitSnapshot::Impl +///---------------------------------------------------------------------------- + +// virtual +LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found) +{ + LLPanel* panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory"); + LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel); + if (!ok_if_not_found) + { + llassert_always(active_panel != NULL); + } + return active_panel; +} + +// virtual +LLSnapshotModel::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater) +{ + return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; +} + +// virtual +LLSnapshotModel::ESnapshotLayerType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater) +{ + return LLSnapshotModel::SNAPSHOT_TYPE_COLOR; +} + +// This is the main function that keeps all the GUI controls in sync with the saved settings. +// It should be called anytime a setting is changed that could affect the controls. +// No other methods should be changing any of the controls directly except for helpers called by this method. +// The basic pattern for programmatically changing the GUI settings is to first set the +// appropriate saved settings and then call this method to sync the GUI with them. +// FIXME: The above comment seems obsolete now. +// virtual +void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater) +{ + LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater); + LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); + LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater); + + LLSnapshotLivePreview* previewp = getPreviewView(); + BOOL got_snap = previewp && previewp->getSnapshotUpToDate(); + + // *TODO: Separate maximum size for Web images from postcards + LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL; + + LLLocale locale(LLLocale::USER_LOCALE); + std::string bytes_string; + if (got_snap) + { + LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10); + } + + // Update displayed image resolution. + LLTextBox* image_res_tb = floater->getChild<LLTextBox>("image_res_text"); + image_res_tb->setVisible(got_snap); + if (got_snap) + { + image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth())); + image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight())); + } + + floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown")); + floater->getChild<LLUICtrl>("file_size_label")->setColor(LLUIColorTable::instance().getColor("LabelTextColor")); + + updateResolution(floater); + + if (previewp) + { + previewp->setSnapshotType(shot_type); + previewp->setSnapshotFormat(shot_format); + previewp->setSnapshotBufferType(layer_type); + } + + LLPanelSnapshot* current_panel = Impl::getActivePanel(floater); + if (current_panel) + { + LLSD info; + info["have-snapshot"] = got_snap; + current_panel->updateControls(info); + } + LL_DEBUGS() << "finished updating controls" << LL_ENDL; +} + +// virtual +std::string LLFloaterOutfitSnapshot::Impl::getSnapshotPanelPrefix() +{ + return "panel_outfit_snapshot_"; +} + +// Show/hide upload status message. +// virtual +void LLFloaterOutfitSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg) +{ + mFloater->setSuccessLabelPanelVisible(finished && ok); + mFloater->setFailureLabelPanelVisible(finished && !ok); + + if (finished) + { + LLUICtrl* finished_lbl = mFloater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl"); + std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str")); + finished_lbl->setValue(result_text); + + LLPanel* snapshot_panel = mFloater->getChild<LLPanel>("panel_outfit_snapshot_inventory"); + snapshot_panel->onOpen(LLSD()); + } +} + +void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data) +{ + LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data; + + if (!view) + { + llassert(view); + return; + } + + S32 width = OUTFIT_SNAPSHOT_WIDTH; + S32 height = OUTFIT_SNAPSHOT_HEIGHT; + + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) + { + S32 original_width = 0, original_height = 0; + previewp->getSize(original_width, original_height); + + if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot")) + { //clamp snapshot resolution to window size when showing UI or HUD in snapshot + width = llmin(width, gViewerWindow->getWindowWidthRaw()); + height = llmin(height, gViewerWindow->getWindowHeightRaw()); + } + + + llassert(width > 0 && height > 0); + + // use the resolution from the selected pre-canned drop-down choice + LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL; + previewp->setSize(width, height); + + if (original_width != width || original_height != height) + { + // hide old preview as the aspect ratio could be wrong + checkAutoSnapshot(previewp, FALSE); + LL_DEBUGS() << "updating thumbnail" << LL_ENDL; + previewp->updateSnapshot(TRUE); + } + } +} + +///---------------------------------------------------------------------------- +/// Class LLFloaterOutfitSnapshot +///---------------------------------------------------------------------------- + +// Default constructor +LLFloaterOutfitSnapshot::LLFloaterOutfitSnapshot(const LLSD& key) +: LLFloaterSnapshotBase(key), +mOutfitGallery(NULL) +{ + impl = new Impl(this); +} + +LLFloaterOutfitSnapshot::~LLFloaterOutfitSnapshot() +{ +} + +// virtual +BOOL LLFloaterOutfitSnapshot::postBuild() +{ + mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn"); + childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); + mRefreshLabel = getChild<LLUICtrl>("refresh_lbl"); + mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel"); + mFailureLblPanel = getChild<LLUICtrl>("failed_panel"); + + childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this); + getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot")); + + childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this); + getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot")); + + getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame")); + childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this); + + getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot")); + childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this); + + getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this)); + getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this)); + + // Filters + LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox"); + std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList(); + for (U32 i = 0; i < filter_list.size(); i++) + { + filterbox->add(filter_list[i]); + } + childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this); + + mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder"); + + // create preview window + LLRect full_screen_rect = getRootView()->getRect(); + LLSnapshotLivePreview::Params p; + p.rect(full_screen_rect); + LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); + LLView* parent_view = gSnapshotFloaterView->getParent(); + + parent_view->removeChild(gSnapshotFloaterView); + // make sure preview is below snapshot floater + parent_view->addChild(previewp); + parent_view->addChild(gSnapshotFloaterView); + + //move snapshot floater to special purpose snapshotfloaterview + gFloaterView->removeChild(this); + gSnapshotFloaterView->addChild(this); + + impl->mPreviewHandle = previewp->getHandle(); + previewp->setContainer(this); + impl->updateControls(this); + impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); + impl->updateLayout(this); + + previewp->mKeepAspectRatio = FALSE; + previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect()); + + return TRUE; +} + +// virtual +void LLFloaterOutfitSnapshot::onOpen(const LLSD& key) +{ + LLSnapshotLivePreview* preview = getPreviewView(); + if (preview) + { + LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL; + preview->updateSnapshot(TRUE); + } + focusFirstItem(FALSE); + gSnapshotFloaterView->setEnabled(TRUE); + gSnapshotFloaterView->setVisible(TRUE); + gSnapshotFloaterView->adjustToFitScreen(this, FALSE); + + impl->updateControls(this); + impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); + impl->updateLayout(this); + + LLPanel* snapshot_panel = getChild<LLPanel>("panel_outfit_snapshot_inventory"); + snapshot_panel->onOpen(LLSD()); + postPanelSwitch(); + +} + +void LLFloaterOutfitSnapshot::onExtendFloater() +{ + impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); +} + +// static +void LLFloaterOutfitSnapshot::update() +{ + LLFloaterOutfitSnapshot* inst = findInstance(); + if (inst != NULL) + { + inst->impl->updateLivePreview(); + } +} + + +// static +LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance() +{ + return LLFloaterReg::findTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot"); +} + +// static +LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance() +{ + return LLFloaterReg::getTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot"); +} + +// virtual +void LLFloaterOutfitSnapshot::saveTexture() +{ + LL_DEBUGS() << "saveTexture" << LL_ENDL; + + LLSnapshotLivePreview* previewp = getPreviewView(); + if (!previewp) + { + llassert(previewp != NULL); + return; + } + + if (mOutfitGallery) + { + mOutfitGallery->onBeforeOutfitSnapshotSave(); + } + previewp->saveTexture(TRUE, getOutfitID().asString()); + if (mOutfitGallery) + { + mOutfitGallery->onAfterOutfitSnapshotSave(); + } + closeFloater(); +} + +///---------------------------------------------------------------------------- +/// Class LLOutfitSnapshotFloaterView +///---------------------------------------------------------------------------- + +LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p) +{ +} + +LLOutfitSnapshotFloaterView::~LLOutfitSnapshotFloaterView() +{ +} diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h new file mode 100644 index 0000000000000000000000000000000000000000..bee386ec63bb70ca29708b62375367e048880213 --- /dev/null +++ b/indra/newview/llfloateroutfitsnapshot.h @@ -0,0 +1,123 @@ +/** + * @file llfloateroutfitsnapshot.h + * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2016, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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_LLFLOATEROUTFITSNAPSHOT_H +#define LL_LLFLOATEROUTFITSNAPSHOT_H + +#include "llfloater.h" +#include "llfloatersnapshot.h" +#include "lloutfitgallery.h" +#include "llsnapshotlivepreview.h" + +///---------------------------------------------------------------------------- +/// Class LLFloaterOutfitSnapshot +///---------------------------------------------------------------------------- + +class LLFloaterOutfitSnapshot : public LLFloaterSnapshotBase +{ + LOG_CLASS(LLFloaterOutfitSnapshot); + +public: + + LLFloaterOutfitSnapshot(const LLSD& key); + /*virtual*/ ~LLFloaterOutfitSnapshot(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + + static void update(); + + void onExtendFloater(); + + static LLFloaterOutfitSnapshot* getInstance(); + static LLFloaterOutfitSnapshot* findInstance(); + /*virtual*/ void saveTexture(); + + const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } + + void setOutfitID(LLUUID id) { mOutfitID = id; } + LLUUID getOutfitID() { return mOutfitID; } + void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } + + class Impl; + friend class Impl; +private: + + LLUUID mOutfitID; + LLOutfitGallery* mOutfitGallery; +}; + +///---------------------------------------------------------------------------- +/// Class LLFloaterOutfitSnapshot::Impl +///---------------------------------------------------------------------------- + +class LLFloaterOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase +{ + LOG_CLASS(LLFloaterOutfitSnapshot::Impl); +public: + Impl(LLFloaterSnapshotBase* floater) + : LLFloaterSnapshotBase::ImplBase(floater) + {} + ~Impl() + {} + void updateResolution(void* data); + + static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status); + + /*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true); + /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater); + /*virtual*/ std::string getSnapshotPanelPrefix(); + + /*virtual*/ void updateControls(LLFloaterSnapshotBase* floater); + +private: + /*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater); + /*virtual*/ void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null); +}; + +///---------------------------------------------------------------------------- +/// Class LLOutfitSnapshotFloaterView +///---------------------------------------------------------------------------- + +class LLOutfitSnapshotFloaterView : public LLFloaterView +{ +public: + struct Params + : public LLInitParam::Block<Params, LLFloaterView::Params> + { + }; + +protected: + LLOutfitSnapshotFloaterView(const Params& p); + friend class LLUICtrlFactory; + +public: + virtual ~LLOutfitSnapshotFloaterView(); +}; + +extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView; + +#endif // LL_LLFLOATEROUTFITSNAPSHOT_H diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp index 31245db34450f97bff6bf04f9556b4bbf68ec4d1..87973c2286e3863051eaccadfd18ef49649741b9 100644 --- a/indra/newview/llfloaterpay.cpp +++ b/indra/newview/llfloaterpay.cpp @@ -72,6 +72,8 @@ struct LLGiveMoneyInfo mFloater(floater), mAmount(amount){} }; +typedef boost::shared_ptr<LLGiveMoneyInfo> give_money_ptr; + ///---------------------------------------------------------------------------- /// Class LLFloaterPay ///---------------------------------------------------------------------------- @@ -94,18 +96,18 @@ class LLFloaterPay : public LLFloater bool is_group); static bool payConfirmationCallback(const LLSD& notification, const LLSD& response, - LLGiveMoneyInfo* info); + give_money_ptr info); private: static void onCancel(void* data); static void onKeystroke(LLLineEditor* editor, void* data); - static void onGive(void* data); + static void onGive(give_money_ptr info); void give(S32 amount); static void processPayPriceReply(LLMessageSystem* msg, void **userdata); void finishPayUI(const LLUUID& target_id, BOOL is_group); protected: - std::vector<LLGiveMoneyInfo*> mCallbackData; + std::vector<give_money_ptr> mCallbackData; money_callback mCallback; LLTextBox* mObjectNameText; LLUUID mTargetUUID; @@ -113,7 +115,7 @@ class LLFloaterPay : public LLFloater BOOL mHaveName; LLButton* mQuickPayButton[MAX_PAY_BUTTONS]; - LLGiveMoneyInfo* mQuickPayInfo[MAX_PAY_BUTTONS]; + give_money_ptr mQuickPayInfo[MAX_PAY_BUTTONS]; LLSafeHandle<LLObjectSelection> mObjectSelection; }; @@ -136,7 +138,11 @@ LLFloaterPay::LLFloaterPay(const LLSD& key) // Destroys the object LLFloaterPay::~LLFloaterPay() { - std::for_each(mCallbackData.begin(), mCallbackData.end(), DeletePointer()); + std::vector<give_money_ptr>::iterator iter; + for (iter = mCallbackData.begin(); iter != mCallbackData.end(); ++iter) + { + (*iter)->mFloater = NULL; + } mCallbackData.clear(); // Name callbacks will be automatically disconnected since LLFloater is trackable @@ -148,40 +154,40 @@ BOOL LLFloaterPay::postBuild() { S32 i = 0; - LLGiveMoneyInfo* info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_0); + give_money_ptr info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_0)); mCallbackData.push_back(info); - childSetAction("fastpay 1",&LLFloaterPay::onGive,info); + childSetAction("fastpay 1", boost::bind(LLFloaterPay::onGive, info)); getChildView("fastpay 1")->setVisible(FALSE); mQuickPayButton[i] = getChild<LLButton>("fastpay 1"); mQuickPayInfo[i] = info; ++i; - info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_1); + info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_1)); mCallbackData.push_back(info); - childSetAction("fastpay 5",&LLFloaterPay::onGive,info); + childSetAction("fastpay 5", boost::bind(LLFloaterPay::onGive, info)); getChildView("fastpay 5")->setVisible(FALSE); mQuickPayButton[i] = getChild<LLButton>("fastpay 5"); mQuickPayInfo[i] = info; ++i; - info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_2); + info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_2)); mCallbackData.push_back(info); - childSetAction("fastpay 10",&LLFloaterPay::onGive,info); + childSetAction("fastpay 10", boost::bind(LLFloaterPay::onGive, info)); getChildView("fastpay 10")->setVisible(FALSE); mQuickPayButton[i] = getChild<LLButton>("fastpay 10"); mQuickPayInfo[i] = info; ++i; - info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_3); + info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_3)); mCallbackData.push_back(info); - childSetAction("fastpay 20",&LLFloaterPay::onGive,info); + childSetAction("fastpay 20", boost::bind(LLFloaterPay::onGive, info)); getChildView("fastpay 20")->setVisible(FALSE); mQuickPayButton[i] = getChild<LLButton>("fastpay 20"); @@ -195,10 +201,10 @@ BOOL LLFloaterPay::postBuild() getChild<LLLineEditor>("amount")->setKeystrokeCallback(&LLFloaterPay::onKeystroke, this); getChild<LLLineEditor>("amount")->setPrevalidate(LLTextValidate::validateNonNegativeS32); - info = new LLGiveMoneyInfo(this, 0); + info = give_money_ptr(new LLGiveMoneyInfo(this, 0)); mCallbackData.push_back(info); - childSetAction("pay btn",&LLFloaterPay::onGive,info); + childSetAction("pay btn", boost::bind(LLFloaterPay::onGive, info)); setDefaultBtn("pay btn"); getChildView("pay btn")->setVisible(FALSE); getChildView("pay btn")->setEnabled(FALSE); @@ -278,7 +284,6 @@ void LLFloaterPay::processPayPriceReply(LLMessageSystem* msg, void **userdata) self->mQuickPayButton[i]->setLabelUnselected(button_str); self->mQuickPayButton[i]->setVisible(TRUE); self->mQuickPayInfo[i]->mAmount = pay_button; - self->getChildView("fastpay text")->setVisible(TRUE); if ( pay_button > max_pay_amount ) { @@ -406,7 +411,6 @@ void LLFloaterPay::payDirectly(money_callback callback, floater->getChildView("pay btn")->setVisible(TRUE); floater->getChildView("amount text")->setVisible(TRUE); - floater->getChildView("fastpay text")->setVisible(TRUE); for(S32 i=0;i<MAX_PAY_BUTTONS;++i) { floater->mQuickPayButton[i]->setVisible(TRUE); @@ -415,9 +419,9 @@ void LLFloaterPay::payDirectly(money_callback callback, floater->finishPayUI(target_id, is_group); } -bool LLFloaterPay::payConfirmationCallback(const LLSD& notification, const LLSD& response, LLGiveMoneyInfo* info) +bool LLFloaterPay::payConfirmationCallback(const LLSD& notification, const LLSD& response, give_money_ptr info) { - if (!info || !info->mFloater) + if (!info.get() || !info->mFloater) { return false; } @@ -479,54 +483,61 @@ void LLFloaterPay::onKeystroke(LLLineEditor*, void* data) } // static -void LLFloaterPay::onGive(void* data) +void LLFloaterPay::onGive(give_money_ptr info) { - LLGiveMoneyInfo* info = reinterpret_cast<LLGiveMoneyInfo*>(data); - LLFloaterPay* floater = info->mFloater; - if(info && floater) - { - S32 amount = info->mAmount; - if(amount == 0) - { - amount = atoi(floater->getChild<LLUICtrl>("amount")->getValue().asString().c_str()); - } - if (amount > PAY_AMOUNT_NOTIFICATION && gStatusBar && gStatusBar->getBalance() > amount) - { - LLUUID payee_id = LLUUID::null; - BOOL is_group = false; - if (floater->mObjectSelection.notNull()) - { - LLSelectNode* node = floater->mObjectSelection->getFirstRootNode(); - if (node) - { - node->mPermissions->getOwnership(payee_id, is_group); - } - else - { - // object no longer exists - LLNotificationsUtil::add("PayObjectFailed"); - floater->closeFloater(); - return; - } - } - else - { - is_group = floater->mTargetIsGroup; - payee_id = floater->mTargetUUID; - } - - LLSD args; - args["TARGET"] = LLSLURL( is_group ? "group" : "agent", payee_id, "completename").getSLURLString(); - args["AMOUNT"] = amount; - - LLNotificationsUtil::add("PayConfirmation", args, LLSD(), boost::bind(&LLFloaterPay::payConfirmationCallback, _1, _2, info)); - } - else - { - floater->give(amount); - floater->closeFloater(); - } - } + if (!info.get() || !info->mFloater) + { + return; + } + + LLFloaterPay* floater = info->mFloater; + S32 amount = info->mAmount; + if (amount == 0) + { + LLUICtrl* text_field = floater->getChild<LLUICtrl>("amount"); + if (!text_field) + { + return; + } + amount = atoi(text_field->getValue().asString().c_str()); + } + + if (amount > PAY_AMOUNT_NOTIFICATION && gStatusBar && gStatusBar->getBalance() > amount) + { + LLUUID payee_id = LLUUID::null; + BOOL is_group = false; + if (floater->mObjectSelection.notNull()) + { + LLSelectNode* node = floater->mObjectSelection->getFirstRootNode(); + if (node) + { + node->mPermissions->getOwnership(payee_id, is_group); + } + else + { + // object no longer exists + LLNotificationsUtil::add("PayObjectFailed"); + floater->closeFloater(); + return; + } + } + else + { + is_group = floater->mTargetIsGroup; + payee_id = floater->mTargetUUID; + } + + LLSD args; + args["TARGET"] = LLSLURL(is_group ? "group" : "agent", payee_id, "completename").getSLURLString(); + args["AMOUNT"] = amount; + + LLNotificationsUtil::add("PayConfirmation", args, LLSD(), boost::bind(&LLFloaterPay::payConfirmationCallback, _1, _2, info)); + } + else + { + floater->give(amount); + floater->closeFloater(); + } } void LLFloaterPay::give(S32 amount) @@ -581,7 +592,8 @@ void LLFloaterPay::give(S32 amount) else { // just transfer the L$ - mCallback(mTargetUUID, gAgent.getRegion(), amount, mTargetIsGroup, TRANS_GIFT, LLStringUtil::null); + std::string paymentMessage(getChild<LLLineEditor>("payment_message")->getValue().asString()); + mCallback(mTargetUUID, gAgent.getRegion(), amount, mTargetIsGroup, TRANS_GIFT, (paymentMessage.empty() ? LLStringUtil::null : paymentMessage)); // check if the payee needs to be unmuted LLMuteList::getInstance()->autoRemove(mTargetUUID, LLMuteList::AR_MONEY); diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp index b0b2770c6eef6c90a284cd80262f1ca145a5941d..2281ea1496b4093646758f914a42aa791e53c702 100644 --- a/indra/newview/llfloaterperms.cpp +++ b/indra/newview/llfloaterperms.cpp @@ -183,6 +183,11 @@ void LLFloaterPermsDefault::sendInitialPerms() void LLFloaterPermsDefault::updateCap() { + if (!gAgent.getRegion()) + { + LL_WARNS("Avatar") << "Region not set, cannot request capability update" << LL_ENDL; + return; + } std::string object_url = gAgent.getRegion()->getCapability("AgentPreferences"); if(!object_url.empty()) diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 36bdcf4d897e89472aad099de8f94e58749df189..100ee5ab72dd49cb3a64a5fb01dcd12276794586 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1232,6 +1232,9 @@ void LLFloaterPreference::refreshEnabledState() (ctrl_wind_light->get()) ? TRUE : FALSE; ctrl_deferred->setEnabled(enabled); + + // Cannot have floater active until caps have been received + getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true); } void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() @@ -1250,7 +1253,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny"); bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump"); bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE); - + // Avatar Mode // Enable Avatar Shaders LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram"); @@ -1369,9 +1372,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() disableUnavailableSettings(); getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess()); - - // Cannot have floater active until caps have been received - getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true); } // static @@ -1411,7 +1411,7 @@ void LLAvatarComplexityControls::setIndirectMaxArc() else { // This is the inverse of the calculation in updateMaxComplexity - indirect_max_arc = (U32)((log(max_arc) - MIN_ARC_LOG) / ARC_LIMIT_MAP_SCALE) + MIN_INDIRECT_ARC_LIMIT; + indirect_max_arc = (U32)ll_round(((log(F32(max_arc)) - MIN_ARC_LOG) / ARC_LIMIT_MAP_SCALE)) + MIN_INDIRECT_ARC_LIMIT; } gSavedSettings.setU32("IndirectMaxComplexity", indirect_max_arc); } @@ -1930,7 +1930,7 @@ void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* valu { // if this is changed, the inverse calculation in setIndirectMaxArc // must be changed to match - max_arc = (U32)exp(MIN_ARC_LOG + (ARC_LIMIT_MAP_SCALE * (indirect_value - MIN_INDIRECT_ARC_LIMIT))); + max_arc = (U32)ll_round(exp(MIN_ARC_LOG + (ARC_LIMIT_MAP_SCALE * (indirect_value - MIN_INDIRECT_ARC_LIMIT)))); } gSavedSettings.setU32("RenderAvatarMaxComplexity", (U32)max_arc); @@ -2004,7 +2004,7 @@ void LLFloaterPreference::onClickAutoReplace() void LLFloaterPreference::onClickSpellChecker() { - LLFloaterReg::showInstance("prefs_spellchecker"); + LLFloaterReg::showInstance("prefs_spellchecker"); } void LLFloaterPreference::onClickAdvanced() diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index ed6f4ede9f4a6e86ab9abd4090b056f0e36858ac..275554540e587f533e9889e56cc5765b97e4fe29 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -37,6 +37,7 @@ #include "llcachename.h" #include "llcheckboxctrl.h" #include "llfontgl.h" +#include "llimagebmp.h" #include "llimagej2c.h" #include "llinventory.h" #include "llnotificationsutil.h" @@ -76,6 +77,7 @@ #include "llselectmgr.h" #include "llversioninfo.h" #include "lluictrlfactory.h" +#include "llviewercontrol.h" #include "llviewernetwork.h" #include "llagentui.h" @@ -86,6 +88,7 @@ #include "llcorehttputil.h" #include "llviewerassetupload.h" +const std::string SCREEN_PREV_FILENAME = "screen_report_last.bmp"; //========================================================================= //----------------------------------------------------------------------------- @@ -181,18 +184,12 @@ BOOL LLFloaterReporter::postBuild() } setPosBox(pos); - // Take a screenshot, but don't draw this floater. - setVisible(FALSE); - takeScreenshot(); - setVisible(TRUE); - // Default text to be blank getChild<LLUICtrl>("object_name")->setValue(LLStringUtil::null); getChild<LLUICtrl>("owner_name")->setValue(LLStringUtil::null); mOwnerName = LLStringUtil::null; getChild<LLUICtrl>("summary_edit")->setFocus(TRUE); - getChild<LLCheckBoxCtrl>("screen_check")->set(TRUE); mDefaultSummary = getChild<LLUICtrl>("details_edit")->getValue().asString(); @@ -246,8 +243,6 @@ LLFloaterReporter::~LLFloaterReporter() // virtual void LLFloaterReporter::draw() { - getChildView("screen_check")->setEnabled(TRUE ); - LLFloater::draw(); } @@ -255,7 +250,6 @@ void LLFloaterReporter::enableControls(BOOL enable) { getChildView("category_combo")->setEnabled(enable); getChildView("chat_check")->setEnabled(enable); - getChildView("screen_check")->setEnabled(enable); getChildView("screenshot")->setEnabled(FALSE); getChildView("pick_btn")->setEnabled(enable); getChildView("summary_edit")->setEnabled(enable); @@ -448,23 +442,15 @@ void LLFloaterReporter::onClickSend(void *userdata) if(!url.empty() || !sshot_url.empty()) { self->sendReportViaCaps(url, sshot_url, self->gatherReport()); + LLNotificationsUtil::add("HelpReportAbuseConfirm"); self->closeFloater(); } else { - if(self->getChild<LLUICtrl>("screen_check")->getValue()) - { - self->getChildView("send_btn")->setEnabled(FALSE); - self->getChildView("cancel_btn")->setEnabled(FALSE); - // the callback from uploading the image calls sendReportViaLegacy() - self->uploadImage(); - } - else - { - self->sendReportViaLegacy(self->gatherReport()); - LLUploadDialog::modalUploadFinished(); - self->closeFloater(); - } + self->getChildView("send_btn")->setEnabled(FALSE); + self->getChildView("cancel_btn")->setEnabled(FALSE); + // the callback from uploading the image calls sendReportViaLegacy() + self->uploadImage(); } } } @@ -524,50 +510,59 @@ void LLFloaterReporter::showFromMenu(EReportType report_type) LL_WARNS() << "Unknown LLViewerReporter type : " << report_type << LL_ENDL; return; } - - LLFloaterReporter* f = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter", LLSD()); - if (f) + LLFloaterReporter* reporter_floater = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); + if(reporter_floater && reporter_floater->isInVisibleChain()) { - f->setReportType(report_type); + gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", FALSE); + } + reporter_floater = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter", LLSD()); + if (reporter_floater) + { + reporter_floater->setReportType(report_type); } } // static void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_name, const LLUUID& experience_id) { - LLFloaterReporter* f = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter"); - + LLFloaterReporter* reporter_floater = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); + if(reporter_floater && reporter_floater->isInVisibleChain()) + { + gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", FALSE); + } + reporter_floater = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter"); if (avatar_name.empty()) { // Request info for this object - f->getObjectInfo(object_id); + reporter_floater->getObjectInfo(object_id); } else { - f->setFromAvatarID(object_id); + reporter_floater->setFromAvatarID(object_id); } if(experience_id.notNull()) { - f->getExperienceInfo(experience_id); + reporter_floater->getExperienceInfo(experience_id); } // Need to deselect on close - f->mDeselectOnClose = TRUE; - - f->openFloater(); + reporter_floater->mDeselectOnClose = TRUE; } void LLFloaterReporter::showFromExperience( const LLUUID& experience_id ) { - LLFloaterReporter* f = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter"); - f->getExperienceInfo(experience_id); + LLFloaterReporter* reporter_floater = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); + if(reporter_floater && reporter_floater->isInVisibleChain()) + { + gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", FALSE); + } + reporter_floater = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter"); + reporter_floater->getExperienceInfo(experience_id); // Need to deselect on close - f->mDeselectOnClose = TRUE; - - f->openFloater(); + reporter_floater->mDeselectOnClose = TRUE; } @@ -713,10 +708,7 @@ LLSD LLFloaterReporter::gatherReport() // only send a screenshot ID if we're asked to and the email is // going to LL - Estate Owners cannot see the screenshot asset LLUUID screenshot_id = LLUUID::null; - if (getChild<LLUICtrl>("screen_check")->getValue()) - { - screenshot_id = getChild<LLUICtrl>("screenshot")->getValue(); - }; + screenshot_id = getChild<LLUICtrl>("screenshot")->getValue(); LLSD report = LLSD::emptyMap(); report["report-type"] = (U8) mReportType; @@ -770,7 +762,7 @@ void LLFloaterReporter::finishedARPost(const LLSD &) void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url, const LLSD& report) { - if(getChild<LLUICtrl>("screen_check")->getValue().asBoolean() && !sshot_url.empty()) + if(!sshot_url.empty()) { // try to upload screenshot LLResourceUploadInfo::ptr_t uploadInfo(new LLARScreenShotUploader(report, mResourceDatap->mAssetInfo.mUuid, mResourceDatap->mAssetInfo.mType)); @@ -784,18 +776,24 @@ void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url } } -void LLFloaterReporter::takeScreenshot() +void LLFloaterReporter::takeScreenshot(bool use_prev_screenshot) { - const S32 IMAGE_WIDTH = 1024; - const S32 IMAGE_HEIGHT = 768; - - LLPointer<LLImageRaw> raw = new LLImageRaw; - if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE, TRUE, FALSE)) + gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", TRUE); + if(!use_prev_screenshot) { - LL_WARNS() << "Unable to take screenshot" << LL_ENDL; - return; + std::string screenshot_filename(gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + SCREEN_PREV_FILENAME); + LLPointer<LLImageBMP> bmp_image = new LLImageBMP; + if(bmp_image->encode(mImageRaw, 0.0f)) + { + bmp_image->save(screenshot_filename); + } + } + else + { + mImageRaw = mPrevImageRaw; } - LLPointer<LLImageJ2C> upload_data = LLViewerTextureList::convertToUploadFile(raw); + + LLPointer<LLImageJ2C> upload_data = LLViewerTextureList::convertToUploadFile(mImageRaw); // create a resource data mResourceDatap->mInventoryType = LLInventoryType::IT_NONE; @@ -827,7 +825,7 @@ void LLFloaterReporter::takeScreenshot() // store in the image list so it doesn't try to fetch from the server LLPointer<LLViewerFetchedTexture> image_in_list = LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid); - image_in_list->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER); + image_in_list->createGLTexture(0, mImageRaw, 0, TRUE, LLGLTexture::OTHER); // the texture picker then uses that texture LLTextureCtrl* texture = getChild<LLTextureCtrl>("screenshot"); @@ -837,7 +835,46 @@ void LLFloaterReporter::takeScreenshot() texture->setDefaultImageAssetID(mResourceDatap->mAssetInfo.mUuid); texture->setCaption(getString("Screenshot")); } +} + +void LLFloaterReporter::onOpen(const LLSD& key) +{ + mImageRaw = new LLImageRaw; + const S32 IMAGE_WIDTH = 1024; + const S32 IMAGE_HEIGHT = 768; + + // Take a screenshot, but don't draw this floater. + setVisible(FALSE); + if( !gViewerWindow->rawSnapshot(mImageRaw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE, TRUE, FALSE)) + { + LL_WARNS() << "Unable to take screenshot" << LL_ENDL; + setVisible(TRUE); + return; + } + setVisible(TRUE); + if(gSavedPerAccountSettings.getBOOL("PreviousScreenshotForReport")) + { + std::string screenshot_filename(gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + SCREEN_PREV_FILENAME); + mPrevImageRaw = new LLImageRaw; + LLPointer<LLImageBMP> start_image_bmp = new LLImageBMP; + if(start_image_bmp->load(screenshot_filename)) + { + if (start_image_bmp->decode(mPrevImageRaw, 0.0f)) + { + LLNotificationsUtil::add("LoadPreviousReportScreenshot", LLSD(), LLSD(), boost::bind(&LLFloaterReporter::onLoadScreenshotDialog,this, _1, _2)); + return; + } + } + } + + takeScreenshot(); +} + +void LLFloaterReporter::onLoadScreenshotDialog(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + takeScreenshot(option == 0); } void LLFloaterReporter::uploadImage() @@ -885,6 +922,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data, self->mScreenID = uuid; LL_INFOS() << "Got screen shot " << uuid << LL_ENDL; self->sendReportViaLegacy(self->gatherReport()); + LLNotificationsUtil::add("HelpReportAbuseConfirm"); self->closeFloater(); } } @@ -900,6 +938,11 @@ void LLFloaterReporter::setPosBox(const LLVector3d &pos) getChild<LLUICtrl>("pos_field")->setValue(pos_string); } +void LLFloaterReporter::onClose(bool app_quitting) +{ + gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting); +} + // void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd) // { diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index 1aff07bd372b623913841ed13ed3ab9bfe4855eb..e5232268c093346f3d3aaedb218d1fa11f08d02b 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -81,6 +81,8 @@ class LLFloaterReporter LLFloaterReporter(const LLSD& key); /*virtual*/ ~LLFloaterReporter(); /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onClose(bool app_quitting); virtual void draw(); void setReportType(EReportType type) { mReportType = type; } @@ -103,10 +105,12 @@ class LLFloaterReporter void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id); + void onLoadScreenshotDialog(const LLSD& notification, const LLSD& response); + private: static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null, const LLUUID& experience_id = LLUUID::null); - void takeScreenshot(); + void takeScreenshot(bool use_prev_screenshot = false); void sendReportViaCaps(std::string url); void uploadImage(); bool validateReport(); @@ -140,6 +144,9 @@ class LLFloaterReporter std::string mDefaultSummary; LLResourceData* mResourceDatap; boost::signals2::connection mAvatarNameCacheConnection; + + LLPointer<LLImageRaw> mImageRaw; + LLPointer<LLImageRaw> mPrevImageRaw; }; #endif diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 7b8fc5b35bf53be4a970fbceb8ab51e06eed4704..c14bb4e7ae4cf2ea1b8840e8512ea8b8e3a4a46b 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -523,6 +523,8 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) LLScrollListCell::Params cell_params; cell_params.font = LLFontGL::getFontSansSerif(); + // Start out right justifying numeric displays + cell_params.font_halign = LLFontGL::RIGHT; cell_params.column = "size"; cell_params.value = size; @@ -532,6 +534,8 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) cell_params.value = urls; item_params.columns.add(cell_params); + cell_params.font_halign = LLFontGL::LEFT; + // The rest of the columns are text to left justify them cell_params.column = "name"; cell_params.value = name_buf; item_params.columns.add(cell_params); @@ -546,7 +550,7 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) cell_params.column = "location"; cell_params.value = has_locations - ? llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z) + ? llformat("<%0.0f, %0.0f, %0.0f>", location_x, location_y, location_z) : ""; item_params.columns.add(cell_params); @@ -623,13 +627,20 @@ void LLPanelScriptLimitsRegionMemory::setRegionSummary(LLSD content) if((mParcelMemoryUsed >= 0) && (mParcelMemoryMax >= 0)) { - S32 parcel_memory_available = mParcelMemoryMax - mParcelMemoryUsed; - LLStringUtil::format_map_t args_parcel_memory; args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed); - args_parcel_memory["[MAX]"] = llformat ("%d", mParcelMemoryMax); - args_parcel_memory["[AVAILABLE]"] = llformat ("%d", parcel_memory_available); - std::string msg_parcel_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_parcel_memory); + std::string translate_message = "ScriptLimitsMemoryUsedSimple"; + + if (0 < mParcelMemoryMax) + { + S32 parcel_memory_available = mParcelMemoryMax - mParcelMemoryUsed; + + args_parcel_memory["[MAX]"] = llformat ("%d", mParcelMemoryMax); + args_parcel_memory["[AVAILABLE]"] = llformat ("%d", parcel_memory_available); + translate_message = "ScriptLimitsMemoryUsed"; + } + + std::string msg_parcel_memory = LLTrans::getString(translate_message, args_parcel_memory); getChild<LLUICtrl>("memory_used")->setValue(LLSD(msg_parcel_memory)); } @@ -660,6 +671,8 @@ BOOL LLPanelScriptLimitsRegionMemory::postBuild() { return FALSE; } + list->setCommitCallback(boost::bind(&LLPanelScriptLimitsRegionMemory::checkButtonsEnabled, this)); + checkButtonsEnabled(); //set all columns to resizable mode even if some columns will be empty for(S32 column = 0; column < list->getNumColumns(); column++) @@ -750,6 +763,14 @@ void LLPanelScriptLimitsRegionMemory::clearList() getChild<LLUICtrl>("parcels_listed")->setValue(LLSD(msg_empty_string)); mObjectListItems.clear(); + checkButtonsEnabled(); +} + +void LLPanelScriptLimitsRegionMemory::checkButtonsEnabled() +{ + LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list"); + getChild<LLButton>("highlight_btn")->setEnabled(list->getNumSelected() > 0); + getChild<LLButton>("return_btn")->setEnabled(list->getNumSelected() > 0); } // static @@ -1051,10 +1072,12 @@ void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content) element["columns"][0]["column"] = "size"; element["columns"][0]["value"] = llformat("%d", size); element["columns"][0]["font"] = "SANSSERIF"; + element["columns"][0]["halign"] = LLFontGL::RIGHT; element["columns"][1]["column"] = "urls"; element["columns"][1]["value"] = llformat("%d", urls); element["columns"][1]["font"] = "SANSSERIF"; + element["columns"][1]["halign"] = LLFontGL::RIGHT; element["columns"][2]["column"] = "name"; element["columns"][2]["value"] = name; @@ -1141,14 +1164,20 @@ void LLPanelScriptLimitsAttachment::setAttachmentSummary(LLSD content) if((mAttachmentMemoryUsed >= 0) && (mAttachmentMemoryMax >= 0)) { - S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed; - LLStringUtil::format_map_t args_attachment_memory; args_attachment_memory["[COUNT]"] = llformat ("%d", mAttachmentMemoryUsed); - args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax); - args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available); - std::string msg_attachment_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_attachment_memory); - getChild<LLUICtrl>("memory_used")->setValue(LLSD(msg_attachment_memory)); + std::string translate_message = "ScriptLimitsMemoryUsedSimple"; + + if (0 < mAttachmentMemoryMax) + { + S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed; + + args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax); + args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available); + translate_message = "ScriptLimitsMemoryUsed"; + } + + getChild<LLUICtrl>("memory_used")->setValue(LLTrans::getString(translate_message, args_attachment_memory)); } if((mAttachmentURLsUsed >= 0) && (mAttachmentURLsMax >= 0)) diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h index e3cbbd185fc64b73d8b4f61ce7e7d4ee6f776c9e..2ac3862b4f3507f66c89bcc0bfa02234a71549f3 100644 --- a/indra/newview/llfloaterscriptlimits.h +++ b/indra/newview/llfloaterscriptlimits.h @@ -113,6 +113,7 @@ class LLPanelScriptLimitsRegionMemory : public LLPanelScriptLimitsInfo, LLRemote void showBeacon(); void returnObjectsFromParcel(S32 local_id); void returnObjects(); + void checkButtonsEnabled(); private: void onNameCache(const LLUUID& id, diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index 0cb37dabe7ccb8cd0005198156afc795b1cab3fe..b139e5daf5c290ed48ea2f81c5a374305a3390d4 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -257,7 +257,6 @@ void LLFloaterSellLandUI::setBadge(const char* id, Badge badge) static std::string badgeOK("badge_ok.j2c"); static std::string badgeNote("badge_note.j2c"); static std::string badgeWarn("badge_warn.j2c"); - static std::string badgeError("badge_error.j2c"); std::string badgeName; switch (badge) @@ -266,7 +265,7 @@ void LLFloaterSellLandUI::setBadge(const char* id, Badge badge) case BADGE_OK: badgeName = badgeOK; break; case BADGE_NOTE: badgeName = badgeNote; break; case BADGE_WARN: badgeName = badgeWarn; break; - case BADGE_ERROR: badgeName = badgeError; break; + case BADGE_ERROR: badgeName = badgeWarn; break; } getChild<LLUICtrl>(id)->setValue(badgeName); diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp index c7218ad9d59532a3440533b8440ec95b96dc03e5..8b3cfa7fd510433ee6ac2cab295c6dd99625fa64 100644 --- a/indra/newview/llfloatersidepanelcontainer.cpp +++ b/indra/newview/llfloatersidepanelcontainer.cpp @@ -80,6 +80,11 @@ void LLFloaterSidePanelContainer::closeFloater(bool app_quitting) } LLFloater::closeFloater(app_quitting); + + if (getInstanceName() == "inventory" && !getKey().isUndefined()) + { + destroy(); + } } LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_name, const LLSD& params) diff --git a/indra/newview/llfloatersidepanelcontainer.h b/indra/newview/llfloatersidepanelcontainer.h index d7ecd52e5746d2f432f116002b5b274b9f7da02f..635514e26ca48292617703879a3da5275a786c62 100644 --- a/indra/newview/llfloatersidepanelcontainer.h +++ b/indra/newview/llfloatersidepanelcontainer.h @@ -53,6 +53,8 @@ class LLFloaterSidePanelContainer : public LLFloater /*virtual*/ void closeFloater(bool app_quitting = false); + void cleanup() { destroy(); } + LLPanel* openChildPanel(const std::string& panel_name, const LLSD& params); static void showPanel(const std::string& floater_name, const LLSD& key); diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index b906671c7fd1b0ce387739904dfd142c6d740225..c0980719bb8fdcf9bb007c309a6d426a765e46d1 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2016, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,6 @@ #include "llfloatersnapshot.h" -#include "llagent.h" #include "llfacebookconnect.h" #include "llfloaterreg.h" #include "llfloaterfacebook.h" @@ -51,7 +50,6 @@ ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- -LLUICtrl* LLFloaterSnapshot::sThumbnailPlaceholder = NULL; LLSnapshotFloaterView* gSnapshotFloaterView = NULL; const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f; @@ -61,92 +59,8 @@ const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512 static LLDefaultChildRegistry::Register<LLSnapshotFloaterView> r("snapshot_floater_view"); - -///---------------------------------------------------------------------------- -/// Class LLFloaterSnapshot::Impl -///---------------------------------------------------------------------------- - -class LLFloaterSnapshot::Impl -{ - LOG_CLASS(LLFloaterSnapshot::Impl); -public: - typedef enum e_status - { - STATUS_READY, - STATUS_WORKING, - STATUS_FINISHED - } EStatus; - - Impl() - : mAvatarPauseHandles(), - mLastToolset(NULL), - mAspectRatioCheckOff(false), - mNeedRefresh(false), - mStatus(STATUS_READY) - { - } - ~Impl() - { - //unpause avatars - mAvatarPauseHandles.clear(); - - } - static void onClickNewSnapshot(void* data); - static void onClickAutoSnap(LLUICtrl *ctrl, void* data); - static void onClickFilter(LLUICtrl *ctrl, void* data); - //static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data); - static void onClickUICheck(LLUICtrl *ctrl, void* data); - static void onClickHUDCheck(LLUICtrl *ctrl, void* data); - static void applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL checked); - static void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE); - static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data); - static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); - static void onImageQualityChange(LLFloaterSnapshot* view, S32 quality_val); - static void onImageFormatChange(LLFloaterSnapshot* view); - static void applyCustomResolution(LLFloaterSnapshot* view, S32 w, S32 h); - static void onSnapshotUploadFinished(bool status); - static void onSendingPostcardFinished(bool status); - static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); - static void setImageSizeSpinnersValues(LLFloaterSnapshot *view, S32 width, S32 height) ; - static void updateSpinners(LLFloaterSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed); - - static LLPanelSnapshot* getActivePanel(LLFloaterSnapshot* floater, bool ok_if_not_found = true); - static LLSnapshotLivePreview::ESnapshotType getActiveSnapshotType(LLFloaterSnapshot* floater); - static LLFloaterSnapshot::ESnapshotFormat getImageFormat(LLFloaterSnapshot* floater); - static LLSpinCtrl* getWidthSpinner(LLFloaterSnapshot* floater); - static LLSpinCtrl* getHeightSpinner(LLFloaterSnapshot* floater); - static void enableAspectRatioCheckbox(LLFloaterSnapshot* floater, BOOL enable); - static void setAspectRatioCheckboxValue(LLFloaterSnapshot* floater, BOOL checked); - - static LLSnapshotLivePreview* getPreviewView(LLFloaterSnapshot *floater); - static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname); - static void updateControls(LLFloaterSnapshot* floater); - static void updateLayout(LLFloaterSnapshot* floater); - static void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null); - EStatus getStatus() const { return mStatus; } - static void setNeedRefresh(LLFloaterSnapshot* floater, bool need); - -private: - static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater); - static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname); - static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); - static void checkAspectRatio(LLFloaterSnapshot *view, S32 index) ; - static void setWorking(LLFloaterSnapshot* floater, bool working); - static void setFinished(LLFloaterSnapshot* floater, bool finished, bool ok = true, const std::string& msg = LLStringUtil::null); - - -public: - std::vector<LLAnimPauseRequest> mAvatarPauseHandles; - - LLToolset* mLastToolset; - LLHandle<LLView> mPreviewHandle; - bool mAspectRatioCheckOff ; - bool mNeedRefresh; - EStatus mStatus; -}; - -// static -LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshot* floater, bool ok_if_not_found) +// virtual +LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found) { LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container"); LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel_container->getCurrentPanel()); @@ -157,58 +71,40 @@ LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshot* floa return active_panel; } -// static -LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getActiveSnapshotType(LLFloaterSnapshot* floater) +// virtual +LLSnapshotModel::ESnapshotType LLFloaterSnapshotBase::ImplBase::getActiveSnapshotType(LLFloaterSnapshotBase* floater) { - LLSnapshotLivePreview::ESnapshotType type = LLSnapshotLivePreview::SNAPSHOT_WEB; - std::string name; LLPanelSnapshot* spanel = getActivePanel(floater); - if (spanel) - { - name = spanel->getName(); - } - - if (name == "panel_snapshot_postcard") - { - type = LLSnapshotLivePreview::SNAPSHOT_POSTCARD; - } - else if (name == "panel_snapshot_inventory") - { - type = LLSnapshotLivePreview::SNAPSHOT_TEXTURE; - } - else if (name == "panel_snapshot_local") - { - type = LLSnapshotLivePreview::SNAPSHOT_LOCAL; - } - - return type; + //return type; + if (spanel) + { + return spanel->getSnapshotType(); + } + return LLSnapshotModel::SNAPSHOT_WEB; } -// static -LLFloaterSnapshot::ESnapshotFormat LLFloaterSnapshot::Impl::getImageFormat(LLFloaterSnapshot* floater) +// virtual +LLSnapshotModel::ESnapshotFormat LLFloaterSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater) { LLPanelSnapshot* active_panel = getActivePanel(floater); // FIXME: if the default is not PNG, profile uploads may fail. - return active_panel ? active_panel->getImageFormat() : LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; + return active_panel ? active_panel->getImageFormat() : LLSnapshotModel::SNAPSHOT_FORMAT_PNG; } -// static -LLSpinCtrl* LLFloaterSnapshot::Impl::getWidthSpinner(LLFloaterSnapshot* floater) +LLSpinCtrl* LLFloaterSnapshot::Impl::getWidthSpinner(LLFloaterSnapshotBase* floater) { LLPanelSnapshot* active_panel = getActivePanel(floater); return active_panel ? active_panel->getWidthSpinner() : floater->getChild<LLSpinCtrl>("snapshot_width"); } -// static -LLSpinCtrl* LLFloaterSnapshot::Impl::getHeightSpinner(LLFloaterSnapshot* floater) +LLSpinCtrl* LLFloaterSnapshot::Impl::getHeightSpinner(LLFloaterSnapshotBase* floater) { LLPanelSnapshot* active_panel = getActivePanel(floater); return active_panel ? active_panel->getHeightSpinner() : floater->getChild<LLSpinCtrl>("snapshot_height"); } -// static -void LLFloaterSnapshot::Impl::enableAspectRatioCheckbox(LLFloaterSnapshot* floater, BOOL enable) +void LLFloaterSnapshot::Impl::enableAspectRatioCheckbox(LLFloaterSnapshotBase* floater, BOOL enable) { LLPanelSnapshot* active_panel = getActivePanel(floater); if (active_panel) @@ -217,8 +113,7 @@ void LLFloaterSnapshot::Impl::enableAspectRatioCheckbox(LLFloaterSnapshot* float } } -// static -void LLFloaterSnapshot::Impl::setAspectRatioCheckboxValue(LLFloaterSnapshot* floater, BOOL checked) +void LLFloaterSnapshot::Impl::setAspectRatioCheckboxValue(LLFloaterSnapshotBase* floater, BOOL checked) { LLPanelSnapshot* active_panel = getActivePanel(floater); if (active_panel) @@ -227,40 +122,41 @@ void LLFloaterSnapshot::Impl::setAspectRatioCheckboxValue(LLFloaterSnapshot* flo } } -// static -LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater) +LLSnapshotLivePreview* LLFloaterSnapshotBase::getPreviewView() { - LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)floater->impl.mPreviewHandle.get(); + return impl->getPreviewView(); +} + +LLSnapshotLivePreview* LLFloaterSnapshotBase::ImplBase::getPreviewView() +{ + LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get(); return previewp; } -// static -LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater) +// virtual +LLSnapshotModel::ESnapshotLayerType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater) { - LLViewerWindow::ESnapshotType type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; + LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR; LLSD value = floater->getChild<LLUICtrl>("layer_types")->getValue(); const std::string id = value.asString(); if (id == "colors") - type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; + type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR; else if (id == "depth") - type = LLViewerWindow::SNAPSHOT_TYPE_DEPTH; + type = LLSnapshotModel::SNAPSHOT_TYPE_DEPTH; return type; } -// static -void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const std::string& comboname) +void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshotBase* floater, const std::string& comboname) { LLComboBox* combo = floater->getChild<LLComboBox>(comboname); combo->setVisible(TRUE); updateResolution(combo, floater, FALSE); // to sync spinners with combo } -//static -void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) +//virtual +void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floaterp) { - LLSnapshotLivePreview* previewp = getPreviewView(floaterp); - - BOOL advanced = gSavedSettings.getBOOL("AdvanceSnapshot"); + LLSnapshotLivePreview* previewp = getPreviewView(); //BD - Automatically calculate the size of our snapshot window to enlarge // the snapshot preview to its maximum size, this is especially helpfull @@ -277,16 +173,16 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) } S32 floater_width = 224.f; - if(advanced) + if(mAdvanced) { floater_width = floater_width + panel_width; } LLUICtrl* thumbnail_placeholder = floaterp->getChild<LLUICtrl>("thumbnail_placeholder"); - thumbnail_placeholder->setVisible(advanced); + thumbnail_placeholder->setVisible(mAdvanced); thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight()); - floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(advanced); - floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(advanced); + floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(mAdvanced); + floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(mAdvanced); if(!floaterp->isMinimized()) { floaterp->reshape(floater_width, floaterp->getRect().getHeight()); @@ -316,7 +212,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) iter != LLCharacter::sInstances.end(); ++iter) { avatarp = *iter; - floaterp->impl.mAvatarPauseHandles.push_back(avatarp->requestPause()); + floaterp->impl->mAvatarPauseHandles.push_back(avatarp->requestPause()); } // freeze everything else @@ -324,7 +220,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset) { - floaterp->impl.mLastToolset = LLToolMgr::getInstance()->getCurrentToolset(); + floaterp->impl->mLastToolset = LLToolMgr::getInstance()->getCurrentToolset(); LLToolMgr::getInstance()->setCurrentToolset(gCameraToolset); } } @@ -340,15 +236,15 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) } //RN: thaw all avatars - floaterp->impl.mAvatarPauseHandles.clear(); + floaterp->impl->mAvatarPauseHandles.clear(); // thaw everything else gSavedSettings.setBOOL("FreezeTime", FALSE); // restore last tool (e.g. pie menu, etc) - if (floaterp->impl.mLastToolset) + if (floaterp->impl->mLastToolset) { - LLToolMgr::getInstance()->setCurrentToolset(floaterp->impl.mLastToolset); + LLToolMgr::getInstance()->setCurrentToolset(floaterp->impl->mLastToolset); } } } @@ -359,15 +255,15 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) // The basic pattern for programmatically changing the GUI settings is to first set the // appropriate saved settings and then call this method to sync the GUI with them. // FIXME: The above comment seems obsolete now. -// static -void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) +// virtual +void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater) { - LLSnapshotLivePreview::ESnapshotType shot_type = getActiveSnapshotType(floater); - ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); - LLViewerWindow::ESnapshotType layer_type = getLayerType(floater); + LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater); + LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); + LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater); floater->getChild<LLComboBox>("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat")); - floater->getChildView("layer_types")->setEnabled(shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL); + floater->getChildView("layer_types")->setEnabled(shot_type == LLSnapshotModel::SNAPSHOT_LOCAL); LLPanelSnapshot* active_panel = getActivePanel(floater); if (active_panel) @@ -381,7 +277,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) S32 w = gViewerWindow->getWindowWidthRaw(); LL_DEBUGS() << "Initializing width spinner (" << width_ctrl->getName() << "): " << w << LL_ENDL; width_ctrl->setValue(w); - if(getActiveSnapshotType(floater) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) + if (getActiveSnapshotType(floater) == LLSnapshotModel::SNAPSHOT_TEXTURE) { width_ctrl->setIncrement(w >> 1); } @@ -391,7 +287,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) S32 h = gViewerWindow->getWindowHeightRaw(); LL_DEBUGS() << "Initializing height spinner (" << height_ctrl->getName() << "): " << h << LL_ENDL; height_ctrl->setValue(h); - if(getActiveSnapshotType(floater) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) + if (getActiveSnapshotType(floater) == LLSnapshotModel::SNAPSHOT_TEXTURE) { height_ctrl->setIncrement(h >> 1); } @@ -423,7 +319,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) } } - LLSnapshotLivePreview* previewp = getPreviewView(floater); + LLSnapshotLivePreview* previewp = getPreviewView(); BOOL got_bytes = previewp && previewp->getDataSize() > 0; BOOL got_snap = previewp && previewp->getSnapshotUpToDate(); @@ -448,35 +344,35 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown")); floater->getChild<LLUICtrl>("file_size_label")->setColor( - shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD + shot_type == LLSnapshotModel::SNAPSHOT_POSTCARD && got_bytes && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" )); // Update the width and height spinners based on the corresponding resolution combos. (?) switch(shot_type) { - case LLSnapshotLivePreview::SNAPSHOT_WEB: - layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; + case LLSnapshotModel::SNAPSHOT_WEB: + layer_type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR; floater->getChild<LLUICtrl>("layer_types")->setValue("colors"); setResolution(floater, "profile_size_combo"); break; - case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: - layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; + case LLSnapshotModel::SNAPSHOT_POSTCARD: + layer_type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR; floater->getChild<LLUICtrl>("layer_types")->setValue("colors"); setResolution(floater, "postcard_size_combo"); break; - case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: - layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; + case LLSnapshotModel::SNAPSHOT_TEXTURE: + layer_type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR; floater->getChild<LLUICtrl>("layer_types")->setValue("colors"); setResolution(floater, "texture_size_combo"); break; - case LLSnapshotLivePreview::SNAPSHOT_LOCAL: + case LLSnapshotModel::SNAPSHOT_LOCAL: setResolution(floater, "local_size_combo"); break; default: break; } - setAspectRatioCheckboxValue(floater, !floater->impl.mAspectRatioCheckOff && gSavedSettings.getBOOL("KeepAspectForSnapshot")); + setAspectRatioCheckboxValue(floater, !floater->impl->mAspectRatioCheckOff && gSavedSettings.getBOOL("KeepAspectForSnapshot")); if (previewp) { @@ -495,33 +391,32 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) LL_DEBUGS() << "finished updating controls" << LL_ENDL; } -// static -void LLFloaterSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg) +//virtual +void LLFloaterSnapshotBase::ImplBase::setStatus(EStatus status, bool ok, const std::string& msg) { - LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance(); switch (status) { case STATUS_READY: - setWorking(floater, false); - setFinished(floater, false); + setWorking(false); + setFinished(false); break; case STATUS_WORKING: - setWorking(floater, true); - setFinished(floater, false); + setWorking(true); + setFinished(false); break; case STATUS_FINISHED: - setWorking(floater, false); - setFinished(floater, true, ok, msg); + setWorking(false); + setFinished(true, ok, msg); break; } - floater->impl.mStatus = status; + mStatus = status; } -// static -void LLFloaterSnapshot::Impl::setNeedRefresh(LLFloaterSnapshot* floater, bool need) +// virtual +void LLFloaterSnapshotBase::ImplBase::setNeedRefresh(bool need) { - if (!floater) return; + if (!mFloater) return; // Don't display the "Refresh to save" message if we're in auto-refresh mode. if (gSavedSettings.getBOOL("AutoSnapshot")) @@ -529,12 +424,12 @@ void LLFloaterSnapshot::Impl::setNeedRefresh(LLFloaterSnapshot* floater, bool ne need = false; } - floater->mRefreshLabel->setVisible(need); - floater->impl.mNeedRefresh = need; + mFloater->setRefreshLabelVisible(need); + mNeedRefresh = need; } -// static -void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail) +// virtual +void LLFloaterSnapshotBase::ImplBase::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail) { if (previewp) { @@ -545,43 +440,43 @@ void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, } // static -void LLFloaterSnapshot::Impl::onClickNewSnapshot(void* data) +void LLFloaterSnapshotBase::ImplBase::onClickNewSnapshot(void* data) { - LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterSnapshot *)data); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - if (previewp && view) + LLFloaterSnapshotBase* floater = (LLFloaterSnapshotBase *)data; + LLSnapshotLivePreview* previewp = floater->getPreviewView(); + if (previewp) { - view->impl.setStatus(Impl::STATUS_READY); + floater->impl->setStatus(ImplBase::STATUS_READY); LL_DEBUGS() << "updating snapshot" << LL_ENDL; previewp->mForceUpdateSnapshot = TRUE; } } // static -void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data) +void LLFloaterSnapshotBase::ImplBase::onClickAutoSnap(LLUICtrl *ctrl, void* data) { LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; gSavedSettings.setBOOL( "AutoSnapshot", check->get() ); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; + LLFloaterSnapshotBase *view = (LLFloaterSnapshotBase *)data; if (view) { - checkAutoSnapshot(getPreviewView(view)); - updateControls(view); + view->impl->checkAutoSnapshot(view->getPreviewView()); + view->impl->updateControls(view); } } // static -void LLFloaterSnapshot::Impl::onClickFilter(LLUICtrl *ctrl, void* data) +void LLFloaterSnapshotBase::ImplBase::onClickFilter(LLUICtrl *ctrl, void* data) { - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; + LLFloaterSnapshotBase *view = (LLFloaterSnapshotBase *)data; if (view) { - updateControls(view); - LLSnapshotLivePreview* previewp = getPreviewView(view); + view->impl->updateControls(view); + LLSnapshotLivePreview* previewp = view->getPreviewView(); if (previewp) { - checkAutoSnapshot(previewp); + view->impl->checkAutoSnapshot(previewp); // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale LLComboBox* filterbox = static_cast<LLComboBox *>(view->getChild<LLComboBox>("filters_combobox")); std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : ""); @@ -592,7 +487,7 @@ void LLFloaterSnapshot::Impl::onClickFilter(LLUICtrl *ctrl, void* data) } // static -void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data) +void LLFloaterSnapshotBase::ImplBase::onClickUICheck(LLUICtrl *ctrl, void* data) { LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; gSavedSettings.setBOOL( "RenderUIInSnapshot", check->get() ); @@ -600,17 +495,17 @@ void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data) LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = view->getPreviewView(); if(previewp) { previewp->updateSnapshot(TRUE, TRUE); } - updateControls(view); + view->impl->updateControls(view); } } // static -void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data) +void LLFloaterSnapshotBase::ImplBase::onClickHUDCheck(LLUICtrl *ctrl, void* data) { LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; gSavedSettings.setBOOL( "RenderHUDInSnapshot", check->get() ); @@ -618,17 +513,16 @@ void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data) LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = view->getPreviewView(); if(previewp) { previewp->updateSnapshot(TRUE, TRUE); } - updateControls(view); + view->impl->updateControls(view); } } -// static -void LLFloaterSnapshot::Impl::applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL checked) +void LLFloaterSnapshot::Impl::applyKeepAspectCheck(LLFloaterSnapshotBase* view, BOOL checked) { gSavedSettings.setBOOL("KeepAspectForSnapshot", checked); @@ -641,7 +535,7 @@ void LLFloaterSnapshot::Impl::applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index } - LLSnapshotLivePreview* previewp = getPreviewView(view) ; + LLSnapshotLivePreview* previewp = getPreviewView() ; if(previewp) { previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; @@ -659,11 +553,11 @@ void LLFloaterSnapshot::Impl::applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL } // static -void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data) +void LLFloaterSnapshotBase::ImplBase::onCommitFreezeFrame(LLUICtrl* ctrl, void* data) { LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLFloaterSnapshotBase *view = (LLFloaterSnapshotBase *)data; + LLSnapshotLivePreview* previewp = view->getPreviewView(); if (!view || !check_box || !previewp) { @@ -677,16 +571,15 @@ void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data) previewp->prepareFreezeFrame(); } - updateLayout(view); + view->impl->updateLayout(view); } -// static -void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 index) +void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshotBase *view, S32 index) { - LLSnapshotLivePreview *previewp = getPreviewView(view) ; + LLSnapshotLivePreview *previewp = getPreviewView() ; // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here - if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == getActiveSnapshotType(view)) + if (LLSnapshotModel::SNAPSHOT_TEXTURE == getActiveSnapshotType(view)) { previewp->mKeepAspectRatio = FALSE ; return ; @@ -710,7 +603,7 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde keep_aspect = FALSE; } - view->impl.mAspectRatioCheckOff = !enable_cb; + view->impl->mAspectRatioCheckOff = !enable_cb; if (previewp) { @@ -719,51 +612,55 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde } // Show/hide upload progress indicators. -// static -void LLFloaterSnapshot::Impl::setWorking(LLFloaterSnapshot* floater, bool working) +void LLFloaterSnapshotBase::ImplBase::setWorking(bool working) { - LLUICtrl* working_lbl = floater->getChild<LLUICtrl>("working_lbl"); + LLUICtrl* working_lbl = mFloater->getChild<LLUICtrl>("working_lbl"); working_lbl->setVisible(working); - floater->getChild<LLUICtrl>("working_indicator")->setVisible(working); + mFloater->getChild<LLUICtrl>("working_indicator")->setVisible(working); if (working) { - const std::string panel_name = getActivePanel(floater, false)->getName(); - const std::string prefix = panel_name.substr(std::string("panel_snapshot_").size()); - std::string progress_text = floater->getString(prefix + "_" + "progress_str"); + const std::string panel_name = getActivePanel(mFloater, false)->getName(); + const std::string prefix = panel_name.substr(getSnapshotPanelPrefix().size()); + std::string progress_text = mFloater->getString(prefix + "_" + "progress_str"); working_lbl->setValue(progress_text); } // All controls should be disabled while posting. - floater->setCtrlsEnabled(!working); - LLPanelSnapshot* active_panel = getActivePanel(floater); + mFloater->setCtrlsEnabled(!working); + LLPanelSnapshot* active_panel = getActivePanel(mFloater); if (active_panel) { active_panel->enableControls(!working); } } +//virtual +std::string LLFloaterSnapshot::Impl::getSnapshotPanelPrefix() +{ + return "panel_snapshot_"; +} + // Show/hide upload status message. -// static -void LLFloaterSnapshot::Impl::setFinished(LLFloaterSnapshot* floater, bool finished, bool ok, const std::string& msg) +// virtual +void LLFloaterSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg) { - floater->mSucceessLblPanel->setVisible(finished && ok); - floater->mFailureLblPanel->setVisible(finished && !ok); + mFloater->setSuccessLabelPanelVisible(finished && ok); + mFloater->setFailureLabelPanelVisible(finished && !ok); if (finished) { - LLUICtrl* finished_lbl = floater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl"); - std::string result_text = floater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str")); + LLUICtrl* finished_lbl = mFloater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl"); + std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str")); finished_lbl->setValue(result_text); - LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container"); + LLSideTrayPanelContainer* panel_container = mFloater->getChild<LLSideTrayPanelContainer>("panel_container"); panel_container->openPreviousPanel(); panel_container->getCurrentPanel()->onOpen(LLSD()); } } // Apply a new resolution selected from the given combobox. -// static void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update) { LLComboBox* combobox = (LLComboBox*)ctrl; @@ -783,7 +680,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL S32 width = sdres[0]; S32 height = sdres[1]; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp && combobox->getCurrentIndex() >= 0) { S32 original_width = 0 , original_height = 0 ; @@ -813,7 +710,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL new_height = spanel->getTypedPreviewHeight(); // Limit custom size for inventory snapshots to 512x512 px. - if (getActiveSnapshotType(view) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) + if (getActiveSnapshotType(view) == LLSnapshotModel::SNAPSHOT_TEXTURE) { new_width = llmin(new_width, MAX_TEXTURE_SIZE); new_height = llmin(new_height, MAX_TEXTURE_SIZE); @@ -851,7 +748,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL { getWidthSpinner(view)->setValue(width); getHeightSpinner(view)->setValue(height); - if (getActiveSnapshotType(view) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) + if (getActiveSnapshotType(view) == LLSnapshotModel::SNAPSHOT_TEXTURE) { getWidthSpinner(view)->setIncrement(width >> 1); getHeightSpinner(view)->setIncrement(height >> 1); @@ -865,7 +762,8 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL // hide old preview as the aspect ratio could be wrong checkAutoSnapshot(previewp, FALSE); LL_DEBUGS() << "updating thumbnail" << LL_ENDL; - getPreviewView(view)->updateSnapshot(TRUE); + // Don't update immediately, give window chance to redraw + getPreviewView()->updateSnapshot(TRUE, FALSE, 1.f); if(do_update) { LL_DEBUGS() << "Will update controls" << LL_ENDL; @@ -884,40 +782,37 @@ void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data) if (view) { - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = view->getPreviewView(); if (previewp) { - previewp->setSnapshotBufferType((LLViewerWindow::ESnapshotType)combobox->getCurrentIndex()); + previewp->setSnapshotBufferType((LLSnapshotModel::ESnapshotLayerType)combobox->getCurrentIndex()); } - checkAutoSnapshot(previewp, TRUE); + view->impl->checkAutoSnapshot(previewp, TRUE); } } -// static -void LLFloaterSnapshot::Impl::onImageQualityChange(LLFloaterSnapshot* view, S32 quality_val) +void LLFloaterSnapshot::Impl::onImageQualityChange(LLFloaterSnapshotBase* view, S32 quality_val) { - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { previewp->setSnapshotQuality(quality_val); } } -// static -void LLFloaterSnapshot::Impl::onImageFormatChange(LLFloaterSnapshot* view) +void LLFloaterSnapshot::Impl::onImageFormatChange(LLFloaterSnapshotBase* view) { if (view) { gSavedSettings.setS32("SnapshotFormat", getImageFormat(view)); LL_DEBUGS() << "image format changed, updating snapshot" << LL_ENDL; - getPreviewView(view)->updateSnapshot(TRUE); + getPreviewView()->updateSnapshot(TRUE); updateControls(view); } } // Sets the named size combo to "custom" mode. -// static -void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname) +void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshotBase* floater, const std::string& comboname) { LLComboBox* combo = floater->getChild<LLComboBox>(comboname); combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index @@ -925,7 +820,6 @@ void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const s } // Update supplied width and height according to the constrain proportions flag; limit them by max_val. -//static BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value) { S32 w = width ; @@ -970,20 +864,18 @@ BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3 return (w != width || h != height) ; } -//static -void LLFloaterSnapshot::Impl::setImageSizeSpinnersValues(LLFloaterSnapshot *view, S32 width, S32 height) +void LLFloaterSnapshot::Impl::setImageSizeSpinnersValues(LLFloaterSnapshotBase* view, S32 width, S32 height) { getWidthSpinner(view)->forceSetValue(width); getHeightSpinner(view)->forceSetValue(height); - if (getActiveSnapshotType(view) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) + if (getActiveSnapshotType(view) == LLSnapshotModel::SNAPSHOT_TEXTURE) { getWidthSpinner(view)->setIncrement(width >> 1); getHeightSpinner(view)->setIncrement(height >> 1); } } -// static -void LLFloaterSnapshot::Impl::updateSpinners(LLFloaterSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed) +void LLFloaterSnapshot::Impl::updateSpinners(LLFloaterSnapshotBase* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed) { getWidthSpinner(view)->resetDirty(); getHeightSpinner(view)->resetDirty(); @@ -993,13 +885,12 @@ void LLFloaterSnapshot::Impl::updateSpinners(LLFloaterSnapshot* view, LLSnapshot } } -// static -void LLFloaterSnapshot::Impl::applyCustomResolution(LLFloaterSnapshot* view, S32 w, S32 h) +void LLFloaterSnapshot::Impl::applyCustomResolution(LLFloaterSnapshotBase* view, S32 w, S32 h) { LL_DEBUGS() << "applyCustomResolution(" << w << ", " << h << ")" << LL_ENDL; if (!view) return; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { S32 curw,curh; @@ -1023,90 +914,104 @@ void LLFloaterSnapshot::Impl::applyCustomResolution(LLFloaterSnapshot* view, S32 } // static -void LLFloaterSnapshot::Impl::onSnapshotUploadFinished(bool status) +void LLFloaterSnapshot::Impl::onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status) { - setStatus(STATUS_FINISHED, status, "profile"); + floater->impl->setStatus(STATUS_FINISHED, status, "profile"); } - // static -void LLFloaterSnapshot::Impl::onSendingPostcardFinished(bool status) +void LLFloaterSnapshot::Impl::onSendingPostcardFinished(LLFloaterSnapshotBase* floater, bool status) { - setStatus(STATUS_FINISHED, status, "postcard"); + floater->impl->setStatus(STATUS_FINISHED, status, "postcard"); } ///---------------------------------------------------------------------------- -/// Class LLFloaterSnapshot +/// Class LLFloaterSnapshotBase ///---------------------------------------------------------------------------- // Default constructor -LLFloaterSnapshot::LLFloaterSnapshot(const LLSD& key) - : LLFloater(key), +LLFloaterSnapshotBase::LLFloaterSnapshotBase(const LLSD& key) + : LLFloater(key), mRefreshBtn(NULL), mRefreshLabel(NULL), mSucceessLblPanel(NULL), - mFailureLblPanel(NULL), - impl (*(new Impl)) + mFailureLblPanel(NULL) { } -// Destroys the object -LLFloaterSnapshot::~LLFloaterSnapshot() +LLFloaterSnapshotBase::~LLFloaterSnapshotBase() { - if (impl.mPreviewHandle.get()) impl.mPreviewHandle.get()->die(); + if (impl->mPreviewHandle.get()) impl->mPreviewHandle.get()->die(); //unfreeze everything else gSavedSettings.setBOOL("FreezeTime", FALSE); - if (impl.mLastToolset) + if (impl->mLastToolset) { - LLToolMgr::getInstance()->setCurrentToolset(impl.mLastToolset); + LLToolMgr::getInstance()->setCurrentToolset(impl->mLastToolset); } - delete &impl; + delete impl; } +///---------------------------------------------------------------------------- +/// Class LLFloaterSnapshot +///---------------------------------------------------------------------------- +// Default constructor +LLFloaterSnapshot::LLFloaterSnapshot(const LLSD& key) + : LLFloaterSnapshotBase(key) +{ + impl = new Impl(this); +} + +LLFloaterSnapshot::~LLFloaterSnapshot() +{ +} + +// virtual BOOL LLFloaterSnapshot::postBuild() { mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn"); - childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this); + childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); mRefreshLabel = getChild<LLUICtrl>("refresh_lbl"); mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel"); mFailureLblPanel = getChild<LLUICtrl>("failed_panel"); - childSetCommitCallback("ui_check", Impl::onClickUICheck, this); + childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this); getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot")); - childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this); + childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this); getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot")); - impl.setAspectRatioCheckboxValue(this, gSavedSettings.getBOOL("KeepAspectForSnapshot")); + ((Impl*)impl)->setAspectRatioCheckboxValue(this, gSavedSettings.getBOOL("KeepAspectForSnapshot")); childSetCommitCallback("layer_types", Impl::onCommitLayerTypes, this); getChild<LLUICtrl>("layer_types")->setValue("colors"); getChildView("layer_types")->setEnabled(FALSE); getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame")); - childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this); + childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this); getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot")); - childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this); - + childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this); + + getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterSnapshot::onExtendFloater, this)); + getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterSnapshot::onExtendFloater, this)); // Filters LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox"); - std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList(); - for (U32 i = 0; i < filter_list.size(); i++) - { - filterbox->add(filter_list[i]); - } - childSetCommitCallback("filters_combobox", Impl::onClickFilter, this); + std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList(); + for (U32 i = 0; i < filter_list.size(); i++) + { + filterbox->add(filter_list[i]); + } + childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this); - LLWebProfile::setImageUploadResultCallback(boost::bind(&LLFloaterSnapshot::Impl::onSnapshotUploadFinished, _1)); - LLPostCard::setPostResultCallback(boost::bind(&LLFloaterSnapshot::Impl::onSendingPostcardFinished, _1)); + LLWebProfile::setImageUploadResultCallback(boost::bind(&Impl::onSnapshotUploadFinished, this, _1)); + LLPostCard::setPostResultCallback(boost::bind(&Impl::onSendingPostcardFinished, this, _1)); - sThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder"); + mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder"); // create preview window LLRect full_screen_rect = getRootView()->getRect(); @@ -1131,10 +1036,11 @@ BOOL LLFloaterSnapshot::postBuild() getChild<LLComboBox>("local_size_combo")->selectNthItem(8); getChild<LLComboBox>("local_format_combo")->selectNthItem(0); - impl.mPreviewHandle = previewp->getHandle(); + impl->mPreviewHandle = previewp->getHandle(); previewp->setContainer(this); - impl.updateControls(this); - impl.updateLayout(this); + impl->updateControls(this); + impl->setAdvanced(gSavedSettings.getBOOL("AdvanceSnapshot")); + impl->updateLayout(this); previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect()); @@ -1142,9 +1048,10 @@ BOOL LLFloaterSnapshot::postBuild() return TRUE; } -void LLFloaterSnapshot::draw() +// virtual +void LLFloaterSnapshotBase::draw() { - LLSnapshotLivePreview* previewp = impl.getPreviewView(this); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock())) { @@ -1154,11 +1061,11 @@ void LLFloaterSnapshot::draw() LLFloater::draw(); - if (previewp && !isMinimized() && sThumbnailPlaceholder->getVisible()) + if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible()) { if(previewp->getThumbnailImage()) { - bool working = impl.getStatus() == Impl::STATUS_WORKING; + bool working = impl->getStatus() == ImplBase::STATUS_WORKING; const LLRect& thumbnail_rect = getThumbnailPlaceholderRect(); const S32 thumbnail_w = previewp->getThumbnailWidth(); const S32 thumbnail_h = previewp->getThumbnailHeight(); @@ -1183,16 +1090,17 @@ void LLFloaterSnapshot::draw() gGL.pushUIMatrix(); LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom); - sThumbnailPlaceholder->draw(); + mThumbnailPlaceholder->draw(); gGL.popUIMatrix(); } } - impl.updateLayout(this); + impl->updateLayout(this); } +//virtual void LLFloaterSnapshot::onOpen(const LLSD& key) { - LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(this); + LLSnapshotLivePreview* preview = getPreviewView(); if(preview) { LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL; @@ -1203,19 +1111,26 @@ void LLFloaterSnapshot::onOpen(const LLSD& key) gSnapshotFloaterView->setVisible(TRUE); gSnapshotFloaterView->adjustToFitScreen(this, FALSE); - impl.updateControls(this); - impl.updateLayout(this); + impl->updateControls(this); + impl->setAdvanced(gSavedSettings.getBOOL("AdvanceSnapshot")); + impl->updateLayout(this); // Initialize default tab. getChild<LLSideTrayPanelContainer>("panel_container")->getCurrentPanel()->onOpen(LLSD()); } -void LLFloaterSnapshot::onClose(bool app_quitting) +void LLFloaterSnapshot::onExtendFloater() +{ + impl->setAdvanced(gSavedSettings.getBOOL("AdvanceSnapshot")); +} + +//virtual +void LLFloaterSnapshotBase::onClose(bool app_quitting) { getParent()->setMouseOpaque(FALSE); //unfreeze everything, hide fullscreen preview - LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(this); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { previewp->setVisible(FALSE); @@ -1223,125 +1138,145 @@ void LLFloaterSnapshot::onClose(bool app_quitting) } gSavedSettings.setBOOL("FreezeTime", FALSE); - impl.mAvatarPauseHandles.clear(); + impl->mAvatarPauseHandles.clear(); - if (impl.mLastToolset) + if (impl->mLastToolset) { - LLToolMgr::getInstance()->setCurrentToolset(impl.mLastToolset); + LLToolMgr::getInstance()->setCurrentToolset(impl->mLastToolset); } } // virtual -S32 LLFloaterSnapshot::notify(const LLSD& info) +S32 LLFloaterSnapshotBase::notify(const LLSD& info) { - // A child panel wants to change snapshot resolution. - if (info.has("combo-res-change")) + if (info.has("set-ready")) { - std::string combo_name = info["combo-res-change"]["control-name"].asString(); - impl.updateResolution(getChild<LLUICtrl>(combo_name), this); + impl->setStatus(ImplBase::STATUS_READY); return 1; } - if (info.has("custom-res-change")) + if (info.has("set-working")) { - LLSD res = info["custom-res-change"]; - impl.applyCustomResolution(this, res["w"].asInteger(), res["h"].asInteger()); + impl->setStatus(ImplBase::STATUS_WORKING); return 1; } - if (info.has("keep-aspect-change")) + if (info.has("set-finished")) { - impl.applyKeepAspectCheck(this, info["keep-aspect-change"].asBoolean()); + LLSD data = info["set-finished"]; + impl->setStatus(ImplBase::STATUS_FINISHED, data["ok"].asBoolean(), data["msg"].asString()); return 1; } - if (info.has("image-quality-change")) + if (info.has("snapshot-updating")) { - impl.onImageQualityChange(this, info["image-quality-change"].asInteger()); + // Disable the send/post/save buttons until snapshot is ready. + impl->updateControls(this); return 1; } - if (info.has("image-format-change")) + if (info.has("snapshot-updated")) { - impl.onImageFormatChange(this); + // Enable the send/post/save buttons. + impl->updateControls(this); + // We've just done refresh. + impl->setNeedRefresh(false); + + // The refresh button is initially hidden. We show it after the first update, + // i.e. when preview appears. + if (!mRefreshBtn->getVisible()) + { + mRefreshBtn->setVisible(true); + } return 1; } - if (info.has("set-ready")) + return 0; +} + +// virtual +S32 LLFloaterSnapshot::notify(const LLSD& info) +{ + bool res = LLFloaterSnapshotBase::notify(info); + if (res) + return res; + // A child panel wants to change snapshot resolution. + if (info.has("combo-res-change")) { - impl.setStatus(Impl::STATUS_READY); + std::string combo_name = info["combo-res-change"]["control-name"].asString(); + ((Impl*)impl)->updateResolution(getChild<LLUICtrl>(combo_name), this); return 1; } - if (info.has("set-working")) + if (info.has("custom-res-change")) { - impl.setStatus(Impl::STATUS_WORKING); + LLSD res = info["custom-res-change"]; + ((Impl*)impl)->applyCustomResolution(this, res["w"].asInteger(), res["h"].asInteger()); return 1; } - if (info.has("set-finished")) + if (info.has("keep-aspect-change")) { - LLSD data = info["set-finished"]; - impl.setStatus(Impl::STATUS_FINISHED, data["ok"].asBoolean(), data["msg"].asString()); + ((Impl*)impl)->applyKeepAspectCheck(this, info["keep-aspect-change"].asBoolean()); return 1; } - - if (info.has("snapshot-updating")) + + if (info.has("image-quality-change")) { - // Disable the send/post/save buttons until snapshot is ready. - impl.updateControls(this); + ((Impl*)impl)->onImageQualityChange(this, info["image-quality-change"].asInteger()); return 1; } - if (info.has("snapshot-updated")) + if (info.has("image-format-change")) { - // Enable the send/post/save buttons. - impl.updateControls(this); - // We've just done refresh. - impl.setNeedRefresh(this, false); - - // The refresh button is initially hidden. We show it after the first update, - // i.e. when preview appears. - if (!mRefreshBtn->getVisible()) - { - mRefreshBtn->setVisible(true); - } + ((Impl*)impl)->onImageFormatChange(this); return 1; - } + } return 0; } -//static -void LLFloaterSnapshot::update() +BOOL LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized) { - LLFloaterSnapshot* inst = findInstance(); - LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook"); - LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr"); - LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter"); + LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook"); + LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr"); + LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter"); + + if (!initialized && !floater_facebook && !floater_flickr && !floater_twitter) + return FALSE; - if (!inst && !floater_facebook && !floater_flickr && !floater_twitter) - return; - BOOL changed = FALSE; LL_DEBUGS() << "npreviews: " << LLSnapshotLivePreview::sList.size() << LL_ENDL; for (std::set<LLSnapshotLivePreview*>::iterator iter = LLSnapshotLivePreview::sList.begin(); - iter != LLSnapshotLivePreview::sList.end(); ++iter) + iter != LLSnapshotLivePreview::sList.end(); ++iter) { changed |= LLSnapshotLivePreview::onIdle(*iter); } - - if (inst && changed) + return changed; +} + + +void LLFloaterSnapshotBase::ImplBase::updateLivePreview() +{ + if (ImplBase::updatePreviewList(true) && mFloater) { LL_DEBUGS() << "changed" << LL_ENDL; - inst->impl.updateControls(inst); + updateControls(mFloater); } } -// static -LLFloaterSnapshot* LLFloaterSnapshot::getInstance() +//static +void LLFloaterSnapshot::update() { - return LLFloaterReg::getTypedInstance<LLFloaterSnapshot>("snapshot"); + LLFloaterSnapshot* inst = findInstance(); + if (inst != NULL) + { + inst->impl->updateLivePreview(); + } + else + { + ImplBase::updatePreviewList(false); + } } // static @@ -1351,18 +1286,17 @@ LLFloaterSnapshot* LLFloaterSnapshot::findInstance() } // static +LLFloaterSnapshot* LLFloaterSnapshot::getInstance() +{ + return LLFloaterReg::getTypedInstance<LLFloaterSnapshot>("snapshot"); +} + +// virtual void LLFloaterSnapshot::saveTexture() { LL_DEBUGS() << "saveTexture" << LL_ENDL; - // FIXME: duplicated code - LLFloaterSnapshot* instance = findInstance(); - if (!instance) - { - llassert(instance != NULL); - return; - } - LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance); + LLSnapshotLivePreview* previewp = getPreviewView(); if (!previewp) { llassert(previewp != NULL); @@ -1372,18 +1306,10 @@ void LLFloaterSnapshot::saveTexture() previewp->saveTexture(); } -// static BOOL LLFloaterSnapshot::saveLocal() { LL_DEBUGS() << "saveLocal" << LL_ENDL; - // FIXME: duplicated code - LLFloaterSnapshot* instance = findInstance(); - if (!instance) - { - llassert(instance != NULL); - return FALSE; - } - LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance); + LLSnapshotLivePreview* previewp = getPreviewView(); if (!previewp) { llassert(previewp != NULL); @@ -1393,57 +1319,32 @@ BOOL LLFloaterSnapshot::saveLocal() return previewp->saveLocal(); } -// static -void LLFloaterSnapshot::postSave() +void LLFloaterSnapshotBase::postSave() { - LLFloaterSnapshot* instance = findInstance(); - if (!instance) - { - llassert(instance != NULL); - return; - } - - instance->impl.updateControls(instance); - instance->impl.setStatus(Impl::STATUS_WORKING); + impl->updateControls(this); + impl->setStatus(ImplBase::STATUS_WORKING); } -// static -void LLFloaterSnapshot::postPanelSwitch() +// virtual +void LLFloaterSnapshotBase::postPanelSwitch() { - LLFloaterSnapshot* instance = getInstance(); - instance->impl.updateControls(instance); + impl->updateControls(this); // Remove the success/failure indicator whenever user presses a snapshot option button. - instance->impl.setStatus(Impl::STATUS_READY); + impl->setStatus(ImplBase::STATUS_READY); } -// static -void LLFloaterSnapshot::inventorySaveFailed() +void LLFloaterSnapshotBase::inventorySaveFailed() { - LLFloaterSnapshot* instance = findInstance(); - if (!instance) - { - llassert(instance != NULL); - return; - } - - instance->impl.updateControls(instance); - instance->impl.setStatus(Impl::STATUS_FINISHED, false, "inventory"); + impl->updateControls(this); + impl->setStatus(ImplBase::STATUS_FINISHED, false, "inventory"); } -// static -LLPointer<LLImageFormatted> LLFloaterSnapshot::getImageData() +LLPointer<LLImageFormatted> LLFloaterSnapshotBase::getImageData() { // FIXME: May not work for textures. - LLFloaterSnapshot* instance = findInstance(); - if (!instance) - { - llassert(instance != NULL); - return NULL; - } - - LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance); + LLSnapshotLivePreview* previewp = getPreviewView(); if (!previewp) { llassert(previewp != NULL); @@ -1460,17 +1361,9 @@ LLPointer<LLImageFormatted> LLFloaterSnapshot::getImageData() return img; } -// static -const LLVector3d& LLFloaterSnapshot::getPosTakenGlobal() +const LLVector3d& LLFloaterSnapshotBase::getPosTakenGlobal() { - LLFloaterSnapshot* instance = findInstance(); - if (!instance) - { - llassert(instance != NULL); - return LLVector3d::zero; - } - - LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance); + LLSnapshotLivePreview* previewp = getPreviewView(); if (!previewp) { llassert(previewp != NULL); @@ -1504,6 +1397,7 @@ LLSnapshotFloaterView::~LLSnapshotFloaterView() { } +// virtual BOOL LLSnapshotFloaterView::handleKey(KEY key, MASK mask, BOOL called_from_parent) { // use default handler when not in freeze-frame mode @@ -1525,6 +1419,7 @@ BOOL LLSnapshotFloaterView::handleKey(KEY key, MASK mask, BOOL called_from_paren return TRUE; } +// virtual BOOL LLSnapshotFloaterView::handleMouseDown(S32 x, S32 y, MASK mask) { // use default handler when not in freeze-frame mode @@ -1540,6 +1435,7 @@ BOOL LLSnapshotFloaterView::handleMouseDown(S32 x, S32 y, MASK mask) return TRUE; } +// virtual BOOL LLSnapshotFloaterView::handleMouseUp(S32 x, S32 y, MASK mask) { // use default handler when not in freeze-frame mode @@ -1555,6 +1451,7 @@ BOOL LLSnapshotFloaterView::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } +// virtual BOOL LLSnapshotFloaterView::handleHover(S32 x, S32 y, MASK mask) { // use default handler when not in freeze-frame mode diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index eb3a94999b0842c6365da43b5c29732b3a379651..1f303ea4d6532d34193e8afaf7fce11ca7563628 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2016, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,54 +27,184 @@ #ifndef LL_LLFLOATERSNAPSHOT_H #define LL_LLFLOATERSNAPSHOT_H +#include "llagent.h" #include "llfloater.h" +#include "llpanelsnapshot.h" +#include "llsnapshotmodel.h" class LLSpinCtrl; +class LLSnapshotLivePreview; -class LLFloaterSnapshot : public LLFloater +class LLFloaterSnapshotBase : public LLFloater { - LOG_CLASS(LLFloaterSnapshot); + LOG_CLASS(LLFloaterSnapshotBase); + +public: + + LLFloaterSnapshotBase(const LLSD& key); + virtual ~LLFloaterSnapshotBase(); + + /*virtual*/ void draw(); + /*virtual*/ void onClose(bool app_quitting); + virtual S32 notify(const LLSD& info); + + // TODO: create a snapshot model instead + virtual void saveTexture() = 0; + void postSave(); + virtual void postPanelSwitch(); + LLPointer<LLImageFormatted> getImageData(); + LLSnapshotLivePreview* getPreviewView(); + const LLVector3d& getPosTakenGlobal(); + + const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } + void setRefreshLabelVisible(bool value) { mRefreshLabel->setVisible(value); } + void setSuccessLabelPanelVisible(bool value) { mSucceessLblPanel->setVisible(value); } + void setFailureLabelPanelVisible(bool value) { mFailureLblPanel->setVisible(value); } + void inventorySaveFailed(); + + class ImplBase; + friend class ImplBase; + ImplBase* impl; + +protected: + LLUICtrl* mThumbnailPlaceholder; + LLUICtrl *mRefreshBtn, *mRefreshLabel; + LLUICtrl *mSucceessLblPanel, *mFailureLblPanel; +}; + +class LLFloaterSnapshotBase::ImplBase +{ public: - typedef enum e_snapshot_format + typedef enum e_status { - SNAPSHOT_FORMAT_PNG, - SNAPSHOT_FORMAT_JPEG, - SNAPSHOT_FORMAT_BMP - } ESnapshotFormat; + STATUS_READY, + STATUS_WORKING, + STATUS_FINISHED + } EStatus; + + ImplBase(LLFloaterSnapshotBase* floater) : mAvatarPauseHandles(), + mLastToolset(NULL), + mAspectRatioCheckOff(false), + mNeedRefresh(false), + mStatus(STATUS_READY), + mFloater(floater) + {} + virtual ~ImplBase() + { + //unpause avatars + mAvatarPauseHandles.clear(); + } + + static void onClickNewSnapshot(void* data); + static void onClickAutoSnap(LLUICtrl *ctrl, void* data); + static void onClickFilter(LLUICtrl *ctrl, void* data); + static void onClickUICheck(LLUICtrl *ctrl, void* data); + static void onClickHUDCheck(LLUICtrl *ctrl, void* data); + static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data); + + virtual LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) = 0; + virtual LLSnapshotModel::ESnapshotType getActiveSnapshotType(LLFloaterSnapshotBase* floater); + virtual LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater) = 0; + virtual std::string getSnapshotPanelPrefix() = 0; + + LLSnapshotLivePreview* getPreviewView(); + virtual void updateControls(LLFloaterSnapshotBase* floater) = 0; + virtual void updateLayout(LLFloaterSnapshotBase* floater); + virtual void updateLivePreview(); + virtual void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null); + virtual EStatus getStatus() const { return mStatus; } + virtual void setNeedRefresh(bool need); + + static BOOL updatePreviewList(bool initialized); + + void setAdvanced(bool advanced) { mAdvanced = advanced; } + + virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0; + virtual void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); + void setWorking(bool working); + virtual void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null) = 0; + +public: + LLFloaterSnapshotBase* mFloater; + std::vector<LLAnimPauseRequest> mAvatarPauseHandles; + + LLToolset* mLastToolset; + LLHandle<LLView> mPreviewHandle; + bool mAspectRatioCheckOff; + bool mNeedRefresh; + bool mAdvanced; + EStatus mStatus; +}; + +class LLFloaterSnapshot : public LLFloaterSnapshotBase +{ + LOG_CLASS(LLFloaterSnapshot); +public: LLFloaterSnapshot(const LLSD& key); - virtual ~LLFloaterSnapshot(); + /*virtual*/ ~LLFloaterSnapshot(); /*virtual*/ BOOL postBuild(); - /*virtual*/ void draw(); /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); /*virtual*/ S32 notify(const LLSD& info); static void update(); - // TODO: create a snapshot model instead + void onExtendFloater(); + static LLFloaterSnapshot* getInstance(); static LLFloaterSnapshot* findInstance(); - static void saveTexture(); - static BOOL saveLocal(); - static void postSave(); - static void postPanelSwitch(); - static void inventorySaveFailed(); - static LLPointer<LLImageFormatted> getImageData(); - static const LLVector3d& getPosTakenGlobal(); + /*virtual*/ void saveTexture(); + BOOL saveLocal(); static void setAgentEmail(const std::string& email); - static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); } + class Impl; + friend class Impl; +}; -private: - static LLUICtrl* sThumbnailPlaceholder; - LLUICtrl *mRefreshBtn, *mRefreshLabel; - LLUICtrl *mSucceessLblPanel, *mFailureLblPanel; +///---------------------------------------------------------------------------- +/// Class LLFloaterSnapshot::Impl +///---------------------------------------------------------------------------- - class Impl; - Impl& impl; +class LLFloaterSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase +{ + LOG_CLASS(LLFloaterSnapshot::Impl); +public: + Impl(LLFloaterSnapshotBase* floater) + : LLFloaterSnapshotBase::ImplBase(floater) + {} + ~Impl() + {} + + void applyKeepAspectCheck(LLFloaterSnapshotBase* view, BOOL checked); + void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE); + static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); + void onImageQualityChange(LLFloaterSnapshotBase* view, S32 quality_val); + void onImageFormatChange(LLFloaterSnapshotBase* view); + void applyCustomResolution(LLFloaterSnapshotBase* view, S32 w, S32 h); + static void onSendingPostcardFinished(LLFloaterSnapshotBase* floater, bool status); + BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); + void setImageSizeSpinnersValues(LLFloaterSnapshotBase *view, S32 width, S32 height); + void updateSpinners(LLFloaterSnapshotBase* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed); + static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status); + + /*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true); + /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater); + LLSpinCtrl* getWidthSpinner(LLFloaterSnapshotBase* floater); + LLSpinCtrl* getHeightSpinner(LLFloaterSnapshotBase* floater); + void enableAspectRatioCheckbox(LLFloaterSnapshotBase* floater, BOOL enable); + void setAspectRatioCheckboxValue(LLFloaterSnapshotBase* floater, BOOL checked); + /*virtual*/ std::string getSnapshotPanelPrefix(); + + void setResolution(LLFloaterSnapshotBase* floater, const std::string& comboname); + /*virtual*/ void updateControls(LLFloaterSnapshotBase* floater); + +private: + /*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater); + void comboSetCustom(LLFloaterSnapshotBase *floater, const std::string& comboname); + void checkAspectRatio(LLFloaterSnapshotBase *view, S32 index); + void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null); }; class LLSnapshotFloaterView : public LLFloaterView diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 987a7449ee7804335b60ad899d9d54f3816b0fa3..b14b9b7578eaac034bee5ac0b6af0b43de2d347f 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -1177,7 +1177,12 @@ void LLFloaterTools::updateLandImpacts() S32 rezzed_prims = parcel->getSimWidePrimCount(); S32 total_capacity = parcel->getSimWideMaxPrimCapacity(); - + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + if (region) + { + S32 max_tasks_per_region = (S32)region->getMaxTasks(); + total_capacity = llmin(total_capacity, max_tasks_per_region); + } std::string remaining_capacity_str = ""; bool show_mesh_cost = gMeshRepo.meshRezEnabled(); diff --git a/indra/newview/llfloatertwitter.cpp b/indra/newview/llfloatertwitter.cpp index c48b1a3325320c8e62e16f5188701e3152794e6e..4bab89ace220177482acbe25de207578f7119e8d 100644 --- a/indra/newview/llfloatertwitter.cpp +++ b/indra/newview/llfloatertwitter.cpp @@ -241,8 +241,8 @@ void LLTwitterPhotoPanel::onVisibilityChange(BOOL visible) mPreviewHandle = previewp->getHandle(); previewp->setContainer(this); - previewp->setSnapshotType(previewp->SNAPSHOT_WEB); - previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG); + previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB); + previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_JPEG); previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index 024e315632812112cd6bbe12e206adb7ac0b5724..dece3fc1ea69fe736613c58ac2c22a92af792594 100644 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -55,7 +55,8 @@ LLFloaterWebContent::_Params::_Params() preferred_media_size("preferred_media_size"), trusted_content("trusted_content", false), show_page_title("show_page_title", true), - clean_browser("clean_browser", false) + clean_browser("clean_browser", false), + dev_mode("dev_mode", false) {} LLFloaterWebContent::LLFloaterWebContent( const Params& params ) @@ -74,14 +75,16 @@ LLFloaterWebContent::LLFloaterWebContent( const Params& params ) mShowPageTitle(params.show_page_title), mAllowNavigation(true), mCurrentURL(""), - mDisplayURL("") + mDisplayURL(""), + mDevelopMode(params.dev_mode) // if called from "Develop" Menu, set a flag and change things to be more useful for devs { mCommitCallbackRegistrar.add( "WebContent.Back", boost::bind( &LLFloaterWebContent::onClickBack, this )); mCommitCallbackRegistrar.add( "WebContent.Forward", boost::bind( &LLFloaterWebContent::onClickForward, this )); mCommitCallbackRegistrar.add( "WebContent.Reload", boost::bind( &LLFloaterWebContent::onClickReload, this )); mCommitCallbackRegistrar.add( "WebContent.Stop", boost::bind( &LLFloaterWebContent::onClickStop, this )); mCommitCallbackRegistrar.add( "WebContent.EnterAddress", boost::bind( &LLFloaterWebContent::onEnterAddress, this )); - mCommitCallbackRegistrar.add( "WebContent.PopExternal", boost::bind( &LLFloaterWebContent::onPopExternal, this )); + mCommitCallbackRegistrar.add( "WebContent.PopExternal", boost::bind(&LLFloaterWebContent::onPopExternal, this)); + mCommitCallbackRegistrar.add( "WebContent.TestURL", boost::bind(&LLFloaterWebContent::onTestURL, this, _2)); } BOOL LLFloaterWebContent::postBuild() @@ -195,8 +198,6 @@ void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height) width + getRect().getWidth() - browser_rect.getWidth(), height + getRect().getHeight() - browser_rect.getHeight()); - LL_DEBUGS() << "geometry change: " << geom << LL_ENDL; - LLRect new_rect; getParent()->screenRectToLocal(geom, &new_rect); setShape(new_rect); @@ -205,8 +206,6 @@ void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height) // static void LLFloaterWebContent::preCreate(LLFloaterWebContent::Params& p) { - LL_DEBUGS() << "url = " << p.url() << ", target = " << p.target() << ", uuid = " << p.id() << LL_ENDL; - if (!p.id.isProvided()) { p.id = LLUUID::generateNewID().asString(); @@ -224,12 +223,6 @@ void LLFloaterWebContent::preCreate(LLFloaterWebContent::Params& p) // and close the least recently opened one if this will put us over the limit. LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList(p.window_class); - LL_DEBUGS() << "total instance count is " << instances.size() << LL_ENDL; - - for(LLFloaterReg::const_instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); iter++) - { - LL_DEBUGS() << " " << (*iter)->getKey()["target"] << LL_ENDL; - } if(instances.size() >= (size_t)browser_window_limit) { @@ -241,16 +234,19 @@ void LLFloaterWebContent::preCreate(LLFloaterWebContent::Params& p) void LLFloaterWebContent::open_media(const Params& p) { - // Specifying a mime type of text/html here causes the plugin system to skip the MIME type probe and just open a browser plugin. LLViewerMedia::proxyWindowOpened(p.target(), p.id()); - mWebBrowser->setHomePageUrl(p.url, HTTP_CONTENT_TEXT_HTML); + mWebBrowser->setHomePageUrl(p.url); mWebBrowser->setTarget(p.target); - mWebBrowser->navigateTo(p.url, HTTP_CONTENT_TEXT_HTML, p.clean_browser); + mWebBrowser->navigateTo(p.url); set_current_url(p.url); getChild<LLLayoutPanel>("status_bar")->setVisible(p.show_chrome); getChild<LLLayoutPanel>("nav_controls")->setVisible(p.show_chrome); + + // turn additional debug controls on but only for Develop mode (Develop menu open) + getChild<LLLayoutPanel>("debug_controls")->setVisible(mDevelopMode); + bool address_entry_enabled = p.allow_address_entry && !p.trusted_content; mAllowNavigation = p.allow_back_forward_navigation; getChildView("address")->setEnabled(address_entry_enabled); @@ -499,7 +495,7 @@ void LLFloaterWebContent::onEnterAddress() LLStringUtil::trim(url); if ( url.length() > 0 ) { - mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); + mWebBrowser->navigateTo(url); }; } @@ -508,9 +504,18 @@ void LLFloaterWebContent::onPopExternal() // make sure there is at least something there. // (perhaps this test should be for minimum length of a URL) std::string url = mAddressCombo->getValue().asString(); - LLStringUtil::trim(url); - if ( url.length() > 0 ) + LLStringUtil::trim(url); + if (url.length() > 0) + { + LLWeb::loadURLExternal(url); + }; +} + +void LLFloaterWebContent::onTestURL(std::string url) +{ + LLStringUtil::trim(url); + if (url.length() > 0) { - LLWeb::loadURLExternal( url ); + mWebBrowser->navigateTo(url); }; } diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h index 4291fd9f2c391f56a7c2baaa2b640f2a9adffeaf..0bf93504c28623293b7e7360d61948041f09dc85 100644 --- a/indra/newview/llfloaterwebcontent.h +++ b/indra/newview/llfloaterwebcontent.h @@ -58,7 +58,8 @@ class LLFloaterWebContent : allow_back_forward_navigation, trusted_content, show_page_title, - clean_browser; + clean_browser, + dev_mode; Optional<LLRect> preferred_media_size; _Params(); @@ -92,6 +93,7 @@ class LLFloaterWebContent : void onClickStop(); void onEnterAddress(); void onPopExternal(); + void onTestURL(std::string url); static void preCreate(Params& p); void open_media(const Params& ); @@ -113,6 +115,7 @@ class LLFloaterWebContent : std::string mUUID; bool mShowPageTitle; bool mAllowNavigation; + bool mDevelopMode; }; #endif // LL_LLFLOATERWEBCONTENT_H diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index c67feb8158ba72f95199cd4d157278911a6dd5fd..d89fa03c1aad0689ff745bcc8a6b1ce082a039c9 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -558,7 +558,7 @@ void LLFloaterWorldMap::trackAvatar( const LLUUID& avatar_id, const std::string& } else { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } setDefaultBtn("Teleport"); } @@ -602,7 +602,7 @@ void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id ) } else { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } setDefaultBtn("Teleport"); } @@ -628,7 +628,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) if (!sim_info) { // We haven't found a region for that point yet, leave the tracking to the world map - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); LLWorldMap::getInstance()->setTracking(pos_global); S32 world_x = S32(pos_global.mdV[0] / 256); S32 world_y = S32(pos_global.mdV[1] / 256); @@ -644,7 +644,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) { // Down region. Show the blue circle of death! // i.e. let the world map that this and tell it it's invalid - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); LLWorldMap::getInstance()->setTracking(pos_global); LLWorldMap::getInstance()->setTrackingInvalid(); setDefaultBtn(""); @@ -863,7 +863,7 @@ void LLFloaterWorldMap::friendsChanged() (buddy_info && !buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)) || gAgent.isGodlike()) { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } } } @@ -1070,7 +1070,7 @@ void LLFloaterWorldMap::onLandmarkComboPrearrange( ) if( current_choice.isNull() || !list->setCurrentByID( current_choice ) ) { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } } @@ -1080,7 +1080,7 @@ void LLFloaterWorldMap::onComboTextEntry() // Reset the tracking whenever we start typing into any of the search fields, // so that hitting <enter> does an auto-complete versus teleporting us to the // previously selected landmark/friend. - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } void LLFloaterWorldMap::onSearchTextEntry( ) @@ -1103,7 +1103,7 @@ void LLFloaterWorldMap::onLandmarkComboCommit() LLUUID asset_id; LLUUID item_id = list->getCurrentID(); - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); //RN: stopTracking() clears current combobox selection, need to reassert it here list->setCurrentByID(item_id); @@ -1158,7 +1158,7 @@ void LLFloaterWorldMap::onAvatarComboPrearrange( ) if( !list->setCurrentByID( current_choice ) || current_choice.isNull() ) { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } } @@ -1271,7 +1271,7 @@ void LLFloaterWorldMap::onCoordinatesCommit() void LLFloaterWorldMap::onClearBtn() { mTrackedStatus = LLTracker::TRACKING_NOTHING; - LLTracker::stopTracking((void *)(intptr_t)TRUE); + LLTracker::stopTracking(true); LLWorldMap::getInstance()->cancelTracking(); mSLURL = LLSLURL(); // Clear the SLURL since it's invalid mSetToUserPosition = TRUE; // Revert back to the current user position diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h index ae3800e17badd84b298351641c0280a708419142..2fb912a93048b87340a4b6e4e8d32e0a230f14f6 100644 --- a/indra/newview/llfriendcard.h +++ b/indra/newview/llfriendcard.h @@ -37,9 +37,10 @@ class LLFriendCardsManager : public LLSingleton<LLFriendCardsManager> , public LLFriendObserver { + LLSINGLETON(LLFriendCardsManager); + ~LLFriendCardsManager(); LOG_CLASS(LLFriendCardsManager); - friend class LLSingleton<LLFriendCardsManager>; friend class CreateFriendCardCallback; public: @@ -97,8 +98,6 @@ class LLFriendCardsManager private: typedef boost::function<void()> callback_t; - LLFriendCardsManager(); - ~LLFriendCardsManager(); /** diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index 26a5924ec307f4c499ad792586267f890e8b1fe4..402bdf6039952df5e1391eaddaf190df64b74514 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -51,6 +51,8 @@ class LLGestureManagerObserver class LLGestureMgr : public LLSingleton<LLGestureMgr>, public LLInventoryFetchItemsObserver { + LLSINGLETON(LLGestureMgr); + ~LLGestureMgr(); public: typedef boost::function<void (LLMultiGesture* loaded_gesture)> gesture_loaded_callback_t; @@ -58,8 +60,6 @@ class LLGestureMgr : public LLSingleton<LLGestureMgr>, public LLInventoryFetchIt typedef std::map<LLUUID, LLMultiGesture*> item_map_t; typedef std::map<LLUUID, gesture_loaded_callback_t> callback_map_t; - LLGestureMgr(); - ~LLGestureMgr(); void init(); diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp index 271dd44c1f94ae013ece7998bbc8659f7bc5ad86..7c2a3cad43b79a30da54b2f8099e533706c5136e 100644 --- a/indra/newview/llgroupiconctrl.cpp +++ b/indra/newview/llgroupiconctrl.cpp @@ -74,9 +74,16 @@ LLGroupIconCtrl::~LLGroupIconCtrl() LLGroupMgr::getInstance()->removeObserver(this); } -void LLGroupIconCtrl::setIconId(const LLSD& value) +void LLGroupIconCtrl::setIconId(const LLUUID& icon_id) { - LLIconCtrl::setValue(value); + if (icon_id.notNull()) + { + LLIconCtrl::setValue(icon_id); + } + else + { + LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); + } } void LLGroupIconCtrl::setValue(const LLSD& value) @@ -122,14 +129,7 @@ bool LLGroupIconCtrl::updateFromCache() LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mGroupId); if (!group_data) return false; - if (group_data->mInsigniaID.notNull()) - { - LLIconCtrl::setValue(group_data->mInsigniaID); - } - else - { - LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); - } + setIconId(group_data->mInsigniaID); if (mDrawTooltip && !group_data->mName.empty()) { diff --git a/indra/newview/llgroupiconctrl.h b/indra/newview/llgroupiconctrl.h index f8b22cf581e60f7dcb6d57f5fa7d3c74415a2706..43e384d3e277746ef77889f5a23ea01d8d1484da 100644 --- a/indra/newview/llgroupiconctrl.h +++ b/indra/newview/llgroupiconctrl.h @@ -66,7 +66,13 @@ class LLGroupIconCtrl */ virtual void setValue(const LLSD& value); - void setIconId(const LLSD& value); + /** + * Sets icon_id as icon value directly. Avoids LLGroupMgr cache checks for group id + * Uses default icon in case id is null. + * + * @params icon_id - it is processed as icon id, default image will be used in case id is null. + */ + void setIconId(const LLUUID& icon_id); // LLGroupMgrObserver observer trigger virtual void changed(LLGroupChange gc); diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 6126db2988c98e9e3b7e47310d3e40ffbc7f925d..62414d3bbb745e3e2b607e59321f09abbd0f161c 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -379,10 +379,7 @@ void LLGroupListItem::setGroupID(const LLUUID& group_id) void LLGroupListItem::setGroupIconID(const LLUUID& group_icon_id) { - if (group_icon_id.notNull()) - { - mGroupIcon->setIconId(group_icon_id); - } + mGroupIcon->setIconId(group_icon_id); } void LLGroupListItem::setGroupIconVisible(bool visible) diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index e5ce76803582042cf1915ec41a9db05c303bf25d..940ef6eea13af48a80782c117585e3aed2235b8c 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -348,6 +348,8 @@ struct LLRoleActionSet class LLGroupMgr : public LLSingleton<LLGroupMgr> { + LLSINGLETON(LLGroupMgr); + ~LLGroupMgr(); LOG_CLASS(LLGroupMgr); public: @@ -369,8 +371,6 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr> public: - LLGroupMgr(); - ~LLGroupMgr(); void addObserver(LLGroupMgrObserver* observer); void addObserver(const LLUUID& group_id, LLParticularGroupObserver* observer); diff --git a/indra/newview/llhints.h b/indra/newview/llhints.h index ebffe561b9513d1d8fbe92c3640129d10d74e00b..dd6195a9ce37e782287df50b334dd7e61a5f8be4 100644 --- a/indra/newview/llhints.h +++ b/indra/newview/llhints.h @@ -29,6 +29,7 @@ #include "llpanel.h" #include "llnotifications.h" +#include "llinitdestroyclass.h" class LLHints : public LLInitClass<LLHints> diff --git a/indra/newview/llhudmanager.h b/indra/newview/llhudmanager.h index 9c5d49decd0aff979431310167fdacb95fcc520e..7782739690dca1e83e31da5120262d70e4870c19 100644 --- a/indra/newview/llhudmanager.h +++ b/indra/newview/llhudmanager.h @@ -36,10 +36,10 @@ class LLMessageSystem; class LLHUDManager : public LLSingleton<LLHUDManager> { -public: - LLHUDManager(); + LLSINGLETON(LLHUDManager); ~LLHUDManager(); +public: LLHUDEffect *createViewerEffect(const U8 type, BOOL send_to_sim = TRUE, BOOL originated_here = TRUE); void updateEffects(); diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 52e83fe412c78971a2f729c7e3f200f353ad765b..6b1e196182dc9b74929253c6685fa0956c9dcaac 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -53,7 +53,7 @@ const F32 VERTICAL_PADDING = 12.f; const F32 BUFFER_SIZE = 2.f; const F32 HUD_TEXT_MAX_WIDTH = 190.f; const F32 HUD_TEXT_MAX_WIDTH_NO_BUBBLE = 1000.f; -const F32 MAX_DRAW_DISTANCE = 64.f; +const F32 MAX_DRAW_DISTANCE = 300.f; std::set<LLPointer<LLHUDText> > LLHUDText::sTextObjects; std::vector<LLPointer<LLHUDText> > LLHUDText::sVisibleTextObjects; @@ -394,7 +394,20 @@ void LLHUDText::updateVisibility() LLVector3 pos_agent_center = gAgent.getPosAgentFromGlobal(mPositionGlobal) - dir_from_camera; F32 last_distance_center = (pos_agent_center - LLViewerCamera::getInstance()->getOrigin()).magVec(); - if(last_distance_center > MAX_DRAW_DISTANCE) + F32 max_draw_distance = gSavedSettings.getF32("PrimTextMaxDrawDistance"); + + if(max_draw_distance < 0) + { + max_draw_distance = 0; + gSavedSettings.setF32("PrimTextMaxDrawDistance", max_draw_distance); + } + else if(max_draw_distance > MAX_DRAW_DISTANCE) + { + max_draw_distance = MAX_DRAW_DISTANCE; + gSavedSettings.setF32("PrimTextMaxDrawDistance", MAX_DRAW_DISTANCE); + } + + if(last_distance_center > max_draw_distance) { mVisible = FALSE; return; diff --git a/indra/newview/llimagefiltersmanager.h b/indra/newview/llimagefiltersmanager.h index 4751933065bfa9c8fa9635d3a5f550e10238da0d..f1ed3cf1c395cdbac8a695ba45942fcdcf34e886 100644 --- a/indra/newview/llimagefiltersmanager.h +++ b/indra/newview/llimagefiltersmanager.h @@ -34,6 +34,8 @@ class LLImageFiltersManager : public LLSingleton<LLImageFiltersManager> { + LLSINGLETON(LLImageFiltersManager); + ~LLImageFiltersManager(); LOG_CLASS(LLImageFiltersManager); public: const std::vector<std::string> getFiltersList() const; @@ -43,10 +45,7 @@ class LLImageFiltersManager : public LLSingleton<LLImageFiltersManager> void loadAllFilters(); void loadFiltersFromDir(const std::string& dir); - friend class LLSingleton<LLImageFiltersManager>; /*virtual*/ void initSingleton(); - LLImageFiltersManager(); - ~LLImageFiltersManager(); // List of filters : first is the user friendly localized name, second is the xml file name std::map<std::string,std::string> mFiltersList; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 951389b8568059c8e5473d3b9ba68561bbba059e..2405c3a1a3630ca31c92a2c6550f3eeba31ee27d 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -2354,7 +2354,13 @@ void LLIncomingCallDialog::onAvatarNameCache(const LLUUID& agent_id, void LLIncomingCallDialog::onOpen(const LLSD& key) { LLCallDialog::onOpen(key); - make_ui_sound("UISndStartIM"); + + if (gSavedSettings.getBOOL("PlaySoundIncomingVoiceCall")) + { + // play a sound for incoming voice call if respective property is set + make_ui_sound("UISndStartIM"); + } + LLStringUtil::format_map_t args; LLGroupData data; // if it's a group call, retrieve group name to use it in question diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 41a8813acb2b4ac2cb933c673eca32735f017c52..da40ac83931f38e3258516b4412e8732ac562052 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -33,6 +33,7 @@ #include "lllogchat.h" #include "llvoicechannel.h" +#include "llinitdestroyclass.h" #include "llcoros.h" #include "lleventcoro.h" @@ -61,6 +62,7 @@ class LLSessionTimeoutTimer : public LLEventTimer */ class LLIMModel : public LLSingleton<LLIMModel> { + LLSINGLETON(LLIMModel); public: struct LLIMSession : public boost::signals2::trackable @@ -151,7 +153,6 @@ class LLIMModel : public LLSingleton<LLIMModel> }; - LLIMModel(); /** Session id to session object */ std::map<LLUUID, LLIMSession*> mId2SessionMap; @@ -312,6 +313,7 @@ class LLIMSessionObserver class LLIMMgr : public LLSingleton<LLIMMgr> { + LLSINGLETON(LLIMMgr); friend class LLIMModel; public: @@ -322,8 +324,6 @@ class LLIMMgr : public LLSingleton<LLIMMgr> INVITATION_TYPE_IMMEDIATE = 2 }; - LLIMMgr(); - virtual ~LLIMMgr() {}; // Add a message to a session. The session can keyed to sesion id // or agent id. diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp index 8e91af321e294953659a2d74b7b22647f7ef2cf8..a4fce36783f4d6202fea59e52791c994f0c3362a 100644 --- a/indra/newview/llinspectgroup.cpp +++ b/indra/newview/llinspectgroup.cpp @@ -41,6 +41,7 @@ #include "lltooltip.h" // positionViewNearMouse() #include "lltrans.h" #include "lluictrl.h" +#include "llgroupiconctrl.h" ////////////////////////////////////////////////////////////////////////////// // LLInspectGroup @@ -233,7 +234,7 @@ void LLInspectGroup::processGroupData() getChild<LLUICtrl>("group_details")->setValue( LLSD(data->mCharter) ); - getChild<LLUICtrl>("group_icon")->setValue( LLSD(data->mInsigniaID) ); + getChild<LLGroupIconCtrl>("group_icon")->setIconId(data->mInsigniaID); std::string cost; bool is_member = LLGroupActions::isInGroup(mGroupID); diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp index a12ec390af477035e79523785c88b3b511d1ad58..b64df2bd47176affd6fcfc24bb7de8f2f3c24d1f 100644 --- a/indra/newview/llinspectremoteobject.cpp +++ b/indra/newview/llinspectremoteobject.cpp @@ -181,7 +181,7 @@ void LLInspectRemoteObject::update() getChild<LLUICtrl>("map_btn")->setEnabled(! mSLurl.empty()); // disable the Block button if we don't have the object ID (will this ever happen?) - getChild<LLUICtrl>("block_btn")->setEnabled(! mObjectID.isNull()); + getChild<LLUICtrl>("block_btn")->setEnabled(!mObjectID.isNull() && !LLMuteList::getInstance()->isMuted(mObjectID)); } ////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 26c9b40fb1dfee804f43f93a78cb1cf61fef2a33..1de579d4c3bb1a7c3739e803499beba7328bbe6e 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -41,6 +41,7 @@ #include "llfloateropenobject.h" #include "llfloaterreg.h" #include "llfloatermarketplacelistings.h" +#include "llfloateroutfitphotopreview.h" #include "llfloatersidepanelcontainer.h" #include "llfloaterworldmap.h" #include "llfolderview.h" @@ -286,6 +287,16 @@ BOOL LLInvFVBridge::cutToClipboard() return FALSE; } +// virtual +bool LLInvFVBridge::isCutToClipboard() +{ + if (LLClipboard::instance().isCutMode()) + { + return LLClipboard::instance().isOnClipboard(mUUID); + } + return false; +} + // Callback for cutToClipboard if DAMA required... BOOL LLInvFVBridge::callback_cutToClipboard(const LLSD& notification, const LLSD& response) { @@ -307,9 +318,7 @@ BOOL LLInvFVBridge::perform_cutToClipboard() if (obj && isItemMovable() && isItemRemovable()) { LLClipboard::instance().setCutMode(true); - BOOL added_to_clipboard = LLClipboard::instance().addToClipboard(mUUID); - removeObject(&gInventory, mUUID); // Always perform the remove even if the object couldn't make it to the clipboard - return added_to_clipboard; + return LLClipboard::instance().addToClipboard(mUUID); } return FALSE; } @@ -1390,6 +1399,12 @@ bool LLInvFVBridge::canShare() const // Categories can be given. can_share = (model->getCategory(mUUID) != NULL); } + + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if ((mUUID == trash_id) || gInventory.isObjectDescendentOf(mUUID, trash_id)) + { + can_share = false; + } } } @@ -1925,13 +1940,15 @@ BOOL LLItemBridge::removeItem() } // move it to the trash - LLPreview::hide(mUUID, TRUE); LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; const LLUUID& trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); LLViewerInventoryItem* item = getItem(); if (!item) return FALSE; - + if (item->getType() != LLAssetType::AT_LSL_TEXT) + { + LLPreview::hide(mUUID, TRUE); + } // Already in trash if (model->isObjectDescendentOf(mUUID, trash_id)) return FALSE; @@ -3076,6 +3093,10 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) LLAppearanceMgr::instance().takeOffOutfit( cat->getLinkedUUID() ); return; } + else if ("copyoutfittoclipboard" == action) + { + copyOutfitToClipboard(); + } else if ("purge" == action) { purgeItem(model, mUUID); @@ -3233,6 +3254,39 @@ void LLFolderBridge::gatherMessage(std::string& message, S32 depth, LLError::ELe } } +void LLFolderBridge::copyOutfitToClipboard() +{ + std::string text; + + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(mUUID, cat_array, item_array); + + S32 item_count(0); + if( item_array ) + { + item_count = item_array->size(); + } + + if (item_count) + { + for (S32 i = 0; i < item_count;) + { + LLSD uuid =item_array->at(i)->getUUID(); + LLViewerInventoryItem* item = gInventory.getItem(uuid); + + i++; + if (item != NULL) + { + // Append a newline to all but the last line + text += i != item_count ? item->getName() + "\n" : item->getName(); + } + } + } + + LLClipboard::instance().copyToClipboard(utf8str_to_wstring(text),0,text.size()); +} + void LLFolderBridge::openItem() { LL_DEBUGS() << "LLFolderBridge::openItem()" << LL_ENDL; @@ -3720,6 +3774,15 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items // This is the lost+found folder. items.push_back(std::string("Empty Lost And Found")); + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(mUUID, cat_array, item_array); + // Enable Empty menu item only when there is something to act upon. + if (0 == cat_array->size() && 0 == item_array->size()) + { + disabled_items.push_back(std::string("Empty Lost And Found")); + } + disabled_items.push_back(std::string("New Folder")); disabled_items.push_back(std::string("New Script")); disabled_items.push_back(std::string("New Note")); @@ -3764,6 +3827,15 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items { // This is the trash. items.push_back(std::string("Empty Trash")); + + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(mUUID, cat_array, item_array); + // Enable Empty menu item only when there is something to act upon. + if (0 == cat_array->size() && 0 == item_array->size()) + { + disabled_items.push_back(std::string("Empty Trash")); + } } else if(isItemInTrash()) { @@ -3813,6 +3885,11 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items } } + if (model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT) == mUUID) + { + items.push_back(std::string("Copy outfit list to clipboard")); + } + //Added by aura to force inventory pull on right-click to display folder options correctly. 07-17-06 mCallingCards = mWearables = FALSE; @@ -4358,10 +4435,13 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response // Returns true if the item can be moved to Current Outfit or any outfit folder. static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit) { - if ((inv_item->getInventoryType() != LLInventoryType::IT_WEARABLE) && - (inv_item->getInventoryType() != LLInventoryType::IT_GESTURE) && - (inv_item->getInventoryType() != LLInventoryType::IT_ATTACHMENT) && - (inv_item->getInventoryType() != LLInventoryType::IT_OBJECT)) + LLInventoryType::EType inv_type = inv_item->getInventoryType(); + if ((inv_type != LLInventoryType::IT_WEARABLE) && + (inv_type != LLInventoryType::IT_GESTURE) && + (inv_type != LLInventoryType::IT_ATTACHMENT) && + (inv_type != LLInventoryType::IT_OBJECT) && + (inv_type != LLInventoryType::IT_SNAPSHOT) && + (inv_type != LLInventoryType::IT_TEXTURE)) { return FALSE; } @@ -4372,6 +4452,11 @@ static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_curr return FALSE; } + if((inv_type == LLInventoryType::IT_TEXTURE) || (inv_type == LLInventoryType::IT_SNAPSHOT)) + { + return !move_is_into_current_outfit; + } + if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID())) { return FALSE; @@ -4422,6 +4507,20 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item) void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit) { + if((inv_item->getInventoryType() == LLInventoryType::IT_TEXTURE) || (inv_item->getInventoryType() == LLInventoryType::IT_SNAPSHOT)) + { + const LLUUID &my_outifts_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false); + if(mUUID != my_outifts_id) + { + LLFloaterOutfitPhotoPreview* photo_preview = LLFloaterReg::showTypedInstance<LLFloaterOutfitPhotoPreview>("outfit_photo_preview", inv_item->getUUID()); + if(photo_preview) + { + photo_preview->setOutfitID(mUUID); + } + } + return; + } + // BAP - should skip if dup. if (move_is_into_current_outfit) { diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 9053c61171f877141da63ed7398e3c1581829324..b7d8c9d034a8f6918496c56f525d26ee78532832 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -116,6 +116,7 @@ class LLInvFVBridge : public LLFolderViewModelItemInventory virtual BOOL isItemCopyable() const { return FALSE; } virtual BOOL copyToClipboard() const; virtual BOOL cutToClipboard(); + virtual bool isCutToClipboard(); virtual BOOL isClipboardPasteable() const; virtual BOOL isClipboardPasteableAsLink() const; virtual void pasteFromClipboard() {} @@ -343,6 +344,7 @@ class LLFolderBridge : public LLInvFVBridge BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck); void modifyOutfit(BOOL append); + void copyOutfitToClipboard(); void determineFolderType(); void dropToFavorites(LLInventoryItem* inv_item); diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 003bbcafeda23d8835e50eb263428251d2f8a7d5..e995c138b4e77305198ab1455f1e523bb8de3232 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -84,21 +84,18 @@ LLInventoryFilter::LLInventoryFilter(const Params& p) bool LLInventoryFilter::check(const LLFolderViewModelItem* item) { const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item); - // Clipboard cut items are *always* filtered so we need this value upfront - const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE); // If it's a folder and we're showing all folders, return automatically. const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY; if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)) { - return passed_clipboard; + return true; } bool passed = (mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) != std::string::npos : true); passed = passed && checkAgainstFilterType(listener); passed = passed && checkAgainstPermissions(listener); passed = passed && checkAgainstFilterLinks(listener); - passed = passed && passed_clipboard; return passed; } @@ -108,9 +105,8 @@ bool LLInventoryFilter::check(const LLInventoryItem* item) const bool passed_string = (mFilterSubString.size() ? item->getName().find(mFilterSubString) != std::string::npos : true); const bool passed_filtertype = checkAgainstFilterType(item); const bool passed_permissions = checkAgainstPermissions(item); - const bool passed_clipboard = checkAgainstClipboard(item->getUUID()); - return passed_filtertype && passed_permissions && passed_clipboard && passed_string; + return passed_filtertype && passed_permissions && passed_string; } bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const @@ -129,13 +125,10 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const { - // Always check against the clipboard - const BOOL passed_clipboard = checkAgainstClipboard(folder_id); - // we're showing all folders, overriding filter if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS) { - return passed_clipboard; + return true; } // when applying a filter, matching folders get their contents downloaded first @@ -201,7 +194,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const LLViewerInventoryItem* item = gInventory.getItem(folder_id); if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER) { - return passed_clipboard; + return true; } if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY) @@ -216,7 +209,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const return false; } - return passed_clipboard; + return true; } bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInventory* listener) const diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index d8f019374e234d2529b1d39f0a49dd19d579db20..f04d6cc753cf526a6f7f1bb475933085a9e3becb 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -48,7 +48,6 @@ #include "llavataractions.h" #include "llclipboard.h" #include "lldonotdisturbnotificationstorage.h" -#include "llfloaterinventory.h" #include "llfloatersidepanelcontainer.h" #include "llfocusmgr.h" #include "llfolderview.h" @@ -752,36 +751,13 @@ void show_item_original(const LLUUID& item_uuid) void reset_inventory_filter() { - //inventory floater - bool floater_inventory_visible = false; - - 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) + LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); + if (sidepanel_inventory) { - LLFloaterInventory* floater_inventory = dynamic_cast<LLFloaterInventory*>(*iter); - if (floater_inventory) + LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); + if (main_inventory) { - LLPanelMainInventory* main_inventory = floater_inventory->getMainInventoryPanel(); - main_inventory->onFilterEdit(""); - - if(floater_inventory->getVisible()) - { - floater_inventory_visible = true; - } - } - } - - if(!floater_inventory_visible) - { - LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); - if (sidepanel_inventory) - { - LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); - if (main_inventory) - { - main_inventory->onFilterEdit(""); - } } } } diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 013a5a7629afe0e0631d9440d8d76713c662162c..495180f087a50097dfb5ba052085baf71a1e5938 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -46,8 +46,7 @@ struct IconEntry : public LLDictionaryEntry class LLIconDictionary : public LLSingleton<LLIconDictionary>, public LLDictionary<LLInventoryType::EIconName, IconEntry> { -public: - LLIconDictionary(); + LLSINGLETON(LLIconDictionary); }; typedef LLPointer<LLUIImage> LLUIImagePtr; diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index 36e1cc97d1c6c582baaff39164cf56bba7420114..1dc1aa395e0de7e9da2ca75b7deb50373ce716ed 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -45,7 +45,7 @@ LLInventoryItemsList::Params::Params() LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p) : LLFlatListViewEx(p) -, mNeedsRefresh(false) +, mRefreshState(REFRESH_COMPLETE) , mForceRefresh(false) { // TODO: mCommitOnSelectionChange is set to "false" in LLFlatListView @@ -66,13 +66,13 @@ LLInventoryItemsList::~LLInventoryItemsList() void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array) { - getIDs().clear(); + getIDs().clear(); LLInventoryModel::item_array_t::const_iterator it = item_array.begin(); for( ; item_array.end() != it; ++it) { getIDs().push_back((*it)->getUUID()); } - mNeedsRefresh = true; + mRefreshState = REFRESH_ALL; } boost::signals2::connection LLInventoryItemsList::setRefreshCompleteCallback(const commit_signal_t::slot_type& cb) @@ -113,9 +113,9 @@ void LLInventoryItemsList::updateSelection() void LLInventoryItemsList::doIdle() { - if (!mNeedsRefresh) return; + if (mRefreshState == REFRESH_COMPLETE) return; - if (isInVisibleChain() || mForceRefresh) + if (isInVisibleChain() || mForceRefresh ) { refresh(); @@ -137,54 +137,130 @@ LLTrace::BlockTimerStatHandle FTM_INVENTORY_ITEMS_REFRESH("Inventory List Refres void LLInventoryItemsList::refresh() { - LL_RECORD_BLOCK_TIME(FTM_INVENTORY_ITEMS_REFRESH); - static const unsigned ADD_LIMIT = 20; - - uuid_vec_t added_items; - uuid_vec_t removed_items; - - computeDifference(getIDs(), added_items, removed_items); - - bool add_limit_exceeded = false; - unsigned int nadded = 0; - - uuid_vec_t::const_iterator it = added_items.begin(); - for( ; added_items.end() != it; ++it) - { - if(nadded >= ADD_LIMIT) - { - add_limit_exceeded = true; - break; - } - LLViewerInventoryItem* item = gInventory.getItem(*it); - // Do not rearrange items on each adding, let's do that on filter call - llassert(item); - if (item) - { - addNewItem(item, false); - ++nadded; - } - } - - it = removed_items.begin(); - for( ; removed_items.end() != it; ++it) - { - // don't filter items right away - removeItemByUUID(*it, false); - } - - // Filter, rearrange and notify parent about shape changes - filterItems(); - - bool needs_refresh = add_limit_exceeded; - setNeedsRefresh(needs_refresh); - setForceRefresh(needs_refresh); - - // After list building completed, select items that had been requested to select before list was build - if(!needs_refresh) - { - updateSelection(); - } + LL_RECORD_BLOCK_TIME(FTM_INVENTORY_ITEMS_REFRESH); + + switch (mRefreshState) + { + case REFRESH_ALL: + { + mAddedItems.clear(); + mRemovedItems.clear(); + computeDifference(getIDs(), mAddedItems, mRemovedItems); + if (mRemovedItems.size() > 0) + { + mRefreshState = REFRESH_LIST_ERASE; + } + else if (mAddedItems.size() > 0) + { + mRefreshState = REFRESH_LIST_APPEND; + } + else + { + mRefreshState = REFRESH_LIST_SORT; + } + + rearrangeItems(); + notifyParentItemsRectChanged(); + break; + } + case REFRESH_LIST_ERASE: + { + uuid_vec_t::const_iterator it = mRemovedItems.begin(); + for (; mRemovedItems.end() != it; ++it) + { + // don't filter items right away + removeItemByUUID(*it, false); + } + mRemovedItems.clear(); + mRefreshState = REFRESH_LIST_SORT; // fix visibility and arrange + break; + } + case REFRESH_LIST_APPEND: + { + static const unsigned ADD_LIMIT = 25; // Note: affects perfomance + + unsigned int nadded = 0; + + // form a list to add + uuid_vec_t::iterator it = mAddedItems.begin(); + pairs_list_t panel_list; + while(mAddedItems.size() > 0 && nadded < ADD_LIMIT) + { + LLViewerInventoryItem* item = gInventory.getItem(*it); + llassert(item); + if (item) + { + LLPanel *list_item = createNewItem(item); + if (list_item) + { + item_pair_t* new_pair = new item_pair_t(list_item, item->getUUID()); + panel_list.push_back(new_pair); + ++nadded; + } + } + + it = mAddedItems.erase(it); + } + + // add the list + // Note: usually item pairs are sorted with std::sort, but we are calling + // this function on idle and pairs' list can take a lot of time to sort + // through, so we are sorting items into list while adding them + addItemPairs(panel_list, false); + + // update visibility of items in the list + std::string cur_filter = getFilterSubString(); + LLStringUtil::toUpper(cur_filter); + LLSD action; + action.with("match_filter", cur_filter); + + pairs_const_iterator_t pair_it = panel_list.begin(); + for (; pair_it != panel_list.end(); ++pair_it) + { + item_pair_t* item_pair = *pair_it; + if (item_pair->first->getParent() != NULL) + { + updateItemVisibility(item_pair->first, action); + } + } + + rearrangeItems(); + notifyParentItemsRectChanged(); + + if (mAddedItems.size() > 0) + { + mRefreshState = REFRESH_LIST_APPEND; + } + else + { + // Note: while we do sort and check visibility at REFRESH_LIST_APPEND, update + // could have changed something about existing items so redo checks for all items. + mRefreshState = REFRESH_LIST_SORT; + } + break; + } + case REFRESH_LIST_SORT: + { + // Filter, sort, rearrange and notify parent about shape changes + filterItems(); + + if (mAddedItems.size() == 0) + { + // After list building completed, select items that had been requested to select before list was build + updateSelection(); + mRefreshState = REFRESH_COMPLETE; + } + else + { + mRefreshState = REFRESH_LIST_APPEND; + } + break; + } + default: + break; + } + + setForceRefresh(mRefreshState != REFRESH_COMPLETE); } void LLInventoryItemsList::computeDifference( @@ -204,24 +280,15 @@ void LLInventoryItemsList::computeDifference( LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved); } -void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/) +LLPanel* LLInventoryItemsList::createNewItem(LLViewerInventoryItem* item) { - if (!item) - { - LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL; - llassert(item != NULL); - } - - LLPanelInventoryListItemBase *list_item = LLPanelInventoryListItemBase::create(item); - if (!list_item) - return; - - bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange); - if (!is_item_added) - { - LL_WARNS() << "Couldn't add flat list item." << LL_ENDL; - llassert(is_item_added); - } + if (!item) + { + LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL; + llassert(item != NULL); + return NULL; + } + return LLPanelInventoryListItemBase::create(item); } // EOF diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 1aa230df9934645bee644bbc301a960a64d0dde8..fe05c2ed7c25ac0211a9d80009bbfba90e82adef 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -51,9 +51,9 @@ class LLInventoryItemsList : public LLFlatListViewEx /** * Let list know items need to be refreshed in next doIdle() */ - void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; } + void setNeedsRefresh(bool needs_refresh){ mRefreshState = needs_refresh ? REFRESH_ALL : REFRESH_COMPLETE; } - bool getNeedsRefresh(){ return mNeedsRefresh; } + U32 getNeedsRefresh(){ return mRefreshState; } /** * Sets the flag indicating that the list needs to be refreshed even if it is @@ -71,7 +71,7 @@ class LLInventoryItemsList : public LLFlatListViewEx * This is needed for example to filter items of the list hidden by closed * accordion tab. */ - void doIdle(); // Real idle routine + virtual void doIdle(); // Real idle routine static void idle(void* user_data); // static glue to doIdle() protected: @@ -94,17 +94,29 @@ class LLInventoryItemsList : public LLFlatListViewEx void computeDifference(const uuid_vec_t& vnew, uuid_vec_t& vadded, uuid_vec_t& vremoved); /** - * Add an item to the list - */ - virtual void addNewItem(LLViewerInventoryItem* item, bool rearrange = true); + * Create panel(item) from inventory item + */ + virtual LLPanel* createNewItem(LLViewerInventoryItem* item); + +protected: + enum ERefreshStates + { + REFRESH_COMPLETE = 0, + REFRESH_LIST_SORT, + REFRESH_LIST_APPEND, + REFRESH_LIST_ERASE, + REFRESH_ALL + }; + + ERefreshStates mRefreshState; private: uuid_vec_t mIDs; // IDs of items that were added in refreshList(). // Will be used in refresh() to determine added and removed ids uuid_vec_t mSelectTheseIDs; // IDs that will be selected if list is not loaded till now - - bool mNeedsRefresh; + uuid_vec_t mAddedItems; + uuid_vec_t mRemovedItems; bool mForceRefresh; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index cada2d7cf2da347cf22a8d4f14666332ab89b3ee..503fa28a335f3a950077f12361026324d1f8f29a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -582,7 +582,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, // Add the category to the internal representation LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(id, parent_id, preferred_type, name, gAgent.getID()); - cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL); + cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1 cat->setDescendentCount(0); LLCategoryUpdate update(cat->getParentUUID(), 1); accountForUpdate(update); @@ -640,7 +640,7 @@ void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inv result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(), result["name"].asString(), gAgent.getID()); - cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL); + cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1 cat->setDescendentCount(0); LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1); @@ -914,8 +914,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, category_id); if( item_array ) { + LLInventoryModel::LLCategoryUpdate update(category_id, 1); + gInventory.accountForUpdate(update); + // *FIX: bit of a hack to call update server from here... - new_item->updateServer(TRUE); + new_item->updateParentOnServer(FALSE); item_array->push_back(new_item); } else @@ -956,9 +959,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) item_array = get_ptr_in_map(mParentChildItemTree, parent_id); if(item_array) { + LLInventoryModel::LLCategoryUpdate update(parent_id, 1); + gInventory.accountForUpdate(update); // *FIX: bit of a hack to call update server from // here... - new_item->updateServer(TRUE); + new_item->updateParentOnServer(FALSE); item_array->push_back(new_item); } else @@ -1045,7 +1050,6 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32 if(old_cat) { // We already have an old category, modify its values - U32 mask = LLInventoryObserver::NONE; LLUUID old_parent_id = old_cat->getParentUUID(); LLUUID new_parent_id = cat->getParentUUID(); if(old_parent_id != new_parent_id) @@ -1100,7 +1104,8 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32 item_array_t* itemsp = new item_array_t; mParentChildCategoryTree[new_cat->getUUID()] = catsp; mParentChildItemTree[new_cat->getUUID()] = itemsp; - addChangedMask(LLInventoryObserver::ADD, cat->getUUID()); + mask |= LLInventoryObserver::ADD; + addChangedMask(mask, cat->getUUID()); } } @@ -1390,7 +1395,11 @@ void LLInventoryModel::onObjectDeletedFromServer(const LLUUID& object_id, bool f } // From purgeObject() - LLPreview::hide(object_id); + LLViewerInventoryItem *item = getItem(object_id); + if (item && (item->getType() != LLAssetType::AT_LSL_TEXT)) + { + LLPreview::hide(object_id, TRUE); + } deleteObject(object_id, fix_broken_links, do_notify_observers); } } @@ -2726,24 +2735,13 @@ void LLInventoryModel::registerCallbacks(LLMessageSystem* msg) msg->setHandlerFuncFast(_PREHASH_RemoveInventoryObjects, processRemoveInventoryObjects, NULL); - //msg->setHandlerFuncFast(_PREHASH_ExchangeCallingCard, - // processExchangeCallingcard, - // NULL); - //msg->setHandlerFuncFast(_PREHASH_AddCallingCard, - // processAddCallingcard, - // NULL); - //msg->setHandlerFuncFast(_PREHASH_DeclineCallingCard, - // processDeclineCallingcard, - // NULL); msg->setHandlerFuncFast(_PREHASH_SaveAssetIntoInventory, processSaveAssetIntoInventory, NULL); msg->setHandlerFuncFast(_PREHASH_BulkUpdateInventory, processBulkUpdateInventory, NULL); - msg->setHandlerFunc("InventoryDescendents", processInventoryDescendents); msg->setHandlerFunc("MoveInventoryItem", processMoveInventoryItem); - msg->setHandlerFunc("FetchInventoryReply", processFetchInventoryReply); } @@ -2763,14 +2761,6 @@ void LLInventoryModel::processUpdateCreateInventoryItem(LLMessageSystem* msg, vo } -// static -void LLInventoryModel::processFetchInventoryReply(LLMessageSystem* msg, void**) -{ - // no accounting - gInventory.messageUpdateCore(msg, false); -} - - bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32 mask) { //make sure our added inventory observer is active @@ -3213,85 +3203,6 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) InventoryCallbackInfo cbinfo = (*inv_it); gInventoryCallbacks.fire(cbinfo.mCallback, cbinfo.mInvID); } - - //gInventory.validate(); - - // Don't show the inventory. We used to call showAgentInventory here. - //LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); - //if(view) - //{ - // const BOOL take_keyboard_focus = FALSE; - // view->setSelection(category.getUUID(), take_keyboard_focus ); - // LLView* focus_view = gFocusMgr.getKeyboardFocus(); - // LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback(); - // // HACK to open inventory offers that are accepted. This information - // // really needs to flow through the instant messages and inventory - // // transfer/update messages. - // if (LLFloaterInventory::sOpenNextNewItem) - // { - // view->openSelected(); - // LLFloaterInventory::sOpenNextNewItem = FALSE; - // } - // - // // restore keyboard focus - // gFocusMgr.setKeyboardFocus(focus_view); - //} -} - -// static -void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**) -{ - LLUUID agent_id; - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); - if(agent_id != gAgent.getID()) - { - LL_WARNS() << "Got a UpdateInventoryItem for the wrong agent." << LL_ENDL; - return; - } - LLUUID parent_id; - msg->getUUID("AgentData", "FolderID", parent_id); - LLUUID owner_id; - msg->getUUID("AgentData", "OwnerID", owner_id); - S32 version; - msg->getS32("AgentData", "Version", version); - S32 descendents; - msg->getS32("AgentData", "Descendents", descendents); - - S32 i; - S32 count = msg->getNumberOfBlocksFast(_PREHASH_FolderData); - LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id); - for(i = 0; i < count; ++i) - { - tcategory->unpackMessage(msg, _PREHASH_FolderData, i); - gInventory.updateCategory(tcategory); - } - - count = msg->getNumberOfBlocksFast(_PREHASH_ItemData); - LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; - for(i = 0; i < count; ++i) - { - titem->unpackMessage(msg, _PREHASH_ItemData, i); - // If the item has already been added (e.g. from link prefetch), then it doesn't need to be re-added. - if (gInventory.getItem(titem->getUUID())) - { - LL_DEBUGS("Inventory") << "Skipping prefetched item [ Name: " << titem->getName() - << " | Type: " << titem->getActualType() << " | ItemUUID: " << titem->getUUID() << " ] " << LL_ENDL; - continue; - } - gInventory.updateItem(titem); - } - - // set version and descendentcount according to message. - LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id); - if(cat) - { - cat->setVersion(version); - cat->setDescendentCount(descendents); - // Get this UUID on the changed list so that whatever's listening for it - // will get triggered. - gInventory.addChangedMask(LLInventoryObserver::INTERNAL, cat->getUUID()); - } - gInventory.notifyObservers(); } // static @@ -3578,30 +3489,6 @@ void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, c } } -//* @param[in] items vector of items in order to be saved. -/* -void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items) -{ - int sortField = 0; - - // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field - for (item_array_t::const_iterator i = items.begin(); i != items.end(); ++i) - { - LLViewerInventoryItem* item = *i; - - item->setSortField(++sortField); - item->setComplete(TRUE); - item->updateServer(FALSE); - - updateItem(item); - - // Tell the parent folder to refresh its sort order. - addChangedMask(LLInventoryObserver::SORT, item->getParentUUID()); - } - - notifyObservers(); -} -*/ // See also LLInventorySort where landmarks in the Favorites folder are sorted. class LLViewerInventoryItemSort { @@ -3612,37 +3499,6 @@ class LLViewerInventoryItemSort } }; -/** - * Sorts passed items by LLViewerInventoryItem sort field. - * - * @param[in, out] items - array of items, not sorted. - */ -//static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items) -//{ -// static LLViewerInventoryItemSort sort_functor; -// std::sort(items.begin(), items.end(), sort_functor); -//} - -// * @param source_item_id - LLUUID of the source item to be moved into new position -// * @param target_item_id - LLUUID of the target item before which source item should be placed. -/* -void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id) -{ - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - LLIsType is_type(LLAssetType::AT_LANDMARK); - LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type); - - // ensure items are sorted properly before changing order. EXT-3498 - rearrange_item_order_by_sort_field(items); - - // update order - updateItemsOrder(items, source_item_id, target_item_id); - - saveItemsOrder(items); -} -*/ //---------------------------------------------------------------------------- // *NOTE: DEBUG functionality diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 3004eaf7c1fc0312c61d9ecc96675c0f9a0a3c4d..826d1f880d76db5c845450e46f3808d49637df6c 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -630,9 +630,7 @@ class LLInventoryModel static void processRemoveInventoryObjects(LLMessageSystem* msg, void**); static void processSaveAssetIntoInventory(LLMessageSystem* msg, void**); static void processBulkUpdateInventory(LLMessageSystem* msg, void**); - static void processInventoryDescendents(LLMessageSystem* msg, void**); static void processMoveInventoryItem(LLMessageSystem* msg, void**); - static void processFetchInventoryReply(LLMessageSystem* msg, void**); protected: bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting, U32 mask = 0x0); diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 19fbfc2ed3b3e40b2f285f38b31c57d484200d20..00d2908c1b52775af1b626e734cd949f5de37458 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -43,9 +43,9 @@ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLInventoryModelBackgroundFetch : public LLSingleton<LLInventoryModelBackgroundFetch> { -public: - LLInventoryModelBackgroundFetch(); + LLSINGLETON(LLInventoryModelBackgroundFetch); ~LLInventoryModelBackgroundFetch(); +public: // Start and stop background breadth-first fetching of inventory contents. // This gets triggered when performing a filter-search. diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 72ec092ed4cb851251337ee2682848a4e294a4ed..4427f32de99ad37c774ee5f7efce7e175486146e 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -241,33 +241,11 @@ void fetch_items_from_llsd(const LLSD& items_llsd) gInventory.requestPost(true, url, body[i], handler, (i ? "Library Item" : "Inventory Item")); continue; } + else + { + LL_WARNS("INVENTORY") << "Failed to get capability." << LL_ENDL; + } - LLMessageSystem* msg = gMessageSystem; - BOOL start_new_message = TRUE; - for (S32 j=0; j<body[i]["items"].size(); j++) - { - LLSD item_entry = body[i]["items"][j]; - if (start_new_message) - { - start_new_message = FALSE; - msg->newMessageFast(_PREHASH_FetchInventory); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - } - msg->nextBlockFast(_PREHASH_InventoryData); - msg->addUUIDFast(_PREHASH_OwnerID, item_entry["owner_id"].asUUID()); - msg->addUUIDFast(_PREHASH_ItemID, item_entry["item_id"].asUUID()); - if (msg->isSendFull(NULL)) - { - start_new_message = TRUE; - gAgent.sendReliableMessage(); - } - } - if (!start_new_message) - { - gAgent.sendReliableMessage(); - } } } @@ -678,7 +656,7 @@ void LLInventoryCategoriesObserver::changed(U32 mask) } } -bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb) +bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb, bool init_name_hash) { S32 version = LLViewerInventoryCategory::VERSION_UNKNOWN; S32 current_num_known_descendents = LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN; @@ -716,8 +694,15 @@ bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t if (can_be_added) { - mCategoryMap.insert(category_map_value_t( - cat_id,LLCategoryData(cat_id, cb, version, current_num_known_descendents))); + if(init_name_hash) + { + LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cat_id); + mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, cb, version, current_num_known_descendents,item_name_hash))); + } + else + { + mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, cb, version, current_num_known_descendents))); + } } return can_be_added; @@ -740,6 +725,18 @@ LLInventoryCategoriesObserver::LLCategoryData::LLCategoryData( mItemNameHash.finalize(); } +LLInventoryCategoriesObserver::LLCategoryData::LLCategoryData( + const LLUUID& cat_id, callback_t cb, S32 version, S32 num_descendents, LLMD5 name_hash) + + : mCatID(cat_id) + , mCallback(cb) + , mVersion(version) + , mDescendentsCount(num_descendents) + , mIsNameHashInitialized(true) + , mItemNameHash(name_hash) +{ +} + void LLScrollOnRenameObserver::changed(U32 mask) { if (mask & LLInventoryObserver::LABEL) diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index 8cf6a6bdab8f821815d831f3c0c6ae9a9729974c..36d8ee3f59486165c26122999cbffc8c066cbcc1 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -267,14 +267,14 @@ class LLInventoryCategoriesObserver : public LLInventoryObserver * @return "true" if category was added, "false" if it could * not be found. */ - bool addCategory(const LLUUID& cat_id, callback_t cb); + bool addCategory(const LLUUID& cat_id, callback_t cb, bool init_name_hash = false); void removeCategory(const LLUUID& cat_id); protected: struct LLCategoryData { LLCategoryData(const LLUUID& cat_id, callback_t cb, S32 version, S32 num_descendents); - + LLCategoryData(const LLUUID& cat_id, callback_t cb, S32 version, S32 num_descendents, LLMD5 name_hash); callback_t mCallback; S32 mVersion; S32 mDescendentsCount; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index f5dcbf838daf7dcbebecbe5b51e5f4b1460b31a7..6a27c0fe216038349c725b39bd659b6dd5a358ad 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -34,7 +34,6 @@ #include "llappearancemgr.h" #include "llavataractions.h" #include "llclipboard.h" -#include "llfloaterinventory.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llfolderview.h" diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index aa934f95a1ed3faedb434082deb11801de4a1fe5..a55938f334d12fe39ba911218dd72cb3fc582d26 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -181,7 +181,12 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate) if (gDirUtilp->fileExists(mFilename)) { // verifying that the file has indeed been modified + +#ifndef LL_WINDOWS const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename)); +#else + const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(utf8str_to_utf16str(mFilename))); +#endif LLSD new_last_modified = asctime(localtime(&temp_time)); if (mLastModified.asString() != new_last_modified.asString()) diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h index 9fef42c5df11996246dd882ba1c4718f11533cb5..1cecbabd3b5302f1850af6e0eb1dfee636e3ea3c 100644 --- a/indra/newview/lllocationhistory.h +++ b/indra/newview/lllocationhistory.h @@ -103,6 +103,7 @@ class LLLocationHistoryItem { class LLLocationHistory: public LLSingleton<LLLocationHistory> { + LLSINGLETON(LLLocationHistory); LOG_CLASS(LLLocationHistory); public: @@ -117,7 +118,6 @@ class LLLocationHistory: public LLSingleton<LLLocationHistory> typedef boost::function<void(EChangeType event)> history_changed_callback_t; typedef boost::signals2::signal<void(EChangeType event)> history_changed_signal_t; - LLLocationHistory(); void addItem(const LLLocationHistoryItem& item); bool touchItem(const LLLocationHistoryItem& item); diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 53b2ca2b74a12b4ea241778edb37897409b8d3a5..11bc1425f902566721a15e32ec5231fd1fe2d8de 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -243,7 +243,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) params.commit_on_focus_lost(false); params.follows.flags(FOLLOWS_ALL); mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params); - mTextEntry->setContextMenu(NULL); + mTextEntry->resetContextMenu(); addChild(mTextEntry); // LLLineEditor is replaced with LLLocationLineEditor diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 639641d1c25bf07c71e75322bba7a6724034558a..2635054bba02bc3526af36cb64ff0faf1f2ae836 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -132,15 +132,9 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line) class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner> { -public: - LLLogChatTimeScanner() - { - // Note, date/time facets will be destroyed by string streams - mDateStream.imbue(std::locale(mDateStream.getloc(), new date_input_facet(DATE_FORMAT))); - mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_facet(TIME_FORMAT))); - mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_input_facet(DATE_FORMAT))); - } + LLSINGLETON(LLLogChatTimeScanner); +public: date getTodayPacificDate() { typedef boost::date_time::local_adjustor<ptime, -8, no_dst> pst; @@ -205,6 +199,15 @@ class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner> std::stringstream mTimeStream; }; +inline +LLLogChatTimeScanner::LLLogChatTimeScanner() +{ + // Note, date/time facets will be destroyed by string streams + mDateStream.imbue(std::locale(mDateStream.getloc(), new date_input_facet(DATE_FORMAT))); + mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_facet(TIME_FORMAT))); + mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_input_facet(DATE_FORMAT))); +} + LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL; std::map<LLUUID,LLLoadHistoryThread *> LLLogChat::sLoadHistoryThreads; @@ -244,7 +247,10 @@ std::string LLLogChat::makeLogFileName(std::string filename) filename = cleanFileName(filename); filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename); - filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION; + if (!filename.empty()) + { + filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION; + } return filename; } @@ -924,7 +930,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params //possibly a case of complex object names consisting of 3+ words if (!has_name) { - U32 divider_pos = stuff.find(NAME_TEXT_DIVIDER); + std::string::size_type divider_pos = stuff.find(NAME_TEXT_DIVIDER); if (divider_pos != std::string::npos && divider_pos < (stuff.length() - NAME_TEXT_DIVIDER.length())) { im[LL_IM_FROM] = stuff.substr(0, divider_pos); diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index dfd39e4752eaea084f7e032f5ac98e2613282729..67d0f01ba670912e9d5be27f85f42576d8333af7 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -39,12 +39,12 @@ class LLNotificationsInterface; // negotiate user authentication attempts. class LLLoginInstance : public LLSingleton<LLLoginInstance> { + LLSINGLETON(LLLoginInstance); + ~LLLoginInstance(); + public: class Disposable; - LLLoginInstance(); - ~LLLoginInstance(); - void connect(LLPointer<LLCredential> credentials); // Connect to the current grid choice. void connect(const std::string& uri, LLPointer<LLCredential> credentials); // Connect to the given uri. void reconnect(); // reconnect using the current credentials. diff --git a/indra/newview/llmainlooprepeater.h b/indra/newview/llmainlooprepeater.h index f84c0ca94c2d1b4c812533d655e689a357c275a8..2ec3a74e4ae3bc4a446182cc444c5d654cd044d6 100644 --- a/indra/newview/llmainlooprepeater.h +++ b/indra/newview/llmainlooprepeater.h @@ -43,9 +43,8 @@ class LLMainLoopRepeater: public LLSingleton<LLMainLoopRepeater> { + LLSINGLETON(LLMainLoopRepeater); public: - LLMainLoopRepeater(void); - // Start the repeater service. void start(void); diff --git a/indra/newview/llmanip.h b/indra/newview/llmanip.h index 1fb05e047a93b6b41605c301c7228be973d1108d..69881e8589399ca3392576b6f18643468e818b82 100644 --- a/indra/newview/llmanip.h +++ b/indra/newview/llmanip.h @@ -1,4 +1,4 @@ -/** +/** * @file llmanip.h * @brief LLManip class definition * @@ -37,7 +37,7 @@ class LLToolComposite; class LLVector3; class LLObjectSelection; -const S32 MIN_DIVISION_PIXEL_WIDTH = 9; +const S32 MIN_DIVISION_PIXEL_WIDTH = 3; class LLManip : public LLTool { diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 3a0f96cd37d6a15d86e4bce4af5dd08b8b8027bd..7bd5e4cba2105302fa157d41e4ca931ce88a2f68 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -1157,6 +1157,9 @@ BOOL LLManipRotate::updateVisiblity() 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) { @@ -1166,6 +1169,7 @@ BOOL LLManipRotate::updateVisiblity() mRadiusMeters = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); mRadiusMeters /= gAgentCamera.mHUDCurZoom; + mRadiusMeters *= ui_scale_factor; mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag; mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm; @@ -1205,6 +1209,7 @@ BOOL LLManipRotate::updateVisiblity() 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; diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 3cbe742e3ca4e58d38237163053d9dc5026af44f..8b2ac4f303eaed9f7879e9afeda0be9d726bb2d0 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -228,12 +228,16 @@ void LLManipScale::render() const F32 BOX_HANDLE_BASE_SIZE = 50.0f; // box size in pixels = BOX_HANDLE_BASE_SIZE * BOX_HANDLE_BASE_FACTOR const F32 BOX_HANDLE_BASE_FACTOR = 0.2f; + //Assume that UI scale factor is equivalent for X and Y axis + F32 ui_scale_factor = LLUI::getScaleFactor().mV[VX]; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { for (S32 i = 0; i < NUM_MANIPULATORS; i++) { mBoxHandleSize[i] = BOX_HANDLE_BASE_SIZE * BOX_HANDLE_BASE_FACTOR / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); mBoxHandleSize[i] /= gAgentCamera.mHUDCurZoom; + mBoxHandleSize[i] *= ui_scale_factor; } } else @@ -266,6 +270,7 @@ void LLManipScale::render() // range == zero mBoxHandleSize[i] = BOX_HANDLE_BASE_FACTOR; } + mBoxHandleSize[i] *= ui_scale_factor; } } diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index b4259a456cc1e773ee58c2a49b99d99510a64da3..785022792bb68d76ba9e7108fd2deba87d6fcfd0 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llmaniptranslate.cpp * @brief LLManipTranslate class implementation * @@ -548,12 +548,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) if (off_axis_magnitude > mSnapOffsetMeters) { mInSnapRegime = TRUE; - LLVector3 mouse_down_offset(mDragCursorStartGlobal - mDragSelectionStartGlobal); LLVector3 cursor_snap_agent = gAgent.getPosAgentFromGlobal(cursor_point_snap_line); - if (!gSavedSettings.getBOOL("SnapToMouseCursor")) - { - cursor_snap_agent -= mouse_down_offset; - } F32 cursor_grid_dist = (cursor_snap_agent - mGridOrigin) * axis_f; @@ -1862,6 +1857,9 @@ void LLManipTranslate::renderTranslationHandles() 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"); diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 6cc7a0fc9967136e8f0e49fe0aa0b924b7d02862..54f95520db263353364d6c29deac6689c69255b7 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -773,7 +773,9 @@ void LLMarketplaceData::getMerchantStatusCoro() std::string url = getSLMConnectURL("/merchant"); if (url.empty()) { - LL_INFOS("Marketplace") << "No marketplace capability on Sim" << LL_ENDL; + LL_WARNS("Marketplace") << "No marketplace capability on Sim" << LL_ENDL; + setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE); + return; } LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts); diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index 9d795c6ced836e1c1287382168d739efeb82b0a6..ec312baca395b65116c27286cfe73c53ec7f3229 100644 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -86,11 +86,10 @@ namespace MarketplaceFetchCodes class LLMarketplaceInventoryImporter : public LLSingleton<LLMarketplaceInventoryImporter> { + LLSINGLETON(LLMarketplaceInventoryImporter); public: static void update(); - - LLMarketplaceInventoryImporter(); - + typedef boost::signals2::signal<void (bool)> status_changed_signal_t; typedef boost::signals2::signal<void (U32, const LLSD&)> status_report_signal_t; @@ -181,10 +180,11 @@ class LLSLMDeleteListingsResponder; class LLMarketplaceData : public LLSingleton<LLMarketplaceData> { - friend class LLSingleton < LLMarketplaceData > ; + LLSINGLETON(LLMarketplaceData); + virtual ~LLMarketplaceData(); public: - friend class LLSLMGetMerchantResponder; + friend class LLSLMGetMerchantResponder; friend class LLSLMGetListingsResponder; friend class LLSLMCreateListingsResponder; friend class LLSLMGetListingResponder; @@ -242,9 +242,6 @@ class LLMarketplaceData void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1); private: - LLMarketplaceData(); - virtual ~LLMarketplaceData(); - // Modify Marketplace data set : each method returns true if the function succeeds, false if error // Used internally only by SLM Responders when data are received from the SLM Server bool addListing(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id, bool is_listed, const std::string& edit_url, S32 count); diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index f996557c17a01cb15e5593094b32befd0e00da58..ccbe13fb50c7ebf30eeead15561cdbe818d877e3 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -531,7 +531,7 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content) LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter) { -# ifndef LL_RELEASE_FOR_DOWNLOAD +# ifdef SHOW_ASSERT // same condition that controls llassert() const LLSD& face_data = *faceIter; // conditional to avoid unused variable warning # endif llassert(face_data.isMap()); diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h index 36dd0904b6dad1791a554048c06b3121a42aa8ef..60b58d17de7156d0234e6a5a39e4fd33e7e0ee7b 100644 --- a/indra/newview/llmaterialmgr.h +++ b/indra/newview/llmaterialmgr.h @@ -38,9 +38,7 @@ class LLViewerRegion; class LLMaterialMgr : public LLSingleton<LLMaterialMgr> { - friend class LLSingleton<LLMaterialMgr>; -protected: - LLMaterialMgr(); + LLSINGLETON(LLMaterialMgr); virtual ~LLMaterialMgr(); public: diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 9cf32499838f6e05c45edb3d7441323014cd4863..00043d1e721cdd190149dbd5dd39db5ce27d5ad5 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -1007,7 +1007,11 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) std::string uuid = self->getClickUUID(); LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << target << "\", uri is " << url << LL_ENDL; - LLWeb::loadURL(url, target, std::string()); + // try as slurl first + if (!LLURLDispatcher::dispatch(url, "clicked", NULL, mTrusted)) + { + LLWeb::loadURL(url, target, std::string()); + } // CP: removing this code because we no longer support popups so this breaks the flow. // replaced with a bare call to LLWeb::LoadURL(...) diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp index 8879cfd7fbf8ed593b4ba58df20737bbdf3766c0..63d97f6ac2da08e6103d6567b1bfb2158946e0f0 100644 --- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp @@ -41,8 +41,7 @@ #include "llpathfindingnavmeshstatus.h" #include "llviewerregion.h" -LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh() - : LLSingleton<LLMenuOptionPathfindingRebakeNavmesh>(), +LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh() : mIsInitialized(false), mCanRebakeRegion(false), mRebakeNavMeshMode(kRebakeNavMesh_Default), diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.h b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h index 7b1d2873bad0933e54a0823ddbd7da84f11b6f48..649a387dd3c70db09d278e574021d8833a8bc90c 100644 --- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.h +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h @@ -37,6 +37,8 @@ class LLPathfindingNavMeshStatus; class LLMenuOptionPathfindingRebakeNavmesh : public LLSingleton<LLMenuOptionPathfindingRebakeNavmesh> { + LLSINGLETON(LLMenuOptionPathfindingRebakeNavmesh); + virtual ~LLMenuOptionPathfindingRebakeNavmesh(); LOG_CLASS(LLMenuOptionPathfindingRebakeNavmesh); public: @@ -49,8 +51,6 @@ class LLMenuOptionPathfindingRebakeNavmesh : public LLSingleton<LLMenuOptionPath kRebakeNavMesh_Default = kRebakeNavMesh_NotAvailable } ERebakeNavMeshMode; - LLMenuOptionPathfindingRebakeNavmesh(); - virtual ~LLMenuOptionPathfindingRebakeNavmesh(); void initialize(); void quit(); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 0aaed3e286768ac9495ddc496a0d5517bc1985cc..9dacae2c4eff711ccd89fa7d9ebfeb7a00b28bee 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1753,6 +1753,11 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size) { + if (data == NULL || data_size == 0) + { + return false; + } + LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); std::string mesh_string((char*) data, data_size); std::istringstream stream(mesh_string); @@ -1896,7 +1901,8 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 } LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, const std::string & upload_url, bool do_upload, + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + const std::string & upload_url, bool do_upload, LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer) : LLThread("mesh upload"), @@ -1911,6 +1917,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, mUploadTextures = upload_textures; mUploadSkin = upload_skin; mUploadJoints = upload_joints; + mLockScaleIfJointPosition = lock_scale_if_joint_position; mMutex = new LLMutex(NULL); mPendingUploads = 0; mFinished = false; @@ -2097,6 +2104,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) decomp, mUploadSkin, mUploadJoints, + mLockScaleIfJointPosition, FALSE, FALSE, data.mBaseModel->mSubmodelID); @@ -2255,6 +2263,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) decomp, mUploadSkin, mUploadJoints, + mLockScaleIfJointPosition, FALSE, FALSE, data.mBaseModel->mSubmodelID); @@ -3010,12 +3019,23 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b } else if (data && data_size > 0) { - // header was successfully retrieved from sim, cache in vfs - LLSD header = gMeshRepo.mThread->mMeshHeader[mesh_id]; + // header was successfully retrieved from sim and parsed, cache in vfs + S32 header_bytes = 0; + LLSD header; - S32 version = header["version"].asInteger(); + gMeshRepo.mThread->mHeaderMutex->lock(); + LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id); + if (iter != gMeshRepo.mThread->mMeshHeader.end()) + { + header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id]; + header = iter->second; + } + gMeshRepo.mThread->mHeaderMutex->unlock(); - if (version <= MAX_MESH_VERSION) + if (header_bytes > 0 + && !header.has("404") + && header.has("version") + && header["version"].asInteger() <= MAX_MESH_VERSION) { std::stringstream str; @@ -3064,6 +3084,17 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b } } } + else + { + LL_WARNS(LOG_MESH) << "Trying to cache nonexistent mesh, mesh id: " << mesh_id << LL_ENDL; + + // headerReceived() parsed header, but header's data is invalid so none of the LODs will be available + LLMutexLock lock(gMeshRepo.mThread->mMutex); + for (int i(0); i < 4; ++i) + { + gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); + } + } } } @@ -3935,7 +3966,7 @@ LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id) { LLMutexLock lock(mHeaderMutex); mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); - if (iter != mMeshHeader.end()) + if (iter != mMeshHeader.end() && mMeshHeaderSize[mesh_id] > 0) { return iter->second; } @@ -3946,20 +3977,23 @@ LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id) void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload, + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + std::string upload_url, bool do_upload, LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer) { - LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints, upload_url, - do_upload, fee_observer, upload_observer); + LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, + upload_skin, upload_joints, lock_scale_if_joint_position, + upload_url, do_upload, fee_observer, upload_observer); mUploadWaitList.push_back(thread); } S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) { - if (mThread) + if (mThread && mesh_id.notNull()) { + LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end()) + if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) { LLSD& header = iter->second; @@ -4031,9 +4065,30 @@ void LLMeshRepository::uploadError(LLSD& args) mUploadErrorQ.push(args); } +F32 LLMeshRepository::getStreamingCost(LLUUID mesh_id, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value) +{ + if (mThread && mesh_id.notNull()) + { + LLMutexLock lock(mThread->mHeaderMutex); + LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); + if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + { + return getStreamingCost(iter->second, radius, bytes, bytes_visible, lod, unscaled_value); + } + } + return 0.f; +} + //static F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value) { + if (header.has("404") + || !header.has("lowest_lod") + || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)) + { + return 0.f; + } + F32 max_distance = 512.f; F32 dlowest = llmin(radius/0.03f, max_distance); @@ -4093,7 +4148,7 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32 } } - F32 max_area = 102932.f; //area of circle that encompasses region + F32 max_area = 102944.f; //area of circle that encompasses region (see MAINT-6559) F32 min_area = 1.f; F32 high_area = llmin(F_PI*dmid*dmid, max_area); diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index d35c44397b02eb35267d9a83f76c0637efed0f3a..30f042845ad137a6ddbb36eaad610422cb6d9354 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -400,6 +400,7 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler bool mUploadTextures; bool mUploadSkin; bool mUploadJoints; + bool mLockScaleIfJointPosition; volatile bool mDiscarded; LLHost mHost; @@ -407,7 +408,8 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler std::string mWholeModelUploadURL; LLMeshUploadThread(instance_list& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, const std::string & upload_url, bool do_upload = true, + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + const std::string & upload_url, bool do_upload = true, LLHandle<LLWholeModelFeeObserver> fee_observer = (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); ~LLMeshUploadThread(); @@ -475,6 +477,7 @@ class LLMeshRepository static LLDeadmanTimer sQuiescentTimer; // Time-to-complete-mesh-downloads after significant events + F32 getStreamingCost(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); LLMeshRepository(); @@ -509,8 +512,10 @@ class LLMeshRepository LLSD& getMeshHeader(const LLUUID& mesh_id); void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true, - LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + std::string upload_url, bool do_upload = true, + LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), + LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); S32 getMeshSize(const LLUUID& mesh_id, S32 lod); diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 70035bcc74eff63f30436bbd7473a1d4786142b4..c3dd08c327fb55a7489c1688f54f55f1a0e5ec3e 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -252,7 +252,7 @@ void LLFloaterMove::setSittingMode(BOOL bSitting) LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING); } } - enableInstance(!bSitting); + enableInstance(); } // protected @@ -459,7 +459,7 @@ void LLFloaterMove::showModeButtons(BOOL bShow) } //static -void LLFloaterMove::enableInstance(BOOL bEnable) +void LLFloaterMove::enableInstance() { LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview"); if (instance) @@ -470,7 +470,7 @@ void LLFloaterMove::enableInstance(BOOL bEnable) } else { - instance->showModeButtons(bEnable); + instance->showModeButtons(isAgentAvatarValid() && !gAgentAvatarp->isSitting()); } } } @@ -566,7 +566,7 @@ BOOL LLPanelStandStopFlying::postBuild() { mStandButton = getChild<LLButton>("stand_btn"); mStandButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStandButtonClick, this)); - mStandButton->setCommitCallback(boost::bind(&LLFloaterMove::enableInstance, TRUE)); + mStandButton->setCommitCallback(boost::bind(&LLFloaterMove::enableInstance)); mStandButton->setVisible(FALSE); LLHints::registerHintTarget("stand_btn", mStandButton->getHandle()); @@ -685,8 +685,7 @@ void LLPanelStandStopFlying::onStandButtonClick() LLSelectMgr::getInstance()->deselectAllForStandingUp(); gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); - setFocus(FALSE); // EXT-482 - mStandButton->setVisible(FALSE); // force visibility changing to avoid seeing Stand & Move buttons at once. + setFocus(FALSE); } void LLPanelStandStopFlying::onStopFlyingButtonClick() @@ -694,7 +693,6 @@ void LLPanelStandStopFlying::onStopFlyingButtonClick() gAgent.setFlying(FALSE); setFocus(FALSE); // EXT-482 - mStopFlyingButton->setVisible(FALSE); } /** diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index c525d9dfdb6580d1c5bb1ea62c89fe01a3840cb1..4a31f2a8148d018affc43f6918e7e52933781086 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -56,7 +56,7 @@ class LLFloaterMove static void setAlwaysRunMode(bool run); void setAlwaysRunModeImpl(bool run); static void setSittingMode(BOOL bSitting); - static void enableInstance(BOOL bEnable); + static void enableInstance(); /*virtual*/ void onOpen(const LLSD& key); static void sUpdateFlyingStatus(); diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 01cf68bcdabd07194c68e9ae5309562221e0994e..0f70c9d13f9c83dea08e925d31f4049b55686668 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -47,6 +47,7 @@ #include "pipeline.h" #include <boost/tokenizer.hpp> +#include <boost/bind.hpp> #include "lldispatcher.h" #include "llxfermanager.h" @@ -56,6 +57,7 @@ #include "llworld.h" //for particle system banning #include "llimview.h" #include "llnotifications.h" +#include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "lltrans.h" @@ -146,22 +148,6 @@ std::string LLMute::getDisplayType() const } } - -/* static */ -LLMuteList* LLMuteList::getInstance() -{ - // Register callbacks at the first time that we find that the message system has been created. - static BOOL registered = FALSE; - if( !registered && gMessageSystem != NULL) - { - registered = TRUE; - // Register our various callbacks - gMessageSystem->setHandlerFuncFast(_PREHASH_MuteListUpdate, processMuteListUpdate); - gMessageSystem->setHandlerFuncFast(_PREHASH_UseCachedMuteList, processUseCachedMuteList); - } - return LLSingleton<LLMuteList>::getInstance(); // Call the "base" implementation. -} - //----------------------------------------------------------------------------- // LLMuteList() //----------------------------------------------------------------------------- @@ -169,6 +155,18 @@ LLMuteList::LLMuteList() : mIsLoaded(FALSE) { gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList); + + // Register our callbacks. We may be constructed before gMessageSystem, so + // use callWhenReady() to register them as soon as gMessageSystem becomes + // available. + // When using bind(), must be explicit about default arguments such as + // that last NULL. + gMessageSystem.callWhenReady(boost::bind(&LLMessageSystem::setHandlerFuncFast, _1, + _PREHASH_MuteListUpdate, processMuteListUpdate, + static_cast<void**>(NULL))); + gMessageSystem.callWhenReady(boost::bind(&LLMessageSystem::setHandlerFuncFast, _1, + _PREHASH_UseCachedMuteList, processUseCachedMuteList, + static_cast<void**>(NULL))); } //----------------------------------------------------------------------------- @@ -231,6 +229,16 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags) return FALSE; } + S32 mute_list_limit = gSavedSettings.getS32("MuteListLimit"); + if (getMutes().size() >= mute_list_limit) + { + LL_WARNS() << "Mute limit is reached; ignored" << LL_ENDL; + LLSD args; + args["MUTE_LIMIT"] = mute_list_limit; + LLNotifications::instance().add(LLNotification::Params("MuteLimitReached").substitutions(args)); + return FALSE; + } + if (mute.mType == LLMute::BY_NAME) { // Can't mute empty string by name diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 4e7b6ee880fbf8ad0ecb4e264f53ba0a8d0cef39..4ceddc97fd81f3d00d7fe58215a8b5817d181af7 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -71,6 +71,8 @@ class LLMute class LLMuteList : public LLSingleton<LLMuteList> { + LLSINGLETON(LLMuteList); + ~LLMuteList(); public: // reasons for auto-unmuting a resident enum EAutoReason @@ -81,13 +83,6 @@ class LLMuteList : public LLSingleton<LLMuteList> AR_COUNT // enum count }; - LLMuteList(); - ~LLMuteList(); - - // Implemented locally so that we can perform some delayed initialization. - // Callers should be careful to call this one and not LLSingleton<LLMuteList>::getInstance() - // which would circumvent that mechanism. -MG - static LLMuteList* getInstance(); void addObserver(LLMuteListObserver* observer); void removeObserver(LLMuteListObserver* observer); diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h old mode 100644 new mode 100755 index 29dbaedf7af9c2f63b0add0d058db42614a4a169..a44c6dd6997e315dd6722579861276ac8b3d8896 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -30,6 +30,7 @@ #include "llpanel.h" #include "llbutton.h" #include "lllayoutstack.h" +#include "llinitdestroyclass.h" class LLLocationInputCtrl; class LLMenuGL; @@ -84,12 +85,12 @@ class LLPullButton: public LLButton class LLNavigationBar : public LLPanel, public LLSingleton<LLNavigationBar>, private LLDestroyClass<LLNavigationBar> { + LLSINGLETON(LLNavigationBar); + virtual ~LLNavigationBar(); LOG_CLASS(LLNavigationBar); friend class LLDestroyClass<LLNavigationBar>; - + public: - LLNavigationBar(); - virtual ~LLNavigationBar(); /*virtual*/ void draw(); /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 5fc73c67d1bfbbf4c17c1f0464bdfbe096274a51..248c361ca40eb084f039b0854c5eff292e9d525e 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -735,7 +735,7 @@ void LLNetMap::renderPoint(const LLVector3 &pos_local, const LLColor4U &color, continue; } S32 offset = px + py * image_width; - ((U32*)datap)[offset] = color.mAll; + ((U32*)datap)[offset] = color.asRGBA(); } // top line @@ -748,7 +748,7 @@ void LLNetMap::renderPoint(const LLVector3 &pos_local, const LLColor4U &color, continue; } S32 offset = px + py * image_width; - ((U32*)datap)[offset] = color.mAll; + ((U32*)datap)[offset] = color.asRGBA(); } } else @@ -770,7 +770,7 @@ void LLNetMap::renderPoint(const LLVector3 &pos_local, const LLColor4U &color, continue; } S32 offset = p_x + p_y * image_width; - ((U32*)datap)[offset] = color.mAll; + ((U32*)datap)[offset] = color.asRGBA(); } } } @@ -988,6 +988,6 @@ void LLNetMap::handleStopTracking (const LLSD& userdata) if (mPopupMenu) { mPopupMenu->setItemEnabled ("Stop Tracking", false); - LLTracker::stopTracking ((void*)LLTracker::isTracking(NULL)); + LLTracker::stopTracking (LLTracker::isTracking(NULL)); } } diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h index f37c6b833c0b406827d1427ca03c09488089a919..52c79cc68970d172a37dd3a9abe6c3e9f8625396 100644 --- a/indra/newview/llnotificationmanager.h +++ b/indra/newview/llnotificationmanager.h @@ -46,11 +46,11 @@ class LLToast; */ class LLNotificationManager : public LLSingleton<LLNotificationManager> { - typedef std::pair<std::string, LLEventHandler*> eventhandlers; -public: - LLNotificationManager(); + LLSINGLETON(LLNotificationManager); virtual ~LLNotificationManager(); + typedef std::pair<std::string, LLEventHandler*> eventhandlers; +public: //TODO: make private // this method initialize handlers' map for different types of notifications void init(void); diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 2657b84ef30379962260d45674ee1bd7d33604d2..63ab88da425fb60f729cd3886ba32cce945cce0f 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -96,17 +96,21 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) LLUUID from_id = notification->getPayload()["from_id"]; - //Will not play a notification sound for inventory and teleport offer based upon chat preference - bool playSound = (!notification->isDND() - && ((notification->getName() == "UserGiveItem" - && gSavedSettings.getBOOL("PlaySoundInventoryOffer")) - || (notification->getName() == "TeleportOffered" - && gSavedSettings.getBOOL("PlaySoundTeleportOffer")))); - - if(playSound) - { - notification->playSound(); - } + if (!notification->isDND()) + { + //Will not play a notification sound for inventory and teleport offer based upon chat preference + bool playSound = (notification->getName() == "UserGiveItem" + && gSavedSettings.getBOOL("PlaySoundInventoryOffer")) + || ((notification->getName() == "TeleportOffered" + || notification->getName() == "TeleportOffered_MaturityExceeded" + || notification->getName() == "TeleportOffered_MaturityBlocked") + && gSavedSettings.getBOOL("PlaySoundTeleportOffer")); + + if (playSound) + { + notification->playSound(); + } + } LLHandlerUtil::spawnIMSession(name, from_id); LLHandlerUtil::addNotifPanelToIM(notification); diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp index 3418b33d377897bbe88faca093017a802c6d5082..35fdfa88bb52d39ca7d313949cc16d4d01f5d764 100644 --- a/indra/newview/llnotificationstorage.cpp +++ b/indra/newview/llnotificationstorage.cpp @@ -45,9 +45,10 @@ typedef boost::function<LLNotificationResponderInterface * (const LLSD& pParams) class LLResponderRegistry : public LLRegistrySingleton<std::string, responder_constructor_t, LLResponderRegistry> { - public: - template<typename RESPONDER_TYPE> static LLNotificationResponderInterface * create(const LLSD& pParams); - LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams); + LLSINGLETON_EMPTY_CTOR(LLResponderRegistry); +public: + template<typename RESPONDER_TYPE> static LLNotificationResponderInterface * create(const LLSD& pParams); + LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams); }; template<typename RESPONDER_TYPE> LLNotificationResponderInterface * LLResponderRegistry::create(const LLSD& pParams) diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eeeb7e5c25652eff83bb836380c69ed803dc7dae --- /dev/null +++ b/indra/newview/lloutfitgallery.cpp @@ -0,0 +1,1321 @@ +/** + * @file lloutfitgallery.cpp + * @author Pavlo Kryvych + * @brief Visual gallery of agent's outfits for My Appearance side panel + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2015, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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" // must be first include +#include "lloutfitgallery.h" + +#include <boost/foreach.hpp> + +// llcommon +#include "llcommonutils.h" +#include "llvfile.h" + +#include "llappearancemgr.h" +#include "lleconomy.h" +#include "llerror.h" +#include "llfilepicker.h" +#include "llfloaterperms.h" +#include "llfloaterreg.h" +#include "llfloateroutfitsnapshot.h" +#include "llimagedimensionsinfo.h" +#include "llinventoryfunctions.h" +#include "llinventorymodel.h" +#include "lllocalbitmaps.h" +#include "llnotificationsutil.h" +#include "lltexturectrl.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "llviewermenufile.h" +#include "llviewertexturelist.h" +#include "llwearableitemslist.h" + +static LLPanelInjector<LLOutfitGallery> t_outfit_gallery("outfit_gallery"); + +#define MAX_OUTFIT_PHOTO_WIDTH 256 +#define MAX_OUTFIT_PHOTO_HEIGHT 256 + +LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p) + : LLOutfitListBase(), + mTexturesObserver(NULL), + mOutfitsObserver(NULL), + mScrollPanel(NULL), + mGalleryPanel(NULL), + mGalleryCreated(false), + mRowCount(0), + mItemsAddedCount(0), + mOutfitLinkPending(NULL), + mOutfitRenamePending(NULL), + mRowPanelHeight(p.row_panel_height), + mVerticalGap(p.vertical_gap), + mHorizontalGap(p.horizontal_gap), + mItemWidth(p.item_width), + mItemHeight(p.item_height), + mItemHorizontalGap(p.item_horizontal_gap), + mItemsInRow(p.items_in_row), + mRowPanWidthFactor(p.row_panel_width_factor), + mGalleryWidthFactor(p.gallery_width_factor), + mTextureSelected(NULL) +{ + updateGalleryWidth(); +} + +LLOutfitGallery::Params::Params() + : row_panel_height("row_panel_height", 180), + vertical_gap("vertical_gap", 10), + horizontal_gap("horizontal_gap", 10), + item_width("item_width", 150), + item_height("item_height", 175), + item_horizontal_gap("item_horizontal_gap", 16), + items_in_row("items_in_row", 3), + row_panel_width_factor("row_panel_width_factor", 166), + gallery_width_factor("gallery_width_factor", 163) +{ + addSynonym(row_panel_height, "row_height"); +} + +const LLOutfitGallery::Params& LLOutfitGallery::getDefaultParams() +{ + return LLUICtrlFactory::getDefaultParams<LLOutfitGallery>(); +} + +BOOL LLOutfitGallery::postBuild() +{ + BOOL rv = LLOutfitListBase::postBuild(); + mScrollPanel = getChild<LLScrollContainer>("gallery_scroll_panel"); + LLPanel::Params params = LLPanel::getDefaultParams(); // Don't parse XML when creating dummy LLPanel + mGalleryPanel = LLUICtrlFactory::create<LLPanel>(params); + mMessageTextBox = getChild<LLTextBox>("no_outfits_txt"); + mOutfitGalleryMenu = new LLOutfitGalleryContextMenu(this); + return rv; +} + +void LLOutfitGallery::onOpen(const LLSD& info) +{ + LLOutfitListBase::onOpen(info); + if (!mGalleryCreated) + { + loadPhotos(); + uuid_vec_t cats; + getCurrentCategories(cats); + int n = cats.size(); + buildGalleryPanel(n); + mScrollPanel->addChild(mGalleryPanel); + for (int i = 0; i < n; i++) + { + addToGallery(mOutfitMap[cats[i]]); + } + reArrangeRows(); + mGalleryCreated = true; + } +} + +void LLOutfitGallery::draw() +{ + LLPanel::draw(); + if (mGalleryCreated) + { + updateRowsIfNeeded(); + } +} + +void LLOutfitGallery::updateRowsIfNeeded() +{ + if(((getRect().getWidth() - mRowPanelWidth) > mItemWidth) && mRowCount > 1) + { + reArrangeRows(1); + } + else if((mRowPanelWidth > (getRect().getWidth() + mItemHorizontalGap)) && mItemsInRow > 3) + { + reArrangeRows(-1); + } +} + +bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2) +{ + if(gSavedSettings.getBOOL("OutfitGallerySortByName") || + ((item1->isDefaultImage() && item2->isDefaultImage()) || (!item1->isDefaultImage() && !item2->isDefaultImage()))) + { + std::string name1 = item1->getItemName(); + std::string name2 = item2->getItemName(); + + LLStringUtil::toUpper(name1); + LLStringUtil::toUpper(name2); + return name1 < name2; + } + else + { + return item2->isDefaultImage(); + } +} + +void LLOutfitGallery::reArrangeRows(S32 row_diff) +{ + + std::vector<LLOutfitGalleryItem*> buf_items = mItems; + for (std::vector<LLOutfitGalleryItem*>::const_reverse_iterator it = buf_items.rbegin(); it != buf_items.rend(); ++it) + { + removeFromGalleryLast(*it); + } + for (std::vector<LLOutfitGalleryItem*>::const_reverse_iterator it = mHiddenItems.rbegin(); it != mHiddenItems.rend(); ++it) + { + buf_items.push_back(*it); + } + mHiddenItems.clear(); + + mItemsInRow+= row_diff; + updateGalleryWidth(); + std::sort(buf_items.begin(), buf_items.end(), compareGalleryItem); + + for (std::vector<LLOutfitGalleryItem*>::const_iterator it = buf_items.begin(); it != buf_items.end(); ++it) + { + (*it)->setHidden(false); + applyFilter(*it,sFilterSubString); + addToGallery(*it); + } + updateMessageVisibility(); +} + +void LLOutfitGallery::updateGalleryWidth() +{ + mRowPanelWidth = mRowPanWidthFactor * mItemsInRow - mItemHorizontalGap; + mGalleryWidth = mGalleryWidthFactor * mItemsInRow - mItemHorizontalGap; +} + +LLPanel* LLOutfitGallery::addLastRow() +{ + mRowCount++; + int row = 0; + int vgap = mVerticalGap * row; + LLPanel* result = buildRowPanel(0, row * mRowPanelHeight + vgap); + mGalleryPanel->addChild(result); + return result; +} + +void LLOutfitGallery::moveRowUp(int row) +{ + moveRow(row, mRowCount - 1 - row + 1); +} + +void LLOutfitGallery::moveRowDown(int row) +{ + moveRow(row, mRowCount - 1 - row - 1); +} + +void LLOutfitGallery::moveRow(int row, int pos) +{ + int vgap = mVerticalGap * pos; + moveRowPanel(mRowPanels[row], 0, pos * mRowPanelHeight + vgap); +} + +void LLOutfitGallery::removeLastRow() +{ + mRowCount--; + mGalleryPanel->removeChild(mLastRowPanel); + mUnusedRowPanels.push_back(mLastRowPanel); + mRowPanels.pop_back(); + mLastRowPanel = mRowPanels.back(); +} + +LLPanel* LLOutfitGallery::addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap) +{ + LLPanel* lpanel = buildItemPanel(pos * mItemWidth + hgap); + lpanel->addChild(item); + row_stack->addChild(lpanel); + mItemPanels.push_back(lpanel); + return lpanel; +} + +void LLOutfitGallery::addToGallery(LLOutfitGalleryItem* item) +{ + if(item->isHidden()) + { + mHiddenItems.push_back(item); + return; + } + mItemsAddedCount++; + mItemIndexMap[item] = mItemsAddedCount - 1; + int n = mItemsAddedCount; + int row_count = (n % mItemsInRow) == 0 ? n / mItemsInRow : n / mItemsInRow + 1; + int n_prev = n - 1; + int row_count_prev = (n_prev % mItemsInRow) == 0 ? n_prev / mItemsInRow : n_prev / mItemsInRow + 1; + + bool add_row = row_count != row_count_prev; + int pos = 0; + if (add_row) + { + for (int i = 0; i < row_count_prev; i++) + { + moveRowUp(i); + } + mLastRowPanel = addLastRow(); + mRowPanels.push_back(mLastRowPanel); + } + pos = (n - 1) % mItemsInRow; + mItems.push_back(item); + addToRow(mLastRowPanel, item, pos, mHorizontalGap * pos); + reshapeGalleryPanel(row_count); +} + + +void LLOutfitGallery::removeFromGalleryLast(LLOutfitGalleryItem* item) +{ + if(item->isHidden()) + { + mHiddenItems.pop_back(); + return; + } + int n_prev = mItemsAddedCount; + int n = mItemsAddedCount - 1; + int row_count = (n % mItemsInRow) == 0 ? n / mItemsInRow : n / mItemsInRow + 1; + int row_count_prev = (n_prev % mItemsInRow) == 0 ? n_prev / mItemsInRow : n_prev / mItemsInRow + 1; + mItemsAddedCount--; + + bool remove_row = row_count != row_count_prev; + removeFromLastRow(mItems[mItemsAddedCount]); + mItems.pop_back(); + if (remove_row) + { + for (int i = 0; i < row_count_prev - 1; i++) + { + moveRowDown(i); + } + removeLastRow(); + } + reshapeGalleryPanel(row_count); +} + + +void LLOutfitGallery::removeFromGalleryMiddle(LLOutfitGalleryItem* item) +{ + if(item->isHidden()) + { + mHiddenItems.erase(std::remove(mHiddenItems.begin(), mHiddenItems.end(), item), mHiddenItems.end()); + return; + } + int n = mItemIndexMap[item]; + mItemIndexMap.erase(item); + std::vector<LLOutfitGalleryItem*> saved; + for (int i = mItemsAddedCount - 1; i > n; i--) + { + saved.push_back(mItems[i]); + removeFromGalleryLast(mItems[i]); + } + removeFromGalleryLast(mItems[n]); + int saved_count = saved.size(); + for (int i = 0; i < saved_count; i++) + { + addToGallery(saved.back()); + saved.pop_back(); + } +} + +void LLOutfitGallery::removeFromLastRow(LLOutfitGalleryItem* item) +{ + mItemPanels.back()->removeChild(item); + mLastRowPanel->removeChild(mItemPanels.back()); + mUnusedItemPanels.push_back(mItemPanels.back()); + mItemPanels.pop_back(); +} + +LLOutfitGalleryItem* LLOutfitGallery::buildGalleryItem(std::string name) +{ + LLOutfitGalleryItem::Params giparams; + LLOutfitGalleryItem* gitem = LLUICtrlFactory::create<LLOutfitGalleryItem>(giparams); + gitem->reshape(mItemWidth, mItemHeight); + gitem->setVisible(true); + gitem->setFollowsLeft(); + gitem->setFollowsTop(); + gitem->setOutfitName(name); + return gitem; +} + +void LLOutfitGallery::buildGalleryPanel(int row_count) +{ + LLPanel::Params params; + mGalleryPanel = LLUICtrlFactory::create<LLPanel>(params); + reshapeGalleryPanel(row_count); +} + +void LLOutfitGallery::reshapeGalleryPanel(int row_count) +{ + int bottom = 0; + int left = 0; + int height = row_count * (mRowPanelHeight + mVerticalGap); + LLRect rect = LLRect(left, bottom + height, left + mGalleryWidth, bottom); + mGalleryPanel->setRect(rect); + mGalleryPanel->reshape(mGalleryWidth, height); + mGalleryPanel->setVisible(true); + mGalleryPanel->setFollowsLeft(); + mGalleryPanel->setFollowsTop(); +} + +LLPanel* LLOutfitGallery::buildItemPanel(int left) +{ + LLPanel::Params lpparams; + int top = 0; + LLPanel* lpanel = NULL; + if(mUnusedItemPanels.empty()) + { + lpanel = LLUICtrlFactory::create<LLPanel>(lpparams); + } + else + { + lpanel = mUnusedItemPanels.back(); + mUnusedItemPanels.pop_back(); + } + LLRect rect = LLRect(left, top + mItemHeight, left + mItemWidth + mItemHorizontalGap, top); + lpanel->setRect(rect); + lpanel->reshape(mItemWidth + mItemHorizontalGap, mItemHeight); + lpanel->setVisible(true); + lpanel->setFollowsLeft(); + lpanel->setFollowsTop(); + return lpanel; +} + +LLPanel* LLOutfitGallery::buildRowPanel(int left, int bottom) +{ + LLPanel::Params sparams; + LLPanel* stack = NULL; + if(mUnusedRowPanels.empty()) + { + stack = LLUICtrlFactory::create<LLPanel>(sparams); + } + else + { + stack = mUnusedRowPanels.back(); + mUnusedRowPanels.pop_back(); + } + moveRowPanel(stack, left, bottom); + return stack; +} + +void LLOutfitGallery::moveRowPanel(LLPanel* stack, int left, int bottom) +{ + LLRect rect = LLRect(left, bottom + mRowPanelHeight, left + mRowPanelWidth, bottom); + stack->setRect(rect); + stack->reshape(mRowPanelWidth, mRowPanelHeight); + stack->setVisible(true); + stack->setFollowsLeft(); + stack->setFollowsTop(); +} + +LLOutfitGallery::~LLOutfitGallery() +{ + delete mOutfitGalleryMenu; + + if (gInventory.containsObserver(mTexturesObserver)) + { + gInventory.removeObserver(mTexturesObserver); + } + delete mTexturesObserver; + + if (gInventory.containsObserver(mOutfitsObserver)) + { + gInventory.removeObserver(mOutfitsObserver); + } + delete mOutfitsObserver; + + while (!mUnusedRowPanels.empty()) + { + LLPanel* panelp = mUnusedRowPanels.back(); + mUnusedRowPanels.pop_back(); + panelp->die(); + } + while (!mUnusedItemPanels.empty()) + { + LLPanel* panelp = mUnusedItemPanels.back(); + mUnusedItemPanels.pop_back(); + panelp->die(); + } +} + +void LLOutfitGallery::setFilterSubString(const std::string& string) +{ + sFilterSubString = string; + reArrangeRows(); +} + +void LLOutfitGallery::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id) +{ + if (mOutfitMap[base_id]) + { + mOutfitMap[base_id]->setOutfitWorn(true); + } + if (mOutfitMap[prev_id]) + { + mOutfitMap[prev_id]->setOutfitWorn(false); + } +} + +void LLOutfitGallery::applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring) +{ + if (!item) return; + + std::string outfit_name = item->getItemName(); + LLStringUtil::toUpper(outfit_name); + + std::string cur_filter = filter_substring; + LLStringUtil::toUpper(cur_filter); + + bool hidden = (std::string::npos == outfit_name.find(cur_filter)); + item->setHidden(hidden); +} + +void LLOutfitGallery::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid) +{ +} + +void LLOutfitGallery::getCurrentCategories(uuid_vec_t& vcur) +{ + for (outfit_map_t::const_iterator iter = mOutfitMap.begin(); + iter != mOutfitMap.end(); + iter++) + { + if ((*iter).second != NULL) + { + vcur.push_back((*iter).first); + } + } +} + +void LLOutfitGallery::updateAddedCategory(LLUUID cat_id) +{ + LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); + if (!cat) return; + + std::string name = cat->getName(); + LLOutfitGalleryItem* item = buildGalleryItem(name); + mOutfitMap.insert(LLOutfitGallery::outfit_map_value_t(cat_id, item)); + item->setRightMouseDownCallback(boost::bind(&LLOutfitListBase::outfitRightClickCallBack, this, + _1, _2, _3, cat_id)); + LLWearableItemsList* list = NULL; + item->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::ChangeOutfitSelection, this, list, cat_id)); + if (mGalleryCreated) + { + addToGallery(item); + } + + LLViewerInventoryCategory* outfit_category = gInventory.getCategory(cat_id); + if (!outfit_category) + return; + + if (mOutfitsObserver == NULL) + { + mOutfitsObserver = new LLInventoryCategoriesObserver(); + gInventory.addObserver(mOutfitsObserver); + } + + // Start observing changes in "My Outfits" category. + mOutfitsObserver->addCategory(cat_id, + boost::bind(&LLOutfitGallery::refreshOutfit, this, cat_id), true); + + outfit_category->fetch(); + refreshOutfit(cat_id); +} + +void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id) +{ + outfit_map_t::iterator outfits_iter = mOutfitMap.find(cat_id); + if (outfits_iter != mOutfitMap.end()) + { + // 0. Remove category from observer. + mOutfitsObserver->removeCategory(cat_id); + + //const LLUUID& outfit_id = outfits_iter->first; + LLOutfitGalleryItem* item = outfits_iter->second; + + // An outfit is removed from the list. Do the following: + // 2. Remove the outfit from selection. + deselectOutfit(cat_id); + + // 3. Remove category UUID to accordion tab mapping. + mOutfitMap.erase(outfits_iter); + + // 4. Remove outfit from gallery. + removeFromGalleryMiddle(item); + + // kill removed item + if (item != NULL) + { + item->die(); + } + } + +} + +void LLOutfitGallery::updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name) +{ + outfit_map_t::iterator outfit_iter = mOutfitMap.find(cat->getUUID()); + if (outfit_iter != mOutfitMap.end()) + { + // Update name of outfit in gallery + LLOutfitGalleryItem* item = outfit_iter->second; + if (item) + { + item->setOutfitName(name); + } + } +} + +void LLOutfitGallery::onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) +{ + if (mOutfitMenu && cat_id.notNull()) + { + uuid_vec_t selected_uuids; + selected_uuids.push_back(cat_id); + mOutfitGalleryMenu->show(ctrl, selected_uuids, x, y); + } +} + +void LLOutfitGallery::onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) +{ + if (mSelectedOutfitUUID == category_id) + return; + if (mOutfitMap[mSelectedOutfitUUID]) + { + mOutfitMap[mSelectedOutfitUUID]->setSelected(FALSE); + } + if (mOutfitMap[category_id]) + { + mOutfitMap[category_id]->setSelected(TRUE); + } +} + +void LLOutfitGallery::wearSelectedOutfit() +{ + LLAppearanceMgr::instance().replaceCurrentOutfit(getSelectedOutfitUUID()); +} + +bool LLOutfitGallery::hasItemSelected() +{ + return false; +} + +bool LLOutfitGallery::canWearSelected() +{ + return false; +} + +bool LLOutfitGallery::hasDefaultImage(const LLUUID& outfit_cat_id) +{ + if (mOutfitMap[outfit_cat_id]) + { + return mOutfitMap[outfit_cat_id]->isDefaultImage(); + } + return false; +} + +void LLOutfitGallery::updateMessageVisibility() +{ + if(mItems.empty()) + { + mMessageTextBox->setVisible(TRUE); + mScrollPanel->setVisible(FALSE); + std::string message = sFilterSubString.empty()? getString("no_outfits_msg") : getString("no_matched_outfits_msg"); + mMessageTextBox->setValue(message); + } + else + { + mScrollPanel->setVisible(TRUE); + mMessageTextBox->setVisible(FALSE); + } +} + +LLOutfitListGearMenuBase* LLOutfitGallery::createGearMenu() +{ + return new LLOutfitGalleryGearMenu(this); +} + +static LLDefaultChildRegistry::Register<LLOutfitGalleryItem> r("outfit_gallery_item"); + +LLOutfitGalleryItem::LLOutfitGalleryItem(const Params& p) + : LLPanel(p), + mTexturep(NULL), + mSelected(false), + mWorn(false), + mDefaultImage(true), + mOutfitName("") +{ + buildFromFile("panel_outfit_gallery_item.xml"); +} + +LLOutfitGalleryItem::~LLOutfitGalleryItem() +{ + +} + +BOOL LLOutfitGalleryItem::postBuild() +{ + setDefaultImage(); + + mOutfitNameText = getChild<LLTextBox>("outfit_name"); + mOutfitWornText = getChild<LLTextBox>("outfit_worn_text"); + mTextBgPanel = getChild<LLPanel>("text_bg_panel"); + setOutfitWorn(false); + mHidden = false; + return TRUE; +} + +void LLOutfitGalleryItem::draw() +{ + LLPanel::draw(); + + // Draw border + LLUIColor border_color = LLUIColorTable::instance().getColor(mSelected ? "OutfitGalleryItemSelected" : "OutfitGalleryItemUnselected", LLColor4::white); + LLRect border = getChildView("preview_outfit")->getRect(); + border.mRight = border.mRight + 1; + gl_rect_2d(border, border_color.get(), FALSE); + + // If the floater is focused, don't apply its alpha to the texture (STORM-677). + const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + if (mTexturep) + { + LLRect interior = border; + interior.stretch(-1); + + gl_draw_scaled_image(interior.mLeft - 1, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha); + + // Pump the priority + mTexturep->addTextureStats((F32)(interior.getWidth() * interior.getHeight())); + } + +} + +void LLOutfitGalleryItem::setOutfitName(std::string name) +{ + mOutfitNameText->setText(name); + mOutfitNameText->setToolTip(name); + mOutfitName = name; +} + +void LLOutfitGalleryItem::setOutfitWorn(bool value) +{ + mWorn = value; + LLStringUtil::format_map_t worn_string_args; + std::string worn_string = getString("worn_string", worn_string_args); + LLUIColor text_color = LLUIColorTable::instance().getColor(mSelected ? "White" : (mWorn ? "OutfitGalleryItemWorn" : "White"), LLColor4::white); + mOutfitWornText->setReadOnlyColor(text_color.get()); + mOutfitNameText->setReadOnlyColor(text_color.get()); + mOutfitWornText->setValue(value ? worn_string : ""); +} + +void LLOutfitGalleryItem::setSelected(bool value) +{ + mSelected = value; + mTextBgPanel->setBackgroundVisible(value); + setOutfitWorn(mWorn); +} + +BOOL LLOutfitGalleryItem::handleMouseDown(S32 x, S32 y, MASK mask) +{ + setFocus(TRUE); + return LLUICtrl::handleMouseDown(x, y, mask); +} + +BOOL LLOutfitGalleryItem::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + setFocus(TRUE); + return LLUICtrl::handleRightMouseDown(x, y, mask); +} + +void LLOutfitGalleryItem::setImageAssetId(LLUUID image_asset_id) +{ + mImageAssetId = image_asset_id; + mTexturep = LLViewerTextureManager::getFetchedTexture(image_asset_id, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + getChildView("preview_outfit")->setVisible(FALSE); + mDefaultImage = false; +} + +LLUUID LLOutfitGalleryItem::getImageAssetId() +{ + return mImageAssetId; +} + +void LLOutfitGalleryItem::setDefaultImage() +{ + mTexturep = NULL; + mImageAssetId.setNull(); + getChildView("preview_outfit")->setVisible(TRUE); + mDefaultImage = true; +} + +LLContextMenu* LLOutfitGalleryContextMenu::createMenu() +{ + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + LLUUID selected_id = mUUIDs.front(); + + registrar.add("Outfit.WearReplace", + boost::bind(&LLAppearanceMgr::replaceCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); + registrar.add("Outfit.WearAdd", + boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); + registrar.add("Outfit.TakeOff", + boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id)); + registrar.add("Outfit.Edit", boost::bind(editOutfit)); + registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id)); + registrar.add("Outfit.Delete", boost::bind(&LLOutfitGalleryContextMenu::onRemoveOutfit, this, selected_id)); + registrar.add("Outfit.Create", boost::bind(&LLOutfitGalleryContextMenu::onCreate, this, _2)); + registrar.add("Outfit.UploadPhoto", boost::bind(&LLOutfitGalleryContextMenu::onUploadPhoto, this, selected_id)); + registrar.add("Outfit.SelectPhoto", boost::bind(&LLOutfitGalleryContextMenu::onSelectPhoto, this, selected_id)); + registrar.add("Outfit.TakeSnapshot", boost::bind(&LLOutfitGalleryContextMenu::onTakeSnapshot, this, selected_id)); + registrar.add("Outfit.RemovePhoto", boost::bind(&LLOutfitGalleryContextMenu::onRemovePhoto, this, selected_id)); + enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitGalleryContextMenu::onEnable, this, _2)); + enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitGalleryContextMenu::onVisible, this, _2)); + + return createFromFile("menu_gallery_outfit_tab.xml"); +} + +void LLOutfitGalleryContextMenu::onUploadPhoto(const LLUUID& outfit_cat_id) +{ + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + if (gallery && outfit_cat_id.notNull()) + { + gallery->uploadPhoto(outfit_cat_id); + } +} + +void LLOutfitGalleryContextMenu::onSelectPhoto(const LLUUID& outfit_cat_id) +{ + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + if (gallery && outfit_cat_id.notNull()) + { + gallery->onSelectPhoto(outfit_cat_id); + } +} + +void LLOutfitGalleryContextMenu::onRemovePhoto(const LLUUID& outfit_cat_id) +{ + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + if (gallery && outfit_cat_id.notNull()) + { + gallery->checkRemovePhoto(outfit_cat_id); + gallery->refreshOutfit(outfit_cat_id); + } +} + +void LLOutfitGalleryContextMenu::onTakeSnapshot(const LLUUID& outfit_cat_id) +{ + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + if (gallery && outfit_cat_id.notNull()) + { + gallery->onTakeSnapshot(outfit_cat_id); + } +} + +void LLOutfitGalleryContextMenu::onRemoveOutfit(const LLUUID& outfit_cat_id) +{ + LLNotificationsUtil::add("DeleteOutfits", LLSD(), LLSD(), boost::bind(&LLOutfitGalleryContextMenu::onOutfitsRemovalConfirmation, this, _1, _2, outfit_cat_id)); +} + +void LLOutfitGalleryContextMenu::onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response, const LLUUID& outfit_cat_id) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return; // canceled + + if (outfit_cat_id.notNull()) + { + gInventory.removeCategory(outfit_cat_id); + } +} + +void LLOutfitGalleryContextMenu::onCreate(const LLSD& data) +{ + LLWearableType::EType type = LLWearableType::typeNameToType(data.asString()); + if (type == LLWearableType::WT_NONE) + { + LL_WARNS() << "Invalid wearable type" << LL_ENDL; + return; + } + + LLAgentWearables::createWearable(type, true); +} + +bool LLOutfitGalleryContextMenu::onEnable(LLSD::String param) +{ + return LLOutfitContextMenu::onEnable(param); +} + +bool LLOutfitGalleryContextMenu::onVisible(LLSD::String param) +{ + if ("remove_photo" == param) + { + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + LLUUID selected_id = mUUIDs.front(); + if (gallery && selected_id.notNull()) + { + return !gallery->hasDefaultImage(selected_id); + } + } + return LLOutfitContextMenu::onVisible(param); +} + +LLOutfitGalleryGearMenu::LLOutfitGalleryGearMenu(LLOutfitListBase* olist) + : LLOutfitListGearMenuBase(olist) +{ +} + +void LLOutfitGalleryGearMenu::onUpdateItemsVisibility() +{ + if (!mMenu) return; + bool have_selection = getSelectedOutfitID().notNull(); + mMenu->setItemVisible("expand", FALSE); + mMenu->setItemVisible("collapse", FALSE); + mMenu->setItemVisible("upload_photo", have_selection); + mMenu->setItemVisible("select_photo", have_selection); + mMenu->setItemVisible("take_snapshot", have_selection); + mMenu->setItemVisible("remove_photo", !hasDefaultImage()); + mMenu->setItemVisible("sepatator3", TRUE); + mMenu->setItemVisible("sort_folders_by_name", TRUE); + LLOutfitListGearMenuBase::onUpdateItemsVisibility(); +} + +void LLOutfitGalleryGearMenu::onUploadFoto() +{ + LLUUID selected_outfit_id = getSelectedOutfitID(); + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + if (gallery && selected_outfit_id.notNull()) + { + gallery->uploadPhoto(selected_outfit_id); + } +} + +void LLOutfitGalleryGearMenu::onSelectPhoto() +{ + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + LLUUID selected_outfit_id = getSelectedOutfitID(); + if (gallery && !selected_outfit_id.isNull()) + { + gallery->onSelectPhoto(selected_outfit_id); + } +} + +void LLOutfitGalleryGearMenu::onRemovePhoto() +{ + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + LLUUID selected_outfit_id = getSelectedOutfitID(); + if (gallery && !selected_outfit_id.isNull()) + { + gallery->checkRemovePhoto(selected_outfit_id); + gallery->refreshOutfit(selected_outfit_id); + } +} + +void LLOutfitGalleryGearMenu::onTakeSnapshot() +{ + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + LLUUID selected_outfit_id = getSelectedOutfitID(); + if (gallery && !selected_outfit_id.isNull()) + { + gallery->onTakeSnapshot(selected_outfit_id); + } +} + +void LLOutfitGalleryGearMenu::onChangeSortOrder() +{ + bool sort_by_name = !gSavedSettings.getBOOL("OutfitGallerySortByName"); + gSavedSettings.setBOOL("OutfitGallerySortByName", sort_by_name); + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + if (gallery) + { + gallery->reArrangeRows(); + } +} + +bool LLOutfitGalleryGearMenu::hasDefaultImage() +{ + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); + LLUUID selected_outfit_id = getSelectedOutfitID(); + if (gallery && selected_outfit_id.notNull()) + { + return gallery->hasDefaultImage(selected_outfit_id); + } + return true; +} + +void LLOutfitGallery::onTextureSelectionChanged(LLInventoryItem* itemp) +{ +} + +void LLOutfitGallery::loadPhotos() +{ + //Iterate over inventory + LLUUID textures = gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE); + LLViewerInventoryCategory* textures_category = gInventory.getCategory(textures); + if (!textures_category) + return; + if (mTexturesObserver == NULL) + { + mTexturesObserver = new LLInventoryCategoriesObserver(); + gInventory.addObserver(mTexturesObserver); + } + + // Start observing changes in "Textures" category. + mTexturesObserver->addCategory(textures, + boost::bind(&LLOutfitGallery::refreshTextures, this, textures)); + + textures_category->fetch(); +} + +void LLOutfitGallery::refreshOutfit(const LLUUID& category_id) +{ + LLViewerInventoryCategory* category = gInventory.getCategory(category_id); + { + bool photo_loaded = false; + LLInventoryModel::cat_array_t sub_cat_array; + LLInventoryModel::item_array_t outfit_item_array; + // Collect all sub-categories of a given category. + gInventory.collectDescendents( + category->getUUID(), + sub_cat_array, + outfit_item_array, + LLInventoryModel::EXCLUDE_TRASH); + BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array) + { + LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem(); + if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE) + { + LLUUID asset_id = linked_item->getAssetUUID(); + mOutfitMap[category_id]->setImageAssetId(asset_id); + photo_loaded = true; + std::string linked_item_name = linked_item->getName(); + if (!mOutfitRenamePending.isNull() && mOutfitRenamePending.asString() == linked_item_name) + { + LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(mOutfitRenamePending); + LLStringUtil::format_map_t photo_string_args; + photo_string_args["OUTFIT_NAME"] = outfit_cat->getName(); + std::string new_name = getString("outfit_photo_string", photo_string_args); + LLSD updates; + updates["name"] = new_name; + update_inventory_item(linked_item->getUUID(), updates, NULL); + mOutfitRenamePending.setNull(); + LLFloater* inv_floater = LLFloaterReg::getInstance("inventory"); + if (inv_floater) + { + inv_floater->closeFloater(); + } + LLFloater* appearance_floater = LLFloaterReg::getInstance("appearance"); + if (appearance_floater) + { + appearance_floater->setFocus(TRUE); + } + } + break; + } + if (!photo_loaded) + { + mOutfitMap[category_id]->setDefaultImage(); + } + } + } + + if (mGalleryCreated && !LLApp::isQuitting()) + { + reArrangeRows(); + } +} + +void LLOutfitGallery::refreshTextures(const LLUUID& category_id) +{ + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + + // Collect all sub-categories of a given category. + LLIsType is_texture(LLAssetType::AT_TEXTURE); + gInventory.collectDescendentsIf( + category_id, + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_texture); + + //Find texture which contain pending outfit ID string in name + LLViewerInventoryItem* photo_upload_item = NULL; + BOOST_FOREACH(LLViewerInventoryItem* item, item_array) + { + std::string name = item->getName(); + if (!mOutfitLinkPending.isNull() && name == mOutfitLinkPending.asString()) + { + photo_upload_item = item; + break; + } + } + + if (photo_upload_item != NULL) + { + LLUUID photo_item_id = photo_upload_item->getUUID(); + LLInventoryObject* upload_object = gInventory.getObject(photo_item_id); + if (!upload_object) + { + LL_WARNS() << "LLOutfitGallery::refreshTextures added_object is null!" << LL_ENDL; + } + else + { + linkPhotoToOutfit(photo_item_id, mOutfitLinkPending); + mOutfitRenamePending = mOutfitLinkPending; + mOutfitLinkPending.setNull(); + } + } +} + +void LLOutfitGallery::uploadPhoto(LLUUID outfit_id) +{ + outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id); + if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull()) + { + return; + } + + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE)) + { + std::string filename = picker.getFirstFile(); + LLLocalBitmap* unit = new LLLocalBitmap(filename); + if (unit->getValid()) + { + std::string exten = gDirUtilp->getExtension(filename); + U32 codec = LLImageBase::getCodecFromExtension(exten); + + LLImageDimensionsInfo image_info; + std::string image_load_error; + if (!image_info.load(filename, codec)) + { + image_load_error = image_info.getLastError(); + } + + S32 max_width = MAX_OUTFIT_PHOTO_WIDTH; + S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT; + + 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); + + image_load_error = LLTrans::getString("outfit_photo_load_dimensions_error", args); + } + + if (!image_load_error.empty()) + { + LLSD subst; + subst["REASON"] = image_load_error; + LLNotificationsUtil::add("OutfitPhotoLoadError", subst); + return; + } + + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). + void *nruserdata = NULL; + nruserdata = (void *)&outfit_id; + + LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id); + if (!outfit_cat) return; + + checkRemovePhoto(outfit_id); + std::string upload_pending_name = outfit_id.asString(); + std::string upload_pending_desc = ""; + LLAssetStorage::LLStoreAssetCallback callback = NULL; + LLUUID photo_id = upload_new_resource(filename, // file + upload_pending_name, + upload_pending_desc, + 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + upload_pending_name, callback, expected_upload_cost, nruserdata); + mOutfitLinkPending = outfit_id; + } + } +} + +void LLOutfitGallery::linkPhotoToOutfit(LLUUID photo_id, LLUUID outfit_id) +{ + LLPointer<LLInventoryCallback> cb = new LLUpdateGalleryOnPhotoLinked(); + link_inventory_object(outfit_id, photo_id, cb); +} + +bool LLOutfitGallery::checkRemovePhoto(LLUUID outfit_id) +{ + LLAppearanceMgr::instance().removeOutfitPhoto(outfit_id); + return true; +} + +void LLUpdateGalleryOnPhotoLinked::fire(const LLUUID& inv_item_id) +{ +} + +LLUUID LLOutfitGallery::getPhotoAssetId(const LLUUID& outfit_id) +{ + outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id); + if (outfit_it != mOutfitMap.end()) + { + return outfit_it->second->getImageAssetId(); + } + return LLUUID(); +} + +LLUUID LLOutfitGallery::getDefaultPhoto() +{ + return LLUUID(); +} + +void LLOutfitGallery::onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id) +{ + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + + if (floaterp && op == LLTextureCtrl::TEXTURE_SELECT) + { + LLUUID image_item_id; + if (id.notNull()) + { + image_item_id = id; + } + else + { + image_item_id = floaterp->findItemID(floaterp->getAssetID(), FALSE, TRUE); + if (image_item_id.isNull()) + { + LL_WARNS() << "id or image_item_id is NULL!" << LL_ENDL; + return; + } + } + + std::string image_load_error; + S32 max_width = MAX_OUTFIT_PHOTO_WIDTH; + S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT; + if (mTextureSelected.isNull() || + mTextureSelected->getFullWidth() == 0 || + mTextureSelected->getFullHeight() == 0) + { + image_load_error = LLTrans::getString("outfit_photo_verify_dimensions_error"); + LL_WARNS() << "Cannot verify selected texture dimensions" << LL_ENDL; + return; + } + S32 width = mTextureSelected->getFullWidth(); + S32 height = mTextureSelected->getFullHeight(); + if ((width > max_width) || (height > max_height)) + { + LLStringUtil::format_map_t args; + args["WIDTH"] = llformat("%d", max_width); + args["HEIGHT"] = llformat("%d", max_height); + + image_load_error = LLTrans::getString("outfit_photo_select_dimensions_error", args); + } + + if (!image_load_error.empty()) + { + LLSD subst; + subst["REASON"] = image_load_error; + LLNotificationsUtil::add("OutfitPhotoLoadError", subst); + return; + } + + checkRemovePhoto(getSelectedOutfitUUID()); + linkPhotoToOutfit(image_item_id, getSelectedOutfitUUID()); + } +} + +void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id) +{ + if (selected_outfit_id.notNull()) + { + + // 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, + getPhotoAssetId(selected_outfit_id), + getPhotoAssetId(selected_outfit_id), + getPhotoAssetId(selected_outfit_id), + FALSE, + TRUE, + "SELECT PHOTO", + PERM_NONE, + PERM_NONE, + PERM_NONE, + FALSE, + NULL); + + mFloaterHandle = floaterp->getHandle(); + mTextureSelected = NULL; + + LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp); + if (texture_floaterp) + { + texture_floaterp->setTextureSelectedCallback(boost::bind(&LLOutfitGallery::onTextureSelectionChanged, this, _1)); + texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2)); + texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1)); + texture_floaterp->setLocalTextureEnabled(FALSE); + } + + floaterp->openFloater(); + } + floaterp->setFocus(TRUE); + } +} + +void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id) +{ + LLFloaterReg::toggleInstanceOrBringToFront("outfit_snapshot"); + LLFloaterOutfitSnapshot* snapshot_floater = LLFloaterOutfitSnapshot::getInstance(); + if (snapshot_floater) + { + snapshot_floater->setOutfitID(selected_outfit_id); + snapshot_floater->getInstance()->setGallery(this); + } +} + +void LLOutfitGallery::onBeforeOutfitSnapshotSave() +{ + LLUUID selected_outfit_id = getSelectedOutfitUUID(); + if (!selected_outfit_id.isNull()) + { + checkRemovePhoto(selected_outfit_id); + } +} + +void LLOutfitGallery::onAfterOutfitSnapshotSave() +{ + LLUUID selected_outfit_id = getSelectedOutfitUUID(); + if (!selected_outfit_id.isNull()) + { + mOutfitLinkPending = selected_outfit_id; + } +} + +void LLOutfitGallery::onTexturePickerUpdateImageStats(LLPointer<LLViewerTexture> texture) +{ + mTextureSelected = texture; +} diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h new file mode 100644 index 0000000000000000000000000000000000000000..b9fc10f015a6a20f27dde27c5623f97bcda1a971 --- /dev/null +++ b/indra/newview/lloutfitgallery.h @@ -0,0 +1,285 @@ +/** + * @file lloutfitgallery.h + * @author Pavlo Kryvych + * @brief Visual gallery of agent's outfits for My Appearance side panel + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2015, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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_LLOUTFITGALLERYCTRL_H +#define LL_LLOUTFITGALLERYCTRL_H + +#include "llextendedstatus.h" +#include "lliconctrl.h" +#include "lllayoutstack.h" +#include "lloutfitslist.h" +#include "llpanelappearancetab.h" +#include "lltexturectrl.h" +#include "llviewertexture.h" + +#include <vector> + +class LLVFS; +class LLOutfitGallery; +class LLOutfitGalleryItem; +class LLOutfitListGearMenuBase; +class LLOutfitGalleryGearMenu; +class LLOutfitGalleryContextMenu; + +class LLUpdateGalleryOnPhotoLinked : public LLInventoryCallback +{ +public: + LLUpdateGalleryOnPhotoLinked(){} + virtual ~LLUpdateGalleryOnPhotoLinked(){} + /* virtual */ void fire(const LLUUID& inv_item_id); +private: +}; + +class LLOutfitGallery : public LLOutfitListBase +{ +public: + friend class LLOutfitGalleryGearMenu; + friend class LLOutfitGalleryContextMenu; + friend class LLUpdateGalleryOnPhotoLinked; + + struct Params + : public LLInitParam::Block<Params, LLPanel::Params> + { + Optional<S32> row_panel_height; + Optional<S32> row_panel_width_factor; + Optional<S32> gallery_width_factor; + Optional<S32> vertical_gap; + Optional<S32> horizontal_gap; + Optional<S32> item_width; + Optional<S32> item_height; + Optional<S32> item_horizontal_gap; + Optional<S32> items_in_row; + + Params(); + }; + + static const LLOutfitGallery::Params& getDefaultParams(); + + LLOutfitGallery(const LLOutfitGallery::Params& params = getDefaultParams()); + virtual ~LLOutfitGallery(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& info); + /*virtual*/ void draw(); + + void onSelectPhoto(LLUUID selected_outfit_id); + void onTakeSnapshot(LLUUID selected_outfit_id); + + void wearSelectedOutfit(); + + + /*virtual*/ void setFilterSubString(const std::string& string); + + /*virtual*/ void getCurrentCategories(uuid_vec_t& vcur); + /*virtual*/ void updateAddedCategory(LLUUID cat_id); + /*virtual*/ void updateRemovedCategory(LLUUID cat_id); + /*virtual*/ void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name); + + /*virtual*/ bool hasItemSelected(); + /*virtual*/ bool canWearSelected(); + + /*virtual*/ bool getHasExpandableFolders() { return FALSE; } + + void updateMessageVisibility(); + bool hasDefaultImage(const LLUUID& outfit_cat_id); + + void refreshTextures(const LLUUID& category_id); + void refreshOutfit(const LLUUID& category_id); + + void onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id); + void onTexturePickerUpdateImageStats(LLPointer<LLViewerTexture> texture); + void onBeforeOutfitSnapshotSave(); + void onAfterOutfitSnapshotSave(); +protected: + /*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id); + /*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid); + /*virtual*/ void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); + /*virtual*/ void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id); + + /*virtual*/ void onCollapseAllFolders() {} + /*virtual*/ void onExpandAllFolders() {} + /*virtual*/ LLOutfitListGearMenuBase* createGearMenu(); + + void applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring); + +private: + void loadPhotos(); + void uploadPhoto(LLUUID outfit_id); + LLUUID getPhotoAssetId(const LLUUID& outfit_id); + LLUUID getDefaultPhoto(); + void linkPhotoToOutfit(LLUUID outfit_id, LLUUID photo_id); + bool checkRemovePhoto(LLUUID outfit_id); + void addToGallery(LLOutfitGalleryItem* item); + void removeFromGalleryLast(LLOutfitGalleryItem* item); + void removeFromGalleryMiddle(LLOutfitGalleryItem* item); + LLPanel* addLastRow(); + void removeLastRow(); + void moveRowUp(int row); + void moveRowDown(int row); + void moveRow(int row, int pos); + LLPanel* addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap); + void removeFromLastRow(LLOutfitGalleryItem* item); + void reArrangeRows(S32 row_diff = 0); + void updateRowsIfNeeded(); + void updateGalleryWidth(); + + LLOutfitGalleryItem* buildGalleryItem(std::string name); + + void onTextureSelectionChanged(LLInventoryItem* itemp); + + void buildGalleryPanel(int row_count); + void reshapeGalleryPanel(int row_count); + LLPanel* buildItemPanel(int left); + LLPanel* buildRowPanel(int left, int bottom); + void moveRowPanel(LLPanel* stack, int left, int bottom); + std::vector<LLPanel*> mRowPanels; + std::vector<LLPanel*> mItemPanels; + std::vector<LLPanel*> mUnusedRowPanels; + std::vector<LLPanel*> mUnusedItemPanels; + std::vector<LLOutfitGalleryItem*> mItems; + std::vector<LLOutfitGalleryItem*> mHiddenItems; + LLScrollContainer* mScrollPanel; + LLPanel* mGalleryPanel; + LLPanel* mLastRowPanel; + LLUUID mOutfitLinkPending; + LLUUID mOutfitRenamePending; + LLTextBox* mMessageTextBox; + bool mGalleryCreated; + int mRowCount; + int mItemsAddedCount; + LLPointer<LLViewerTexture> mTextureSelected; + /* Params */ + int mRowPanelHeight; + int mVerticalGap; + int mHorizontalGap; + int mItemWidth; + int mItemHeight; + int mItemHorizontalGap; + int mItemsInRow; + int mRowPanelWidth; + int mGalleryWidth; + int mRowPanWidthFactor; + int mGalleryWidthFactor; + + LLListContextMenu* mOutfitGalleryMenu; + + LLHandle<LLFloater> mFloaterHandle; + + typedef std::map<LLUUID, LLOutfitGalleryItem*> outfit_map_t; + typedef outfit_map_t::value_type outfit_map_value_t; + outfit_map_t mOutfitMap; + typedef std::map<LLOutfitGalleryItem*, int> item_num_map_t; + typedef item_num_map_t::value_type item_numb_map_value_t; + item_num_map_t mItemIndexMap; + + + LLInventoryCategoriesObserver* mTexturesObserver; + LLInventoryCategoriesObserver* mOutfitsObserver; +}; +class LLOutfitGalleryContextMenu : public LLOutfitContextMenu +{ +public: + + friend class LLOutfitGallery; + LLOutfitGalleryContextMenu(LLOutfitListBase* outfit_list) + : LLOutfitContextMenu(outfit_list), + mOutfitList(outfit_list){} +protected: + /* virtual */ LLContextMenu* createMenu(); + bool onEnable(LLSD::String param); + bool onVisible(LLSD::String param); + void onUploadPhoto(const LLUUID& outfit_cat_id); + void onSelectPhoto(const LLUUID& outfit_cat_id); + void onRemovePhoto(const LLUUID& outfit_cat_id); + void onTakeSnapshot(const LLUUID& outfit_cat_id); + void onCreate(const LLSD& data); + void onRemoveOutfit(const LLUUID& outfit_cat_id); + void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response, const LLUUID& outfit_cat_id); +private: + LLOutfitListBase* mOutfitList; +}; + + +class LLOutfitGalleryGearMenu : public LLOutfitListGearMenuBase +{ +public: + friend class LLOutfitGallery; + LLOutfitGalleryGearMenu(LLOutfitListBase* olist); + +protected: + /*virtual*/ void onUpdateItemsVisibility(); +private: + /*virtual*/ void onUploadFoto(); + /*virtual*/ void onSelectPhoto(); + /*virtual*/ void onTakeSnapshot(); + /*virtual*/ void onRemovePhoto(); + /*virtual*/ void onChangeSortOrder(); + + bool hasDefaultImage(); +}; + +class LLOutfitGalleryItem : public LLPanel +{ +public: + struct Params : public LLInitParam::Block<Params, LLPanel::Params> + {}; + + LLOutfitGalleryItem(const Params& p); + virtual ~LLOutfitGalleryItem(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + + void setDefaultImage(); + void setImageAssetId(LLUUID asset_id); + LLUUID getImageAssetId(); + void setOutfitName(std::string name); + void setOutfitWorn(bool value); + void setSelected(bool value); + + std::string getItemName() {return mOutfitName;} + bool isDefaultImage() {return mDefaultImage;} + + bool isHidden() {return mHidden;} + void setHidden(bool hidden) {mHidden = hidden;} + +private: + LLPointer<LLViewerFetchedTexture> mTexturep; + LLUUID mImageAssetId; + LLTextBox* mOutfitNameText; + LLTextBox* mOutfitWornText; + LLPanel* mTextBgPanel; + bool mSelected; + bool mWorn; + bool mDefaultImage; + bool mHidden; + std::string mOutfitName; +}; + +#endif // LL_LLOUTFITGALLERYCTRL_H diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h index 87d4b0c998d060d870aa9dfbfa704b985892f508..77041db68d094c475df3615fac856a6024f0f475 100644 --- a/indra/newview/lloutfitobserver.h +++ b/indra/newview/lloutfitobserver.h @@ -36,10 +36,10 @@ */ class LLOutfitObserver: public LLInventoryObserver, public LLSingleton<LLOutfitObserver> { -public: + LLSINGLETON(LLOutfitObserver); virtual ~LLOutfitObserver(); - friend class LLSingleton<LLOutfitObserver>; +public: virtual void changed(U32 mask); @@ -58,7 +58,6 @@ class LLOutfitObserver: public LLInventoryObserver, public LLSingleton<LLOutfitO void addOutfitLockChangedCallback(const signal_t::slot_type& cb) { mOutfitLockChanged.connect(cb); } protected: - LLOutfitObserver(); /** Get a version of an inventory category specified by its UUID */ static S32 getCategoryVersion(const LLUUID& cat_id); diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 883221382ced24f2e81310e4815ed5c025953c77..e1f51e62e3b77671d04414104707d7dc1850d2f1 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -38,7 +38,6 @@ #include "llfloatersidepanelcontainer.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" -#include "lllistcontextmenu.h" #include "llmenubutton.h" #include "llnotificationsutil.h" #include "lloutfitobserver.h" @@ -98,276 +97,18 @@ const outfit_accordion_tab_params& get_accordion_tab_params() } -////////////////////////////////////////////////////////////////////////// - -class LLOutfitListGearMenu -{ -public: - LLOutfitListGearMenu(LLOutfitsList* olist) - : mOutfitList(olist), - mMenu(NULL) - { - llassert_always(mOutfitList); - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - - registrar.add("Gear.Wear", boost::bind(&LLOutfitListGearMenu::onWear, this)); - registrar.add("Gear.TakeOff", boost::bind(&LLOutfitListGearMenu::onTakeOff, this)); - registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this)); - registrar.add("Gear.Delete", boost::bind(&LLOutfitsList::removeSelected, mOutfitList)); - registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2)); - registrar.add("Gear.Collapse", boost::bind(&LLOutfitsList::collapse_all_folders, mOutfitList)); - registrar.add("Gear.Expand", boost::bind(&LLOutfitsList::expand_all_folders, mOutfitList)); - - registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenu::onAdd, this)); - - enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2)); - enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenu::onVisible, this, _2)); - - mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>( - "menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - llassert(mMenu); - } - - void updateItemsVisibility() - { - if (!mMenu) return; - - bool have_selection = getSelectedOutfitID().notNull(); - mMenu->setItemVisible("sepatator1", have_selection); - mMenu->setItemVisible("sepatator2", have_selection); - mMenu->arrangeAndClear(); // update menu height - } - - LLToggleableMenu* getMenu() { return mMenu; } - -private: - const LLUUID& getSelectedOutfitID() - { - return mOutfitList->getSelectedOutfitUUID(); - } - - LLViewerInventoryCategory* getSelectedOutfit() - { - const LLUUID& selected_outfit_id = getSelectedOutfitID(); - if (selected_outfit_id.isNull()) - { - return NULL; - } - - LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id); - return cat; - } - - void onWear() - { - LLViewerInventoryCategory* selected_outfit = getSelectedOutfit(); - if (selected_outfit) - { - LLAppearanceMgr::instance().wearInventoryCategory( - selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE); - } - } - - void onAdd() - { - const LLUUID& selected_id = getSelectedOutfitID(); - - if (selected_id.notNull()) - { - LLAppearanceMgr::getInstance()->addCategoryToCurrentOutfit(selected_id); - } - } - - void onTakeOff() - { - // Take off selected outfit. - const LLUUID& selected_outfit_id = getSelectedOutfitID(); - if (selected_outfit_id.notNull()) - { - LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id); - } - } - - void onRename() - { - const LLUUID& selected_outfit_id = getSelectedOutfitID(); - if (selected_outfit_id.notNull()) - { - LLAppearanceMgr::instance().renameOutfit(selected_outfit_id); - } - } - - void onCreate(const LLSD& data) - { - LLWearableType::EType type = LLWearableType::typeNameToType(data.asString()); - if (type == LLWearableType::WT_NONE) - { - LL_WARNS() << "Invalid wearable type" << LL_ENDL; - return; - } - - LLAgentWearables::createWearable(type, true); - } - - bool onEnable(LLSD::String param) - { - // Handle the "Wear - Replace Current Outfit" menu option specially - // because LLOutfitList::isActionEnabled() checks whether it's allowed - // to wear selected outfit OR selected items, while we're only - // interested in the outfit (STORM-183). - if ("wear" == param) - { - return LLAppearanceMgr::instance().getCanReplaceCOF(mOutfitList->getSelectedOutfitUUID()); - } - - return mOutfitList->isActionEnabled(param); - } - - bool onVisible(LLSD::String param) - { - const LLUUID& selected_outfit_id = getSelectedOutfitID(); - if (selected_outfit_id.isNull()) // no selection or invalid outfit selected - { - return false; - } - - // *TODO This condition leads to menu item behavior inconsistent with - // "Wear" button behavior and should be modified or removed. - bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id; - - if ("wear" == param) - { - return !is_worn; - } - - return true; - } - - LLOutfitsList* mOutfitList; - LLToggleableMenu* mMenu; -}; - -////////////////////////////////////////////////////////////////////////// - -class LLOutfitContextMenu : public LLListContextMenu -{ -public: - - LLOutfitContextMenu(LLOutfitsList* outfit_list) - : LLListContextMenu(), - mOutfitList(outfit_list) - {} -protected: - /* virtual */ LLContextMenu* createMenu() - { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - LLUUID selected_id = mUUIDs.front(); - - registrar.add("Outfit.WearReplace", - boost::bind(&LLAppearanceMgr::replaceCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); - registrar.add("Outfit.WearAdd", - boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); - registrar.add("Outfit.TakeOff", - boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id)); - registrar.add("Outfit.Edit", boost::bind(editOutfit)); - registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id)); - registrar.add("Outfit.Delete", boost::bind(&LLOutfitsList::removeSelected, mOutfitList)); - - enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitContextMenu::onEnable, this, _2)); - enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitContextMenu::onVisible, this, _2)); - - return createFromFile("menu_outfit_tab.xml"); - } - - bool onEnable(LLSD::String param) - { - LLUUID outfit_cat_id = mUUIDs.back(); - - if ("rename" == param) - { - return get_is_category_renameable(&gInventory, outfit_cat_id); - } - else if ("wear_replace" == param) - { - return LLAppearanceMgr::instance().getCanReplaceCOF(outfit_cat_id); - } - else if ("wear_add" == param) - { - return LLAppearanceMgr::getCanAddToCOF(outfit_cat_id); - } - else if ("take_off" == param) - { - return LLAppearanceMgr::getCanRemoveFromCOF(outfit_cat_id); - } - - return true; - } - - bool onVisible(LLSD::String param) - { - LLUUID outfit_cat_id = mUUIDs.back(); - bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id; - - if ("edit" == param) - { - return is_worn; - } - else if ("wear_replace" == param) - { - return !is_worn; - } - else if ("delete" == param) - { - return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id); - } - - return true; - } - - static void editOutfit() - { - LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit")); - } - - static void renameOutfit(const LLUUID& outfit_cat_id) - { - LLAppearanceMgr::instance().renameOutfit(outfit_cat_id); - } - -private: - LLOutfitsList* mOutfitList; -}; - -////////////////////////////////////////////////////////////////////////// - static LLPanelInjector<LLOutfitsList> t_outfits_list("outfits_list"); LLOutfitsList::LLOutfitsList() - : LLPanelAppearanceTab() - , mAccordion(NULL) + : LLOutfitListBase() + , mAccordion(NULL) , mListCommands(NULL) - , mIsInitialized(false) , mItemSelected(false) { - mCategoriesObserver = new LLInventoryCategoriesObserver(); - - mGearMenu = new LLOutfitListGearMenu(this); - mOutfitMenu = new LLOutfitContextMenu(this); } LLOutfitsList::~LLOutfitsList() { - delete mGearMenu; - delete mOutfitMenu; - - if (gInventory.containsObserver(mCategoriesObserver)) - { - gInventory.removeObserver(mCategoriesObserver); - } - delete mCategoriesObserver; } BOOL LLOutfitsList::postBuild() @@ -375,54 +116,20 @@ BOOL LLOutfitsList::postBuild() mAccordion = getChild<LLAccordionCtrl>("outfits_accordion"); mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR); - LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn"); - - menu_gear_btn->setMouseDownCallback(boost::bind(&LLOutfitListGearMenu::updateItemsVisibility, mGearMenu)); - menu_gear_btn->setMenu(mGearMenu->getMenu()); - - return TRUE; + return LLOutfitListBase::postBuild(); } //virtual -void LLOutfitsList::onOpen(const LLSD& /*info*/) +void LLOutfitsList::onOpen(const LLSD& info) { - if (!mIsInitialized) - { - // *TODO: I'm not sure is this check necessary but it never match while developing. - if (!gInventory.isInventoryUsable()) - return; + if (!mIsInitialized) + { + const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); + // Start observing changes in Current Outfit category. + mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this)); + } - const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); - - // *TODO: I'm not sure is this check necessary but it never match while developing. - LLViewerInventoryCategory* category = gInventory.getCategory(outfits); - if (!category) - return; - - gInventory.addObserver(mCategoriesObserver); - - // Start observing changes in "My Outfits" category. - mCategoriesObserver->addCategory(outfits, - boost::bind(&LLOutfitsList::refreshList, this, outfits)); - - const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); - - // Start observing changes in Current Outfit category. - mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this)); - - LLOutfitObserver::instance().addBOFChangedCallback(boost::bind(&LLOutfitsList::highlightBaseOutfit, this)); - LLOutfitObserver::instance().addBOFReplacedCallback(boost::bind(&LLOutfitsList::highlightBaseOutfit, this)); - - // Fetch "My Outfits" contents and refresh the list to display - // initially fetched items. If not all items are fetched now - // the observer will refresh the list as soon as the new items - // arrive. - category->fetch(); - refreshList(outfits); - highlightBaseOutfit(); - - mIsInitialized = true; - } + LLOutfitListBase::onOpen(info); LLAccordionCtrlTab* selected_tab = mAccordion->getSelectedTab(); if (!selected_tab) return; @@ -431,174 +138,131 @@ void LLOutfitsList::onOpen(const LLSD& /*info*/) selected_tab->showAndFocusHeader(); } -void LLOutfitsList::refreshList(const LLUUID& category_id) -{ - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - - // Collect all sub-categories of a given category. - LLIsType is_category(LLAssetType::AT_CATEGORY); - gInventory.collectDescendentsIf( - category_id, - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH, - is_category); - - uuid_vec_t vadded; - uuid_vec_t vremoved; - - // Create added and removed items vectors. - computeDifference(cat_array, vadded, vremoved); - - // Handle added tabs. - for (uuid_vec_t::const_iterator iter = vadded.begin(); - iter != vadded.end(); - ++iter) - { - const LLUUID cat_id = (*iter); - LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); - if (!cat) continue; - - std::string name = cat->getName(); - - outfit_accordion_tab_params tab_params(get_accordion_tab_params()); - LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(tab_params); - if (!tab) continue; - LLWearableItemsList* wearable_list = LLUICtrlFactory::create<LLWearableItemsList>(tab_params.wearable_list); - wearable_list->setShape(tab->getLocalRect()); - tab->addChild(wearable_list); - tab->setName(name); - tab->setTitle(name); - - // *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated. - tab->setDisplayChildren(false); - mAccordion->addCollapsibleCtrl(tab); - - // Start observing the new outfit category. - LLWearableItemsList* list = tab->getChild<LLWearableItemsList>("wearable_items_list"); - if (!mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id))) - { - // Remove accordion tab if category could not be added to observer. - mAccordion->removeCollapsibleCtrl(tab); - - // kill removed tab - tab->die(); - continue; - } - - // Map the new tab with outfit category UUID. - mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab)); - - tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this, - _1, _2, _3, cat_id)); +void LLOutfitsList::updateAddedCategory(LLUUID cat_id) +{ + LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); + if (!cat) return; - // Setting tab focus callback to monitor currently selected outfit. - tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id)); + std::string name = cat->getName(); - // Setting callback to reset items selection inside outfit on accordion collapsing and expanding (EXT-7875) - tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::resetItemSelection, this, list, cat_id)); + outfit_accordion_tab_params tab_params(get_accordion_tab_params()); + LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(tab_params); + if (!tab) return; + LLWearableItemsList* wearable_list = LLUICtrlFactory::create<LLWearableItemsList>(tab_params.wearable_list); + wearable_list->setShape(tab->getLocalRect()); + tab->addChild(wearable_list); - // force showing list items that don't match current filter(EXT-7158) - list->setForceShowingUnmatchedItems(true); + tab->setName(name); + tab->setTitle(name); - // Setting list commit callback to monitor currently selected wearable item. - list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1)); + // *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated. + tab->setDisplayChildren(false); + mAccordion->addCollapsibleCtrl(tab); - // Setting list refresh callback to apply filter on list change. - list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1)); + // Start observing the new outfit category. + LLWearableItemsList* list = tab->getChild<LLWearableItemsList>("wearable_items_list"); + if (!mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id))) + { + // Remove accordion tab if category could not be added to observer. + mAccordion->removeCollapsibleCtrl(tab); - list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3)); + // kill removed tab + tab->die(); + return; + } - // Fetch the new outfit contents. - cat->fetch(); + // Map the new tab with outfit category UUID. + mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab)); - // Refresh the list of outfit items after fetch(). - // Further list updates will be triggered by the category observer. - list->updateList(cat_id); + tab->setRightMouseDownCallback(boost::bind(&LLOutfitListBase::outfitRightClickCallBack, this, + _1, _2, _3, cat_id)); - // If filter is currently applied we store the initial tab state and - // open it to show matched items if any. - if (!sFilterSubString.empty()) - { - tab->notifyChildren(LLSD().with("action","store_state")); - tab->setDisplayChildren(true); + // Setting tab focus callback to monitor currently selected outfit. + tab->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::ChangeOutfitSelection, this, list, cat_id)); - // Setting mForceRefresh flag will make the list refresh its contents - // even if it is not currently visible. This is required to apply the - // filter to the newly added list. - list->setForceRefresh(true); + // Setting callback to reset items selection inside outfit on accordion collapsing and expanding (EXT-7875) + tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::resetItemSelection, this, list, cat_id)); - list->setFilterSubString(sFilterSubString); - } - } + // force showing list items that don't match current filter(EXT-7158) + list->setForceShowingUnmatchedItems(true); - // Handle removed tabs. - for (uuid_vec_t::const_iterator iter=vremoved.begin(); iter != vremoved.end(); ++iter) - { - outfits_map_t::iterator outfits_iter = mOutfitsMap.find((*iter)); - if (outfits_iter != mOutfitsMap.end()) - { - const LLUUID& outfit_id = outfits_iter->first; - LLAccordionCtrlTab* tab = outfits_iter->second; + // Setting list commit callback to monitor currently selected wearable item. + list->setCommitCallback(boost::bind(&LLOutfitsList::onListSelectionChange, this, _1)); - // An outfit is removed from the list. Do the following: - // 1. Remove outfit category from observer to stop monitoring its changes. - mCategoriesObserver->removeCategory(outfit_id); + // Setting list refresh callback to apply filter on list change. + list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1)); - // 2. Remove the outfit from selection. - deselectOutfit(outfit_id); + list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3)); - // 3. Remove category UUID to accordion tab mapping. - mOutfitsMap.erase(outfits_iter); + // Fetch the new outfit contents. + cat->fetch(); - // 4. Remove outfit tab from accordion. - mAccordion->removeCollapsibleCtrl(tab); + // Refresh the list of outfit items after fetch(). + // Further list updates will be triggered by the category observer. + list->updateList(cat_id); - // kill removed tab - if (tab != NULL) - { - tab->die(); - } - } - } + // If filter is currently applied we store the initial tab state and + // open it to show matched items if any. + if (!sFilterSubString.empty()) + { + tab->notifyChildren(LLSD().with("action", "store_state")); + tab->setDisplayChildren(true); - // Get changed items from inventory model and update outfit tabs - // which might have been renamed. - const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs(); - for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin(); - items_iter != changed_items.end(); - ++items_iter) - { - updateOutfitTab(*items_iter); - } + // Setting mForceRefresh flag will make the list refresh its contents + // even if it is not currently visible. This is required to apply the + // filter to the newly added list. + list->setForceRefresh(true); - mAccordion->sort(); + list->setFilterSubString(sFilterSubString); + } } -void LLOutfitsList::highlightBaseOutfit() +void LLOutfitsList::updateRemovedCategory(LLUUID cat_id) { - // id of base outfit - LLUUID base_id = LLAppearanceMgr::getInstance()->getBaseOutfitUUID(); - if (base_id != mHighlightedOutfitUUID) - { - if (mOutfitsMap[mHighlightedOutfitUUID]) - { - mOutfitsMap[mHighlightedOutfitUUID]->setTitleFontStyle("NORMAL"); - mOutfitsMap[mHighlightedOutfitUUID]->setTitleColor(LLUIColorTable::instance().getColor("AccordionHeaderTextColor")); - } + outfits_map_t::iterator outfits_iter = mOutfitsMap.find(cat_id); + if (outfits_iter != mOutfitsMap.end()) + { + const LLUUID& outfit_id = outfits_iter->first; + LLAccordionCtrlTab* tab = outfits_iter->second; + + // An outfit is removed from the list. Do the following: + // 1. Remove outfit category from observer to stop monitoring its changes. + mCategoriesObserver->removeCategory(outfit_id); + + // 2. Remove the outfit from selection. + deselectOutfit(outfit_id); + + // 3. Remove category UUID to accordion tab mapping. + mOutfitsMap.erase(outfits_iter); + + // 4. Remove outfit tab from accordion. + mAccordion->removeCollapsibleCtrl(tab); + + // kill removed tab + if (tab != NULL) + { + tab->die(); + } + } +} - mHighlightedOutfitUUID = base_id; - } - if (mOutfitsMap[base_id]) +//virtual +void LLOutfitsList::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id) +{ + if (mOutfitsMap[prev_id]) + { + mOutfitsMap[prev_id]->setTitleFontStyle("NORMAL"); + mOutfitsMap[prev_id]->setTitleColor(LLUIColorTable::instance().getColor("AccordionHeaderTextColor")); + } + if (mOutfitsMap[base_id]) { mOutfitsMap[base_id]->setTitleFontStyle("BOLD"); mOutfitsMap[base_id]->setTitleColor(LLUIColorTable::instance().getColor("SelectedOutfitTextColor")); } } -void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl) +void LLOutfitsList::onListSelectionChange(LLUICtrl* ctrl) { LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl); if (!list) return; @@ -606,10 +270,10 @@ void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl) LLViewerInventoryItem *item = gInventory.getItem(list->getSelectedUUID()); if (!item) return; - changeOutfitSelection(list, item->getParentUUID()); + ChangeOutfitSelection(list, item->getParentUUID()); } -void LLOutfitsList::performAction(std::string action) +void LLOutfitListBase::performAction(std::string action) { if (mSelectedOutfitUUID.isNull()) return; @@ -630,23 +294,7 @@ void LLOutfitsList::performAction(std::string action) } } -void LLOutfitsList::removeSelected() -{ - LLNotificationsUtil::add("DeleteOutfits", LLSD(), LLSD(), boost::bind(&LLOutfitsList::onOutfitsRemovalConfirmation, this, _1, _2)); -} - -void LLOutfitsList::onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return; // canceled - - if (mSelectedOutfitUUID.notNull()) - { - gInventory.removeCategory(mSelectedOutfitUUID); - } -} - -void LLOutfitsList::setSelectedOutfitByUUID(const LLUUID& outfit_uuid) +void LLOutfitsList::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid) { for (outfits_map_t::iterator iter = mOutfitsMap.begin(); iter != mOutfitsMap.end(); @@ -661,7 +309,7 @@ void LLOutfitsList::setSelectedOutfitByUUID(const LLUUID& outfit_uuid) if (!list) continue; tab->setFocus(TRUE); - changeOutfitSelection(list, outfit_uuid); + ChangeOutfitSelection(list, outfit_uuid); tab->setDisplayChildren(true); } @@ -677,14 +325,14 @@ void LLOutfitsList::setFilterSubString(const std::string& string) } // virtual -bool LLOutfitsList::isActionEnabled(const LLSD& userdata) +bool LLOutfitListBase::isActionEnabled(const LLSD& userdata) { if (mSelectedOutfitUUID.isNull()) return false; const std::string command_name = userdata.asString(); if (command_name == "delete") { - return !mItemSelected && LLAppearanceMgr::instance().getCanRemoveOutfit(mSelectedOutfitUUID); + return !hasItemSelected() && LLAppearanceMgr::instance().getCanRemoveOutfit(mSelectedOutfitUUID); } if (command_name == "rename") { @@ -745,7 +393,7 @@ void LLOutfitsList::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const } } -void LLOutfitsList::collapse_all_folders() +void LLOutfitsList::onCollapseAllFolders() { for (outfits_map_t::iterator iter = mOutfitsMap.begin(); iter != mOutfitsMap.end(); @@ -759,7 +407,7 @@ void LLOutfitsList::collapse_all_folders() } } -void LLOutfitsList::expand_all_folders() +void LLOutfitsList::onExpandAllFolders() { for (outfits_map_t::iterator iter = mOutfitsMap.begin(); iter != mOutfitsMap.end(); @@ -773,11 +421,6 @@ void LLOutfitsList::expand_all_folders() } } -boost::signals2::connection LLOutfitsList::setSelectionChangeCallback(selection_change_callback_t cb) -{ - return mSelectionChangeSignal.connect(cb); -} - bool LLOutfitsList::hasItemSelected() { return mItemSelected; @@ -786,42 +429,12 @@ bool LLOutfitsList::hasItemSelected() ////////////////////////////////////////////////////////////////////////// // Private methods ////////////////////////////////////////////////////////////////////////// -void LLOutfitsList::computeDifference( - const LLInventoryModel::cat_array_t& vcats, - uuid_vec_t& vadded, - uuid_vec_t& vremoved) -{ - uuid_vec_t vnew; - // Creating a vector of newly collected sub-categories UUIDs. - for (LLInventoryModel::cat_array_t::const_iterator iter = vcats.begin(); - iter != vcats.end(); - iter++) - { - vnew.push_back((*iter)->getUUID()); - } - - uuid_vec_t vcur; - // Creating a vector of currently displayed sub-categories UUIDs. - for (outfits_map_t::const_iterator iter = mOutfitsMap.begin(); - iter != mOutfitsMap.end(); - iter++) - { - vcur.push_back((*iter).first); - } - LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved); -} - -void LLOutfitsList::updateOutfitTab(const LLUUID& category_id) +void LLOutfitsList::updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name) { - outfits_map_t::iterator outfits_iter = mOutfitsMap.find(category_id); + outfits_map_t::iterator outfits_iter = mOutfitsMap.find(cat->getUUID()); if (outfits_iter != mOutfitsMap.end()) { - LLViewerInventoryCategory *cat = gInventory.getCategory(category_id); - if (!cat) return; - - std::string name = cat->getName(); - // Update tab name with the new category name. LLAccordionCtrlTab* tab = outfits_iter->second; if (tab) @@ -836,10 +449,10 @@ void LLOutfitsList::resetItemSelection(LLWearableItemsList* list, const LLUUID& { list->resetSelection(); mItemSelected = false; - setSelectedOutfitUUID(category_id); + signalSelectionOutfitUUID(category_id); } -void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) +void LLOutfitsList::onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) { MASK mask = gKeyboard->currentMask(TRUE); @@ -865,24 +478,14 @@ void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUI mItemSelected = list && (list->getSelectedItem() != NULL); mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list)); - setSelectedOutfitUUID(category_id); -} - -void LLOutfitsList::setSelectedOutfitUUID(const LLUUID& category_id) -{ - mSelectionChangeSignal(mSelectedOutfitUUID = category_id); } void LLOutfitsList::deselectOutfit(const LLUUID& category_id) { // Remove selected lists map entry. mSelectedListsMap.erase(category_id); - - // Reset selection if the outfit is selected. - if (category_id == mSelectedOutfitUUID) - { - setSelectedOutfitUUID(LLUUID::null); - } + + LLOutfitListBase::deselectOutfit(category_id); } void LLOutfitsList::restoreOutfitSelection(LLAccordionCtrlTab* tab, const LLUUID& category_id) @@ -890,7 +493,7 @@ void LLOutfitsList::restoreOutfitSelection(LLAccordionCtrlTab* tab, const LLUUID // Try restoring outfit selection after filtering. if (mAccordion->getSelectedTab() == tab) { - setSelectedOutfitUUID(category_id); + signalSelectionOutfitUUID(category_id); } } @@ -1036,24 +639,6 @@ bool LLOutfitsList::canWearSelected() return true; } -void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) -{ - LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); - if(mOutfitMenu && is_tab_header_clicked(tab, y) && cat_id.notNull()) - { - // Focus tab header to trigger tab selection change. - LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header"); - if (header) - { - header->setFocus(TRUE); - } - - uuid_vec_t selected_uuids; - selected_uuids.push_back(cat_id); - mOutfitMenu->show(ctrl, selected_uuids, x, y); - } -} - void LLOutfitsList::wearSelectedItems() { uuid_vec_t selected_uuids; @@ -1132,6 +717,47 @@ void LLOutfitsList::onCOFChanged() } } +void LLOutfitsList::getCurrentCategories(uuid_vec_t& vcur) +{ + // Creating a vector of currently displayed sub-categories UUIDs. + for (outfits_map_t::const_iterator iter = mOutfitsMap.begin(); + iter != mOutfitsMap.end(); + iter++) + { + vcur.push_back((*iter).first); + } +} + + +void LLOutfitsList::sortOutfits() +{ + mAccordion->sort(); +} + +void LLOutfitsList::onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) +{ + LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); + if (mOutfitMenu && is_tab_header_clicked(tab, y) && cat_id.notNull()) + { + // Focus tab header to trigger tab selection change. + LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header"); + if (header) + { + header->setFocus(TRUE); + } + + uuid_vec_t selected_uuids; + selected_uuids.push_back(cat_id); + mOutfitMenu->show(ctrl, selected_uuids, x, y); + } +} + +LLOutfitListGearMenuBase* LLOutfitsList::createGearMenu() +{ + return new LLOutfitListGearMenu(this); +} + + bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y) { if(!tab || !tab->getHeaderVisible()) return false; @@ -1140,4 +766,519 @@ bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y) return y >= header_bottom; } +LLOutfitListBase::LLOutfitListBase() + : LLPanelAppearanceTab() + , mIsInitialized(false) +{ + mCategoriesObserver = new LLInventoryCategoriesObserver(); + mOutfitMenu = new LLOutfitContextMenu(this); + //mGearMenu = createGearMenu(); +} + +LLOutfitListBase::~LLOutfitListBase() +{ + delete mOutfitMenu; + delete mGearMenu; + + if (gInventory.containsObserver(mCategoriesObserver)) + { + gInventory.removeObserver(mCategoriesObserver); + } + delete mCategoriesObserver; +} + +void LLOutfitListBase::onOpen(const LLSD& info) +{ + if (!mIsInitialized) + { + // *TODO: I'm not sure is this check necessary but it never match while developing. + if (!gInventory.isInventoryUsable()) + return; + + const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); + + // *TODO: I'm not sure is this check necessary but it never match while developing. + LLViewerInventoryCategory* category = gInventory.getCategory(outfits); + if (!category) + return; + + gInventory.addObserver(mCategoriesObserver); + + // Start observing changes in "My Outfits" category. + mCategoriesObserver->addCategory(outfits, + boost::bind(&LLOutfitListBase::refreshList, this, outfits)); + + const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); + + // Start observing changes in Current Outfit category. + //mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this)); + + LLOutfitObserver::instance().addBOFChangedCallback(boost::bind(&LLOutfitListBase::highlightBaseOutfit, this)); + LLOutfitObserver::instance().addBOFReplacedCallback(boost::bind(&LLOutfitListBase::highlightBaseOutfit, this)); + + // Fetch "My Outfits" contents and refresh the list to display + // initially fetched items. If not all items are fetched now + // the observer will refresh the list as soon as the new items + // arrive. + category->fetch(); + refreshList(outfits); + highlightBaseOutfit(); + + mIsInitialized = true; + } +} + +void LLOutfitListBase::refreshList(const LLUUID& category_id) +{ + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + + // Collect all sub-categories of a given category. + LLIsType is_category(LLAssetType::AT_CATEGORY); + gInventory.collectDescendentsIf( + category_id, + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_category); + + uuid_vec_t vadded; + uuid_vec_t vremoved; + + // Create added and removed items vectors. + computeDifference(cat_array, vadded, vremoved); + + // Handle added tabs. + for (uuid_vec_t::const_iterator iter = vadded.begin(); + iter != vadded.end(); + ++iter) + { + const LLUUID cat_id = (*iter); + updateAddedCategory(cat_id); + } + + // Handle removed tabs. + for (uuid_vec_t::const_iterator iter = vremoved.begin(); iter != vremoved.end(); ++iter) + { + const LLUUID cat_id = (*iter); + updateRemovedCategory(cat_id); + } + + // Get changed items from inventory model and update outfit tabs + // which might have been renamed. + const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs(); + for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin(); + items_iter != changed_items.end(); + ++items_iter) + { + LLViewerInventoryCategory *cat = gInventory.getCategory(*items_iter); + if (!cat) + { + LLInventoryObject* obj = gInventory.getObject(*items_iter); + if(!obj || (obj->getType() != LLAssetType::AT_CATEGORY)) + { + return; + } + cat = (LLViewerInventoryCategory*)obj; + } + std::string name = cat->getName(); + + updateChangedCategoryName(cat, name); + } + + sortOutfits(); +} + +void LLOutfitListBase::computeDifference( + const LLInventoryModel::cat_array_t& vcats, + uuid_vec_t& vadded, + uuid_vec_t& vremoved) +{ + uuid_vec_t vnew; + // Creating a vector of newly collected sub-categories UUIDs. + for (LLInventoryModel::cat_array_t::const_iterator iter = vcats.begin(); + iter != vcats.end(); + iter++) + { + vnew.push_back((*iter)->getUUID()); + } + + uuid_vec_t vcur; + getCurrentCategories(vcur); + + LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved); +} + +void LLOutfitListBase::sortOutfits() +{ +} + +void LLOutfitListBase::highlightBaseOutfit() +{ + // id of base outfit + LLUUID base_id = LLAppearanceMgr::getInstance()->getBaseOutfitUUID(); + if (base_id != mHighlightedOutfitUUID) + { + LLUUID prev_id = mHighlightedOutfitUUID; + mHighlightedOutfitUUID = base_id; + onHighlightBaseOutfit(base_id, prev_id); + } + +} + +void LLOutfitListBase::removeSelected() +{ + LLNotificationsUtil::add("DeleteOutfits", LLSD(), LLSD(), boost::bind(&LLOutfitListBase::onOutfitsRemovalConfirmation, this, _1, _2)); +} + +void LLOutfitListBase::onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return; // canceled + + if (mSelectedOutfitUUID.notNull()) + { + gInventory.removeCategory(mSelectedOutfitUUID); + } +} + +void LLOutfitListBase::setSelectedOutfitByUUID(const LLUUID& outfit_uuid) +{ + onSetSelectedOutfitByUUID(outfit_uuid); +} + +boost::signals2::connection LLOutfitListBase::setSelectionChangeCallback(selection_change_callback_t cb) +{ + return mSelectionChangeSignal.connect(cb); +} + +void LLOutfitListBase::signalSelectionOutfitUUID(const LLUUID& category_id) +{ + mSelectionChangeSignal(category_id); +} + +void LLOutfitListBase::outfitRightClickCallBack(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) +{ + onOutfitRightClick(ctrl, x, y, cat_id); +} + +void LLOutfitListBase::ChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) +{ + onChangeOutfitSelection(list, category_id); + mSelectedOutfitUUID = category_id; + signalSelectionOutfitUUID(category_id); +} + +BOOL LLOutfitListBase::postBuild() +{ + mGearMenu = createGearMenu(); + + LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn"); + + menu_gear_btn->setMouseDownCallback(boost::bind(&LLOutfitListGearMenuBase::updateItemsVisibility, mGearMenu)); + menu_gear_btn->setMenu(mGearMenu->getMenu()); + return TRUE; +} + +void LLOutfitListBase::collapseAllFolders() +{ + onCollapseAllFolders(); +} + +void LLOutfitListBase::expandAllFolders() +{ + onExpandAllFolders(); +} + +void LLOutfitListBase::deselectOutfit(const LLUUID& category_id) +{ + // Reset selection if the outfit is selected. + if (category_id == mSelectedOutfitUUID) + { + signalSelectionOutfitUUID(LLUUID::null); + } +} + +LLContextMenu* LLOutfitContextMenu::createMenu() +{ + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + LLUUID selected_id = mUUIDs.front(); + + registrar.add("Outfit.WearReplace", + boost::bind(&LLAppearanceMgr::replaceCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); + registrar.add("Outfit.WearAdd", + boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); + registrar.add("Outfit.TakeOff", + boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id)); + registrar.add("Outfit.Edit", boost::bind(editOutfit)); + registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id)); + registrar.add("Outfit.Delete", boost::bind(&LLOutfitListBase::removeSelected, mOutfitList)); + + enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitContextMenu::onEnable, this, _2)); + enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitContextMenu::onVisible, this, _2)); + + return createFromFile("menu_outfit_tab.xml"); + +} + +bool LLOutfitContextMenu::onEnable(LLSD::String param) +{ + LLUUID outfit_cat_id = mUUIDs.back(); + + if ("rename" == param) + { + return get_is_category_renameable(&gInventory, outfit_cat_id); + } + else if ("wear_replace" == param) + { + return LLAppearanceMgr::instance().getCanReplaceCOF(outfit_cat_id); + } + else if ("wear_add" == param) + { + return LLAppearanceMgr::getCanAddToCOF(outfit_cat_id); + } + else if ("take_off" == param) + { + return LLAppearanceMgr::getCanRemoveFromCOF(outfit_cat_id); + } + + return true; +} + +bool LLOutfitContextMenu::onVisible(LLSD::String param) +{ + LLUUID outfit_cat_id = mUUIDs.back(); + bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id; + + if ("edit" == param) + { + return is_worn; + } + else if ("wear_replace" == param) + { + return !is_worn; + } + else if ("delete" == param) + { + return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id); + } + + return true; +} + +//static +void LLOutfitContextMenu::editOutfit() +{ + LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit")); +} + +void LLOutfitContextMenu::renameOutfit(const LLUUID& outfit_cat_id) +{ + LLAppearanceMgr::instance().renameOutfit(outfit_cat_id); +} + +LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist) + : mOutfitList(olist), + mMenu(NULL) +{ + llassert_always(mOutfitList); + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + registrar.add("Gear.Wear", boost::bind(&LLOutfitListGearMenuBase::onWear, this)); + registrar.add("Gear.TakeOff", boost::bind(&LLOutfitListGearMenuBase::onTakeOff, this)); + registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenuBase::onRename, this)); + registrar.add("Gear.Delete", boost::bind(&LLOutfitListBase::removeSelected, mOutfitList)); + registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenuBase::onCreate, this, _2)); + registrar.add("Gear.Collapse", boost::bind(&LLOutfitListBase::onCollapseAllFolders, mOutfitList)); + registrar.add("Gear.Expand", boost::bind(&LLOutfitListBase::onExpandAllFolders, mOutfitList)); + + registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this)); + + registrar.add("Gear.UploadPhoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this)); + registrar.add("Gear.SelectPhoto", boost::bind(&LLOutfitListGearMenuBase::onSelectPhoto, this)); + registrar.add("Gear.TakeSnapshot", boost::bind(&LLOutfitListGearMenuBase::onTakeSnapshot, this)); + registrar.add("Gear.RemovePhoto", boost::bind(&LLOutfitListGearMenuBase::onRemovePhoto, this)); + registrar.add("Gear.SortByName", boost::bind(&LLOutfitListGearMenuBase::onChangeSortOrder, this)); + + enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2)); + enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenuBase::onVisible, this, _2)); + + mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>( + "menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + llassert(mMenu); +} + +LLOutfitListGearMenuBase::~LLOutfitListGearMenuBase() +{} + +void LLOutfitListGearMenuBase::updateItemsVisibility() +{ + onUpdateItemsVisibility(); +} + +void LLOutfitListGearMenuBase::onUpdateItemsVisibility() +{ + if (!mMenu) return; + + bool have_selection = getSelectedOutfitID().notNull(); + mMenu->setItemVisible("sepatator1", have_selection); + mMenu->setItemVisible("sepatator2", have_selection); + mMenu->arrangeAndClear(); // update menu height +} + +LLToggleableMenu* LLOutfitListGearMenuBase::getMenu() +{ + return mMenu; +} +const LLUUID& LLOutfitListGearMenuBase::getSelectedOutfitID() +{ + return mOutfitList->getSelectedOutfitUUID(); +} + +LLViewerInventoryCategory* LLOutfitListGearMenuBase::getSelectedOutfit() +{ + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.isNull()) + { + return NULL; + } + + LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id); + return cat; +} + +void LLOutfitListGearMenuBase::onWear() +{ + LLViewerInventoryCategory* selected_outfit = getSelectedOutfit(); + if (selected_outfit) + { + LLAppearanceMgr::instance().wearInventoryCategory( + selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE); + } +} + +void LLOutfitListGearMenuBase::onAdd() +{ + const LLUUID& selected_id = getSelectedOutfitID(); + + if (selected_id.notNull()) + { + LLAppearanceMgr::getInstance()->addCategoryToCurrentOutfit(selected_id); + } +} + +void LLOutfitListGearMenuBase::onTakeOff() +{ + // Take off selected outfit. + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.notNull()) + { + LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id); + } +} + +void LLOutfitListGearMenuBase::onRename() +{ + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.notNull()) + { + LLAppearanceMgr::instance().renameOutfit(selected_outfit_id); + } +} + +void LLOutfitListGearMenuBase::onCreate(const LLSD& data) +{ + LLWearableType::EType type = LLWearableType::typeNameToType(data.asString()); + if (type == LLWearableType::WT_NONE) + { + LL_WARNS() << "Invalid wearable type" << LL_ENDL; + return; + } + + LLAgentWearables::createWearable(type, true); +} + +bool LLOutfitListGearMenuBase::onEnable(LLSD::String param) +{ + // Handle the "Wear - Replace Current Outfit" menu option specially + // because LLOutfitList::isActionEnabled() checks whether it's allowed + // to wear selected outfit OR selected items, while we're only + // interested in the outfit (STORM-183). + if ("wear" == param) + { + return LLAppearanceMgr::instance().getCanReplaceCOF(mOutfitList->getSelectedOutfitUUID()); + } + + return mOutfitList->isActionEnabled(param); +} + +bool LLOutfitListGearMenuBase::onVisible(LLSD::String param) +{ + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.isNull()) // no selection or invalid outfit selected + { + return false; + } + + // *TODO This condition leads to menu item behavior inconsistent with + // "Wear" button behavior and should be modified or removed. + bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id; + + if ("wear" == param) + { + return !is_worn; + } + + return true; +} + +void LLOutfitListGearMenuBase::onUploadFoto() +{ + +} + +void LLOutfitListGearMenuBase::onSelectPhoto() +{ + +} + +void LLOutfitListGearMenuBase::onTakeSnapshot() +{ + +} + +void LLOutfitListGearMenuBase::onRemovePhoto() +{ + +} + +void LLOutfitListGearMenuBase::onChangeSortOrder() +{ + +} + +LLOutfitListGearMenu::LLOutfitListGearMenu(LLOutfitListBase* olist) + : LLOutfitListGearMenuBase(olist) +{} + +LLOutfitListGearMenu::~LLOutfitListGearMenu() +{} + +void LLOutfitListGearMenu::onUpdateItemsVisibility() +{ + if (!mMenu) return; + mMenu->setItemVisible("expand", TRUE); + mMenu->setItemVisible("collapse", TRUE); + mMenu->setItemVisible("upload_photo", FALSE); + mMenu->setItemVisible("select_photo", FALSE); + mMenu->setItemVisible("take_snapshot", FALSE); + mMenu->setItemVisible("remove_photo", FALSE); + mMenu->setItemVisible("sepatator3", FALSE); + mMenu->setItemVisible("sort_folders_by_name", FALSE); + LLOutfitListGearMenuBase::onUpdateItemsVisibility(); +} + // EOF diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 2e3fb3f4882598e8d2897c89a1eb3177f6346382..81be8de94f885ff866451bf6b19d05264ef639f7 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -32,11 +32,14 @@ // newview #include "llinventorymodel.h" +#include "lllistcontextmenu.h" #include "llpanelappearancetab.h" +#include "lltoggleablemenu.h" +#include "llviewermenu.h" class LLAccordionCtrlTab; class LLInventoryCategoriesObserver; -class LLOutfitListGearMenu; +class LLOutfitListGearMenuBase; class LLWearableItemsList; class LLListContextMenu; @@ -57,6 +60,142 @@ class LLOutfitTabNameComparator : public LLAccordionCtrl::LLTabComparator /*virtual*/ bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const; }; +class LLOutfitListBase : public LLPanelAppearanceTab +{ +public: + typedef boost::function<void(const LLUUID&)> selection_change_callback_t; + typedef boost::signals2::signal<void(const LLUUID&)> selection_change_signal_t; + + LLOutfitListBase(); + virtual ~LLOutfitListBase(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& info); + + void refreshList(const LLUUID& category_id); + void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved); + // highlights currently worn outfit in list and unhighlights previously worn + void highlightBaseOutfit(); + void ChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id); + + + virtual void getCurrentCategories(uuid_vec_t& vcur) = 0; + virtual void updateAddedCategory(LLUUID cat_id) = 0; + virtual void updateRemovedCategory(LLUUID cat_id) = 0; + virtual void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name) = 0; + virtual void sortOutfits(); + + void removeSelected(); + void setSelectedOutfitByUUID(const LLUUID& outfit_uuid); + const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; } + boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb); + void outfitRightClickCallBack(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); + + virtual bool isActionEnabled(const LLSD& userdata); + virtual void performAction(std::string action); + virtual bool hasItemSelected() = 0; + virtual bool canWearSelected() = 0; + + virtual void deselectOutfit(const LLUUID& category_id); + + void signalSelectionOutfitUUID(const LLUUID& category_id); + + void collapseAllFolders(); + virtual void onCollapseAllFolders() = 0; + + void expandAllFolders(); + virtual void onExpandAllFolders() = 0; + + virtual bool getHasExpandableFolders() = 0; + +protected: + virtual LLOutfitListGearMenuBase* createGearMenu() = 0; + virtual void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id) = 0; + virtual void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid) = 0; + virtual void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) = 0; + void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response); + virtual void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) = 0; + + bool mIsInitialized; + LLInventoryCategoriesObserver* mCategoriesObserver; + LLUUID mSelectedOutfitUUID; + // id of currently highlited outfit + LLUUID mHighlightedOutfitUUID; + selection_change_signal_t mSelectionChangeSignal; + LLListContextMenu* mOutfitMenu; + LLOutfitListGearMenuBase* mGearMenu; +}; + +////////////////////////////////////////////////////////////////////////// + +class LLOutfitContextMenu : public LLListContextMenu +{ +public: + + LLOutfitContextMenu(LLOutfitListBase* outfit_list) + : LLListContextMenu(), + mOutfitList(outfit_list) + {} +protected: + /* virtual */ LLContextMenu* createMenu(); + + bool onEnable(LLSD::String param); + + bool onVisible(LLSD::String param); + + static void editOutfit(); + + static void renameOutfit(const LLUUID& outfit_cat_id); + +private: + LLOutfitListBase* mOutfitList; +}; + +class LLOutfitListGearMenuBase +{ +public: + LLOutfitListGearMenuBase(LLOutfitListBase* olist); + virtual ~LLOutfitListGearMenuBase(); + + void updateItemsVisibility(); + + LLToggleableMenu* getMenu(); + +protected: + virtual void onUpdateItemsVisibility(); + virtual void onUploadFoto(); + virtual void onSelectPhoto(); + virtual void onTakeSnapshot(); + virtual void onRemovePhoto(); + virtual void onChangeSortOrder(); + + const LLUUID& getSelectedOutfitID(); + + LLOutfitListBase* mOutfitList; + LLToggleableMenu* mMenu; +private: + + LLViewerInventoryCategory* getSelectedOutfit(); + + void onWear(); + void onAdd(); + void onTakeOff(); + void onRename(); + void onCreate(const LLSD& data); + bool onEnable(LLSD::String param); + bool onVisible(LLSD::String param); +}; + +class LLOutfitListGearMenu : public LLOutfitListGearMenuBase +{ +public: + LLOutfitListGearMenu(LLOutfitListBase* olist); + virtual ~LLOutfitListGearMenu(); + +protected: + /*virtual*/ void onUpdateItemsVisibility(); +}; + /** * @class LLOutfitsList * @@ -66,11 +205,9 @@ class LLOutfitTabNameComparator : public LLAccordionCtrl::LLTabComparator * * Starts fetching necessary inventory content on first opening. */ -class LLOutfitsList : public LLPanelAppearanceTab +class LLOutfitsList : public LLOutfitListBase { public: - typedef boost::function<void (const LLUUID&)> selection_change_callback_t; - typedef boost::signals2::signal<void (const LLUUID&)> selection_change_signal_t; LLOutfitsList(); virtual ~LLOutfitsList(); @@ -79,78 +216,76 @@ class LLOutfitsList : public LLPanelAppearanceTab /*virtual*/ void onOpen(const LLSD& info); - void refreshList(const LLUUID& category_id); - - // highlits currently worn outfit tab text and unhighlights previously worn - void highlightBaseOutfit(); - void performAction(std::string action); + //virtual void refreshList(const LLUUID& category_id); - void removeSelected(); + /*virtual*/ void updateAddedCategory(LLUUID cat_id); + /*virtual*/ void updateRemovedCategory(LLUUID cat_id); - void setSelectedOutfitByUUID(const LLUUID& outfit_uuid); + // highlits currently worn outfit tab text and unhighlights previously worn + /*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id); - /*virtual*/ void setFilterSubString(const std::string& string); + //void performAction(std::string action); - /*virtual*/ bool isActionEnabled(const LLSD& userdata); - const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; } + /*virtual*/ void setFilterSubString(const std::string& string); /*virtual*/ void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const; - boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb); - - // Collects selected items from all selected lists and wears them(if possible- adds, else replaces) + // Collects selected items from all selected lists and wears them(if possible- adds, else replaces) void wearSelectedItems(); /** * Returns true if there is a selection inside currently selected outfit */ - bool hasItemSelected(); + /*virtual*/ bool hasItemSelected(); /** Collapses all outfit accordions. */ - void collapse_all_folders(); + /*virtual*/ void onCollapseAllFolders(); /** Expands all outfit accordions. */ - void expand_all_folders(); + void onExpandAllFolders(); + /*virtual*/ bool getHasExpandableFolders() { return TRUE; } -private: +protected: + LLOutfitListGearMenuBase* createGearMenu(); - void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response); +private: /** * Wrapper for LLCommonUtils::computeDifference. @see LLCommonUtils::computeDifference */ - void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved); + //void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved); + + void getCurrentCategories(uuid_vec_t& vcur); /** * Updates tab displaying outfit identified by category_id. */ - void updateOutfitTab(const LLUUID& category_id); + /*virtual*/ void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name); + + /*virtual*/ void sortOutfits(); + + /*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid); /** * Resets previous selection and stores newly selected list and outfit id. */ - void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id); + /*virtual*/ void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id); /** *Resets items selection inside outfit */ void resetItemSelection(LLWearableItemsList* list, const LLUUID& category_id); - /** - * Saves newly selected outfit ID. - */ - void setSelectedOutfitUUID(const LLUUID& category_id); - /** * Removes the outfit from selection. */ - void deselectOutfit(const LLUUID& category_id); + /*virtual*/ void deselectOutfit(const LLUUID& category_id); /** * Try restoring selection for a temporary hidden tab. @@ -182,15 +317,16 @@ class LLOutfitsList : public LLPanelAppearanceTab */ bool canWearSelected(); - void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); void onCOFChanged(); - void onSelectionChange(LLUICtrl* ctrl); + void onListSelectionChange(LLUICtrl* ctrl); + + /*virtual*/ void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); static void onOutfitRename(const LLSD& notification, const LLSD& response); - LLInventoryCategoriesObserver* mCategoriesObserver; + //LLInventoryCategoriesObserver* mCategoriesObserver; LLAccordionCtrl* mAccordion; LLPanel* mListCommands; @@ -199,11 +335,6 @@ class LLOutfitsList : public LLPanelAppearanceTab typedef wearables_lists_map_t::value_type wearables_lists_map_value_t; wearables_lists_map_t mSelectedListsMap; - LLUUID mSelectedOutfitUUID; - // id of currently highlited outfit - LLUUID mHighlightedOutfitUUID; - selection_change_signal_t mSelectionChangeSignal; - typedef std::map<LLUUID, LLAccordionCtrlTab*> outfits_map_t; typedef outfits_map_t::value_type outfits_map_value_t; outfits_map_t mOutfitsMap; @@ -212,10 +343,9 @@ class LLOutfitsList : public LLPanelAppearanceTab // Used to monitor COF changes for updating items worn state. See EXT-8636. uuid_vec_t mCOFLinkedItems; - LLOutfitListGearMenu* mGearMenu; - LLListContextMenu* mOutfitMenu; + //LLOutfitListGearMenu* mGearMenu; - bool mIsInitialized; + //bool mIsInitialized; /** * True if there is a selection inside currently selected outfit */ diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index b7e1b2d3a432e8441f665bc60c9657dfdfc8c516..f2d43a103772fd81506033d369b972e79ae80e21 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -117,8 +117,7 @@ class LLEditWearableDictionary : public LLSingleton<LLEditWearableDictionary> //-------------------------------------------------------------------- // Constructors and Destructors //-------------------------------------------------------------------- -public: - LLEditWearableDictionary(); + LLSINGLETON(LLEditWearableDictionary); virtual ~LLEditWearableDictionary(); //-------------------------------------------------------------------- diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index b2164c1f21f2683cc87e3b583fe2c4ad8a5af49b..d17f5494a05e1fddc4a7617e6fe468bd0c89680c 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -199,7 +199,7 @@ void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group) mGroupNameEditor = panel_group->getChild<LLLineEditor>("group_name_editor"); - mGroupNameEditor->setPrevalidate( LLTextValidate::validateASCII ); + mGroupNameEditor->setPrevalidate( LLTextValidate::validateASCIINoLeadingSpace ); } diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 54728885c1aaf6cea6207b93d7e9e3c787ecbfe3..48b659a81e21c2b02c70327c572f3ebd2a49fcdc 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -37,7 +37,6 @@ #include "llinventoryfunctions.h" #include "llinventoryicon.h" #include "llinventorymodel.h" -#include "llfloaterinventory.h" #include "llagent.h" #include "llagentui.h" diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index c779ba5cdd68006583e75e5592472e63fc40039c..fa946ee5c7ac6c5da50a89fc6cbb93662e7e06d6 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -33,7 +33,6 @@ #include "lldndbutton.h" #include "lleconomy.h" #include "llfilepicker.h" -#include "llfloaterinventory.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" @@ -106,7 +105,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p) mSavedFolderState(NULL), mFilterText(""), mMenuGearDefault(NULL), - mMenuAdd(NULL), + mMenuAddHandle(), mNeedUploadCost(true) { // Menu Callbacks (non contex menus) @@ -115,7 +114,6 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p) 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.NewWindow", boost::bind(&LLPanelMainInventory::newWindow, this)); 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)); @@ -200,10 +198,15 @@ BOOL LLPanelMainInventory::postBuild() // *TODO:Get the cost info from the server const std::string upload_cost("10"); - mMenuAdd->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost); - mMenuAdd->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost); - mMenuAdd->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost); - mMenuAdd->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost); + + LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); + if (menu) + { + menu->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost); + menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost); + menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost); + menu->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost); + } // Trigger callback for focus received so we can deselect items in inbox/outbox LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this)); @@ -983,7 +986,8 @@ void LLPanelMainInventory::initListCommandsHandlers() mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2)); mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGearMenuButton->setMenu(mMenuGearDefault); - mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mMenuAddHandle = menu->getHandle(); // Update the trash button when selected item(s) get worn or taken off. LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this)); @@ -1001,11 +1005,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. bool recent_active = ("Recent Items" == mActivePanel->getName()); - mMenuAdd->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active); + LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); + if (menu) + { + menu->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active); - setUploadCostIfNeeded(); + setUploadCostIfNeeded(); - showActionMenu(mMenuAdd,"add_btn"); + showActionMenu(menu,"add_btn"); + } } void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name) @@ -1156,7 +1164,11 @@ void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility ) { if(!new_visibility) { - mMenuAdd->setVisible(FALSE); + LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); + if (menu) + { + menu->setVisible(FALSE); + } getActivePanel()->getRootFolder()->finishRenamingItem(); } } @@ -1180,6 +1192,20 @@ bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata) 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(); @@ -1237,6 +1263,18 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) 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; + } + 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; + } return TRUE; } @@ -1289,12 +1327,13 @@ void LLPanelMainInventory::setUploadCostIfNeeded() // have two instances of Inventory panel at the moment(and two instances of context menu), // call to gMenuHolder->childSetLabelArg() sets upload cost only for one of the instances. - if(mNeedUploadCost && mMenuAdd) + LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get(); + if(mNeedUploadCost && menu) { - LLMenuItemBranchGL* upload_menu = mMenuAdd->findChild<LLMenuItemBranchGL>("upload"); + LLMenuItemBranchGL* upload_menu = menu->findChild<LLMenuItemBranchGL>("upload"); if(upload_menu) { - S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); std::string cost_str; // getPriceUpload() returns -1 if no data available yet. diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index 290e2e5f477d4d47757b0129c689084d085e30c6..38936804acf0f0e1cb9a8cf288afb21704cd7ed6 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -86,6 +86,8 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver void setFocusFilterEditor(); + static void newWindow(); + protected: // // Misc functions @@ -110,7 +112,6 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver // menu callbacks void doToSelected(const LLSD& userdata); void closeAllFolders(); - void newWindow(); void doCreate(const LLSD& userdata); void resetFilters(); void setSortBy(const LLSD& userdata); @@ -156,8 +157,8 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver private: LLDragAndDropButton* mTrashButton; LLToggleableMenu* mMenuGearDefault; - LLMenuGL* mMenuAdd; LLMenuButton* mGearMenuButton; + LLHandle<LLView> mMenuAddHandle; bool mNeedUploadCost; // List Commands // diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 8331c152e206a34fc2f3f3c9b006e1e53963f91b..208ee77f2d69899b4f3af2e800dd9e37725fc362 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -51,7 +51,6 @@ #include "llbutton.h" #include "llcombobox.h" #include "llfiltereditor.h" -#include "llfloaterinventory.h" #include "llinventorybridge.h" #include "llinventorymodel.h" #include "llinventorymodelbackgroundfetch.h" @@ -779,6 +778,10 @@ void LLPanelOutfitEdit::onVisibilityChanged(const LLSD &in_visible_chain) { update(); } + else + { + mWearableListManager->holdProgress(); //list population restarts with visibility + } } void LLPanelOutfitEdit::onAddWearableClicked(void) @@ -1059,9 +1062,6 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void) case LLAssetType::AT_BODYPART: applyListViewFilter(LVIT_BODYPART); break; - case LLAssetType::AT_GESTURE: - applyListViewFilter(LVIT_GESTURES); - break; case LLAssetType::AT_CLOTHING: default: applyListViewFilter(LVIT_CLOTHING); diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 841bb4337a8f78b91b10ae9614425c237505835d..30870daf406297f220ab4e335fd9acf8e5feb9ac 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -80,7 +80,6 @@ class LLPanelOutfitEdit : public LLPanel { LVIT_ALL = 0, LVIT_CLOTHING, - LVIT_GESTURES, LVIT_BODYPART, LVIT_ATTACHMENT, LVIT_SHAPE, diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 1e1f59055f3b5c5404a4a214787fab27073c104a..007ab4dd63286128683f0fe329d0de6c54334ad4 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -37,13 +37,16 @@ #include "llagentwearables.h" #include "llappearancemgr.h" #include "lloutfitobserver.h" +#include "lloutfitgallery.h" #include "lloutfitslist.h" #include "llpanelwearing.h" #include "llsaveoutfitcombobtn.h" #include "llsidepanelappearance.h" +#include "llviewercontrol.h" #include "llviewerfoldertype.h" static const std::string OUTFITS_TAB_NAME = "outfitslist_tab"; +static const std::string OUTFIT_GALLERY_TAB_NAME = "outfit_gallery_tab"; static const std::string COF_TAB_NAME = "cof_tab"; static LLPanelInjector<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory"); @@ -65,6 +68,10 @@ LLPanelOutfitsInventory::LLPanelOutfitsInventory() : LLPanelOutfitsInventory::~LLPanelOutfitsInventory() { + if (mAppearanceTabs) + { + gSavedSettings.setS32("LastAppearanceTab", mAppearanceTabs->getCurrentPanelIndex()); + } } // virtual @@ -100,6 +107,10 @@ void LLPanelOutfitsInventory::onOpen(const LLSD& key) panel_appearance->fetchInventory(); panel_appearance->refreshCurrentOutfitName(); } + + if (!mAppearanceTabs->selectTab(gSavedSettings.getS32("LastAppearanceTab"))) + mAppearanceTabs->selectFirstTab(); + mInitialized = true; } @@ -165,14 +176,22 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string) void LLPanelOutfitsInventory::onWearButtonClick() { - if (mMyOutfitsPanel->hasItemSelected()) + if(isOutfitsListPanelActive()) { - mMyOutfitsPanel->wearSelectedItems(); + if (mMyOutfitsPanel->hasItemSelected()) + { + mMyOutfitsPanel->wearSelectedItems(); + } + else + { + mMyOutfitsPanel->performAction("replaceoutfit"); + } } - else + else if(isOutfitsGalleryPanelActive()) { - mMyOutfitsPanel->performAction("replaceoutfit"); + mOutfitGalleryPanel->wearSelectedOutfit(); } + } bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD& response) @@ -234,6 +253,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers() mListCommands = getChild<LLPanel>("bottom_panel"); mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this)); mMyOutfitsPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this)); + mOutfitGalleryPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this)); } void LLPanelOutfitsInventory::updateListCommands() @@ -245,15 +265,23 @@ void LLPanelOutfitsInventory::updateListCommands() LLButton* wear_btn = mListCommands->getChild<LLButton>("wear_btn"); mMyOutfitsPanel->childSetEnabled("trash_btn", trash_enabled); + mOutfitGalleryPanel->childSetEnabled("trash_btn", trash_enabled); wear_btn->setEnabled(wear_enabled); wear_btn->setVisible(wear_visible); mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled); - wear_btn->setToolTip(getString(mMyOutfitsPanel->hasItemSelected() ? "wear_items_tooltip" : "wear_outfit_tooltip")); + wear_btn->setToolTip(getString((!isOutfitsGalleryPanelActive() && mMyOutfitsPanel->hasItemSelected()) ? "wear_items_tooltip" : "wear_outfit_tooltip")); } void LLPanelOutfitsInventory::onTrashButtonClick() { - mMyOutfitsPanel->removeSelected(); + if(isOutfitsListPanelActive()) + { + mMyOutfitsPanel->removeSelected(); + } + else if(isOutfitsGalleryPanelActive()) + { + mOutfitGalleryPanel->removeSelected(); + } } bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata) @@ -268,12 +296,16 @@ bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata) void LLPanelOutfitsInventory::initTabPanels() { + //TODO: Add LLOutfitGallery change callback mCurrentOutfitPanel = findChild<LLPanelWearing>(COF_TAB_NAME); mCurrentOutfitPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this)); mMyOutfitsPanel = findChild<LLOutfitsList>(OUTFITS_TAB_NAME); mMyOutfitsPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this)); + mOutfitGalleryPanel = findChild<LLOutfitGallery>(OUTFIT_GALLERY_TAB_NAME); + mOutfitGalleryPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this)); + mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs"); mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this)); } @@ -296,6 +328,22 @@ bool LLPanelOutfitsInventory::isCOFPanelActive() const return mActivePanel->getName() == COF_TAB_NAME; } +bool LLPanelOutfitsInventory::isOutfitsListPanelActive() const +{ + if (!mActivePanel) return false; + + return mActivePanel->getName() == OUTFITS_TAB_NAME; +} + +bool LLPanelOutfitsInventory::isOutfitsGalleryPanelActive() const +{ + if (!mActivePanel) return false; + + return mActivePanel->getName() == OUTFIT_GALLERY_TAB_NAME; +} + + + void LLPanelOutfitsInventory::setWearablesLoading(bool val) { updateVerbs(); diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index a7917b457c95934671c3aeadd407fe9821f82d86..6a0ea04fa6a050d14e95bb9a573c1f674eb5c2d7 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -30,8 +30,9 @@ #include "llpanel.h" +class LLOutfitGallery; class LLOutfitsList; -class LLOutfitListGearMenu; +class LLOutfitListGearMenuBase; class LLPanelAppearanceTab; class LLPanelWearing; class LLMenuGL; @@ -72,10 +73,13 @@ class LLPanelOutfitsInventory : public LLPanel void initTabPanels(); void onTabChange(); bool isCOFPanelActive() const; + bool isOutfitsListPanelActive() const; + bool isOutfitsGalleryPanelActive() const; private: LLPanelAppearanceTab* mActivePanel; LLOutfitsList* mMyOutfitsPanel; + LLOutfitGallery* mOutfitGalleryPanel; LLPanelWearing* mCurrentOutfitPanel; // tab panels // diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 6e677bbce55228b0df138be22c258e5aeca0496c..203c57b732257c704ad302506a9ab2ebe64da6db 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -63,6 +63,7 @@ #include "roles_constants.h" #include "llgroupactions.h" #include "lltrans.h" +#include "llinventorymodel.h" U8 string_value_to_click_action(std::string p_value); @@ -1016,13 +1017,26 @@ void LLPanelPermissions::onCommitNextOwnerTransfer(LLUICtrl* ctrl, void* data) // static void LLPanelPermissions::onCommitName(LLUICtrl*, void* data) { - //LL_INFOS() << "LLPanelPermissions::onCommitName()" << LL_ENDL; LLPanelPermissions* self = (LLPanelPermissions*)data; LLLineEditor* tb = self->getChild<LLLineEditor>("Object Name"); - if(tb) + if (!tb) { - LLSelectMgr::getInstance()->selectionSetObjectName(tb->getText()); -// LLSelectMgr::getInstance()->selectionSetObjectName(self->mLabelObjectName->getText()); + return; + } + LLSelectMgr::getInstance()->selectionSetObjectName(tb->getText()); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + if (selection->isAttachment() && (selection->getNumNodes() == 1) && !tb->getText().empty()) + { + LLUUID object_id = selection->getFirstObject()->getAttachmentItemID(); + LLViewerInventoryItem* item = findItem(object_id); + if (item) + { + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); + new_item->rename(tb->getText()); + new_item->updateServer(FALSE); + gInventory.updateItem(new_item); + gInventory.notifyObservers(); + } } } @@ -1030,12 +1044,26 @@ void LLPanelPermissions::onCommitName(LLUICtrl*, void* data) // static void LLPanelPermissions::onCommitDesc(LLUICtrl*, void* data) { - //LL_INFOS() << "LLPanelPermissions::onCommitDesc()" << LL_ENDL; LLPanelPermissions* self = (LLPanelPermissions*)data; LLLineEditor* le = self->getChild<LLLineEditor>("Object Description"); - if(le) + if (!le) { - LLSelectMgr::getInstance()->selectionSetObjectDescription(le->getText()); + return; + } + LLSelectMgr::getInstance()->selectionSetObjectDescription(le->getText()); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + if (selection->isAttachment() && (selection->getNumNodes() == 1)) + { + LLUUID object_id = selection->getFirstObject()->getAttachmentItemID(); + LLViewerInventoryItem* item = findItem(object_id); + if (item) + { + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); + new_item->setDescription(le->getText()); + new_item->updateServer(FALSE); + gInventory.updateItem(new_item); + gInventory.notifyObservers(); + } } } @@ -1159,3 +1187,12 @@ void LLPanelPermissions::onCommitIncludeInSearch(LLUICtrl* ctrl, void*) LLSelectMgr::getInstance()->selectionSetIncludeInSearch(box->get()); } + +LLViewerInventoryItem* LLPanelPermissions::findItem(LLUUID &object_id) +{ + if (!object_id.isNull()) + { + return gInventory.getItem(object_id); + } + return NULL; +} diff --git a/indra/newview/llpanelpermissions.h b/indra/newview/llpanelpermissions.h index 87805bbf906509c6345e073e3f3d905eed34b872..2d15954baa97ada2a1d8b382e6da561a773f829a 100644 --- a/indra/newview/llpanelpermissions.h +++ b/indra/newview/llpanelpermissions.h @@ -37,6 +37,7 @@ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLNameBox; +class LLViewerInventoryItem; class LLPanelPermissions : public LLPanel { @@ -77,6 +78,8 @@ class LLPanelPermissions : public LLPanel static void onCommitClickAction(LLUICtrl* ctrl, void*); static void onCommitIncludeInSearch(LLUICtrl* ctrl, void*); + static LLViewerInventoryItem* findItem(LLUUID &object_id); + protected: void disableAll(); diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 2fa4ee376a235a33824f14865476d3412f7f6beb..610b3a6396068610a98a1d81737dd3249dbcd7bd 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -502,10 +502,6 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, if(!parcel->getGroupID().isNull()) { - // FIXME: Using parcel group as region group. - gCacheName->getGroup(parcel->getGroupID(), - boost::bind(&LLPanelPlaceInfo::onNameCache, mRegionGroupText, _2)); - std::string owner = LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString(); mParcelOwner->setText(owner); @@ -524,12 +520,20 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString(); mParcelOwner->setText(parcel_owner); LLAvatarNameCache::get(region->getOwner(), boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mRegionOwnerText)); + mRegionGroupText->setText( getString("none_text")); } if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus()) { mRegionOwnerText->setText(mRegionOwnerText->getText() + getString("sale_pending_text")); } + + if(!parcel->getGroupID().isNull()) + { + // FIXME: Using parcel group as region group. + gCacheName->getGroup(parcel->getGroupID(), + boost::bind(&LLPanelPlaceInfo::onNameCache, mRegionGroupText, _2)); + } } mEstateRatingText->setText(region->getSimAccessString()); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index a9a0c30e2678bdd7504a36f39a071c22a0a2cdce..5d43c386123403af07e9dc9bb8dea09708c96709 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -711,6 +711,34 @@ void LLPanelPlaces::onEditButtonClicked() updateVerbs(); } +class LLUpdateLandmarkParent : public LLInventoryCallback +{ +public: + LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) : + mItem(item), + mNewParentId(new_parent) + {}; + /* virtual */ void fire(const LLUUID& inv_item_id) + { + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1); + update.push_back(new_folder); + gInventory.accountForUpdate(update); + + mItem->setParent(mNewParentId); + mItem->updateParentOnServer(FALSE); + + gInventory.updateItem(mItem); + gInventory.notifyObservers(); + } + +private: + LLPointer<LLViewerInventoryItem> mItem; + LLUUID mNewParentId; +}; + void LLPanelPlaces::onSaveButtonClicked() { if (!mLandmarkInfo || mItem.isNull()) @@ -726,6 +754,7 @@ void LLPanelPlaces::onSaveButtonClicked() LLUUID item_id = mItem->getUUID(); LLUUID folder_id = mLandmarkInfo->getLandmarkFolder(); + bool change_parent = folder_id != mItem->getParentUUID(); LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem); @@ -734,10 +763,16 @@ void LLPanelPlaces::onSaveButtonClicked() { new_item->rename(current_title_value); new_item->setDescription(current_notes_value); - new_item->updateServer(FALSE); + LLPointer<LLInventoryCallback> cb; + if (change_parent) + { + cb = new LLUpdateLandmarkParent(new_item, folder_id); + } + LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0); + gInventory.accountForUpdate(up); + update_inventory_item(new_item, cb); } - - if(folder_id != mItem->getParentUUID()) + else if (change_parent) { LLInventoryModel::update_list_t update; LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(),-1); diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 763657ebad51fa7651c2bdf1b52328178520269e..0bcd8a9e63cfa21b1bd797ea46ef869d4430d40a 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -95,7 +95,8 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() : mVolumeSliderVisible(0), mWindowShade(NULL), mHideImmediately(false), - mSecureURL(false) + mSecureURL(false), + mMediaPlaySliderCtrlMouseDownValue(0.0) { mCommitCallbackRegistrar.add("MediaCtrl.Close", boost::bind(&LLPanelPrimMediaControls::onClickClose, this)); mCommitCallbackRegistrar.add("MediaCtrl.Back", boost::bind(&LLPanelPrimMediaControls::onClickBack, this)); @@ -109,7 +110,8 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() : mCommitCallbackRegistrar.add("MediaCtrl.Open", boost::bind(&LLPanelPrimMediaControls::onClickOpen, this)); mCommitCallbackRegistrar.add("MediaCtrl.Zoom", boost::bind(&LLPanelPrimMediaControls::onClickZoom, this)); mCommitCallbackRegistrar.add("MediaCtrl.CommitURL", boost::bind(&LLPanelPrimMediaControls::onCommitURL, this)); - mCommitCallbackRegistrar.add("MediaCtrl.JumpProgress", boost::bind(&LLPanelPrimMediaControls::onCommitSlider, this)); + mCommitCallbackRegistrar.add("MediaCtrl.MouseDown", boost::bind(&LLPanelPrimMediaControls::onMediaPlaySliderCtrlMouseDown, this)); + mCommitCallbackRegistrar.add("MediaCtrl.MouseUp", boost::bind(&LLPanelPrimMediaControls::onMediaPlaySliderCtrlMouseUp, this)); mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeUp", boost::bind(&LLPanelPrimMediaControls::onCommitVolumeUp, this)); mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeDown", boost::bind(&LLPanelPrimMediaControls::onCommitVolumeDown, this)); mCommitCallbackRegistrar.add("MediaCtrl.Volume", boost::bind(&LLPanelPrimMediaControls::onCommitVolumeSlider, this)); @@ -1246,26 +1248,38 @@ void LLPanelPrimMediaControls::setCurrentURL() #endif // USE_COMBO_BOX_FOR_MEDIA_URL } -void LLPanelPrimMediaControls::onCommitSlider() + +void LLPanelPrimMediaControls::onMediaPlaySliderCtrlMouseDown() { - focusOnTarget(); + mMediaPlaySliderCtrlMouseDownValue = mMediaPlaySliderCtrl->getValue().asReal(); - LLViewerMediaImpl* media_impl = getTargetMediaImpl(); - if (media_impl) + mUpdateSlider = false; +} + +void LLPanelPrimMediaControls::onMediaPlaySliderCtrlMouseUp() +{ + F64 cur_value = mMediaPlaySliderCtrl->getValue().asReal(); + + if (mMediaPlaySliderCtrlMouseDownValue != cur_value) { - // get slider value - F64 slider_value = mMediaPlaySliderCtrl->getValue().asReal(); - if(slider_value <= 0.0) - { - media_impl->stop(); - } - else + focusOnTarget(); + + LLViewerMediaImpl* media_impl = getTargetMediaImpl(); + if (media_impl) { - media_impl->seek(slider_value*mMovieDuration); - //mUpdateSlider= false; + if (cur_value <= 0.0) + { + media_impl->stop(); + } + else + { + media_impl->seek(cur_value * mMovieDuration); + } } + + mUpdateSlider = true; } -} +} void LLPanelPrimMediaControls::onCommitVolumeUp() { diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index 6d2eb3430e456290445fbaa5c816cab2c951e47f..21d52360744d7e53c0f4847bccb14efb3029a5b7 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -107,8 +107,10 @@ class LLPanelPrimMediaControls : public LLPanel void updateZoom(); void setCurrentURL(); - void onCommitSlider(); - + + void onMediaPlaySliderCtrlMouseDown(); + void onMediaPlaySliderCtrlMouseUp(); + void onCommitVolumeUp(); void onCommitVolumeDown(); void onCommitVolumeSlider(); @@ -219,6 +221,8 @@ class LLPanelPrimMediaControls : public LLPanel S32 mVolumeSliderVisible; LLNotificationPtr mActiveNotification; + + F64 mMediaPlaySliderCtrlMouseDownValue; }; #endif // LL_PANELPRIMMEDIACONTROLS_H diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 184238c40ca1373b0e5b412ee0e4ba2fde30bef0..8afa35efa0b4066ab1e10b58d8af234cf792106f 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -44,19 +44,11 @@ static const std::string PANEL_PICKS = "panel_picks"; std::string getProfileURL(const std::string& agent_name) { - std::string url; - - if (LLGridManager::getInstance()->isInProductionGrid()) - { - url = gSavedSettings.getString("WebProfileURL"); - } - else - { - url = gSavedSettings.getString("WebProfileNonProductionURL"); - } + std::string url = "[WEB_PROFILE_URL][AGENT_NAME]"; LLSD subs; + subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL(); subs["AGENT_NAME"] = agent_name; - url = LLWeb::expandURLSubstitutions(url,subs); + url = LLWeb::expandURLSubstitutions(url, subs); LLStringUtil::toLower(url); return url; } diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp index 106fb4997ef1e4761b8ae1b22fbc913b8b754438..a17e3f9e78abe86b45e92f03dd0929c6a9f77ed4 100644 --- a/indra/newview/llpanelsnapshot.cpp +++ b/indra/newview/llpanelsnapshot.cpp @@ -29,6 +29,8 @@ // libs #include "llcombobox.h" +#include "llfloater.h" +#include "llfloatersnapshot.h" #include "llsliderctrl.h" #include "llspinctrl.h" #include "lltrans.h" @@ -50,15 +52,29 @@ S32 power_of_two(S32 sz, S32 upper) return res; } +LLPanelSnapshot::LLPanelSnapshot() + : mSnapshotFloater(NULL) +{} + // virtual BOOL LLPanelSnapshot::postBuild() { getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onResolutionComboCommit, this, _1)); - getChild<LLUICtrl>(getWidthSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this)); - getChild<LLUICtrl>(getHeightSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this)); - getChild<LLUICtrl>(getAspectRatioCBName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onKeepAspectRatioCommit, this, _1)); - + if (!getWidthSpinnerName().empty()) + { + getChild<LLUICtrl>(getWidthSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this)); + } + if (!getHeightSpinnerName().empty()) + { + getChild<LLUICtrl>(getHeightSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this)); + } + if (!getAspectRatioCBName().empty()) + { + getChild<LLUICtrl>(getAspectRatioCBName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onKeepAspectRatioCommit, this, _1)); + } updateControls(LLSD()); + + mSnapshotFloater = getParentByType<LLFloaterSnapshotBase>(); return TRUE; } @@ -76,13 +92,13 @@ void LLPanelSnapshot::onOpen(const LLSD& key) // e.g. attempt to send a large BMP image by email. if (old_format != new_format) { - LLFloaterSnapshot::getInstance()->notify(LLSD().with("image-format-change", true)); + getParentByType<LLFloater>()->notify(LLSD().with("image-format-change", true)); } } -LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshot::getImageFormat() const +LLSnapshotModel::ESnapshotFormat LLPanelSnapshot::getImageFormat() const { - return LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG; + return LLSnapshotModel::SNAPSHOT_FORMAT_JPEG; } void LLPanelSnapshot::enableControls(BOOL enable) @@ -92,27 +108,32 @@ void LLPanelSnapshot::enableControls(BOOL enable) LLSpinCtrl* LLPanelSnapshot::getWidthSpinner() { + llassert(!getWidthSpinnerName().empty()); return getChild<LLSpinCtrl>(getWidthSpinnerName()); } LLSpinCtrl* LLPanelSnapshot::getHeightSpinner() { + llassert(!getHeightSpinnerName().empty()); return getChild<LLSpinCtrl>(getHeightSpinnerName()); } S32 LLPanelSnapshot::getTypedPreviewWidth() const { + llassert(!getWidthSpinnerName().empty()); return getChild<LLUICtrl>(getWidthSpinnerName())->getValue().asInteger(); } S32 LLPanelSnapshot::getTypedPreviewHeight() const { - return getChild<LLUICtrl>(getHeightSpinnerName())->getValue().asInteger(); + llassert(!getHeightSpinnerName().empty()); + return getChild<LLUICtrl>(getHeightSpinnerName())->getValue().asInteger(); } void LLPanelSnapshot::enableAspectRatioCheckbox(BOOL enable) { - getChild<LLUICtrl>(getAspectRatioCBName())->setEnabled(enable); + llassert(!getAspectRatioCBName().empty()); + getChild<LLUICtrl>(getAspectRatioCBName())->setEnabled(enable); } LLSideTrayPanelContainer* LLPanelSnapshot::getParentContainer() @@ -171,14 +192,17 @@ void LLPanelSnapshot::goBack() void LLPanelSnapshot::cancel() { goBack(); - LLFloaterSnapshot::getInstance()->notify(LLSD().with("set-ready", true)); + getParentByType<LLFloater>()->notify(LLSD().with("set-ready", true)); } void LLPanelSnapshot::onCustomResolutionCommit() { LLSD info; - LLSpinCtrl *widthSpinner = getChild<LLSpinCtrl>(getWidthSpinnerName()); - LLSpinCtrl *heightSpinner = getChild<LLSpinCtrl>(getHeightSpinnerName()); + std::string widthSpinnerName = getWidthSpinnerName(); + std::string heightSpinnerName = getHeightSpinnerName(); + llassert(!widthSpinnerName.empty() && !heightSpinnerName.empty()); + LLSpinCtrl *widthSpinner = getChild<LLSpinCtrl>(widthSpinnerName); + LLSpinCtrl *heightSpinner = getChild<LLSpinCtrl>(heightSpinnerName); if (getName() == "panel_snapshot_inventory") { S32 width = widthSpinner->getValue().asInteger(); @@ -197,17 +221,22 @@ void LLPanelSnapshot::onCustomResolutionCommit() info["w"] = widthSpinner->getValue().asInteger(); info["h"] = heightSpinner->getValue().asInteger(); } - LLFloaterSnapshot::getInstance()->notify(LLSD().with("custom-res-change", info)); + getParentByType<LLFloater>()->notify(LLSD().with("custom-res-change", info)); } void LLPanelSnapshot::onResolutionComboCommit(LLUICtrl* ctrl) { LLSD info; info["combo-res-change"]["control-name"] = ctrl->getName(); - LLFloaterSnapshot::getInstance()->notify(info); + getParentByType<LLFloater>()->notify(info); } void LLPanelSnapshot::onKeepAspectRatioCommit(LLUICtrl* ctrl) { - LLFloaterSnapshot::getInstance()->notify(LLSD().with("keep-aspect-change", ctrl->getValue().asBoolean())); + getParentByType<LLFloater>()->notify(LLSD().with("keep-aspect-change", ctrl->getValue().asBoolean())); +} + +LLSnapshotModel::ESnapshotType LLPanelSnapshot::getSnapshotType() +{ + return LLSnapshotModel::SNAPSHOT_WEB; } diff --git a/indra/newview/llpanelsnapshot.h b/indra/newview/llpanelsnapshot.h index 42ad798d60fdbe6f1a91c07c1a9a4d79a92651a6..55273797cc04e5a4948caf50a69b8fadb53892b0 100644 --- a/indra/newview/llpanelsnapshot.h +++ b/indra/newview/llpanelsnapshot.h @@ -27,9 +27,13 @@ #ifndef LL_LLPANELSNAPSHOT_H #define LL_LLPANELSNAPSHOT_H -#include "llfloatersnapshot.h" +//#include "llfloatersnapshot.h" +#include "llpanel.h" +#include "llsnapshotmodel.h" +class LLSpinCtrl; class LLSideTrayPanelContainer; +class LLFloaterSnapshotBase; /** * Snapshot panel base class. @@ -37,6 +41,8 @@ class LLSideTrayPanelContainer; class LLPanelSnapshot: public LLPanel { public: + LLPanelSnapshot(); + /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); @@ -51,7 +57,8 @@ class LLPanelSnapshot: public LLPanel virtual LLSpinCtrl* getWidthSpinner(); virtual LLSpinCtrl* getHeightSpinner(); virtual void enableAspectRatioCheckbox(BOOL enable); - virtual LLFloaterSnapshot::ESnapshotFormat getImageFormat() const; + virtual LLSnapshotModel::ESnapshotFormat getImageFormat() const; + virtual LLSnapshotModel::ESnapshotType getSnapshotType(); virtual void updateControls(const LLSD& info) = 0; ///< Update controls from saved settings void enableControls(BOOL enable); @@ -59,12 +66,14 @@ class LLPanelSnapshot: public LLPanel LLSideTrayPanelContainer* getParentContainer(); void updateImageQualityLevel(); void goBack(); ///< Switch to the default (Snapshot Options) panel - void cancel(); + virtual void cancel(); // common UI callbacks void onCustomResolutionCommit(); void onResolutionComboCommit(LLUICtrl* ctrl); void onKeepAspectRatioCommit(LLUICtrl* ctrl); + + LLFloaterSnapshotBase* mSnapshotFloater; }; #endif // LL_LLPANELSNAPSHOT_H diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp index a2d1752c6a88307448892746d350fe6950e619cd..21ac7604ff52cb7ce516a8c2f9cdb2a18ce36aac 100644 --- a/indra/newview/llpanelsnapshotinventory.cpp +++ b/indra/newview/llpanelsnapshotinventory.cpp @@ -33,6 +33,7 @@ #include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model #include "llpanelsnapshot.h" +#include "llsnapshotlivepreview.h" #include "llviewercontrol.h" // gSavedSettings #include "llstatusbar.h" // can_afford_transaction() #include "llnotificationsutil.h" @@ -40,8 +41,22 @@ /** * The panel provides UI for saving snapshot as an inventory texture. */ +class LLPanelSnapshotInventoryBase + : public LLPanelSnapshot +{ + LOG_CLASS(LLPanelSnapshotInventoryBase); + +public: + LLPanelSnapshotInventoryBase(); + + /*virtual*/ BOOL postBuild(); +protected: + void onSend(); + /*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType(); +}; + class LLPanelSnapshotInventory -: public LLPanelSnapshot + : public LLPanelSnapshotInventoryBase { LOG_CLASS(LLPanelSnapshotInventory); @@ -60,10 +75,46 @@ class LLPanelSnapshotInventory /*virtual*/ std::string getImageSizePanelName() const { return LLStringUtil::null; } /*virtual*/ void updateControls(const LLSD& info); - void onSend(); }; -static LLPanelInjector<LLPanelSnapshotInventory> panel_class("llpanelsnapshotinventory"); +class LLPanelOutfitSnapshotInventory + : public LLPanelSnapshotInventoryBase +{ + LOG_CLASS(LLPanelOutfitSnapshotInventory); + +public: + LLPanelOutfitSnapshotInventory(); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + +private: + /*virtual*/ std::string getWidthSpinnerName() const { return ""; } + /*virtual*/ std::string getHeightSpinnerName() const { return ""; } + /*virtual*/ std::string getAspectRatioCBName() const { return ""; } + /*virtual*/ std::string getImageSizeComboName() const { return "texture_size_combo"; } + /*virtual*/ std::string getImageSizePanelName() const { return LLStringUtil::null; } + /*virtual*/ void updateControls(const LLSD& info); + + /*virtual*/ void cancel(); +}; + +static LLPanelInjector<LLPanelSnapshotInventory> panel_class1("llpanelsnapshotinventory"); + +static LLPanelInjector<LLPanelOutfitSnapshotInventory> panel_class2("llpaneloutfitsnapshotinventory"); + +LLPanelSnapshotInventoryBase::LLPanelSnapshotInventoryBase() +{ +} + +BOOL LLPanelSnapshotInventoryBase::postBuild() +{ + return LLPanelSnapshot::postBuild(); +} + +LLSnapshotModel::ESnapshotType LLPanelSnapshotInventoryBase::getSnapshotType() +{ + return LLSnapshotModel::SNAPSHOT_TEXTURE; +} LLPanelSnapshotInventory::LLPanelSnapshotInventory() { @@ -78,13 +129,13 @@ BOOL LLPanelSnapshotInventory::postBuild() getChild<LLSpinCtrl>(getHeightSpinnerName())->setAllowEdit(FALSE); getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshotInventory::onResolutionCommit, this, _1)); - return LLPanelSnapshot::postBuild(); + return LLPanelSnapshotInventoryBase::postBuild(); } // virtual void LLPanelSnapshotInventory::onOpen(const LLSD& key) { - getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload())); + getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload())); LLPanelSnapshot::onOpen(key); } @@ -102,19 +153,59 @@ void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl) getChild<LLSpinCtrl>(getHeightSpinnerName())->setVisible(!current_window_selected); } -void LLPanelSnapshotInventory::onSend() +void LLPanelSnapshotInventoryBase::onSend() { - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); if (can_afford_transaction(expected_upload_cost)) { - LLFloaterSnapshot::saveTexture(); - LLFloaterSnapshot::postSave(); + if (mSnapshotFloater) + { + mSnapshotFloater->saveTexture(); + mSnapshotFloater->postSave(); + } } else { LLSD args; args["COST"] = llformat("%d", expected_upload_cost); LLNotificationsUtil::add("ErrorPhotoCannotAfford", args); - LLFloaterSnapshot::inventorySaveFailed(); + if (mSnapshotFloater) + { + mSnapshotFloater->inventorySaveFailed(); + } + } +} + +LLPanelOutfitSnapshotInventory::LLPanelOutfitSnapshotInventory() +{ + mCommitCallbackRegistrar.add("Inventory.SaveOutfitPhoto", boost::bind(&LLPanelOutfitSnapshotInventory::onSend, this)); + mCommitCallbackRegistrar.add("Inventory.SaveOutfitCancel", boost::bind(&LLPanelOutfitSnapshotInventory::cancel, this)); +} + +// virtual +BOOL LLPanelOutfitSnapshotInventory::postBuild() +{ + return LLPanelSnapshotInventoryBase::postBuild(); +} + +// virtual +void LLPanelOutfitSnapshotInventory::onOpen(const LLSD& key) +{ + getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload())); + LLPanelSnapshot::onOpen(key); +} + +// virtual +void LLPanelOutfitSnapshotInventory::updateControls(const LLSD& info) +{ + const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true; + getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot); +} + +void LLPanelOutfitSnapshotInventory::cancel() +{ + if (mSnapshotFloater) + { + mSnapshotFloater->closeFloater(); } } diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp index 01dfdc4ecedb3ec66dca656c5e1e20519cfbd06c..3652c10586d51cf18eea686fc53625b4bd185030 100644 --- a/indra/newview/llpanelsnapshotlocal.cpp +++ b/indra/newview/llpanelsnapshotlocal.cpp @@ -33,6 +33,7 @@ #include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model #include "llpanelsnapshot.h" +#include "llsnapshotlivepreview.h" #include "llviewercontrol.h" // gSavedSettings #include "llviewerwindow.h" @@ -55,7 +56,8 @@ class LLPanelSnapshotLocal /*virtual*/ std::string getAspectRatioCBName() const { return "local_keep_aspect_check"; } /*virtual*/ std::string getImageSizeComboName() const { return "local_size_combo"; } /*virtual*/ std::string getImageSizePanelName() const { return "local_image_size_lp"; } - /*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const; + /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const; + /*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType(); /*virtual*/ void updateControls(const LLSD& info); S32 mLocalFormat; @@ -94,23 +96,23 @@ void LLPanelSnapshotLocal::onOpen(const LLSD& key) } // virtual -LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const +LLSnapshotModel::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const { - LLFloaterSnapshot::ESnapshotFormat fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; + LLSnapshotModel::ESnapshotFormat fmt = LLSnapshotModel::SNAPSHOT_FORMAT_PNG; LLComboBox* local_format_combo = getChild<LLComboBox>("local_format_combo"); const std::string id = local_format_combo->getValue().asString(); if (id == "PNG") { - fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; + fmt = LLSnapshotModel::SNAPSHOT_FORMAT_PNG; } else if (id == "JPEG") { - fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG; + fmt = LLSnapshotModel::SNAPSHOT_FORMAT_JPEG; } else if (id == "BMP") { - fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP; + fmt = LLSnapshotModel::SNAPSHOT_FORMAT_BMP; } return fmt; @@ -119,11 +121,11 @@ LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const // virtual void LLPanelSnapshotLocal::updateControls(const LLSD& info) { - LLFloaterSnapshot::ESnapshotFormat fmt = - (LLFloaterSnapshot::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat"); + LLSnapshotModel::ESnapshotFormat fmt = + (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat"); getChild<LLComboBox>("local_format_combo")->selectNthItem((S32) fmt); - const bool show_quality_ctrls = (fmt == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG); + const bool show_quality_ctrls = (fmt == LLSnapshotModel::SNAPSHOT_FORMAT_JPEG); getChild<LLUICtrl>("image_quality_slider")->setVisible(show_quality_ctrls); getChild<LLUICtrl>("image_quality_level")->setVisible(show_quality_ctrls); @@ -162,10 +164,10 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl) LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance(); floater->notify(LLSD().with("set-working", true)); - BOOL saved = LLFloaterSnapshot::saveLocal(); + BOOL saved = floater->saveLocal(); if (saved) { - LLFloaterSnapshot::postSave(); + mSnapshotFloater->postSave(); goBack(); floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local"))); } @@ -174,3 +176,8 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl) cancel(); } } + +LLSnapshotModel::ESnapshotType LLPanelSnapshotLocal::getSnapshotType() +{ + return LLSnapshotModel::SNAPSHOT_LOCAL; +} diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp index 0fc9ceec8318fc59c02e99998bb5edef0ece2de2..95c14e4226c9eef40b6093a70fd1895bbca43669 100644 --- a/indra/newview/llpanelsnapshotoptions.cpp +++ b/indra/newview/llpanelsnapshotoptions.cpp @@ -62,6 +62,8 @@ class LLPanelSnapshotOptions void onSendToFacebook(); void onSendToTwitter(); void onSendToFlickr(); + + LLFloaterSnapshotBase* mSnapshotFloater; }; static LLPanelInjector<LLPanelSnapshotOptions> panel_class("llpanelsnapshotoptions"); @@ -75,17 +77,18 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions() mCommitCallbackRegistrar.add("Snapshot.SendToFacebook", boost::bind(&LLPanelSnapshotOptions::onSendToFacebook, this)); mCommitCallbackRegistrar.add("Snapshot.SendToTwitter", boost::bind(&LLPanelSnapshotOptions::onSendToTwitter, this)); mCommitCallbackRegistrar.add("Snapshot.SendToFlickr", boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this)); - LLGlobalEconomy::Singleton::getInstance()->addObserver(this); + LLGlobalEconomy::getInstance()->addObserver(this); } LLPanelSnapshotOptions::~LLPanelSnapshotOptions() { - LLGlobalEconomy::Singleton::getInstance()->removeObserver(this); + LLGlobalEconomy::getInstance()->removeObserver(this); } // virtual BOOL LLPanelSnapshotOptions::postBuild() { + mSnapshotFloater = getParentByType<LLFloaterSnapshotBase>(); return LLPanel::postBuild(); } @@ -97,7 +100,7 @@ void LLPanelSnapshotOptions::onOpen(const LLSD& key) void LLPanelSnapshotOptions::updateUploadCost() { - S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); getChild<LLUICtrl>("save_to_inventory_btn")->setLabelArg("[AMOUNT]", llformat("%d", upload_cost)); } @@ -112,7 +115,7 @@ void LLPanelSnapshotOptions::openPanel(const std::string& panel_name) parent->openPanel(panel_name); parent->getCurrentPanel()->onOpen(LLSD()); - LLFloaterSnapshot::postPanelSwitch(); + mSnapshotFloater->postPanelSwitch(); } void LLPanelSnapshotOptions::onSaveToProfile() diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp index e4f39aac0450cdb5244776964b4dc237432ebda8..be8bde09f8672f5bd0894a15720f3d61b1f3d4b2 100644 --- a/indra/newview/llpanelsnapshotpostcard.cpp +++ b/indra/newview/llpanelsnapshotpostcard.cpp @@ -38,6 +38,7 @@ #include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model #include "llpanelsnapshot.h" #include "llpostcard.h" +#include "llsnapshotlivepreview.h" #include "llviewercontrol.h" // gSavedSettings #include "llviewerwindow.h" #include "llviewerregion.h" @@ -64,12 +65,13 @@ class LLPanelSnapshotPostcard /*virtual*/ std::string getAspectRatioCBName() const { return "postcard_keep_aspect_check"; } /*virtual*/ std::string getImageSizeComboName() const { return "postcard_size_combo"; } /*virtual*/ std::string getImageSizePanelName() const { return "postcard_image_size_lp"; } - /*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG; } + /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const { return LLSnapshotModel::SNAPSHOT_FORMAT_JPEG; } + /*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType(); /*virtual*/ void updateControls(const LLSD& info); bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response); - static void sendPostcardFinished(LLSD result); - void sendPostcard(); + static void sendPostcardFinished(LLSD result); + void sendPostcard(); void onMsgFormFocusRecieved(); void onFormatComboCommit(LLUICtrl* ctrl); @@ -93,13 +95,6 @@ LLPanelSnapshotPostcard::LLPanelSnapshotPostcard() // virtual BOOL LLPanelSnapshotPostcard::postBuild() { - // pick up the user's up-to-date email address - gAgent.sendAgentUserInfoRequest(); - - std::string name_string; - LLAgentUI::buildFullname(name_string); - getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string)); - // For the first time a user focuses to .the msg box, all text will be selected. getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(boost::bind(&LLPanelSnapshotPostcard::onMsgFormFocusRecieved, this)); @@ -113,6 +108,16 @@ BOOL LLPanelSnapshotPostcard::postBuild() // virtual void LLPanelSnapshotPostcard::onOpen(const LLSD& key) { + // pick up the user's up-to-date email address + if (mAgentEmail.empty()) + { + gAgent.sendAgentUserInfoRequest(); + + std::string name_string; + LLAgentUI::buildFullname(name_string); + getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string)); + } + LLPanelSnapshot::onOpen(key); } @@ -190,8 +195,8 @@ void LLPanelSnapshotPostcard::sendPostcard() getChild<LLUICtrl>("to_form")->getValue().asString(), getChild<LLUICtrl>("subject_form")->getValue().asString(), getChild<LLUICtrl>("msg_form")->getValue().asString(), - LLFloaterSnapshot::getPosTakenGlobal(), - LLFloaterSnapshot::getImageData(), + mSnapshotFloater->getPosTakenGlobal(), + mSnapshotFloater->getImageData(), boost::bind(&LLPanelSnapshotPostcard::sendPostcardFinished, _4))); LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); @@ -205,7 +210,7 @@ void LLPanelSnapshotPostcard::sendPostcard() // Give user feedback of the event. gViewerWindow->playSnapshotAnimAndSound(); - LLFloaterSnapshot::postSave(); + mSnapshotFloater->postSave(); } void LLPanelSnapshotPostcard::onMsgFormFocusRecieved() @@ -264,3 +269,8 @@ void LLPanelSnapshotPostcard::onSend() // Send postcard. sendPostcard(); } + +LLSnapshotModel::ESnapshotType LLPanelSnapshotPostcard::getSnapshotType() +{ + return LLSnapshotModel::SNAPSHOT_POSTCARD; +} diff --git a/indra/newview/llpanelsnapshotprofile.cpp b/indra/newview/llpanelsnapshotprofile.cpp index 8949eb73ebafe3cb5c29fdc639b0773090f4a3d5..38dec780300225bad11ea52a1ac104eab08136f0 100644 --- a/indra/newview/llpanelsnapshotprofile.cpp +++ b/indra/newview/llpanelsnapshotprofile.cpp @@ -58,7 +58,7 @@ class LLPanelSnapshotProfile /*virtual*/ std::string getAspectRatioCBName() const { return "profile_keep_aspect_check"; } /*virtual*/ std::string getImageSizeComboName() const { return "profile_size_combo"; } /*virtual*/ std::string getImageSizePanelName() const { return "profile_image_size_lp"; } - /*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; } + /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const { return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; } /*virtual*/ void updateControls(const LLSD& info); void onSend(); @@ -96,6 +96,6 @@ void LLPanelSnapshotProfile::onSend() std::string caption = getChild<LLUICtrl>("caption")->getValue().asString(); bool add_location = getChild<LLUICtrl>("add_location_cb")->getValue().asBoolean(); - LLWebProfile::uploadImage(LLFloaterSnapshot::getImageData(), caption, add_location); - LLFloaterSnapshot::postSave(); + LLWebProfile::uploadImage(mSnapshotFloater->getImageData(), caption, add_location); + mSnapshotFloater->postSave(); } diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 3de9dc2f8058defc0b7559078c4ac8aace2e2970..fe0608d5441594e958547554213017c52425502d 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -104,7 +104,9 @@ class LLTeleportHistoryFlatItem : public LLPanel //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -class LLTeleportHistoryFlatItemStorage: public LLSingleton<LLTeleportHistoryFlatItemStorage> { +class LLTeleportHistoryFlatItemStorage: public LLSingleton<LLTeleportHistoryFlatItemStorage> +{ + LLSINGLETON_EMPTY_CTOR(LLTeleportHistoryFlatItemStorage); protected: typedef std::vector< LLHandle<LLTeleportHistoryFlatItem> > flat_item_list_t; diff --git a/indra/newview/llpaneltopinfobar.h b/indra/newview/llpaneltopinfobar.h index f37bd9c048823990ffab34a7c02823ff958d5ca9..78dd99702906f95f2f32bc6aa0045d838ceb6dbb 100644 --- a/indra/newview/llpaneltopinfobar.h +++ b/indra/newview/llpaneltopinfobar.h @@ -28,6 +28,7 @@ #define LLPANELTOPINFOBAR_H_ #include "llpanel.h" +#include "llinitdestroyclass.h" class LLButton; class LLTextBox; @@ -36,6 +37,8 @@ class LLParcelChangeObserver; class LLPanelTopInfoBar : public LLPanel, public LLSingleton<LLPanelTopInfoBar>, private LLDestroyClass<LLPanelTopInfoBar> { + LLSINGLETON(LLPanelTopInfoBar); + ~LLPanelTopInfoBar(); LOG_CLASS(LLPanelTopInfoBar); friend class LLDestroyClass<LLPanelTopInfoBar>; @@ -43,9 +46,6 @@ class LLPanelTopInfoBar : public LLPanel, public LLSingleton<LLPanelTopInfoBar>, public: typedef boost::signals2::signal<void ()> resize_signal_t; - LLPanelTopInfoBar(); - ~LLPanelTopInfoBar(); - /*virtual*/ BOOL postBuild(); /*virtual*/ void draw(); diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index d0353259a52f860da324a1383e7269cb3c115f9c..a150007177e3ede7451edcbbde6fb281478b8049 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -30,13 +30,19 @@ #include "lltoggleablemenu.h" +#include "llagent.h" +#include "llaccordionctrl.h" +#include "llaccordionctrltab.h" #include "llappearancemgr.h" #include "llfloatersidepanelcontainer.h" #include "llinventoryfunctions.h" +#include "llinventoryicon.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" #include "llmenubutton.h" +#include "llscrolllistctrl.h" #include "llviewermenu.h" +#include "llviewerregion.h" #include "llwearableitemslist.h" #include "llsdserialize.h" #include "llclipboard.h" @@ -146,11 +152,47 @@ class LLWearingContextMenu : public LLListContextMenu menu->setItemVisible("detach", allow_detach); menu->setItemVisible("edit_outfit_separator", allow_take_off || allow_detach); menu->setItemVisible("show_original", mUUIDs.size() == 1); + menu->setItemVisible("edit_item", FALSE); } }; ////////////////////////////////////////////////////////////////////////// +class LLTempAttachmentsContextMenu : public LLListContextMenu +{ +public: + LLTempAttachmentsContextMenu(LLPanelWearing* panel_wearing) + : mPanelWearing(panel_wearing) + {} +protected: + /* virtual */ LLContextMenu* createMenu() + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + + registrar.add("Wearing.EditItem", boost::bind(&LLPanelWearing::onEditAttachment, mPanelWearing)); + registrar.add("Wearing.Detach", boost::bind(&LLPanelWearing::onRemoveAttachment, mPanelWearing)); + LLContextMenu* menu = createFromFile("menu_wearing_tab.xml"); + + updateMenuItemsVisibility(menu); + + return menu; + } + + void updateMenuItemsVisibility(LLContextMenu* menu) + { + menu->setItemVisible("take_off", FALSE); + menu->setItemVisible("detach", TRUE); + menu->setItemVisible("edit_outfit_separator", TRUE); + menu->setItemVisible("show_original", FALSE); + menu->setItemVisible("edit_item", TRUE); + menu->setItemVisible("edit", FALSE); + } + + LLPanelWearing* mPanelWearing; +}; + +////////////////////////////////////////////////////////////////////////// + std::string LLPanelAppearanceTab::sFilterSubString = LLStringUtil::null; static LLPanelInjector<LLPanelWearing> t_panel_wearing("panel_wearing"); @@ -159,30 +201,48 @@ LLPanelWearing::LLPanelWearing() : LLPanelAppearanceTab() , mCOFItemsList(NULL) , mIsInitialized(false) + , mAttachmentsChangedConnection() { mCategoriesObserver = new LLInventoryCategoriesObserver(); mGearMenu = new LLWearingGearMenu(this); mContextMenu = new LLWearingContextMenu(); + mAttachmentsMenu = new LLTempAttachmentsContextMenu(this); } LLPanelWearing::~LLPanelWearing() { delete mGearMenu; delete mContextMenu; + delete mAttachmentsMenu; if (gInventory.containsObserver(mCategoriesObserver)) { gInventory.removeObserver(mCategoriesObserver); } delete mCategoriesObserver; + + if (mAttachmentsChangedConnection.connected()) + { + mAttachmentsChangedConnection.disconnect(); + } } BOOL LLPanelWearing::postBuild() { + mAccordionCtrl = getChild<LLAccordionCtrl>("wearables_accordion"); + mWearablesTab = getChild<LLAccordionCtrlTab>("tab_wearables"); + mWearablesTab->setIgnoreResizeNotification(true); + mAttachmentsTab = getChild<LLAccordionCtrlTab>("tab_temp_attachments"); + mAttachmentsTab->setDropDownStateChangedCallback(boost::bind(&LLPanelWearing::onAccordionTabStateChanged, this)); + mCOFItemsList = getChild<LLWearableItemsList>("cof_items_list"); mCOFItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onWearableItemsListRightClick, this, _1, _2, _3)); + mTempItemsList = getChild<LLScrollListCtrl>("temp_attachments_list"); + mTempItemsList->setFgUnselectedColor(LLColor4::white); + mTempItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onTempAttachmentsListRightClick, this, _1, _2, _3)); + LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn"); menu_gear_btn->setMenu(mGearMenu->getMenu()); @@ -223,6 +283,44 @@ void LLPanelWearing::onOpen(const LLSD& /*info*/) } } +void LLPanelWearing::draw() +{ + if (mUpdateTimer.getStarted() && (mUpdateTimer.getElapsedTimeF32() > 0.1)) + { + mUpdateTimer.stop(); + updateAttachmentsList(); + } + LLPanel::draw(); +} + +void LLPanelWearing::onAccordionTabStateChanged() +{ + if(mAttachmentsTab->isExpanded()) + { + startUpdateTimer(); + mAttachmentsChangedConnection = LLAppearanceMgr::instance().setAttachmentsChangedCallback(boost::bind(&LLPanelWearing::startUpdateTimer, this)); + } + else + { + if (mAttachmentsChangedConnection.connected()) + { + mAttachmentsChangedConnection.disconnect(); + } + } +} + +void LLPanelWearing::startUpdateTimer() +{ + if (!mUpdateTimer.getStarted()) + { + mUpdateTimer.start(); + } + else + { + mUpdateTimer.reset(); + } +} + // virtual void LLPanelWearing::setFilterSubString(const std::string& string) { @@ -251,6 +349,124 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata) return false; } +void LLPanelWearing::updateAttachmentsList() +{ + std::vector<LLViewerObject*> attachs = LLAgentWearables::getTempAttachments(); + mTempItemsList->deleteAllItems(); + mAttachmentsMap.clear(); + if(!attachs.empty()) + { + if(!populateAttachmentsList()) + { + requestAttachmentDetails(); + } + } + else + { + std::string no_attachments = getString("no_attachments"); + LLSD row; + row["columns"][0]["column"] = "text"; + row["columns"][0]["value"] = no_attachments; + row["columns"][0]["font"] = "SansSerifBold"; + mTempItemsList->addElement(row); + } +} + +bool LLPanelWearing::populateAttachmentsList(bool update) +{ + bool populated = true; + if(mTempItemsList) + { + mTempItemsList->deleteAllItems(); + mAttachmentsMap.clear(); + std::vector<LLViewerObject*> attachs = LLAgentWearables::getTempAttachments(); + + std::string icon_name = LLInventoryIcon::getIconName(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT); + for (std::vector<LLViewerObject*>::iterator iter = attachs.begin(); + iter != attachs.end(); ++iter) + { + LLViewerObject *attachment = *iter; + LLSD row; + row["id"] = attachment->getID(); + row["columns"][0]["column"] = "icon"; + row["columns"][0]["type"] = "icon"; + row["columns"][0]["value"] = icon_name; + row["columns"][1]["column"] = "text"; + if(mObjectNames.count(attachment->getID()) && !mObjectNames[attachment->getID()].empty()) + { + row["columns"][1]["value"] = mObjectNames[attachment->getID()]; + } + else if(update) + { + row["columns"][1]["value"] = attachment->getID(); + populated = false; + } + else + { + row["columns"][1]["value"] = "Loading..."; + populated = false; + } + mTempItemsList->addElement(row); + mAttachmentsMap[attachment->getID()] = attachment; + } + } + return populated; +} + +void LLPanelWearing::requestAttachmentDetails() +{ + LLSD body; + std::string url = gAgent.getRegion()->getCapability("AttachmentResources"); + if (!url.empty()) + { + LLCoros::instance().launch("LLPanelWearing::getAttachmentLimitsCoro", + boost::bind(&LLPanelWearing::getAttachmentLimitsCoro, this, url)); + } +} + +void LLPanelWearing::getAttachmentLimitsCoro(std::string url) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", 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); + + if (!status) + { + LL_WARNS() << "Unable to retrieve attachment limits." << LL_ENDL; + return; + } + + result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); + setAttachmentDetails(result); +} + + +void LLPanelWearing::setAttachmentDetails(LLSD content) +{ + mObjectNames.clear(); + S32 number_attachments = content["attachments"].size(); + for(int i = 0; i < number_attachments; i++) + { + S32 number_objects = content["attachments"][i]["objects"].size(); + for(int j = 0; j < number_objects; j++) + { + LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID(); + std::string name = content["attachments"][i]["objects"][j]["name"].asString(); + mObjectNames[task_id] = name; + } + } + if(!mObjectNames.empty()) + { + populateAttachmentsList(true); + } +} + boost::signals2::connection LLPanelWearing::setSelectionChangeCallback(commit_callback_t cb) { if (!mCOFItemsList) return boost::signals2::connection(); @@ -270,6 +486,20 @@ void LLPanelWearing::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y) mContextMenu->show(ctrl, selected_uuids, x, y); } +void LLPanelWearing::onTempAttachmentsListRightClick(LLUICtrl* ctrl, S32 x, S32 y) +{ + LLScrollListCtrl* list = dynamic_cast<LLScrollListCtrl*>(ctrl); + if (!list) return; + list->selectItemAt(x, y, MASK_NONE); + uuid_vec_t selected_uuids; + + if(list->getCurrentID().notNull()) + { + selected_uuids.push_back(list->getCurrentID()); + mAttachmentsMenu->show(ctrl, selected_uuids, x, y); + } +} + bool LLPanelWearing::hasItemSelected() { return mCOFItemsList->getSelectedItem() != NULL; @@ -280,6 +510,28 @@ void LLPanelWearing::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const mCOFItemsList->getSelectedUUIDs(selected_uuids); } +void LLPanelWearing::onEditAttachment() +{ + LLScrollListItem* item = mTempItemsList->getFirstSelected(); + if (item) + { + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]); + handle_object_edit(); + } +} + +void LLPanelWearing::onRemoveAttachment() +{ + LLScrollListItem* item = mTempItemsList->getFirstSelected(); + if (item) + { + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]); + LLSelectMgr::getInstance()->sendDropAttachment(); + } +} + void LLPanelWearing::copyToClipboard() { std::string text; diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h index 9a212b3cca92c2feafd0e644c1ba1f44c5794e7c..c5cb79092ad5aee9c15b50c3369ab68c7431f6bb 100644 --- a/indra/newview/llpanelwearing.h +++ b/indra/newview/llpanelwearing.h @@ -31,9 +31,14 @@ // newview #include "llpanelappearancetab.h" +#include "llselectmgr.h" +#include "lltimer.h" +class LLAccordionCtrl; +class LLAccordionCtrlTab; class LLInventoryCategoriesObserver; class LLListContextMenu; +class LLScrollListCtrl; class LLWearableItemsList; class LLWearingGearMenu; @@ -52,6 +57,8 @@ class LLPanelWearing : public LLPanelAppearanceTab /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + /*virtual*/ void onOpen(const LLSD& info); /*virtual*/ void setFilterSubString(const std::string& string); @@ -62,17 +69,43 @@ class LLPanelWearing : public LLPanelAppearanceTab /*virtual*/ void copyToClipboard(); + void startUpdateTimer(); + void updateAttachmentsList(); + boost::signals2::connection setSelectionChangeCallback(commit_callback_t cb); bool hasItemSelected(); + bool populateAttachmentsList(bool update = false); + void onAccordionTabStateChanged(); + void setAttachmentDetails(LLSD content); + void requestAttachmentDetails(); + void onEditAttachment(); + void onRemoveAttachment(); + private: void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); + void onTempAttachmentsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); + + void getAttachmentLimitsCoro(std::string url); LLInventoryCategoriesObserver* mCategoriesObserver; LLWearableItemsList* mCOFItemsList; + LLScrollListCtrl* mTempItemsList; LLWearingGearMenu* mGearMenu; LLListContextMenu* mContextMenu; + LLListContextMenu* mAttachmentsMenu; + + LLAccordionCtrlTab* mWearablesTab; + LLAccordionCtrlTab* mAttachmentsTab; + LLAccordionCtrl* mAccordionCtrl; + + std::map<LLUUID, LLViewerObject*> mAttachmentsMap; + + std::map<LLUUID, std::string> mObjectNames; + + boost::signals2::connection mAttachmentsChangedConnection; + LLFrameTimer mUpdateTimer; bool mIsInitialized; }; diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp index b886e46765804bf92bc9d1978eaaf90580be33d3..eb7b95552e371809324b56b49e1887655493c279 100644 --- a/indra/newview/llpathfindinglinksetlist.cpp +++ b/indra/newview/llpathfindinglinksetlist.cpp @@ -204,7 +204,10 @@ void LLPathfindingLinksetList::parseLinksetListData(const LLSD& pLinksetListData { const std::string& uuid(linksetDataIter->first); const LLSD& linksetData = linksetDataIter->second; - LLPathfindingObjectPtr linksetPtr(new LLPathfindingLinkset(uuid, linksetData)); - objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, linksetPtr)); + if(linksetData.size() != 0) + { + LLPathfindingObjectPtr linksetPtr(new LLPathfindingLinkset(uuid, linksetData)); + objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, linksetPtr)); + } } } diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp index 711a869e823d478ac8a7946f7c94e2d0e98e3b67..cb4c07a417bb3d9ab012f8d9a54f9f7975431443 100644 --- a/indra/newview/llpathfindingmanager.cpp +++ b/indra/newview/llpathfindingmanager.cpp @@ -144,8 +144,7 @@ typedef boost::shared_ptr<LinksetsResponder> LinksetsResponderPtr; // LLPathfindingManager //--------------------------------------------------------------------------- -LLPathfindingManager::LLPathfindingManager() - : LLSingleton<LLPathfindingManager>(), +LLPathfindingManager::LLPathfindingManager(): mNavMeshMap(), mAgentStateSignal() { diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h index e8fad590ba7c9e8cb0a04fe7d87d82be37a3e970..a44cd892da61c4d45028bb4680fa76c27f2e3bc6 100644 --- a/indra/newview/llpathfindingmanager.h +++ b/indra/newview/llpathfindingmanager.h @@ -48,6 +48,9 @@ class LinksetsResponder; class LLPathfindingManager : public LLSingleton<LLPathfindingManager> { + LLSINGLETON(LLPathfindingManager); + virtual ~LLPathfindingManager(); + friend class LLNavMeshSimStateChangeNode; friend class NavMeshStatusResponder; friend class LLAgentStateChangeNode; @@ -60,9 +63,6 @@ class LLPathfindingManager : public LLSingleton<LLPathfindingManager> kRequestError } ERequestStatus; - LLPathfindingManager(); - virtual ~LLPathfindingManager(); - void initSystem(); void quitSystem(); diff --git a/indra/newview/llpathfindingpathtool.cpp b/indra/newview/llpathfindingpathtool.cpp index 006755e20b1c48952c202a5f83e7f8270ba5efb3..318732510117efed78fa0bdbf3376db23c1de13d 100644 --- a/indra/newview/llpathfindingpathtool.cpp +++ b/indra/newview/llpathfindingpathtool.cpp @@ -46,7 +46,6 @@ LLPathfindingPathTool::LLPathfindingPathTool() : LLTool(PATH_TOOL_NAME), - LLSingleton<LLPathfindingPathTool>(), mFinalPathData(), mTempPathData(), mPathResult(LLPathingLib::LLPL_NO_PATH), diff --git a/indra/newview/llpathfindingpathtool.h b/indra/newview/llpathfindingpathtool.h index 97284265f19b0d4327de284b82b0dee170fbe41c..88cb3a15f89e1e2131d4f613b1ebd746712a9616 100644 --- a/indra/newview/llpathfindingpathtool.h +++ b/indra/newview/llpathfindingpathtool.h @@ -36,6 +36,9 @@ class LLPathfindingPathTool : public LLTool, public LLSingleton<LLPathfindingPathTool> { + LLSINGLETON(LLPathfindingPathTool); + virtual ~LLPathfindingPathTool(); + public: typedef enum { @@ -59,9 +62,6 @@ class LLPathfindingPathTool : public LLTool, public LLSingleton<LLPathfindingPat kCharacterTypeD } ECharacterType; - LLPathfindingPathTool(); - virtual ~LLPathfindingPathTool(); - typedef boost::function<void (void)> path_event_callback_t; typedef boost::signals2::signal<void (void)> path_event_signal_t; typedef boost::signals2::connection path_event_slot_t; diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp index 9c0222d0bcef0eee343455e4dac879cc81043ad8..264382ae8280be64506e877e961f2d57073d1ea3 100644 --- a/indra/newview/llpersistentnotificationstorage.cpp +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -36,9 +36,8 @@ #include "llscriptfloater.h" #include "llviewermessage.h" #include "llviewernetwork.h" -LLPersistentNotificationStorage::LLPersistentNotificationStorage() - : LLSingleton<LLPersistentNotificationStorage>() - , LLNotificationStorage("") +LLPersistentNotificationStorage::LLPersistentNotificationStorage(): + LLNotificationStorage("") , mLoaded(false) { } diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h index bf0306380e7bd1f3c9658222451d4ea5fa48659d..40c9923c7412036cc0b26cf1cb5ab860e0cb4acc 100644 --- a/indra/newview/llpersistentnotificationstorage.h +++ b/indra/newview/llpersistentnotificationstorage.h @@ -45,10 +45,10 @@ class LLSD; class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>, public LLNotificationStorage { + LLSINGLETON(LLPersistentNotificationStorage); + ~LLPersistentNotificationStorage(); LOG_CLASS(LLPersistentNotificationStorage); public: - LLPersistentNotificationStorage(); - ~LLPersistentNotificationStorage(); void saveNotifications(); void loadNotifications(); diff --git a/indra/newview/llpipelinelistener.cpp b/indra/newview/llpipelinelistener.cpp index 20759239bf5f66663c8b77385d6bc56135b426da..dfbe689f56f4e444b444ce18391da219c223ee19 100644 --- a/indra/newview/llpipelinelistener.cpp +++ b/indra/newview/llpipelinelistener.cpp @@ -48,7 +48,7 @@ namespace { U32 render_type = render_type_from_string( iter->asString() ); if ( render_type != 0 ) { - LLPipeline::toggleRenderTypeControl( (void*) render_type ); + LLPipeline::toggleRenderTypeControl( render_type ); } } } @@ -59,7 +59,7 @@ namespace { U32 render_type = render_type_from_string( request["type"].asString() ); if ( render_type != 0 ) { - response["value"] = LLPipeline::hasRenderTypeControl( (void*) render_type ); + response["value"] = LLPipeline::hasRenderTypeControl( render_type ); } else { @@ -87,7 +87,7 @@ namespace { U32 render_feature = feature_from_string( iter->asString() ); if ( render_feature != 0 ) { - LLPipeline::toggleRenderDebugControl( (void*) render_feature ); + LLPipeline::toggleRenderDebugControl( render_feature ); } } } @@ -126,7 +126,7 @@ namespace { U32 info_display = info_display_from_string( iter->asString() ); if ( info_display != 0 ) { - LLPipeline::toggleRenderDebug( (void*) info_display ); + LLPipeline::toggleRenderDebug( info_display ); } } } diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp index a498d27d2ba247c6f31570282fbc8bf6bc1bfcde..55cb7d616bce1f8e2ea3306016bf2a3ea1cd4c4b 100644 --- a/indra/newview/llplacesinventorybridge.cpp +++ b/indra/newview/llplacesinventorybridge.cpp @@ -30,7 +30,6 @@ #include "llplacesinventorybridge.h" -#include "llfloaterinventory.h" // for LLInventoryPanel #include "llfolderview.h" // for FIRST_SELECTED_ITEM #include "llinventorypanel.h" diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h index 2805fc425716c7d4e8f33b9e8187162e35d24635..27d9b83bd170731c599cb7db6d9e76741160cde1 100644 --- a/indra/newview/llplacesinventorypanel.h +++ b/indra/newview/llplacesinventorypanel.h @@ -27,7 +27,6 @@ #ifndef LL_LLINVENTORYSUBTREEPANEL_H #define LL_LLINVENTORYSUBTREEPANEL_H -#include "llfloaterinventory.h" #include "llinventorypanel.h" class LLLandmarksPanel; diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp index d95546f11d211a3826cad348239710191f7c390c..f40b3e029522e2b0439c31394f95981d3b5883e3 100644 --- a/indra/newview/llpresetsmanager.cpp +++ b/indra/newview/llpresetsmanager.cpp @@ -38,6 +38,7 @@ #include "llviewercontrol.h" #include "llfloaterpreference.h" #include "llfloaterreg.h" +#include "llfeaturemanager.h" LLPresetsManager::LLPresetsManager() { @@ -54,13 +55,17 @@ void LLPresetsManager::triggerChangeSignal() void LLPresetsManager::createMissingDefault() { + if(gDirUtilp->getLindenUserDir().empty()) + { + return; + } std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml"); if (!gDirUtilp->fileExists(default_file)) { LL_INFOS() << "No default preset found -- creating one at " << default_file << LL_ENDL; // Write current graphic settings as the default - savePreset(PRESETS_GRAPHIC, PRESETS_DEFAULT); + savePreset(PRESETS_GRAPHIC, PRESETS_DEFAULT, true); } else { @@ -103,8 +108,7 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam if (found) { std::string path = gDirUtilp->add(dir, file); - std::string name = gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true); - + std::string name = LLURI::unescape(gDirUtilp->getBaseFileName(path, /*strip_exten = */ true)); LL_DEBUGS() << " Found preset '" << name << "'" << LL_ENDL; if (PRESETS_DEFAULT != name) @@ -134,7 +138,7 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam presets = mPresetNames; } -bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string name) +bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string name, bool createDefault) { if (LLTrans::getString(PRESETS_DEFAULT) == name) { @@ -146,11 +150,10 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n if(PRESETS_GRAPHIC == subdirectory) { - gSavedSettings.setString("PresetGraphicActive", name); - LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); - if (instance) + if (instance && !createDefault) { + gSavedSettings.setString("PresetGraphicActive", name); instance->getControlNames(name_list); LL_DEBUGS() << "saving preset '" << name << "'; " << name_list.size() << " names" << LL_ENDL; name_list.push_back("PresetGraphicActive"); @@ -170,23 +173,36 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n LL_ERRS() << "Invalid presets directory '" << subdirectory << "'" << LL_ENDL; } - if (name_list.size() > 1) // if the active preset name is the only thing in the list, don't save the list + if (name_list.size() > 1 // if the active preset name is the only thing in the list, don't save the list + || (createDefault && name == PRESETS_DEFAULT && subdirectory == PRESETS_GRAPHIC)) // or create a default graphics preset from hw recommended settings { // make an empty llsd LLSD paramsData(LLSD::emptyMap()); - for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it) + if (createDefault) { - std::string ctrl_name = *it; - LLControlVariable* ctrl = gSavedSettings.getControl(ctrl_name).get(); - std::string comment = ctrl->getComment(); - std::string type = LLControlGroup::typeEnumToString(ctrl->type()); - LLSD value = ctrl->getValue(); - - paramsData[ctrl_name]["Comment"] = comment; - paramsData[ctrl_name]["Persist"] = 1; - paramsData[ctrl_name]["Type"] = type; - paramsData[ctrl_name]["Value"] = value; + paramsData = LLFeatureManager::getInstance()->getRecommendedSettingsMap(); + if (gSavedSettings.getU32("RenderAvatarMaxComplexity") == 0) + { + // use the recommended setting as an initial one (MAINT-6435) + gSavedSettings.setU32("RenderAvatarMaxComplexity", paramsData["RenderAvatarMaxComplexity"]["Value"].asInteger()); + } + } + else + { + for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it) + { + std::string ctrl_name = *it; + LLControlVariable* ctrl = gSavedSettings.getControl(ctrl_name).get(); + std::string comment = ctrl->getComment(); + std::string type = LLControlGroup::typeEnumToString(ctrl->type()); + LLSD value = ctrl->getValue(); + + paramsData[ctrl_name]["Comment"] = comment; + paramsData[ctrl_name]["Persist"] = 1; + paramsData[ctrl_name]["Type"] = type; + paramsData[ctrl_name]["Value"] = value; + } } std::string pathName(getPresetsDir(subdirectory) + gDirUtilp->getDirDelimiter() + LLURI::escape(name) + ".xml"); @@ -203,10 +219,12 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n LL_DEBUGS() << "saved preset '" << name << "'; " << paramsData.size() << " parameters" << LL_ENDL; - gSavedSettings.setString("PresetGraphicActive", name); - - // signal interested parties - triggerChangeSignal(); + if (!createDefault) + { + gSavedSettings.setString("PresetGraphicActive", name); + // signal interested parties + triggerChangeSignal(); + } } else { diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h index ac4f0c010ce31cfc0862682a33549836288e66a8..0014e32267ffd026a9c698e29a3dd20d8b2fb7e6 100644 --- a/indra/newview/llpresetsmanager.h +++ b/indra/newview/llpresetsmanager.h @@ -46,6 +46,9 @@ enum EDefaultOptions class LLPresetsManager : public LLSingleton<LLPresetsManager> { + LLSINGLETON(LLPresetsManager); + ~LLPresetsManager(); + public: typedef std::list<std::string> preset_name_list_t; @@ -56,7 +59,7 @@ class LLPresetsManager : public LLSingleton<LLPresetsManager> static std::string getPresetsDir(const std::string& subdirectory); void setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo, EDefaultOptions default_option); void loadPresetNamesFromDir(const std::string& dir, preset_name_list_t& presets, EDefaultOptions default_option); - bool savePreset(const std::string& subdirectory, std::string name); + bool savePreset(const std::string& subdirectory, std::string name, bool createDefault = false); void loadPreset(const std::string& subdirectory, std::string name); bool deletePreset(const std::string& subdirectory, std::string name); @@ -67,9 +70,6 @@ class LLPresetsManager : public LLSingleton<LLPresetsManager> preset_name_list_t mPresetNames; - LLPresetsManager(); - ~LLPresetsManager(); - preset_list_signal_t mPresetListChangeSignal; private: diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index 35ac0537a3d01758397f939b3d13eb509d471ad4..fb40af1302dcc79419052d8da6e2724a1e6b131d 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -37,6 +37,7 @@ #include "lllineeditor.h" #include "lluictrlfactory.h" #include "lluictrlfactory.h" +#include "lldatapacker.h" extern LLAgent gAgent; diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index ba9845ef04519df0d3e7cc7890f464771b934d80..510d91839d6b6cff88a8cb0b83ccf0ff4ac0c851 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -437,6 +437,23 @@ void LLPreviewNotecard::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, } } +void LLPreviewNotecard::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId) +{ + + LLSD floater_key; + floater_key["taskid"] = taskId; + floater_key["itemid"] = itemId; + LLPreviewNotecard* nc = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", floater_key); + if (nc) + { + if (nc->hasEmbeddedInventory()) + { + gVFS->removeFile(newAssetId, LLAssetType::AT_NOTECARD); + } + nc->setAssetId(newAssetId); + nc->refreshFromInventory(); + } +} bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) { @@ -485,7 +502,7 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) else if (!mObjectUUID.isNull() && !task_url.empty()) { uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mObjectUUID, mItemUUID, LLAssetType::AT_NOTECARD, buffer, - boost::bind(&LLPreviewNotecard::finishInventoryUpload, _1, _3, LLUUID::null))); + boost::bind(&LLPreviewNotecard::finishTaskUpload, _1, _3, mObjectUUID))); url = task_url; } diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index ba571995f6d2b359b4c8e4668285f8cb0f09d8ac..017c4485bae4744440b98de9383870459dbf1ab9 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -96,6 +96,7 @@ class LLPreviewNotecard : public LLPreview bool handleConfirmDeleteDialog(const LLSD& notification, const LLSD& response); static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId); + static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId); protected: LLViewerTextEditor* mEditor; diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 5b1b3565978b09ba7ad0b3ae0fadb8de209f6204..f28ffce602b677b0d52b887f285cec421db4513a 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -375,7 +375,8 @@ LLScriptEdCore::LLScriptEdCore( mLiveFile(NULL), mLive(live), mContainer(container), - mHasScriptData(FALSE) + mHasScriptData(FALSE), + mScriptRemoved(FALSE) { setFollowsAll(); setBorderVisible(FALSE); @@ -666,7 +667,7 @@ bool LLScriptEdCore::hasChanged() void LLScriptEdCore::draw() { BOOL script_changed = hasChanged(); - getChildView("Save_btn")->setEnabled(script_changed); + getChildView("Save_btn")->setEnabled(script_changed && !mScriptRemoved); if( mEditor->hasFocus() ) { @@ -840,7 +841,7 @@ void LLScriptEdCore::addHelpItemToHistory(const std::string& help_string) BOOL LLScriptEdCore::canClose() { - if(mForceClose || !hasChanged()) + if(mForceClose || !hasChanged() || mScriptRemoved) { return TRUE; } @@ -1511,6 +1512,17 @@ BOOL LLPreviewLSL::postBuild() return LLPreview::postBuild(); } +void LLPreviewLSL::draw() +{ + const LLInventoryItem* item = getItem(); + if(!item) + { + setTitle(LLTrans::getString("ScriptWasDeleted")); + mScriptEd->setItemRemoved(TRUE); + } + + LLPreview::draw(); +} // virtual void LLPreviewLSL::callbackLSLCompileSucceeded() { diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index a8c6a6eeebd9ba5f2ca929830e275b1eb1584d1f..6b311256417fac16f3415c0c0ef89439605ed111 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -119,6 +119,8 @@ class LLScriptEdCore : public LLPanel void setScriptName(const std::string& name){mScriptName = name;}; + void setItemRemoved(bool script_removed){mScriptRemoved = script_removed;}; + private: void onBtnHelp(); void onBtnDynamicHelp(); @@ -163,6 +165,7 @@ class LLScriptEdCore : public LLPanel BOOL mHasScriptData; LLLiveLSLFile* mLiveFile; LLUUID mAssociatedExperience; + BOOL mScriptRemoved; LLScriptEdContainer* mContainer; // parent view @@ -198,6 +201,7 @@ class LLPreviewLSL : public LLScriptEdContainer /*virtual*/ BOOL postBuild(); protected: + virtual void draw(); virtual BOOL canClose(); void closeIfNeeded(); diff --git a/indra/newview/llproductinforequest.h b/indra/newview/llproductinforequest.h index 75dbf220d17cdf140bba4aea684e9b3a101293a7..d1036374e8008302ff83f8b8d68ee12f4d7eaade 100644 --- a/indra/newview/llproductinforequest.h +++ b/indra/newview/llproductinforequest.h @@ -41,12 +41,11 @@ */ class LLProductInfoRequestManager : public LLSingleton<LLProductInfoRequestManager> { + LLSINGLETON(LLProductInfoRequestManager); public: - LLProductInfoRequestManager(); std::string getDescriptionForSku(const std::string& sku); private: - friend class LLSingleton<LLProductInfoRequestManager>; /* virtual */ void initSingleton(); void getLandDescriptionsCoro(std::string url); diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h index d0d637686749fe2490ea5ef5525c56b07f4eb9d8..c7aaf604f5dd554ce64d4d60f47f2cf5c80cbf70 100644 --- a/indra/newview/llrecentpeople.h +++ b/indra/newview/llrecentpeople.h @@ -50,6 +50,7 @@ class LLDate; */ class LLRecentPeople: public LLSingleton<LLRecentPeople>, public LLOldEvents::LLSimpleListener { + LLSINGLETON_EMPTY_CTOR(LLRecentPeople); LOG_CLASS(LLRecentPeople); public: typedef boost::signals2::signal<void ()> signal_t; diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h index d22a0de4635bfd14abd5e7f862aeb86073fd26aa..ea9640efda99e81461f2df77fa5c3fee7df53b4e 100644 --- a/indra/newview/llregioninfomodel.h +++ b/indra/newview/llregioninfomodel.h @@ -36,6 +36,7 @@ class LLMessageSystem; */ class LLRegionInfoModel : public LLSingleton<LLRegionInfoModel> { + LLSINGLETON(LLRegionInfoModel); LOG_CLASS(LLRegionInfoModel); public: @@ -73,10 +74,8 @@ class LLRegionInfoModel : public LLSingleton<LLRegionInfoModel> std::string mSimType; protected: - friend class LLSingleton<LLRegionInfoModel>; friend class LLViewerRegion; - LLRegionInfoModel(); /** * Refresh model with data from the incoming server message. diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h index cb5af50c5f083e737a7f5aab4a693b18fa466794..5b0d1891378fbbbb4975e6010e13c691952972ff 100644 --- a/indra/newview/llremoteparcelrequest.h +++ b/indra/newview/llremoteparcelrequest.h @@ -74,9 +74,10 @@ class LLRemoteParcelInfoObserver class LLRemoteParcelInfoProcessor : public LLSingleton<LLRemoteParcelInfoProcessor> { -public: + LLSINGLETON_EMPTY_CTOR(LLRemoteParcelInfoProcessor); virtual ~LLRemoteParcelInfoProcessor() {} +public: void addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer); void removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer); diff --git a/indra/newview/llrootview.h b/indra/newview/llrootview.h index 5223a314f39b392b3c74cdd5d29a6eaec6d42011..2ac958e7b831781ed54a730f70d9c92969c0f688 100644 --- a/indra/newview/llrootview.h +++ b/indra/newview/llrootview.h @@ -32,7 +32,9 @@ #include "lltooltip.h" class LLRootViewRegistry : public LLChildRegistry<LLRootViewRegistry> -{}; +{ + LLSINGLETON(LLRootViewRegistry); +}; class LLRootView : public LLView { diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h index 2b6ea57b96016a88663da97aa9865d0e399ee141..7cd531bd34667c510e492f3d396ba63226e792b1 100644 --- a/indra/newview/llscenemonitor.h +++ b/indra/newview/llscenemonitor.h @@ -39,10 +39,10 @@ class LLViewerTexture; class LLSceneMonitor : public LLSingleton<LLSceneMonitor> { + LLSINGLETON(LLSceneMonitor); + ~LLSceneMonitor(); LOG_CLASS(LLSceneMonitor); public: - LLSceneMonitor(); - ~LLSceneMonitor(); void freezeAvatar(LLCharacter* avatarp); void setDebugViewerVisible(bool visible); diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index ba2c37ce7cf376dd9a6e4fa35090d2cb960f1514..681787bcbe937fb660b354fd8a943221ca76ccc9 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -117,6 +117,14 @@ BOOL LLScreenChannelBase::postBuild() void LLScreenChannelBase::reshape(S32 width, S32 height, BOOL called_from_parent) { + if (mChannelAlignment == CA_CENTRE) + { + // Keep notifications and alerts centered + // WorldViewRectScaled is out of date at reshape but Window has same width + S32 channel_bound = gViewerWindow->getWindowRectScaled().getWidth() / 2; + setRect(LLRect(channel_bound, 0, channel_bound, 0)); + updateRect(); //sets top and bottom only + } redrawToasts(); } diff --git a/indra/newview/llscriptfloater.h b/indra/newview/llscriptfloater.h index 70451194b38bbde051a7f5c3a7b1a9193db1d5d8..c0b84abdcb1f9eb6123a6b2524828f92914dddd7 100644 --- a/indra/newview/llscriptfloater.h +++ b/indra/newview/llscriptfloater.h @@ -41,6 +41,7 @@ class LLScriptFloaterManager : public LLSingleton<LLScriptFloaterManager> // *TODO // LLScriptFloaterManager and LLScriptFloater will need some refactoring after we // know how script notifications should look like. + LLSINGLETON_EMPTY_CTOR(LLScriptFloaterManager); public: typedef enum e_object_type diff --git a/indra/newview/llsearchhistory.cpp b/indra/newview/llsearchhistory.cpp index 0ea05a03d6775bf1aa6effa9eaf5c0f68c756dff..449e0080f0e52eea772ec4ea4a36cf4227b4368c 100644 --- a/indra/newview/llsearchhistory.cpp +++ b/indra/newview/llsearchhistory.cpp @@ -116,26 +116,26 @@ void LLSearchHistory::addEntry(const std::string& search_query) mSearchHistory.push_front(item); } -bool LLSearchHistory::LLSearchHistoryItem::operator < (const LLSearchHistory::LLSearchHistoryItem& right) +bool LLSearchHistory::LLSearchHistoryItem::operator < (const LLSearchHistory::LLSearchHistoryItem& right) const { S32 result = LLStringUtil::compareInsensitive(search_query, right.search_query); return result < 0; } -bool LLSearchHistory::LLSearchHistoryItem::operator > (const LLSearchHistory::LLSearchHistoryItem& right) +bool LLSearchHistory::LLSearchHistoryItem::operator > (const LLSearchHistory::LLSearchHistoryItem& right) const { S32 result = LLStringUtil::compareInsensitive(search_query, right.search_query); return result > 0; } -bool LLSearchHistory::LLSearchHistoryItem::operator==(const LLSearchHistory::LLSearchHistoryItem& right) +bool LLSearchHistory::LLSearchHistoryItem::operator==(const LLSearchHistory::LLSearchHistoryItem& right) const { return 0 == LLStringUtil::compareInsensitive(search_query, right.search_query); } -bool LLSearchHistory::LLSearchHistoryItem::operator==(const std::string& right) +bool LLSearchHistory::LLSearchHistoryItem::operator==(const std::string& right) const { return 0 == LLStringUtil::compareInsensitive(search_query, right); } diff --git a/indra/newview/llsearchhistory.h b/indra/newview/llsearchhistory.h index 3309a8fcac0d2a0447e4dd88220fe932fc3b461a..4ae6122396eb51b7a82864081939854cc9158910 100644 --- a/indra/newview/llsearchhistory.h +++ b/indra/newview/llsearchhistory.h @@ -28,6 +28,7 @@ #define LL_LLSEARCHHISTORY_H #include "llsingleton.h" +#include "llinitdestroyclass.h" #include "llui.h" /** @@ -36,6 +37,7 @@ */ class LLSearchHistory : public LLSingleton<LLSearchHistory>, private LLDestroyClass<LLSearchHistory> { + LLSINGLETON(LLSearchHistory); friend class LLDestroyClass<LLSearchHistory>; public: @@ -71,7 +73,6 @@ class LLSearchHistory : public LLSingleton<LLSearchHistory>, private LLDestroyCl */ void addEntry(const std::string& search_text); - LLSearchHistory(); /** * Class for storing data about single search request. @@ -98,16 +99,16 @@ class LLSearchHistory : public LLSingleton<LLSearchHistory>, private LLDestroyCl /** * Allows std::list sorting */ - bool operator < (const LLSearchHistory::LLSearchHistoryItem& right); + bool operator < (const LLSearchHistory::LLSearchHistoryItem& right) const; /** * Allows std::list sorting */ - bool operator > (const LLSearchHistory::LLSearchHistoryItem& right); + bool operator > (const LLSearchHistory::LLSearchHistoryItem& right) const; - bool operator==(const LLSearchHistoryItem& right); + bool operator==(const LLSearchHistoryItem& right) const; - bool operator==(const std::string& right); + bool operator==(const std::string& right) const; /** * Serializes search history item to LLSD diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp index 4f9f83b6f26364dbec03a1269a4091c5441f6d25..72d7cf1e4522eebcf56bfb455976d79dd7abc000 100644 --- a/indra/newview/llsecapi.cpp +++ b/indra/newview/llsecapi.cpp @@ -29,6 +29,8 @@ #include "llviewerprecompiledheaders.h" #include "llsecapi.h" #include "llsechandler_basic.h" +#include "llexception.h" +#include "stringize.h" #include <openssl/evp.h> #include <openssl/err.h> #include <map> @@ -64,12 +66,12 @@ void initializeSecHandler() } catch (LLProtectedDataException e) { - exception_msg = e.getMessage(); + exception_msg = e.what(); } } if (!exception_msg.empty()) // an exception was thrown. { - throw LLProtectedDataException(exception_msg.c_str()); + LLTHROW(LLProtectedDataException(exception_msg)); } } @@ -101,6 +103,7 @@ std::ostream& operator <<(std::ostream& s, const LLCredential& cred) LLSD LLCredential::getLoginParams() { LLSD result = LLSD::emptyMap(); + std::string username; try { if (mIdentifier["type"].asString() == "agent") @@ -109,17 +112,19 @@ LLSD LLCredential::getLoginParams() result["passwd"] = "$1$" + mAuthenticator["secret"].asString(); result["first"] = mIdentifier["first_name"]; result["last"] = mIdentifier["last_name"]; - + username = result["first"].asString() + " " + result["last"].asString(); } else if (mIdentifier["type"].asString() == "account") { result["username"] = mIdentifier["account_name"]; result["passwd"] = mAuthenticator["secret"]; - + username = result["username"].asString(); } } catch (...) { + // nat 2016-08-18: not clear what exceptions the above COULD throw?! + LOG_UNHANDLED_EXCEPTION(STRINGIZE("for '" << username << "'")); // we could have corrupt data, so simply return a null login param if so LL_WARNS("AppInit") << "Invalid credential" << LL_ENDL; } diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h index 6fe3ee31cf0369b7d8ba12424ce941868a9aef6d..6af5a28fa5eb1fc8fc1372e5d233fdfb8b522d81 100644 --- a/indra/newview/llsecapi.h +++ b/indra/newview/llsecapi.h @@ -32,6 +32,7 @@ #include <openssl/x509.h> #include <ostream> #include "llpointer.h" +#include "llexception.h" #ifdef LL_WINDOWS #pragma warning(disable:4250) @@ -116,17 +117,13 @@ -class LLProtectedDataException +struct LLProtectedDataException: public LLException { -public: - LLProtectedDataException(const char *msg) + LLProtectedDataException(const std::string& msg): + LLException(msg) { - LL_WARNS("SECAPI") << "Protected Data Error: " << (std::string)msg << LL_ENDL; - mMsg = (std::string)msg; + LL_WARNS("SECAPI") << "Protected Data Error: " << msg << LL_ENDL; } - std::string getMessage() { return mMsg; } -protected: - std::string mMsg; }; // class LLCertificate @@ -334,22 +331,21 @@ std::ostream& operator <<(std::ostream& s, const LLCredential& cred); // All error handling is via exceptions. -class LLCertException +class LLCertException: public LLException { public: - LLCertException(LLPointer<LLCertificate> cert, const char* msg) + LLCertException(LLPointer<LLCertificate> cert, const std::string& msg): + LLException(msg) { mCert = cert; - LL_WARNS("SECAPI") << "Certificate Error: " << (std::string)msg << LL_ENDL; - mMsg = (std::string)msg; + LL_WARNS("SECAPI") << "Certificate Error: " << msg << LL_ENDL; } - LLPointer<LLCertificate> getCert() { return mCert; } - std::string getMessage() { return mMsg; } + virtual ~LLCertException() throw() {} + LLPointer<LLCertificate> getCert() const { return mCert; } protected: LLPointer<LLCertificate> mCert; - std::string mMsg; }; class LLInvalidCertificate : public LLCertException @@ -358,6 +354,7 @@ class LLInvalidCertificate : public LLCertException LLInvalidCertificate(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertInvalid") { } + virtual ~LLInvalidCertificate() throw() {} protected: }; @@ -367,6 +364,7 @@ class LLCertValidationTrustException : public LLCertException LLCertValidationTrustException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertUntrusted") { } + virtual ~LLCertValidationTrustException() throw() {} protected: }; @@ -378,7 +376,7 @@ class LLCertValidationHostnameException : public LLCertException { mHostname = hostname; } - + virtual ~LLCertValidationHostnameException() throw() {} std::string getHostname() { return mHostname; } protected: std::string mHostname; @@ -392,6 +390,7 @@ class LLCertValidationExpirationException : public LLCertException { mTime = current_time; } + virtual ~LLCertValidationExpirationException() throw() {} LLDate GetTime() { return mTime; } protected: LLDate mTime; @@ -403,6 +402,7 @@ class LLCertKeyUsageValidationException : public LLCertException LLCertKeyUsageValidationException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertKeyUsage") { } + virtual ~LLCertKeyUsageValidationException() throw() {} protected: }; @@ -412,6 +412,7 @@ class LLCertBasicConstraintsValidationException : public LLCertException LLCertBasicConstraintsValidationException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertBasicConstraints") { } + virtual ~LLCertBasicConstraintsValidationException() throw() {} protected: }; @@ -421,6 +422,7 @@ class LLCertValidationInvalidSignatureException : public LLCertException LLCertValidationInvalidSignatureException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertInvalidSignature") { } + virtual ~LLCertValidationInvalidSignatureException() throw() {} protected: }; diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index 40516f9bbb6243d0fe978f2a193b66f416135046..d6fb801cc0089f5bef88255708eb05e20eb6832d 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -35,6 +35,8 @@ #include "llfile.h" #include "lldir.h" #include "llviewercontrol.h" +#include "llexception.h" +#include "stringize.h" #include <vector> #include <ios> #include <openssl/ossl_typ.h> @@ -72,14 +74,14 @@ LLBasicCertificate::LLBasicCertificate(const std::string& pem_cert) if(pem_bio == NULL) { LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL; - throw LLInvalidCertificate(this); + LLTHROW(LLInvalidCertificate(this)); } mCert = NULL; PEM_read_bio_X509(pem_bio, &mCert, 0, NULL); BIO_free(pem_bio); if (!mCert) { - throw LLInvalidCertificate(this); + LLTHROW(LLInvalidCertificate(this)); } } @@ -88,7 +90,7 @@ LLBasicCertificate::LLBasicCertificate(X509* pCert) { if (!pCert || !pCert->cert_info) { - throw LLInvalidCertificate(this); + LLTHROW(LLInvalidCertificate(this)); } mCert = X509_dup(pCert); } @@ -617,7 +619,7 @@ void LLBasicCertificateStore::load_from_file(const std::string& filename) } catch (...) { - LL_WARNS("SECAPI") << "Failure creating certificate from the certificate store file." << LL_ENDL; + LOG_UNHANDLED_EXCEPTION("creating certificate from the certificate store file"); } X509_free(cert_x509); cert_x509 = NULL; @@ -873,22 +875,22 @@ void _validateCert(int validation_policy, // check basic properties exist in the cert if(!current_cert_info.has(CERT_SUBJECT_NAME) || !current_cert_info.has(CERT_SUBJECT_NAME_STRING)) { - throw LLCertException(cert, "Cert doesn't have a Subject Name"); + LLTHROW(LLCertException(cert, "Cert doesn't have a Subject Name")); } if(!current_cert_info.has(CERT_ISSUER_NAME_STRING)) { - throw LLCertException(cert, "Cert doesn't have an Issuer Name"); + LLTHROW(LLCertException(cert, "Cert doesn't have an Issuer Name")); } // check basic properties exist in the cert if(!current_cert_info.has(CERT_VALID_FROM) || !current_cert_info.has(CERT_VALID_TO)) { - throw LLCertException(cert, "Cert doesn't have an expiration period"); + LLTHROW(LLCertException(cert, "Cert doesn't have an expiration period")); } if (!current_cert_info.has(CERT_SHA1_DIGEST)) { - throw LLCertException(cert, "No SHA1 digest"); + LLTHROW(LLCertException(cert, "No SHA1 digest")); } if (validation_policy & VALIDATION_POLICY_TIME) @@ -903,7 +905,7 @@ void _validateCert(int validation_policy, if((validation_date < current_cert_info[CERT_VALID_FROM].asDate()) || (validation_date > current_cert_info[CERT_VALID_TO].asDate())) { - throw LLCertValidationExpirationException(cert, validation_date); + LLTHROW(LLCertValidationExpirationException(cert, validation_date)); } } if (validation_policy & VALIDATION_POLICY_SSL_KU) @@ -914,14 +916,14 @@ void _validateCert(int validation_policy, !(_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE], LLSD((std::string)CERT_KU_KEY_ENCIPHERMENT))))) { - throw LLCertKeyUsageValidationException(cert); + LLTHROW(LLCertKeyUsageValidationException(cert)); } // only validate EKU if the cert has it if(current_cert_info.has(CERT_EXTENDED_KEY_USAGE) && current_cert_info[CERT_EXTENDED_KEY_USAGE].isArray() && (!_LLSDArrayIncludesValue(current_cert_info[CERT_EXTENDED_KEY_USAGE], LLSD((std::string)CERT_EKU_SERVER_AUTH)))) { - throw LLCertKeyUsageValidationException(cert); + LLTHROW(LLCertKeyUsageValidationException(cert)); } } if (validation_policy & VALIDATION_POLICY_CA_KU) @@ -930,7 +932,7 @@ void _validateCert(int validation_policy, (!_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE], (std::string)CERT_KU_CERT_SIGN))) { - throw LLCertKeyUsageValidationException(cert); + LLTHROW(LLCertKeyUsageValidationException(cert)); } } @@ -942,13 +944,13 @@ void _validateCert(int validation_policy, if(!current_cert_info[CERT_BASIC_CONSTRAINTS].has(CERT_BASIC_CONSTRAINTS_CA) || !current_cert_info[CERT_BASIC_CONSTRAINTS][CERT_BASIC_CONSTRAINTS_CA]) { - throw LLCertBasicConstraintsValidationException(cert); + LLTHROW(LLCertBasicConstraintsValidationException(cert)); } if (current_cert_info[CERT_BASIC_CONSTRAINTS].has(CERT_BASIC_CONSTRAINTS_PATHLEN) && ((current_cert_info[CERT_BASIC_CONSTRAINTS][CERT_BASIC_CONSTRAINTS_PATHLEN].asInteger() != 0) && (depth > current_cert_info[CERT_BASIC_CONSTRAINTS][CERT_BASIC_CONSTRAINTS_PATHLEN].asInteger()))) { - throw LLCertBasicConstraintsValidationException(cert); + LLTHROW(LLCertBasicConstraintsValidationException(cert)); } } } @@ -1018,7 +1020,7 @@ void LLBasicCertificateStore::validate(int validation_policy, if(cert_chain->size() < 1) { - throw LLCertException(NULL, "No certs in chain"); + LLTHROW(LLCertException(NULL, "No certs in chain")); } iterator current_cert = cert_chain->begin(); LLSD current_cert_info; @@ -1033,11 +1035,11 @@ void LLBasicCertificateStore::validate(int validation_policy, (*current_cert)->getLLSD(current_cert_info); if(!validation_params.has(CERT_HOSTNAME)) { - throw LLCertException((*current_cert), "No hostname passed in for validation"); + LLTHROW(LLCertException((*current_cert), "No hostname passed in for validation")); } if(!current_cert_info.has(CERT_SUBJECT_NAME) || !current_cert_info[CERT_SUBJECT_NAME].has(CERT_NAME_CN)) { - throw LLInvalidCertificate((*current_cert)); + LLTHROW(LLInvalidCertificate((*current_cert))); } LL_DEBUGS("SECAPI") << "Validating the hostname " << validation_params[CERT_HOSTNAME].asString() << @@ -1054,7 +1056,7 @@ void LLBasicCertificateStore::validate(int validation_policy, X509* cert_x509 = (*current_cert)->getOpenSSLX509(); if(!cert_x509) { - throw LLInvalidCertificate((*current_cert)); + LLTHROW(LLInvalidCertificate((*current_cert))); } std::string sha1_hash((const char *)cert_x509->sha1_hash, SHA_DIGEST_LENGTH); X509_free( cert_x509 ); @@ -1075,7 +1077,7 @@ void LLBasicCertificateStore::validate(int validation_policy, if((validation_date < cache_entry->second.first) || (validation_date > cache_entry->second.second)) { - throw LLCertValidationExpirationException((*current_cert), validation_date); + LLTHROW(LLCertValidationExpirationException((*current_cert), validation_date)); } } // successfully found in cache @@ -1107,7 +1109,7 @@ void LLBasicCertificateStore::validate(int validation_policy, if(!_verify_signature((*current_cert), previous_cert)) { - throw LLCertValidationInvalidSignatureException(previous_cert); + LLTHROW(LLCertValidationInvalidSignatureException(previous_cert)); } } _validateCert(local_validation_policy, @@ -1156,7 +1158,7 @@ void LLBasicCertificateStore::validate(int validation_policy, if(!_verify_signature((*found_store_cert), (*current_cert))) { - throw LLCertValidationInvalidSignatureException(*current_cert); + LLTHROW(LLCertValidationInvalidSignatureException(*current_cert)); } // successfully validated. mTrustedCertCache[sha1_hash] = std::pair<LLDate, LLDate>(from_time, to_time); @@ -1173,7 +1175,7 @@ void LLBasicCertificateStore::validate(int validation_policy, if (validation_policy & VALIDATION_POLICY_TRUSTED) { // we reached the end without finding a trusted cert. - throw LLCertValidationTrustException((*cert_chain)[cert_chain->size()-1]); + LLTHROW(LLCertValidationTrustException((*cert_chain)[cert_chain->size()-1])); } mTrustedCertCache[sha1_hash] = std::pair<LLDate, LLDate>(from_time, to_time); @@ -1261,7 +1263,7 @@ void LLSecAPIBasicHandler::_readProtectedData() protected_data_stream.read((char *)salt, STORE_SALT_SIZE); if (protected_data_stream.gcount() < STORE_SALT_SIZE) { - throw LLProtectedDataException("Config file too short."); + LLTHROW(LLProtectedDataException("Config file too short.")); } cipher.decrypt(salt, STORE_SALT_SIZE); @@ -1301,7 +1303,7 @@ void LLSecAPIBasicHandler::_readProtectedData() if (parser->parse(parse_stream, mProtectedDataMap, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE) { - throw LLProtectedDataException("Config file cannot be decrypted."); + LLTHROW(LLProtectedDataException("Config file cannot be decrypted.")); } } } @@ -1364,7 +1366,7 @@ void LLSecAPIBasicHandler::_writeProtectedData() } catch (...) { - LL_WARNS() << "LLProtectedDataException(Error writing Protected Data Store)" << LL_ENDL; + LOG_UNHANDLED_EXCEPTION("LLProtectedDataException(Error writing Protected Data Store)"); // it's good practice to clean up any secure information on error // (even though this file isn't really secure. Perhaps in the future // it may be, however. @@ -1372,39 +1374,39 @@ void LLSecAPIBasicHandler::_writeProtectedData() // EXP-1825 crash in LLSecAPIBasicHandler::_writeProtectedData() // Decided throwing an exception here was overkill until we figure out why this happens - //throw LLProtectedDataException("Error writing Protected Data Store"); + //LLTHROW(LLProtectedDataException("Error writing Protected Data Store")); } - try - { - // move the temporary file to the specified file location. - if((( (LLFile::isfile(mProtectedDataFilename) != 0) - && (LLFile::remove(mProtectedDataFilename) != 0))) - || (LLFile::rename(tmp_filename, mProtectedDataFilename))) - { - LL_WARNS() << "LLProtectedDataException(Could not overwrite protected data store)" << LL_ENDL; - LLFile::remove(tmp_filename); + try + { + // move the temporary file to the specified file location. + if((( (LLFile::isfile(mProtectedDataFilename) != 0) + && (LLFile::remove(mProtectedDataFilename) != 0))) + || (LLFile::rename(tmp_filename, mProtectedDataFilename))) + { + LL_WARNS() << "LLProtectedDataException(Could not overwrite protected data store)" << LL_ENDL; + LLFile::remove(tmp_filename); - // EXP-1825 crash in LLSecAPIBasicHandler::_writeProtectedData() - // Decided throwing an exception here was overkill until we figure out why this happens - //throw LLProtectedDataException("Could not overwrite protected data store"); - } + // EXP-1825 crash in LLSecAPIBasicHandler::_writeProtectedData() + // Decided throwing an exception here was overkill until we figure out why this happens + //LLTHROW(LLProtectedDataException("Could not overwrite protected data store")); + } } catch (...) { - LL_WARNS() << "LLProtectedDataException(Error renaming '" << tmp_filename - << "' to '" << mProtectedDataFilename << "')" << LL_ENDL; + LOG_UNHANDLED_EXCEPTION(STRINGIZE("renaming '" << tmp_filename << "' to '" + << mProtectedDataFilename << "'")); // it's good practice to clean up any secure information on error // (even though this file isn't really secure. Perhaps in the future - // it may be, however. + // it may be, however). LLFile::remove(tmp_filename); //crash in LLSecAPIBasicHandler::_writeProtectedData() // Decided throwing an exception here was overkill until we figure out why this happens - //throw LLProtectedDataException("Error writing Protected Data Store"); + //LLTHROW(LLProtectedDataException("Error writing Protected Data Store")); } } - + // instantiate a certificate from a pem string LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(const std::string& pem_cert) { diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 323689b788eb7128587d42859c110aa43dc7c45e..dd934ce6b8f79f2c8aba0d6d4bbc21491b21567b 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6006,6 +6006,11 @@ S32 LLSelectNode::getLastSelectedTE() return mLastTESelected; } +S32 LLSelectNode::getLastOperatedTE() +{ + return mLastTESelected; +} + LLViewerObject* LLSelectNode::getObject() { if (!mObject) @@ -6244,6 +6249,9 @@ void pushWireframe(LLDrawable* drawable) void LLSelectNode::renderOneWireframe(const LLColor4& color) { + //Need to because crash on ATI 3800 (and similar cards) MAINT-5018 + LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + LLViewerObject* objectp = getObject(); if (!objectp) { @@ -7197,7 +7205,9 @@ U32 LLObjectSelection::getSelectedObjectTriangleCount(S32* vcount) if (object) { - count += object->getTriangleCount(vcount); + S32 vt = 0; + count += object->getTriangleCount(&vt); + *vcount += vt; } } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index bc50e443f80035b09cd354f691d871e9f0ccc2a1..2a893af266c3aa8b5bd76a8ced034c925ce9baf4 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -170,6 +170,7 @@ class LLSelectNode void selectTE(S32 te_index, BOOL selected); BOOL isTESelected(S32 te_index); S32 getLastSelectedTE(); + S32 getLastOperatedTE(); S32 getTESelectMask() { return mTESelectMask; } void renderOneWireframe(const LLColor4& color); void renderOneSilhouette(const LLColor4 &color); @@ -388,6 +389,9 @@ struct LLSelectGetFirstTest; class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr> { + LLSINGLETON(LLSelectMgr); + ~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? @@ -413,9 +417,6 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr> LLCachedControl<bool> mDebugSelectMgr; public: - LLSelectMgr(); - ~LLSelectMgr(); - static void cleanupGlobals(); // LLEditMenuHandler interface diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 86135ee6e83a0df031548f01b87b12e6dd7b0ece..a32ed258f84f86b554d65a10819cdb5c6cac3a33 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -383,12 +383,22 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_cam void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearable *wearable, BOOL disable_camera_switch) { - if (!mEditWearable || mEditWearable->getVisible() == visible) + if (!mEditWearable) { - // visibility isn't changing, hence nothing to do return; } + if (mEditWearable->getVisible() == visible && (!visible || mEditWearable->getWearable() != wearable)) + { + // visibility isn't changing and panel doesn't need an update, hence nothing to do + return; + } + + // If we're just switching between outfit and wearable editing or updating item, + // don't end customization and don't switch camera + // Don't end customization and don't switch camera without visibility change + BOOL change_state = !disable_camera_switch && mEditWearable->getVisible() != visible; + if (!wearable) { wearable = gAgentWearables.getViewerWearable(LLWearableType::WT_SHAPE, 0); @@ -403,8 +413,8 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearab if (visible) { - LLVOAvatarSelf::onCustomizeStart(disable_camera_switch); - mEditWearable->setWearable(wearable, disable_camera_switch); + LLVOAvatarSelf::onCustomizeStart(!change_state); + mEditWearable->setWearable(wearable, !change_state); mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency } else @@ -412,9 +422,9 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearab // Save changes if closing. mEditWearable->saveChanges(); LLAppearanceMgr::getInstance()->updateIsDirty(); - if (!disable_camera_switch) // if we're just switching between outfit and wearable editing, don't end customization. + if (change_state) { - LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch); + LLVOAvatarSelf::onCustomizeEnd(!change_state); } } } diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 6bcae1e85882db64971dd91c3bcccaad0fb2e493..c6a0198afd091977f008776c753ef660d0f56f40 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -34,6 +34,7 @@ #include "llbutton.h" #include "lldate.h" #include "llfirstuse.h" +#include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llfoldertype.h" #include "llfolderview.h" @@ -731,3 +732,16 @@ std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList() return inventory_selected_uuids; } + +void LLSidepanelInventory::cleanup() +{ + 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();) + { + LLFloaterSidePanelContainer* iv = dynamic_cast<LLFloaterSidePanelContainer*>(*iter++); + if (iv) + { + iv->cleanup(); + } + } +} diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 17a3098db9c66431bc61d0ea5c07ea1a127a6a88..5060f7025f6ac8946ece4011262b78a32e4f8852 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -82,6 +82,8 @@ class LLSidepanelInventory : public LLPanel void updateVerbs(); + static void cleanup(); + protected: // Tracks highlighted (selected) item in inventory panel. LLInventoryItem *getSelectedItem(); diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dba690242ad2eea020e924b5d009936282535352 --- /dev/null +++ b/indra/newview/llskinningutil.cpp @@ -0,0 +1,218 @@ +/** +* @file llskinningutil.cpp +* @brief Functions for mesh object skinning +* @author vir@lindenlab.com +* +* $LicenseInfo:firstyear=2015&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2015, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* 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 "llskinningutil.h" +#include "llvoavatar.h" +#include "llviewercontrol.h" +#include "llmeshrepository.h" + +// static +void LLSkinningUtil::initClass() +{ +} + +// static +U32 LLSkinningUtil::getMaxJointCount() +{ + U32 result = LL_MAX_JOINTS_PER_MESH_OBJECT; + return result; +} + +// static +U32 LLSkinningUtil::getMeshJointCount(const LLMeshSkinInfo *skin) +{ + return llmin((U32)getMaxJointCount(), (U32)skin->mJointNames.size()); +} + +// static +void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin) +{ + if (skin->mInvalidJointsScrubbed) + { + return; + } + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + // Fix invalid names to "mPelvis". Currently meshes with + // invalid names will be blocked on upload, so this is just + // needed for handling of any legacy bad data. + if (!avatar->getJoint(skin->mJointNames[j])) + { + LL_DEBUGS("Avatar") << "Mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL; + skin->mJointNames[j] = "mPelvis"; + } + } + skin->mInvalidJointsScrubbed = true; +} + +// static +void LLSkinningUtil::initSkinningMatrixPalette( + LLMatrix4* mat, + S32 count, + const LLMeshSkinInfo* skin, + LLVOAvatar *avatar) +{ + for (U32 j = 0; j < count; ++j) + { + LLJoint *joint = NULL; + if (skin->mJointNums[j] == -1) + { + joint = avatar->getJoint(skin->mJointNames[j]); + if (joint) + { + skin->mJointNums[j] = joint->getJointNum(); + } + } + else + { + joint = avatar->getJoint(skin->mJointNums[j]); + } + if (joint) + { +#define MAT_USE_SSE +#ifdef MAT_USE_SSE + LLMatrix4a bind, world, res; + bind.loadu(skin->mInvBindMatrix[j]); + world.loadu(joint->getWorldMatrix()); + matMul(bind,world,res); + memcpy(mat[j].mMatrix,res.mMatrix,16*sizeof(float)); +#else + mat[j] = skin->mInvBindMatrix[j]; + mat[j] *= joint->getWorldMatrix(); +#endif + } + else + { + mat[j] = skin->mInvBindMatrix[j]; + // This shouldn't happen - in mesh upload, skinned + // rendering should be disabled unless all joints are + // valid. In other cases of skinned rendering, invalid + // joints should already have been removed during scrubInvalidJoints(). + LL_WARNS_ONCE("Avatar") << "Rigged to invalid joint name " << skin->mJointNames[j] << LL_ENDL; + } + } +} + +// static +void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) +{ +#ifdef SHOW_ASSERT // same condition that controls llassert() + const S32 max_joints = skin->mJointNames.size(); + for (U32 j=0; j<num_vertices; j++) + { + F32 *w = weights[j].getF32ptr(); + + F32 wsum = 0.0; + for (U32 k=0; k<4; ++k) + { + S32 i = llfloor(w[k]); + llassert(i>=0); + llassert(i<max_joints); + wsum += w[k]-i; + } + llassert(wsum > 0.0f); + } +#endif +} + +void LLSkinningUtil::scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) +{ + const S32 max_joints = skin->mJointNames.size(); + for (U32 j=0; j<num_vertices; j++) + { + F32 *w = weights[j].getF32ptr(); + + for (U32 k=0; k<4; ++k) + { + S32 i = llfloor(w[k]); + F32 f = w[k]-i; + i = llclamp(i,0,max_joints-1); + w[k] = i + f; + } + } + checkSkinWeights(weights, num_vertices, skin); +} + +// static +void LLSkinningUtil::getPerVertexSkinMatrix( + F32* weights, + LLMatrix4a* mat, + bool handle_bad_scale, + LLMatrix4a& final_mat, + U32 max_joints) +{ + bool valid_weights = true; + final_mat.clear(); + + S32 idx[4]; + + LLVector4 wght; + + F32 scale = 0.f; + for (U32 k = 0; k < 4; k++) + { + F32 w = weights[k]; + + // BENTO potential optimizations + // - Do clamping in unpackVolumeFaces() (once instead of every time) + // - int vs floor: if we know w is + // >= 0.0, we can use int instead of floorf; the latter + // allegedly has a lot of overhead due to ieeefp error + // checking which we should not need. + idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)max_joints-1); + + wght[k] = w - floorf(w); + scale += wght[k]; + } + if (handle_bad_scale && scale <= 0.f) + { + wght = LLVector4(1.0f, 0.0f, 0.0f, 0.0f); + valid_weights = false; + } + else + { + // This is enforced in unpackVolumeFaces() + llassert(scale>0.f); + wght *= 1.f/scale; + } + + for (U32 k = 0; k < 4; k++) + { + F32 w = wght[k]; + + LLMatrix4a src; + src.setMul(mat[idx[k]], w); + + final_mat.add(src); + } + // SL-366 - with weight validation/cleanup code, it should no longer be + // possible to hit the bad scale case. + llassert(valid_weights); +} + diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h new file mode 100644 index 0000000000000000000000000000000000000000..135b25d4d21c5d280e6764c758d5b8f6cc5d28df --- /dev/null +++ b/indra/newview/llskinningutil.h @@ -0,0 +1,47 @@ +/** +* @file llskinningutil.h +* @brief Functions for mesh object skinning +* @author vir@lindenlab.com +* +* $LicenseInfo:firstyear=2015&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2015, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* 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 LLSKINNINGUTIL_H +#define LLSKINNINGUTIL_H + +class LLVOAvatar; +class LLMeshSkinInfo; +class LLMatrix4a; + +class LLSkinningUtil +{ +public: + static void initClass(); + static U32 getMaxJointCount(); + static U32 getMeshJointCount(const LLMeshSkinInfo *skin); + static void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin); + static void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); + static void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); + static void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); + static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); +}; + +#endif diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 623565817d17bf76757300a2a4b9a338ef8fc138..58e48480c1ea9c252b8af93af8d92570efad0b15 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -86,13 +86,13 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Param mNeedsFlash(TRUE), mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")), mDataSize(0), - mSnapshotType(SNAPSHOT_POSTCARD), - mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))), + mSnapshotType(LLSnapshotModel::SNAPSHOT_POSTCARD), + mSnapshotFormat(LLSnapshotModel::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))), mSnapshotUpToDate(FALSE), mCameraPos(LLViewerCamera::getInstance()->getOrigin()), mCameraRot(LLViewerCamera::getInstance()->getQuaternion()), mSnapshotActive(FALSE), - mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR), + mSnapshotBufferType(LLSnapshotModel::SNAPSHOT_TYPE_COLOR), mFilterName(""), mAllowRenderUI(TRUE), mAllowFullScreenPreview(TRUE), @@ -465,7 +465,11 @@ void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_pare LL_DEBUGS() << "window reshaped, updating thumbnail" << LL_ENDL; if (mViewContainer && mViewContainer->isInVisibleChain()) { - updateSnapshot(TRUE); + // We usually resize only on window reshape, so give it a chance to redraw, assign delay + updateSnapshot( + TRUE, // new snapshot is needed + FALSE, // thumbnail will be updated either way. + AUTO_SNAPSHOT_TIME_DELAY); // shutter delay. } } } @@ -737,7 +741,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->getWidth(), previewp->getHeight(), previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"), - previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE, + previewp->getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE, previewp->mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"), FALSE, previewp->mSnapshotBufferType, @@ -813,7 +817,7 @@ void LLSnapshotLivePreview::prepareFreezeFrame() mViewerImage[mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE); LLPointer<LLViewerTexture> curr_preview_image = mViewerImage[mCurImageIndex]; gGL.getTexUnit(0)->bind(curr_preview_image); - curr_preview_image->setFilteringOption(getSnapshotType() == SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT); + curr_preview_image->setFilteringOption(getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT); curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -827,7 +831,7 @@ void LLSnapshotLivePreview::prepareFreezeFrame() S32 LLSnapshotLivePreview::getEncodedImageWidth() const { S32 width = getWidth(); - if (getSnapshotType() == SNAPSHOT_TEXTURE) + if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE) { width = LLImageRaw::biasedDimToPowerOfTwo(width,MAX_TEXTURE_SIZE); } @@ -836,7 +840,7 @@ S32 LLSnapshotLivePreview::getEncodedImageWidth() const S32 LLSnapshotLivePreview::getEncodedImageHeight() const { S32 height = getHeight(); - if (getSnapshotType() == SNAPSHOT_TEXTURE) + if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE) { height = LLImageRaw::biasedDimToPowerOfTwo(height,MAX_TEXTURE_SIZE); } @@ -854,7 +858,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage() mPreviewImage->getHeight(), mPreviewImage->getComponents()); - if (getSnapshotType() == SNAPSHOT_TEXTURE) + if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE) { // We don't store the intermediate formatted image in mFormattedImage in the J2C case LL_DEBUGS() << "Encoding new image of format J2C" << LL_ENDL; @@ -881,7 +885,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage() { // Update mFormattedImage if necessary getFormattedImage(); - if (getSnapshotFormat() == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP) + if (getSnapshotFormat() == LLSnapshotModel::SNAPSHOT_FORMAT_BMP) { // BMP hack : copy instead of decode otherwise decode will crash. mPreviewImageEncoded->copy(mPreviewImage); @@ -903,23 +907,23 @@ void LLSnapshotLivePreview::estimateDataSize() // Compression ratio F32 ratio = 1.0; - if (getSnapshotType() == SNAPSHOT_TEXTURE) + if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE) { ratio = 8.0; // This is what we shoot for when compressing to J2C } else { - LLFloaterSnapshot::ESnapshotFormat format = getSnapshotFormat(); + LLSnapshotModel::ESnapshotFormat format = getSnapshotFormat(); switch (format) { - case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG: + case LLSnapshotModel::SNAPSHOT_FORMAT_PNG: ratio = 3.0; // Average observed PNG compression ratio break; - case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG: + case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG: // Observed from JPG compression tests ratio = (110 - mSnapshotQuality) / 2; break; - case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP: + case LLSnapshotModel::SNAPSHOT_FORMAT_BMP: ratio = 1.0; // No compression with BMP break; } @@ -947,18 +951,18 @@ LLPointer<LLImageFormatted> LLSnapshotLivePreview::getFormattedImage() } // Create the new formatted image of the appropriate format. - LLFloaterSnapshot::ESnapshotFormat format = getSnapshotFormat(); + LLSnapshotModel::ESnapshotFormat format = getSnapshotFormat(); LL_DEBUGS() << "Encoding new image of format " << format << LL_ENDL; switch (format) { - case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG: + case LLSnapshotModel::SNAPSHOT_FORMAT_PNG: mFormattedImage = new LLImagePNG(); break; - case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG: + case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG: mFormattedImage = new LLImageJPEG(mSnapshotQuality); break; - case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP: + case LLSnapshotModel::SNAPSHOT_FORMAT_BMP: mFormattedImage = new LLImageBMP(); break; } @@ -978,7 +982,7 @@ void LLSnapshotLivePreview::setSize(S32 w, S32 h) setHeight(h); } -void LLSnapshotLivePreview::setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat format) +void LLSnapshotLivePreview::setSnapshotFormat(LLSnapshotModel::ESnapshotFormat format) { if (mSnapshotFormat != format) { @@ -993,7 +997,7 @@ void LLSnapshotLivePreview::getSize(S32& w, S32& h) const h = getHeight(); } -void LLSnapshotLivePreview::saveTexture() +void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name) { LL_DEBUGS() << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << LL_ENDL; // gen a new uuid for this asset @@ -1032,13 +1036,15 @@ void LLSnapshotLivePreview::saveTexture() LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL); std::string who_took_it; LLAgentUI::buildFullname(who_took_it); - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); - std::string name = "Snapshot: " + pos_string; - std::string desc = "Taken by " + who_took_it + " at " + pos_string; + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); + std::string res_name = outfit_snapshot ? name : "Snapshot : " + pos_string; + std::string res_desc = outfit_snapshot ? "" : "Taken by " + who_took_it + " at " + pos_string; + LLFolderType::EType folder_type = outfit_snapshot ? LLFolderType::FT_NONE : LLFolderType::FT_SNAPSHOT_CATEGORY; + LLInventoryType::EType inv_type = outfit_snapshot ? LLInventoryType::IT_NONE : LLInventoryType::IT_SNAPSHOT; LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo( - tid, LLAssetType::AT_TEXTURE, name, desc, 0, - LLFolderType::FT_SNAPSHOT_CATEGORY, LLInventoryType::IT_SNAPSHOT, + tid, LLAssetType::AT_TEXTURE, res_name, res_desc, 0, + folder_type, inv_type, PERM_ALL, LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), expected_upload_cost)); diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index 57e5d83f8e83232278b8c8d25888ab6e2de3fb41..b689c503205ca2d2b4528e91ff1f55a3b7ba1c65 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -27,7 +27,7 @@ #ifndef LL_LLSNAPSHOTLIVEPREVIEW_H #define LL_LLSNAPSHOTLIVEPREVIEW_H -#include "llpanelsnapshot.h" +#include "llsnapshotmodel.h" #include "llviewertexture.h" #include "llviewerwindow.h" @@ -40,14 +40,6 @@ class LLSnapshotLivePreview : public LLView { LOG_CLASS(LLSnapshotLivePreview); public: - enum ESnapshotType - { - SNAPSHOT_POSTCARD, - SNAPSHOT_TEXTURE, - SNAPSHOT_LOCAL, - SNAPSHOT_WEB - }; - struct Params : public LLInitParam::Block<Params, LLView::Params> { @@ -80,8 +72,8 @@ class LLSnapshotLivePreview : public LLView void setMaxImageSize(S32 size) ; S32 getMaxImageSize() {return mMaxImageSize ;} - ESnapshotType getSnapshotType() const { return mSnapshotType; } - LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; } + LLSnapshotModel::ESnapshotType getSnapshotType() const { return mSnapshotType; } + LLSnapshotModel::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; } BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; } BOOL isSnapshotActive() { return mSnapshotActive; } LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; } @@ -98,16 +90,16 @@ class LLSnapshotLivePreview : public LLView void setImageScaled(BOOL scaled) { mImageScaled[mCurImageIndex] = scaled; } const LLVector3d& getPosTakenGlobal() const { return mPosTakenGlobal; } - void setSnapshotType(ESnapshotType type) { mSnapshotType = type; } - void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat format); + void setSnapshotType(LLSnapshotModel::ESnapshotType type) { mSnapshotType = type; } + void setSnapshotFormat(LLSnapshotModel::ESnapshotFormat format); bool setSnapshotQuality(S32 quality, bool set_by_user = true); - void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; } + void setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType type) { mSnapshotBufferType = type; } void setAllowRenderUI(BOOL allow) { mAllowRenderUI = allow; } void setAllowFullScreenPreview(BOOL allow) { mAllowFullScreenPreview = allow; } void setFilter(std::string filter_name) { mFilterName = filter_name; } std::string getFilter() const { return mFilterName; } void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f); - void saveTexture(); + void saveTexture(BOOL outfit_snapshot = FALSE, std::string name = ""); BOOL saveLocal(); LLPointer<LLImageFormatted> getFormattedImage(); @@ -169,14 +161,14 @@ class LLSnapshotLivePreview : public LLView LLVector3d mPosTakenGlobal; S32 mSnapshotQuality; S32 mDataSize; - ESnapshotType mSnapshotType; - LLFloaterSnapshot::ESnapshotFormat mSnapshotFormat; + LLSnapshotModel::ESnapshotType mSnapshotType; + LLSnapshotModel::ESnapshotFormat mSnapshotFormat; BOOL mSnapshotUpToDate; LLFrameTimer mFallAnimTimer; LLVector3 mCameraPos; LLQuaternion mCameraRot; BOOL mSnapshotActive; - LLViewerWindow::ESnapshotType mSnapshotBufferType; + LLSnapshotModel::ESnapshotLayerType mSnapshotBufferType; std::string mFilterName; public: diff --git a/indra/newview/llsnapshotmodel.h b/indra/newview/llsnapshotmodel.h new file mode 100644 index 0000000000000000000000000000000000000000..71402fb5bc8ea23e4971a21143e266880d8e3ca2 --- /dev/null +++ b/indra/newview/llsnapshotmodel.h @@ -0,0 +1,55 @@ +/** +* @file llsnapshotmodel.h +* @brief Snapshot model for storing snapshot data etc. +* +* $LicenseInfo:firstyear=2004&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2016, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* 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_LLSNAPSHOTMODEL_H +#define LL_LLSNAPSHOTMODEL_H + +class LLSnapshotModel +{ +public: + enum ESnapshotType + { + SNAPSHOT_POSTCARD, + SNAPSHOT_TEXTURE, + SNAPSHOT_LOCAL, + SNAPSHOT_WEB + }; + + typedef enum e_snapshot_format + { + SNAPSHOT_FORMAT_PNG, + SNAPSHOT_FORMAT_JPEG, + SNAPSHOT_FORMAT_BMP + } ESnapshotFormat; + + typedef enum + { + SNAPSHOT_TYPE_COLOR, + SNAPSHOT_TYPE_DEPTH + } ESnapshotLayerType; +}; + +#endif // LL_LLSNAPSHOTMODEL_H diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index b0eb4137a735634a160a7af5fb9cf1bbf9cf01bc..94b838e8291673cdc464e93501dddbd704863e97 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -61,9 +61,6 @@ extern bool gShiftFrame; static U32 sZombieGroups = 0; U32 LLSpatialGroup::sNodeCount = 0; -U32 gOctreeMaxCapacity; -F32 gOctreeMinSize; - BOOL LLSpatialGroup::sNoDelete = FALSE; static F32 sLastMaxTexPriority = 1.f; @@ -3213,6 +3210,11 @@ void renderAvatarCollisionVolumes(LLVOAvatar* avatar) avatar->renderCollisionVolumes(); } +void renderAvatarBones(LLVOAvatar* avatar) +{ + avatar->renderBones(); +} + void renderAgentTarget(LLVOAvatar* avatar) { // render these for self only (why, i don't know) @@ -3371,6 +3373,11 @@ class LLOctreeRenderNonOccluded : public OctreeTraveler renderAvatarCollisionVolumes(avatar); } + if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_JOINTS)) + { + renderAvatarBones(avatar); + } + if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AGENT_TARGET)) { renderAgentTarget(avatar); @@ -3661,6 +3668,7 @@ void LLSpatialPartition::renderDebug() 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_BUILD_QUEUE | LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index 5cff70f37767cdf42aace17853c62923a548f2b0..617bae39844c3a3880031ab703ed7f87ea3ba8cf 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -341,20 +341,18 @@ class LLIMSpeakerMgr : public LLSpeakerMgr class LLActiveSpeakerMgr : public LLSpeakerMgr, public LLSingleton<LLActiveSpeakerMgr> { + LLSINGLETON(LLActiveSpeakerMgr); LOG_CLASS(LLActiveSpeakerMgr); -public: - LLActiveSpeakerMgr(); protected: virtual void updateSpeakerList(); }; class LLLocalSpeakerMgr : public LLSpeakerMgr, public LLSingleton<LLLocalSpeakerMgr> { - LOG_CLASS(LLLocalSpeakerMgr); -public: - LLLocalSpeakerMgr(); + LLSINGLETON(LLLocalSpeakerMgr); ~LLLocalSpeakerMgr (); + LOG_CLASS(LLLocalSpeakerMgr); protected: virtual void updateSpeakerList(); }; diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp index 78fe7863c8090226f197d9267ea4649e48a01e4f..5ca1d4b4a57d597c558f4594052f70ed31acacb3 100644 --- a/indra/newview/llspeakingindicatormanager.cpp +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -48,6 +48,8 @@ */ class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, LLVoiceClientParticipantObserver { + LLSINGLETON(SpeakingIndicatorManager); + ~SpeakingIndicatorManager(); LOG_CLASS(SpeakingIndicatorManager); public: @@ -91,10 +93,6 @@ class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, L typedef speaking_indicators_mmap_t::const_iterator indicator_const_iterator; typedef std::pair<indicator_const_iterator, indicator_const_iterator> indicator_range_t; - friend class LLSingleton<SpeakingIndicatorManager>; - SpeakingIndicatorManager(); - ~SpeakingIndicatorManager(); - /** * Callback to determine when voice channel is changed. * diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 62ca3434d736ec1ea163fe1d4d7f93fa12e1ad6b..50f4c7854ebb9a3beb84f6f6f7ef9841d1bf54a9 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -28,6 +28,7 @@ #include "llappviewer.h" #include "llstartup.h" +#include "llcallstack.h" #if LL_WINDOWS # include <process.h> // _spawnl() @@ -193,6 +194,9 @@ #include "llstartuplistener.h" #include "lltoolbarview.h" #include "llexperiencelog.h" +#include "llcleanup.h" + +#include "llstacktrace.h" #if LL_WINDOWS #include "lldxhardware.h" @@ -771,7 +775,11 @@ bool idle_startup() LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL; } } - + display_startup(); + if (gViewerWindow->getSystemUIScaleFactorChanged()) + { + LLViewerWindow::showSystemUIScaleFactorChanged(); + } LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input } else @@ -1217,7 +1225,7 @@ bool idle_startup() LLPostProcess::initClass(); display_startup(); - LLAvatarAppearance::initClass(); + LLAvatarAppearance::initClass("avatar_lad.xml","avatar_skeleton.xml"); display_startup(); LLViewerObject::initVOClasses(); @@ -2803,7 +2811,7 @@ void LLStartUp::initExperiences() void LLStartUp::cleanupNameCache() { - LLAvatarNameCache::cleanupClass(); + SUBSYSTEM_CLEANUP(LLAvatarNameCache); delete gCacheName; gCacheName = NULL; @@ -3020,7 +3028,7 @@ bool LLStartUp::startLLProxy() } else { - LL_WARNS("Proxy") << "Invalid other HTTP proxy configuration."<< LL_ENDL; + LL_WARNS("Proxy") << "Invalid other HTTP proxy configuration: " << httpProxyType << LL_ENDL; // Set the missing or wrong configuration back to something valid. gSavedSettings.setString("HttpProxyType", "None"); diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 041eae4b3c9cd36af417dd1fe2a02581f667c9a2..72c5c961aaaeebfafa261a26dcf51165a18366b3 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -309,7 +309,7 @@ void LLStatusBar::refresh() (LLViewerMedia::hasInWorldMedia() || LLViewerMedia::hasParcelMedia() || LLViewerMedia::hasParcelAudio()); mMediaToggle->setEnabled(button_enabled); // Note the "sense" of the toggle is opposite whether media is playing or not - bool any_media_playing = (LLViewerMedia::isAnyMediaShowing() || + bool any_media_playing = (LLViewerMedia::isAnyMediaPlaying() || LLViewerMedia::isParcelMediaPlaying() || LLViewerMedia::isParcelAudioPlaying()); mMediaToggle->setValue(!any_media_playing); @@ -562,8 +562,8 @@ void LLStatusBar::onClickMediaToggle(void* data) { LLStatusBar *status_bar = (LLStatusBar*)data; // "Selected" means it was showing the "play" icon (so media was playing), and now it shows "pause", so turn off media - bool enable = ! status_bar->mMediaToggle->getValue(); - LLViewerMedia::setAllMediaEnabled(enable); + bool pause = status_bar->mMediaToggle->getValue(); + LLViewerMedia::setAllMediaPaused(pause); } BOOL can_afford_transaction(S32 cost) diff --git a/indra/newview/llstylemap.h b/indra/newview/llstylemap.h index 8aa0af535c38f9aa062db679b52a6cb7da2d9c33..96b392059372bf38463a5b32c875fff1f0a678e5 100644 --- a/indra/newview/llstylemap.h +++ b/indra/newview/llstylemap.h @@ -39,6 +39,7 @@ typedef std::map<LLUUID, LLStyle::Params> style_map_t; class LLStyleMap : public LLSingleton<LLStyleMap> { + LLSINGLETON_EMPTY_CTOR(LLStyleMap); public: // Just like the [] accessor but it will add the entry in if it doesn't exist. const LLStyle::Params &lookupAgent(const LLUUID &source); diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 2d06b8599c2152de1f1db604ac008852613806c5..d28a7cc048859852fc0622d4d3f63881eeb52b17 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -230,8 +230,8 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 const F32 xyScaleInv = (1.f / xyScale)*(0.2222222222f); F32 vec[3] = { - fmod((F32)(mOriginGlobal.mdV[0] + x)*xyScaleInv, 256.f), - fmod((F32)(mOriginGlobal.mdV[1] + y)*xyScaleInv, 256.f), + (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); diff --git a/indra/newview/llsyntaxid.h b/indra/newview/llsyntaxid.h index 0afa6dc04ba2868e21f7600351991fea1a0c83ae..1360b3e042efc43b716d67d5341179ef00714e55 100644 --- a/indra/newview/llsyntaxid.h +++ b/indra/newview/llsyntaxid.h @@ -38,9 +38,9 @@ class fetchKeywordsFileResponder; class LLSyntaxIdLSL : public LLSingleton<LLSyntaxIdLSL> { - friend class LLSingleton<LLSyntaxIdLSL>; + LLSINGLETON(LLSyntaxIdLSL); friend class fetchKeywordsFileResponder; - + private: std::set<std::string> mInflightFetches; typedef boost::signals2::signal<void()> syntax_id_changed_signal_t; @@ -67,7 +67,6 @@ class LLSyntaxIdLSL : public LLSingleton<LLSyntaxIdLSL> LLSD mKeywordsXml; public: - LLSyntaxIdLSL(); void initialize(); bool keywordFetchInProgress(); LLSD getKeywordsXML() const { return mKeywordsXml; }; diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index d02293e6fffa2fe595b9e75ef05a5ca0a5536e29..b96a2573a1f934f51054878676c6ed5bfe228092 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -32,6 +32,7 @@ #include "llscreenchannel.h" #include "llsyswellitem.h" #include "lltransientdockablefloater.h" +#include "llinitdestroyclass.h" class LLAvatarName; class LLChiclet; diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h index e9c29c39bf3e945d91a57f4260d8ad705919f56d..db0ccdda59cec04280062ed2f148131c152df4c6 100644 --- a/indra/newview/llteleporthistory.h +++ b/indra/newview/llteleporthistory.h @@ -73,6 +73,8 @@ class LLTeleportHistoryItem */ class LLTeleportHistory: public LLSingleton<LLTeleportHistory> { + LLSINGLETON(LLTeleportHistory); + ~LLTeleportHistory(); LOG_CLASS(LLTeleportHistory); public: @@ -81,9 +83,6 @@ class LLTeleportHistory: public LLSingleton<LLTeleportHistory> typedef boost::function<void()> history_callback_t; typedef boost::signals2::signal<void()> history_signal_t; - LLTeleportHistory(); - ~LLTeleportHistory(); - /** * Go back in the history. */ diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h index cf4c85a9910106a91c9f69be4cfe62dea049cb0a..946ac0af1aaed473bb4fd6e1adce22ae1a985708 100644 --- a/indra/newview/llteleporthistorystorage.h +++ b/indra/newview/llteleporthistorystorage.h @@ -68,6 +68,8 @@ class LLTeleportHistoryPersistentItem */ class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage> { + LLSINGLETON(LLTeleportHistoryStorage); + ~LLTeleportHistoryStorage(); LOG_CLASS(LLTeleportHistoryStorage); public: @@ -78,9 +80,6 @@ class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage> typedef boost::function<void(S32 removed_index)> history_callback_t; typedef boost::signals2::signal<void(S32 removed_index)> history_signal_t; - LLTeleportHistoryStorage(); - ~LLTeleportHistoryStorage(); - /** * @return history items. */ diff --git a/indra/newview/lltextureatlasmanager.h b/indra/newview/lltextureatlasmanager.h index b643056198d9a2278969a8461e25c7f50848ab7a..1b8df708c6299abfb79bdb42e6da5bb76f693fa7 100644 --- a/indra/newview/lltextureatlasmanager.h +++ b/indra/newview/lltextureatlasmanager.h @@ -85,12 +85,11 @@ class LLTextureAtlasSlot : public LLRefCount class LLTextureAtlasManager : public LLSingleton<LLTextureAtlasManager> { -private: + LLSINGLETON(LLTextureAtlasManager); + ~LLTextureAtlasManager(); typedef std::list<LLPointer<LLTextureAtlas> > ll_texture_atlas_list_t ; public: - LLTextureAtlasManager(); - ~LLTextureAtlasManager(); LLPointer<LLTextureAtlasSlot> reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, LLSpatialGroup* groupp, LLViewerTexture* imagep) ; diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 37cc908e8456dc09da792e873da5048c9afe7e24..a54127362114a837f96cc51ecfc565227cb09878 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -547,10 +547,18 @@ bool LLTextureCacheRemoteWorker::doWrite() // First state / stage : check that what we're trying to cache is in an OK shape if (mState == INIT) { - llassert_always(mOffset == 0); // We currently do not support write offsets - llassert_always(mDataSize > 0); // Things will go badly wrong if mDataSize is nul or negative... - llassert_always(mImageSize >= mDataSize); - mState = CACHE; + if ((mOffset != 0) // We currently do not support write offsets + || (mDataSize <= 0) // Things will go badly wrong if mDataSize is nul or negative... + || (mImageSize < mDataSize)) + { + LL_WARNS() << "INIT state check failed" << LL_ENDL; + mDataSize = -1; // failed + done = true; + } + else + { + mState = CACHE; + } } // No LOCAL state for write(): because it doesn't make much sense to cache a local file... @@ -559,7 +567,7 @@ bool LLTextureCacheRemoteWorker::doWrite() if (!done && (mState == CACHE)) { bool alreadyCached = false; - LLTextureCache::Entry entry ; + LLTextureCache::Entry entry; // Checks if this image is already in the entry list idx = mCache->getHeaderCacheEntry(mID, entry); @@ -571,107 +579,132 @@ bool LLTextureCacheRemoteWorker::doWrite() // (almost always) write to the fast cache. if (mRawImage->getDataSize()) { - llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel)); + if(!mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel)) + { + LL_WARNS() << "writeToFastCache failed" << LL_ENDL; + mDataSize = -1; // failed + done = true; + } + } } } - } else { alreadyCached = mCache->updateEntry(idx, entry, mImageSize, mDataSize); // update the existing entry. } - if (idx < 0) - { - LL_WARNS() << "LLTextureCacheWorker: " << mID - << " Unable to create header entry for writing!" << LL_ENDL; - mDataSize = -1; // failed - done = true; - } - else + if (!done) { - if (alreadyCached && (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE)) + if (idx < 0) { - // Small texture already cached case: we're done with writing + LL_WARNS() << "LLTextureCacheWorker: " << mID + << " Unable to create header entry for writing!" << LL_ENDL; + mDataSize = -1; // failed done = true; } else { - // If the texture has already been cached, we don't resave the header and go directly to the body part - mState = alreadyCached ? BODY : HEADER; + if (alreadyCached && (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE)) + { + // Small texture already cached case: we're done with writing + done = true; + } + else + { + // If the texture has already been cached, we don't resave the header and go directly to the body part + mState = alreadyCached ? BODY : HEADER; + } } } } + // Third stage / state : write the header record in the header file (texture.cache) if (!done && (mState == HEADER)) { - llassert_always(idx >= 0); // we need an entry here or storing the header makes no sense - S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE; // skip to the correct spot in the header file - S32 size = TEXTURE_CACHE_ENTRY_SIZE; // record size is fixed for the header - S32 bytes_written; - - if (mDataSize < TEXTURE_CACHE_ENTRY_SIZE) + if (idx < 0) // we need an entry here or storing the header makes no sense { - // We need to write a full record in the header cache so, if the amount of data is smaller - // than a record, we need to transfer the data to a buffer padded with 0 and write that - U8* padBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_CACHE_ENTRY_SIZE); - memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE); // Init with zeros - memcpy(padBuffer, mWriteData, mDataSize); // Copy the write buffer - bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool()); - FREE_MEM(LLImageBase::getPrivatePool(), padBuffer); + LL_WARNS() << "index check failed" << LL_ENDL; + mDataSize = -1; // failed + done = true; } else { - // Write the header record (== first TEXTURE_CACHE_ENTRY_SIZE bytes of the raw file) in the header file - bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size, mCache->getLocalAPRFilePool()); - } + S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE; // skip to the correct spot in the header file + S32 size = TEXTURE_CACHE_ENTRY_SIZE; // record size is fixed for the header + S32 bytes_written; - if (bytes_written <= 0) - { - LL_WARNS() << "LLTextureCacheWorker: " << mID + if (mDataSize < TEXTURE_CACHE_ENTRY_SIZE) + { + // We need to write a full record in the header cache so, if the amount of data is smaller + // than a record, we need to transfer the data to a buffer padded with 0 and write that + U8* padBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_CACHE_ENTRY_SIZE); + memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE); // Init with zeros + memcpy(padBuffer, mWriteData, mDataSize); // Copy the write buffer + bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool()); + FREE_MEM(LLImageBase::getPrivatePool(), padBuffer); + } + else + { + // Write the header record (== first TEXTURE_CACHE_ENTRY_SIZE bytes of the raw file) in the header file + bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size, mCache->getLocalAPRFilePool()); + } + + if (bytes_written <= 0) + { + LL_WARNS() << "LLTextureCacheWorker: " << mID << " Unable to write header entry!" << LL_ENDL; - mDataSize = -1; // failed - done = true; - } + mDataSize = -1; // failed + done = true; + } - // If we wrote everything (may be more with padding) in the header cache, - // we're done so we don't have a body to store - if (mDataSize <= bytes_written) - { - done = true; - } - else - { - mState = BODY; + // If we wrote everything (may be more with padding) in the header cache, + // we're done so we don't have a body to store + if (mDataSize <= bytes_written) + { + done = true; + } + else + { + mState = BODY; + } } } // Fourth stage / state : write the body file, i.e. the rest of the texture in a "UUID" file name if (!done && (mState == BODY)) { - llassert(mDataSize > TEXTURE_CACHE_ENTRY_SIZE); // wouldn't make sense to be here otherwise... - S32 file_size = mDataSize - TEXTURE_CACHE_ENTRY_SIZE; - + if (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE) // wouldn't make sense to be here otherwise... { - // build the cache file name from the UUID - std::string filename = mCache->getTextureFileName(mID); -// LL_INFOS() << "Writing Body: " << filename << " Bytes: " << file_offset+file_size << LL_ENDL; - S32 bytes_written = LLAPRFile::writeEx( filename, - mWriteData + TEXTURE_CACHE_ENTRY_SIZE, - 0, file_size, - mCache->getLocalAPRFilePool()); - if (bytes_written <= 0) + LL_WARNS() << "mDataSize check failed" << LL_ENDL; + mDataSize = -1; // failed + done = true; + } + else + { + S32 file_size = mDataSize - TEXTURE_CACHE_ENTRY_SIZE; + { - LL_WARNS() << "LLTextureCacheWorker: " << mID + // build the cache file name from the UUID + std::string filename = mCache->getTextureFileName(mID); + // LL_INFOS() << "Writing Body: " << filename << " Bytes: " << file_offset+file_size << LL_ENDL; + S32 bytes_written = LLAPRFile::writeEx(filename, + mWriteData + TEXTURE_CACHE_ENTRY_SIZE, + 0, file_size, + mCache->getLocalAPRFilePool()); + if (bytes_written <= 0) + { + LL_WARNS() << "LLTextureCacheWorker: " << mID << " incorrect number of bytes written to body: " << bytes_written << " / " << file_size << LL_ENDL; - mDataSize = -1; // failed - done = true; + mDataSize = -1; // failed + done = true; + } } + + // Nothing else to do at that point... + done = true; } - - // Nothing else to do at that point... - done = true; } mRawImage = NULL; @@ -1928,6 +1961,12 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis { //make a duplicate to keep the original raw image untouched. raw = raw->duplicate(); + if (raw->isBufferInvalid()) + { + LL_WARNS() << "Invalid image duplicate buffer" << LL_ENDL; + return false; + } + raw->scale(w, h) ; discardlevel += i ; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index e5aa740a33a73cb10f95ed35cbdd17089de3f5a0..c7adaa908f7e7a7b91573e63e9e78ef6e2456f7f 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -37,15 +37,12 @@ #include "llbutton.h" #include "lldraghandle.h" #include "llfocusmgr.h" -#include "llviewertexture.h" -#include "llfolderview.h" #include "llfolderviewmodel.h" #include "llinventory.h" #include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" -#include "llfloaterinventory.h" #include "lllineeditor.h" #include "llui.h" #include "llviewerinventory.h" @@ -71,6 +68,7 @@ #include "llradiogroup.h" #include "llfloaterreg.h" #include "lllocalbitmaps.h" +#include "llerror.h" static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f; static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f; @@ -82,118 +80,13 @@ static const S32 LOCAL_TRACKING_ID_COLUMN = 1; //static const char WHITE_IMAGE_NAME[] = "Blank Texture"; //static const char NO_IMAGE_NAME[] = "None"; -////////////////////////////////////////////////////////////////////////////////////////// -// LLFloaterTexturePicker - -class LLFloaterTexturePicker : public LLFloater -{ -public: - LLFloaterTexturePicker( - LLTextureCtrl* owner, - const std::string& label, - PermissionMask immediate_filter_perm_mask, - PermissionMask dnd_filter_perm_mask, - PermissionMask non_immediate_filter_perm_mask, - BOOL can_apply_immediately, - LLUIImagePtr fallback_image_name); - - 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 onClose(bool app_settings); - - // New functions - void setImageID( const LLUUID& image_asset_id, bool set_selection = true); - void updateImageStats(); - const LLUUID& getAssetID() { return mImageAssetID; } - const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only); - void setCanApplyImmediately(BOOL b); - - void setActive( BOOL active ); - - LLTextureCtrl* getOwner() const { return mOwner; } - void setOwner(LLTextureCtrl* owner) { mOwner = owner; } - - void stopUsingPipette(); - PermissionMask getFilterPermMask(); - void updateFilterPermMask(); - void commitIfImmediateSet(); - void commitCancel(); - - void onFilterEdit(const std::string& search_string ); - - void setCanApply(bool can_preview, bool can_apply); - void setTextureSelectedCallback(texture_selected_callback cb) {mTextureSelectedCallback = cb;} - - 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 ); - static void onBtnClear( void* userdata ); - void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); - static void onShowFolders(LLUICtrl* ctrl, void* userdata); - static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata); - void onTextureSelect( const LLTextureEntry& te ); - - 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); - -protected: - LLPointer<LLViewerTexture> mTexturep; - LLTextureCtrl* mOwner; - - LLUUID mImageAssetID; // Currently selected texture - LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null. - - 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; - - std::string mPendingName; - BOOL mActive; - - LLFilterEditor* mFilterEdit; - LLInventoryPanel* mInventoryPanel; - PermissionMask mImmediateFilterPermMask; - PermissionMask mDnDFilterPermMask; - PermissionMask mNonImmediateFilterPermMask; - BOOL mCanApplyImmediately; - BOOL mNoCopyTextureSelected; - F32 mContextConeOpacity; - LLSaveFolderState mSavedFolderState; - BOOL mSelectedItemPinned; - - LLRadioGroup* mModeSelector; - LLScrollListCtrl* mLocalScrollCtrl; - -private: - bool mCanApply; - bool mCanPreview; - bool mPreviewSettingChanged; - texture_selected_callback mTextureSelectedCallback; -}; - LLFloaterTexturePicker::LLFloaterTexturePicker( - LLTextureCtrl* owner, + 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, @@ -202,9 +95,13 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( LLUIImagePtr fallback_image) : LLFloater(LLSD()), mOwner( owner ), - mImageAssetID( owner->getImageAssetID() ), - mFallbackImage( fallback_image ), - mOriginalImageAssetID(owner->getImageAssetID()), + 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), @@ -217,7 +114,11 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mSelectedItemPinned( FALSE ), mCanApply(true), mCanPreview(true), - mPreviewSettingChanged(false) + mPreviewSettingChanged(false), + mOnFloaterCommitCallback(NULL), + mOnFloaterCloseCallback(NULL), + mSetImageAssetIDCallback(NULL), + mOnUpdateImageStatsCallback(NULL) { buildFromFile("floater_texture_ctrl.xml"); mCanApplyImmediately = can_apply_immediately; @@ -294,6 +195,10 @@ void LLFloaterTexturePicker::updateImageStats() { std::string formatted_dims = llformat("%d x %d", mTexturep->getFullWidth(),mTexturep->getFullHeight()); mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims); + if (mOnUpdateImageStatsCallback) + { + mOnUpdateImageStatsCallback(mTexturep); + } } else { @@ -400,9 +305,9 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask) void LLFloaterTexturePicker::onClose(bool app_quitting) { - if (mOwner) + if (mOwner && mOnFloaterCloseCallback) { - mOwner->onFloaterClose(); + mOnFloaterCloseCallback(); } stopUsingPipette(); } @@ -582,9 +487,9 @@ void LLFloaterTexturePicker::draw() mTentativeLabel->setVisible( FALSE ); } - getChildView("Default")->setEnabled(mImageAssetID != mOwner->getDefaultImageAssetID() || mOwner->getTentative()); - getChildView("Blank")->setEnabled(mImageAssetID != mOwner->getBlankImageAssetID() || mOwner->getTentative()); - getChildView("None")->setEnabled(mOwner->getAllowNoTexture() && (!mImageAssetID.isNull() || mOwner->getTentative())); + getChildView("Default")->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative); + getChildView("Blank")->setEnabled(mImageAssetID != mBlankImageAssetID || mTentative); + getChildView("None")->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative)); LLFloater::draw(); @@ -629,7 +534,7 @@ void LLFloaterTexturePicker::draw() } // Draw Tentative Label over the image - if( mOwner->getTentative() && !mViewModel->isDirty() ) + if( mTentative && !mViewModel->isDirty() ) { mTentativeLabel->setVisible( TRUE ); drawChild(mTentativeLabel); @@ -659,7 +564,7 @@ void LLFloaterTexturePicker::draw() } } -const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only) +const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library) { LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; @@ -679,7 +584,10 @@ const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL co LLPermissions item_permissions = itemp->getPermissions(); if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID())) { - return itemp->getUUID(); + if(!ignore_library || !gInventory.isObjectDescendentOf(itemp->getUUID(),gInventory.getLibraryRootFolderID())) + { + return itemp->getUUID(); + } } } // otherwise just return first instance, unless copyable requested @@ -689,7 +597,10 @@ const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL co } else { - return items[0]->getUUID(); + if(!ignore_library || !gInventory.isObjectDescendentOf(items[0]->getUUID(),gInventory.getLibraryRootFolderID())) + { + return items[0]->getUUID(); + } } } @@ -704,17 +615,17 @@ PermissionMask LLFloaterTexturePicker::getFilterPermMask() void LLFloaterTexturePicker::commitIfImmediateSet() { - if (!mNoCopyTextureSelected && mOwner && mCanApply) + if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply) { - mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE); + mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, LLUUID::null); } } void LLFloaterTexturePicker::commitCancel() { - if (!mNoCopyTextureSelected && mOwner && mCanApply) + if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply) { - mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL); + mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, LLUUID::null); } } @@ -725,7 +636,7 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata) self->setCanApply(true, true); if (self->mOwner) { - self->setImageID( self->mOwner->getDefaultImageAssetID() ); + self->setImageID( self->getDefaultImageAssetID() ); } self->commitIfImmediateSet(); } @@ -735,7 +646,7 @@ void LLFloaterTexturePicker::onBtnBlank(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; self->setCanApply(true, true); - self->setImageID( self->mOwner->getBlankImageAssetID() ); + self->setImageID( self->getBlankImageAssetID() ); self->commitIfImmediateSet(); } @@ -765,9 +676,9 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; self->setImageID( self->mOriginalImageAssetID ); - if (self->mOwner) + if (self->mOnFloaterCommitCallback) { - self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL); + self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, LLUUID::null); } self->mViewModel->resetDirty(); self->closeFloater(); @@ -777,17 +688,18 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata) void LLFloaterTexturePicker::onBtnSelect(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + LLUUID local_id = LLUUID::null; if (self->mOwner) { - LLUUID local_id = LLUUID::null; - if (self->mLocalScrollCtrl->getVisible() && !self->mLocalScrollCtrl->getAllSelected().empty()) { LLUUID temp_id = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID(); local_id = LLLocalBitmapMgr::getWorldID(temp_id); } - - self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT, local_id); + } + if (self->mOnFloaterCommitCallback) + { + self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_SELECT, local_id); } self->closeFloater(); } @@ -941,11 +853,17 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata) { LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN); LLUUID inworld_id = LLLocalBitmapMgr::getWorldID(tracking_id); - self->mOwner->setImageAssetID(inworld_id); + if (self->mSetImageAssetIDCallback) + { + self->mSetImageAssetIDCallback(inworld_id); + } if (self->childGetValue("apply_immediate_check").asBoolean()) { - self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE, inworld_id); + if (self->mOnFloaterCommitCallback) + { + self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, inworld_id); + } } } } @@ -1028,6 +946,11 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) mInventoryPanel->setFilterSubString(search_string); } +void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled) +{ + mModeSelector->setIndexEnabled(1,enabled); +} + void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) { LLUUID inventory_item_id = findItemID(te.getID(), TRUE); @@ -1238,13 +1161,17 @@ void LLTextureCtrl::showPicker(BOOL take_focus) { floaterp = new LLFloaterTexturePicker( this, + getImageAssetID(), + getDefaultImageAssetID(), + getBlankImageAssetID(), + getTentative(), + getAllowNoTexture(), mLabel, mImmediateFilterPermMask, mDnDFilterPermMask, mNonImmediateFilterPermMask, mCanApplyImmediately, mFallbackImage); - mFloaterHandle = floaterp->getHandle(); LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp); @@ -1252,6 +1179,18 @@ void LLTextureCtrl::showPicker(BOOL take_focus) { 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)); + } + if (texture_floaterp) + { + texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1)); + } LLFloater* root_floater = gFloaterView->getParentFloater(this); if (root_floater) @@ -1393,7 +1332,7 @@ void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb) void LLTextureCtrl::setImageAssetName(const std::string& name) { - LLPointer<LLUIImage> imagep = LLUI::getUIImage(name, LLGLTexture::BOOST_PREVIEW); + LLPointer<LLUIImage> imagep = LLUI::getUIImage(name); if(imagep) { LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get()); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 15ca7bed928ddb0b2e9fe4bf1de07468e783314b..840feddfaf151c7db37d73a3dcf2778411a18b35 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -29,12 +29,20 @@ #define LL_LLTEXTURECTRL_H #include "llcoord.h" +#include "llfiltereditor.h" #include "llfloater.h" +#include "llfolderview.h" +#include "lllocalbitmaps.h" #include "llstring.h" #include "lluictrl.h" #include "llpermissionsflags.h" +#include "llradiogroup.h" #include "lltextbox.h" // for params +#include "llviewerinventory.h" #include "llviewborder.h" // for params +#include "llviewerobject.h" +#include "llviewertexture.h" +#include "llwindow.h" class LLButton; class LLFloaterTexturePicker; @@ -166,7 +174,7 @@ class LLTextureCtrl void closeDependentFloater(); void onFloaterClose(); - void onFloaterCommit(ETexturePickOp op, LLUUID id = LLUUID::null); + void onFloaterCommit(ETexturePickOp op, LLUUID id); // This call is returned when a drag is detected. Your callback // should return TRUE if the drag is acceptable. @@ -227,4 +235,140 @@ class LLTextureCtrl S32 mLabelWidth; }; +////////////////////////////////////////////////////////////////////////////////////////// +// LLFloaterTexturePicker +typedef boost::function<void(LLTextureCtrl::ETexturePickOp op, LLUUID id)> floater_commit_callback; +typedef boost::function<void()> floater_close_callback; +typedef boost::function<void(const LLUUID& asset_id)> set_image_asset_id_callback; +typedef boost::function<void(LLPointer<LLViewerTexture> texture)> set_on_update_image_stats_callback; + +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, + PermissionMask non_immediate_filter_perm_mask, + BOOL can_apply_immediately, + LLUIImagePtr fallback_image_name + ); + + 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 onClose(bool app_settings); + + // New functions + void setImageID(const LLUUID& image_asset_id, bool set_selection = true); + void updateImageStats(); + 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(); + PermissionMask getFilterPermMask(); + + void updateFilterPermMask(); + void commitIfImmediateSet(); + void commitCancel(); + + void onFilterEdit(const std::string& search_string); + + void setCanApply(bool can_preview, bool can_apply); + 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); + static void onBtnClear(void* userdata); + void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); + static void onShowFolders(LLUICtrl* ctrl, void* userdata); + static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata); + void onTextureSelect(const LLTextureEntry& te); + + 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); + + void setLocalTextureEnabled(BOOL enabled); + +protected: + LLPointer<LLViewerTexture> mTexturep; + 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; + + std::string mPendingName; + BOOL mActive; + + LLFilterEditor* mFilterEdit; + LLInventoryPanel* mInventoryPanel; + PermissionMask mImmediateFilterPermMask; + PermissionMask mDnDFilterPermMask; + PermissionMask mNonImmediateFilterPermMask; + BOOL mCanApplyImmediately; + BOOL mNoCopyTextureSelected; + F32 mContextConeOpacity; + LLSaveFolderState mSavedFolderState; + BOOL mSelectedItemPinned; + + LLRadioGroup* mModeSelector; + LLScrollListCtrl* mLocalScrollCtrl; + +private: + bool mCanApply; + bool mCanPreview; + bool mPreviewSettingChanged; + + 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; +}; + #endif // LL_LLTEXTURECTRL_H diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 7020ac0c6598d3b4dd3f647fc92f367ca417ad8b..edde7c8076c0703dba2aa3dbf481f2566042ebd4 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -202,6 +202,21 @@ void LLToast::hide() } } +/*virtual*/ +void LLToast::setFocus(BOOL b) +{ + if (b && !hasFocus() && mPanel) + { + LLModalDialog::setFocus(TRUE); + // mostly for buttons + mPanel->setFocus(TRUE); + } + else + { + LLModalDialog::setFocus(b); + } +} + void LLToast::onFocusLost() { if(mWrapperPanel && !isBackgroundVisible()) diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index f02d7c2a1a99ea8f5247a5401a527d8067739b08..cd92189012de3b394ced1313c8021a42a3f9d8eb 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -150,6 +150,8 @@ class LLToast : public LLModalDialog, public LLInstanceTracker<LLToast> // virtual void hide(); + /*virtual*/ void setFocus(BOOL b); + /*virtual*/ void onFocusLost(); /*virtual*/ void onFocusReceived(); diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index f6ca0bc9d719d4bffbd1871e81afbe6be340b698..f7dc32d0d771cd28650beef6784a90de2a84f2e1 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -47,7 +47,6 @@ #include "llglheaders.h" #include "llagent.h" #include "llavatariconctrl.h" -#include "llfloaterinventory.h" #include "llinventorytype.h" const S32 LLToastGroupNotifyPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT = 7; diff --git a/indra/newview/lltoastscriptquestion.cpp b/indra/newview/lltoastscriptquestion.cpp index 91ba8c024777f65132303860936218e8a0f44c1f..7a3a1d8fd7971177116e23519820e70a2964c74a 100644 --- a/indra/newview/lltoastscriptquestion.cpp +++ b/indra/newview/lltoastscriptquestion.cpp @@ -54,6 +54,19 @@ BOOL LLToastScriptQuestion::postBuild() return TRUE; } + +// virtual +void LLToastScriptQuestion::setFocus(BOOL b) +{ + LLToastPanel::setFocus(b); + // toast can fade out and disappear with focus ON, so reset to default anyway + LLButton* dfbutton = getDefaultButton(); + if (dfbutton && dfbutton->getVisible() && dfbutton->getEnabled()) + { + dfbutton->setFocus(b); + } +} + void LLToastScriptQuestion::snapToMessageHeight() { LLTextBox* mMessage = getChild<LLTextBox>("top_info_message"); @@ -118,6 +131,12 @@ void LLToastScriptQuestion::createButtons() button->setRect(rect); buttons_width += rect.getWidth() + LEFT_PAD; + + if (form_element.has("default") && form_element["default"].asBoolean()) + { + button->setFocus(TRUE); + setDefaultBtn(button); + } } } } diff --git a/indra/newview/lltoastscriptquestion.h b/indra/newview/lltoastscriptquestion.h index 3a557f60f66dc70fde27f855117416ca4691c828..a756f88415ef5f7e89834ec18d19664097c8ee4f 100644 --- a/indra/newview/lltoastscriptquestion.h +++ b/indra/newview/lltoastscriptquestion.h @@ -39,6 +39,8 @@ class LLToastScriptQuestion : public LLToastPanel virtual BOOL postBuild(); virtual ~LLToastScriptQuestion(){}; + /*virtual*/ void setFocus(BOOL b); + private: void snapToMessageHeight(); diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp index 5e703933caf2e2e75c98f76776d65810606dee7b..4aad650b680b44aab4bd28e53f1ec9e36e57fa52 100644 --- a/indra/newview/lltool.cpp +++ b/indra/newview/lltool.cpp @@ -38,7 +38,6 @@ #include "lltoolfocus.h" #include "llfocusmgr.h" #include "llagent.h" -#include "llagentcamera.h" #include "llviewerjoystick.h" extern BOOL gDebugClicks; @@ -85,14 +84,7 @@ BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask) } // by default, didn't handle it // LL_INFOS() << "LLTool::handleMouseDown" << LL_ENDL; - if (gAgentCamera.cameraMouselook()) - { - gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); - } - else - { - gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); - } + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); return TRUE; } @@ -103,15 +95,8 @@ BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask) LL_INFOS() << "LLTool left mouse up" << LL_ENDL; } // by default, didn't handle it - // LL_INFOS() << "LLTool::handleMouseUp" << LL_ENDL; - if (gAgentCamera.cameraMouselook()) - { - gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); - } - else - { - gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); - } + // LL_INFOS() << "LLTool::handleMouseUp" << LL_ENDL; + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); return TRUE; } diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index fd950864aa9c9fb340b09b0ad3bb134dc91e7634..01d799dcd50d62415c521a23ab9532cf81ccfbf2 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -283,7 +283,7 @@ bool LLToolBarView::loadToolbars(bool force_default) } BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.left_toolbar.commands) { - if (addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_LEFT])) + if (!addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_LEFT])) { LL_WARNS() << "Error adding command '" << command_params.name() << "' to left toolbar." << LL_ENDL; } @@ -298,7 +298,7 @@ bool LLToolBarView::loadToolbars(bool force_default) } BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.right_toolbar.commands) { - if (addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_RIGHT])) + if (!addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_RIGHT])) { LL_WARNS() << "Error adding command '" << command_params.name() << "' to right toolbar." << LL_ENDL; } @@ -313,7 +313,7 @@ bool LLToolBarView::loadToolbars(bool force_default) } BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.bottom_toolbar.commands) { - if (addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM])) + if (!addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM])) { LL_WARNS() << "Error adding command '" << command_params.name() << "' to bottom toolbar." << LL_ENDL; } diff --git a/indra/newview/lltoolbrush.h b/indra/newview/lltoolbrush.h index 2ec6911de91e4520a1b461f6e3347d8009decf3d..c108d8325681b0f54317f5d5899f05444bcb5ae7 100644 --- a/indra/newview/lltoolbrush.h +++ b/indra/newview/lltoolbrush.h @@ -43,10 +43,10 @@ class LLViewerRegion; class LLToolBrushLand : public LLTool, public LLEditMenuHandler, public LLSingleton<LLToolBrushLand> { + LLSINGLETON(LLToolBrushLand); typedef std::set<LLViewerRegion*> region_list_t; public: - LLToolBrushLand(); // x,y in window coords, 0,0 = left,bot virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 2b4fa757f671e96c3dbf183400f2650c6361b9ca..392c103d7c2021ddcedc832c205ed7aa85d7c6e1 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -683,7 +683,7 @@ LLToolCompGun::LLToolCompGun() : LLToolComposite(std::string("Mouselook")) { mGun = new LLToolGun(this); - mGrab = new LLToolGrab(this); + mGrab = new LLToolGrabBase(this); mNull = sNullTool; setCurrentTool(mGun); @@ -742,13 +742,12 @@ BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask) BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask) { - // if the left button is blocked, don't put up the pie menu - if (gAgent.leftButtonBlocked()) - { - // in case of "grabbed" control flag will be set later - gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); - return FALSE; - } + // if the left button is grabbed, don't put up the pie menu + if (gAgent.leftButtonGrabbed()) + { + gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); + return FALSE; + } // On mousedown, start grabbing gGrabTransientTool = this; @@ -760,13 +759,12 @@ BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask) { - // if the left button is blocked, don't put up the pie menu - if (gAgent.leftButtonBlocked()) - { - // in case of "grabbed" control flag will be set later - gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); - return FALSE; - } + // if the left button is grabbed, don't put up the pie menu + if (gAgent.leftButtonGrabbed()) + { + gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); + return FALSE; + } // On mousedown, start grabbing gGrabTransientTool = this; diff --git a/indra/newview/lltoolcomp.h b/indra/newview/lltoolcomp.h index e75d3c22e28fb116af78f1106518b8601a57468f..86506f725ef4a93fa3563955759efa453589bd6c 100644 --- a/indra/newview/lltoolcomp.h +++ b/indra/newview/lltoolcomp.h @@ -103,9 +103,9 @@ class LLToolComposite : public LLTool class LLToolCompInspect : public LLToolComposite, public LLSingleton<LLToolCompInspect> { -public: - LLToolCompInspect(); + LLSINGLETON(LLToolCompInspect); virtual ~LLToolCompInspect(); +public: // Overridden from LLToolComposite virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -128,9 +128,9 @@ class LLToolCompInspect : public LLToolComposite, public LLSingleton<LLToolCompI class LLToolCompTranslate : public LLToolComposite, public LLSingleton<LLToolCompTranslate> { -public: - LLToolCompTranslate(); + LLSINGLETON(LLToolCompTranslate); virtual ~LLToolCompTranslate(); +public: // Overridden from LLToolComposite virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -149,9 +149,9 @@ class LLToolCompTranslate : public LLToolComposite, public LLSingleton<LLToolCom class LLToolCompScale : public LLToolComposite, public LLSingleton<LLToolCompScale> { -public: - LLToolCompScale(); + LLSINGLETON(LLToolCompScale); virtual ~LLToolCompScale(); +public: // Overridden from LLToolComposite virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -171,9 +171,9 @@ class LLToolCompScale : public LLToolComposite, public LLSingleton<LLToolCompSca class LLToolCompRotate : public LLToolComposite, public LLSingleton<LLToolCompRotate> { -public: - LLToolCompRotate(); + LLSINGLETON(LLToolCompRotate); virtual ~LLToolCompRotate(); +public: // Overridden from LLToolComposite virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -194,9 +194,9 @@ class LLToolCompRotate : public LLToolComposite, public LLSingleton<LLToolCompRo class LLToolCompCreate : public LLToolComposite, public LLSingleton<LLToolCompCreate> { -public: - LLToolCompCreate(); + LLSINGLETON(LLToolCompCreate); virtual ~LLToolCompCreate(); +public: // Overridden from LLToolComposite virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -214,14 +214,14 @@ class LLToolCompCreate : public LLToolComposite, public LLSingleton<LLToolCompCr // LLToolCompGun class LLToolGun; -class LLToolGrab; +class LLToolGrabBase; class LLToolSelect; class LLToolCompGun : public LLToolComposite, public LLSingleton<LLToolCompGun> { -public: - LLToolCompGun(); + LLSINGLETON(LLToolCompGun); virtual ~LLToolCompGun(); +public: // Overridden from LLToolComposite virtual BOOL handleHover(S32 x, S32 y, MASK mask); @@ -237,7 +237,7 @@ class LLToolCompGun : public LLToolComposite, public LLSingleton<LLToolCompGun> protected: LLToolGun* mGun; - LLToolGrab* mGrab; + LLToolGrabBase* mGrab; LLTool* mNull; }; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 98586e3b3d9eddcde581dad6b99d499209106e30..27c4c9085752400890e5ab5c5d118dba5a64ba43 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -223,66 +223,6 @@ void LLCategoryDropObserver::done() } delete this; } -/* Doesn't seem to be used anymore. -class LLCategoryDropDescendentsObserver : public LLInventoryFetchDescendentsObserver -{ -public: - LLCategoryDropDescendentsObserver( - const LLUUID& obj_id, LLToolDragAndDrop::ESource src) : - mObjectID(obj_id), - mSource(src) - {} - ~LLCategoryDropDescendentsObserver() {} - virtual void done(); - -protected: - LLUUID mObjectID; - LLToolDragAndDrop::ESource mSource; -}; - -void LLCategoryDropDescendentsObserver::done() -{ - - gInventory.removeObserver(this); - uuid_vec_t::iterator it = mComplete.begin(); - uuid_vec_t::iterator end = mComplete.end(); - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - for(; it != end; ++it) - { - gInventory.collectDescendents( - (*it), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH); - } - - S32 count = items.size(); - if (count) - { - std::set<LLUUID> unique_ids; - for(S32 i = 0; i < count; ++i) - { - unique_ids.insert(items.get(i)->getUUID()); - } - uuid_vec_t ids; - std::back_insert_iterator<uuid_vec_t> copier(ids); - std::copy(unique_ids.begin(), unique_ids.end(), copier); - LLCategoryDropObserver* dropper; - dropper = new LLCategoryDropObserver(ids, mObjectID, mSource); - dropper->startFetch(); - if (dropper->isDone()) - { - dropper->done(); - } - else - { - gInventory.addObserver(dropper); - } - } - delete this; -} -*/ S32 LLToolDragAndDrop::sOperationId = 0; diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 63be1ef09b2b94beb88421c02d152139540f7b6b..766046785b6cd13ac7e0ddc0d45a4528faeb6f7a 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -43,11 +43,10 @@ class LLPickInfo; class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop> { + LLSINGLETON(LLToolDragAndDrop); public: typedef boost::signals2::signal<void ()> enddrag_signal_t; - LLToolDragAndDrop(); - // overridden from LLTool virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); @@ -281,8 +280,8 @@ class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop> class LLDragAndDropDictionary : public LLSingleton<LLDragAndDropDictionary>, public LLDictionary<EDragAndDropType, DragAndDropEntry> { + LLSINGLETON(LLDragAndDropDictionary); public: - LLDragAndDropDictionary(); dragOrDrop3dImpl get(EDragAndDropType dad_type, EDropTarget drop_target); }; }; diff --git a/indra/newview/lltoolface.h b/indra/newview/lltoolface.h index 7eb13b0fbcf2c4edf6a9969e7a20eb12ade009c2..e4b8ae12b87d4a62e95e727feee1527acc97b149 100644 --- a/indra/newview/lltoolface.h +++ b/indra/newview/lltoolface.h @@ -35,9 +35,9 @@ class LLPickInfo; class LLToolFace : public LLTool, public LLSingleton<LLToolFace> { -public: - LLToolFace(); + LLSINGLETON(LLToolFace); virtual ~LLToolFace(); +public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index c4696c3a01208eb7e4f55eefe64178ea0f28db48..caa055e5e08c9dfe19637dcb3103a1425f5adc4d 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -223,6 +223,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info) } if (!(pick_info.mKeyMask & MASK_ALT) && + !LLFloaterCamera::inFreeCameraMode() && gAgentCamera.cameraThirdPerson() && gViewerWindow->getLeftMouseDown() && !gSavedSettings.getBOOL("FreezeTime") && diff --git a/indra/newview/lltoolfocus.h b/indra/newview/lltoolfocus.h index d23eb2cce63196a4b92a6a877df0539912f4298b..cfc235b6c2a411fba999d95e0de805f7fb13b532 100644 --- a/indra/newview/lltoolfocus.h +++ b/indra/newview/lltoolfocus.h @@ -34,9 +34,9 @@ class LLPickInfo; class LLToolCamera : public LLTool, public LLSingleton<LLToolCamera> { -public: - LLToolCamera(); + LLSINGLETON(LLToolCamera); virtual ~LLToolCamera(); +public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index c0ca4d7a9a4737fa316e3622e3f5cbf577f124b6..5623036b91c95dcf9028f2c9b59aa3ffaeec8456 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -69,7 +69,7 @@ extern BOOL gDebugClicks; // // Methods // -LLToolGrab::LLToolGrab( LLToolComposite* composite ) +LLToolGrabBase::LLToolGrabBase( LLToolComposite* composite ) : LLTool( std::string("Grab"), composite ), mMode( GRAB_INACTIVE ), mVerticalDragging( FALSE ), @@ -88,12 +88,12 @@ LLToolGrab::LLToolGrab( LLToolComposite* composite ) mHideBuildHighlight(FALSE) { } -LLToolGrab::~LLToolGrab() +LLToolGrabBase::~LLToolGrabBase() { } // virtual -void LLToolGrab::handleSelect() +void LLToolGrabBase::handleSelect() { if(gFloaterTools) { @@ -106,7 +106,7 @@ void LLToolGrab::handleSelect() gGrabBtnSpin = FALSE; } -void LLToolGrab::handleDeselect() +void LLToolGrabBase::handleDeselect() { if( hasMouseCapture() ) { @@ -123,7 +123,7 @@ void LLToolGrab::handleDeselect() } -BOOL LLToolGrab::handleDoubleClick(S32 x, S32 y, MASK mask) +BOOL LLToolGrabBase::handleDoubleClick(S32 x, S32 y, MASK mask) { if (gDebugClicks) { @@ -133,7 +133,7 @@ BOOL LLToolGrab::handleDoubleClick(S32 x, S32 y, MASK mask) return FALSE; } -BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask) +BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask) { if (gDebugClicks) { @@ -143,7 +143,7 @@ BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask) // call the base class to propogate info to sim LLTool::handleMouseDown(x, y, mask); - if (!gAgent.leftButtonBlocked()) + if (!gAgent.leftButtonGrabbed()) { // can grab transparent objects (how touch event propagates, scripters rely on this) gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE); @@ -152,7 +152,7 @@ BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask) return TRUE; } -void LLToolGrab::pickCallback(const LLPickInfo& pick_info) +void LLToolGrabBase::pickCallback(const LLPickInfo& pick_info) { LLToolGrab::getInstance()->mGrabPick = pick_info; LLViewerObject *objectp = pick_info.getObject(); @@ -182,7 +182,7 @@ void LLToolGrab::pickCallback(const LLPickInfo& pick_info) } } -BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info) +BOOL LLToolGrabBase::handleObjectHit(const LLPickInfo& info) { mGrabPick = info; LLViewerObject* objectp = mGrabPick.getObject(); @@ -315,7 +315,7 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info) } -void LLToolGrab::startSpin() +void LLToolGrabBase::startSpin() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) @@ -339,7 +339,7 @@ void LLToolGrab::startSpin() } -void LLToolGrab::stopSpin() +void LLToolGrabBase::stopSpin() { mSpinGrabbing = FALSE; @@ -373,7 +373,7 @@ void LLToolGrab::stopSpin() } -void LLToolGrab::startGrab() +void LLToolGrabBase::startGrab() { // Compute grab_offset in the OBJECT's root's coordinate frame // (sometimes root == object) @@ -422,7 +422,7 @@ void LLToolGrab::startGrab() } -BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask) +BOOL LLToolGrabBase::handleHover(S32 x, S32 y, MASK mask) { if (!gViewerWindow->getLeftMouseDown()) { @@ -466,7 +466,7 @@ const F32 GRAB_SENSITIVITY_Y = 0.0075f; // Dragging. -void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) +void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask) { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp || !hasMouseCapture() ) return; @@ -724,7 +724,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) } -void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask) +void LLToolGrabBase::handleHoverNonPhysical(S32 x, S32 y, MASK mask) { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp || !hasMouseCapture() ) return; @@ -881,7 +881,7 @@ void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask) // Not dragging. Just showing affordances -void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask) +void LLToolGrabBase::handleHoverInactive(S32 x, S32 y, MASK mask) { // JC - TODO - change cursor based on gGrabBtnVertical, gGrabBtnSpin LL_DEBUGS("UserInput") << "hover handled by LLToolGrab (inactive-not over editable object)" << LL_ENDL; @@ -889,7 +889,7 @@ void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask) } // User is trying to do something that's not allowed. -void LLToolGrab::handleHoverFailed(S32 x, S32 y, MASK mask) +void LLToolGrabBase::handleHoverFailed(S32 x, S32 y, MASK mask) { if( GRAB_NOOBJECT == mMode ) { @@ -930,7 +930,7 @@ void LLToolGrab::handleHoverFailed(S32 x, S32 y, MASK mask) -BOOL LLToolGrab::handleMouseUp(S32 x, S32 y, MASK mask) +BOOL LLToolGrabBase::handleMouseUp(S32 x, S32 y, MASK mask) { // call the base class to propogate info to sim LLTool::handleMouseUp(x, y, mask); @@ -961,7 +961,7 @@ BOOL LLToolGrab::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } -void LLToolGrab::stopEditing() +void LLToolGrabBase::stopEditing() { if( hasMouseCapture() ) { @@ -969,7 +969,7 @@ void LLToolGrab::stopEditing() } } -void LLToolGrab::onMouseCaptureLost() +void LLToolGrabBase::onMouseCaptureLost() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) @@ -1026,7 +1026,7 @@ void LLToolGrab::onMouseCaptureLost() } -void LLToolGrab::stopGrab() +void LLToolGrabBase::stopGrab() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) @@ -1067,29 +1067,29 @@ void LLToolGrab::stopGrab() } -void LLToolGrab::draw() +void LLToolGrabBase::draw() { } -void LLToolGrab::render() +void LLToolGrabBase::render() { } -BOOL LLToolGrab::isEditing() +BOOL LLToolGrabBase::isEditing() { return (mGrabPick.getObject().notNull()); } -LLViewerObject* LLToolGrab::getEditingObject() +LLViewerObject* LLToolGrabBase::getEditingObject() { return mGrabPick.getObject(); } -LLVector3d LLToolGrab::getEditingPointGlobal() +LLVector3d LLToolGrabBase::getEditingPointGlobal() { return getGrabPointGlobal(); } -LLVector3d LLToolGrab::getGrabPointGlobal() +LLVector3d LLToolGrabBase::getGrabPointGlobal() { switch(mMode) { diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h index 5d24c8813e4dcfef52c968aacf2ab91e909a1d13..02ed5c26d752c9ffb3eeddaf0cf73ca7002a8f1f 100644 --- a/indra/newview/lltoolgrab.h +++ b/indra/newview/lltoolgrab.h @@ -45,12 +45,17 @@ void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, co void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick); - -class LLToolGrab : public LLTool, public LLSingleton<LLToolGrab> +/** + * LLToolGrabBase contains most of the semantics of LLToolGrab. It's just that + * LLToolGrab is an LLSingleton, but we also explicitly instantiate + * LLToolGrabBase as part of LLToolCompGun. You can't just make an extra + * instance of an LLSingleton! + */ +class LLToolGrabBase : public LLTool { public: - LLToolGrab( LLToolComposite* composite = NULL ); - ~LLToolGrab(); + LLToolGrabBase(LLToolComposite* composite=NULL); + ~LLToolGrabBase(); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -140,10 +145,14 @@ class LLToolGrab : public LLTool, public LLSingleton<LLToolGrab> BOOL mClickedInMouselook; }; +/// This is the LLSingleton instance of LLToolGrab. +class LLToolGrab : public LLToolGrabBase, public LLSingleton<LLToolGrab> +{ + LLSINGLETON_EMPTY_CTOR(LLToolGrab); +}; + extern BOOL gGrabBtnVertical; extern BOOL gGrabBtnSpin; extern LLTool* gGrabTransientTool; #endif // LL_TOOLGRAB_H - - diff --git a/indra/newview/lltoolindividual.h b/indra/newview/lltoolindividual.h index 961a6a4d93d4c49f27f717acca790363dd8012c0..e7c2060fba01909da6a84bc444dc7f03d9e256bf 100644 --- a/indra/newview/lltoolindividual.h +++ b/indra/newview/lltoolindividual.h @@ -39,9 +39,9 @@ class LLPickInfo; class LLToolIndividual : public LLTool, public LLSingleton<LLToolIndividual> { -public: - LLToolIndividual(); + LLSINGLETON(LLToolIndividual); virtual ~LLToolIndividual(); +public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index b0e3b5bf898b2944c8a0a575c16b397596feea13..f6eb290bc34660297224b132b9b6189440e1e294 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -267,7 +267,7 @@ bool LLToolMgr::canEdit() bool LLToolMgr::buildEnabledOrActive() { - return inEdit() || canEdit(); + return LLFloaterReg::instanceVisible("build") || canEdit(); } void LLToolMgr::toggleBuildMode(const LLSD& sdname) diff --git a/indra/newview/lltoolmgr.h b/indra/newview/lltoolmgr.h index e5b45750d900f6fb2eebe1faea562f736f0748ea..28465d5d2cd1e83de8cbe1829bfd840822413fe9 100644 --- a/indra/newview/lltoolmgr.h +++ b/indra/newview/lltoolmgr.h @@ -42,9 +42,9 @@ const MASK MASK_COPY = MASK_SHIFT; class LLToolMgr : public LLSingleton<LLToolMgr> { -public: - LLToolMgr(); + LLSINGLETON(LLToolMgr); ~LLToolMgr(); +public: // Must be called after gSavedSettings set up. void initTools(); diff --git a/indra/newview/lltoolobjpicker.h b/indra/newview/lltoolobjpicker.h index 0c37be1f92471fbb87d0203b1b57d923b06b62e7..5ad9b67e217859e85709603b33b0ea29b775e53b 100644 --- a/indra/newview/lltoolobjpicker.h +++ b/indra/newview/lltoolobjpicker.h @@ -35,8 +35,8 @@ class LLPickInfo; class LLToolObjPicker : public LLTool, public LLSingleton<LLToolObjPicker> { + LLSINGLETON(LLToolObjPicker); public: - LLToolObjPicker(); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index 6391e675c551a7c7ffbf846097adbea8034a8352..95d155a474a4ea1005df415b3784524794bfb906 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -37,9 +37,9 @@ class LLObjectSelection; class LLToolPie : public LLTool, public LLSingleton<LLToolPie> { + LLSINGLETON(LLToolPie); LOG_CLASS(LLToolPie); public: - LLToolPie( ); // Virtual functions inherited from LLMouseHandler virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down); diff --git a/indra/newview/lltoolpipette.h b/indra/newview/lltoolpipette.h index 8a83bf31af641534257bcc459aeb94940d2d2608..7575d8ad18454b60ad66451af839338b4efdc6d0 100644 --- a/indra/newview/lltoolpipette.h +++ b/indra/newview/lltoolpipette.h @@ -43,10 +43,10 @@ class LLPickInfo; class LLToolPipette : public LLTool, public LLSingleton<LLToolPipette> { -public: - LLToolPipette(); + LLSINGLETON(LLToolPipette); virtual ~LLToolPipette(); +public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolselectland.h b/indra/newview/lltoolselectland.h index b368a4b1533e8f69d2ad2afd797724f9615c3950..b5ba72f16d5d0073e3bcb6127cf12c136b1352c4 100644 --- a/indra/newview/lltoolselectland.h +++ b/indra/newview/lltoolselectland.h @@ -35,10 +35,10 @@ class LLParcelSelection; class LLToolSelectLand : public LLTool, public LLSingleton<LLToolSelectLand> { -public: - LLToolSelectLand( ); + LLSINGLETON(LLToolSelectLand); virtual ~LLToolSelectLand(); +public: /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index b015cde45d699f75d62f78d4ea4dfefc7909181d..2ec5c41b8862ca77dc0841edc9f8eeb80d5ab771 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -100,9 +100,8 @@ LLTracker::~LLTracker() // static -void LLTracker::stopTracking(void* userdata) +void LLTracker::stopTracking(bool clear_ui) { - BOOL clear_ui = ((BOOL)(intptr_t)userdata); instance()->stopTrackingAll(clear_ui); } @@ -183,7 +182,7 @@ void LLTracker::render3D() F32 dist = gFloaterWorldMap->getDistanceToDestination(pos_global, 0.5f); if (dist < DESTINATION_REACHED_RADIUS) { - instance()->stopTrackingLocation(FALSE,TRUE); + instance()->stopTrackingLocation(false,true); } else { @@ -606,7 +605,7 @@ void LLTracker::renderBeacon(LLVector3d pos_global, } -void LLTracker::stopTrackingAll(BOOL clear_ui) +void LLTracker::stopTrackingAll(bool clear_ui) { switch (mTrackingStatus) { @@ -626,7 +625,7 @@ void LLTracker::stopTrackingAll(BOOL clear_ui) } -void LLTracker::stopTrackingAvatar(BOOL clear_ui) +void LLTracker::stopTrackingAvatar(bool clear_ui) { LLAvatarTracker& av_tracker = LLAvatarTracker::instance(); if( !av_tracker.getAvatarID().isNull() ) @@ -640,7 +639,7 @@ void LLTracker::stopTrackingAvatar(BOOL clear_ui) } -void LLTracker::stopTrackingLandmark(BOOL clear_ui) +void LLTracker::stopTrackingLandmark(bool clear_ui) { purgeBeaconText(); mTrackedLandmarkAssetID.setNull(); @@ -655,7 +654,7 @@ void LLTracker::stopTrackingLandmark(BOOL clear_ui) } -void LLTracker::stopTrackingLocation(BOOL clear_ui, BOOL dest_reached) +void LLTracker::stopTrackingLocation(bool clear_ui, bool dest_reached) { purgeBeaconText(); mTrackedLocationName.assign(""); diff --git a/indra/newview/lltracker.h b/indra/newview/lltracker.h index a1c5052c1b85a157c8b8a32e6bd456ba0833719f..4a6f10b767dda24893c8d494501227fec2f9137b 100644 --- a/indra/newview/lltracker.h +++ b/indra/newview/lltracker.h @@ -74,8 +74,8 @@ class LLTracker // these are static so that they can be used a callbacks static ETrackingStatus getTrackingStatus() { return instance()->mTrackingStatus; } static ETrackingLocationType getTrackedLocationType() { return instance()->mTrackingLocationType; } - static BOOL isTracking(void*) { return instance()->mTrackingStatus != TRACKING_NOTHING; } - static void stopTracking(void*); + static bool isTracking(void*) { return instance()->mTrackingStatus != TRACKING_NOTHING; } + static void stopTracking(bool); static void clearFocus(); static const LLUUID& getTrackedLandmarkAssetID() { return instance()->mTrackedLandmarkAssetID; } @@ -114,10 +114,10 @@ class LLTracker LLHUDText* hud_textp, const std::string& label ); - void stopTrackingAll(BOOL clear_ui = FALSE); - void stopTrackingAvatar(BOOL clear_ui = FALSE); - void stopTrackingLocation(BOOL clear_ui = FALSE, BOOL dest_reached = FALSE); - void stopTrackingLandmark(BOOL clear_ui = FALSE); + void stopTrackingAll(bool clear_ui = false); + void stopTrackingAvatar(bool clear_ui = false); + void stopTrackingLocation(bool clear_ui = false, bool dest_reached = false); + void stopTrackingLandmark(bool clear_ui = false); void drawMarker(const LLVector3d& pos_global, const LLColor4& color); void setLandmarkVisited(); diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h index b4611c8c87bb4d2954938fba16110e08d9c72a06..d126543f1535b9cec4128121c1ff500d954c428e 100644 --- a/indra/newview/lltransientfloatermgr.h +++ b/indra/newview/lltransientfloatermgr.h @@ -38,9 +38,7 @@ class LLTransientFloater; */ class LLTransientFloaterMgr: public LLSingleton<LLTransientFloaterMgr> { -protected: - LLTransientFloaterMgr(); - friend class LLSingleton<LLTransientFloaterMgr>; + LLSINGLETON(LLTransientFloaterMgr); public: enum ETransientGroup diff --git a/indra/newview/lltwitterconnect.h b/indra/newview/lltwitterconnect.h index be481a17c10b9f4e27f97dea1cd8c79145f2150f..e77048cc35112390873121dd5dd4e2797ff8e674 100644 --- a/indra/newview/lltwitterconnect.h +++ b/indra/newview/lltwitterconnect.h @@ -43,6 +43,7 @@ class LLEventPump; */ class LLTwitterConnect : public LLSingleton<LLTwitterConnect> { + LLSINGLETON(LLTwitterConnect); LOG_CLASS(LLTwitterConnect); public: enum EConnectionState @@ -81,10 +82,7 @@ class LLTwitterConnect : public LLSingleton<LLTwitterConnect> void openTwitterWeb(std::string url); private: - friend class LLSingleton<LLTwitterConnect>; - LLTwitterConnect(); - ~LLTwitterConnect() {}; std::string getTwitterConnectURL(const std::string& route = "", bool include_read_from_master = false); EConnectionState mConnectionState; diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index a0ca91672aa357f9743dba9cc0f58a4d58f06a11..375dce485d71b2eec8c332f686a689ecb4bb4b9d 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -99,10 +99,16 @@ const std::string &LLVersionInfo::getShortVersion() namespace { + // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The + // macro expands to the string name of the channel, but without quotes. We + // need to turn it into a quoted string. This macro trick does that. +#define stringize_inner(x) #x +#define stringize_outer(x) stringize_inner(x) + /// Storage of the channel name the viewer is using. // The channel name is set by hardcoded constant, // or by calling LLVersionInfo::resetChannel() - std::string sWorkingChannelName(LL_VIEWER_CHANNEL); + std::string sWorkingChannelName(stringize_outer(LL_VIEWER_CHANNEL)); // Storage for the "version and channel" string. // This will get reset too. diff --git a/indra/newview/llviewchildren.cpp b/indra/newview/llviewchildren.cpp index 5c5bbdc8f589ab25809a89efb95bf9e8e724bf59..32b2f7e9f5b8cf382efd13f41f824f5c95fec178 100644 --- a/indra/newview/llviewchildren.cpp +++ b/indra/newview/llviewchildren.cpp @@ -79,8 +79,9 @@ void LLViewChildren::setBadge(const std::string& id, Badge badge, bool visible) default: case BADGE_OK: child->setValue(std::string("badge_ok.j2c")); break; case BADGE_NOTE: child->setValue(std::string("badge_note.j2c")); break; - case BADGE_WARN: child->setValue(std::string("badge_warn.j2c")); break; - case BADGE_ERROR: child->setValue(std::string("badge_error.j2c")); break; + case BADGE_WARN: + case BADGE_ERROR: + child->setValue(std::string("badge_warn.j2c")); break; } } } diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp index 08ba5a5f252cebade2b4399a5fda49e2a0f332c5..ad0c1734f9fd132b12eb91f39e5434d5cefdf06f 100644 --- a/indra/newview/llviewerassettype.cpp +++ b/indra/newview/llviewerassettype.cpp @@ -48,8 +48,7 @@ struct ViewerAssetEntry : public LLDictionaryEntry class LLViewerAssetDictionary : public LLSingleton<LLViewerAssetDictionary>, public LLDictionary<LLViewerAssetType::EType, ViewerAssetEntry> { -public: - LLViewerAssetDictionary(); + LLSINGLETON(LLViewerAssetDictionary); }; LLViewerAssetDictionary::LLViewerAssetDictionary() diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 497ff4d2bfe95f068ea371388c6da7eee54c7488..cafaf8645a391dd621e17dbf3e4dd2d494c5a6bd 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -174,7 +174,7 @@ S32 LLResourceUploadInfo::getEconomyUploadCost() getAssetType() == LLAssetType::AT_ANIMATION || getAssetType() == LLAssetType::AT_MESH) { - return LLGlobalEconomy::Singleton::instance().getPriceUpload(); + return LLGlobalEconomy::instance().getPriceUpload(); } return 0; @@ -779,12 +779,17 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti if (uploadInfo->showUploadDialog()) LLUploadDialog::modalUploadFinished(); - // Let the Snapshot floater know we have finished uploading a snapshot to inventory. + // Let the Snapshot floater know we have finished uploading a snapshot to inventory LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot"); - if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot) + if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot && floater_snapshot->isShown()) { floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory"))); } + LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot"); + if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown()) + { + floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory"))); + } } //========================================================================= @@ -819,8 +824,15 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res } LLSD args; - args["FILE"] = uploadInfo->getDisplayName(); - args["REASON"] = reason; + if(label == "ErrorMessage") + { + args["ERROR_MESSAGE"] = reason; + } + else + { + args["FILE"] = uploadInfo->getDisplayName(); + args["REASON"] = reason; + } LLNotificationsUtil::add(label, args); @@ -839,10 +851,14 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res // Let the Snapshot floater know we have failed uploading. LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot"); - if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot) + if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot && floater_snapshot->isShown()) { floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory"))); } - + LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot"); + if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown()) + { + floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory"))); + } } diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h index 8c302c65492456033c91401557c2474472321be9..16f9b63113d88699a0ffb8d74fe459decc9e8366 100644 --- a/indra/newview/llvieweraudio.h +++ b/indra/newview/llvieweraudio.h @@ -43,6 +43,9 @@ void audio_update_wind(bool force_update = true); class LLViewerAudio : public LLSingleton<LLViewerAudio> { + LLSINGLETON(LLViewerAudio); + virtual ~LLViewerAudio(); + public: enum EFadeState @@ -52,9 +55,6 @@ class LLViewerAudio : public LLSingleton<LLViewerAudio> FADE_OUT, }; - LLViewerAudio(); - virtual ~LLViewerAudio(); - void startInternetStreamWithAutoFade(std::string streamURI); void stopInternetStreamWithAutoFade(); diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index 7b2887d725b5458979a437725676bc5b6d824890..f8c973690a08aff2a3d26111348da4a931beb3ba 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -54,6 +54,7 @@ extern template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInst LL_ALIGN_PREFIX(16) class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera> { + LLSINGLETON(LLViewerCamera); public: void* operator new(size_t size) { @@ -82,8 +83,6 @@ class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera> static eCameraID sCurCameraID; - LLViewerCamera(); - void updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 2cf56582f5b0cfab16a229971babe0bfe982fe56..a0bb689c902e1870b0f7af8cb9ca7a765aa40178 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -67,6 +67,7 @@ #include "llvowlsky.h" #include "llrender.h" #include "llnavigationbar.h" +#include "llnotificationsutil.h" #include "llfloatertools.h" #include "llpaneloutfitsinventory.h" #include "llpanellogin.h" @@ -118,6 +119,13 @@ static bool handleTerrainDetailChanged(const LLSD& newvalue) } +static bool handleDebugAvatarJointsChanged(const LLSD& newvalue) +{ + std::string new_string = newvalue.asString(); + LLJoint::setDebugJointNames(new_string); + 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 @@ -726,6 +734,7 @@ void settings_setup_listeners() gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged)); + gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2)); } #if TEST_CACHED_CONTROL diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index afa00e3e6e54dd6c68fe34250eda3c5536381e7b..13eccaefc1c422044624fb10307e74a9941e7fd9 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1107,7 +1107,7 @@ void render_hud_attachments() bool has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); if (has_ui) { - gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); + gPipeline.toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); } S32 use_occlusion = LLPipeline::sUseOcclusion; @@ -1152,7 +1152,7 @@ void render_hud_attachments() if (has_ui) { - gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); + gPipeline.toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); } LLPipeline::sUseOcclusion = use_occlusion; LLPipeline::sRenderingHUDs = FALSE; @@ -1230,13 +1230,13 @@ bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model) return get_hud_matrices(whole_screen, proj, model); } -BOOL setup_hud_matrices() +bool setup_hud_matrices() { LLRect whole_screen = get_whole_screen_region(); return setup_hud_matrices(whole_screen); } -BOOL setup_hud_matrices(const LLRect& screen_region) +bool setup_hud_matrices(const LLRect& screen_region) { glh::matrix4f proj, model; bool result = get_hud_matrices(screen_region, proj, model); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 91e4980e45b87202141b56895c62e3adb157ebd0..ec7a81584aa6fa0fa9126d4917d24b28de257aaa 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -77,7 +77,6 @@ #include "llfloaterimagepreview.h" #include "llfloaterimsession.h" #include "llfloaterinspect.h" -#include "llfloaterinventory.h" #include "llfloaterjoystick.h" #include "llfloaterlagmeter.h" #include "llfloaterland.h" @@ -93,6 +92,8 @@ #include "llfloaternotificationstabbed.h" #include "llfloaterobjectweights.h" #include "llfloateropenobject.h" +#include "llfloateroutfitphotopreview.h" +#include "llfloateroutfitsnapshot.h" #include "llfloaterpathfindingcharacters.h" #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindinglinksets.h" @@ -276,6 +277,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("object_weights", "floater_object_weights.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterObjectWeights>); LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>); LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>); + LLFloaterReg::add("outfit_photo_preview", "floater_outfit_photo_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitPhotoPreview>); LLFloaterPayUtil::registerFloater(); LLFloaterReg::add("pathfinding_characters", "floater_pathfinding_characters.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingCharacters>); @@ -333,7 +335,8 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>); LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>); LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>); - LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); + LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>); + LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index b8ff2cc9b4fee36e2bff7a9d220b6c76a62ff606..9cb2e0336a337a0786b1bd1892e4cf05c63faef7 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -103,8 +103,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry class LLViewerFolderDictionary : public LLSingleton<LLViewerFolderDictionary>, public LLDictionary<LLFolderType::EType, ViewerFolderEntry> { -public: - LLViewerFolderDictionary(); + LLSINGLETON(LLViewerFolderDictionary); protected: bool initEnsemblesFromFile(); // Reads in ensemble information from foldertypes.xml }; diff --git a/indra/newview/llviewerhelp.h b/indra/newview/llviewerhelp.h index a983012e2ee4ca9025b8a39c0d6896a33f6a2bfc..da50e07a4362a092c2241e26929dbf6be5f52a87 100644 --- a/indra/newview/llviewerhelp.h +++ b/indra/newview/llviewerhelp.h @@ -39,7 +39,7 @@ class LLUICtrl; class LLViewerHelp : public LLHelp, public LLSingleton<LLViewerHelp> { - friend class LLSingleton<LLViewerHelp>; + LLSINGLETON_EMPTY_CTOR(LLViewerHelp); public: /// display the specified help topic in the help viewer diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 0ee873d7a117f12ff1f3c0d8d1ebc9508fae3249..caffeadb73f61d508e8f0602fd60bb581f582b19 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -49,7 +49,6 @@ #include "llinventorybridge.h" #include "llinventorypanel.h" -#include "llfloaterinventory.h" #include "lllandmarkactions.h" #include "llviewerassettype.h" @@ -94,107 +93,10 @@ void doInventoryCb(LLPointer<LLInventoryCallback> cb, LLUUID id) ///---------------------------------------------------------------------------- class LLLocalizedInventoryItemsDictionary : public LLSingleton<LLLocalizedInventoryItemsDictionary> { + LLSINGLETON(LLLocalizedInventoryItemsDictionary); public: std::map<std::string, std::string> mInventoryItemsDict; - LLLocalizedInventoryItemsDictionary() - { - mInventoryItemsDict["New Shape"] = LLTrans::getString("New Shape"); - mInventoryItemsDict["New Skin"] = LLTrans::getString("New Skin"); - mInventoryItemsDict["New Hair"] = LLTrans::getString("New Hair"); - mInventoryItemsDict["New Eyes"] = LLTrans::getString("New Eyes"); - mInventoryItemsDict["New Shirt"] = LLTrans::getString("New Shirt"); - mInventoryItemsDict["New Pants"] = LLTrans::getString("New Pants"); - mInventoryItemsDict["New Shoes"] = LLTrans::getString("New Shoes"); - mInventoryItemsDict["New Socks"] = LLTrans::getString("New Socks"); - mInventoryItemsDict["New Jacket"] = LLTrans::getString("New Jacket"); - mInventoryItemsDict["New Gloves"] = LLTrans::getString("New Gloves"); - mInventoryItemsDict["New Undershirt"] = LLTrans::getString("New Undershirt"); - mInventoryItemsDict["New Underpants"] = LLTrans::getString("New Underpants"); - mInventoryItemsDict["New Skirt"] = LLTrans::getString("New Skirt"); - mInventoryItemsDict["New Alpha"] = LLTrans::getString("New Alpha"); - mInventoryItemsDict["New Tattoo"] = LLTrans::getString("New Tattoo"); - mInventoryItemsDict["New Physics"] = LLTrans::getString("New Physics"); - mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable"); - - mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture"); - mInventoryItemsDict["New Script"] = LLTrans::getString("New Script"); - mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder"); - mInventoryItemsDict["New Note"] = LLTrans::getString("New Note"); - mInventoryItemsDict["Contents"] = LLTrans::getString("Contents"); - - mInventoryItemsDict["Gesture"] = LLTrans::getString("Gesture"); - mInventoryItemsDict["Male Gestures"] = LLTrans::getString("Male Gestures"); - mInventoryItemsDict["Female Gestures"] = LLTrans::getString("Female Gestures"); - mInventoryItemsDict["Other Gestures"] = LLTrans::getString("Other Gestures"); - mInventoryItemsDict["Speech Gestures"] = LLTrans::getString("Speech Gestures"); - mInventoryItemsDict["Common Gestures"] = LLTrans::getString("Common Gestures"); - - //predefined gestures - - //male - mInventoryItemsDict["Male - Excuse me"] = LLTrans::getString("Male - Excuse me"); - mInventoryItemsDict["Male - Get lost"] = LLTrans::getString("Male - Get lost"); // double space after Male. EXT-8319 - mInventoryItemsDict["Male - Blow kiss"] = LLTrans::getString("Male - Blow kiss"); - mInventoryItemsDict["Male - Boo"] = LLTrans::getString("Male - Boo"); - mInventoryItemsDict["Male - Bored"] = LLTrans::getString("Male - Bored"); - mInventoryItemsDict["Male - Hey"] = LLTrans::getString("Male - Hey"); - mInventoryItemsDict["Male - Laugh"] = LLTrans::getString("Male - Laugh"); - mInventoryItemsDict["Male - Repulsed"] = LLTrans::getString("Male - Repulsed"); - mInventoryItemsDict["Male - Shrug"] = LLTrans::getString("Male - Shrug"); - mInventoryItemsDict["Male - Stick tougue out"] = LLTrans::getString("Male - Stick tougue out"); - mInventoryItemsDict["Male - Wow"] = LLTrans::getString("Male - Wow"); - - //female - mInventoryItemsDict["Female - Chuckle"] = LLTrans::getString("Female - Chuckle"); - mInventoryItemsDict["Female - Cry"] = LLTrans::getString("Female - Cry"); - mInventoryItemsDict["Female - Embarrassed"] = LLTrans::getString("Female - Embarrassed"); - mInventoryItemsDict["Female - Excuse me"] = LLTrans::getString("Female - Excuse me"); - mInventoryItemsDict["Female - Get lost"] = LLTrans::getString("Female - Get lost"); // double space after Female. EXT-8319 - mInventoryItemsDict["Female - Blow kiss"] = LLTrans::getString("Female - Blow kiss"); - mInventoryItemsDict["Female - Boo"] = LLTrans::getString("Female - Boo"); - mInventoryItemsDict["Female - Bored"] = LLTrans::getString("Female - Bored"); - mInventoryItemsDict["Female - Hey"] = LLTrans::getString("Female - Hey"); - mInventoryItemsDict["Female - Hey baby"] = LLTrans::getString("Female - Hey baby"); - mInventoryItemsDict["Female - Laugh"] = LLTrans::getString("Female - Laugh"); - mInventoryItemsDict["Female - Looking good"] = LLTrans::getString("Female - Looking good"); - mInventoryItemsDict["Female - Over here"] = LLTrans::getString("Female - Over here"); - mInventoryItemsDict["Female - Please"] = LLTrans::getString("Female - Please"); - mInventoryItemsDict["Female - Repulsed"] = LLTrans::getString("Female - Repulsed"); - mInventoryItemsDict["Female - Shrug"] = LLTrans::getString("Female - Shrug"); - mInventoryItemsDict["Female - Stick tougue out"]= LLTrans::getString("Female - Stick tougue out"); - mInventoryItemsDict["Female - Wow"] = LLTrans::getString("Female - Wow"); - - //common - mInventoryItemsDict["/bow"] = LLTrans::getString("/bow"); - mInventoryItemsDict["/clap"] = LLTrans::getString("/clap"); - mInventoryItemsDict["/count"] = LLTrans::getString("/count"); - mInventoryItemsDict["/extinguish"] = LLTrans::getString("/extinguish"); - mInventoryItemsDict["/kmb"] = LLTrans::getString("/kmb"); - mInventoryItemsDict["/muscle"] = LLTrans::getString("/muscle"); - mInventoryItemsDict["/no"] = LLTrans::getString("/no"); - mInventoryItemsDict["/no!"] = LLTrans::getString("/no!"); - mInventoryItemsDict["/paper"] = LLTrans::getString("/paper"); - mInventoryItemsDict["/pointme"] = LLTrans::getString("/pointme"); - mInventoryItemsDict["/pointyou"] = LLTrans::getString("/pointyou"); - mInventoryItemsDict["/rock"] = LLTrans::getString("/rock"); - mInventoryItemsDict["/scissor"] = LLTrans::getString("/scissor"); - mInventoryItemsDict["/smoke"] = LLTrans::getString("/smoke"); - mInventoryItemsDict["/stretch"] = LLTrans::getString("/stretch"); - mInventoryItemsDict["/whistle"] = LLTrans::getString("/whistle"); - mInventoryItemsDict["/yes"] = LLTrans::getString("/yes"); - mInventoryItemsDict["/yes!"] = LLTrans::getString("/yes!"); - mInventoryItemsDict["afk"] = LLTrans::getString("afk"); - mInventoryItemsDict["dance1"] = LLTrans::getString("dance1"); - mInventoryItemsDict["dance2"] = LLTrans::getString("dance2"); - mInventoryItemsDict["dance3"] = LLTrans::getString("dance3"); - mInventoryItemsDict["dance4"] = LLTrans::getString("dance4"); - mInventoryItemsDict["dance5"] = LLTrans::getString("dance5"); - mInventoryItemsDict["dance6"] = LLTrans::getString("dance6"); - mInventoryItemsDict["dance7"] = LLTrans::getString("dance7"); - mInventoryItemsDict["dance8"] = LLTrans::getString("dance8"); - } - /** * Finds passed name in dictionary and replaces it with found localized value. * @@ -217,6 +119,103 @@ class LLLocalizedInventoryItemsDictionary : public LLSingleton<LLLocalizedInvent } }; +LLLocalizedInventoryItemsDictionary::LLLocalizedInventoryItemsDictionary() +{ + mInventoryItemsDict["New Shape"] = LLTrans::getString("New Shape"); + mInventoryItemsDict["New Skin"] = LLTrans::getString("New Skin"); + mInventoryItemsDict["New Hair"] = LLTrans::getString("New Hair"); + mInventoryItemsDict["New Eyes"] = LLTrans::getString("New Eyes"); + mInventoryItemsDict["New Shirt"] = LLTrans::getString("New Shirt"); + mInventoryItemsDict["New Pants"] = LLTrans::getString("New Pants"); + mInventoryItemsDict["New Shoes"] = LLTrans::getString("New Shoes"); + mInventoryItemsDict["New Socks"] = LLTrans::getString("New Socks"); + mInventoryItemsDict["New Jacket"] = LLTrans::getString("New Jacket"); + mInventoryItemsDict["New Gloves"] = LLTrans::getString("New Gloves"); + mInventoryItemsDict["New Undershirt"] = LLTrans::getString("New Undershirt"); + mInventoryItemsDict["New Underpants"] = LLTrans::getString("New Underpants"); + mInventoryItemsDict["New Skirt"] = LLTrans::getString("New Skirt"); + mInventoryItemsDict["New Alpha"] = LLTrans::getString("New Alpha"); + mInventoryItemsDict["New Tattoo"] = LLTrans::getString("New Tattoo"); + mInventoryItemsDict["New Physics"] = LLTrans::getString("New Physics"); + mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable"); + + mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture"); + mInventoryItemsDict["New Script"] = LLTrans::getString("New Script"); + mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder"); + mInventoryItemsDict["New Note"] = LLTrans::getString("New Note"); + mInventoryItemsDict["Contents"] = LLTrans::getString("Contents"); + + mInventoryItemsDict["Gesture"] = LLTrans::getString("Gesture"); + mInventoryItemsDict["Male Gestures"] = LLTrans::getString("Male Gestures"); + mInventoryItemsDict["Female Gestures"] = LLTrans::getString("Female Gestures"); + mInventoryItemsDict["Other Gestures"] = LLTrans::getString("Other Gestures"); + mInventoryItemsDict["Speech Gestures"] = LLTrans::getString("Speech Gestures"); + mInventoryItemsDict["Common Gestures"] = LLTrans::getString("Common Gestures"); + + //predefined gestures + + //male + mInventoryItemsDict["Male - Excuse me"] = LLTrans::getString("Male - Excuse me"); + mInventoryItemsDict["Male - Get lost"] = LLTrans::getString("Male - Get lost"); // double space after Male. EXT-8319 + mInventoryItemsDict["Male - Blow kiss"] = LLTrans::getString("Male - Blow kiss"); + mInventoryItemsDict["Male - Boo"] = LLTrans::getString("Male - Boo"); + mInventoryItemsDict["Male - Bored"] = LLTrans::getString("Male - Bored"); + mInventoryItemsDict["Male - Hey"] = LLTrans::getString("Male - Hey"); + mInventoryItemsDict["Male - Laugh"] = LLTrans::getString("Male - Laugh"); + mInventoryItemsDict["Male - Repulsed"] = LLTrans::getString("Male - Repulsed"); + mInventoryItemsDict["Male - Shrug"] = LLTrans::getString("Male - Shrug"); + mInventoryItemsDict["Male - Stick tougue out"] = LLTrans::getString("Male - Stick tougue out"); + mInventoryItemsDict["Male - Wow"] = LLTrans::getString("Male - Wow"); + + //female + mInventoryItemsDict["Female - Chuckle"] = LLTrans::getString("Female - Chuckle"); + mInventoryItemsDict["Female - Cry"] = LLTrans::getString("Female - Cry"); + mInventoryItemsDict["Female - Embarrassed"] = LLTrans::getString("Female - Embarrassed"); + mInventoryItemsDict["Female - Excuse me"] = LLTrans::getString("Female - Excuse me"); + mInventoryItemsDict["Female - Get lost"] = LLTrans::getString("Female - Get lost"); // double space after Female. EXT-8319 + mInventoryItemsDict["Female - Blow kiss"] = LLTrans::getString("Female - Blow kiss"); + mInventoryItemsDict["Female - Boo"] = LLTrans::getString("Female - Boo"); + mInventoryItemsDict["Female - Bored"] = LLTrans::getString("Female - Bored"); + mInventoryItemsDict["Female - Hey"] = LLTrans::getString("Female - Hey"); + mInventoryItemsDict["Female - Hey baby"] = LLTrans::getString("Female - Hey baby"); + mInventoryItemsDict["Female - Laugh"] = LLTrans::getString("Female - Laugh"); + mInventoryItemsDict["Female - Looking good"] = LLTrans::getString("Female - Looking good"); + mInventoryItemsDict["Female - Over here"] = LLTrans::getString("Female - Over here"); + mInventoryItemsDict["Female - Please"] = LLTrans::getString("Female - Please"); + mInventoryItemsDict["Female - Repulsed"] = LLTrans::getString("Female - Repulsed"); + mInventoryItemsDict["Female - Shrug"] = LLTrans::getString("Female - Shrug"); + mInventoryItemsDict["Female - Stick tougue out"]= LLTrans::getString("Female - Stick tougue out"); + mInventoryItemsDict["Female - Wow"] = LLTrans::getString("Female - Wow"); + + //common + mInventoryItemsDict["/bow"] = LLTrans::getString("/bow"); + mInventoryItemsDict["/clap"] = LLTrans::getString("/clap"); + mInventoryItemsDict["/count"] = LLTrans::getString("/count"); + mInventoryItemsDict["/extinguish"] = LLTrans::getString("/extinguish"); + mInventoryItemsDict["/kmb"] = LLTrans::getString("/kmb"); + mInventoryItemsDict["/muscle"] = LLTrans::getString("/muscle"); + mInventoryItemsDict["/no"] = LLTrans::getString("/no"); + mInventoryItemsDict["/no!"] = LLTrans::getString("/no!"); + mInventoryItemsDict["/paper"] = LLTrans::getString("/paper"); + mInventoryItemsDict["/pointme"] = LLTrans::getString("/pointme"); + mInventoryItemsDict["/pointyou"] = LLTrans::getString("/pointyou"); + mInventoryItemsDict["/rock"] = LLTrans::getString("/rock"); + mInventoryItemsDict["/scissor"] = LLTrans::getString("/scissor"); + mInventoryItemsDict["/smoke"] = LLTrans::getString("/smoke"); + mInventoryItemsDict["/stretch"] = LLTrans::getString("/stretch"); + mInventoryItemsDict["/whistle"] = LLTrans::getString("/whistle"); + mInventoryItemsDict["/yes"] = LLTrans::getString("/yes"); + mInventoryItemsDict["/yes!"] = LLTrans::getString("/yes!"); + mInventoryItemsDict["afk"] = LLTrans::getString("afk"); + mInventoryItemsDict["dance1"] = LLTrans::getString("dance1"); + mInventoryItemsDict["dance2"] = LLTrans::getString("dance2"); + mInventoryItemsDict["dance3"] = LLTrans::getString("dance3"); + mInventoryItemsDict["dance4"] = LLTrans::getString("dance4"); + mInventoryItemsDict["dance5"] = LLTrans::getString("dance5"); + mInventoryItemsDict["dance6"] = LLTrans::getString("dance6"); + mInventoryItemsDict["dance7"] = LLTrans::getString("dance7"); + mInventoryItemsDict["dance8"] = LLTrans::getString("dance8"); +} ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs @@ -384,16 +383,26 @@ void LLViewerInventoryItem::updateServer(BOOL is_new) const LLInventoryModel::LLCategoryUpdate up(mParentUUID, is_new ? 1 : 0); gInventory.accountForUpdate(up); - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_UpdateInventoryItem); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, mTransactionID); - msg->nextBlockFast(_PREHASH_InventoryData); - msg->addU32Fast(_PREHASH_CallbackID, 0); - packMessage(msg); - gAgent.sendReliableMessage(); + LLSD updates = asLLSD(); + // Replace asset_id and/or shadow_id with transaction_id (hash_id) + if (updates.has("asset_id")) + { + updates.erase("asset_id"); + if(getTransactionID().notNull()) + { + updates["hash_id"] = getTransactionID(); + } + } + if (updates.has("shadow_id")) + { + updates.erase("shadow_id"); + if(getTransactionID().notNull()) + { + updates["hash_id"] = getTransactionID(); + } + } + AISAPI::completion_t cr = boost::bind(&doInventoryCb, (LLPointer<LLInventoryCallback>)NULL, _1); + AISAPI::UpdateItem(getUUID(), updates, cr); } void LLViewerInventoryItem::fetchFromServer(void) const @@ -636,17 +645,9 @@ void LLViewerInventoryCategory::updateServer(BOOL is_new) const return; } - LLInventoryModel::LLCategoryUpdate up(mParentUUID, is_new ? 1 : 0); - gInventory.accountForUpdate(up); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_UpdateInventoryFolder); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_FolderData); - packMessage(msg); - gAgent.sendReliableMessage(); + LLSD new_llsd = asLLSD(); + AISAPI::completion_t cr = boost::bind(&doInventoryCb, (LLPointer<LLInventoryCallback>)NULL, _1); + AISAPI::UpdateCategory(getUUID(), new_llsd, cr); } S32 LLViewerInventoryCategory::getVersion() const @@ -669,18 +670,6 @@ bool LLViewerInventoryCategory::fetch() mDescendentsRequested.reset(); mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY); - // bitfield - // 1 = by date - // 2 = folders by date - // Need to mask off anything but the first bit. - // This comes from LLInventoryFilter from llfolderview.h - U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1; - - // *NOTE: For bug EXT-2879, originally commented out - // gAgent.getRegion()->getCapability in order to use the old - // message-based system. This has been uncommented now that - // AIS folks are aware of the issue and have a fix in process. - // see ticket for details. std::string url; if (gAgent.getRegion()) @@ -695,24 +684,6 @@ bool LLViewerInventoryCategory::fetch() { LLInventoryModelBackgroundFetch::instance().start(mUUID, false); } - else - { //Deprecated, but if we don't have a capability, use the old system. - LL_INFOS(LOG_INV) << "FetchInventoryDescendents2 capability not found. Using deprecated UDP message." << LL_ENDL; - - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("FetchInventoryDescendents"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->nextBlock("InventoryData"); - msg->addUUID("FolderID", mUUID); - msg->addUUID("OwnerID", mOwnerID); - - msg->addS32("SortOrder", sort_order); - msg->addBOOL("FetchFolders", FALSE); - msg->addBOOL("FetchItems", TRUE); - gAgent.sendReliableMessage(); - } return true; } return false; @@ -905,17 +876,16 @@ void LLViewerInventoryCategory::changeType(LLFolderType::EType new_folder_type) const LLUUID &parent_id = getParentUUID(); const std::string &name = getName(); - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_UpdateInventoryFolder); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_FolderData); - msg->addUUIDFast(_PREHASH_FolderID, folder_id); - msg->addUUIDFast(_PREHASH_ParentID, parent_id); - msg->addS8Fast(_PREHASH_Type, new_folder_type); - msg->addStringFast(_PREHASH_Name, name); - gAgent.sendReliableMessage(); + LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(folder_id, + parent_id, + new_folder_type, + name, + gAgent.getID()); + + + LLSD new_llsd = new_cat->asLLSD(); + AISAPI::completion_t cr = boost::bind(&doInventoryCb, (LLPointer<LLInventoryCallback>) NULL, _1); + AISAPI::UpdateCategory(folder_id, new_llsd, cr); setPreferredType(new_folder_type); gInventory.addChangedMask(LLInventoryObserver::LABEL, folder_id); @@ -1036,6 +1006,22 @@ void activate_gesture_cb(const LLUUID& inv_item) LLGestureMgr::instance().activateGesture(inv_item); } +void set_default_permissions(LLViewerInventoryItem* item, std::string perm_type) +{ + llassert(item); + LLPermissions perm = item->getPermissions(); + if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms(perm_type) + || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms(perm_type)) + { + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms(perm_type)); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms(perm_type)); + + item->setPermissions(perm); + + item->updateServer(FALSE); + } +} + void create_script_cb(const LLUUID& inv_item) { if (!inv_item.isNull()) @@ -1043,13 +1029,9 @@ void create_script_cb(const LLUUID& inv_item) LLViewerInventoryItem* item = gInventory.getItem(inv_item); if (item) { - LLPermissions perm = item->getPermissions(); - perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Scripts")); - perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Scripts")); - - item->setPermissions(perm); + set_default_permissions(item, "Scripts"); - item->updateServer(FALSE); + // item was just created, update even if permissions did not changed gInventory.updateItem(item); gInventory.notifyObservers(); } @@ -1065,13 +1047,8 @@ void create_gesture_cb(const LLUUID& inv_item) LLViewerInventoryItem* item = gInventory.getItem(inv_item); if (item) { - LLPermissions perm = item->getPermissions(); - perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures")); - perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures")); - - item->setPermissions(perm); + set_default_permissions(item, "Gestures"); - item->updateServer(FALSE); gInventory.updateItem(item); gInventory.notifyObservers(); @@ -1090,13 +1067,8 @@ void create_notecard_cb(const LLUUID& inv_item) LLViewerInventoryItem* item = gInventory.getItem(inv_item); if (item) { - LLPermissions perm = item->getPermissions(); - perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Notecards")); - perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Notecards")); + set_default_permissions(item, "Notecards"); - item->setPermissions(perm); - - item->updateServer(FALSE); gInventory.updateItem(item); gInventory.notifyObservers(); } @@ -1289,40 +1261,10 @@ void link_inventory_array(const LLUUID& category, << " UUID:" << category << " ] " << LL_ENDL; #endif } - - if (AISAPI::isAvailable()) - { - LLSD new_inventory = LLSD::emptyMap(); - new_inventory["links"] = links; - AISAPI::completion_t cr = (cb) ? boost::bind(&doInventoryCb, cb, _1) : AISAPI::completion_t(); - AISAPI::CreateInventory(category, new_inventory, cr); - } - else - { - LLMessageSystem* msg = gMessageSystem; - for (LLSD::array_iterator iter = links.beginArray(); iter != links.endArray(); ++iter ) - { - msg->newMessageFast(_PREHASH_LinkInventoryItem); - msg->nextBlock(_PREHASH_AgentData); - { - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - } - msg->nextBlock(_PREHASH_InventoryBlock); - { - LLSD link = (*iter); - msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb)); - msg->addUUIDFast(_PREHASH_FolderID, category); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); - msg->addUUIDFast(_PREHASH_OldItemID, link["linked_id"].asUUID()); - msg->addS8Fast(_PREHASH_Type, link["type"].asInteger()); - msg->addS8Fast(_PREHASH_InvType, link["inv_type"].asInteger()); - msg->addStringFast(_PREHASH_Name, link["name"].asString()); - msg->addStringFast(_PREHASH_Description, link["desc"].asString()); - } - gAgent.sendReliableMessage(); - } - } + LLSD new_inventory = LLSD::emptyMap(); + new_inventory["links"] = links; + AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); + AISAPI::CreateInventory(category, new_inventory, cr); } void move_inventory_item( @@ -1354,49 +1296,27 @@ void update_inventory_item( LLPointer<LLInventoryCallback> cb) { const LLUUID& item_id = update_item->getUUID(); - if (AISAPI::isAvailable()) - { - LLSD updates = update_item->asLLSD(); - // Replace asset_id and/or shadow_id with transaction_id (hash_id) - if (updates.has("asset_id")) - { - updates.erase("asset_id"); - updates["hash_id"] = update_item->getTransactionID(); - } - if (updates.has("shadow_id")) - { - updates.erase("shadow_id"); - updates["hash_id"] = update_item->getTransactionID(); - } - AISAPI::completion_t cr = (cb) ? boost::bind(&doInventoryCb, cb, _1) : AISAPI::completion_t(); - AISAPI::UpdateItem(item_id, updates, cr); - } - else - { - LLPointer<LLViewerInventoryItem> obj = gInventory.getItem(item_id); - LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << (update_item ? update_item->getName() : "(NOT FOUND)") << LL_ENDL; - if(obj) - { - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_UpdateInventoryItem); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, update_item->getTransactionID()); - msg->nextBlockFast(_PREHASH_InventoryData); - msg->addU32Fast(_PREHASH_CallbackID, 0); - update_item->packMessage(msg); - gAgent.sendReliableMessage(); - - LLInventoryModel::LLCategoryUpdate up(update_item->getParentUUID(), 0); - gInventory.accountForUpdate(up); - gInventory.updateItem(update_item); - if (cb) - { - cb->fire(item_id); - } - } - } + + LLSD updates = update_item->asLLSD(); + // Replace asset_id and/or shadow_id with transaction_id (hash_id) + if (updates.has("asset_id")) + { + updates.erase("asset_id"); + if (update_item->getTransactionID().notNull()) + { + updates["hash_id"] = update_item->getTransactionID(); + } + } + if (updates.has("shadow_id")) + { + updates.erase("shadow_id"); + if (update_item->getTransactionID().notNull()) + { + updates["hash_id"] = update_item->getTransactionID(); + } + } + AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); + AISAPI::UpdateItem(item_id, updates, cr); } // Note this only supports updating an existing item. Goes through AISv3 @@ -1407,41 +1327,8 @@ void update_inventory_item( const LLSD& updates, LLPointer<LLInventoryCallback> cb) { - if (AISAPI::isAvailable()) - { - AISAPI::completion_t cr = (cb) ? boost::bind(&doInventoryCb, cb, _1) : AISAPI::completion_t(); - AISAPI::UpdateItem(item_id, updates, cr); - } - else - { - LLPointer<LLViewerInventoryItem> obj = gInventory.getItem(item_id); - LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << LL_ENDL; - if(obj) - { - LLPointer<LLViewerInventoryItem> new_item(new LLViewerInventoryItem); - new_item->copyViewerItem(obj); - new_item->fromLLSD(updates,false); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_UpdateInventoryItem); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, new_item->getTransactionID()); - msg->nextBlockFast(_PREHASH_InventoryData); - msg->addU32Fast(_PREHASH_CallbackID, 0); - new_item->packMessage(msg); - gAgent.sendReliableMessage(); - - LLInventoryModel::LLCategoryUpdate up(new_item->getParentUUID(), 0); - gInventory.accountForUpdate(up); - gInventory.updateItem(new_item); - if (cb) - { - cb->fire(item_id); - } - } - } + AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); + AISAPI::UpdateItem(item_id, updates, cr); } void update_inventory_category( @@ -1461,32 +1348,9 @@ void update_inventory_category( LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(obj); new_cat->fromLLSD(updates); - // FIXME - restore this once the back-end work has been done. - if (AISAPI::isAvailable()) - { - LLSD new_llsd = new_cat->asLLSD(); - AISAPI::completion_t cr = (cb) ? boost::bind(&doInventoryCb, cb, _1) : AISAPI::completion_t(); - AISAPI::UpdateCategory(cat_id, new_llsd, cr); - } - else // no cap - { - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_UpdateInventoryFolder); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_FolderData); - new_cat->packMessage(msg); - gAgent.sendReliableMessage(); - - LLInventoryModel::LLCategoryUpdate up(new_cat->getParentUUID(), 0); - gInventory.accountForUpdate(up); - gInventory.updateCategory(new_cat); - if (cb) - { - cb->fire(cat_id); - } - } + LLSD new_llsd = new_cat->asLLSD(); + AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); + AISAPI::UpdateCategory(cat_id, new_llsd, cr); } } @@ -1604,41 +1468,8 @@ void remove_inventory_category( LLNotificationsUtil::add("CannotRemoveProtectedCategories"); return; } - if (AISAPI::isAvailable()) - { - AISAPI::completion_t cr = (cb) ? boost::bind(&doInventoryCb, cb, _1) : AISAPI::completion_t(); - AISAPI::RemoveCategory(cat_id, cr); - } - else // no cap - { - // RemoveInventoryFolder does not remove children, so must - // clear descendents first. - LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(cat_id); - if(children != LLInventoryModel::CHILDREN_NO) - { - LL_DEBUGS(LOG_INV) << "Will purge descendents first before deleting category " << cat_id << LL_ENDL; - LLPointer<LLInventoryCallback> wrap_cb = new LLRemoveCategoryOnDestroy(cat_id, cb); - purge_descendents_of(cat_id, wrap_cb); - return; - } - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_RemoveInventoryFolder); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_FolderData); - msg->addUUIDFast(_PREHASH_FolderID, cat_id); - gAgent.sendReliableMessage(); - - // Update inventory and call callback immediately since - // message-based system has no callback mechanism (!) - gInventory.onObjectDeletedFromServer(cat_id); - if (cb) - { - cb->fire(cat_id); - } - } + AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); + AISAPI::RemoveCategory(cat_id, cr); } else { @@ -1857,29 +1688,11 @@ void slam_inventory_folder(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> cb) { - if (AISAPI::isAvailable()) - { - LL_DEBUGS(LOG_INV) << "using AISv3 to slam folder, id " << folder_id - << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; + LL_DEBUGS(LOG_INV) << "using AISv3 to slam folder, id " << folder_id + << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; - AISAPI::completion_t cr = (cb) ? boost::bind(&doInventoryCb, cb, _1) : AISAPI::completion_t(); - AISAPI::SlamFolder(folder_id, contents, cr); - } - else // no cap - { - LL_DEBUGS(LOG_INV) << "using item-by-item calls to slam folder, id " << folder_id - << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; - for (LLSD::array_const_iterator it = contents.beginArray(); - it != contents.endArray(); - ++it) - { - const LLSD& item_contents = *it; - LLViewerInventoryItem *item = new LLViewerInventoryItem; - item->fromLLSD(item_contents); - link_inventory_object(folder_id, item, cb); - } - remove_folder_contents(folder_id,false,cb); - } + AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); + AISAPI::SlamFolder(folder_id, contents, cr); } void remove_folder_contents(const LLUUID& category, bool keep_outfit_links, diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 4e91e4110af684bbd4a5d13e009daf4a7f228416..074d51b8b3661bba68920ad485de44b94fabb947 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -30,7 +30,7 @@ #include "llinventory.h" #include "llframetimer.h" #include "llwearable.h" -#include "llui.h" //for LLDestroyClass +#include "llinitdestroyclass.h" //for LLDestroyClass #include <boost/signals2.hpp> // boost::signals2::trackable @@ -38,6 +38,7 @@ class LLInventoryPanel; class LLFolderView; class LLFolderBridge; class LLViewerInventoryCategory; +class LLInventoryCallback; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLViewerInventoryItem @@ -387,9 +388,9 @@ void update_inventory_item( LLPointer<LLInventoryCallback> cb); void update_inventory_category( - const LLUUID& cat_id, - const LLSD& updates, - LLPointer<LLInventoryCallback> cb); + const LLUUID& cat_id, + const LLSD& updates, + LLPointer<LLInventoryCallback> cb); void remove_inventory_items( LLInventoryObject::object_list_t& items, diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index e46299f9d2d54ae2cf90c2aff73944100d9ceaa6..b7bd131246a4ec3e647e229c3c494d6e8417c6ab 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -48,14 +48,13 @@ LLViewerJoint::LLViewerJoint() : LLAvatarJoint() { } -LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) : - LLAvatarJoint(name, parent) -{ } - LLViewerJoint::LLViewerJoint(S32 joint_num) : LLAvatarJoint(joint_num) { } +LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) : + LLAvatarJoint(name, parent) +{ } //----------------------------------------------------------------------------- // ~LLViewerJoint() diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h index fd262b6e804793cfdc602545bd83dbd668ff2cd9..abe11bbf5c47a14dccfcea7c5ff0283539417b5b 100644 --- a/indra/newview/llviewerjoint.h +++ b/indra/newview/llviewerjoint.h @@ -44,7 +44,8 @@ class LLViewerJoint : { public: LLViewerJoint(); - LLViewerJoint(S32 joint_num); + LLViewerJoint(S32 joint_num); + // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform* LLViewerJoint(const std::string &name, LLJoint *parent = NULL); virtual ~LLViewerJoint(); diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 888decd3bedebbed0717c70bec84bb8723814eb8..66e392ac424075f3ac3e3cb3d89705333073fef5 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -352,6 +352,7 @@ void LLViewerJointAttachment::setAttachmentVisibility(BOOL visible) void LLViewerJointAttachment::setOriginalPosition(LLVector3& position) { mOriginalPos = position; + // SL-315 setPosition(position); } diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index bf7cf08c6364221e94b1f31ae5db841a2ee0e2d5..43a81ada4952ce35fb83e8fb4f757ee7a47fba33 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -203,7 +203,7 @@ void LLViewerJointMesh::uploadJointMatrices() // DrawElementsBLEND and utility code //-------------------------------------------------------------------- -// compate_int is used by the qsort function to sort the index array +// compare_int is used by the qsort function to sort the index array int compare_int(const void *a, const void *b) { if (*(U32*)a < *(U32*)b) diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h index 80c758a5af77991df14926a8b41651540259d171..016b435ee84648a54f4f04bf7d9baef7fe9cc847 100644 --- a/indra/newview/llviewerjoystick.h +++ b/indra/newview/llviewerjoystick.h @@ -45,10 +45,10 @@ typedef enum e_joystick_driver_state class LLViewerJoystick : public LLSingleton<LLViewerJoystick> { -public: - LLViewerJoystick(); + LLSINGLETON(LLViewerJoystick); virtual ~LLViewerJoystick(); - + +public: void init(bool autoenable); void terminate(); diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 2186ed3c5297d508e58c800aa262d3a5ed132f23..fd4315a319d25f2a9ed6aceb93856c0cb6903374 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -57,6 +57,7 @@ const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed struct LLKeyboardActionRegistry : public LLRegistrySingleton<std::string, boost::function<void (EKeystate keystate)>, LLKeyboardActionRegistry> { + LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry); }; LLViewerKeyboard gViewerKeyboard; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 6ed063e06637fd8c5238612c4d97742177370450..9f05ee61bde4c3ddd0f52586842890ef8efc7be2 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -167,6 +167,7 @@ static bool sForceUpdate = false; static LLUUID sOnlyAudibleTextureID = LLUUID::null; static F64 sLowestLoadableImplInterest = 0.0f; static bool sAnyMediaShowing = false; +static bool sAnyMediaPlaying = false; static boost::signals2::connection sTeleportFinishConnection; static std::string sUpdatedCookies; static const char *PLUGIN_COOKIE_FILE_NAME = "plugin_cookies.txt"; @@ -606,6 +607,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) createSpareBrowserMediaSource(); sAnyMediaShowing = false; + sAnyMediaPlaying = false; sUpdatedCookies = getCookieStore()->getChangedCookies(); if(!sUpdatedCookies.empty()) { @@ -808,6 +810,12 @@ void LLViewerMedia::updateMedia(void *dummy_arg) sAnyMediaShowing = true; } + if (!pimpl->getUsedInUI() && pimpl->hasMedia() && (pimpl->isMediaPlaying() || !pimpl->isMediaTimeBased())) + { + // consider visible non-timebased media as playing + sAnyMediaPlaying = true; + } + } } @@ -856,6 +864,13 @@ bool LLViewerMedia::isAnyMediaShowing() return sAnyMediaShowing; } +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isAnyMediaPlaying() +{ + return sAnyMediaPlaying; +} + ////////////////////////////////////////////////////////////////////////////////////////// // static void LLViewerMedia::setAllMediaEnabled(bool val) @@ -911,6 +926,77 @@ void LLViewerMedia::setAllMediaEnabled(bool val) } } +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setAllMediaPaused(bool val) +{ + // Set "tentative" autoplay first. We need to do this here or else + // re-enabling won't start up the media below. + gSavedSettings.setBOOL("MediaTentativeAutoPlay", !val); + + // Then + impl_list::iterator iter = sViewerMediaImplList.begin(); + impl_list::iterator end = sViewerMediaImplList.end(); + + for (; iter != end; iter++) + { + LLViewerMediaImpl* pimpl = *iter; + if (!pimpl->getUsedInUI()) + { + // upause/pause time based media, enable/disable any other + if (!val) + { + pimpl->setDisabled(val); + if (pimpl->isMediaTimeBased() && pimpl->isMediaPaused()) + { + pimpl->play(); + } + } + else if (pimpl->isMediaTimeBased() && pimpl->mMediaSource && (pimpl->isMediaPlaying() || pimpl->isMediaPaused())) + { + pimpl->pause(); + } + else + { + pimpl->setDisabled(val); + } + } + } + + // Also do Parcel Media and Parcel Audio + if (!val) + { + if (!LLViewerMedia::isParcelMediaPlaying() && LLViewerMedia::hasParcelMedia()) + { + LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); + } + + if (gSavedSettings.getBOOL("AudioStreamingMusic") && + !LLViewerMedia::isParcelAudioPlaying() && + gAudiop && + LLViewerMedia::hasParcelAudio()) + { + if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying()) + { + // 'false' means unpause + gAudiop->pauseInternetStream(false); + } + else + { + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); + } + } + } + else { + // This actually unloads the impl, as opposed to "stop"ping the media + LLViewerParcelMedia::stop(); + if (gAudiop) + { + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); + } + } +} + ////////////////////////////////////////////////////////////////////////////////////////// // static bool LLViewerMedia::isParcelMediaPlaying() @@ -1490,7 +1576,7 @@ void LLViewerMedia::createSpareBrowserMediaSource() // The null owner will keep the browser plugin from fully initializing // (specifically, it keeps LLPluginClassMedia from negotiating a size change, // which keeps MediaPluginWebkit::initBrowserWindow from doing anything until we have some necessary data, like the background color) - sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType(HTTP_CONTENT_TEXT_HTML, NULL, 0, 0); + sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType(HTTP_CONTENT_TEXT_HTML, NULL, 0, 0, 1.0); } } @@ -1762,7 +1848,7 @@ void LLViewerMediaImpl::setMediaType(const std::string& media_type) ////////////////////////////////////////////////////////////////////////////////////////// /*static*/ -LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, const std::string target, bool clean_browser) +LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, F64 zoom_factor, const std::string target, bool clean_browser) { std::string plugin_basename = LLMIMETypes::implType(media_type); LLPluginClassMedia* media_source = NULL; @@ -1779,6 +1865,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ media_source->setOwner(owner); media_source->setTarget(target); media_source->setSize(default_width, default_height); + media_source->setZoomFactor(zoom_factor); return media_source; } @@ -1819,7 +1906,9 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ } else if(LLFile::stat(plugin_name, &s)) { +#if !LL_LINUX LL_WARNS_ONCE("Media") << "Couldn't find plugin at " << plugin_name << LL_ENDL; +#endif } else { @@ -1827,6 +1916,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ media_source->setSize(default_width, default_height); media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies); media_source->setLanguageCode(LLUI::getLanguage()); + media_source->setZoomFactor(zoom_factor); // collect 'cookies enabled' setting from prefs and send to embedded browser bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" ); @@ -1860,8 +1950,10 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ } } } - +#if !LL_LINUX LL_WARNS_ONCE("Plugin") << "plugin initialization failed for mime type: " << media_type << LL_ENDL; +#endif + if(gAgent.isInitialized()) { if (std::find(sMimeTypesFailed.begin(), sMimeTypesFailed.end(), media_type) == sMimeTypesFailed.end()) @@ -1883,6 +1975,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) // Save the previous media source's last set size before destroying it. mMediaWidth = mMediaSource->getSetWidth(); mMediaHeight = mMediaSource->getSetHeight(); + mZoomFactor = mMediaSource->getZoomFactor(); } // Always delete the old media impl first. @@ -1905,7 +1998,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) // Save the MIME type that really caused the plugin to load mCurrentMimeType = mMimeType; - LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight, mTarget, mCleanBrowser); + LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight, mZoomFactor, mTarget, mCleanBrowser); if (media_source) { diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 48f0d9dc4df8039c049755bce9eb43514feec544..0212bf88bf7514bffd332428b7dbc77885a474d7 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -105,9 +105,13 @@ class LLViewerMedia // Is any media currently "showing"? Includes Parcel Media. Does not include media in the UI. static bool isAnyMediaShowing(); + // Shows if any media is playing, counts visible non time based media as playing. Does not include media in the UI. + static bool isAnyMediaPlaying(); // Set all media enabled or disabled, depending on val. Does not include media in the UI. static void setAllMediaEnabled(bool val); - + // Set all media paused(stopped for non time based) or playing, depending on val. Does not include media in the UI. + static void setAllMediaPaused(bool val); + static void updateMedia(void* dummy_arg = NULL); static void initClass(); @@ -299,7 +303,7 @@ class LLViewerMediaImpl void setTarget(const std::string& target) { mTarget = target; } // utility function to create a ready-to-use media instance from a desired media type. - static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, const std::string target = LLStringUtil::null, bool clean_browser = false); + static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, F64 zoom_factor, const std::string target = LLStringUtil::null, bool clean_browser = false); // Internally set our desired browser user agent string, including // the Second Life version and skin name. Used because we can diff --git a/indra/newview/llviewermedia_streamingaudio.cpp b/indra/newview/llviewermedia_streamingaudio.cpp index c107e8472c8a6b375c59c9435e702ba39ad40f08..3ccf3070ab181a919417c9ae9b4acd3ca28bf408 100644 --- a/indra/newview/llviewermedia_streamingaudio.cpp +++ b/indra/newview/llviewermedia_streamingaudio.cpp @@ -154,7 +154,8 @@ LLPluginClassMedia* LLStreamingAudio_MediaPlugins::initializeMedia(const std::st { LLPluginClassMediaOwner* owner = NULL; S32 default_size = 1; // audio-only - be minimal, doesn't matter - LLPluginClassMedia* media_source = LLViewerMediaImpl::newSourceFromMediaType(media_type, owner, default_size, default_size); + F64 default_zoom = 1.0; + LLPluginClassMedia* media_source = LLViewerMediaImpl::newSourceFromMediaType(media_type, owner, default_size, default_size, default_zoom); if (media_source) { diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h index 0b2a64868ea0c40710b1c288884c5b1cc959f96e..368c671f84b96cb553b86c4184d1c84efae91660 100644 --- a/indra/newview/llviewermediafocus.h +++ b/indra/newview/llviewermediafocus.h @@ -41,10 +41,10 @@ class LLViewerMediaFocus : public LLFocusableElement, public LLSingleton<LLViewerMediaFocus> { -public: - LLViewerMediaFocus(); + LLSINGLETON(LLViewerMediaFocus); ~LLViewerMediaFocus(); - + +public: // Set/clear the face that has media focus (takes keyboard input and has the full set of controls) void setFocusFace(LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal = LLVector3::zero); void clearFocus(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 1b1bbd5071715a142bba6da1a5960a4a99938157..b00caf55920eb5bdf29b00bd234d9fd66de4e494 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -62,7 +62,6 @@ #include "llfloaterbuycontents.h" #include "llbuycurrencyhtml.h" #include "llfloatergodtools.h" -#include "llfloaterinventory.h" #include "llfloaterimcontainer.h" #include "llfloaterland.h" #include "llfloaterimnearbychat.h" @@ -80,6 +79,7 @@ #include "lllandmarkactions.h" #include "llgroupmgr.h" #include "lltooltip.h" +#include "lltoolface.h" #include "llhints.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" @@ -89,6 +89,7 @@ #include "llinventoryfunctions.h" #include "llpanellogin.h" #include "llpanelblockedlist.h" +#include "llpanelmaininventory.h" #include "llmarketplacefunctions.h" #include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmoveview.h" @@ -133,6 +134,7 @@ #include "llpathfindingmanager.h" #include "llstartup.h" #include "boost/unordered_map.hpp" +#include "llcleanup.h" using namespace LLAvatarAppearanceDefines; @@ -187,10 +189,10 @@ LLMenuGL* gDetachSubMenu = NULL; LLMenuGL* gTakeOffClothes = NULL; LLContextMenu* gAttachScreenPieMenu = NULL; LLContextMenu* gAttachPieMenu = NULL; -LLContextMenu* gAttachBodyPartPieMenus[8]; +LLContextMenu* gAttachBodyPartPieMenus[9]; LLContextMenu* gDetachPieMenu = NULL; LLContextMenu* gDetachScreenPieMenu = NULL; -LLContextMenu* gDetachBodyPartPieMenus[8]; +LLContextMenu* gDetachBodyPartPieMenus[9]; // // Local prototypes @@ -397,13 +399,15 @@ void set_merchant_SLM_menu() gToolBarView->enableCommand(command->id(), true); } -void check_merchant_status() +void check_merchant_status(bool force) { if (!gSavedSettings.getBOOL("InventoryOutboxDisplayBoth")) { - // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status() - LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED); - + if (force) + { + // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status() + LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED); + } // Hide SLM related menu item gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(FALSE); @@ -790,7 +794,7 @@ class LLAdvancedToggleRenderType : public view_listener_t U32 render_type = render_type_from_string( userdata.asString() ); if ( render_type != 0 ) { - LLPipeline::toggleRenderTypeControl( (void*)render_type ); + LLPipeline::toggleRenderTypeControl( render_type ); } return true; } @@ -806,7 +810,7 @@ class LLAdvancedCheckRenderType : public view_listener_t if ( render_type != 0 ) { - new_value = LLPipeline::hasRenderTypeControl( (void*)render_type ); + new_value = LLPipeline::hasRenderTypeControl( render_type ); } return new_value; @@ -865,7 +869,7 @@ class LLAdvancedToggleFeature : public view_listener_t U32 feature = feature_from_string( userdata.asString() ); if ( feature != 0 ) { - LLPipeline::toggleRenderDebugFeature( (void*)feature ); + LLPipeline::toggleRenderDebugFeature( feature ); } return true; } @@ -880,7 +884,7 @@ class LLAdvancedCheckFeature : public view_listener_t if ( feature != 0 ) { - new_value = LLPipeline::toggleRenderDebugFeatureControl( (void*)feature ); + new_value = LLPipeline::toggleRenderDebugFeatureControl( feature ); } return new_value; @@ -921,7 +925,7 @@ class LLAdvancedSetDisplayTextureDensity : public view_listener_t { if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == TRUE) { - gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); } LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; } @@ -929,7 +933,7 @@ class LLAdvancedSetDisplayTextureDensity : public view_listener_t { if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) { - gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); } LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT; } @@ -937,7 +941,7 @@ class LLAdvancedSetDisplayTextureDensity : public view_listener_t { if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) { - gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); } gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true); LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED; @@ -946,7 +950,7 @@ class LLAdvancedSetDisplayTextureDensity : public view_listener_t { if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) { - gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); } LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL; } @@ -1089,7 +1093,7 @@ class LLAdvancedToggleInfoDisplay : public view_listener_t if ( info_display != 0 ) { - LLPipeline::toggleRenderDebug( (void*)info_display ); + LLPipeline::toggleRenderDebug( info_display ); } return true; @@ -1106,7 +1110,7 @@ class LLAdvancedCheckInfoDisplay : public view_listener_t if ( info_display != 0 ) { - new_value = LLPipeline::toggleRenderDebugControl( (void*)info_display ); + new_value = LLPipeline::toggleRenderDebugControl( info_display ); } return new_value; @@ -1209,17 +1213,18 @@ class LLAdvancedToggleWireframe : public view_listener_t bool handleEvent(const LLSD& userdata) { gUseWireframe = !(gUseWireframe); + gWindowResized = TRUE; + + LLPipeline::updateRenderDeferred(); if (gUseWireframe) { gInitialDeferredModeForWireframe = LLPipeline::sRenderDeferred; } - gWindowResized = TRUE; - LLPipeline::updateRenderDeferred(); gPipeline.resetVertexBuffers(); - if (!gUseWireframe && !gInitialDeferredModeForWireframe && LLPipeline::sRenderDeferred != gInitialDeferredModeForWireframe && gPipeline.isInit()) + if (!gUseWireframe && !gInitialDeferredModeForWireframe && LLPipeline::sRenderDeferred != bool(gInitialDeferredModeForWireframe) && gPipeline.isInit()) { LLPipeline::refreshCachedSettings(); gPipeline.releaseGLBuffers(); @@ -5165,30 +5170,91 @@ class LLToolsEnableSelectNextPart : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = (gSavedSettings.getBOOL("EditLinkedParts") && - !LLSelectMgr::getInstance()->getSelection()->isEmpty()); + bool new_value = (!LLSelectMgr::getInstance()->getSelection()->isEmpty() + && (gSavedSettings.getBOOL("EditLinkedParts") + || LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool())); return new_value; } }; -// Cycle selection through linked children in selected object. +// Cycle selection through linked children or/and faces in selected object. // FIXME: Order of children list is not always the same as sim's idea of link order. This may confuse // resis. Need link position added to sim messages to address this. -class LLToolsSelectNextPart : public view_listener_t +class LLToolsSelectNextPartFace : public view_listener_t { - bool handleEvent(const LLSD& userdata) - { + bool handleEvent(const LLSD& userdata) + { + bool cycle_faces = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool(); + bool cycle_linked = gSavedSettings.getBOOL("EditLinkedParts"); + + if (!cycle_faces && !cycle_linked) + { + // Nothing to do + return true; + } + + bool fwd = (userdata.asString() == "next"); + bool prev = (userdata.asString() == "previous"); + bool ifwd = (userdata.asString() == "includenext"); + bool iprev = (userdata.asString() == "includeprevious"); + + LLViewerObject* to_select = NULL; + bool restart_face_on_part = !cycle_faces; + S32 new_te = 0; + + if (cycle_faces) + { + // Cycle through faces of current selection, if end is reached, swithc to next part (if present) + LLSelectNode* nodep = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + if (!nodep) return false; + to_select = nodep->getObject(); + if (!to_select) return false; + + S32 te_count = to_select->getNumTEs(); + S32 selected_te = nodep->getLastOperatedTE(); + + if (fwd || ifwd) + { + if (selected_te < 0) + { + new_te = 0; + } + else if (selected_te + 1 < te_count) + { + // select next face + new_te = selected_te + 1; + } + else + { + // restart from first face on next part + restart_face_on_part = true; + } + } + else if (prev || iprev) + { + if (selected_te > te_count) + { + new_te = te_count - 1; + } + else if (selected_te - 1 >= 0) + { + // select previous face + new_te = selected_te - 1; + } + else + { + // restart from last face on next part + restart_face_on_part = true; + } + } + } + S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); - if (gSavedSettings.getBOOL("EditLinkedParts") && object_count) + if (cycle_linked && object_count && restart_face_on_part) { LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); if (selected && selected->getRootEdit()) { - bool fwd = (userdata.asString() == "next"); - bool prev = (userdata.asString() == "previous"); - bool ifwd = (userdata.asString() == "includenext"); - bool iprev = (userdata.asString() == "includeprevious"); - LLViewerObject* to_select = NULL; LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren(); children.push_front(selected->getRootEdit()); // need root in the list too @@ -5230,22 +5296,40 @@ class LLToolsSelectNextPart : public view_listener_t } } } - - if (to_select) - { - if (gFocusMgr.childHasKeyboardFocus(gFloaterTools)) - { - gFocusMgr.setKeyboardFocus(NULL); // force edit toolbox to commit any changes - } - if (fwd || prev) - { - LLSelectMgr::getInstance()->deselectAll(); - } - LLSelectMgr::getInstance()->selectObjectOnly(to_select); - return true; - } } } + + if (to_select) + { + if (gFocusMgr.childHasKeyboardFocus(gFloaterTools)) + { + gFocusMgr.setKeyboardFocus(NULL); // force edit toolbox to commit any changes + } + if (fwd || prev) + { + LLSelectMgr::getInstance()->deselectAll(); + } + if (cycle_faces) + { + if (restart_face_on_part) + { + if (fwd || ifwd) + { + new_te = 0; + } + else + { + new_te = to_select->getNumTEs() - 1; + } + } + LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, FALSE); + } + else + { + LLSelectMgr::getInstance()->selectObjectOnly(to_select); + } + return true; + } return true; } }; @@ -5982,6 +6066,31 @@ class LLAvatarToggleMyProfile : public view_listener_t } }; +class LLAvatarResetSkeleton: public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar) + { + avatar->resetSkeleton(false); + } + return true; + } +}; + +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; + } +}; class LLAvatarAddContact : public view_listener_t { @@ -6970,20 +7079,25 @@ class LLAvatarCall : public view_listener_t namespace { - struct QueueObjects : public LLSelectedObjectFunctor + struct QueueObjects : public LLSelectedNodeFunctor { BOOL scripted; BOOL modifiable; LLFloaterScriptQueue* mQueue; QueueObjects(LLFloaterScriptQueue* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {} - virtual bool apply(LLViewerObject* obj) + 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()); + mQueue->addObject(obj->getID(), node->mName); return false; } else @@ -6999,7 +7113,7 @@ void queue_actions(LLFloaterScriptQueue* q, const std::string& msg) QueueObjects func(q); LLSelectMgr *mgr = LLSelectMgr::getInstance(); LLObjectSelectionHandle selectHandle = mgr->getSelection(); - bool fail = selectHandle->applyToObjects(&func); + bool fail = selectHandle->applyToNodes(&func); if(fail) { if ( !func.scripted ) @@ -7885,7 +7999,7 @@ void handle_web_browser_test(const LLSD& param) void handle_web_content_test(const LLSD& param) { std::string url = param.asString(); - LLWeb::loadURLInternal(url); + LLWeb::loadURLInternal(url, LLStringUtil::null, LLStringUtil::null, true); } void handle_show_url(const LLSD& param) @@ -8032,66 +8146,66 @@ class LLViewToggleBeacon : public view_listener_t std::string beacon = userdata.asString(); if (beacon == "scriptsbeacon") { - LLPipeline::toggleRenderScriptedBeacons(NULL); - gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons(NULL) ); + LLPipeline::toggleRenderScriptedBeacons(); + gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() ); // toggle the other one off if it's on - if (LLPipeline::getRenderScriptedBeacons(NULL) && LLPipeline::getRenderScriptedTouchBeacons(NULL)) + if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons()) { - LLPipeline::toggleRenderScriptedTouchBeacons(NULL); - gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons(NULL) ); + LLPipeline::toggleRenderScriptedTouchBeacons(); + gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() ); } } else if (beacon == "physicalbeacon") { - LLPipeline::toggleRenderPhysicalBeacons(NULL); - gSavedSettings.setBOOL( "physicalbeacon", LLPipeline::getRenderPhysicalBeacons(NULL) ); + LLPipeline::toggleRenderPhysicalBeacons(); + gSavedSettings.setBOOL( "physicalbeacon", LLPipeline::getRenderPhysicalBeacons() ); } else if (beacon == "moapbeacon") { - LLPipeline::toggleRenderMOAPBeacons(NULL); - gSavedSettings.setBOOL( "moapbeacon", LLPipeline::getRenderMOAPBeacons(NULL) ); + LLPipeline::toggleRenderMOAPBeacons(); + gSavedSettings.setBOOL( "moapbeacon", LLPipeline::getRenderMOAPBeacons() ); } else if (beacon == "soundsbeacon") { - LLPipeline::toggleRenderSoundBeacons(NULL); - gSavedSettings.setBOOL( "soundsbeacon", LLPipeline::getRenderSoundBeacons(NULL) ); + LLPipeline::toggleRenderSoundBeacons(); + gSavedSettings.setBOOL( "soundsbeacon", LLPipeline::getRenderSoundBeacons() ); } else if (beacon == "particlesbeacon") { - LLPipeline::toggleRenderParticleBeacons(NULL); - gSavedSettings.setBOOL( "particlesbeacon", LLPipeline::getRenderParticleBeacons(NULL) ); + LLPipeline::toggleRenderParticleBeacons(); + gSavedSettings.setBOOL( "particlesbeacon", LLPipeline::getRenderParticleBeacons() ); } else if (beacon == "scripttouchbeacon") { - LLPipeline::toggleRenderScriptedTouchBeacons(NULL); - gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons(NULL) ); + LLPipeline::toggleRenderScriptedTouchBeacons(); + gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() ); // toggle the other one off if it's on - if (LLPipeline::getRenderScriptedBeacons(NULL) && LLPipeline::getRenderScriptedTouchBeacons(NULL)) + if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons()) { - LLPipeline::toggleRenderScriptedBeacons(NULL); - gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons(NULL) ); + LLPipeline::toggleRenderScriptedBeacons(); + gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() ); } } else if (beacon == "renderbeacons") { - LLPipeline::toggleRenderBeacons(NULL); - gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons(NULL) ); + LLPipeline::toggleRenderBeacons(); + gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() ); // toggle the other one on if it's not - if (!LLPipeline::getRenderBeacons(NULL) && !LLPipeline::getRenderHighlights(NULL)) + if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights()) { - LLPipeline::toggleRenderHighlights(NULL); - gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights(NULL) ); + LLPipeline::toggleRenderHighlights(); + gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() ); } } else if (beacon == "renderhighlights") { - LLPipeline::toggleRenderHighlights(NULL); - gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights(NULL) ); + LLPipeline::toggleRenderHighlights(); + gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() ); // toggle the other one on if it's not - if (!LLPipeline::getRenderBeacons(NULL) && !LLPipeline::getRenderHighlights(NULL)) + if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights()) { - LLPipeline::toggleRenderBeacons(NULL); - gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons(NULL) ); + LLPipeline::toggleRenderBeacons(); + gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() ); } } @@ -8170,7 +8284,7 @@ class LLViewCheckRenderType : public view_listener_t bool new_value = false; if (type == "hideparticles") { - new_value = LLPipeline::toggleRenderTypeControlNegated((void *)LLPipeline::RENDER_TYPE_PARTICLES); + new_value = LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES); } return new_value; } @@ -8461,7 +8575,7 @@ class LLWorldPostProcess : public view_listener_t void handle_flush_name_caches() { - LLAvatarNameCache::cleanupClass(); + SUBSYSTEM_CLEANUP(LLAvatarNameCache); if (gCacheName) gCacheName->clear(); } @@ -8505,7 +8619,7 @@ class LLToggleUIHints : public view_listener_t void LLUploadCostCalculator::calculateCost() { - S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // getPriceUpload() returns -1 if no data available yet. if(upload_cost >= 0) @@ -8722,7 +8836,7 @@ void initialize_menus() 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 LLToolsSelectNextPart(), "Tools.SelectNextPart"); + view_listener_t::addMenu(new LLToolsSelectNextPartFace(), "Tools.SelectNextPart"); commit.add("Tools.Link", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance())); commit.add("Tools.Unlink", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance())); view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations"); @@ -8967,6 +9081,8 @@ void initialize_menus() enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall)); view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse"); view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile"); + view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton"); + view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations"); enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible)); commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL"))); @@ -9046,7 +9162,7 @@ void initialize_menus() view_listener_t::addMenu(new LLGoToObject(), "GoToObject"); commit.add("PayObject", boost::bind(&handle_give_money_dialog)); - commit.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::showAgentInventory)); + commit.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow)); enable.add("EnablePayObject", boost::bind(&enable_pay_object)); enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar)); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index b7bdf0015775bb61bfd4814f0019267c462ef3f1..7abb0c8e748f9c833d9e9b769badb963e9db4a1f 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -83,7 +83,7 @@ BOOL enable_god_full(void* user_data); BOOL enable_god_liaison(void* user_data); BOOL enable_god_basic(void* user_data); void set_underclothes_menu_options(); -void check_merchant_status(); +void check_merchant_status(bool force = false); void exchange_callingcard(const LLUUID& dest_id); @@ -108,6 +108,7 @@ void handle_look_at_selection(const LLSD& param); void handle_zoom_to_object(LLUUID object_id); void handle_object_return(); void handle_object_delete(); +void handle_object_edit(); void handle_buy_land(); @@ -188,8 +189,8 @@ extern LLContextMenu* gAttachScreenPieMenu; extern LLContextMenu* gDetachScreenPieMenu; extern LLContextMenu* gAttachPieMenu; extern LLContextMenu* gDetachPieMenu; -extern LLContextMenu* gAttachBodyPartPieMenus[8]; -extern LLContextMenu* gDetachBodyPartPieMenus[8]; +extern LLContextMenu* gAttachBodyPartPieMenus[9]; +extern LLContextMenu* gDetachBodyPartPieMenus[9]; extern LLMenuItemCallGL* gMutePieMenu; extern LLMenuItemCallGL* gMuteObjectPieMenu; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 4f24dfafac95e8bf776f18bcee562066f02299f2..d46bb0199bf051945a0b7775f85b75a8cffaefa2 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -37,6 +37,7 @@ #include "llfloatermap.h" #include "llfloatermodelpreview.h" #include "llfloatersnapshot.h" +#include "llfloateroutfitsnapshot.h" #include "llimage.h" #include "llimagebmp.h" #include "llimagepng.h" @@ -83,7 +84,7 @@ class LLFileEnableUpload : public view_listener_t bool handleEvent(const LLSD& userdata) { return true; -// bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()); +// bool new_value = gStatusBar && LLGlobalEconomy::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::getInstance()->getPriceUpload()); // return new_value; } }; @@ -92,6 +93,12 @@ 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; } }; @@ -358,7 +365,7 @@ class LLFileUploadModel : public view_listener_t bool handleEvent(const LLSD& userdata) { LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::getInstance("upload_model"); - if (fmp) + if (fmp && !fmp->isModelLoading()) { fmp->loadModel(3); } @@ -422,7 +429,7 @@ class LLFileUploadBulk : public view_listener_t if (picker.getMultipleOpenFiles()) { std::string filename = picker.getFirstFile(); - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); while (!filename.empty()) { @@ -508,8 +515,10 @@ class LLFileEnableCloseAllWindows : public view_listener_t bool handleEvent(const LLSD& userdata) { LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); - bool is_floater_snapshot_opened = floater_snapshot && floater_snapshot->isInVisibleChain(); - bool open_children = gFloaterView->allChildrenClosed() && !is_floater_snapshot_opened; + LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance(); + bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain()) + || (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain()); + bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened; return !open_children; } }; @@ -520,7 +529,12 @@ class LLFileCloseAllWindows : public view_listener_t { bool app_quitting = false; gFloaterView->closeAllChildren(app_quitting); - LLFloaterSnapshot::getInstance()->closeFloater(app_quitting); + LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); + if (floater_snapshot) + floater_snapshot->closeFloater(app_quitting); + LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance(); + if (floater_outfit_snapshot) + floater_outfit_snapshot->closeFloater(app_quitting); if (gMenuHolder) gMenuHolder->hideMenus(); return true; } @@ -551,18 +565,18 @@ class LLFileTakeSnapshotToDisk : public view_listener_t { gViewerWindow->playSnapshotAnimAndSound(); LLPointer<LLImageFormatted> formatted; - LLFloaterSnapshot::ESnapshotFormat fmt = (LLFloaterSnapshot::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat"); + LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat"); switch (fmt) { - case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG: + case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG: formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality")); break; default: LL_WARNS() << "Unknown local snapshot format: " << fmt << LL_ENDL; - case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG: + case LLSnapshotModel::SNAPSHOT_FORMAT_PNG: formatted = new LLImagePNG; break; - case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP: + case LLSnapshotModel::SNAPSHOT_FORMAT_BMP: formatted = new LLImageBMP; break; } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 92df3866f72634a6bf7b78a7872f29aaf07f832e..2ab59037e1d55d605162fdd0902210a34386cedf 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1639,7 +1639,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID); discard_agent_offer->startFetch(); - if (catp || (itemp && itemp->isFinished())) + if ((catp && gInventory.isCategoryComplete(mObjectID)) || (itemp && itemp->isFinished())) { discard_agent_offer->done(); } @@ -2596,7 +2596,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // The group notice packet does not have an AgentID. Obtain one from the name cache. // If last name is "Resident" strip it out so the cache name lookup works. - U32 index = original_name.find(" Resident"); + std::string::size_type index = original_name.find(" Resident"); if (index != std::string::npos) { original_name = original_name.substr(0, index); @@ -4196,7 +4196,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) LLVector3 beacon_dir(agent_pos.mV[VX] - (F32)fmod(beacon_pos.mdV[VX], 256.0), agent_pos.mV[VY] - (F32)fmod(beacon_pos.mdV[VY], 256.0), 0); if (beacon_dir.magVecSquared() < 25.f) { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() && look_at.isExactlyZero()) { @@ -4719,7 +4719,9 @@ void process_sound_trigger(LLMessageSystem *msg, void **) { if (!gAudiop) { +#if !LL_LINUX LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; +#endif return; } @@ -4781,7 +4783,9 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data) { if (!gAudiop) { +#if !LL_LINUX LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; +#endif return; } @@ -5463,9 +5467,12 @@ static std::string reason_from_transaction_type(S32 transaction_type, case TRANS_CLASSIFIED_CHARGE: return LLTrans::getString("to publish a classified ad"); + case TRANS_GIFT: + // Simulator returns "Payment" if no custom description has been entered + return (item_desc == "Payment" ? std::string() : item_desc); + // These have no reason to display, but are expected and should not // generate warnings - case TRANS_GIFT: case TRANS_PAY_OBJECT: case TRANS_OBJECT_PAYS: return std::string(); @@ -5575,6 +5582,7 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) LLSD payload; bool you_paid_someone = (source_id == gAgentID); + std::string gift_suffix = (transaction_type == TRANS_GIFT ? "_gift" : ""); if (you_paid_someone) { if(!gSavedSettings.getBOOL("NotifyMoneySpend")) @@ -5588,8 +5596,8 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) { if (dest_id.notNull()) { - message = success ? LLTrans::getString("you_paid_ldollars", args) : - LLTrans::getString("you_paid_failure_ldollars", args); + message = success ? LLTrans::getString("you_paid_ldollars" + gift_suffix, args) : + LLTrans::getString("you_paid_failure_ldollars" + gift_suffix, args); } else { @@ -5616,7 +5624,8 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) payload["dest_id"] = dest_id; notification = success ? "PaymentSent" : "PaymentFailure"; } - else { + else + { // ...someone paid you if(!gSavedSettings.getBOOL("NotifyMoneyReceived")) { @@ -5627,9 +5636,10 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) name_id = source_id; if (!reason.empty()) { - message = LLTrans::getString("paid_you_ldollars", args); + message = LLTrans::getString("paid_you_ldollars" + gift_suffix, args); } - else { + else + { message = LLTrans::getString("paid_you_ldollars_no_reason", args); } final_args["MESSAGE"] = message; @@ -6274,9 +6284,9 @@ void process_frozen_message(LLMessageSystem *msgsystem, void **user_data) // do some extra stuff once we get our economy data void process_economy_data(LLMessageSystem *msg, void** /*user_data*/) { - LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance()); + LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::getInstance()); - S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL; @@ -6381,6 +6391,16 @@ bool unknown_script_question_cb(const LLSD& notification, const LLSD& response) return false; } +void experiencePermissionBlock(LLUUID experience, LLSD result) +{ + LLSD permission; + LLSD data; + permission["permission"] = "Block"; + data[experience.asString()] = permission; + data["experience"] = experience; + LLEventPumps::instance().obtain("experience_permission").post(data); +} + bool script_question_cb(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -6457,14 +6477,8 @@ bool script_question_cb(const LLSD& notification, const LLSD& response) if (!region) return false; - LLExperienceCache::instance().setExperiencePermission(experience, std::string("Block"), LLExperienceCache::ExperienceGetFn_t()); + LLExperienceCache::instance().setExperiencePermission(experience, std::string("Block"), boost::bind(&experiencePermissionBlock, experience, _1)); - LLSD permission; - LLSD data; - permission["permission"] = "Block"; - data[experience.asString()] = permission; - data["experience"] = experience; - LLEventPumps::instance().obtain("experience_permission").post(data); } } return false; @@ -6601,6 +6615,11 @@ void process_script_question(LLMessageSystem *msg, void **user_data) if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit) continue; + if (script_perm.question == "JoinAnExperience") + { // Some experience only permissions do not have an explicit permission bit. Add them here. + script_question += " " + LLTrans::getString("ForceSitAvatar") + "\n"; + } + script_question += " " + LLTrans::getString(script_perm.question) + "\n"; } } diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index d8f5c71f8d3bfff2a6b7c30e43832d939a81215d..b0eaa37541db4af72b8eb4c7ccda1bf30e0de7a3 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -210,6 +210,7 @@ void set_dad_inbox_object(const LLUUID& object_id); class LLViewerMessage : public LLSingleton<LLViewerMessage> { + LLSINGLETON_EMPTY_CTOR(LLViewerMessage); public: typedef boost::function<void()> teleport_started_callback_t; typedef boost::signals2::signal<void()> teleport_started_signal_t; diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 6666aecca207f4c984bbd6e20d68bd7e638ba46f..6937d064f982bfa5ce88a0e5b7ed5dd6bd639c8d 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -49,6 +49,8 @@ const std::string GRID_UPDATE_SERVICE_URL = "update_query_url_base"; const std::string GRID_HELPER_URI_VALUE = "helper_uri"; /// the splash page url const std::string GRID_LOGIN_PAGE_VALUE = "login_page"; +/// url for the web profile site +const std::string GRID_WEB_PROFILE_VALUE = "web_profile_url"; /// internal data on system grids const std::string GRID_IS_SYSTEM_GRID_VALUE = "system_grid"; /// whether this is single or double names @@ -70,6 +72,8 @@ const std::string SL_UPDATE_QUERY_URL = "https://update.secondlife.com/update"; const std::string MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/"; const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app"; +const std::string MAIN_GRID_WEB_PROFILE_URL = "https://my.secondlife.com/"; + const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/"; const char* DEFAULT_SLURL_BASE = "https://%s/region/"; const char* DEFAULT_APP_SLURL_BASE = "x-grid-location-info://%s/app"; @@ -91,13 +95,6 @@ LLGridManager::LLGridManager() } -LLGridManager::LLGridManager(const std::string& grid_file) -{ - // initialize with an explicity grid file for testing. - LL_DEBUGS("GridManager")<<LL_ENDL; - initialize(grid_file); -} - // // LLGridManager - class for managing the list of known grids, and the current // selection @@ -125,6 +122,7 @@ void LLGridManager::initialize(const std::string& grid_file) "https://secondlife.com/helpers/", DEFAULT_LOGIN_PAGE, SL_UPDATE_QUERY_URL, + MAIN_GRID_WEB_PROFILE_URL, "Agni"); addSystemGrid(LLTrans::getString("AditiGridLabel"), "util.aditi.lindenlab.com", @@ -132,6 +130,7 @@ void LLGridManager::initialize(const std::string& grid_file) "http://aditi-secondlife.webdev.lindenlab.com/helpers/", DEFAULT_LOGIN_PAGE, SL_UPDATE_QUERY_URL, + "https://my.aditi.lindenlab.com/", "Aditi"); LLSD other_grids; @@ -288,6 +287,10 @@ bool LLGridManager::addGrid(LLSD& grid_data) { grid_data[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/"; } + if (!grid_data.has(GRID_WEB_PROFILE_VALUE)) + { + grid_data[GRID_WEB_PROFILE_VALUE] = std::string("https://") + grid + "/"; + } if (!grid_data.has(GRID_LOGIN_IDENTIFIER_TYPES)) { @@ -302,7 +305,8 @@ bool LLGridManager::addGrid(LLSD& grid_data) <<" id: "<<grid_data[GRID_ID_VALUE].asString()<<"\n" <<" label: "<<grid_data[GRID_LABEL_VALUE].asString()<<"\n" <<" login page: "<<grid_data[GRID_LOGIN_PAGE_VALUE].asString()<<"\n" - <<" helper page: "<<grid_data[GRID_HELPER_URI_VALUE].asString()<<"\n"; + <<" helper page: "<<grid_data[GRID_HELPER_URI_VALUE].asString()<<"\n" + <<" web profile: "<<grid_data[GRID_WEB_PROFILE_VALUE].asString()<<"\n"; /* still in LL_DEBUGS */ for (LLSD::array_const_iterator login_uris = grid_data[GRID_LOGIN_URI_VALUE].beginArray(); login_uris != grid_data[GRID_LOGIN_URI_VALUE].endArray(); @@ -339,6 +343,7 @@ void LLGridManager::addSystemGrid(const std::string& label, const std::string& helper, const std::string& login_page, const std::string& update_url_base, + const std::string& web_profile_url, const std::string& login_id) { LLSD grid = LLSD::emptyMap(); @@ -349,6 +354,7 @@ void LLGridManager::addSystemGrid(const std::string& label, grid[GRID_LOGIN_URI_VALUE].append(login_uri); grid[GRID_LOGIN_PAGE_VALUE] = login_page; grid[GRID_UPDATE_SERVICE_URL] = update_url_base; + grid[GRID_WEB_PROFILE_VALUE] = web_profile_url; grid[GRID_IS_SYSTEM_GRID_VALUE] = true; grid[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray(); grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT); @@ -535,6 +541,21 @@ std::string LLGridManager::getLoginPage() return login_page; } +std::string LLGridManager::getWebProfileURL(const std::string& grid) +{ + std::string web_profile_url; + std::string grid_name = getGrid(grid); + if (!grid_name.empty()) + { + web_profile_url = mGridList[grid_name][GRID_WEB_PROFILE_VALUE].asString(); + } + else + { + LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL; + } + return web_profile_url; +} + void LLGridManager::getLoginIdentifierTypes(LLSD& idTypes) { idTypes = mGridList[mGrid][GRID_LOGIN_IDENTIFIER_TYPES]; diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h index 8526c0ba7f35959b41e90fc81b3a072d3f128b22..b8ff494b8b0d27e79d997dc8d47cea4020d14062 100644 --- a/indra/newview/llviewernetwork.h +++ b/indra/newview/llviewernetwork.h @@ -58,16 +58,15 @@ class LLInvalidGridName **/ class LLGridManager : public LLSingleton<LLGridManager> { + /// Instantiate the grid manager, load default grids, selects the default grid + LLSINGLETON(LLGridManager); + ~LLGridManager(); + public: /* ================================================================ * @name Initialization and Configuration * @{ */ - /// Instantiate the grid manager, load default grids, selects the default grid - LLGridManager(const std::string& grid_file); - LLGridManager(); - ~LLGridManager(); - /// add grids from an external grids file void initialize(const std::string& grid_file); @@ -166,6 +165,13 @@ class LLGridManager : public LLSingleton<LLGridManager> /// Return the application URL prefix for the selected grid std::string getAppSLURLBase() { return getAppSLURLBase(mGrid); } + /// Return the url of the resident profile web site for the given grid + std::string getWebProfileURL(const std::string& grid); + + /// Return the url of the resident profile web site for the selected grid + std::string getWebProfileURL() { return getWebProfileURL(mGrid); } + + //@} /* ================================================================ @@ -216,6 +222,7 @@ class LLGridManager : public LLSingleton<LLGridManager> const std::string& helper, const std::string& login_page, const std::string& update_url_base, + const std::string& web_profile_url, const std::string& login_id = ""); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 5edc3c9745378c85e01928eb43d3ca760f434539..45dbd95bea8205f1adc6d96ffdd2a76f90a7e9b2 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -102,6 +102,7 @@ #include "llmediaentry.h" #include "llfloaterperms.h" #include "llvocache.h" +#include "llcleanup.h" //#define DEBUG_UPDATE_TYPE @@ -244,9 +245,10 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mPixelArea(1024.f), mInventory(NULL), mInventorySerialNum(0), - mRegionp( regionp ), - mInventoryPending(FALSE), + mInvRequestState(INVENTORY_REQUEST_STOPPED), + mInvRequestXFerId(0), mInventoryDirty(FALSE), + mRegionp(regionp), mDead(FALSE), mOrphaned(FALSE), mUserSelected(FALSE), @@ -370,7 +372,7 @@ void LLViewerObject::markDead() if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id)) { // This case is needed for indirectly attached mesh objects. - av->resetJointPositionsOnDetach(mesh_id); + av->resetJointsOnDetach(mesh_id); } // Mark itself as dead @@ -529,11 +531,11 @@ void LLViewerObject::initVOClasses() void LLViewerObject::cleanupVOClasses() { - LLVOGrass::cleanupClass(); - LLVOWater::cleanupClass(); - LLVOTree::cleanupClass(); - LLVOAvatar::cleanupClass(); - LLVOVolume::cleanupClass(); + SUBSYSTEM_CLEANUP(LLVOGrass); + SUBSYSTEM_CLEANUP(LLVOWater); + SUBSYSTEM_CLEANUP(LLVOTree); + SUBSYSTEM_CLEANUP(LLVOAvatar); + SUBSYSTEM_CLEANUP(LLVOVolume); sObjectDataMap.clear(); } @@ -1434,10 +1436,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, setChanged(MOVED | SILHOUETTE); } - else if (mText.notNull()) + else { - mText->markDead(); - mText = NULL; + if (mText.notNull()) + { + mText->markDead(); + mText = NULL; + } + mHudText.clear(); } std::string media_url; @@ -1812,10 +1818,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, setChanged(TEXTURE); } - else if(mText.notNull()) + else { - mText->markDead(); - mText = NULL; + if (mText.notNull()) + { + mText->markDead(); + mText = NULL; + } + mHudText.clear(); } std::string media_url; @@ -2832,6 +2842,11 @@ void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener) } } +BOOL LLViewerObject::isInventoryPending() +{ + return mInvRequestState != INVENTORY_REQUEST_STOPPED; +} + void LLViewerObject::clearInventoryListeners() { for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer()); @@ -2870,7 +2885,7 @@ void LLViewerObject::requestInventory() void LLViewerObject::fetchInventoryFromServer() { - if (!mInventoryPending) + if (!isInventoryPending()) { delete mInventory; LLMessageSystem* msg = gMessageSystem; @@ -2883,7 +2898,7 @@ void LLViewerObject::fetchInventoryFromServer() msg->sendReliable(mRegionp->getHost()); // this will get reset by dirtyInventory or doInventoryCallback - mInventoryPending = TRUE; + mInvRequestState = INVENTORY_REQUEST_PENDING; } } @@ -2944,7 +2959,7 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data) std::string unclean_filename; msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, unclean_filename); ft->mFilename = LLDir::getScrubbedFileName(unclean_filename); - + if(ft->mFilename.empty()) { LL_DEBUGS() << "Task has no inventory" << LL_ENDL; @@ -2966,13 +2981,27 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data) delete ft; return; } - gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename), + U64 new_id = gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename), ft->mFilename, LL_PATH_CACHE, object->mRegionp->getHost(), TRUE, &LLViewerObject::processTaskInvFile, (void**)ft, LLXferManager::HIGH_PRIORITY); + if (object->mInvRequestState == INVENTORY_XFER) + { + if (new_id > 0 && new_id != object->mInvRequestXFerId) + { + // we started new download. + gXferManager->abortRequestById(object->mInvRequestXFerId, -1); + object->mInvRequestXFerId = new_id; + } + } + else + { + object->mInvRequestState = INVENTORY_XFER; + object->mInvRequestXFerId = new_id; + } } void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status) @@ -3099,7 +3128,10 @@ void LLViewerObject::doInventoryCallback() mInventoryCallbacks.erase(curiter); } } - mInventoryPending = FALSE; + + // release inventory loading state + mInvRequestXFerId = 0; + mInvRequestState = INVENTORY_REQUEST_STOPPED; } void LLViewerObject::removeInventory(const LLUUID& item_id) @@ -4990,8 +5022,26 @@ void LLViewerObject::initHudText() void LLViewerObject::restoreHudText() { - if(mText) + if (mHudText.empty()) { + if (mText) + { + mText->markDead(); + mText = NULL; + } + } + else + { + if (!mText) + { + initHudText(); + } + else + { + // Restore default values + mText->setZCompare(TRUE); + mText->setDoFade(TRUE); + } mText->setColor(mHudTextColor); mText->setString(mHudText); } @@ -6271,7 +6321,7 @@ const LLUUID &LLViewerObject::extractAttachmentItemID() return getAttachmentItemID(); } -const std::string& LLViewerObject::getAttachmentItemName() +const std::string& LLViewerObject::getAttachmentItemName() const { static std::string empty; LLInventoryItem *item = gInventory.getItem(getAttachmentItemID()); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index cb8acfdcf82dd9ca0fadd4889a88c329c4aec8db..1e8f3f4ec2d5755e15153caa3d185c3867a97ac0 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -172,7 +172,7 @@ class LLViewerObject void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; } virtual BOOL isAttachment() const { return FALSE; } - const std::string& getAttachmentItemName(); + 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 virtual BOOL isHUDAttachment() const { return FALSE; } @@ -437,7 +437,7 @@ class LLViewerObject // viewer object has the inventory stored locally. void registerInventoryListener(LLVOInventoryListener* listener, void* user_data); void removeInventoryListener(LLVOInventoryListener* listener); - BOOL isInventoryPending() { return mInventoryPending; } + BOOL isInventoryPending(); void clearInventoryListeners(); bool hasInventoryListeners(); void requestInventory(); @@ -720,6 +720,7 @@ class LLViewerObject 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 @@ -756,9 +757,17 @@ class LLViewerObject callback_list_t mInventoryCallbacks; S16 mInventorySerialNum; + enum EInventoryRequestState + { + INVENTORY_REQUEST_STOPPED, + INVENTORY_REQUEST_PENDING, + INVENTORY_XFER + }; + EInventoryRequestState mInvRequestState; + U64 mInvRequestXFerId; + BOOL mInventoryDirty; + LLViewerRegion *mRegionp; // Region that this object belongs to. - BOOL mInventoryPending; - BOOL mInventoryDirty; BOOL mDead; BOOL mOrphaned; // This is an orphaned child BOOL mUserSelected; // Cached user select information diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index bb6bbf33083127c29b7e04d8cf7d1c65b7d70ae5..29219843c9ef20b3ea5161a9d28dcd65b37882d4 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -75,6 +75,8 @@ class LLParcelObserver class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr> { + LLSINGLETON(LLViewerParcelMgr); + ~LLViewerParcelMgr(); public: typedef boost::function<void (const LLVector3d&, const bool& local)> teleport_finished_callback_t; @@ -82,9 +84,6 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr> typedef boost::function<void()> teleport_failed_callback_t; typedef boost::signals2::signal<void()> teleport_failed_signal_t; - LLViewerParcelMgr(); - ~LLViewerParcelMgr(); - static void cleanupGlobals(); BOOL selectionEmpty() const; diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index 40e8e1d45df1322a758fa8682c9858ffce0972b9..ab1cd715ab225552ce52b213f0f0028a13dcf021 100644 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -135,9 +135,8 @@ class LLViewerPartGroup class LLViewerPartSim : public LLSingleton<LLViewerPartSim> { + LLSINGLETON(LLViewerPartSim); public: - LLViewerPartSim(); - virtual ~LLViewerPartSim(){} void destroyClass(); typedef std::vector<LLViewerPartGroup *> group_list_t; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index dafe2cafec02676632892c7871201e6be3f52432..3e0cec0f0999e7fb19b05ae4141f28bd03789070 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -27,6 +27,8 @@ #include "llviewerprecompiledheaders.h" +#include <boost/lexical_cast.hpp> + #include "llfeaturemanager.h" #include "llviewershadermgr.h" @@ -41,6 +43,8 @@ #include "llsky.h" #include "llvosky.h" #include "llrender.h" +#include "lljoint.h" +#include "llskinningutil.h" #ifdef LL_RELEASE_FOR_DOWNLOAD #define UNIFORM_ERRS LL_WARNS_ONCE("Shader") @@ -871,7 +875,9 @@ BOOL LLViewerShaderMgr::loadBasicShaders() shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); boost::unordered_map<std::string, std::string> attribs; - + attribs["MAX_JOINTS_PER_MESH_OBJECT"] = + boost::lexical_cast<std::string>(LLSkinningUtil::getMaxJointCount()); + // 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++) { diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 7843652589f7621b60fa7db3696dcbb3d3ecbabe..97a060d95e401102b79c8281e891a065b47201c1 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -246,13 +246,11 @@ extern LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT class LLViewerStats : public LLSingleton<LLViewerStats> { -public: - void resetStats(); + LLSINGLETON(LLViewerStats); + ~LLViewerStats(); public: - - LLViewerStats(); - ~LLViewerStats(); + void resetStats(); void updateFrameStats(const F64Seconds time_diff); diff --git a/indra/newview/llviewerstatsrecorder.h b/indra/newview/llviewerstatsrecorder.h index d1744f4910d66eaac242ca3af0d3033988260b4f..c974bea49de5f38cdb55016809c719ab72dd1446 100644 --- a/indra/newview/llviewerstatsrecorder.h +++ b/indra/newview/llviewerstatsrecorder.h @@ -44,11 +44,11 @@ class LLViewerObject; class LLViewerStatsRecorder : public LLSingleton<LLViewerStatsRecorder> { - public: - LOG_CLASS(LLViewerStatsRecorder); - LLViewerStatsRecorder(); + LLSINGLETON(LLViewerStatsRecorder); + LOG_CLASS(LLViewerStatsRecorder); ~LLViewerStatsRecorder(); + public: void objectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size) { #if LL_RECORD_VIEWER_STATS diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index ed719ae41827b8127bc55ec813f1c541eb6a4164..6abd6f7b643d63747c17c215e9b5903fb9617524 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -488,7 +488,7 @@ bool LLViewerTexture::isMemoryForTextureLow() LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK); - const S32Megabytes MIN_FREE_TEXTURE_MEMORY(5); //MB + const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20); //MB Changed to 20 MB per MAINT-6882 const S32Megabytes MIN_FREE_MAIN_MEMORY(100); //MB bool low_mem = false; @@ -511,18 +511,17 @@ bool LLViewerTexture::isMemoryForTextureLow() } } } -#if 0 //ignore nVidia cards + //Enabled this branch per MAINT-6882 else if (gGLManager.mHasNVXMemInfo) { S32 free_memory; glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); - if(free_memory / 1024 < MIN_FREE_TEXTURE_MEMORY) + if ((S32Megabytes)(free_memory / 1024) < MIN_FREE_TEXTURE_MEMORY) { low_mem = true; } } -#endif return low_mem; } @@ -1200,7 +1199,7 @@ void LLViewerFetchedTexture::loadFromFastCache() { S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS; S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; - if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) + if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)) { // scale oversized icon, no need to give more work to gl mRawImage->scale(expected_width, expected_height); @@ -1419,11 +1418,17 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) destroyRawImage(); return FALSE; } - mNeedsCreateTexture = FALSE; + mNeedsCreateTexture = FALSE; if (mRawImage.isNull()) { LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL; } + if (mRawImage->isBufferInvalid()) + { + LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL; + destroyRawImage(); + return FALSE; + } // LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", // mRawDiscardLevel, // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize()) @@ -1981,7 +1986,7 @@ bool LLViewerFetchedTexture::updateFetch() { S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS; S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; - if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) + if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)) { // scale oversized icon, no need to give more work to gl mRawImage->scale(expected_width, expected_height); diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index ba7677083852f6d39aa555199fe42699996d5d06..070544063ac5854b3ae9ef8e4fb82c2438625e0a 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -237,6 +237,7 @@ class LLViewerTextureList class LLUIImageList : public LLImageProviderInterface, public LLSingleton<LLUIImageList> { + LLSINGLETON_EMPTY_CTOR(LLUIImageList); public: // LLImageProviderInterface /*virtual*/ LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority); diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index 0f73515b5d8331909708758fa9a2baa8b14425b0..ae9ce37a28cfd6c5307459d1999d7bcacb227d49 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -70,7 +70,7 @@ class LLOverrideBakedTextureUpdate }; // Private local functions -static std::string asset_id_to_filename(const LLUUID &asset_id); +static std::string asset_id_to_filename(const LLUUID &asset_id, const ELLPath dir_spec); LLViewerWearable::LLViewerWearable(const LLTransactionID& transaction_id) : LLWearable(), @@ -451,7 +451,7 @@ void LLViewerWearable::copyDataFrom(const LLViewerWearable* src) // Probably reduntant, but ensure that the newly created wearable is not dirty by setting current value of params in new wearable // to be the same as the saved values (which were loaded from src at param->cloneParam(this)) - revertValues(); + revertValuesWithoutUpdate(); } void LLViewerWearable::setItemID(const LLUUID& item_id) @@ -471,6 +471,11 @@ void LLViewerWearable::revertValues() } } +void LLViewerWearable::revertValuesWithoutUpdate() +{ + LLWearable::revertValues(); +} + void LLViewerWearable::saveValues() { LLWearable::saveValues(); @@ -508,7 +513,7 @@ void LLViewerWearable::saveNewAsset() const // LL_INFOS() << "LLViewerWearable::saveNewAsset() type: " << getTypeName() << LL_ENDL; //LL_INFOS() << *this << LL_ENDL; - const std::string filename = asset_id_to_filename(mAssetID); + const std::string filename = asset_id_to_filename(mAssetID, LL_PATH_CACHE); if(! exportFile(filename)) { std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str()); @@ -520,6 +525,12 @@ void LLViewerWearable::saveNewAsset() const return; } + if (gSavedSettings.getBOOL("LogWearableAssetSave")) + { + const std::string log_filename = asset_id_to_filename(mAssetID, LL_PATH_LOGS); + exportFile(log_filename); + } + // save it out to database if( gAssetStorage ) { @@ -568,7 +579,7 @@ void LLViewerWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* } // Delete temp file - const std::string src_filename = asset_id_to_filename(new_asset_id); + const std::string src_filename = asset_id_to_filename(new_asset_id, LL_PATH_CACHE); LLFile::remove(src_filename); // delete the context data @@ -605,10 +616,10 @@ std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w) return s; } -std::string asset_id_to_filename(const LLUUID &asset_id) +std::string asset_id_to_filename(const LLUUID &asset_id, const ELLPath dir_spec) { std::string asset_id_string; asset_id.toString(asset_id_string); - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl"; + std::string filename = gDirUtilp->getExpandedFilename(dir_spec,asset_id_string) + ".wbl"; return filename; } diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h index 62cd5e21add899551997d32ba06a1b773e315f4a..cc99f6af2f72f812ac10e827c32cff9c89a0d261 100644 --- a/indra/newview/llviewerwearable.h +++ b/indra/newview/llviewerwearable.h @@ -85,6 +85,8 @@ class LLViewerWearable : public LLWearable /*virtual*/ void revertValues(); /*virtual*/ void saveValues(); + void revertValuesWithoutUpdate(); + // Something happened that requires the wearable's label to be updated (e.g. worn/unworn). /*virtual*/void setUpdated() const; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index c17c50fd88114e9f8031434476f2f98adb0dda42..7a60a8e9ac330c1d3dd53dd7297cac467f9b1fc1 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -208,6 +208,7 @@ #include "llwindowlistener.h" #include "llviewerwindowlistener.h" #include "llpaneltopinfobar.h" +#include "llcleanup.h" #if LL_WINDOWS #include <tchar.h> // For Unicode conversion methods @@ -251,6 +252,11 @@ BOOL gDisplayBadge = FALSE; static const U8 NO_FACE = 255; BOOL gQuietSnapshot = FALSE; +// Minimum value for UIScaleFactor, also defined in preferences, ui_scale_slider +static const F32 MIN_UI_SCALE = 0.75f; +// 4.0 in preferences, but win10 supports larger scaling and value is used more as +// sanity check, so leaving space for larger values from DPI updates. +static const F32 MAX_UI_SCALE = 7.0f; static const F32 MIN_DISPLAY_SCALE = 0.75f; std::string LLViewerWindow::sSnapshotBaseName; @@ -287,13 +293,8 @@ class RecordToChatConsoleRecorder : public LLError::Recorder class RecordToChatConsole : public LLSingleton<RecordToChatConsole> { + LLSINGLETON(RecordToChatConsole); public: - RecordToChatConsole() - : LLSingleton<RecordToChatConsole>(), - mRecorder(new RecordToChatConsoleRecorder()) - { - } - void startRecorder() { LLError::addRecorder(mRecorder); } void stopRecorder() { LLError::removeRecorder(mRecorder); } @@ -301,6 +302,11 @@ class RecordToChatConsole : public LLSingleton<RecordToChatConsole> LLError::RecorderPtr mRecorder; }; +RecordToChatConsole::RecordToChatConsole(): + mRecorder(new RecordToChatConsoleRecorder()) +{ +} + //////////////////////////////////////////////////////////////////////////// // // LLDebugText @@ -742,45 +748,45 @@ class LLDebugText } // only display these messages if we are actually rendering beacons at this moment - if (LLPipeline::getRenderBeacons(NULL) && LLFloaterReg::instanceVisible("beacons")) + if (LLPipeline::getRenderBeacons() && LLFloaterReg::instanceVisible("beacons")) { - if (LLPipeline::getRenderMOAPBeacons(NULL)) + if (LLPipeline::getRenderMOAPBeacons()) { addText(xpos, ypos, "Viewing media beacons (white)"); ypos += y_inc; } - if (LLPipeline::toggleRenderTypeControlNegated((void*)LLPipeline::RENDER_TYPE_PARTICLES)) + if (LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES)) { addText(xpos, ypos, particle_hiding); ypos += y_inc; } - if (LLPipeline::getRenderParticleBeacons(NULL)) + if (LLPipeline::getRenderParticleBeacons()) { addText(xpos, ypos, "Viewing particle beacons (blue)"); ypos += y_inc; } - if (LLPipeline::getRenderSoundBeacons(NULL)) + if (LLPipeline::getRenderSoundBeacons()) { addText(xpos, ypos, "Viewing sound beacons (yellow)"); ypos += y_inc; } - if (LLPipeline::getRenderScriptedBeacons(NULL)) + if (LLPipeline::getRenderScriptedBeacons()) { addText(xpos, ypos, beacon_scripted); ypos += y_inc; } else - if (LLPipeline::getRenderScriptedTouchBeacons(NULL)) + if (LLPipeline::getRenderScriptedTouchBeacons()) { addText(xpos, ypos, beacon_scripted_touch); ypos += y_inc; } - if (LLPipeline::getRenderPhysicalBeacons(NULL)) + if (LLPipeline::getRenderPhysicalBeacons()) { addText(xpos, ypos, "Viewing physical object beacons (green)"); ypos += y_inc; @@ -1593,6 +1599,23 @@ BOOL LLViewerWindow::handleDeviceChange(LLWindow *window) return FALSE; } +BOOL LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height) +{ + if (ui_scale_factor >= MIN_UI_SCALE && ui_scale_factor <= MAX_UI_SCALE) + { + gSavedSettings.setF32("LastSystemUIScaleFactor", ui_scale_factor); + gSavedSettings.setF32("UIScaleFactor", ui_scale_factor); + LLViewerWindow::reshape(window_width, window_height); + mResDirty = true; + return TRUE; + } + else + { + LL_WARNS() << "DPI change caused UI scale to go out of bounds: " << ui_scale_factor << LL_ENDL; + return FALSE; + } +} + void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg) { LLAppViewer::instance()->pingMainloopTimeout(msg); @@ -1655,7 +1678,8 @@ LLViewerWindow::LLViewerWindow(const Params& p) mResDirty(false), mStatesDirty(false), mCurrResolutionIndex(0), - mProgressView(NULL) + mProgressView(NULL), + mSystemUIScaleFactorChanged(false) { // 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 @@ -1743,9 +1767,24 @@ LLViewerWindow::LLViewerWindow(const Params& p) gSavedSettings.setS32("FullScreenHeight",scr.mY); } + + F32 system_scale_factor = mWindow->getSystemUISize(); + if (system_scale_factor < MIN_UI_SCALE || system_scale_factor > MAX_UI_SCALE) + { + // reset to default; + system_scale_factor = 1.f; + } + if (p.first_run || gSavedSettings.getF32("LastSystemUIScaleFactor") != system_scale_factor) + { + mSystemUIScaleFactorChanged = !p.first_run; + gSavedSettings.setF32("LastSystemUIScaleFactor", system_scale_factor); + gSavedSettings.setF32("UIScaleFactor", system_scale_factor); + } + + // 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 = gSavedSettings.getF32("UIScaleFactor"); + F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE); mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); mDisplayScale *= ui_scale_factor; @@ -1838,6 +1877,28 @@ LLViewerWindow::LLViewerWindow(const Params& p) mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale); } +//static +void LLViewerWindow::showSystemUIScaleFactorChanged() +{ + LLNotificationsUtil::add("SystemUIScaleFactorChanged", LLSD(), LLSD(), onSystemUIScaleFactorChanged); +} + +//static +bool LLViewerWindow::onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if(option == 0) + { + LLFloaterReg::toggleInstanceOrBringToFront("preferences"); + LLFloater* pref_floater = LLFloaterReg::getInstance("preferences"); + LLTabContainer* tab_container = pref_floater->getChild<LLTabContainer>("pref core"); + tab_container->selectTabByName("advanced1"); + + } + return false; +} + + void LLViewerWindow::initGLDefaults() { gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -2119,10 +2180,7 @@ void LLViewerWindow::shutdownViews() // destroy the nav bar, not currently part of gViewerWindow // *TODO: Make LLNavigationBar part of gViewerWindow - if (LLNavigationBar::instanceExists()) - { - delete LLNavigationBar::getInstance(); - } + LLNavigationBar::deleteSingleton(); LL_INFOS() << "LLNavigationBar destroyed." << LL_ENDL ; // destroy menus after instantiating navbar above, as it needs @@ -2158,7 +2216,7 @@ void LLViewerWindow::shutdownGL() // Shutdown GL cleanly. Order is very important here. //-------------------------------------------------------- LLFontGL::destroyDefaultFonts(); - LLFontManager::cleanupClass(); + SUBSYSTEM_CLEANUP(LLFontManager); stop_glerror(); gSky.cleanup(); @@ -2181,7 +2239,7 @@ void LLViewerWindow::shutdownGL() LLWorldMapView::cleanupTextures(); LLViewerTextureManager::cleanup() ; - LLImageGL::cleanupClass() ; + SUBSYSTEM_CLEANUP(LLImageGL) ; LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ; @@ -2194,7 +2252,7 @@ void LLViewerWindow::shutdownGL() gGL.shutdown(); - LLVertexBuffer::cleanupClass(); + SUBSYSTEM_CLEANUP(LLVertexBuffer); LL_INFOS() << "LLVertexBuffer cleaned." << LL_ENDL ; } @@ -4364,7 +4422,7 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height) } } -BOOL LLViewerWindow::saveSnapshot( const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) +BOOL LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type) { LL_INFOS() << "Saving snapshot to: " << filepath << LL_ENDL; @@ -4403,7 +4461,7 @@ void LLViewerWindow::playSnapshotAnimAndSound() send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f); } -BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) +BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type) { return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type); } @@ -4412,7 +4470,7 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p // Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy // the results over to the final raw image. BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, - BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size) + BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, S32 max_size) { if (!raw) { @@ -4443,7 +4501,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei if ( prev_draw_ui != show_ui) { - LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); + LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); } BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments; @@ -4620,7 +4678,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot"); } - if (type == SNAPSHOT_TYPE_COLOR) + if (type == LLSnapshotModel::SNAPSHOT_TYPE_COLOR) { glReadPixels( subimage_x_offset, out_y + subimage_y_offset, @@ -4629,7 +4687,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei raw->getData() + output_buffer_offset ); } - else // SNAPSHOT_TYPE_DEPTH + 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( @@ -4666,7 +4724,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei // POST SNAPSHOT if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); + LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); } if (hide_hud) @@ -5211,7 +5269,7 @@ F32 LLViewerWindow::getWorldViewAspectRatio() const void LLViewerWindow::calcDisplayScale() { - F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor"); + F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), 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; @@ -5224,7 +5282,7 @@ void LLViewerWindow::calcDisplayScale() if (display_scale != mDisplayScale) { - LL_INFOS() << "Setting display scale to " << display_scale << LL_ENDL; + LL_INFOS() << "Setting display scale to " << display_scale << " for ui scale: " << ui_scale_factor << LL_ENDL; mDisplayScale = display_scale; // Init default fonts diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index ad06f00234a9e08270ccc9e4d714c3f421324e2a..a134dfaaa98342aaacfc52009e10bc90a33fbd9b 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -46,6 +46,7 @@ #include "llhandle.h" #include "llinitparam.h" #include "lltrace.h" +#include "llsnapshotmodel.h" #include <boost/function.hpp> #include <boost/signals2.hpp> @@ -155,7 +156,8 @@ class LLViewerWindow : public LLWindowCallbacks min_width, min_height; Optional<bool> fullscreen, - ignore_pixel_depth; + ignore_pixel_depth, + first_run; Params(); }; @@ -209,6 +211,7 @@ class LLViewerWindow : public LLWindowCallbacks /*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*/ void handlePingWatchdog(LLWindow *window, const char * msg); /*virtual*/ void handlePauseWatchdog(LLWindow *window); @@ -342,15 +345,11 @@ class LLViewerWindow : public LLWindowCallbacks // snapshot functionality. // perhaps some of this should move to llfloatershapshot? -MG - typedef enum - { - SNAPSHOT_TYPE_COLOR, - SNAPSHOT_TYPE_DEPTH - } ESnapshotType; - BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR); + + BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR); BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE, - BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE ); - BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ; + BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE); + BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type); BOOL isSnapshotLocSet() const { return ! sSnapshotDir.empty(); } void resetSnapshotLoc() const { sSnapshotDir.clear(); } BOOL saveImageNumbered(LLImageFormatted *image, bool force_picker = false); @@ -418,6 +417,9 @@ class LLViewerWindow : public LLWindowCallbacks void calcDisplayScale(); static LLRect calcScaledRect(const LLRect & rect, const LLVector2& display_scale); + bool getSystemUIScaleFactorChanged() { return mSystemUIScaleFactorChanged; } + static void showSystemUIScaleFactorChanged(); + private: bool shouldShowToolTipFor(LLMouseHandler *mh); @@ -431,6 +433,7 @@ class LLViewerWindow : public LLWindowCallbacks S32 getChatConsoleBottomPad(); // Vertical padding for child console rect, varied by bottom clutter LLRect getChatConsoleRect(); // Get optimal cosole rect. + static bool onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response); private: LLWindow* mWindow; // graphical window object bool mActive; @@ -509,6 +512,7 @@ class LLViewerWindow : public LLWindowCallbacks LLPointer<LLViewerObject> mDragHoveredObject; static LLTrace::SampleStatHandle<> sMouseVelocityStat; + bool mSystemUIScaleFactorChanged; // system UI scale factor changed from last run }; // diff --git a/indra/newview/llviewerwindowlistener.cpp b/indra/newview/llviewerwindowlistener.cpp index 1fe5fc9800c0591c0e2d072f2182c68904b20493..97b405c1d0943ed0f61f0cf72d79ba00e12f8bf1 100644 --- a/indra/newview/llviewerwindowlistener.cpp +++ b/indra/newview/llviewerwindowlistener.cpp @@ -65,9 +65,9 @@ LLViewerWindowListener::LLViewerWindowListener(LLViewerWindow* llviewerwindow): void LLViewerWindowListener::saveSnapshot(const LLSD& event) const { - typedef std::map<LLSD::String, LLViewerWindow::ESnapshotType> TypeMap; + typedef std::map<LLSD::String, LLSnapshotModel::ESnapshotLayerType> TypeMap; TypeMap types; -#define tp(name) types[#name] = LLViewerWindow::SNAPSHOT_TYPE_##name +#define tp(name) types[#name] = LLSnapshotModel::SNAPSHOT_TYPE_##name tp(COLOR); tp(DEPTH); #undef tp @@ -84,7 +84,7 @@ void LLViewerWindowListener::saveSnapshot(const LLSD& event) const if (event.has("showui")) showui = event["showui"].asBoolean(); bool rebuild(event["rebuild"]); // defaults to false - LLViewerWindow::ESnapshotType type(LLViewerWindow::SNAPSHOT_TYPE_COLOR); + LLSnapshotModel::ESnapshotLayerType type(LLSnapshotModel::SNAPSHOT_TYPE_COLOR); if (event.has("type")) { TypeMap::const_iterator found = types.find(event["type"]); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 672d153e51c193323c5b906fcb216ea28d4e8c72..96a1beffbc326354a47cf26765220df5b853087c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -106,6 +106,8 @@ #include "llsdutil.h" #include "llscenemonitor.h" #include "llsdserialize.h" +#include "llcallstack.h" +#include "llrendersphere.h" extern F32 SPEED_ADJUST_MAX; extern F32 SPEED_ADJUST_MAX_SEC; @@ -186,6 +188,7 @@ const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f; const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f; const U32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0; +const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024; enum ERenderName { @@ -214,26 +217,8 @@ struct LLTextureMaskData ** **/ -//------------------------------------------------------------------------ -// LLVOAvatarBoneInfo -// Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton. -//------------------------------------------------------------------------ -struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarCollisionVolumeInfo> -{ - LLVOAvatarCollisionVolumeInfo() - : name("name"), - pos("pos"), - rot("rot"), - scale("scale") - {} - Mandatory<std::string> name; - Mandatory<LLVector3> pos, - rot, - scale; -}; - -struct LLAppearanceMessageContents +struct LLAppearanceMessageContents: public LLRefCount { LLAppearanceMessageContents(): mAppearanceVersion(-1), @@ -253,49 +238,6 @@ struct LLAppearanceMessageContents bool mHoverOffsetWasSet; }; -struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint> - { - Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> > bone; - Alternative<LLVOAvatarCollisionVolumeInfo> collision_volume; - - LLVOAvatarChildJoint() - : bone("bone"), - collision_volume("collision_volume") - {} -}; - - - -struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo> -{ - LLVOAvatarBoneInfo() - : pivot("pivot") - {} - - Mandatory<LLVector3> pivot; - Multiple<LLVOAvatarChildJoint> children; -}; - -//------------------------------------------------------------------------ -// LLVOAvatarSkeletonInfo -// Overall avatar skeleton -//------------------------------------------------------------------------ -struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo> -{ - LLVOAvatarSkeletonInfo() - : skeleton_root(""), - num_bones("num_bones"), - num_collision_volumes("num_collision_volumes"), - version("version") - {} - - Mandatory<std::string> version; - Mandatory<S32> num_bones, - num_collision_volumes; - Mandatory<LLVOAvatarChildJoint> skeleton_root; -}; - - //----------------------------------------------------------------------------- // class LLBodyNoiseMotion @@ -1111,7 +1053,6 @@ void LLVOAvatar::deleteCachedImages(bool clearAll) { if (LLViewerTexLayerSet::sHasCaches) { - LL_DEBUGS() << "Deleting layer set caches" << LL_ENDL; for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) { @@ -1142,6 +1083,9 @@ void LLVOAvatar::initClass() 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")); } @@ -1395,18 +1339,78 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) newMax.add(buffer); } +void render_sphere_and_line(const LLVector3& begin_pos, const LLVector3& end_pos, F32 sphere_scale, const LLVector3& occ_color, const LLVector3& visible_color) +{ + // Unoccluded bone portions + LLGLDepthTest normal_depth(GL_TRUE); + + // Draw line segment for unoccluded joint + gGL.diffuseColor3f(visible_color[0], visible_color[1], visible_color[2]); + + gGL.begin(LLRender::LINES); + 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(end_pos.mV); + gGL.end(); + + // Draw sphere representing joint pos + gGL.pushMatrix(); + gGL.scalef(sphere_scale, sphere_scale, sphere_scale); + gSphere.renderGGL(); + gGL.popMatrix(); +} + //----------------------------------------------------------------------------- // renderCollisionVolumes() //----------------------------------------------------------------------------- void LLVOAvatar::renderCollisionVolumes() { std::ostringstream ostr; + for (S32 i = 0; i < mNumCollisionVolumes; i++) { - mCollisionVolumes[i].renderCollision(); ostr << mCollisionVolumes[i].getName() << ", "; - } + LLAvatarJointCollisionVolume& collision_volume = mCollisionVolumes[i]; + + collision_volume.updateWorldMatrix(); + + gGL.pushMatrix(); + gGL.multMatrix( &collision_volume.getXform()->getWorldMatrix().mMatrix[0][0] ); + + LLVector3 begin_pos(0,0,0); + LLVector3 end_pos(collision_volume.getEnd()); + static F32 sphere_scale = 1.0f; + static F32 center_dot_scale = 0.05f; + + static LLVector3 CV_COLOR_OCCLUDED(0.0f, 0.0f, 1.0f); + static LLVector3 CV_COLOR_VISIBLE(0.5f, 0.5f, 1.0f); + static LLVector3 DOT_COLOR_OCCLUDED(1.0f, 1.0f, 1.0f); + static LLVector3 DOT_COLOR_VISIBLE(1.0f, 1.0f, 1.0f); + + render_sphere_and_line(begin_pos, end_pos, sphere_scale, CV_COLOR_OCCLUDED, CV_COLOR_VISIBLE); + render_sphere_and_line(begin_pos, end_pos, center_dot_scale, DOT_COLOR_OCCLUDED, DOT_COLOR_VISIBLE); + + gGL.popMatrix(); + } + + if (mNameText.notNull()) { LLVector4a unused; @@ -1418,6 +1422,72 @@ void LLVOAvatar::renderCollisionVolumes() addDebugText(ostr.str()); } +void LLVOAvatar::renderBones() +{ + LLGLEnable blend(GL_BLEND); + + avatar_joint_list_t::iterator iter = mSkeleton.begin(); + avatar_joint_list_t::iterator end = mSkeleton.end(); + + // For bones with position overrides defined + static LLVector3 OVERRIDE_COLOR_OCCLUDED(1.0f, 0.0f, 0.0f); + static LLVector3 OVERRIDE_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); + // For bones which are rigged to by at least one attachment + static LLVector3 RIGGED_COLOR_OCCLUDED(0.0f, 1.0f, 1.0f); + static LLVector3 RIGGED_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); + // 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; + } + + jointp->updateWorldMatrix(); + + LLVector3 occ_color, visible_color; + + LLVector3 pos; + LLUUID mesh_id; + if (jointp->hasAttachmentPosOverride(pos,mesh_id)) + { + occ_color = OVERRIDE_COLOR_OCCLUDED; + visible_color = OVERRIDE_COLOR_VISIBLE; + } + else + { + if (jointIsRiggedTo(jointp->getName())) + { + occ_color = RIGGED_COLOR_OCCLUDED; + visible_color = RIGGED_COLOR_VISIBLE; + } + else + { + occ_color = OTHER_COLOR_OCCLUDED; + visible_color = OTHER_COLOR_VISIBLE; + } + } + LLVector3 begin_pos(0,0,0); + LLVector3 end_pos(jointp->getEnd()); + + F32 sphere_scale = SPHERE_SCALEF; + + gGL.pushMatrix(); + gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] ); + + render_sphere_and_line(begin_pos, end_pos, sphere_scale, occ_color, visible_color); + + gGL.popMatrix(); + } +} + + void LLVOAvatar::renderJoints() { std::ostringstream ostr; @@ -1525,7 +1595,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& 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(); @@ -1734,6 +1804,133 @@ void LLVOAvatar::buildCharacter() mMeshValid = TRUE; } +//----------------------------------------------------------------------------- +// resetVisualParams() +//----------------------------------------------------------------------------- +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())); + *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; + LLDriverParam *param = dynamic_cast<LLDriverParam*>(getVisualParam(info->getID())); + LLDriverParam::entry_list_t driven_list = param->getDrivenList(); + *param = LLDriverParam(this); + llassert(param); + if (!param->setInfo(info)) + { + llassert(false); + } + param->setDrivenList(driven_list); + } +} + +//----------------------------------------------------------------------------- +// resetSkeleton() +//----------------------------------------------------------------------------- +void LLVOAvatar::resetSkeleton(bool reset_animations) +{ + LL_DEBUGS("Avatar") << avString() << " reset starts" << LL_ENDL; + if (!mLastProcessedAppearance) + { + LL_WARNS() << "Can't reset avatar; no appearance message has been received yet." << LL_ENDL; + return; + } + + // Save mPelvis state + //LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition(); + //LLQuaternion pelvis_rot = getJoint("mPelvis")->getRotation(); + + // Clear all attachment pos and scale overrides + clearAttachmentOverrides(); + + // Note that we call buildSkeleton twice in this function. The first time is + // 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) ) + { + LL_ERRS() << "Error resetting skeleton" << LL_ENDL; + } + + // Reset some params to default state, without propagating changes downstream. + resetVisualParams(); + + // Now we have to reset the skeleton again, because its state + // got clobbered by the resetVisualParams() calls + // above. + if( !buildSkeleton(sAvatarSkeletonInfo) ) + { + LL_ERRS() << "Error resetting skeleton" << LL_ENDL; + } + + // Reset attachment points (buildSkeleton only does bones and CVs) + bool ignore_hud_joints = true; + initAttachmentPoints(ignore_hud_joints); + + // Fix up collision volumes + for (LLVisualParam *param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + LLPolyMorphTarget *poly_morph = dynamic_cast<LLPolyMorphTarget*>(param); + if (poly_morph) + { + // This is a kludgy way to correct for the fact that the + // collision volumes have been reset out from under the + // poly morph sliders. + F32 delta_weight = poly_morph->getLastWeight() - poly_morph->getDefaultWeight(); + poly_morph->applyVolumeChanges(delta_weight); + } + } + + // Reset tweakable params to preserved state + bool slam_params = true; + applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params); + updateVisualParams(); + + // Restore attachment pos overrides + rebuildAttachmentOverrides(); + + // Animations + if (reset_animations) + { + if (isSelf()) + { + // This is equivalent to "Stop Animating Me". Will reset + // all animations and propagate the changes to other + // viewers. + gAgent.stopCurrentAnimations(); + } + else + { + // Local viewer-side reset for non-self avatars. + resetAnimations(); + } + } + + LL_DEBUGS("Avatar") << avString() << " reset ends" << LL_ENDL; +} //----------------------------------------------------------------------------- // releaseMeshData() @@ -1745,8 +1942,6 @@ void LLVOAvatar::releaseMeshData() return; } - LL_DEBUGS() << "Releasing mesh data" << LL_ENDL; - // cleanup mesh data for (avatar_joint_list_t::iterator iter = mMeshLOD.begin(); iter != mMeshLOD.end(); @@ -1956,17 +2151,12 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, // Do base class updates... U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); - //LLTEContents tec; - //S32 te_retval = parseTEMessage(mesgsys, _PREHASH_ObjectData, block_num, tec); - - LL_DEBUGS("Avatar") << avString() << update_type << LL_ENDL; - // Print out arrival information once we have name of avatar. - if (has_name && getNVPair("FirstName")) - { - mDebugExistenceTimer.reset(); - debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived"); - } + if (has_name && getNVPair("FirstName")) + { + mDebugExistenceTimer.reset(); + debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived"); + } if(retval & LLViewerObject::INVALID_UPDATE) { @@ -2074,6 +2264,8 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) return; } + LLScopedContextString str("avatar_idle_update " + getFullname()); + checkTextureLoading() ; // force immediate pixel area update on avatars using last frames data (before drawable or camera updates) @@ -3078,6 +3270,7 @@ void LLVOAvatar::idleUpdateBelowWater() void LLVOAvatar::slamPosition() { gAgent.setPositionAgent(getPositionAgent()); + // SL-315 mRoot->setWorldPosition(getPositionAgent()); // teleport setChanged(TRANSLATED); if (mDrawable.notNull()) @@ -3175,23 +3368,31 @@ void LLVOAvatar::updateDebugText() { debug_line += llformat(" - cof rcv:%d", last_received_cof_version); } - debug_line += llformat(" bsz-z: %f avofs-z: %f", mBodySize[2], mAvatarOffset[2]); + 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: %f", hover_offset[2]); + debug_line += llformat(" hov_z: %.3f", hover_offset[2]); debug_line += llformat(" %s", (mIsSitting ? "S" : "T")); debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-")); } - F32 elapsed = mLastAppearanceMessageTimer.getElapsedTimeF32(); - static const char *elapsed_chars = "Xx*..."; - U32 bucket = U32(elapsed*2); - if (bucket < strlen(elapsed_chars)) - { - debug_line += llformat(" %c", elapsed_chars[bucket]); - } + LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition(); + 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]); + debug_line += llformat(" relev %.3f", rightElev); + + LLVector3 root_pos = mRoot->getPosition(); + LLVector3 pelvis_pos = mPelvisp->getPosition(); + debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]); + addDebugText(debug_line); } if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) @@ -3376,6 +3577,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) mTimeLast = animation_time; // put the pelvis at slaved position/mRotation + // SL-315 mRoot->setWorldPosition( getPositionAgent() ); // first frame mRoot->setWorldRotation( getRotation() ); } @@ -3416,6 +3618,13 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } mInAir = in_air; + // SL-402: with the ability to animate the position of joints + // that affect the body size calculation, computed body size + // can get stale much more easily. Simplest fix is to update + // 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; @@ -3430,6 +3639,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) if (newPosition != mRoot->getXform()->getWorldPosition()) { mRoot->touch(); + // SL-315 mRoot->setWorldPosition( newPosition ); // regular update } @@ -3593,6 +3803,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) { LLVector3 pos = mDrawable->getPosition(); pos += getHoverOffset() * mDrawable->getRotation(); + // SL-315 mRoot->setPosition(pos); mRoot->setRotation(mDrawable->getRotation()); } @@ -3623,6 +3834,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) LLVector3 pos = mRoot->getWorldPosition(); pos.mV[VZ] += off_z; mRoot->touch(); + // SL-315 mRoot->setWorldPosition(pos); } } @@ -3738,10 +3950,78 @@ void LLVOAvatar::updateHeadOffset() mHeadOffset = lerp(midEyePt, mHeadOffset, u); } } + +void LLVOAvatar::debugBodySize() const +{ + LLVector3 pelvis_scale = mPelvisp->getScale(); + + // 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 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(); + 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(); + LL_DEBUGS("Avatar") << "head pos " << head << " head_scale " << head_scale << LL_ENDL; + + 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(); + LL_DEBUGS("Avatar") << "hip pos " << hip << " hip_scale " << hip_scale << LL_ENDL; + + 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(); + LL_DEBUGS("Avatar") << "ankle pos " << ankle << " ankle_scale " << ankle_scale << LL_ENDL; + + LLVector3 foot = mFootLeftp->getPosition(); + LL_DEBUGS("Avatar") << "foot pos " << foot << LL_ENDL; + + 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] - + 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]; + + // 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( void ) +void LLVOAvatar::postPelvisSetRecalc() { mRoot->updateWorldMatrixChildren(); computeBodySize(); @@ -4831,6 +5111,12 @@ void LLVOAvatar::processAnimationStateChanges() //----------------------------------------------------------------------------- BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL start ) { + // SL-402, SL-427 - we need to update body size often enough to + // keep appearances in sync, but not so often that animations + // 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 @@ -5055,18 +5341,52 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint* jointp = NULL; if (iter == mJointMap.end() || iter->second == NULL) - { //search for joint and cache found joint in lookup table + { //search for joint and cache found joint in lookup table jointp = mRoot->findJoint(name); mJointMap[name] = jointp; } else - { //return cached pointer + { //return cached pointer jointp = iter->second; } +#ifndef LL_RELEASE_FOR_DOWNLOAD + if (jointp && jointp->getName()!="mScreen" && jointp->getName()!="mRoot") + { + llassert(getJoint(jointp->getJointNum())==jointp); + } +#endif return jointp; } +LLJoint *LLVOAvatar::getJoint( S32 joint_num ) +{ + LLJoint *pJoint = NULL; + S32 collision_start = mNumBones; + S32 attachment_start = mNumBones + mNumCollisionVolumes; + if (joint_num>=attachment_start) + { + // Attachment IDs start at 1 + S32 attachment_id = joint_num - attachment_start + 1; + attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id); + if (iter != mAttachmentPoints.end()) + { + pJoint = iter->second; + } + } + else if (joint_num>=collision_start) + { + S32 collision_id = joint_num-collision_start; + pJoint = &mCollisionVolumes[collision_id]; + } + else if (joint_num>=0) + { + pJoint = mSkeleton[joint_num]; + } + llassert(!pJoint || pJoint->getJointNum() == joint_num); + return pJoint; +} + //----------------------------------------------------------------------------- // getRiggedMeshID // @@ -5097,37 +5417,121 @@ bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id) return false; } -void LLVOAvatar::clearAttachmentPosOverrides() +bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name) { - //Subsequent joints are relative to pelvis - avatar_joint_list_t::iterator iter = mSkeleton.begin(); - avatar_joint_list_t::iterator end = mSkeleton.end(); + 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) + { + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && jointIsRiggedTo(joint_name, attached_object)) + { + return true; + } + } + } + return false; +} - for (; iter != end; ++iter) +bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo) +{ + // 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) { - LLJoint* pJoint = (*iter); - pJoint->clearAttachmentPosOverrides(); + LLViewerObject *childp = *it; + if (jointIsRiggedTo(joint_name,childp)) + { + return true; + } } + + const LLVOVolume *vobj = dynamic_cast<const LLVOVolume*>(vo); + if (!vobj) + { + return false; + } + + LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); + const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); + + if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData ) + { + if (std::find(pSkinData->mJointNames.begin(), pSkinData->mJointNames.end(), joint_name) != + pSkinData->mJointNames.end()) + { + return true; + } + } + + return false; } +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(); + } + } +} + +//----------------------------------------------------------------------------- +// rebuildAttachmentOverrides +//----------------------------------------------------------------------------- +void LLVOAvatar::rebuildAttachmentOverrides() +{ + LLScopedContextString str("rebuildAttachmentOverrides " + getFullname()); + + // Attachment points + 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) + { + addAttachmentOverridesForObject(*at_it); + } + } + } +} //----------------------------------------------------------------------------- // addAttachmentPosOverridesForObject //----------------------------------------------------------------------------- -void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) +void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo) { LLVOAvatar *av = vo->getAvatarAncestor(); if (!av || (av != this)) { LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; + return; } - + + LLScopedContextString str("addAttachmentOverridesForObject " + av->getFullname()); + // 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; - addAttachmentPosOverridesForObject(childp); + addAttachmentOverridesForObject(childp); } LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo); @@ -5148,9 +5552,13 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData ) { const int bindCnt = pSkinData->mAlternateBindMatrix.size(); - if ( bindCnt > 0 ) + 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 int jointCnt = pSkinData->mJointNames.size(); const F32 pelvisZOffset = pSkinData->mPelvisOffset; const LLUUID& mesh_id = pSkinData->mMeshID; bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false; @@ -5160,24 +5568,43 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) { std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); LLJoint* pJoint = getJoint( lookingForJoint ); - if ( pJoint && pJoint->getId() != currentId ) + if (pJoint) { - pJoint->setId( currentId ); const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); - //Set the joint position - pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString() ); - - //If joint is a pelvis then handle old/new pelvis to foot values - if ( lookingForJoint == "mPelvis" ) - { - pelvisGotSet = true; - } + 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; + } + } + if (pSkinData->mLockScaleIfJointPosition) + { + // Note that unlike positions, there's no threshold check here, + // just a lock at the default value. + pJoint->addAttachmentScaleOverride(pJoint->getDefaultScale(), mesh_id, avString()); + } + } } } if (pelvisZOffset != 0.0F) { + F32 pelvis_fixup_before; + bool has_fixup_before = hasPelvisFixup(pelvis_fixup_before); addPelvisFixup( pelvisZOffset, mesh_id ); - pelvisGotSet = true; + 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; + } + } } } @@ -5191,9 +5618,122 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) } //----------------------------------------------------------------------------- -// resetJointPositionsOnDetach +// getAttachmentOverrideNames +//----------------------------------------------------------------------------- +void LLVOAvatar::getAttachmentOverrideNames(std::set<std::string>& pos_names, std::set<std::string>& scale_names) const +{ + LLVector3 pos; + LLVector3 scale; + LLUUID mesh_id; + + // Bones + 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)) + { + pos_names.insert(pJoint->getName()); + } + 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; + if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id)) + { + pos_names.insert(attachment_pt->getName()); + } + // Attachment points don't have scales. + } + +} + +//----------------------------------------------------------------------------- +// showAttachmentOverrides //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo) +void LLVOAvatar::showAttachmentOverrides(bool verbose) const +{ + std::set<std::string> pos_names, scale_names; + getAttachmentOverrideNames(pos_names, scale_names); + if (pos_names.size()) + { + std::stringstream ss; + std::copy(pos_names.begin(), pos_names.end(), std::ostream_iterator<std::string>(ss, ",")); + LL_INFOS() << getFullname() << " attachment positions defined for joints: " << ss.str() << "\n" << LL_ENDL; + } + else + { + LL_DEBUGS("Avatar") << getFullname() << " no attachment positions defined for any joints" << "\n" << LL_ENDL; + } + if (scale_names.size()) + { + std::stringstream ss; + std::copy(scale_names.begin(), scale_names.end(), std::ostream_iterator<std::string>(ss, ",")); + LL_INFOS() << getFullname() << " attachment scales defined for joints: " << ss.str() << "\n" << LL_ENDL; + } + else + { + LL_INFOS() << getFullname() << " no attachment scales defined for any joints" << "\n" << LL_ENDL; + } + + if (!verbose) + { + return; + } + + LLVector3 pos, scale; + LLUUID mesh_id; + S32 count = 0; + + // Bones + 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()); + count++; + } + 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; + if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id)) + { + attachment_pt->showAttachmentPosOverrides(getFullname()); + count++; + } + } + + if (count) + { + LL_DEBUGS("Avatar") << avString() << " end of pos, scale overrides" << LL_ENDL; + LL_DEBUGS("Avatar") << "=================================" << LL_ENDL; + } +} + +//----------------------------------------------------------------------------- +// resetJointsOnDetach +//----------------------------------------------------------------------------- +void LLVOAvatar::resetJointsOnDetach(LLViewerObject *vo) { LLVOAvatar *av = vo->getAvatarAncestor(); if (!av || (av != this)) @@ -5207,21 +5747,21 @@ void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo) it != children.end(); ++it) { LLViewerObject *childp = *it; - resetJointPositionsOnDetach(childp); + resetJointsOnDetach(childp); } // Process self. LLUUID mesh_id; if (getRiggedMeshID(vo,mesh_id)) { - resetJointPositionsOnDetach(mesh_id); + resetJointsOnDetach(mesh_id); } } //----------------------------------------------------------------------------- -// resetJointPositionsOnDetach +// resetJointsOnDetach //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id) +void LLVOAvatar::resetJointsOnDetach(const LLUUID& mesh_id) { //Subsequent joints are relative to pelvis avatar_joint_list_t::iterator iter = mSkeleton.begin(); @@ -5235,12 +5775,14 @@ void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id) //Reset joints except for pelvis if ( pJoint ) { - pJoint->setId( LLUUID::null ); - pJoint->removeAttachmentPosOverride(mesh_id, avString()); + bool dummy; // unused + pJoint->removeAttachmentPosOverride(mesh_id, avString(),dummy); + pJoint->removeAttachmentScaleOverride(mesh_id, avString()); } if ( pJoint && pJoint == pJointPelvis) { removePelvisFixup( mesh_id ); + // SL-315 pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) ); } } @@ -5372,83 +5914,99 @@ BOOL LLVOAvatar::loadSkeletonNode () return FALSE; } - // ATTACHMENTS - { - LLAvatarXmlInfo::attachment_info_list_t::iterator iter; - for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin(); - iter != sAvatarXmlInfo->mAttachmentInfoList.end(); - ++iter) - { - LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter; - if (!isSelf() && info->mJointName == "mScreen") - { //don't process screen joint for other avatars - continue; - } + bool ignore_hud_joints = false; + initAttachmentPoints(ignore_hud_joints); - LLViewerJointAttachment* attachment = new LLViewerJointAttachment(); + return TRUE; +} - attachment->setName(info->mName); - LLJoint *parentJoint = getJoint(info->mJointName); - if (!parentJoint) - { - LL_WARNS() << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << LL_ENDL; - delete attachment; - continue; - } +//----------------------------------------------------------------------------- +// 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) + { + LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter; + if (info->mIsHUDAttachment && (!isSelf() || ignore_hud_joints)) + { + //don't process hud joint for other avatars, or when doing a skeleton reset. + continue; + } - if (info->mHasPosition) - { - attachment->setOriginalPosition(info->mPosition); - } - - if (info->mHasRotation) - { - LLQuaternion rotation; - rotation.setQuat(info->mRotationEuler.mV[VX] * DEG_TO_RAD, - info->mRotationEuler.mV[VY] * DEG_TO_RAD, - info->mRotationEuler.mV[VZ] * DEG_TO_RAD); - attachment->setRotation(rotation); - } + S32 attachmentID = info->mAttachmentID; + if (attachmentID < 1 || attachmentID > 255) + { + LL_WARNS() << "Attachment point out of range [1-255]: " << attachmentID << " on attachment point " << info->mName << LL_ENDL; + continue; + } - int group = info->mGroup; - if (group >= 0) - { - if (group < 0 || group >= 9) - { - LL_WARNS() << "Invalid group number (" << group << ") for attachment point " << info->mName << LL_ENDL; - } - else - { - attachment->setGroup(group); - } - } + LLViewerJointAttachment* attachment = NULL; + bool newly_created = false; + if (mAttachmentPoints.find(attachmentID) == mAttachmentPoints.end()) + { + attachment = new LLViewerJointAttachment(); + newly_created = true; + } + else + { + attachment = mAttachmentPoints[attachmentID]; + } - S32 attachmentID = info->mAttachmentID; - if (attachmentID < 1 || attachmentID > 255) - { - LL_WARNS() << "Attachment point out of range [1-255]: " << attachmentID << " on attachment point " << info->mName << LL_ENDL; - delete attachment; - continue; - } - if (mAttachmentPoints.find(attachmentID) != mAttachmentPoints.end()) - { - LL_WARNS() << "Attachment point redefined with id " << attachmentID << " on attachment point " << info->mName << LL_ENDL; - delete attachment; - continue; - } + attachment->setName(info->mName); + LLJoint *parent_joint = getJoint(info->mJointName); + if (!parent_joint) + { + // If the intended parent for attachment point is unavailable, avatar_lad.xml is corrupt. + LL_WARNS() << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << LL_ENDL; + LL_ERRS() << "Invalid avatar_lad.xml file" << LL_ENDL; + } - attachment->setPieSlice(info->mPieMenuSlice); - attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson); - attachment->setIsHUDAttachment(info->mIsHUDAttachment); + if (info->mHasPosition) + { + attachment->setOriginalPosition(info->mPosition); + attachment->setDefaultPosition(info->mPosition); + } + + if (info->mHasRotation) + { + LLQuaternion rotation; + rotation.setQuat(info->mRotationEuler.mV[VX] * DEG_TO_RAD, + info->mRotationEuler.mV[VY] * DEG_TO_RAD, + info->mRotationEuler.mV[VZ] * DEG_TO_RAD); + attachment->setRotation(rotation); + } - mAttachmentPoints[attachmentID] = attachment; + int group = info->mGroup; + if (group >= 0) + { + if (group < 0 || group > 9) + { + LL_WARNS() << "Invalid group number (" << group << ") for attachment point " << info->mName << LL_ENDL; + } + else + { + attachment->setGroup(group); + } + } - // now add attachment joint - parentJoint->addChild(attachment); - } - } + attachment->setPieSlice(info->mPieMenuSlice); + attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson); + attachment->setIsHUDAttachment(info->mIsHUDAttachment); + // attachment can potentially be animated, needs a number. + attachment->setJointNum(mNumBones + mNumCollisionVolumes + attachmentID - 1); - return TRUE; + if (newly_created) + { + mAttachmentPoints[attachmentID] = attachment; + + // now add attachment joint + parent_joint->addChild(attachment); + } + } } //----------------------------------------------------------------------------- @@ -5920,7 +6478,7 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) LLUUID mesh_id; if (getRiggedMeshID(pVO, mesh_id)) { - resetJointPositionsOnDetach(mesh_id); + resetJointsOnDetach(mesh_id); if ( gAgentCamera.cameraCustomizeAvatar() ) { gAgent.unpauseAnimation(); @@ -6017,6 +6575,7 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) // 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(); @@ -6075,6 +6634,7 @@ void LLVOAvatar::getOffObject() sitDown(FALSE); mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject + // SL-315 mRoot->setPosition(cur_position_world); mRoot->setRotation(cur_rotation_world); mRoot->getXform()->update(); @@ -6118,7 +6678,6 @@ LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj ) return NULL; } -// warning: order(N) not order(1) S32 LLVOAvatar::getAttachmentCount() { S32 count = mAttachmentPoints.size(); @@ -7121,11 +7680,10 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value) 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\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\"/>\n", - viewer_param->getID(), viewer_param->getName().c_str(), value, u8_value, type_string.c_str(), - LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str() -// param_location_name(vparam->getParamLocation()).c_str() - ); + 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::getTypeName(LLWearableType::EType(wtype)).c_str(), + viewer_param->getGroup()); } @@ -7190,7 +7748,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe 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; + //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); @@ -7202,7 +7760,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe { 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; + //LL_DEBUGS("Avatar") << avString() << " hover received " << hover.mV[ VX ] << "," << hover.mV[ VY ] << "," << hover.mV[ VZ ] << LL_ENDL; contents.mHoverOffset = hover; contents.mHoverOffsetWasSet = true; } @@ -7212,7 +7770,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (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; + //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 @@ -7273,7 +7831,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe { 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; + //LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << LL_ENDL; } } } @@ -7302,9 +7860,9 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32 { appearance_version = 1; } - LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion - << " param: " << contents.mParamAppearanceVersion - << " final: " << appearance_version << LL_ENDL; + //LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion + // << " param: " << contents.mParamAppearanceVersion + // << " final: " << appearance_version << LL_ENDL; return true; } @@ -7325,17 +7883,15 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) mLastAppearanceMessageTimer.reset(); - ESex old_sex = getSex(); - - LLAppearanceMessageContents contents; - parseAppearanceMessage(mesgsys, contents); + LLPointer<LLAppearanceMessageContents> contents(new LLAppearanceMessageContents); + parseAppearanceMessage(mesgsys, *contents); if (enable_verbose_dumps) { - dumpAppearanceMsgParams(dump_prefix + "appearance_msg", contents); + dumpAppearanceMsgParams(dump_prefix + "appearance_msg", *contents); } S32 appearance_version; - if (!resolve_appearance_version(contents, appearance_version)) + if (!resolve_appearance_version(*contents, appearance_version)) { LL_WARNS() << "bad appearance version info, discarding" << LL_ENDL; return; @@ -7347,7 +7903,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) return; } - S32 thisAppearanceVersion(contents.mCOFVersion); + 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 @@ -7377,7 +7933,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } // SUNSHINE CLEANUP - is this case OK now? - S32 num_params = contents.mParamWeights.size(); + S32 num_params = contents->mParamWeights.size(); if (num_params <= 1) { // In this case, we have no reliable basis for knowing @@ -7389,18 +7945,30 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } // 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. LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL; - if (isSelf()) - { - // Note: - // locally the COF is maintained via LLInventoryModel::accountForUpdate - // 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. - mLastUpdateReceivedCOFVersion = thisAppearanceVersion; - } - + // Note: + // locally the COF is maintained via LLInventoryModel::accountForUpdate + // 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. + mLastUpdateReceivedCOFVersion = thisAppearanceVersion; + + mLastProcessedAppearance = contents; + + bool slam_params = false; + applyParsedAppearanceMessage(*contents, slam_params); +} + +void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params) +{ + S32 num_params = contents.mParamWeights.size(); + ESex old_sex = getSex(); + if (applyParsedTEMessage(contents.mTEContents) > 0 && isChanged(TEXTURE)) { updateVisualComplexity(); @@ -7430,8 +7998,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; mFirstAppearanceMessageReceived = TRUE; - LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID - << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; + //LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID + // << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; if (is_first_appearance_message ) { @@ -7444,7 +8012,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // Apply visual params if( num_params > 1) { - LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL; + //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; @@ -7454,12 +8022,12 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) LLVisualParam* param = contents.mParams[i]; F32 newWeight = contents.mParamWeights[i]; - if (is_first_appearance_message || (param->getWeight() != newWeight)) + if (slam_params || is_first_appearance_message || (param->getWeight() != newWeight)) { params_changed = TRUE; params_changed_count++; - if(is_first_appearance_message) + if(is_first_appearance_message || slam_params) { //LL_DEBUGS("Avatar") << "param slam " << i << " " << newWeight << LL_ENDL; param->setWeight(newWeight); @@ -7544,7 +8112,6 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } updateMeshTextures(); - //if (enable_verbose_dumps) dumpArchetypeXML(dump_prefix + "process_end"); } // static @@ -7675,7 +8242,7 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu if (selfp) { - LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; + //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; } if (!success && selfp) @@ -7693,14 +8260,14 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, 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; + //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL; } if (selfp && !success) @@ -7809,6 +8376,40 @@ void dump_sequential_xml(const std::string outprefix, const LLSD& content) LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL; } +void LLVOAvatar::getSortedJointNames(S32 joint_type, std::vector<std::string>& result) const +{ + result.clear(); + if (joint_type==0) + { + 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); + result.push_back(pJoint->getName()); + } + } + else if (joint_type==1) + { + for (S32 i = 0; i < mNumCollisionVolumes; i++) + { + LLAvatarJointCollisionVolume* pJoint = &mCollisionVolumes[i]; + result.push_back(pJoint->getName()); + } + } + 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; + result.push_back(pJoint->getName()); + } + } + std::sort(result.begin(), result.end()); +} + void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables ) { std::string outprefix(prefix); @@ -7888,28 +8489,90 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara } } - avatar_joint_list_t::iterator iter = mSkeleton.begin(); - avatar_joint_list_t::iterator end = mSkeleton.end(); - for (; iter != end; ++iter) - { - LLJoint* pJoint = (*iter); + // 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", + mRoot->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); + + // Bones + std::vector<std::string> bone_names, cv_names, attach_names, all_names; + getSortedJointNames(0, bone_names); + getSortedJointNames(1, cv_names); + getSortedJointNames(2, attach_names); + all_names.insert(all_names.end(), bone_names.begin(), bone_names.end()); + all_names.insert(all_names.end(), cv_names.begin(), cv_names.end()); + all_names.insert(all_names.end(), attach_names.begin(), attach_names.end()); + + for (std::vector<std::string>::iterator name_iter = bone_names.begin(); + 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<joint name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n", + 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]); - } + } - for (iter = mSkeleton.begin(); iter != end; ++iter) - { - LLJoint* pJoint = (*iter); + // Collision volumes + for (std::vector<std::string>::iterator name_iter = cv_names.begin(); + 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]); + } + + // Attachment joints + for (std::vector<std::string>::iterator name_iter = attach_names.begin(); + 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]); + } + + // 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; - if (pJoint->hasAttachmentPosOverride(pos,mesh_id)) + if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id)) { - apr_file_printf( file, "\t\t<joint_offset name=\"%s\" position=\"%f %f %f\" mesh_id=\"%s\"/>\n", - pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str()); + 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(), + 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; + + 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(), + num_scale_overrides, (S32) distinct_scale_overrides.size()); } } F32 pelvis_fixup; @@ -8145,6 +8808,7 @@ U32 LLVOAvatar::getPartitionType() const //static void LLVOAvatar::updateImpostors() { + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; LLCharacter::sAllowInstancesChange = FALSE; for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); @@ -8355,6 +9019,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() { U32 cost = VISUAL_COMPLEXITY_UNKNOWN; LLVOVolume::texture_cost_t textures; + hud_complexity_list_t hud_complexity_list; for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { @@ -8431,6 +9096,63 @@ void LLVOAvatar::calculateUpdateRenderComplexity() } } } + if (isSelf() + && attached_object + && attached_object->isHUDAttachment() + && !attached_object->isTempAttachment() + && attached_object->mDrawable) + { + textures.clear(); + + const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); + if (volume) + { + LLHUDComplexity hud_object_complexity; + hud_object_complexity.objectName = attached_object->getAttachmentItemName(); + hud_object_complexity.objectId = attached_object->getAttachmentItemID(); + std::string joint_name; + gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name); + hud_object_complexity.jointName = joint_name; + // get cost and individual textures + hud_object_complexity.objectsCost += volume->getRenderCost(textures); + hud_object_complexity.objectsCount++; + + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* childp = *iter; + const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp); + if (chld_volume) + { + // get cost and individual textures + hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures); + hud_object_complexity.objectsCount++; + } + } + + hud_object_complexity.texturesCount += textures.size(); + + for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); + volume_texture != textures.end(); + ++volume_texture) + { + // add the cost of each individual texture (ignores duplicates) + hud_object_complexity.texturesCost += volume_texture->second; + LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first); + if (tex) + { + // Note: Texture memory might be incorect since texture might be still loading. + hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory(); + if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE) + { + hud_object_complexity.largeTexturesCount++; + } + } + } + hud_complexity_list.push_back(hud_object_complexity); + } + } } } @@ -8447,7 +9169,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() && (all_textures.find(image_id) == all_textures.end())) { // attachment texture not previously seen. - LL_INFOS() << "attachment_texture: " << image_id.asString() << LL_ENDL; + LL_DEBUGS("ARCdetail") << "attachment_texture: " << image_id.asString() << LL_ENDL; all_textures.insert(image_id); } } @@ -8467,7 +9189,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() continue; if (all_textures.find(image_id) == all_textures.end()) { - LL_INFOS() << "local_texture: " << texture_dict->mName << ": " << image_id << LL_ENDL; + LL_DEBUGS("ARCdetail") << "local_texture: " << texture_dict->mName << ": " << image_id << LL_ENDL; all_textures.insert(image_id); } } @@ -8492,11 +9214,15 @@ void LLVOAvatar::calculateUpdateRenderComplexity() static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20); - if (isSelf() && show_my_complexity_changes) - { - LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity); - } - } + if (isSelf() && show_my_complexity_changes) + { + // Avatar complexity + LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity); + + // HUD complexity + LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list); + } + } } void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 418cca519d68697664ce31830df290a91e2bceb4..bd89d4ef23ab7b8bd2cad23d0a5546418deb6dc8 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -68,13 +68,11 @@ class LLVoiceVisualizer; class LLHUDNameTag; class LLHUDEffectSpiral; class LLTexGlobalColor; -struct LLVOAvatarBoneInfo; -struct LLVOAvatarChildJoint; -//class LLViewerJoint; + struct LLAppearanceMessageContents; -struct LLVOAvatarSkeletonInfo; class LLViewerJointMesh; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLVOAvatar // @@ -201,11 +199,18 @@ class LLVOAvatar : void dumpAnimationState(); virtual LLJoint* getJoint(const std::string &name); + LLJoint* getJoint(S32 num); - void addAttachmentPosOverridesForObject(LLViewerObject *vo); - void resetJointPositionsOnDetach(const LLUUID& mesh_id); - void resetJointPositionsOnDetach(LLViewerObject *vo); - void clearAttachmentPosOverrides(); + void addAttachmentOverridesForObject(LLViewerObject *vo); + void resetJointsOnDetach(const LLUUID& mesh_id); + void resetJointsOnDetach(LLViewerObject *vo); + bool jointIsRiggedTo(const std::string& joint_name); + bool jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo); + void clearAttachmentOverrides(); + void rebuildAttachmentOverrides(); + void showAttachmentOverrides(bool verbose = false) const; + void getAttachmentOverrideNames(std::set<std::string>& pos_names, + std::set<std::string>& scale_names) const; /*virtual*/ const LLUUID& getID() const; /*virtual*/ void addDebugText(const std::string& text); @@ -364,10 +369,14 @@ class LLVOAvatar : /*virtual*/ LLAvatarJointMesh* createAvatarJointMesh(); // Returns LLViewerJointMesh public: void updateHeadOffset(); + void debugBodySize() const; void postPelvisSetRecalc( void ); /*virtual*/ BOOL loadSkeletonNode(); + void initAttachmentPoints(bool ignore_hud_joints = false); /*virtual*/ void buildCharacter(); + void resetVisualParams(); + void resetSkeleton(bool reset_animations); LLVector3 mCurRootToHeadOffset; LLVector3 mTargetRootToHeadOffset; @@ -404,6 +413,7 @@ class LLVOAvatar : F32 getLastSkinTime() { return mLastSkinTime; } U32 renderTransparent(BOOL first_pass); void renderCollisionVolumes(); + void renderBones(); void renderJoints(); static void deleteCachedImages(bool clearAll=true); static void destroyGL(); @@ -668,9 +678,12 @@ class LLVOAvatar : ** APPEARANCE **/ + LLPointer<LLAppearanceMessageContents> mLastProcessedAppearance; + public: void parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg); void processAvatarAppearance(LLMessageSystem* mesgsys); + void applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params); void hideSkirt(); void startAppearanceAnimation(); @@ -964,6 +977,7 @@ class LLVOAvatar : // General //-------------------------------------------------------------------- public: + void getSortedJointNames(S32 joint_type, std::vector<std::string>& result) const; void dumpArchetypeXML(const std::string& prefix, bool group_by_wearables = false); void dumpAppearanceMsgParams( const std::string& dump_prefix, const LLAppearanceMessageContents& contents); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 5f48898cb165319a53b9594cfe3d247a8b501b9a..aa5d82a096681b97ced6e22d9a8bbbff8948a33b 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -65,6 +65,7 @@ #include "llsdutil.h" #include "llstartup.h" #include "llsdserialize.h" +#include "llcallstack.h" #include "llcorehttputil.h" #if LL_MSVC @@ -192,6 +193,7 @@ bool update_avatar_rez_metrics() return true; gAgentAvatarp->updateAvatarRezMetrics(false); + return false; } @@ -219,7 +221,6 @@ void LLVOAvatarSelf::initInstance() { mDebugBakedTextureTimes[i][0] = -1.0f; mDebugBakedTextureTimes[i][1] = -1.0f; - mInitialBakeIDs[i] = LLUUID::null; } status &= buildMenus(); @@ -340,6 +341,7 @@ BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info) 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; @@ -381,6 +383,10 @@ BOOL LLVOAvatarSelf::buildMenus() 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")); @@ -409,7 +415,11 @@ BOOL LLVOAvatarSelf::buildMenus() params.name(params.label); gDetachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params); - for (S32 i = 0; i < 8; i++) + 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]) { @@ -494,7 +504,7 @@ BOOL LLVOAvatarSelf::buildMenus() ++iter) { LLViewerJointAttachment* attachment = iter->second; - if (attachment && attachment->getGroup() == 8) + if (attachment->getGroup() == 9) { LLMenuItemCallGL::Params item_params; std::string sub_piemenu_name = attachment->getName(); @@ -580,7 +590,7 @@ BOOL LLVOAvatarSelf::buildMenus() } } - for (S32 group = 0; group < 8; group++) + for (S32 group = 0; group < 9; group++) { // skip over groups that don't have sub menus if (!gAttachBodyPartPieMenus[group] || !gDetachBodyPartPieMenus[group]) @@ -690,13 +700,23 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time) // virtual LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) { - if (mScreenp) + LLJoint *jointp = NULL; + jointp = LLVOAvatar::getJoint(name); + if (!jointp && mScreenp) { - LLJoint* jointp = mScreenp->findJoint(name); - if (jointp) return jointp; + jointp = mScreenp->findJoint(name); + if (jointp) + { + mJointMap[name] = jointp; + } } - return LLVOAvatar::getJoint(name); + if (jointp && jointp != mScreenp && jointp != mRoot) + { + llassert(LLVOAvatar::getJoint((S32)jointp->getJointNum())==jointp); + } + return jointp; } + // virtual BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight) { diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index a9c4ab26a9ac0762f1131ebefd092f2ba3dd1e9d..f9f90bb323a6e99978810cc2320d09334c7424dd 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -103,17 +103,6 @@ class LLVOAvatarSelf : // helper function. Passed in param is assumed to be in avatar's parameter list. BOOL setParamWeight(const LLViewerVisualParam *param, F32 weight); - - -/** Initialization - ** ** - *******************************************************************************/ - -private: - LLUUID mInitialBakeIDs[6]; - //bool mInitialBakesLoaded; - - /******************************************************************************** ** ** ** STATE diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 082f5f0b1d684ebf8bddf7c070b529ca4594031a..7aabde1b2da66d2ac36360dcaaf7db9080098efd 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -223,6 +223,9 @@ class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTr // class LLVOCache : public LLSingleton<LLVOCache> { + LLSINGLETON(LLVOCache); + ~LLVOCache() ; + private: struct HeaderEntryInfo { @@ -253,13 +256,8 @@ class LLVOCache : public LLSingleton<LLVOCache> }; typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t; typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t; -private: - friend class LLSingleton<LLVOCache>; - LLVOCache() ; public: - ~LLVOCache() ; - void initCache(ELLPath location, U32 size, U32 cache_version) ; void removeCache(ELLPath location, bool started = false) ; diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index ef15b2c79ee2d5c184d7cf6e59df2802168e3ad7..309c3eebddfea599b9decd08d3dc362fe096457b 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -167,8 +167,8 @@ class LLVoiceChannelGroup : public LLVoiceChannel class LLVoiceChannelProximal : public LLVoiceChannel, public LLSingleton<LLVoiceChannelProximal> { + LLSINGLETON(LLVoiceChannelProximal); public: - LLVoiceChannelProximal(); /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); /*virtual*/ void handleStatusChange(EStatusType status); diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index b05bcb23b705c8601327d32072647f87488b3abf..32637dcf42e796b0d6dac12261da23cab44efdf3 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -299,11 +299,11 @@ class LLVoiceEffectInterface class LLVoiceClient: public LLSingleton<LLVoiceClient> { + LLSINGLETON(LLVoiceClient); LOG_CLASS(LLVoiceClient); -public: - LLVoiceClient(); ~LLVoiceClient(); +public: typedef boost::signals2::signal<void(void)> micro_changed_signal_t; micro_changed_signal_t mMicroChangedSignal; @@ -485,6 +485,8 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient> **/ class LLSpeakerVolumeStorage : public LLSingleton<LLSpeakerVolumeStorage> { + LLSINGLETON(LLSpeakerVolumeStorage); + ~LLSpeakerVolumeStorage(); LOG_CLASS(LLSpeakerVolumeStorage); public: @@ -513,10 +515,6 @@ class LLSpeakerVolumeStorage : public LLSingleton<LLSpeakerVolumeStorage> void removeSpeakerVolume(const LLUUID& speaker_id); private: - friend class LLSingleton<LLSpeakerVolumeStorage>; - LLSpeakerVolumeStorage(); - ~LLSpeakerVolumeStorage(); - const static std::string SETTINGS_FILE_NAME; void load(); diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 07427e0377d249cfe88f3204215b74fedeb82993..189ed5499318e75c343643e26286df235fccf863 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -427,7 +427,7 @@ void LLVivoxVoiceClient::connectorCreate() void LLVivoxVoiceClient::connectorShutdown() { - if(!mConnectorEstablished) + if(mConnectorEstablished) { std::ostringstream stream; stream diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index f32c7c975f668a037d19e1ec2a56a16cb001e7fc..81e924e4382c06b91919a7a4dad94a30815ff832 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -56,12 +56,11 @@ class LLVivoxVoiceClient : public LLSingleton<LLVivoxVoiceClient>, virtual public LLVoiceModuleInterface, virtual public LLVoiceEffectInterface { + LLSINGLETON(LLVivoxVoiceClient); LOG_CLASS(LLVivoxVoiceClient); -public: - LLVivoxVoiceClient(); virtual ~LLVivoxVoiceClient(); - - + +public: /// @name LLVoiceModuleInterface virtual implementations /// @see LLVoiceModuleInterface //@{ @@ -1027,10 +1026,10 @@ class LLVivoxProtocolParser : public LLIOPipe class LLVivoxSecurity : public LLSingleton<LLVivoxSecurity> { - public: - LLVivoxSecurity(); - virtual ~LLVivoxSecurity(); + LLSINGLETON(LLVivoxSecurity); + virtual ~LLVivoxSecurity(); + public: std::string connectorHandle() { return mConnectorHandle; }; std::string accountHandle() { return mAccountHandle; }; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 4dab213fa0e8d16837edc650343a2e000d953ba6..6b4a450e6fe202537a3f4c79495ae488700de155 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -283,7 +283,7 @@ void LLSkyTex::create(const F32 brightness) S32 offset = basic_offset * sComponents; U32* pix = (U32*)(data + offset); LLColor4U temp = LLColor4U(mSkyData[basic_offset]); - *pix = temp.mAll; + *pix = temp.asRGBA(); } } createGLImage(sCurrent); diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index ee8e91fb71d3a869f6e844777665345e5c8d5678..9cfb9773bd8ccb16486e77d3aac7497b851db688 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -171,7 +171,7 @@ class LLSkyTex { S32 offset = (i * sResolution + j) * sComponents; U32* pix = (U32*) &(mImageRaw[sCurrent]->getData()[offset]); - *pix = col.mAll; + *pix = col.asRGBA(); } LLColor4U getPixel(const S32 i, const S32 j) @@ -179,7 +179,7 @@ class LLSkyTex LLColor4U col; S32 offset = (i * sResolution + j) * sComponents; U32* pix = (U32*) &(mImageRaw[sCurrent]->getData()[offset]); - col.mAll = *pix; + col.fromRGBA( *pix ); return col; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8f0b233f01544b91e90845204f38c1fbef2a1736..657babd92cc8bfc89a7bc5401f3a792506f7a3ac 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -54,6 +54,7 @@ #include "llspatialpartition.h" #include "llhudmanager.h" #include "llflexibleobject.h" +#include "llskinningutil.h" #include "llsky.h" #include "lltexturefetch.h" #include "llvector4a.h" @@ -80,7 +81,7 @@ const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; -U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 20; +U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1; BOOL gAnimateTextures = TRUE; //extern BOOL gHideSelectedObjects; @@ -3627,10 +3628,8 @@ F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_v F32 radius = getScale().length()*0.5f; if (isMesh()) - { - LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID()); - - return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD, unscaled_value); + { + return gMeshRepo.getStreamingCost(getVolume()->getParams().getSculptID(), radius, bytes, visible_bytes, mLOD, unscaled_value); } else { @@ -4182,27 +4181,11 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } //build matrix palette - static const size_t kMaxJoints = 52; + static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; - LLMatrix4a mp[kMaxJoints]; - LLMatrix4* mat = (LLMatrix4*) mp; - - U32 maxJoints = llmin(skin->mJointNames.size(), kMaxJoints); - for (U32 j = 0; j < maxJoints; ++j) - { - LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); - if (!joint) - { - // Fall back to a point inside the avatar if mesh is - // rigged to an unknown joint. - joint = avatar->getJoint("mPelvis"); - } - if (joint) - { - mat[j] = skin->mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); - } - } + LLMatrix4a mat[kMaxJoints]; + U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar); for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) { @@ -4214,6 +4197,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if ( weight ) { + LLSkinningUtil::checkSkinWeights(weight, dst_face.mNumVertices, skin); LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); @@ -4223,40 +4207,11 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons { LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED); + U32 max_joints = LLSkinningUtil::getMaxJointCount(); for (U32 j = 0; j < dst_face.mNumVertices; ++j) { LLMatrix4a final_mat; - final_mat.clear(); - - S32 idx[4]; - - LLVector4 wght; - - F32 scale = 0.f; - for (U32 k = 0; k < 4; k++) - { - F32 w = weight[j][k]; - - idx[k] = (S32) floorf(w); - wght[k] = w - floorf(w); - scale += wght[k]; - } - // This is enforced in unpackVolumeFaces() - llassert(scale>0.f); - wght *= 1.f / scale; - - for (U32 k = 0; k < 4; k++) - { - F32 w = wght[k]; - - LLMatrix4a src; - // Insure ref'd bone is in our clamped array of mats - // clamp idx to maxJoints to avoid reading garbage off stack in release - S32 index = llclamp((S32)idx[k],(S32)0,(S32)kMaxJoints-1); - src.setMul(mp[index], w); - final_mat.add(src); - } - + LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints); LLVector4a& v = vol_face.mPositions[j]; LLVector4a t; @@ -4431,7 +4386,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LL_RECORD_BLOCK_TIME(FTM_REGISTER_FACE); if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)) { - LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; + LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; } if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) @@ -4814,13 +4769,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) drawablep->clearState(LLDrawable::HAS_ALPHA); bool rigged = vobj->isAttachment() && - vobj->isMesh() && - gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); + vobj->isMesh() && + gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); bool is_rigged = false; + if (rigged && pAvatarVO) + { + pAvatarVO->addAttachmentOverridesForObject(vobj); + if (!LLApp::isExiting() && pAvatarVO->isSelf() && debugLoggingEnabled("AvatarAttachments")) + { + bool verbose = true; + pAvatarVO->showAttachmentOverrides(verbose); + } + } + //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { @@ -4837,8 +4802,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //sum up face verts and indices drawablep->updateFaceSize(i); - - if (rigged) { if (!facep->isState(LLFace::RIGGED)) @@ -4852,13 +4815,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //get drawpool of avatar with rigged face LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); - // FIXME should this be inside the face loop? - // doesn't seem to depend on any per-face state. - if ( pAvatarVO ) - { - pAvatarVO->addAttachmentPosOverridesForObject(vobj); - } - if (pool) { const LLTextureEntry* te = facep->getTextureEntry(); diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 90bc6509a6f479c64518289ecfb225463e85dc9f..16130b5ca78674a264210e5a75dc179d9cd8c4a5 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -810,18 +810,18 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable) up *= sc; *(verticesp++) = mStarVertices[vtx]; - *(verticesp++) = mStarVertices[vtx]+left; + *(verticesp++) = mStarVertices[vtx]+up; *(verticesp++) = mStarVertices[vtx]+left+up; - *(verticesp++) = mStarVertices[vtx]+left; + *(verticesp++) = mStarVertices[vtx]; *(verticesp++) = mStarVertices[vtx]+left+up; - *(verticesp++) = mStarVertices[vtx]+up; + *(verticesp++) = mStarVertices[vtx]+left; - *(texcoordsp++) = LLVector2(0,0); - *(texcoordsp++) = LLVector2(0,1); + *(texcoordsp++) = LLVector2(1,0); *(texcoordsp++) = LLVector2(1,1); *(texcoordsp++) = LLVector2(0,1); - *(texcoordsp++) = LLVector2(1,1); *(texcoordsp++) = LLVector2(1,0); + *(texcoordsp++) = LLVector2(0,1); + *(texcoordsp++) = LLVector2(0,0); *(colorsp++) = LLColor4U(mStarColors[vtx]); *(colorsp++) = LLColor4U(mStarColors[vtx]); diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h index fee3ec6f2001c05d9127864480daa23ee3d6b1a4..9a6624258e90f43c43a114fa1250d579b45ec990 100644 --- a/indra/newview/llwatchdog.h +++ b/indra/newview/llwatchdog.h @@ -75,10 +75,10 @@ class LLWatchdogTimeout : public LLWatchdogEntry class LLWatchdogTimerThread; // Defined in the cpp class LLWatchdog : public LLSingleton<LLWatchdog> { -public: - LLWatchdog(); + LLSINGLETON(LLWatchdog); ~LLWatchdog(); +public: // Add an entry to the watchdog. void add(LLWatchdogEntry* e); void remove(LLWatchdogEntry* e); diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h index dc7d41be2ac57b0cff6712da49a30d4bb71d1126..3f169e439a607d52110112e5c2f19326f5a2e795 100644 --- a/indra/newview/llwaterparammanager.h +++ b/indra/newview/llwaterparammanager.h @@ -214,6 +214,8 @@ struct WaterExpFloatControl /// WindLight parameter manager class - what controls all the wind light shaders class LLWaterParamManager : public LLSingleton<LLWaterParamManager> { + LLSINGLETON(LLWaterParamManager); + ~LLWaterParamManager(); LOG_CLASS(LLWaterParamManager); public: typedef std::list<std::string> preset_name_list_t; @@ -317,11 +319,7 @@ class LLWaterParamManager : public LLSingleton<LLWaterParamManager> F32 mDensitySliderValue; private: - friend class LLSingleton<LLWaterParamManager>; /*virtual*/ void initSingleton(); - LLWaterParamManager(); - ~LLWaterParamManager(); - void loadAllPresets(); void loadPresetsFromDir(const std::string& dir); bool loadPreset(const std::string& path); diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index f8981d0c51501cc03aba1e25a6237f3d8e1a8912..ee2270c3236fa0faac9a3a741f6f4d88d21511ea 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -653,24 +653,16 @@ LLWearableItemsList::~LLWearableItemsList() {} // virtual -void LLWearableItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/) +LLPanel* LLWearableItemsList::createNewItem(LLViewerInventoryItem* item) { - if (!item) - { - LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL; - llassert(item != NULL); - } - - LLPanelWearableOutfitItem *list_item = LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled); - if (!list_item) - return; + if (!item) + { + LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL; + llassert(item != NULL); + return NULL; + } - bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange); - if (!is_item_added) - { - LL_WARNS() << "Couldn't add flat list item." << LL_ENDL; - llassert(is_item_added); - } + return LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled); } void LLWearableItemsList::updateList(const LLUUID& category_id) diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 18a30f083bca8412ea1d221df0cb1db3e06b4d5c..f3182ed163b4669b4e44f644e601d8f38358dbce 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -411,8 +411,8 @@ class LLWearableItemsList : public LLInventoryItemsList */ class ContextMenu : public LLListContextMenu, public LLSingleton<ContextMenu> { + LLSINGLETON(ContextMenu); public: - ContextMenu(); /*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y); protected: @@ -453,7 +453,7 @@ class LLWearableItemsList : public LLInventoryItemsList virtual ~LLWearableItemsList(); - /*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true); + /*virtual*/ LLPanel* createNewItem(LLViewerInventoryItem* item); void updateList(const LLUUID& category_id); diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h index d6f0fd09a6d5c0376c78ad8ff2327e3c06c9e747..782f7751e59f19f8702a0ea81f52a7df4510d3ea 100644 --- a/indra/newview/llwearablelist.h +++ b/indra/newview/llwearablelist.h @@ -41,9 +41,9 @@ */ class LLWearableList : public LLSingleton<LLWearableList> { -public: - LLWearableList() {} + LLSINGLETON_EMPTY_CTOR(LLWearableList); ~LLWearableList(); +public: void cleanup() ; S32 getLength() const { return mList.size(); } diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index b37e41fb857429e0e2f8343f6b9eada2a52ea1a3..8026dc3ea8e32212441022fec1b3c9ed2442c716 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -104,10 +104,10 @@ void LLWeb::loadURL(const std::string& url, const std::string& target, const std // static // Explicitly open a Web URL using the Web content floater -void LLWeb::loadURLInternal(const std::string &url, const std::string& target, const std::string& uuid) +void LLWeb::loadURLInternal(const std::string &url, const std::string& target, const std::string& uuid, bool dev_mode) { LLFloaterWebContent::Params p; - p.url(url).target(target).id(uuid); + p.url(url).target(target).id(uuid).dev_mode(dev_mode); LLFloaterReg::showInstance("web_content", p); } diff --git a/indra/newview/llweb.h b/indra/newview/llweb.h index 7c90badbfe643eabae9349d16489e59e3f3c90ac..7149ce9baf49b265f1de93ee560b40faa7e03296 100644 --- a/indra/newview/llweb.h +++ b/indra/newview/llweb.h @@ -57,7 +57,7 @@ class LLWeb static void loadURL(const std::string& url, const std::string& target = LLStringUtil::null, const std::string& uuid = LLStringUtil::null); // load content using built-in browser - static void loadURLInternal(const std::string &url, const std::string& target = LLStringUtil::null, const std::string& uuid = LLStringUtil::null); + static void loadURLInternal(const std::string &url, const std::string& target = LLStringUtil::null, const std::string& uuid = LLStringUtil::null, bool dev_mode = false); /// Returns escaped url (eg, " " to "%20") - used by all loadURL methods static std::string escapeURL(const std::string& url); diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h index a3cbf6dc036cde80da35f5c19d5c20dffbec2f89..90882cf04a099baf97a8afb396f73f5ac90c5f9a 100644 --- a/indra/newview/llwindebug.h +++ b/indra/newview/llwindebug.h @@ -34,6 +34,7 @@ class LLWinDebug: public LLSingleton<LLWinDebug> { + LLSINGLETON_EMPTY_CTOR(LLWinDebug); public: static void init(); static void generateMinidump(struct _EXCEPTION_POINTERS *pExceptionInfo = NULL); diff --git a/indra/newview/llwlanimator.h b/indra/newview/llwlanimator.h index 810f4cf7e59f3d5ea928a5485835f4255b4d34d3..e2e49c73051555cddda76bfa33a6431b42b979e1 100644 --- a/indra/newview/llwlanimator.h +++ b/indra/newview/llwlanimator.h @@ -28,12 +28,11 @@ #define LL_WL_ANIMATOR_H #include "llwlparamset.h" +#include "llenvmanager.h" #include "llwaterparamset.h" #include <string> #include <map> -struct LLWLParamKey; - class LLWLAnimator { public: typedef enum e_time diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index e13aed98edfc507d5bec39592e9fdc8493cc67a1..a55f5bd8fa789cd01f38c63dfb41ad2e1790017e 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -116,103 +116,11 @@ struct WLFloatControl { } }; -struct LLWLParamKey : LLEnvKey -{ -public: - // scope and source of a param set (WL sky preset) - std::string name; - EScope scope; - - // for conversion from LLSD - static const int NAME_IDX = 0; - static const int SCOPE_IDX = 1; - - inline LLWLParamKey(const std::string& n, EScope s) - : name(n), scope(s) - { - } - - inline LLWLParamKey(LLSD llsd) - : name(llsd[NAME_IDX].asString()), scope(EScope(llsd[SCOPE_IDX].asInteger())) - { - } - - inline LLWLParamKey() // NOT really valid, just so std::maps can return a default of some sort - : name(""), scope(SCOPE_LOCAL) - { - } - - inline LLWLParamKey(std::string& stringVal) - { - size_t len = stringVal.length(); - if (len > 0) - { - name = stringVal.substr(0, len - 1); - scope = (EScope) atoi(stringVal.substr(len - 1, len).c_str()); - } - } - - inline std::string toStringVal() const - { - std::stringstream str; - str << name << scope; - return str.str(); - } - - inline LLSD toLLSD() const - { - LLSD llsd = LLSD::emptyArray(); - llsd.append(LLSD(name)); - llsd.append(LLSD(scope)); - return llsd; - } - - inline void fromLLSD(const LLSD& llsd) - { - name = llsd[NAME_IDX].asString(); - scope = EScope(llsd[SCOPE_IDX].asInteger()); - } - - inline bool operator <(const LLWLParamKey other) const - { - if (name < other.name) - { - return true; - } - else if (name > other.name) - { - return false; - } - else - { - return scope < other.scope; - } - } - - inline bool operator ==(const LLWLParamKey other) const - { - return (name == other.name) && (scope == other.scope); - } - - inline std::string toString() const - { - switch (scope) - { - case SCOPE_LOCAL: - return name + std::string(" (") + LLTrans::getString("Local") + std::string(")"); - break; - case SCOPE_REGION: - return name + std::string(" (") + LLTrans::getString("Region") + std::string(")"); - break; - default: - return name + " (?)"; - } - } -}; - /// WindLight parameter manager class - what controls all the wind light shaders class LLWLParamManager : public LLSingleton<LLWLParamManager> { + LLSINGLETON(LLWLParamManager); + ~LLWLParamManager(); LOG_CLASS(LLWLParamManager); public: @@ -375,11 +283,7 @@ class LLWLParamManager : public LLSingleton<LLWLParamManager> static std::string getSysDir(); static std::string getUserDir(); - friend class LLSingleton<LLWLParamManager>; /*virtual*/ void initSingleton(); - LLWLParamManager(); - ~LLWLParamManager(); - // list of all the parameters, listed by name std::map<LLWLParamKey, LLWLParamSet> mParamList; diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 11d3706821fa5cf20411502ce71ddd05f57c526a..cee47a591e36058e1846e60284d5c3804f4a4a17 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -957,10 +957,10 @@ void LLWorld::updateWaterObjects() center_y = min_y + (wy >> 1); S32 add_boundary[4] = { - 512 - (max_x - region_x), - 512 - (max_y - region_y), - 512 - (region_x - min_x), - 512 - (region_y - min_y) }; + (S32)(512 - (max_x - region_x)), + (S32)(512 - (max_y - region_y)), + (S32)(512 - (region_x - min_x)), + (S32)(512 - (region_y - min_y)) }; S32 dir; for (dir = 0; dir < 8; dir++) diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index b2d84180648ddfadc41c3ce0185f9354153451d8..c9ac241d5aae22473d0a302974d57ca00cb0aeab 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -61,8 +61,8 @@ class LLVOAvatar; class LLWorld : public LLSingleton<LLWorld> { + LLSINGLETON(LLWorld); public: - LLWorld(); void destroyClass(); LLViewerRegion* addRegion(const U64 ®ion_handle, const LLHost &host); diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index 1a168e4b4d4f76ee6d25499d00d45491e2c5085a..5e5caa6a74358e8b762fe2d40a7ff82e71bb52bf 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -193,10 +193,10 @@ const S32 MAP_BLOCK_RES = (MAP_MAX_SIZE / MAP_BLOCK_SIZE); class LLWorldMap : public LLSingleton<LLWorldMap> { -public: - LLWorldMap(); + LLSINGLETON(LLWorldMap); ~LLWorldMap(); +public: // Clear all: list of region info, tiles, blocks and items void reset(); diff --git a/indra/newview/llworldmapmessage.h b/indra/newview/llworldmapmessage.h index ac1ea1607c793d6370d3f3e95cd4f414c9889a26..65276df06820835dcd2157d2a2aa76a63bd16b78 100644 --- a/indra/newview/llworldmapmessage.h +++ b/indra/newview/llworldmapmessage.h @@ -34,13 +34,13 @@ class LLMessageSystem; class LLWorldMapMessage : public LLSingleton<LLWorldMapMessage> { + LLSINGLETON(LLWorldMapMessage); + ~LLWorldMapMessage(); + public: typedef boost::function<void(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)> url_callback_t; - LLWorldMapMessage(); - ~LLWorldMapMessage(); - // Process incoming answers to map stuff requests static void processMapBlockReply(LLMessageSystem*, void**); static void processMapItemReply(LLMessageSystem*, void**); diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index 97a9eb7f5fc557accfd4d7fc555f8098f0f8f6e7..cc3645131dd0efb9a7ef9336c2e88f2bb30687ce 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -322,7 +322,7 @@ class Poller mBoundListener = LLEventPumps::instance(). obtain("mainloop"). - listen(LLEventPump::inventName(), boost::bind(&Poller::poll, this, _1)); + listen(LLEventPump::ANONYMOUS, boost::bind(&Poller::poll, this, _1)); LL_INFOS("LLXMLRPCListener") << mMethod << " request sent to " << mUri << LL_ENDL; } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c6bbfb1c8ffd975cd57f9642b4319dec6a68927c..26b71f70bbdb154b5de21ef15b34ff5c73b7fbc9 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -114,6 +114,7 @@ #include "llpathfindingpathtool.h" #include "llscenemonitor.h" #include "llprogressview.h" +#include "llcleanup.h" #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 @@ -129,26 +130,26 @@ bool gShiftFrame = false; //cached settings -BOOL LLPipeline::RenderAvatarVP; -BOOL LLPipeline::VertexShaderEnable; -BOOL LLPipeline::WindLightUseAtmosShaders; -BOOL LLPipeline::RenderDeferred; +bool LLPipeline::RenderAvatarVP; +bool LLPipeline::VertexShaderEnable; +bool LLPipeline::WindLightUseAtmosShaders; +bool LLPipeline::RenderDeferred; F32 LLPipeline::RenderDeferredSunWash; U32 LLPipeline::RenderFSAASamples; U32 LLPipeline::RenderResolutionDivisor; -BOOL LLPipeline::RenderUIBuffer; +bool LLPipeline::RenderUIBuffer; S32 LLPipeline::RenderShadowDetail; -BOOL LLPipeline::RenderDeferredSSAO; +bool LLPipeline::RenderDeferredSSAO; F32 LLPipeline::RenderShadowResolutionScale; -BOOL LLPipeline::RenderLocalLights; -BOOL LLPipeline::RenderDelayCreation; -BOOL LLPipeline::RenderAnimateRes; -BOOL LLPipeline::FreezeTime; +bool LLPipeline::RenderLocalLights; +bool LLPipeline::RenderDelayCreation; +bool LLPipeline::RenderAnimateRes; +bool LLPipeline::FreezeTime; S32 LLPipeline::DebugBeaconLineWidth; F32 LLPipeline::RenderHighlightBrightness; LLColor4 LLPipeline::RenderHighlightColor; F32 LLPipeline::RenderHighlightThickness; -BOOL LLPipeline::RenderSpotLightsInNondeferred; +bool LLPipeline::RenderSpotLightsInNondeferred; LLColor4 LLPipeline::PreviewAmbientColor; LLColor4 LLPipeline::PreviewDiffuse0; LLColor4 LLPipeline::PreviewSpecular0; @@ -168,8 +169,8 @@ S32 LLPipeline::RenderGlowResolutionPow; S32 LLPipeline::RenderGlowIterations; F32 LLPipeline::RenderGlowWidth; F32 LLPipeline::RenderGlowStrength; -BOOL LLPipeline::RenderDepthOfField; -BOOL LLPipeline::RenderDepthOfFieldInEditMode; +bool LLPipeline::RenderDepthOfField; +bool LLPipeline::RenderDepthOfFieldInEditMode; F32 LLPipeline::CameraFocusTransitionTime; F32 LLPipeline::CameraFNumber; F32 LLPipeline::CameraFocalLength; @@ -190,7 +191,7 @@ F32 LLPipeline::RenderEdgeDepthCutoff; F32 LLPipeline::RenderEdgeNormCutoff; LLVector3 LLPipeline::RenderShadowGaussian; F32 LLPipeline::RenderShadowBlurDistFactor; -BOOL LLPipeline::RenderDeferredAtmospheric; +bool LLPipeline::RenderDeferredAtmospheric; S32 LLPipeline::RenderReflectionDetail; F32 LLPipeline::RenderHighlightFadeTime; LLVector3 LLPipeline::RenderShadowClipPlanes; @@ -200,7 +201,7 @@ F32 LLPipeline::RenderFarClip; LLVector3 LLPipeline::RenderShadowSplitExponent; F32 LLPipeline::RenderShadowErrorCutoff; F32 LLPipeline::RenderShadowFOVCutoff; -BOOL LLPipeline::CameraOffset; +bool LLPipeline::CameraOffset; F32 LLPipeline::CameraMaxCoF; F32 LLPipeline::CameraDoFResScale; F32 LLPipeline::RenderAutoHideSurfaceAreaLimit; @@ -215,9 +216,9 @@ extern S32 gBoxFrame; extern BOOL gDisplaySwapBuffers; extern BOOL gDebugGL; -BOOL gAvatarBacklight = FALSE; +bool gAvatarBacklight = false; -BOOL gDebugPipeline = FALSE; +bool gDebugPipeline = false; LLPipeline gPipeline; const LLMatrix4* gGLLastMatrix = NULL; @@ -358,45 +359,45 @@ 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; +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; +bool LLPipeline::sForceOldBakedUpload = false; S32 LLPipeline::sUseOcclusion = 0; -BOOL LLPipeline::sDelayVBUpdate = TRUE; -BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE; -BOOL LLPipeline::sAutoMaskAlphaNonDeferred = FALSE; -BOOL LLPipeline::sDisableShaders = FALSE; -BOOL LLPipeline::sRenderBump = TRUE; -BOOL LLPipeline::sBakeSunlight = FALSE; -BOOL LLPipeline::sNoAlpha = FALSE; -BOOL LLPipeline::sUseTriStrips = TRUE; -BOOL LLPipeline::sUseFarClip = TRUE; -BOOL LLPipeline::sShadowRender = FALSE; -BOOL LLPipeline::sWaterReflections = FALSE; -BOOL LLPipeline::sRenderGlow = FALSE; -BOOL LLPipeline::sReflectionRender = FALSE; -BOOL LLPipeline::sImpostorRender = FALSE; -BOOL LLPipeline::sImpostorRenderAlphaDepthPass = FALSE; -BOOL LLPipeline::sUnderWaterRender = FALSE; -BOOL LLPipeline::sTextureBindTest = FALSE; -BOOL LLPipeline::sRenderFrameTest = FALSE; -BOOL LLPipeline::sRenderAttachedLights = TRUE; -BOOL LLPipeline::sRenderAttachedParticles = TRUE; -BOOL LLPipeline::sRenderDeferred = FALSE; -BOOL LLPipeline::sMemAllocationThrottled = FALSE; +bool LLPipeline::sDelayVBUpdate = true; +bool LLPipeline::sAutoMaskAlphaDeferred = true; +bool LLPipeline::sAutoMaskAlphaNonDeferred = false; +bool LLPipeline::sDisableShaders = false; +bool LLPipeline::sRenderBump = true; +bool LLPipeline::sBakeSunlight = false; +bool LLPipeline::sNoAlpha = false; +bool LLPipeline::sUseTriStrips = true; +bool LLPipeline::sUseFarClip = true; +bool LLPipeline::sShadowRender = false; +bool LLPipeline::sWaterReflections = false; +bool LLPipeline::sRenderGlow = false; +bool LLPipeline::sReflectionRender = false; +bool LLPipeline::sImpostorRender = false; +bool LLPipeline::sImpostorRenderAlphaDepthPass = false; +bool LLPipeline::sUnderWaterRender = false; +bool LLPipeline::sTextureBindTest = false; +bool LLPipeline::sRenderFrameTest = false; +bool LLPipeline::sRenderAttachedLights = true; +bool LLPipeline::sRenderAttachedParticles = true; +bool LLPipeline::sRenderDeferred = false; +bool LLPipeline::sMemAllocationThrottled = false; S32 LLPipeline::sVisibleLightCount = 0; F32 LLPipeline::sMinRenderSize = 0.f; -BOOL LLPipeline::sRenderingHUDs; +bool LLPipeline::sRenderingHUDs; // EventHost API LLPipeline listener. static LLPipelineListener sPipelineListener; @@ -413,14 +414,14 @@ bool addDeferredAttachments(LLRenderTarget& target) } LLPipeline::LLPipeline() : - mBackfaceCull(FALSE), + mBackfaceCull(false), mMatrixOpCount(0), mTextureMatrixOps(0), mNumVisibleNodes(0), mNumVisibleFaces(0), - mInitialized(FALSE), - mVertexShadersEnabled(FALSE), + mInitialized(false), + mVertexShadersEnabled(false), mVertexShadersLoaded(0), mTransformFeedbackPrimitives(0), mRenderDebugFeatureMask(0), @@ -485,7 +486,7 @@ void LLPipeline::init() sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); - mInitialized = TRUE; + mInitialized = true; stop_glerror(); @@ -538,7 +539,7 @@ void LLPipeline::init() mOldRenderDebugMask = mRenderDebugMask; - mBackfaceCull = TRUE; + mBackfaceCull = true; stop_glerror(); @@ -723,7 +724,7 @@ void LLPipeline::cleanup() mMovedBridge.clear(); - mInitialized = FALSE; + mInitialized = false; mDeferredVB = NULL; @@ -759,7 +760,7 @@ void LLPipeline::destroyGL() static LLTrace::BlockTimerStatHandle FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); //static -void LLPipeline::throttleNewMemoryAllocation(BOOL disable) +void LLPipeline::throttleNewMemoryAllocation(bool disable) { if(sMemAllocationThrottled != disable) { @@ -932,7 +933,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (LLPipeline::sRenderDeferred) { S32 shadow_detail = RenderShadowDetail; - BOOL ssao = RenderDeferredSSAO; + bool ssao = RenderDeferredSSAO; const U32 occlusion_divisor = 3; @@ -1058,19 +1059,19 @@ void LLPipeline::updateRenderBump() //static void LLPipeline::updateRenderDeferred() { - BOOL deferred = ((RenderDeferred && + bool deferred = (bool(RenderDeferred && LLRenderTarget::sUseFBO && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && LLPipeline::sRenderBump && VertexShaderEnable && RenderAvatarVP && - WindLightUseAtmosShaders) ? TRUE : FALSE) && + WindLightUseAtmosShaders)) && !gUseWireframe; sRenderDeferred = deferred; if (deferred) { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all - sRenderGlow = TRUE; + sRenderGlow = true; } } @@ -1413,7 +1414,7 @@ void LLPipeline::restoreGL() } -BOOL LLPipeline::canUseVertexShaders() +bool LLPipeline::canUseVertexShaders() { static const std::string vertex_shader_enable_feature_string = "VertexShaderEnable"; @@ -1423,30 +1424,30 @@ BOOL LLPipeline::canUseVertexShaders() !LLFeatureManager::getInstance()->isFeatureAvailable(vertex_shader_enable_feature_string) || (assertInitialized() && mVertexShadersLoaded != 1) ) { - return FALSE; + return false; } else { - return TRUE; + return true; } } -BOOL LLPipeline::canUseWindLightShaders() const +bool LLPipeline::canUseWindLightShaders() const { return (!LLPipeline::sDisableShaders && gWLSkyProgram.mProgramObject != 0 && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1); } -BOOL LLPipeline::canUseWindLightShadersOnObjects() const +bool LLPipeline::canUseWindLightShadersOnObjects() const { return (canUseWindLightShaders() && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0); } -BOOL LLPipeline::canUseAntiAliasing() const +bool LLPipeline::canUseAntiAliasing() const { - return TRUE; + return true; } void LLPipeline::unloadShaders() @@ -1463,7 +1464,7 @@ void LLPipeline::assertInitializedDoError() //============================================================================ -void LLPipeline::enableShadows(const BOOL enable_shadows) +void LLPipeline::enableShadows(const bool enable_shadows) { //should probably do something here to wrangle shadows.... } @@ -2001,7 +2002,7 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) { LLDrawable::drawable_vector_t::iterator curiter = iter++; LLDrawable *drawablep = *curiter; - BOOL done = TRUE; + bool done = true; if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE))) { done = drawablep->updateMove(); @@ -2329,7 +2330,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group) } -BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) +bool LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -2345,17 +2346,17 @@ BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { if (part->visibleObjectsInFrustum(camera)) { - return TRUE; + return true; } } } } } - return FALSE; + return false; } -BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max) +bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max) { const F32 X = 65536.f; @@ -2365,7 +2366,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& 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) @@ -2381,7 +2382,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& { if (!part->getVisibleExtents(camera, min, max)) { - res = FALSE; + res = false; } } } @@ -2408,7 +2409,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl sCull->clear(); - BOOL to_texture = LLPipeline::sUseOcclusion > 1 && + bool to_texture = LLPipeline::sUseOcclusion > 1 && !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && gPipeline.canUseVertexShaders() && @@ -2788,9 +2789,9 @@ void LLPipeline::doOcclusion(LLCamera& camera) } } -BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) +bool LLPipeline::updateDrawableGeom(LLDrawable* drawablep, bool priority) { - BOOL update_complete = drawablep->updateGeometry(priority); + bool update_complete = drawablep->updateGeometry(priority); if (update_complete && assertInitialized()) { drawablep->setState(LLDrawable::BUILT); @@ -3077,7 +3078,7 @@ void LLPipeline::updateGeom(F32 max_dtime) last_group = drawablep->getSpatialGroup(); last_bridge = bridge; - BOOL update_complete = TRUE; + bool update_complete = true; if (!drawablep->isDead()) { update_complete = updateDrawableGeom(drawablep, FALSE); @@ -3134,7 +3135,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) } } -void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) +void LLPipeline::markMoved(LLDrawable *drawablep, bool damped_motion) { if (!drawablep) { @@ -3168,7 +3169,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) } drawablep->setState(LLDrawable::ON_MOVE_LIST); } - if (damped_motion == FALSE) + if (! damped_motion) { drawablep->setState(LLDrawable::MOVE_UNDAMPED); // UNDAMPED trumps DAMPED } @@ -3208,7 +3209,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) assertInitialized(); glClear(GL_DEPTH_BUFFER_BIT); - gDepthDirty = TRUE; + gDepthDirty = true; LLVector4a offseta; offseta.load3(offset.mV); @@ -3306,13 +3307,13 @@ void LLPipeline::markMeshDirty(LLSpatialGroup* group) mMeshDirtyGroup.push_back(group); } -void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) +void LLPipeline::markRebuild(LLSpatialGroup* group, bool priority) { if (group && !group->isDead() && group->getSpatialPartition()) { if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD) { - priority = TRUE; + priority = true; } if (priority) @@ -3345,13 +3346,13 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) } } -void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) +void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, bool priority) { if (drawablep && !drawablep->isDead() && assertInitialized()) { if (!drawablep->isState(LLDrawable::BUILT)) { - priority = TRUE; + priority = true; } if (priority) { @@ -3720,17 +3721,17 @@ void renderMOAPBeacons(LLDrawable* drawablep) if(!vobj || vobj->isAvatar()) return; - BOOL beacon=FALSE; + bool beacon=false; U8 tecount=vobj->getNumTEs(); for(int x=0;x<tecount;x++) { if(vobj->getTE(x)->hasMedia()) { - beacon=TRUE; + beacon=true; break; } } - if(beacon==TRUE) + if(beacon) { if (gPipeline.sRenderBeacons) { @@ -4309,7 +4310,7 @@ void LLPipeline::renderHighlights() //debug use U32 LLPipeline::sCurRenderPoolType = 0 ; -void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) +void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) { LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); @@ -4366,13 +4367,13 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) // Toggle backface culling for debugging LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0); // Set fog - BOOL use_fog = hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG); + bool use_fog = hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG); LLGLEnable fog_enable(use_fog && !gPipeline.canUseWindLightShadersOnObjects() ? GL_FOG : 0); gSky.updateFog(camera.getFar()); if (!use_fog) { - sUnderWaterRender = FALSE; + sUnderWaterRender = false; } gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep); @@ -4409,7 +4410,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) setupHWLights(NULL); } - BOOL occlude = sUseOcclusion > 1; + bool occlude = sUseOcclusion > 1; U32 cur_type = 0; pool_set_t::iterator iter1 = mPools.begin(); @@ -4424,7 +4425,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) if (occlude && cur_type >= LLDrawPool::POOL_GRASS) { - occlude = FALSE; + occlude = false; gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); LLGLSLShader::bindNoShader(); @@ -4489,7 +4490,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) if (occlude) { - occlude = FALSE; + occlude = false; gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); LLGLSLShader::bindNoShader(); @@ -4672,7 +4673,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) gGL.setColorMask(true, false); pool_set_t::iterator iter1 = mPools.begin(); - BOOL occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion; + bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion; while ( iter1 != mPools.end() ) { @@ -4682,7 +4683,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) if (occlude && cur_type >= LLDrawPool::POOL_GRASS) { - occlude = FALSE; + occlude = false; gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); LLGLSLShader::bindNoShader(); @@ -4742,7 +4743,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) if (occlude) { - occlude = FALSE; + occlude = false; gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); LLGLSLShader::bindNoShader(); @@ -5884,7 +5885,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) case LLDrawPool::POOL_TREE: #ifdef _DEBUG { - BOOL found = mTreePools.erase( (uintptr_t)poolp->getTexture() ); + bool found = mTreePools.erase( (uintptr_t)poolp->getTexture() ); llassert( found ); } #else @@ -5895,7 +5896,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) case LLDrawPool::POOL_TERRAIN: #ifdef _DEBUG { - BOOL found = mTerrainPools.erase( (uintptr_t)poolp->getTexture() ); + bool found = mTerrainPools.erase( (uintptr_t)poolp->getTexture() ); llassert( found ); } #else @@ -5958,7 +5959,7 @@ void LLPipeline::resetDrawOrders() // Once-per-frame setup of hardware lights, // including sun/moon, avatar backlight, and up to 6 local lights -void LLPipeline::setupAvatarLights(BOOL for_edit) +void LLPipeline::setupAvatarLights(bool for_edit) { assertInitialized(); @@ -6063,7 +6064,7 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ return max_dist; } F32 radius = light->getLightRadius(); - BOOL selected = light->isSelected(); + bool selected = light->isSelected(); LLVector3 dpos = light->getRenderPosition() - cam_pos; F32 dist2 = dpos.lengthSquared(); if (!selected && dist2 > (max_dist + radius)*(max_dist + radius)) @@ -6658,9 +6659,9 @@ void LLPipeline::findReferences(LLDrawable *drawablep) } } -BOOL LLPipeline::verify() +bool LLPipeline::verify() { - BOOL ok = assertInitialized(); + bool ok = assertInitialized(); if (ok) { for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) @@ -6668,7 +6669,7 @@ BOOL LLPipeline::verify() LLDrawPool *poolp = *iter; if (!poolp->verify()) { - ok = FALSE; + ok = false; } } } @@ -6713,7 +6714,7 @@ BOOL LLPipeline::verify() bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon) { - BOOL Inside = TRUE; + bool Inside = true; LLVector3 MinB = center - size; LLVector3 MaxB = center + size; LLVector3 MaxT; @@ -6725,7 +6726,7 @@ bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& if(origin.mV[i] < MinB.mV[i]) { coord.mV[i] = MinB.mV[i]; - Inside = FALSE; + 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]; @@ -6733,7 +6734,7 @@ bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& else if(origin.mV[i] > MaxB.mV[i]) { coord.mV[i] = MaxB.mV[i]; - Inside = FALSE; + 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]; @@ -6779,7 +6780,7 @@ bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& // // -void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light) +void LLPipeline::setLight(LLDrawable *drawablep, bool is_light) { if (drawablep && assertInitialized()) { @@ -6807,9 +6808,8 @@ void LLPipeline::toggleRenderType(U32 type) } //static -void LLPipeline::toggleRenderTypeControl(void* data) +void LLPipeline::toggleRenderTypeControl(U32 type) { - U32 type = (U32)(intptr_t)data; U32 bit = (1<<type); if (gPipeline.hasRenderType(type)) { @@ -6823,24 +6823,21 @@ void LLPipeline::toggleRenderTypeControl(void* data) } //static -BOOL LLPipeline::hasRenderTypeControl(void* data) +bool LLPipeline::hasRenderTypeControl(U32 type) { - U32 type = (U32)(intptr_t)data; return gPipeline.hasRenderType(type); } // Allows UI items labeled "Hide foo" instead of "Show foo" //static -BOOL LLPipeline::toggleRenderTypeControlNegated(void* data) +bool LLPipeline::toggleRenderTypeControlNegated(S32 type) { - S32 type = (S32)(intptr_t)data; return !gPipeline.hasRenderType(type); } //static -void LLPipeline::toggleRenderDebug(void* data) +void LLPipeline::toggleRenderDebug(U32 bit) { - U32 bit = (U32)(intptr_t)data; if (gPipeline.hasRenderDebugMask(bit)) { LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL; @@ -6854,24 +6851,21 @@ void LLPipeline::toggleRenderDebug(void* data) //static -BOOL LLPipeline::toggleRenderDebugControl(void* data) +bool LLPipeline::toggleRenderDebugControl(U32 bit) { - U32 bit = (U32)(intptr_t)data; return gPipeline.hasRenderDebugMask(bit); } //static -void LLPipeline::toggleRenderDebugFeature(void* data) +void LLPipeline::toggleRenderDebugFeature(U32 bit) { - U32 bit = (U32)(intptr_t)data; gPipeline.mRenderDebugFeatureMask ^= bit; } //static -BOOL LLPipeline::toggleRenderDebugFeatureControl(void* data) +bool LLPipeline::toggleRenderDebugFeatureControl(U32 bit) { - U32 bit = (U32)(intptr_t)data; return gPipeline.hasRenderDebugFeatureMask(bit); } @@ -6904,145 +6898,145 @@ void LLPipeline::popRenderDebugFeatureMask() } // static -void LLPipeline::setRenderScriptedBeacons(BOOL val) +void LLPipeline::setRenderScriptedBeacons(bool val) { sRenderScriptedBeacons = val; } // static -void LLPipeline::toggleRenderScriptedBeacons(void*) +void LLPipeline::toggleRenderScriptedBeacons() { sRenderScriptedBeacons = !sRenderScriptedBeacons; } // static -BOOL LLPipeline::getRenderScriptedBeacons(void*) +bool LLPipeline::getRenderScriptedBeacons() { return sRenderScriptedBeacons; } // static -void LLPipeline::setRenderScriptedTouchBeacons(BOOL val) +void LLPipeline::setRenderScriptedTouchBeacons(bool val) { sRenderScriptedTouchBeacons = val; } // static -void LLPipeline::toggleRenderScriptedTouchBeacons(void*) +void LLPipeline::toggleRenderScriptedTouchBeacons() { sRenderScriptedTouchBeacons = !sRenderScriptedTouchBeacons; } // static -BOOL LLPipeline::getRenderScriptedTouchBeacons(void*) +bool LLPipeline::getRenderScriptedTouchBeacons() { return sRenderScriptedTouchBeacons; } // static -void LLPipeline::setRenderMOAPBeacons(BOOL val) +void LLPipeline::setRenderMOAPBeacons(bool val) { sRenderMOAPBeacons = val; } // static -void LLPipeline::toggleRenderMOAPBeacons(void*) +void LLPipeline::toggleRenderMOAPBeacons() { sRenderMOAPBeacons = !sRenderMOAPBeacons; } // static -BOOL LLPipeline::getRenderMOAPBeacons(void*) +bool LLPipeline::getRenderMOAPBeacons() { return sRenderMOAPBeacons; } // static -void LLPipeline::setRenderPhysicalBeacons(BOOL val) +void LLPipeline::setRenderPhysicalBeacons(bool val) { sRenderPhysicalBeacons = val; } // static -void LLPipeline::toggleRenderPhysicalBeacons(void*) +void LLPipeline::toggleRenderPhysicalBeacons() { sRenderPhysicalBeacons = !sRenderPhysicalBeacons; } // static -BOOL LLPipeline::getRenderPhysicalBeacons(void*) +bool LLPipeline::getRenderPhysicalBeacons() { return sRenderPhysicalBeacons; } // static -void LLPipeline::setRenderParticleBeacons(BOOL val) +void LLPipeline::setRenderParticleBeacons(bool val) { sRenderParticleBeacons = val; } // static -void LLPipeline::toggleRenderParticleBeacons(void*) +void LLPipeline::toggleRenderParticleBeacons() { sRenderParticleBeacons = !sRenderParticleBeacons; } // static -BOOL LLPipeline::getRenderParticleBeacons(void*) +bool LLPipeline::getRenderParticleBeacons() { return sRenderParticleBeacons; } // static -void LLPipeline::setRenderSoundBeacons(BOOL val) +void LLPipeline::setRenderSoundBeacons(bool val) { sRenderSoundBeacons = val; } // static -void LLPipeline::toggleRenderSoundBeacons(void*) +void LLPipeline::toggleRenderSoundBeacons() { sRenderSoundBeacons = !sRenderSoundBeacons; } // static -BOOL LLPipeline::getRenderSoundBeacons(void*) +bool LLPipeline::getRenderSoundBeacons() { return sRenderSoundBeacons; } // static -void LLPipeline::setRenderBeacons(BOOL val) +void LLPipeline::setRenderBeacons(bool val) { sRenderBeacons = val; } // static -void LLPipeline::toggleRenderBeacons(void*) +void LLPipeline::toggleRenderBeacons() { sRenderBeacons = !sRenderBeacons; } // static -BOOL LLPipeline::getRenderBeacons(void*) +bool LLPipeline::getRenderBeacons() { return sRenderBeacons; } // static -void LLPipeline::setRenderHighlights(BOOL val) +void LLPipeline::setRenderHighlights(bool val) { sRenderHighlight = val; } // static -void LLPipeline::toggleRenderHighlights(void*) +void LLPipeline::toggleRenderHighlights() { sRenderHighlight = !sRenderHighlight; } // static -BOOL LLPipeline::getRenderHighlights(void*) +bool LLPipeline::getRenderHighlights() { return sRenderHighlight; } @@ -7096,8 +7090,8 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, } LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end, - BOOL pick_transparent, - BOOL pick_rigged, + bool pick_transparent, + bool pick_rigged, S32* face_hit, LLVector4a* intersection, // return the intersection point LLVector2* tex_coord, // return the texture coordinates of the intersection point @@ -7111,7 +7105,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, LLVector4a position; - sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE; + sPickAvatar = false; //! LLToolMgr::getInstance()->inBuildMode(); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -7177,7 +7171,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f; //check against avatars - sPickAvatar = TRUE; + sPickAvatar = true; for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { @@ -7249,7 +7243,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, } LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end, - BOOL pick_transparent, + bool pick_transparent, S32* face_hit, LLVector4a* intersection, // return the intersection point LLVector2* tex_coord, // return the texture coordinates of the intersection point @@ -7264,11 +7258,11 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, c { LLViewerRegion* region = *iter; - BOOL toggle = FALSE; + bool toggle = false; if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { toggleRenderType(LLPipeline::RENDER_TYPE_HUD); - toggle = TRUE; + toggle = true; } LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD); @@ -7385,7 +7379,7 @@ void LLPipeline::doResetVertexBuffers(bool forced) } LLVOPartGroup::destroyGL(); - LLVertexBuffer::cleanupClass(); + SUBSYSTEM_CLEANUP(LLVertexBuffer); //delete all name pool caches LLGLNamePool::cleanupPools(); @@ -7417,7 +7411,7 @@ void LLPipeline::doResetVertexBuffers(bool forced) LLVOPartGroup::restoreGL(); } -void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture) +void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_texture) { assertInitialized(); gGL.loadMatrix(gGLModelView); @@ -7427,7 +7421,7 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_text gGLLastMatrix = NULL; } -void LLPipeline::renderMaskedObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture) +void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture) { assertInitialized(); gGL.loadMatrix(gGLModelView); @@ -7500,7 +7494,7 @@ void LLPipeline::bindScreenToTexture() static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); -void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) +void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) { if (!(gPipeline.canUseVertexShaders() && sRenderGlow)) @@ -8618,7 +8612,7 @@ void LLPipeline::renderDeferredLighting() gPipeline.popRenderTypeMask(); } - BOOL render_local = RenderLocalLights; + bool render_local = RenderLocalLights; if (render_local) { @@ -9171,7 +9165,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) gPipeline.popRenderTypeMask(); } - BOOL render_local = RenderLocalLights; + bool render_local = RenderLocalLights; if (render_local) { @@ -9730,10 +9724,10 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) { if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) { - BOOL skip_avatar_update = FALSE; + bool skip_avatar_update = false; if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) { - skip_avatar_update = TRUE; + skip_avatar_update = true; } if (!skip_avatar_update) @@ -9748,7 +9742,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLCamera camera = camera_in; camera.setFar(camera.getFar()*0.87654321f); - LLPipeline::sReflectionRender = TRUE; + LLPipeline::sReflectionRender = true; gPipeline.pushRenderTypeMask(); @@ -9934,7 +9928,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) camera.setOrigin(camera_in.getOrigin()); //render distortion map - static BOOL last_update = TRUE; + static bool last_update = true; if (last_update) { camera.setFar(camera_in.getFar()); @@ -9944,7 +9938,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) END_RENDER_TYPES); stop_glerror(); - LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? FALSE : TRUE; + LLPipeline::sUnderWaterRender = ! LLViewerCamera::getInstance()->cameraUnderWater(); if (LLPipeline::sUnderWaterRender) { @@ -10006,12 +10000,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } mWaterDis.flush(); - LLPipeline::sUnderWaterRender = FALSE; + LLPipeline::sUnderWaterRender = false; } last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; - LLPipeline::sReflectionRender = FALSE; + LLPipeline::sReflectionRender = false; if (!LLRenderTarget::sUseFBO) { @@ -10106,7 +10100,7 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_RENDER("Render Shadows"); static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA("Alpha Shadow"); static LLTrace::BlockTimerStatHandle FTM_SHADOW_SIMPLE("Simple Shadow"); -void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion, U32 target_width) +void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, bool use_shader, bool use_occlusion, U32 target_width) { LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); @@ -10116,7 +10110,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera { LLPipeline::sUseOcclusion = 0; } - LLPipeline::sShadowRender = TRUE; + LLPipeline::sShadowRender = true; U32 types[] = { LLRenderPass::PASS_SIMPLE, @@ -10259,18 +10253,18 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gGLLastMatrix = NULL; LLPipeline::sUseOcclusion = occlude; - LLPipeline::sShadowRender = FALSE; + LLPipeline::sShadowRender = false; } static LLTrace::BlockTimerStatHandle FTM_VISIBLE_CLOUD("Visible Cloud"); -BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir) +bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir) { LL_RECORD_BLOCK_TIME(FTM_VISIBLE_CLOUD); //get point cloud of intersection of frust and min, max if (getVisibleExtents(camera, min, max)) { - return FALSE; + return false; } //get set of planes on bounding box @@ -10428,10 +10422,10 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector if (fp.empty()) { - return FALSE; + return false; } - return TRUE; + return true; } void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade) @@ -10523,11 +10517,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW); - BOOL skip_avatar_update = FALSE; + bool skip_avatar_update = false; if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) { - skip_avatar_update = TRUE; + skip_avatar_update = true; } if (!skip_avatar_update) @@ -11287,7 +11281,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } } -void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) +void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture) { for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { @@ -11373,10 +11367,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) S32 occlusion = sUseOcclusion; sUseOcclusion = 0; - sReflectionRender = sRenderDeferred ? FALSE : TRUE; + sReflectionRender = ! sRenderDeferred; - sShadowRender = TRUE; - sImpostorRender = TRUE; + sShadowRender = true; + sImpostorRender = true; LLViewerCamera* viewer_camera = LLViewerCamera::getInstance(); @@ -11625,9 +11619,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLVOAvatar::sUseImpostors = true; // @TODO ??? sUseOcclusion = occlusion; - sReflectionRender = FALSE; - sImpostorRender = FALSE; - sShadowRender = FALSE; + sReflectionRender = false; + sImpostorRender = false; + sShadowRender = false; popRenderTypeMask(); gGL.matrixMode(LLRender::MM_PROJECTION); @@ -11644,7 +11638,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLGLState::checkClientArrays(); } -BOOL LLPipeline::hasRenderBatches(const U32 type) const +bool LLPipeline::hasRenderBatches(const U32 type) const { return sCull->getRenderMapSize(type) > 0; } @@ -11669,12 +11663,12 @@ LLCullResult::sg_iterator LLPipeline::endAlphaGroups() return sCull->endAlphaGroups(); } -BOOL LLPipeline::hasRenderType(const U32 type) const +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]); + // 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]); } void LLPipeline::setRenderTypeMask(U32 type, ...) @@ -11684,7 +11678,7 @@ void LLPipeline::setRenderTypeMask(U32 type, ...) va_start(args, type); while (type < END_RENDER_TYPES) { - mRenderTypeEnabled[type] = TRUE; + mRenderTypeEnabled[type] = true; type = va_arg(args, U32); } va_end(args); @@ -11695,7 +11689,7 @@ void LLPipeline::setRenderTypeMask(U32 type, ...) } } -BOOL LLPipeline::hasAnyRenderType(U32 type, ...) const +bool LLPipeline::hasAnyRenderType(U32 type, ...) const { va_list args; @@ -11704,7 +11698,7 @@ BOOL LLPipeline::hasAnyRenderType(U32 type, ...) const { if (mRenderTypeEnabled[type]) { - return TRUE; + return true; } type = va_arg(args, U32); } @@ -11715,7 +11709,7 @@ BOOL LLPipeline::hasAnyRenderType(U32 type, ...) const LL_ERRS() << "Invalid render type." << LL_ENDL; } - return FALSE; + return false; } void LLPipeline::pushRenderTypeMask() @@ -11740,10 +11734,10 @@ void LLPipeline::andRenderTypeMask(U32 type, ...) { va_list args; - BOOL tmp[NUM_RENDER_TYPES]; + bool tmp[NUM_RENDER_TYPES]; for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) { - tmp[i] = FALSE; + tmp[i] = false; } va_start(args, type); @@ -11751,7 +11745,7 @@ void LLPipeline::andRenderTypeMask(U32 type, ...) { if (mRenderTypeEnabled[type]) { - tmp[type] = TRUE; + tmp[type] = true; } type = va_arg(args, U32); @@ -11777,7 +11771,7 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...) va_start(args, type); while (type < END_RENDER_TYPES) { - mRenderTypeEnabled[type] = FALSE; + mRenderTypeEnabled[type] = false; type = va_arg(args, U32); } @@ -11793,7 +11787,7 @@ void LLPipeline::setAllRenderTypes() { for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) { - mRenderTypeEnabled[i] = TRUE; + mRenderTypeEnabled[i] = true; } } @@ -11801,7 +11795,7 @@ void LLPipeline::clearAllRenderTypes() { for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) { - mRenderTypeEnabled[i] = FALSE; + mRenderTypeEnabled[i] = false; } } @@ -11868,7 +11862,7 @@ void LLPipeline::restorePermanentObjects( const std::vector<U32>& restoreList ) skipRenderingOfTerrain( false ); } -void LLPipeline::skipRenderingOfTerrain( BOOL flag ) +void LLPipeline::skipRenderingOfTerrain( bool flag ) { pool_set_t::iterator iter = mPools.begin(); while ( iter != mPools.end() ) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index bba36351d9f374e9d18fd4f82a0fcd2f78493ac5..c9670a60f26cdcf265e3e5d810ceb02ffe2cf5d9 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -57,10 +57,10 @@ typedef enum e_avatar_skinning_method SKIN_METHOD_VERTEX_PROGRAM } EAvatarSkinningMethod; -BOOL compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn't be defined here! +bool compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn't be defined here! bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon = 0); -BOOL setup_hud_matrices(); // use whole screen to render hud -BOOL setup_hud_matrices(const LLRect& screen_region); // specify portion of screen (in pixels) to render hud attachments from (for picking) +bool setup_hud_matrices(); // use whole screen to render hud +bool setup_hud_matrices(const LLRect& screen_region); // specify portion of screen (in pixels) to render hud attachments from (for picking) glh::matrix4f glh_copy_matrix(F32* src); glh::matrix4f glh_get_current_modelview(); void glh_set_current_modelview(const glh::matrix4f& mat); @@ -133,11 +133,11 @@ class LLPipeline void resetVertexBuffers(LLDrawable* drawable); void generateImpostor(LLVOAvatar* avatar); void bindScreenToTexture(); - void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0); + void renderBloom(bool for_snapshot, F32 zoom_factor = 1.f, int subfield = 0); void init(); void cleanup(); - BOOL isInit() { return mInitialized; }; + 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. @@ -171,19 +171,19 @@ class LLPipeline void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL); void doOcclusion(LLCamera& camera); void markNotCulled(LLSpatialGroup* group, LLCamera &camera); - void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE); + void markMoved(LLDrawable *drawablep, bool damped_motion = false); void markShift(LLDrawable *drawablep); void markTextured(LLDrawable *drawablep); void markGLRebuild(LLGLUpdate* glu); - void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE); - void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); + void markRebuild(LLSpatialGroup* group, bool priority = false); + void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, bool priority = false); 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_transparent, + bool pick_rigged, 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 @@ -197,7 +197,7 @@ class LLPipeline LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end, - BOOL pick_transparent, + 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 @@ -212,20 +212,20 @@ class LLPipeline U32 addObject(LLViewerObject *obj); - void enableShadows(const BOOL enable_shadows); + void enableShadows(const bool enable_shadows); -// void setLocalLighting(const BOOL local_lighting); -// BOOL isLocalLightingEnabled() const; +// void setLocalLighting(const bool local_lighting); +// bool isLocalLightingEnabled() const; S32 setLightingDetail(S32 level); S32 getLightingDetail() const { return mLightingDetail; } S32 getMaxLightingDetail() const; - void setUseVertexShaders(BOOL use_shaders); - BOOL getUseVertexShaders() const { return mVertexShadersEnabled; } - BOOL canUseVertexShaders(); - BOOL canUseWindLightShaders() const; - BOOL canUseWindLightShadersOnObjects() const; - BOOL canUseAntiAliasing() const; + void setUseVertexShaders(bool use_shaders); + bool getUseVertexShaders() const { return mVertexShadersEnabled; } + bool canUseVertexShaders(); + bool canUseWindLightShaders() const; + bool canUseWindLightShadersOnObjects() const; + bool canUseAntiAliasing() const; // phases void resetFrameStats(); @@ -234,9 +234,9 @@ class LLPipeline 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)); + 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 updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); @@ -259,10 +259,10 @@ class LLPipeline void postSort(LLCamera& camera); void forAllVisibleDrawables(void (*func)(LLDrawable*)); - void renderObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE); - void renderMaskedObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE); + void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); + void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); - void renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture); + void renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture); void grabReferences(LLCullResult& result); void clearReferences(); @@ -274,7 +274,7 @@ class LLPipeline void checkReferences(LLSpatialGroup* group); - void renderGeom(LLCamera& camera, BOOL forceVBOUpdate = FALSE); + void renderGeom(LLCamera& camera, bool forceVBOUpdate = false); void renderGeomDeferred(LLCamera& camera); void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true); void renderGeomShadow(LLCamera& camera); @@ -292,7 +292,7 @@ class LLPipeline void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; } - void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader, BOOL use_occlusion, U32 target_width); + void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, bool use_shader, bool use_occlusion, U32 target_width); void renderHighlights(); void renderDebug(); void renderPhysicsDisplay(); @@ -300,13 +300,13 @@ class LLPipeline 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" + bool verify(); // Verify that all data in the pipeline is "correct" S32 getLightCount() const { return mLights.size(); } void calcNearbyLights(LLCamera& camera); void setupHWLights(LLDrawPool* pool); - void setupAvatarLights(BOOL for_edit = FALSE); + void setupAvatarLights(bool for_edit = false); void enableLights(U32 mask); void enableLightsStatic(); void enableLightsDynamic(); @@ -318,9 +318,9 @@ class LLPipeline void shiftObjects(const LLVector3 &offset); - void setLight(LLDrawable *drawablep, BOOL is_light); + void setLight(LLDrawable *drawablep, bool is_light); - BOOL hasRenderBatches(const U32 type) const; + bool hasRenderBatches(const U32 type) const; LLCullResult::drawinfo_iterator beginRenderMap(U32 type); LLCullResult::drawinfo_iterator endRenderMap(U32 type); LLCullResult::sg_iterator beginAlphaGroups(); @@ -329,15 +329,15 @@ class LLPipeline void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES); - BOOL hasRenderDebugFeatureMask(const U32 mask) const { return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; } - BOOL hasRenderDebugMask(const U32 mask) const { return (mRenderDebugMask & mask) ? TRUE : FALSE; } + bool hasRenderDebugFeatureMask(const U32 mask) const { return bool(mRenderDebugFeatureMask & mask); } + bool hasRenderDebugMask(const U32 mask) const { return bool(mRenderDebugMask & mask); } void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; } void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; } void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffff; } void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; } - BOOL hasRenderType(const U32 type) const; - BOOL hasAnyRenderType(const U32 type, ...) const; + bool hasRenderType(const U32 type) const; + bool hasAnyRenderType(const U32 type, ...) const; void setRenderTypeMask(U32 type, ...); // This is equivalent to 'setRenderTypeMask' @@ -356,53 +356,53 @@ class LLPipeline static void toggleRenderType(U32 type); // For UI control of render features - static BOOL hasRenderTypeControl(void* data); - static void toggleRenderDebug(void* data); - static void toggleRenderDebugFeature(void* data); - static void toggleRenderTypeControl(void* data); - static BOOL toggleRenderTypeControlNegated(void* data); - static BOOL toggleRenderDebugControl(void* data); - static BOOL toggleRenderDebugFeatureControl(void* data); + static bool hasRenderTypeControl(U32 data); + static void toggleRenderDebug(U32 data); + static void toggleRenderDebugFeature(U32 data); + static void toggleRenderTypeControl(U32 data); + static bool toggleRenderTypeControlNegated(S32 data); + static bool toggleRenderDebugControl(U32 data); + static bool toggleRenderDebugFeatureControl(U32 data); static void setRenderDebugFeatureControl(U32 bit, bool value); - static void setRenderParticleBeacons(BOOL val); - static void toggleRenderParticleBeacons(void* data); - static BOOL getRenderParticleBeacons(void* data); + static void setRenderParticleBeacons(bool val); + static void toggleRenderParticleBeacons(); + static bool getRenderParticleBeacons(); - static void setRenderSoundBeacons(BOOL val); - static void toggleRenderSoundBeacons(void* data); - static BOOL getRenderSoundBeacons(void* data); + static void setRenderSoundBeacons(bool val); + static void toggleRenderSoundBeacons(); + static bool getRenderSoundBeacons(); - static void setRenderMOAPBeacons(BOOL val); - static void toggleRenderMOAPBeacons(void * data); - static BOOL getRenderMOAPBeacons(void * data); + static void setRenderMOAPBeacons(bool val); + static void toggleRenderMOAPBeacons(); + static bool getRenderMOAPBeacons(); - static void setRenderPhysicalBeacons(BOOL val); - static void toggleRenderPhysicalBeacons(void* data); - static BOOL getRenderPhysicalBeacons(void* data); + static void setRenderPhysicalBeacons(bool val); + static void toggleRenderPhysicalBeacons(); + static bool getRenderPhysicalBeacons(); - static void setRenderScriptedBeacons(BOOL val); - static void toggleRenderScriptedBeacons(void* data); - static BOOL getRenderScriptedBeacons(void* data); + static void setRenderScriptedBeacons(bool val); + static void toggleRenderScriptedBeacons(); + static bool getRenderScriptedBeacons(); - static void setRenderScriptedTouchBeacons(BOOL val); - static void toggleRenderScriptedTouchBeacons(void* data); - static BOOL getRenderScriptedTouchBeacons(void* data); + static void setRenderScriptedTouchBeacons(bool val); + static void toggleRenderScriptedTouchBeacons(); + static bool getRenderScriptedTouchBeacons(); - static void setRenderBeacons(BOOL val); - static void toggleRenderBeacons(void* data); - static BOOL getRenderBeacons(void* data); + static void setRenderBeacons(bool val); + static void toggleRenderBeacons(); + static bool getRenderBeacons(); - static void setRenderHighlights(BOOL val); - static void toggleRenderHighlights(void* data); - static BOOL getRenderHighlights(void* data); + 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 updateRenderBump(); static void updateRenderDeferred(); static void refreshCachedSettings(); - static void throttleNewMemoryAllocation(BOOL disable); + static void throttleNewMemoryAllocation(bool disable); @@ -410,7 +410,7 @@ class LLPipeline void hidePermanentObjects( std::vector<U32>& restoreList ); void restorePermanentObjects( const std::vector<U32>& restoreList ); - void skipRenderingOfTerrain( BOOL flag ); + void skipRenderingOfTerrain( bool flag ); void hideObject( const LLUUID& id ); void restoreHiddenObject( const LLUUID& id ); @@ -418,7 +418,7 @@ class LLPipeline void unloadShaders(); void addToQuickLookup( LLDrawPool* new_poolp ); void removeFromQuickLookup( LLDrawPool* poolp ); - BOOL updateDrawableGeom(LLDrawable* drawable, BOOL priority); + bool updateDrawableGeom(LLDrawable* drawable, bool priority); void assertInitializedDoError(); bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; }; void connectRefreshCachedSettingsSafe(const std::string name); @@ -539,12 +539,12 @@ class LLPipeline LLSpatialPartition* getSpatialPartition(LLViewerObject* vobj); - void updateCamera(BOOL reset = FALSE); + void updateCamera(bool reset = false); LLVector3 mFlyCamPosition; LLQuaternion mFlyCamRotation; - BOOL mBackfaceCull; + bool mBackfaceCull; S32 mMatrixOpCount; S32 mTextureMatrixOps; S32 mNumVisibleNodes; @@ -557,36 +557,36 @@ class LLPipeline static S32 sCompiles; - static BOOL sShowHUDAttachments; - static BOOL sForceOldBakedUpload; // If true will not use capabilities to upload baked textures. + 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 sDelayVBUpdate; - static BOOL sAutoMaskAlphaDeferred; - static BOOL sAutoMaskAlphaNonDeferred; - static BOOL sDisableShaders; // if TRUE, rendering will be done without shaders - static BOOL sRenderBump; - static BOOL sBakeSunlight; - static BOOL sNoAlpha; - static BOOL sUseTriStrips; - static BOOL sUseFarClip; - static BOOL sShadowRender; - static BOOL sWaterReflections; - static BOOL sDynamicLOD; - static BOOL sPickAvatar; - static BOOL sReflectionRender; - static BOOL sImpostorRender; - static BOOL sImpostorRenderAlphaDepthPass; - static BOOL sUnderWaterRender; - static BOOL sRenderGlow; - static BOOL sTextureBindTest; - static BOOL sRenderFrameTest; - static BOOL sRenderAttachedLights; - static BOOL sRenderAttachedParticles; - static BOOL sRenderDeferred; - static BOOL sMemAllocationThrottled; + static bool sDelayVBUpdate; + static bool sAutoMaskAlphaDeferred; + static bool sAutoMaskAlphaNonDeferred; + static bool sDisableShaders; // if true, rendering will be done without shaders + static bool sRenderBump; + static bool sBakeSunlight; + static bool sNoAlpha; + static bool sUseTriStrips; + static bool sUseFarClip; + static bool sShadowRender; + static bool sWaterReflections; + static bool sDynamicLOD; + static bool sPickAvatar; + static bool sReflectionRender; + static bool sImpostorRender; + static bool sImpostorRenderAlphaDepthPass; + static bool sUnderWaterRender; + static bool sRenderGlow; + static bool sTextureBindTest; + static bool sRenderFrameTest; + static bool sRenderAttachedLights; + static bool sRenderAttachedParticles; + static bool sRenderDeferred; + static bool sMemAllocationThrottled; static S32 sVisibleLightCount; static F32 sMinRenderSize; - static BOOL sRenderingHUDs; + static bool sRenderingHUDs; static LLTrace::EventStatHandle<S64> sStatBatchSize; @@ -659,13 +659,13 @@ class LLPipeline LLVector3 mSunDir; LLVector3 mTransformedSunDir; - BOOL mInitialized; - BOOL mVertexShadersEnabled; + bool mInitialized; + bool mVertexShadersEnabled; S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback protected: - BOOL mRenderTypeEnabled[NUM_RENDER_TYPES]; + bool mRenderTypeEnabled[NUM_RENDER_TYPES]; std::stack<std::string> mRenderTypeEnableStack; U32 mRenderDebugFeatureMask; @@ -843,15 +843,15 @@ class LLPipeline U32 mLightMovingMask; S32 mLightingDetail; - static BOOL sRenderPhysicalBeacons; - static BOOL sRenderMOAPBeacons; - static BOOL sRenderScriptedTouchBeacons; - static BOOL sRenderScriptedBeacons; - static BOOL sRenderParticleBeacons; - static BOOL sRenderSoundBeacons; + 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; + static bool sRenderBeacons; + static bool sRenderHighlight; // Determines which set of UVs to use in highlight display // @@ -861,26 +861,26 @@ class LLPipeline static U32 sCurRenderPoolType ; //cached settings - static BOOL WindLightUseAtmosShaders; - static BOOL VertexShaderEnable; - static BOOL RenderAvatarVP; - static BOOL RenderDeferred; + static bool WindLightUseAtmosShaders; + static bool VertexShaderEnable; + static bool RenderAvatarVP; + static bool RenderDeferred; static F32 RenderDeferredSunWash; static U32 RenderFSAASamples; static U32 RenderResolutionDivisor; - static BOOL RenderUIBuffer; + static bool RenderUIBuffer; static S32 RenderShadowDetail; - static BOOL RenderDeferredSSAO; + static bool RenderDeferredSSAO; static F32 RenderShadowResolutionScale; - static BOOL RenderLocalLights; - static BOOL RenderDelayCreation; - static BOOL RenderAnimateRes; - static BOOL FreezeTime; + static bool RenderLocalLights; + 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 bool RenderSpotLightsInNondeferred; static LLColor4 PreviewAmbientColor; static LLColor4 PreviewDiffuse0; static LLColor4 PreviewSpecular0; @@ -900,8 +900,8 @@ class LLPipeline static S32 RenderGlowIterations; static F32 RenderGlowWidth; static F32 RenderGlowStrength; - static BOOL RenderDepthOfField; - static BOOL RenderDepthOfFieldInEditMode; + static bool RenderDepthOfField; + static bool RenderDepthOfFieldInEditMode; static F32 CameraFocusTransitionTime; static F32 CameraFNumber; static F32 CameraFocalLength; @@ -922,7 +922,7 @@ class LLPipeline static F32 RenderEdgeNormCutoff; static LLVector3 RenderShadowGaussian; static F32 RenderShadowBlurDistFactor; - static BOOL RenderDeferredAtmospheric; + static bool RenderDeferredAtmospheric; static S32 RenderReflectionDetail; static F32 RenderHighlightFadeTime; static LLVector3 RenderShadowClipPlanes; @@ -932,7 +932,7 @@ class LLPipeline static LLVector3 RenderShadowSplitExponent; static F32 RenderShadowErrorCutoff; static F32 RenderShadowFOVCutoff; - static BOOL CameraOffset; + static bool CameraOffset; static F32 CameraMaxCoF; static F32 CameraDoFResScale; static F32 RenderAutoHideSurfaceAreaLimit; @@ -942,7 +942,7 @@ void render_bbox(const LLVector3 &min, const LLVector3 &max); void render_hud_elements(); extern LLPipeline gPipeline; -extern BOOL gDebugPipeline; +extern bool gDebugPipeline; extern const LLMatrix4* gGLLastMatrix; #endif diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 8533625e500c5cb109d753f4674320db34a5722c..e0da7f5d9e856bf19d0017bc8a4c36d4c4fd383a 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -948,4 +948,13 @@ <color name="SyntaxLslStringLiteral" value="1 0.14 0 1" /> + <color + name="OutfitGalleryItemSelected" + value="0.22 0.45 0.35 1" /> + <color + name="OutfitGalleryItemWorn" + value="0.33 0.58 0.47 1" /> + <color + name="OutfitGalleryItemUnselected" + value="0.4 0.4 0.4 1" /> </colors> diff --git a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.png b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.png new file mode 100644 index 0000000000000000000000000000000000000000..bacddcbb680251ef535e795d7a5e92d353d44a3a Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.png differ diff --git a/indra/newview/skins/default/textures/icons/Video_URL_Off.png b/indra/newview/skins/default/textures/icons/Video_URL_Off.png new file mode 100644 index 0000000000000000000000000000000000000000..40e5df7d81372cf23f9e924e6f2dc9241a48f0f8 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Video_URL_Off.png differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 72037a84b3ff53dd8df1355e47b46fa657a04f18..760c294f9019b3d2675743a89a2b6d3cc55f229c 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -150,6 +150,7 @@ with the same filename but different name <texture name="Command_Places_Icon" file_name="toolbar_icons/places.png" preload="true" /> <texture name="Command_Preferences_Icon" file_name="toolbar_icons/preferences.png" preload="true" /> <texture name="Command_Profile_Icon" file_name="toolbar_icons/profile.png" preload="true" /> + <texture name="Command_Report_Abuse_Icon" file_name="toolbar_icons/report_abuse.png" preload="true" /> <texture name="Command_Search_Icon" file_name="toolbar_icons/search.png" preload="true" /> <texture name="Command_Snapshot_Icon" file_name="toolbar_icons/snapshot.png" preload="true" /> <texture name="Command_Speak_Icon" file_name="toolbar_icons/speak.png" preload="true" /> @@ -676,7 +677,10 @@ with the same filename but different name <texture name="Unread_Chiclet" file_name="bottomtray/Unread_Chiclet.png" preload="false" /> <texture name="UpArrow_Off" file_name="icons/UpArrow_Off.png" preload="false" /> - <texture name="Vertical Drag Handle" file_name="widgets/vertical_drag_handle.png" scale.left="2" scale.right="7" scale.bottom="8" scale.top="120" scale_type="scale_outer"/> + + <texture name="Video_URL_Off" file_name="icons/Video_URL_Off.png" preload="true" /> + + <texture name="Vertical Drag Handle" file_name="widgets/vertical_drag_handle.png" scale.left="2" scale.right="7" scale.bottom="8" scale.top="120" scale_type="scale_outer"/> <texture name="Volume_Background" file_name="windows/Volume_Background.png" preload="false" scale.left="6" scale.top="33" scale.right="63" scale.bottom="10" /> @@ -774,6 +778,9 @@ with the same filename but different name <texture name="default_land_picture.j2c" /> <texture name="default_profile_picture.j2c" /> <texture name="locked_image.j2c" /> + <texture name="badge_note.j2c" /> + <texture name="badge_warn.j2c" /> + <texture name="badge_ok.j2c" /> <texture name="materials_ui_x_24.png" /> <texture name="Progress_1" file_name="icons/Progress_1.png" preload="true" /> @@ -806,6 +813,7 @@ with the same filename but different name <texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/> <texture name="NavBar Separator" file_name="navbar/separator.png"/> + <texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo.png" preload="true"/> <texture name="Notification_Condense" file_name="icons/Icon_Notification_Condense.png" preload="true"/> <texture name="Notification_Expand" file_name="icons/Icon_Notification_Expand.png" preload="true"/> <texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/> diff --git a/indra/newview/skins/default/textures/toolbar_icons/report_abuse.png b/indra/newview/skins/default/textures/toolbar_icons/report_abuse.png new file mode 100644 index 0000000000000000000000000000000000000000..d5cb6ca2592b23f4059f306705769b03704983e0 Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/report_abuse.png differ diff --git a/indra/newview/skins/default/textures/windows/first_login_image_left.png b/indra/newview/skins/default/textures/windows/first_login_image_left.png index b405a882458d83d6be95c8b23045e4681079a26d..1fa10fde532d08bd105bea355a4bbf233039c86a 100644 Binary files a/indra/newview/skins/default/textures/windows/first_login_image_left.png and b/indra/newview/skins/default/textures/windows/first_login_image_left.png differ diff --git a/indra/newview/skins/default/textures/windows/first_login_image_right.png b/indra/newview/skins/default/textures/windows/first_login_image_right.png index 22a6dd8a53a5c22a7813bb66f9c58a0b06f90370..d764d846b731d03ec54e3bdc5391aea17952eb69 100644 Binary files a/indra/newview/skins/default/textures/windows/first_login_image_right.png and b/indra/newview/skins/default/textures/windows/first_login_image_right.png differ diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml index 8c0b5748ded5095d01c264e12ca32b72a882ce7b..779b168ae01fc2b829d1668662220ad5d3fdf5ba 100644 --- a/indra/newview/skins/default/xui/da/floater_about.xml +++ b/indra/newview/skins/default/xui/da/floater_about.xml @@ -25,6 +25,7 @@ Grafik kort: [GRAPHICS_CARD] J2C Decoder Version: [J2C_VERSION] Audio Driver Version: [AUDIO_DRIVER_VERSION] LLCEFLib/CEF Version: [LLCEFLIB_VERSION] +LibVLC Version: [LIBVLC_VERSION] Voice Server Version: [VOICE_VERSION] </floater.string> <floater.string name="none"> diff --git a/indra/newview/skins/default/xui/de/floater_model_preview.xml b/indra/newview/skins/default/xui/de/floater_model_preview.xml index f06e856966e353d76645013ab8ce3d7c5bd255f6..337fee8cb1b64a083543e9ee12b989e30eaf0c79 100644 --- a/indra/newview/skins/default/xui/de/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/de/floater_model_preview.xml @@ -245,6 +245,7 @@ </text> <check_box label="Skingewicht einschließen" name="upload_skin"/> <check_box label="Gelenkpositionen einschließen" name="upload_joints"/> + <check_box label="Skala sperren, wenn Gelenkposition definiert ist" name="lock_scale_if_joint_position"/> <text name="pelvis_offset_label"> Z-Offset (Avatar anheben oder senken): </text> diff --git a/indra/newview/skins/default/xui/de/floater_pay.xml b/indra/newview/skins/default/xui/de/floater_pay.xml index 1882f5150b523c79ca51663db83f606c4ff0a166..b9e253a6683c7678f9b95b9244a825b3402e208f 100644 --- a/indra/newview/skins/default/xui/de/floater_pay.xml +++ b/indra/newview/skins/default/xui/de/floater_pay.xml @@ -1,9 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Give Money" title=""> - <string name="payee_group">Gruppe bezahlen</string> - <string name="payee_resident">Einwohner bezahlen</string> - <text name="paying_text">Sie zahlen:</text> - <text left="130" name="payee_name">Extrem langen Namen testen, um zu prüfen, ob er abgeschnitten wird</text> + <string name="payee_group"> + Gruppe bezahlen + </string> + <string name="payee_resident"> + Einwohner bezahlen + </string> + <text name="paying_text"> + Sie zahlen: + </text> + <text left="130" name="payee_name"> + Extrem langen Namen testen, um zu prüfen, ob er abgeschnitten wird + </text> + <text name="payment_message_label"> + Beschreibung (optional): + </text> <panel label="Suchen" name="PatternsPanel"> <button label="L$ 1 zahlen" label_selected="L$ 1 zahlen" name="fastpay 1"/> <button label="L$ 5 zahlen" label_selected="L$ 5 zahlen" name="fastpay 5"/> @@ -11,7 +22,9 @@ <button label="L$ 20 zahlen" label_selected="L$ 20 zahlen" name="fastpay 20"/> </panel> <panel label="Suchen" name="InputPanel"> - <text name="amount text">Anderer Betrag:</text> + <text name="amount text"> + Anderer Betrag: + </text> <button label="Bezahlen" label_selected="Bezahlen" name="pay btn"/> <button label="Abbrechen" label_selected="Abbrechen" name="cancel btn"/> </panel> diff --git a/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml index 2c141f616ff139f2ac250016e3eb5830ea82add1..65a7e255f9bfec29d7cb2e8b6263b91505b135dd 100644 --- a/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Maximale Komplexität:" name="IndirectMaxComplexity" tool_tip="Bestimmt, an welchem Punkt ein visuell komplexer Avatar als „Gummibärchen“ dargestellt wird"/> + <slider label="Maximale Komplexität:" name="IndirectMaxComplexity" tool_tip="Bestimmt, an welchem Punkt ein visuell komplexer Avatar als JellyDoll dargestellt wird"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/de/floater_script_queue.xml b/indra/newview/skins/default/xui/de/floater_script_queue.xml index f267fe4b7c8f95fd3cf9b0523c6c7dede14c1654..d11ce83a3e9a24930626d94c5785e01441129400 100644 --- a/indra/newview/skins/default/xui/de/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/de/floater_script_queue.xml @@ -15,5 +15,11 @@ <floater.string name="NotRunning"> Läuft nicht </floater.string> + <floater.string name="Timeout"> + Timeout: [OBJECT_NAME] + </floater.string> + <floater.string name="LoadingObjInv"> + Inventar wird geladen für: [OBJECT_NAME] + </floater.string> <button label="Schließen" label_selected="Schließen" left="215" name="close" width="72"/> </floater> diff --git a/indra/newview/skins/default/xui/de/floater_web_content.xml b/indra/newview/skins/default/xui/de/floater_web_content.xml index 6ab119eeab2b9a54049181e2b9af2a198e87019d..c5c6eb969f6555d2886784e269ac30b9c5790878 100644 --- a/indra/newview/skins/default/xui/de/floater_web_content.xml +++ b/indra/newview/skins/default/xui/de/floater_web_content.xml @@ -10,5 +10,9 @@ <icon name="media_secure_lock_flag" tool_tip="Sicheres Browsen"/> <button name="popexternal" tool_tip="Aktuelle URL im Desktop-Browser öffnen"/> </layout_panel> + <layout_panel name="debug_controls"> + <button name="web_test_home_page" tool_tip="Webtests Homepage"/> + <button name="VLC Plugin Test" tool_tip="MPEG4-Videotest"/> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/de/menu_attachment_other.xml b/indra/newview/skins/default/xui/de/menu_attachment_other.xml index ddb1e7b0b1c112f29c3b5e044e732883d428cdf7..e0f0ea72ed0391885d25218e8615d3d244e463c4 100644 --- a/indra/newview/skins/default/xui/de/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/de/menu_attachment_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Anrufen" name="Call"/> <menu_item_call label="In Gruppe einladen" name="Invite..."/> + <menu_item_call label="Skelett zurücksetzen" name="Reset Skeleton"/> + <menu_item_call label="Skelett und Animationen zurücksetzen" name="Reset Skeleton And Animations"/> <menu_item_call label="Ignorieren" name="Avatar Mute"/> <menu_item_call label="Melden" name="abuse"/> <menu_item_call label="Einfrieren" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/de/menu_attachment_self.xml b/indra/newview/skins/default/xui/de/menu_attachment_self.xml index e0f37b28af7bb9e0a526a76b22b2b58bb6990b1d..f477b78b38b3b162ed9d449f51048d10a0583519 100644 --- a/indra/newview/skins/default/xui/de/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/de/menu_attachment_self.xml @@ -9,6 +9,8 @@ <menu_item_call label="Mein Outfit bearbeiten" name="Edit Outfit"/> <menu_item_call label="Meine Form bearbeiten" name="Edit My Shape"/> <menu_item_call label="Schwebehöhe" name="Hover Height"/> + <menu_item_call label="Skelett zurücksetzen" name="Reset Skeleton"/> + <menu_item_call label="Skelett und Animationen zurücksetzen" name="Reset Skeleton And Animations"/> <menu_item_call label="Meine Freunde" name="Friends..."/> <menu_item_call label="Meine Gruppen" name="Groups..."/> <menu_item_call label="Mein Profil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/de/menu_avatar_other.xml b/indra/newview/skins/default/xui/de/menu_avatar_other.xml index 7242ba1495bcd64b4c0c699c9bb31f4a8e54d331..9c24dc21991d168ae61ad128f14c15125d7822a8 100644 --- a/indra/newview/skins/default/xui/de/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/de/menu_avatar_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Anrufen" name="Call"/> <menu_item_call label="In Gruppe einladen" name="Invite..."/> + <menu_item_call label="Skelett zurücksetzen" name="Reset Skeleton"/> + <menu_item_call label="Skelett und Animationen zurücksetzen" name="Reset Skeleton And Animations"/> <menu_item_call label="Ignorieren" name="Avatar Mute"/> <menu_item_call label="Melden" name="abuse"/> <menu_item_call label="Einfrieren" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/de/menu_avatar_self.xml b/indra/newview/skins/default/xui/de/menu_avatar_self.xml index b53f8cd6af9faf038a2f3d7bcb0502a93279b06b..9b6e267b4252854fefe42c0c5ffffdb72a0f1d35 100644 --- a/indra/newview/skins/default/xui/de/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/de/menu_avatar_self.xml @@ -26,6 +26,8 @@ <menu_item_call label="Mein Outfit bearbeiten" name="Edit Outfit"/> <menu_item_call label="Meine Form bearbeiten" name="Edit My Shape"/> <menu_item_call label="Schwebehöhe" name="Hover Height"/> + <menu_item_call label="Skelett zurücksetzen" name="Reset Skeleton"/> + <menu_item_call label="Skelett und Animationen zurücksetzen" name="Reset Skeleton And Animations"/> <menu_item_call label="Meine Freunde" name="Friends..."/> <menu_item_call label="Meine Gruppen" name="Groups..."/> <menu_item_call label="Mein Profil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/de/menu_login.xml b/indra/newview/skins/default/xui/de/menu_login.xml index 2dc4c1d687a85226a1df624571ff2411c4f314c9..ff21f079432de5e530e3c666b1d9bd562270d90f 100644 --- a/indra/newview/skins/default/xui/de/menu_login.xml +++ b/indra/newview/skins/default/xui/de/menu_login.xml @@ -20,13 +20,12 @@ <menu_item_check label="Debug-Menü anzeigen" name="Show Debug Menu"/> <menu label="Debug" name="Debug"> <menu_item_call label="Debug-Einstellungen anzeigen" name="Debug Settings"/> - <menu_item_call label="UI/Farb-Einstellungen" name="UI/Color Settings"/> <menu_item_call label="XUI-Editor" name="UI Preview Tool"/> <menu label="UI-Tests" name="UI Tests"/> <menu_item_call label="Fenstergröße einstellen..." name="Set Window Size..."/> <menu_item_call label="Servicebedingungen anzeigen" name="TOS"/> <menu_item_call label="Wichtige Meldung anzeigen" name="Critical"/> - <menu_item_call label="Web Content Floater Debug Test" name="Web Content Floater Debug Test"/> + <menu_item_call label="Medienbrowser" name="Media Browser"/> <menu label="Protokollierungsstufe festlegen" name="Set Logging Level"> <menu_item_check label="Debug" name="Debug"/> <menu_item_check label="Info" name="Info"/> diff --git a/indra/newview/skins/default/xui/de/menu_object_icon.xml b/indra/newview/skins/default/xui/de/menu_object_icon.xml index f92fa0f82b7c512a6761c8eb0e2348079cf32c75..f2f3dddd0bad0c006e0cdb2073284097a06df9f7 100644 --- a/indra/newview/skins/default/xui/de/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/de/menu_object_icon.xml @@ -2,6 +2,7 @@ <menu name="Object Icon Menu"> <menu_item_call label="Objektprofil..." name="Object Profile"/> <menu_item_call label="Ignorieren..." name="Block"/> + <menu_item_call label="Freischalten" name="Unblock"/> <menu_item_call label="Auf Karte anzeigen" name="show_on_map"/> <menu_item_call label="Zu Objektposition teleportieren" name="teleport_to_object"/> </menu> diff --git a/indra/newview/skins/default/xui/de/menu_outfit_gear.xml b/indra/newview/skins/default/xui/de/menu_outfit_gear.xml index 0cf3c09882bb17059fc452fef82890f48cb7aa92..211cc5c54e232ccb1a588f8c49732c372fcbf614 100644 --- a/indra/newview/skins/default/xui/de/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/de/menu_outfit_gear.xml @@ -3,6 +3,10 @@ <menu_item_call label="Anziehen - Aktuelles Outfit ersetzen" name="wear"/> <menu_item_call label="Anziehen - Aktuelles Outfit hinzufügen" name="wear_add"/> <menu_item_call label="Ausziehen - Aus aktuellem Outfit entfernen" name="take_off"/> + <menu_item_call label="Foto hochladen (10 L$)" name="upload_photo"/> + <menu_item_call label="Foto auswählen" name="select_photo"/> + <menu_item_call label="Schnappschuss aufnehmen" name="take_snapshot"/> + <menu_item_call label="Foto entfernen" name="remove_photo"/> <menu label="Neue Kleider" name="New Clothes"> <menu_item_call label="Neues Hemd" name="New Shirt"/> <menu_item_call label="Neue Hose" name="New Pants"/> @@ -27,4 +31,5 @@ <menu_item_call label="Alle Ordner schließen" name="collapse"/> <menu_item_call label="Outfit neu benennen" name="rename"/> <menu_item_call label="Outfit löschen" name="delete_outfit"/> + <menu_item_check label="Ordner immer nach Namen sortieren" name="sort_folders_by_name"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/de/menu_people_friends_view.xml b/indra/newview/skins/default/xui/de/menu_people_friends_view.xml index da4890fe96ceeba7eb8d0436191d066b01671261..d6c4d419fa6755cf54215e4884385e0ec4efe6a6 100644 --- a/indra/newview/skins/default/xui/de/menu_people_friends_view.xml +++ b/indra/newview/skins/default/xui/de/menu_people_friends_view.xml @@ -4,5 +4,6 @@ <menu_item_check label="Nach Status sortieren" name="sort_status"/> <menu_item_check label="Symbole für Personen anzeigen" name="view_icons"/> <menu_item_check label="Erteilte Genehmigungen anzeigen" name="view_permissions"/> + <menu_item_check label="Benutzernamen ausblenden" name="view_usernames"/> <menu_item_check label="Unterhaltungsprotokoll anzeigen..." name="view_conversation"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/de/menu_people_nearby.xml b/indra/newview/skins/default/xui/de/menu_people_nearby.xml index cdbb3ae917c19c18ce9cc1a3b8dff42b80873f62..40914b6f68d2b06e43082796d13a8b95174711b7 100644 --- a/indra/newview/skins/default/xui/de/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/de/menu_people_nearby.xml @@ -13,4 +13,6 @@ <menu_item_call label="Freigeben" name="share"/> <menu_item_call label="Bezahlen" name="pay"/> <menu_item_check label="Ignorieren/Nicht mehr ignorieren" name="block_unblock"/> + <menu_item_call label="Einfrieren" name="freeze"/> + <menu_item_call label="Hinauswerfen" name="eject"/> </context_menu> diff --git a/indra/newview/skins/default/xui/de/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/de/menu_people_nearby_view.xml index d38ec65037661b26f08063a5a02091fc8c9600dc..61cc4fe09871f81d81e1c6227e969b8b61de7eb5 100644 --- a/indra/newview/skins/default/xui/de/menu_people_nearby_view.xml +++ b/indra/newview/skins/default/xui/de/menu_people_nearby_view.xml @@ -5,4 +5,5 @@ <menu_item_check label="Nach Nähe sortieren" name="sort_distance"/> <menu_item_check label="Symbole für Personen anzeigen" name="view_icons"/> <menu_item_check label="Karte anzeigen" name="view_map"/> + <menu_item_check label="Benutzernamen ausblenden" name="view_usernames"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/de/menu_url_objectim.xml b/indra/newview/skins/default/xui/de/menu_url_objectim.xml index fc01ea84447e158afec28986d4bebe443093f7bd..95fe97407bda45e84e77bdacf86ecadff952ca74 100644 --- a/indra/newview/skins/default/xui/de/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/de/menu_url_objectim.xml @@ -2,6 +2,7 @@ <context_menu name="Url Popup"> <menu_item_call label="Objektprofil..." name="show_object"/> <menu_item_call label="Blockieren..." name="block_object"/> + <menu_item_call label="Freischalten" name="unblock_object"/> <menu_item_call label="Auf Karte zeigen" name="show_on_map"/> <menu_item_call label="Zu Objekt-Position teleportieren" name="teleport_to_object"/> <menu_item_call label="Objektname in Zwischenablage kopieren" name="url_copy_label"/> diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml index d83a6071f6e1a8b75810a16fdbc4597208b91515..db57e416611b2b2a3db18111c10693358b93fd38 100644 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Nicht stören" name="Do Not Disturb"/> </menu> <menu_item_call label="L$ kaufen..." name="Buy and Sell L$"/> - <menu_item_call label="Händler-Outbox..." name="MerchantOutbox"/> <menu_item_call label="Marktplatz-Auflistungen..." name="MarketplaceListings"/> <menu_item_call label="Kontoübersicht..." name="Manage My Account"> <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=de"/> @@ -114,11 +113,11 @@ <menu_item_call label="Verknüpfung" name="Link"/> <menu_item_call label="Verknüpfung auflösen" name="Unlink"/> <menu_item_check label="Verknüpfte Teile bearbeiten" name="Edit Linked Parts"/> - <menu label="Verknüpfte Teile auswählen" name="Select Linked Parts"> - <menu_item_call label="Nächstes Teil auswählen" name="Select Next Part"/> - <menu_item_call label="Vorheriges Teil auswählen" name="Select Previous Part"/> - <menu_item_call label="Nächsten Teil mit einsschließen" name="Include Next Part"/> - <menu_item_call label="Vorherige Teile mit einschließen" name="Include Previous Part"/> + <menu label="Elemente auswählen" name="Select Elements"> + <menu_item_call label="Nächsten Teil oder nächste Fläche auswählen" name="Select Next Part or Face"/> + <menu_item_call label="Vorherigen Teil oder vorherige Fläche auswählen" name="Select Previous Part or Face"/> + <menu_item_call label="Nächsten Teil oder nächste Fläche einschließen" name="Include Next Part or Face"/> + <menu_item_call label="Vorherigen Teil oder vorherige Fläche einschließen" name="Include Previous Part or Face"/> </menu> <menu_item_call label="Linksets..." name="pathfinding_linkset_menu_item"/> <menu_item_call label="Fokus auf Auswahl" name="Focus on Selection"/> @@ -369,8 +368,7 @@ <menu_item_call label="Regionsobjekt-Cache ausgeben" name="Dump Region Object Cache"/> </menu> <menu label="UI" name="UI"> - <menu_item_call label="Test Medienbrowser" name="Web Browser Test"/> - <menu_item_call label="Webinhaltsbrowser" name="Web Content Browser"/> + <menu_item_call label="Medienbrowser" name="Media Browser"/> <menu_item_call label="SelectMgr ausgeben" name="Dump SelectMgr"/> <menu_item_call label="Inventarinfo ausgeben" name="Dump Inventory"/> <menu_item_call label="Timer ausgeben" name="Dump Timers"/> @@ -415,6 +413,7 @@ <menu_item_check label="LOD deaktiveren" name="Disable LOD"/> <menu_item_check label="Fehler für sichtbare Agenten beseitigen" name="Debug Character Vis"/> <menu_item_check label="Gelenkpunkte anzeigen" name="Show Collision Skeleton"/> + <menu_item_check label="Knochen anzeigen" name="Show Bones"/> <menu_item_check label="Agent-Ziel anzeigen" name="Display Agent Target"/> <menu_item_call label="Anhänge ausgeben" name="Dump Attachments"/> <menu_item_call label="Fehler in Avatar-Texturen beseitigen" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/de/menu_wearing_tab.xml b/indra/newview/skins/default/xui/de/menu_wearing_tab.xml index 695451a105602b82daac79f9b5b6643096cae321..61002b3dad2564f0c889b300467c6be68c022c32 100644 --- a/indra/newview/skins/default/xui/de/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/de/menu_wearing_tab.xml @@ -3,4 +3,6 @@ <menu_item_call label="Ausziehen" name="take_off"/> <menu_item_call label="Abnehmen" name="detach"/> <menu_item_call label="Outfit bearbeiten" name="edit"/> + <menu_item_call label="Bearbeiten" name="edit_item"/> + <menu_item_call label="Original anzeigen" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/de/mime_types.xml b/indra/newview/skins/default/xui/de/mime_types.xml index ee05e47a6359c6139850039e7c50b1acb8f2c330..8728a577378aa7450c62a333ba48f25d1b13a58b 100644 --- a/indra/newview/skins/default/xui/de/mime_types.xml +++ b/indra/newview/skins/default/xui/de/mime_types.xml @@ -57,6 +57,11 @@ Echtzeit-Streaming </label> </scheme> + <scheme name="libvlc"> + <label name="libvlc_label"> + Von LibVLC unterstützte Medien + </label> + </scheme> <mimetype name="blank"> <label name="blank_label"> - Keine - @@ -202,6 +207,11 @@ Video (MP4) </label> </mimetype> + <mimetype name="application/octet-stream"> + <label name="video/octet-stream"> + Film + </label> + </mimetype> <mimetype menu="1" name="video/quicktime"> <label name="video/quicktime_label"> Video (QuickTime) diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index 6fcd025a945897fae572e1e213db24e38411b4b9..25e013ed907ed0f1315bec2b18c2010b53fbda70 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -336,6 +336,9 @@ Wenn diese Rolle nicht mehr diese Fähigkeiten haben soll, deaktivieren Sie sie Sie sind dabei, [COUNT] Mitglieder aus der Gruppe zu verbannen. <usetemplate ignoretext="Verbannen mehrerer Gruppenmitglieder bestätigen" name="okcancelignore" notext="Abbrechen" yestext="Verbannen"/> </notification> + <notification name="GroupBanUserOnBanlist"> + Manchen Einwohnern wurde keine Einladung gesendet, weil sie aus der Gruppe ausgeschlossen sind. + </notification> <notification name="AttachmentDrop"> Sie möchten Ihren Anhang wirklich fallen lassen? Möchten Sie fortfahren? @@ -464,6 +467,12 @@ Um Medien nur auf einer Fläche einzufügen, wählen Sie „Oberfläche auswähl <notification name="ErrorEncodingSnapshot"> Fehler beim Erstellen des Fotos! </notification> + <notification name="ErrorPhotoCannotAfford"> + Es kostet L$[COST], um ein Foto in Ihrem Inventar zu speichern. Sie können entweder L$ kaufen oder das Foto auf Ihrem Computer speichern. + </notification> + <notification name="ErrorTextureCannotAfford"> + Es kostet L$[COST], um eine Textur in Ihrem Inventar zu speichern. Sie können entweder L$ kaufen oder das Foto auf Ihrem Computer speichern. + </notification> <notification name="ErrorUploadingPostcard"> Ein Foto konnte aus folgendem Grund nicht gesendet werden: [REASON] </notification> @@ -487,6 +496,9 @@ Der Outfit-Ordner enthält keine Kleidung, Körperteile oder Anhänge. <notification name="CannotWearInfoNotComplete"> Sie können das Objekt nicht anziehen, weil es noch nicht geladen wurde. Warten Sie kurz und versuchen Sie es dann noch einmal. </notification> + <notification name="MustEnterPasswordToLogIn"> + Bitte geben Sie zur Anmeldung Ihr Kennwort ein. + </notification> <notification name="MustHaveAccountToLogIn"> Sue haben ein Feld leer gelassen. Sie müssen den Benutzernamen Ihres Avatars eingeben. @@ -555,6 +567,9 @@ Hinweis: Der Cache wird dabei gelöscht/geleert. <notification name="ChangeConnectionPort"> Die Port-Einstellungen werden nach einem Neustart von [APP_NAME] wirksam. </notification> + <notification name="ChangeDeferredDebugSetting"> + Die Debug-Einstellung tritt nach Neustart von [APP_NAME] in Kraft. + </notification> <notification name="ChangeSkin"> Die neue Benutzeroberfläche wird nach einem Neustart von [APP_NAME] angezeigt. </notification> @@ -576,6 +591,10 @@ Hinweis: Der Cache wird dabei gelöscht/geleert. Notizkarte löschen? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="LoadPreviousReportScreenshot"> + Möchten Sie den vorherigen Screenshot für Ihren Bericht verwenden? + <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> + </notification> <notification name="GestureSaveFailedTooManySteps"> Speichern der Geste fehlgeschlagen. Die Geste besteht aus zu vielen Schritten. @@ -636,30 +655,12 @@ Weitere Informationen finden Sie auf [_URL]. </url> <usetemplate ignoretext="Meine Hardware wird nicht unterstützt" name="okcancelignore" notext="Nein" yestext="Ja"/> </notification> - <notification name="IntelOldDriver"> - Wahrscheinlich gibt es einen neueren Treiber für Ihren Grafikchip. Durch Aktualisieren der Grafiktreiber lässt sich die Leistung u. U. beträchtlich verbessern. - - Unter [_URL] nach aktualisierten Treibern suchen? - <url name="url"> - http://www.intel.com/p/de_DE/support/detect/graphics - </url> - <usetemplate ignoretext="Mein Grafiktreiber ist veraltet" name="okcancelignore" notext="Nein" yestext="Ja"/> - </notification> - <notification name="AMDOldDriver"> - Wahrscheinlich gibt es einen neueren Treiber für Ihren Grafikchip. Durch Aktualisieren der Grafiktreiber lässt sich die Leistung u. U. beträchtlich verbessern. - - Unter [_URL] nach aktualisierten Treibern suchen? - <url name="url"> - http://support.amd.com/de/Pages/AMDSupportHub.aspx - </url> - <usetemplate ignoretext="Mein Grafiktreiber ist veraltet" name="okcancelignore" notext="Nein" yestext="Ja"/> - </notification> - <notification name="NVIDIAOldDriver"> + <notification name="OldGPUDriver"> Wahrscheinlich gibt es einen neueren Treiber für Ihren Grafikchip. Durch Aktualisieren der Grafiktreiber lässt sich die Leistung u. U. beträchtlich verbessern. - Unter [_URL] nach aktualisierten Treibern suchen? + Unter [URL] nach aktualisierten Treibern suchen? <url name="url"> - http://www.nvidia.com/Download/index.aspx?lang=de-de + [URL] </url> <usetemplate ignoretext="Mein Grafiktreiber ist veraltet" name="okcancelignore" notext="Nein" yestext="Ja"/> </notification> @@ -750,6 +751,9 @@ Verschieben Sie alle betreffenden Objekte in dieselbe Region. </url> <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="MuteLimitReached"> + Sie können keinen weiteren Eintrag zur Liste der ignorierten Einwohner hinzufügen, weil der Höchstwert ([MUTE_LIMIT] Einträge) erreicht ist. + </notification> <notification name="UnableToLinkObjects"> Verknüpfung dieser [COUNT] Objekte nicht möglich. Sie können maximal [MAX] Objekte verknüpfen. @@ -1380,12 +1384,18 @@ Sie können [SECOND_LIFE] normal verwenden. Andere Benutzer können Sie korrekt <ignore name="ignore" text="Das Herunterladen der Kleidung dauert lange"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - Ihre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 visuelle Komplexität] ist [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + Ihre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Avatarkomplexität] ist [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Warnen, falls Avatarkomplexität zu hoch ist" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - Ihre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 visuelle Komplexität] ist [AGENT_COMPLEXITY]. + Ihre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Avatarkomplexität] ist [AGENT_COMPLEXITY]. + <usetemplate ignoretext="Warnung anzeigen, wenn sich die Komplexität meines Avatars ändert" name="notifyignore"/> + </notification> + <notification name="HUDComplexityWarning"> + [HUD_REASON]; dies wirkt sich wahrscheinlich negativ auf die Leistung aus. + <usetemplate ignoretext="Warnung anzeigen, wenn die Komplexität meines HUD zu hoch ist" name="notifyignore"/> </notification> <notification name="FirstRun"> Installation von [APP_NAME] vollständig abgeschlossen. @@ -1478,6 +1488,10 @@ Wählen Sie ein einzelnes Objekt aus und versuchen Sie es erneut. Alle Einwohner in dieser Region nach Hause teleportieren? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="ChangeObjectBonusFactor"> + Wenn Sie den Objektbonus heruntersetzen, nachdem in einer Region Bauwerke errichtet wurden, können Objekte möglicherweise zurückgegeben oder gelöscht werden. Möchten Sie den Objektbonus wirklich ändern? + <usetemplate ignoretext="Änderung des Objektbonusfaktors bestätigen" name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> <notification name="EstateObjectReturn"> Möchten Sie wirklich alle Objekte zurückgeben, die [USER_NAME] gehören? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> @@ -1501,6 +1515,10 @@ Ersetzen Sie die Textur [TEXTURE_NUM] mit einer Bilddatei von maximal 512x512 un Möchten Sie das aktuelle Terrain formen, es zum Mittelpunkt der oberen und unteren Terraingrenzen und zum Standard des „Zurücksetzen“-Tools machen? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + Sie sind dabei, für Höhenbereiche untere Werte anzugeben, die größer sind als die oberen Werte. Fortfahren? + <usetemplate canceltext="Nicht fragen" name="yesnocancelbuttons" notext="Abbrechen" yestext="OK"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Es sind maximal [MAX_AGENTS] zulässige Einwohner erlaubt. </notification> @@ -1521,6 +1539,9 @@ Ersetzen Sie die Textur [TEXTURE_NUM] mit einer Bilddatei von maximal 512x512 un <notification name="OwnerCanNotBeDenied"> Der Eigentümer des Grundbesitzes kann nicht zur Liste der „Verbannten Einwohner“ hinzugefügt werden. </notification> + <notification name="ProblemAddingEstateManagerBanned"> + Verbannter Einwohner kann nicht zur Grundbesitzverwalterliste hinzugefügt werden. + </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> Das Aussehen lässt sich erst ändern, wenn Kleider und Form/Gestalt geladen sind. </notification> @@ -1692,6 +1713,10 @@ Wenn Sie die neuesten Features und Fixes ausprobieren möchten, gehen Sie zur Se Möchten Sie Ihren Internetbrowser öffnen, um diesen Inhalt anzuzeigen? <usetemplate ignoretext="Meinen Browser starten, um eine Webseite anzuzeigen" name="okcancelignore" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="SystemUIScaleFactorChanged"> + Der UI-Größenfaktor des Systems hat sich seit der letzten Ausführung geändert. Möchten Sie die Seite mit den UI-Größeneinstellungen öffnen? + <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> + </notification> <notification name="WebLaunchJoinNow"> Möchten Sie Ihre [http://secondlife.com/account/ Startseite] aufrufen, um Ihr Konto zu verwalten? <usetemplate ignoretext="Meinen Browser starten, um mein Konto zu verwalten" name="okcancelignore" notext="Abbrechen" yestext="OK"/> @@ -1731,16 +1756,15 @@ Wenn Sie die neuesten Features und Fixes ausprobieren möchten, gehen Sie zur Se Diese Gruppe verlassen? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="GroupDepart"> + Sie haben die Gruppe „[group_name]“ verlassen. + </notification> <notification name="OwnerCannotLeaveGroup"> Sie können die Gruppe nicht verlassen, da Sie der letzte Besitzer der Gruppe sind. Weisen Sie die Besitzerrolle zuerst einem anderen Mitglied zu. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="GroupDepartError"> - Kann Gruppe nicht verlassen: [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Sie haben die Gruppe „[group_name]“ verlassen. + Sie können die Gruppe nicht verlassen, <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="ConfirmKick"> @@ -2142,6 +2166,10 @@ Tausende Regionen werden verändert und der Spaceserver wird dadurch stark belas Zu viele Prims wurden ausgewählt. Bitte wählen Sie höchstens [MAX_PRIM_COUNT] Prims aus und versuchen Sie es erneut. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="TooManyScriptsSelected"> + Zu viele Skripts in den Objekten ausgewählt. Bitte wählen Sie weniger Objekte aus und versuchen Sie es erneut. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="ProblemImportingEstateCovenant"> Problem beim Import des Grundbesitzvertrags. <usetemplate name="okbutton" yestext="OK"/> @@ -2311,6 +2339,10 @@ Inventarobjekt(e) verschieben? Zahlung fehlgeschlagen: Objekt nicht gefunden. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="PaymentBlockedButtonMismatch"> + Zahlung gestoppt: Der bezahlte Preis stimmt nicht mit den für dieses Objekt definierten Zahlungsschaltflächen überein. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="OpenObjectCannotCopy"> Sie haben keine Berechtigung zum Kopieren von Elementen in diesem Objekt. </notification> @@ -2346,6 +2378,11 @@ Diese Aktion kann nicht rückgängig gemacht werden. Dies ist eine große Auswahl mit Linksets. Wenn Sie die Verknüpfung auflösen, kann sie möglicherweise nicht erneut hergestellt werden. Als Vorsichtsmaßnahme empfiehlt es sich, Kopien von Linksets in Ihr Inventar aufzunehmen. <usetemplate ignoretext="Auflösen der Verknüpfung eines Linksets bestätigen" name="okcancelignore" notext="Abbrechen" yestext="Verknüpfung auflösen"/> </notification> + <notification name="HelpReportAbuseConfirm"> + Vielen Dank, dass Sie uns über dieses Problem informiert haben. +Wir untersuchen Ihre Meldung, um zu bestimmen, ob ein Missbrauch vorliegt, und werden dann die entsprechende Maßnahme ergreifen. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="HelpReportAbuseSelectCategory"> Wählen Sie eine Missbrauchskategorie aus. Die Angabe einer Kategorie hilft uns bei der Bearbeitung des Berichts. @@ -2415,6 +2452,10 @@ Möchten Sie den Nicht-stören-Modus deaktivieren, bevor Sie diese Transaktion a Sind Sie sicher, dass Sie den Inhalt Ihres Papierkorbs löschen möchten? <usetemplate ignoretext="Bestätigen, bevor der Ordner Papierkorb im Inventar geleert wird" name="okcancelignore" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + Ihr Papierkorb läuft über. Dies kann zu Anmeldeproblemen führen. + <usetemplate name="okcancelbuttons" notext="Papierkorb später leeren" yestext="Papierkorb jetzt leeren"/> + </notification> <notification name="ConfirmClearBrowserCache"> Sind Sie sicher, dass Sie Ihren Reise-, Internet- und Suchverlauf löschen möchten? <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> @@ -2769,6 +2810,10 @@ Fliegen ist hier nicht möglich. <notification name="PathfindingDirty"> Diese Region weist ausstehende Pathfinding-Änderungen auf. Wenn Sie Baurechte besitzen, können Sie die Region durch Klicken auf die Schaltfläche „Region neu formen“ neu formen. </notification> + <notification name="PathfindingDirtyRebake"> + Diese Region weist ausstehende Pathfinding-Änderungen auf. Wenn Sie Baurechte besitzen, können Sie die Region durch Klicken auf die Schaltfläche „Region neu formen“ neu formen. + <usetemplate name="okbutton" yestext="Region neu formen"/> + </notification> <notification name="DynamicPathfindingDisabled"> Dynamisches Pathfinding ist in dieser Region nicht aktiviert. Geskriptete Objekte, die Pathfinding-LSL-Aufrufe verwenden, funktionieren in dieser Region u. U. nicht wie erwartet. </notification> @@ -3272,6 +3317,12 @@ Diese werden für ein paar Sekunden sicherheitshalber gesperrt. <notification name="AttachmentSaved"> Der Anhang wurde gespeichert. </notification> + <notification name="AppearanceToXMLSaved"> + Erscheinungsbild als XML in [PATH] gespeichert + </notification> + <notification name="AppearanceToXMLFailed"> + Fehler beim Speichern des Erscheinungsbilds als XML. + </notification> <notification name="PresetNotSaved"> Fehler beim Speichern der Voreinstellung [NAME]. </notification> @@ -3484,13 +3535,6 @@ Durch Ausblenden der Schaltfläche „Sprechen“ wird die Sprechfunktion deakti <notification name="ForceQuitDueToLowMemory"> SL wird wegen Speichermangel in 30 Sekunden beendet. </notification> - <notification name="PopupAttempt"> - Ein Popup konnte nicht geöffnet werden. - <form name="form"> - <ignore name="ignore" text="Alle Popups aktivieren"/> - <button name="open" text="Popup-Fenster öffnen"/> - </form> - </notification> <notification name="SOCKS_NOT_PERMITTED"> SOCKS 5-Proxy „[HOST]:[PORT]“ hat Verbindungsverbindung abgewiesen, da laut Regelsatz nicht zulässig. <usetemplate name="okbutton" yestext="OK"/> @@ -3865,6 +3909,9 @@ Warten Sie kurz und versuchen Sie es noch einmal. Objekt „[OBJECT_NAME]“ kann nicht nach [OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da nicht genügend Ressourcen für dieses Objekt auf dieser Parzelle vorhanden sind. </notification> + <notification name="NoParcelPermsNoObject"> + Kopiervorgang fehlgeschlagen, da Sie keinen Zugriff auf diese Parzelle haben. + </notification> <notification name="CantMoveObjectRegionVersion"> Objekt „[OBJECT_NAME]“ kann nicht nach [OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da die andere Region eine ältere Version verwendet, die das Empfangen dieses Objekts per Regionswechsel nicht unterstützt. @@ -3880,6 +3927,10 @@ Warten Sie kurz und versuchen Sie es noch einmal. <notification name="NoPermModifyObject"> Ihnen fehlt die Berechtigung zum Modifizieren dieses Objekts. </notification> + <notification name="TooMuchObjectInventorySelected"> + Zu viele Objekte mit umfangreichem Inventar ausgewählt. Bitte wählen Sie weniger Objekte aus und versuchen Sie es erneut. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="CantEnablePhysObjContributesToNav"> Physik kann nicht für ein Objekt aktiviert werden, das zum Navmesh beiträgt. </notification> @@ -3916,6 +3967,12 @@ Warten Sie kurz und versuchen Sie es noch einmal. <notification name="CantSaveModifyAttachment"> Kein Speichern in Objektinhalt möglich: Dadurch würden die Anhängeberechtigungen geändert. </notification> + <notification name="AttachmentHasTooMuchInventory"> + Ihre Anhänge enthalten zu viele Inventarobjekte. Sie können keine weiteren hinzufügen. + </notification> + <notification name="IllegalAttachment"> + Der Anhang hat einen nicht vorhandenen Punkt auf dem Avatar angefordert. Der Anhang wurde stattdessen auf der Brust angebracht. + </notification> <notification name="TooManyScripts"> Zu viele Skripts. </notification> @@ -4008,6 +4065,12 @@ Warten Sie kurz und versuchen Sie es noch einmal. <notification name="TeleportedByObjectUnknownUser"> Sie wurden von Objekt „[OBJECT_NAME]“, das einem unbekannten Benutzer gehört, teleportiert. </notification> + <notification name="StandDeniedByObject"> + „[OBJECT_NAME]“ lässt zur Zeit nicht zu, dass Sie stehen. + </notification> + <notification name="ResitDeniedByObject"> + „[OBJECT_NAME]“ lässt zur Zeit nicht zu, dass Sie sich woanders hinsetzen. + </notification> <notification name="CantCreateObjectRegionFull"> Angefordertes Objekt kann nicht erstellt werden. Die Region ist voll. </notification> @@ -4304,6 +4367,9 @@ Wählen Sie eine kleinere Landfläche aus. <notification name="CantTransfterMoneyRegionDisabled"> Geldüberweisungen an Objekte sind in dieser Region gegenwärtig deaktiviert. </notification> + <notification name="DroppedMoneyTransferRequest"> + Zahlung konnte aufgrund der Systembelastung nicht durchgeführt werden. + </notification> <notification name="CantPayNoAgent"> Nicht ersichtlich, wer bezahlt werden muss. </notification> @@ -4339,4 +4405,8 @@ Wählen Sie eine kleinere Landfläche aus. Chatverlaufsdatei ist noch mit vorheriger Operation beschäftigt. Versuchen Sie es in ein paar Minuten noch einmal oder chatten Sie mit einer anderen Person. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="OutfitPhotoLoadError"> + [REASON] + <usetemplate name="okbutton" yestext="OK"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml index d5158b2d971a108f659761840b266b1045b64b8d..365269d95e00a5abe2b0d7cd462bbecb39a1e6dd 100644 --- a/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml @@ -7,6 +7,7 @@ Ausgewählte Objekte tragen </panel.string> <tab_container name="appearance_tabs"> + <panel label="OUTFIT-GALERIE" name="outfit_gallery_tab"/> <panel label="MEINE OUTFITS" name="outfitslist_tab"/> <panel label="AKTUELLES OUTFIT" name="cof_tab"/> </tab_container> diff --git a/indra/newview/skins/default/xui/de/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/de/panel_outfits_wearing.xml index 27141796a85360963a3195f8f4450c74910e2eb2..10c31d334c4a82319ed38230913697b9e5520840 100644 --- a/indra/newview/skins/default/xui/de/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/de/panel_outfits_wearing.xml @@ -1,6 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Wearing"> + <panel.string name="no_attachments"> + Keine Anhänge getragen. + </panel.string> + <accordion name="wearables_accordion"> + <accordion_tab name="tab_wearables" title="Tragbare Objekte"/> + <accordion_tab name="tab_temp_attachments" title="Temporäre Anhänge"/> + </accordion> <panel name="bottom_panel"> - <button name="options_gear_btn" tool_tip="Zusätzliche Optionen anzeigen"/> + <menu_button name="options_gear_btn" tool_tip="Zusätzliche Optionen anzeigen"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml index fcb45e26be25cf01ef1f9cce9b9809c886bf5c76..508e87a8b70a4d86a7e13119fcfd46a3ce5c850a 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Anzeigen: </text> - <check_box label="Wenn ich L$ ausgebe oder erhalte" name="notify_money_change_checkbox"/> + <check_box label="Wenn ich L$ ausgebe" name="notify_money_spend_checkbox"/> <check_box label="Wenn meine Freunde sich an- oder abmelden" name="friends_online_notify_checkbox"/> + <check_box label="Wenn ich L$ erhalte" name="notify_money_received_checkbox"/> <text name="show_label"> Immer anzeigen: </text> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml index 06fd22141f6168a9b39c8464e762a279b03357eb..74fb4d0f858739bab3b6e0032bdea4cf61ad80e3 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> Besser </text> + <slider label="Maximale Avatarkomplexität:" name="IndirectMaxComplexity" tool_tip="Bestimmt, an welchem Punkt ein visuell komplexer Avatar als JellyDoll dargestellt wird"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Atmosphären-Shader" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="Erweitertes Beleuchtungsmodell" name="UseLightShaders"/> <button label="Einstellungen als Voreinstellung speichern..." name="PrefSaveButton"/> <button label="Voreinstellung laden..." name="PrefLoadButton"/> + min_val="0.125" <button label="Voreinstellung löschen..." name="PrefDeleteButton"/> <button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults"/> <button label="Erweiterte Einstellungen..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml index dc456e2281c88106b86cf3fee86c4900620d362e..4414bbfae7bdd30fc0336967946682f500d2fe6b 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml @@ -30,6 +30,7 @@ <combo_box.item label="Ich werde Updates manuell herunterladen und installieren" name="Install_manual"/> </combo_box> <check_box label="Bereit, Release-Kandidaten zu verwenden" name="update_willing_to_test"/> + <check_box label="Versionshinweise nach der Aktualisierung anzeigen" name="update_show_release_notes"/> <text name="Proxy Settings:"> Proxy-Einstellungen: </text> diff --git a/indra/newview/skins/default/xui/de/panel_sound_devices.xml b/indra/newview/skins/default/xui/de/panel_sound_devices.xml index b739b6197fa30b384b6041c98f6e950554e86bb7..df4b30383eb56be892215398e3022df84f2595e7 100644 --- a/indra/newview/skins/default/xui/de/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/de/panel_sound_devices.xml @@ -16,9 +16,9 @@ Ausgabe </text> <text name="My volume label"> - Meine Lautstärke: + Mikrofonlautstärke: </text> - <slider_bar initial_value="1,0" name="mic_volume_slider" tool_tip="Lautstärke mit diesem Regler ändern"/> + <slider_bar initial_value="1,0" name="mic_volume_slider" tool_tip="Mit diesem Schieberegler können Sie den Mikrofonpegel ändern"/> <text name="wait_text"> Bitte warten </text> diff --git a/indra/newview/skins/default/xui/de/panel_status_bar.xml b/indra/newview/skins/default/xui/de/panel_status_bar.xml index d3d85de3c3a6fa33577adb594bb6803494e9130e..b0cb1e0592f41f4a535681b5e2e2d9078b97f921 100644 --- a/indra/newview/skins/default/xui/de/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/de/panel_status_bar.xml @@ -5,7 +5,7 @@ <panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string> <panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string> <panel.string name="buycurrencylabel">[AMT] L$</panel.string> - <panel left="-415" name="balance_bg" width="205"> + <panel left="-436" name="balance_bg" width="205"> <text name="balance" tool_tip="Klicken, um L$-Guthaben zu aktualisieren" value="L$ ??"/> <button label="L$ kaufen" name="buyL" tool_tip="Hier klicken, um mehr L$ zu kaufen"/> <button label="Einkaufen" name="goShop" tool_tip="Second Life-Marktplatz öffnen" width="85"/> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 810022525a76875980a919f0556f829c6e138806..4a2cbcc81f84ca512c44334a71b02bbd18e01ab0 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -41,6 +41,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> + <string name="BuildConfig"> + Build-Konfiguration [BUILD_CONFIG] + </string> <string name="AboutPosition"> Sie befinden sich an [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf <nolink>[HOSTNAME]</nolink> ([HOSTIP]) SLURL: <nolink>[SLURL]</nolink> @@ -58,20 +61,40 @@ Grafikkarte: [GRAPHICS_CARD] <string name="AboutDriver"> Windows-Grafiktreiberversion: [GRAPHICS_DRIVER_VERSION] </string> - <string name="AboutLibs"> + <string name="AboutOGL"> OpenGL-Version: [OPENGL_VERSION] - -J2C-Decoderversion: [J2C_VERSION] + </string> + <string name="AboutSettings"> + Fenstergröße: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Schriftgrößenanpassung [FONT_SIZE_ADJUSTMENT] Pt +UI-Skalierung: [UI_SCALE] +Sichtweite: [DRAW_DISTANCE] m +Bandbreite: [NET_BANDWITH] kbit/s +LOD-Faktor: [LOD_FACTOR] +Darstellungsqualität: [RENDER_QUALITY] / 7 +Erweitertes Beleuchtungsmodell: [GPU_SHADERS] +Texturspeicher: [TEXTURE_MEMORY] MB +Erstellungszeit VFS (Cache): [VFS_TIME] + </string> + <string name="AboutLibs"> + J2C-Decoderversion: [J2C_VERSION] Audiotreiberversion: [AUDIO_DRIVER_VERSION] LLCEFLib/CEF-Version: [LLCEFLIB_VERSION] +LibVLC-Version: [LIBVLC_VERSION] Voice-Server-Version: [VOICE_VERSION] </string> <string name="AboutTraffic"> Paketverlust: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1] %) </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> <string name="ErrorFetchingServerReleaseNotesURL"> Fehler beim Abrufen der URL für die Server-Versionshinweise. </string> + <string name="BuildConfiguration"> + Build-Konfiguration + </string> <string name="ProgressRestoring"> Wird wiederhergestellt... </string> @@ -1083,6 +1106,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="TeleportYourAgent"> Sie teleportieren </string> + <string name="ForceSitAvatar"> + Ihren Avatar zwingen, sich zu setzen + </string> <string name="NotConnected"> Nicht verbunden </string> @@ -1390,6 +1416,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="BodyPartsRightLeg"> Rechtes Bein </string> + <string name="BodyPartsEnhancedSkeleton"> + Erweitertes Skelett + </string> <string name="GraphicsQualityLow"> Niedrig </string> @@ -1838,6 +1867,51 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="Avatar Center"> Avatar-Mitte </string> + <string name="Left Ring Finger"> + Linker Ringfinger + </string> + <string name="Right Ring Finger"> + Rechter Ringfinger + </string> + <string name="Tail Base"> + Schwanzansatz + </string> + <string name="Tail Tip"> + Schwanzspitze + </string> + <string name="Left Wing"> + Linker Flügel + </string> + <string name="Right Wing"> + Rechter Flügel + </string> + <string name="Jaw"> + Kiefer + </string> + <string name="Alt Left Ear"> + Alt. linkes Ohr + </string> + <string name="Alt Right Ear"> + Alt. rechtes Ohr + </string> + <string name="Alt Left Eye"> + Alt. linkes Auge + </string> + <string name="Alt Right Eye"> + Alt. rechtes Auge + </string> + <string name="Tongue"> + Zunge + </string> + <string name="Groin"> + Leiste + </string> + <string name="Left Hind Foot"> + Linker hinterer Fuß + </string> + <string name="Right Hind Foot"> + Rechter hinterer Fuß + </string> <string name="Invalid Attachment"> Ungültige Stelle für Anhang </string> @@ -1883,6 +1957,27 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="av_render_anyone"> Sie sind u. U. für niemanden in Ihrer Nähe sichtbar. </string> + <string name="hud_description_total"> + Ihr HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (getragen von [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] beansprucht viel Texturspeicher + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] enthält zu viele ressourcenintensive Objekte und Texturen + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] enthält viele große Texturen + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] enthält zu viele Objekte + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] enthält zu viele Texturen + </string> <string name="AgeYearsA"> [COUNT] Jahr </string> @@ -2042,6 +2137,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="ObjectOutOfRange"> Skript (Objekt außerhalb des Bereichs) </string> + <string name="ScriptWasDeleted"> + Skript (aus Inventar gelöscht) + </string> <string name="GodToolsObjectOwnedBy"> Objekt [OBJECT], Besitzer [OWNER] </string> @@ -2227,12 +2325,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="ATTACH_BELLY"> Bauch </string> - <string name="ATTACH_RPEC"> - Rechts - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Linke Brust </string> + <string name="ATTACH_RIGHT_PEC"> + Rechte Brust + </string> <string name="ATTACH_HUD_CENTER_2"> HUD Mitte 2 </string> @@ -2263,6 +2361,51 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="ATTACH_AVATAR_CENTER"> Avatar-Mitte </string> + <string name="ATTACH_LHAND_RING1"> + Linker Ringfinger + </string> + <string name="ATTACH_RHAND_RING1"> + Rechter Ringfinger + </string> + <string name="ATTACH_TAIL_BASE"> + Schwanzansatz + </string> + <string name="ATTACH_TAIL_TIP"> + Schwanzspitze + </string> + <string name="ATTACH_LWING"> + Linker Flügel + </string> + <string name="ATTACH_RWING"> + Rechter Flügel + </string> + <string name="ATTACH_FACE_JAW"> + Kiefer + </string> + <string name="ATTACH_FACE_LEAR"> + Alt. linkes Ohr + </string> + <string name="ATTACH_FACE_REAR"> + Alt. rechtes Ohr + </string> + <string name="ATTACH_FACE_LEYE"> + Alt. linkes Auge + </string> + <string name="ATTACH_FACE_REYE"> + Alt. rechtes Auge + </string> + <string name="ATTACH_FACE_TONGUE"> + Zunge + </string> + <string name="ATTACH_GROIN"> + Leiste + </string> + <string name="ATTACH_HIND_LFOOT"> + Linker hinterer Fuß + </string> + <string name="ATTACH_HIND_RFOOT"> + Rechter hinterer Fuß + </string> <string name="CursorPos"> Zeile [LINE], Spalte [COLUMN] </string> @@ -2609,6 +2752,15 @@ Gültige Formate: .wav, .tga, .bmp, .jpg, .jpeg oder .bvh <string name="Play Media"> Medien Abspielen/Pausieren </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=de-de + </string> + <string name="AMDDriverPage"> + http://support.amd.com/de/Pages/AMDSupportHub.aspx + </string> <string name="MBCmdLineError"> Beim Parsen der Befehlszeile wurde ein Fehler festgestellt. Weitere Informationen: http://wiki.secondlife.com/wiki/Client_parameters (EN) @@ -4252,6 +4404,12 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_ <string name="OfflineStatus"> Offline </string> + <string name="not_online_msg"> + Benutzer nicht online – Nachricht wird gespeichert und später zugestellt. + </string> + <string name="not_online_inventory"> + Benutzer nicht online – Inventar gespeichert. + </string> <string name="answered_call"> Ihr Anruf wurde entgegengenommen </string> @@ -4378,12 +4536,18 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_ <string name="paid_you_ldollars"> [NAME] hat Ihnen [REASON] [AMOUNT] L$ bezahlt. </string> + <string name="paid_you_ldollars_gift"> + [NAME] hat Ihnen [AMOUNT] L$ bezahlt: [REASON] + </string> <string name="paid_you_ldollars_no_reason"> [NAME] hat Ihnen [AMOUNT] L$ bezahlt. </string> <string name="you_paid_ldollars"> Sie haben [REASON] [AMOUNT] L$ an [NAME] bezahlt. </string> + <string name="you_paid_ldollars_gift"> + Sie haben [NAME] [AMOUNT] L$ bezahlt: [REASON] + </string> <string name="you_paid_ldollars_no_info"> Sie haben [AMOUNT] L$ bezahlt. </string> @@ -4396,6 +4560,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_ <string name="you_paid_failure_ldollars"> Sie haben [NAME] [AMOUNT] L$ [REASON] nicht bezahlt. </string> + <string name="you_paid_failure_ldollars_gift"> + Sie haben [NAME] [AMOUNT] L$ nicht bezahlt: [REASON] + </string> <string name="you_paid_failure_ldollars_no_info"> Sie haben [AMOUNT] L$ nicht bezahlt. </string> @@ -4722,6 +4889,15 @@ Missbrauchsbericht <string name="texture_load_dimensions_error"> Bilder, die größer sind als [WIDTH]*[HEIGHT] können nicht geladen werden </string> + <string name="outfit_photo_load_dimensions_error"> + Max. Fotogröße für Outfit ist [WIDTH]*[HEIGHT]. Bitte verkleinern Sie das Bild oder verwenden Sie ein anderes. + </string> + <string name="outfit_photo_select_dimensions_error"> + Max. Fotogröße für Outfit ist [WIDTH]*[HEIGHT]. Bitte wählen Sie eine andere Textur aus. + </string> + <string name="outfit_photo_verify_dimensions_error"> + Fotoabmessungen können nicht bestätigt werden. Bitte warten Sie, bis die Fotogröße im Auswahlfenster angezeigt wird. + </string> <string name="words_separator" value=","/> <string name="server_is_down"> Trotz all unserer Bemühungen ist ein unerwarteter Fehler aufgetreten. @@ -5226,6 +5402,9 @@ Setzen Sie den Editorpfad in Anführungszeichen <string name="Command_Profile_Label"> Profil </string> + <string name="Command_Report_Abuse_Label"> + Missbrauch melden + </string> <string name="Command_Search_Label"> Suchen </string> @@ -5316,6 +5495,9 @@ Setzen Sie den Editorpfad in Anführungszeichen <string name="Command_Profile_Tooltip"> Ihr Profil bearbeiten oder anzeigen </string> + <string name="Command_Report_Abuse_Tooltip"> + Missbrauch melden + </string> <string name="Command_Search_Tooltip"> Orte, Veranstaltungen, Leute finden </string> diff --git a/indra/newview/skins/default/xui/en/floater_avatar.xml b/indra/newview/skins/default/xui/en/floater_avatar.xml index cd5cca02bdb19023929b882956c8308713bb7f6b..92c5d8bcbe235ddb4d4eba241682f9d1324bd950 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater positioning="cascading" - ignore_ui_scale="false" legacy_header_height="225" can_minimize="true" can_close="true" diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml index 521389d7b3a18582eb9e43da4340127263af4b0f..72a7b5540c0fd7af9700dc68d56540d2e40449b4 100644 --- a/indra/newview/skins/default/xui/en/floater_camera.xml +++ b/indra/newview/skins/default/xui/en/floater_camera.xml @@ -43,13 +43,11 @@ name="controls" width="226"> <panel - color="Transparent" follows="all" height="102" layout="topleft" left="8" name="preset_views_list" - opaque="true" top="24" width="212" visible="false"> @@ -100,14 +98,11 @@ </panel_camera_item> </panel> <panel - color="Transparent" follows="all" height="68" - item_pad="4" layout="topleft" left="8" name="camera_modes_list" - opaque="true" top="24" width="212" visible="false"> diff --git a/indra/newview/skins/default/xui/en/floater_destinations.xml b/indra/newview/skins/default/xui/en/floater_destinations.xml index 94ebaa9cb2ed7026979860aef3c49eeca6a7ab55..4fe8e3bdd1a8cbcbfa85e5c74dbf983fb8c8cb2f 100644 --- a/indra/newview/skins/default/xui/en/floater_destinations.xml +++ b/indra/newview/skins/default/xui/en/floater_destinations.xml @@ -1,11 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater positioning="cascading" - ignore_ui_scale="false" legacy_header_height="225" can_minimize="true" can_close="true" - user_resize="true" can_resize="true" min_height="230" min_width="350" diff --git a/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml b/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml index 8ec6735a015ee246b15a8ddda1fecec14f7bcc32..52084e5f8ed07390d63097c4578346513c01fffb 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater positioning="cascading" - ignore_ui_scale="false" legacy_header_height="225" can_minimize="true" can_close="true" diff --git a/indra/newview/skins/default/xui/en/floater_facebook.xml b/indra/newview/skins/default/xui/en/floater_facebook.xml index 2ea34fb751e8d914d79ec2e154b37639294bc2e8..b34d70516af376f85194e33f6e92e75e67f72df9 100644 --- a/indra/newview/skins/default/xui/en/floater_facebook.xml +++ b/indra/newview/skins/default/xui/en/floater_facebook.xml @@ -22,8 +22,7 @@ top="7" height="437" follows="all" - halign="center" - use_highlighting_on_hover="true"> + halign="center"> <panel filename="panel_facebook_status.xml" class="llfacebookstatuspanel" diff --git a/indra/newview/skins/default/xui/en/floater_flickr.xml b/indra/newview/skins/default/xui/en/floater_flickr.xml index 24de3ddd8d5a1db41621948aa6b964bb71be9d1f..52ef16c7e8b51114681d1c9741f5511cbfc18294 100644 --- a/indra/newview/skins/default/xui/en/floater_flickr.xml +++ b/indra/newview/skins/default/xui/en/floater_flickr.xml @@ -29,8 +29,7 @@ top="7" height="555" follows="all" - halign="center" - use_highlighting_on_hover="true"> + halign="center"> <panel filename="panel_flickr_photo.xml" class="llflickrphotopanel" diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index 28c89868bdd6526bfe04eb892fcda5b05ef6b630..34fa0b0fe90d1eb3a5b2adcd052251988ffabd0a 100644 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -121,7 +121,6 @@ follows="all" layout="topleft" name="conversations_list_panel" - opaque="true" top_pad="0" left="5" right="-1"/> @@ -144,7 +143,6 @@ follows="all" layout="topleft" name="stub_panel" - opaque="true" top_pad="0" left="0" right="-1"> diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index d2c8dddfe10d8f5348b74c1c811178bbcc97e2be..2750316f2e74fe684d026b9ba02539805191c52b 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1217,6 +1217,13 @@ label_text.text_color="White" name="upload_joints" top_pad="15"/> + <check_box + follows="top|left" + height="15" + label="Lock scale if joint position defined" + label_text.text_color="White" + name="lock_scale_if_joint_position" + top_pad="15"/> <text follows="top|left" height="15" diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml index 5e84283ab050107b58c3b23e2007302a413e3452..90166232e97c64d4f982732d22c92519f868edc9 100644 --- a/indra/newview/skins/default/xui/en/floater_moveview.xml +++ b/indra/newview/skins/default/xui/en/floater_moveview.xml @@ -155,7 +155,6 @@ layout="topleft" name="move right btn" quadrant="right" - right_delta="4" scale_image="false" tool_tip="Walk right (press Shift + Right Arrow or D)" top_pad="10" @@ -210,7 +209,6 @@ image_pressed_selected="Movement_Down_On" image_unselected="Movement_Down_Off" layout="topleft" - right_delta="0" name="move down btn" scale_image="false" tool_tip="Fly down (press C)" diff --git a/indra/newview/skins/default/xui/en/floater_outfit_photo_preview.xml b/indra/newview/skins/default/xui/en/floater_outfit_photo_preview.xml new file mode 100644 index 0000000000000000000000000000000000000000..bfc1c39e9db0cdfcc9aef0cf6e8f1599a4ca6219 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_outfit_photo_preview.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + can_resize="false" + height="325" + layout="topleft" + name="outfit_photo_preview" + help_topic="preview_texture" + width="410"> + <floater.string + name="Title"> + Texture: [NAME] + </floater.string> + <floater.string + name="exceed_limits"> + Max outfit photo size is [MAX_WIDTH]*[MAX_HEIGHT]. Please select another texture. + </floater.string> + <floater.string + name="photo_confirmation"> + Set this as Outfit Photo for [OUTFIT]? + </floater.string> + <text + type="string" + halign="right" + length="1" + follows="right|bottom" + height="16" + layout="topleft" + left="110" + name="dimensions" + top="255" + width="200"> + [WIDTH]px x [HEIGHT]px + </text> + <text + type="string" + follows="left|top" + height="16" + layout="topleft" + name="notification" + left="25" + halign="center" + top_pad="5" + width="360"> + </text> + <button + follows="right|bottom" + height="22" + label="OK" + layout="topleft" + name="ok_btn" + top_pad="5" + right="-115" + top_delta="0" + width="90" /> + <button + follows="right|bottom" + height="22" + label="Cancel" + layout="topleft" + name="cancel_btn" + right="-20" + top_delta="0" + width="90" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml new file mode 100644 index 0000000000000000000000000000000000000000..15c480f144777e18527f117714b0debd7fc1a2e7 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + positioning="cascading" + legacy_header_height="18" + can_minimize="true" + can_resize="false" + can_close="true" + height="455" + layout="topleft" + name="outfit_snapshot" + single_instance="true" + help_topic="snapshot" + save_rect="true" + save_visibility="false" + title="OUTFIT SNAPSHOT" + width="624" + min_height="455"> + <floater.string + name="unknown"> + unknown + </floater.string> + <string + name="inventory_progress_str"> + Saving to Inventory + </string> + <string + name="inventory_succeeded_str"> + Saved to Inventory! + </string> + <string + name="inventory_failed_str"> + Failed to save to inventory. + </string> + <button + follows="left|top" + height="25" + image_overlay="Refresh_Off" + image_hover_unselected="Toolbar_Middle_Over" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + image_overlay_alignment="left" + imgoverlay_label_space="5" + pad_bottom="0" + halign="left" + layout="topleft" + left="10" + label="REFRESH" + name="new_snapshot_btn" + top_pad="26" + width="167" /> + <button + follows="left|top" + control_name="AdvanceOutfitSnapshot" + invisibility_control="AdvanceOutfitSnapshot" + height="25" + is_toggle="true" + layout="topleft" + image_hover_unselected="Toolbar_Middle_Over" + image_selected="Toolbar_Middle_Off" + image_unselected="Toolbar_Middle_Off" + image_overlay="Conv_toolbar_expand" + name="retract_btn" + left_pad="1" + top_delta="0" + width="31" /> + <button + follows="left|top" + control_name="AdvanceOutfitSnapshot" + visibility_control="AdvanceOutfitSnapshot" + height="25" + is_toggle="true" + layout="topleft" + image_overlay="Conv_toolbar_collapse" + image_hover_unselected="Toolbar_Middle_Over" + image_selected="Toolbar_Middle_Off" + image_unselected="Toolbar_Middle_Off" + name="extend_btn" + left_delta="0" + top_delta="0" + width="31" /> + <panel + height="154" + layout="topleft" + follows="top|left" + left="0" + name="advanced_options_panel" + top_pad="-6" + width="210"> + <view_border + bevel_style="in" + follows="left|top|right" + height="1" + left="10" + layout="topleft" + name="advanced_options_hr" + right="-1" + top_pad="5" + /> + <text + type="string" + length="1" + follows="left|top" + height="13" + layout="topleft" + left="10" + name="layer_type_label" + top_pad="10" + width="100"> + Capture: + </text> + <check_box + label="Interface" + layout="topleft" + left="30" + height="16" + top_pad="8" + width="180" + name="ui_check" /> + <check_box + label="HUDs" + layout="topleft" + height="16" + left="30" + top_pad="1" + width="180" + name="hud_check" /> + <check_box + label="Freeze frame (fullscreen)" + layout="topleft" + height="16" + left="10" + top_pad="1" + width="180" + name="freeze_frame_check" /> + <check_box + label="Auto-refresh" + layout="topleft" + height="16" + left="10" + top_pad="1" + width="180" + name="auto_snapshot_check" /> + <text + type="string" + length="1" + follows="left|top" + height="13" + layout="topleft" + left="10" + name="filter_list_label" + top_pad="10" + width="50"> + Filter: + </text> + <combo_box + control_name="PhotoFilters" + follows="left|right|top" + name="filters_combobox" + tool_tip="Image filters" + top_delta="-3" + left="50" + right="-1" + height="21" + width="135"> + <combo_box.item + label="No Filter" + name="NoFilter" + value="NoFilter" /> + </combo_box> + <view_border + bevel_style="in" + follows="left|top|right" + height="1" + left="10" + layout="topleft" + name="advanced_options_hr" + right="-1" + top_pad="7" + /> + </panel> + <panel + class="llpaneloutfitsnapshotinventory" + follows="left|top" + height="230" + layout="topleft" + left="0" + name="panel_outfit_snapshot_inventory" + filename="panel_outfit_snapshot_inventory.xml" + top_pad="10" + width="215" + /> + <view_border + bevel_style="in" + follows="left|top" + height="1" + left="10" + layout="topleft" + name="status_hr" + width="199" + top_pad="-16"/> + <panel + background_visible="false" + follows="left|top" + font="SansSerifLarge" + halign="center" + height="20" + layout="topleft" + left="10" + length="1" + name="succeeded_panel" + width="198" + top_pad="1" + type="string" + visible="false"> + <text + follows="all" + font="SansSerif" + halign="center" + height="18" + layout="topleft" + left="1" + length="1" + name="succeeded_lbl" + right="-1" + text_color="0.2 0.85 0.2 1" + top="4" + translate="false" + type="string"> + Succeeded + </text> + </panel> + <panel + background_visible="false" + follows="left|top" + font="SansSerifLarge" + halign="center" + height="20" + layout="topleft" + left="10" + length="1" + name="failed_panel" + width="198" + top_delta="0" + type="string" + visible="false"> + <text + follows="all" + font="SansSerif" + halign="center" + height="18" + layout="topleft" + left="1" + length="1" + name="failed_lbl" + right="-1" + text_color="0.95 0.4 0.4 1" + top="4" + translate="false" + type="string"> + Failed + </text> + </panel> + <loading_indicator + follows="left|top" + height="24" + layout="topleft" + name="working_indicator" + left="10" + top_delta="0" + visible="false" + width="24" /> + <text + follows="left|top" + font="SansSerifBold" + height="14" + layout="topleft" + left_pad="3" + length="1" + halign="left" + name="working_lbl" + top_delta="5" + translate="false" + type="string" + visible="false" + width="162"> + Working + </text> + <text + follows="left|top" + font="SansSerifBold" + halign="left" + height="18" + layout="topleft" + left="10" + length="1" + name="refresh_lbl" + text_color="0.95 0.4 0.4 1" + top_delta="0" + translate="false" + type="string" + visible="false" + width="130"> + Refresh to save. + </text> + <ui_ctrl + layout="topleft" + name="thumbnail_placeholder" + top="23" + left="215" + width="400" + height="400" + follows="top|left"/> + <view_border + bevel_style="in" + height="21" + layout="topleft" + name="img_info_border" + top_pad="0" + right="-10" + follows="left|top|right" + left_delta="0"/> + <text + type="string" + font="SansSerifSmall" + length="1" + follows="left|top|right" + height="14" + layout="topleft" + left="220" + right="-20" + halign="left" + name="image_res_text" + top_delta="5" + width="200"> + [WIDTH]px (width) x [HEIGHT]px (height) + </text> + <text + follows="right|top" + font="SansSerifSmall" + height="14" + layout="topleft" + left="-65" + length="1" + halign="right" + name="file_size_label" + top_delta="0" + type="string" + width="50"> + [SIZE] KB + </text> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml index ffbb6aa28b4af568d0d616d66b6bfaa7be4bb866..d714cc613ef444f4157a3f65b0fb3807cd3607b2 100644 --- a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml +++ b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml @@ -8,6 +8,7 @@ layout="topleft" name="outgoing call" help_topic="outgoing_call" + sound_flags="0" save_dock_state="true" title="CALLING" width="410"> diff --git a/indra/newview/skins/default/xui/en/floater_pay.xml b/indra/newview/skins/default/xui/en/floater_pay.xml index 9d91f801a6f236b4a04984052b7eb52d6739ddc4..3e3f8b49ce9072497313646e7b3acf8c3230d4c6 100644 --- a/indra/newview/skins/default/xui/en/floater_pay.xml +++ b/indra/newview/skins/default/xui/en/floater_pay.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_minimize="false" - height="186" + height="208" layout="topleft" name="Give Money" help_topic="give_money" @@ -43,6 +43,26 @@ width="180"> Test Name That Is Extremely Long To Check Clipping </text> + <text + type="string" + follows="top|left" + height="18" + left="10" + name="payment_message_label" + top_pad="6" + width="120"> + Description (optional): + </text> + <line_editor + border_style="line" + follows="left|top|right" + height="19" + top_delta="-2" + layout="topleft" + max_length_bytes="127" + name="payment_message" + right="-11" + width="109" /> <panel border_thickness="0" height="104" @@ -125,7 +145,7 @@ top_pad="0" max_length_bytes="9" name="amount" - width="90" /> + right="-1" /> <button enabled="false" height="23" diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index 638a4e2da88ceca6d7278498fce3392d5a23561a..9a9101e0da1f71e9f54012634d8a457562c4fe25 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -3,7 +3,7 @@ legacy_header_height="18" positioning="centered" default_tab_group="1" - height="460" + height="512" layout="topleft" name="Preferences" help_topic="preferences" @@ -19,7 +19,7 @@ layout="topleft" right="-105" name="OK" - top="433" + top="473" width="90"> <button.commit_callback function="Pref.OK" /> @@ -40,7 +40,7 @@ <tab_container follows="all" halign="left" - height="410" + height="440" layout="topleft" left="0" name="pref core" 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 2bd3aa8bcc165d7bd7c0583b924e6d958acad2e9..c6b91a8b2f3ade8c3d72e242d0757717f531b27c 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 @@ -117,7 +117,7 @@ <slider control_name="IndirectMaxComplexity" - tool_tip="Controls at what point a visually complex avatar is drawn as a jelly doll" + tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll" follows="left|top" height="16" initial_value="101" diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml index af62c7a9bcf4053f21e41eec7dd4605b1b55ce8f..225266af8649334b3935927b7b4a1078b90b9064 100644 --- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml @@ -21,14 +21,6 @@ name="screenshot" top="15" width="220" /> - <check_box - height="15" - label="Use this screenshot" - layout="topleft" - left="8" - name="screen_check" - top_pad="-12" - width="116" /> <text type="string" length="1" @@ -39,7 +31,7 @@ layout="topleft" left="10" name="reporter_title" - top_pad="0" + top_pad="-2" width="100"> Reporter: </text> diff --git a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml index 71ff961c59fa61b18da75514f1afd8d39680e254..b53698a9f21939e71580096955a59f6d03016e35 100644 --- a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml @@ -7,29 +7,22 @@ save_rect="true" save_visibility="true" title="SCENE LOAD STATISTICS" - width="260"> - <button follows="top|left" - top="20" - bottom="60" - left="10" - width="100" - label="Pause" - name="playpause"/> + width="400"> <scroll_container follows="top|left|bottom|right" bottom="400" layout="topleft" left="0" name="statistics_scroll" reserve_scroll_corner="true" - top="60" - width="260"> + top="20" + width="395"> <container_view follows="top|left|bottom|right" height="378" layout="topleft" left="2" name="statistics_view" top="20" - width="245" > + width="380" > <!--Basic Section--> <stat_view name="basic" label="Basic" diff --git a/indra/newview/skins/default/xui/en/floater_script_limits.xml b/indra/newview/skins/default/xui/en/floater_script_limits.xml index 6b36cdfcc5e0776cf4a200b1edfe2d8590150fdb..96b2ceec63d5114908b81d4fe33f5dca3a13e73f 100644 --- a/indra/newview/skins/default/xui/en/floater_script_limits.xml +++ b/indra/newview/skins/default/xui/en/floater_script_limits.xml @@ -8,7 +8,8 @@ name="scriptlimits" save_rect="true" title="SCRIPT INFORMATION" - width="480"> + min_width="620" + width="620"> <tab_container bottom="555" follows="left|right|top|bottom" diff --git a/indra/newview/skins/default/xui/en/floater_script_queue.xml b/indra/newview/skins/default/xui/en/floater_script_queue.xml index f4aca7bb3dd3339743154385ffc690b13e19ed9b..0982683a7f51769eb10a02c997425f99003053a5 100644 --- a/indra/newview/skins/default/xui/en/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/en/floater_script_queue.xml @@ -29,6 +29,14 @@ name="NotRunning"> Not running </floater.string> + <floater.string + name="Timeout"> + Timeout: [OBJECT_NAME] + </floater.string> + <floater.string + name="LoadingObjInv"> + Loading inventory for: [OBJECT_NAME] + </floater.string> <button follows="right|bottom" height="24" diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml index 90f9591f292f917192967b92f669830ea98f7aa1..be9b93837a45a153d465e87911b6e42045467a6c 100644 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -8,7 +8,7 @@ save_rect="true" save_visibility="true" title="STATISTICS" - width="260"> + width="270"> <scroll_container follows="all" height="380" layout="topleft" @@ -16,14 +16,14 @@ name="statistics_scroll" reserve_scroll_corner="true" top="20" - width="260"> + width="265"> <container_view follows="all" height="378" layout="topleft" - left="2" + left="0" name="statistics_view" top="20" - width="245" > + width="250" > <stat_view name="basic" label="Basic" setting="OpenDebugStatBasic"> diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml index 6021ba0a5ab8b8ebea4da81876c637009ba4fbd0..53618b684bb6e2ac4b84be6bc67207206ca06ecf 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml @@ -85,8 +85,7 @@ layout="topleft" left_delta="-12" name="unknown" - top_pad="4" - width=""> + top_pad="4"> Size: [DIMENSIONS] </text> @@ -219,7 +218,6 @@ height="260" follows="left|top|right|bottom" column_padding="0" - can_resize="false" draw_heading="true" multi_select="true" search_column="1" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 3c282338752b4bdda8b3ed41897c0fc24a442352..91e4c1b60384631b5b9f65387bdb20130b021206 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -1104,7 +1104,6 @@ even though the user gets a free copy. name="Edit Cost" label="L$" label_width="15" - label_text.valign="center" valign="center" width="85" min_val="0" diff --git a/indra/newview/skins/default/xui/en/floater_twitter.xml b/indra/newview/skins/default/xui/en/floater_twitter.xml index 3e1a91e58dddfa68cda673b00fc03fe77c3d94bf..5e8dfb8a527a151a82717f32f2188c988a0a2f56 100644 --- a/indra/newview/skins/default/xui/en/floater_twitter.xml +++ b/indra/newview/skins/default/xui/en/floater_twitter.xml @@ -20,8 +20,7 @@ tab_position="top" top="7" height="457" - halign="center" - use_highlighting_on_hover="true"> + halign="center"> <panel filename="panel_twitter_photo.xml" class="lltwitterphotopanel" diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml index a80440e844892d3cefe08f35cbed13a7bdd6efb4..4473ce0cdac4cc4bd01a1ad14c4912825606654f 100644 --- a/indra/newview/skins/default/xui/en/floater_web_content.xml +++ b/indra/newview/skins/default/xui/en/floater_web_content.xml @@ -153,6 +153,136 @@ function="WebContent.PopExternal" /> </button> </layout_panel> + <layout_panel + height="22" + layout="topleft" + left_delta="0" + name="debug_controls" + top_delta="0" + auto_resize="false" + width="585"> + <button + image_overlay="Home_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + chrome="true" + tool_tip="Web tests home page" + enabled="true" + follows="left|top" + height="22" + layout="topleft" + left="1" + name="web_test_home_page" + top="0" + width="22"> + <button.commit_callback + function="WebContent.TestURL" + parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> + </button> + + <button + image_overlay="Video_URL_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + chrome="true" + tool_tip="MPEG4 Video Test" + enabled="true" + follows="left|top" + height="22" + layout="topleft" + left="27" + name="VLC Plugin Test" + top="0" + width="22"> + <button.commit_callback + function="WebContent.TestURL" + parameter="https://callum-linden.s3.amazonaws.com/sample_media/ss.mp4"/> + </button> + <button + image_overlay="Video_URL_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + chrome="true" + tool_tip="MKV Video Test" + enabled="true" + follows="left|top" + height="22" + layout="topleft" + left="51" + name="VLC Plugin Test" + top="0" + width="22"> + <button.commit_callback + function="WebContent.TestURL" + parameter="https://callum-linden.s3.amazonaws.com/sample_media/jellyfish.mkv"/> + </button> + <button + image_overlay="Video_URL_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + chrome="true" + tool_tip="WebM Video Test" + enabled="true" + follows="left|top" + height="22" + layout="topleft" + left="75" + name="VLC Plugin Test" + top="0" + width="22"> + <button.commit_callback + function="WebContent.TestURL" + parameter="https://callum-linden.s3.amazonaws.com/sample_media/jumprope.webm"/> + </button> + <button + image_overlay="Video_URL_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + chrome="true" + tool_tip="MP3 audio Test" + enabled="true" + follows="left|top" + height="22" + layout="topleft" + left="99" + name="VLC Plugin Test" + top="0" + width="22"> + <button.commit_callback + function="WebContent.TestURL" + parameter="https://callum-linden.s3.amazonaws.com/alegria.mp3"/> + </button> + <button + image_overlay="Video_URL_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + chrome="true" + tool_tip="FLV Test" + enabled="true" + follows="left|top" + height="22" + layout="topleft" + left="123" + name="VLC Plugin Test" + top="0" + width="22"> + <button.commit_callback + function="WebContent.TestURL" + parameter="https://callum-linden.s3.amazonaws.com/sample_media/vandal.flv"/> + </button> + </layout_panel> <layout_panel height="40" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml index 5d05ecf12738f30803807e3c8aaca4bcabdefdfb..550af03683ff6cab2da8392115bfe236129c5605 100644 --- a/indra/newview/skins/default/xui/en/fonts.xml +++ b/indra/newview/skins/default/xui/en/fonts.xml @@ -10,6 +10,7 @@ <file>ArialUni.ttf</file> </os> <os name="Mac"> + <file>ヒラギノ角ゴシック W3.ttc</file> <file>ヒラã‚゙ノ角ゴ Pro W3.otf</file> <file>ヒラã‚゙ノ角ゴ ProN W3.otf</file> <file>ヒラã‚ã‚™ãƒŽæ˜Žæœ ProN W3.ttc</file> diff --git a/indra/newview/skins/default/xui/en/inspect_group.xml b/indra/newview/skins/default/xui/en/inspect_group.xml index 324ff3eabd6b7e23850502e2ec85af8a6b0299d8..a69585074ca189b505c5433f02495aaadd34d3e6 100644 --- a/indra/newview/skins/default/xui/en/inspect_group.xml +++ b/indra/newview/skins/default/xui/en/inspect_group.xml @@ -66,7 +66,7 @@ Fear the moose! Fear it! And the mongoose too! width="220"> L$123 to join </text> - <icon + <group_icon follows="all" height="38" right="-10" diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml index 9e520b2d31b22c39e03acd5bf4986f2fc6a06047..2f60bab0b7e7fa36ca63455994e8d8cf90b49d52 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml @@ -39,6 +39,22 @@ <menu_item_call.on_click function="Avatar.InviteToGroup" /> </menu_item_call> + <menu_item_separator /> + + <menu_item_call label="Reset Skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + + <menu_item_call label="Reset Skeleton And Animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> + </menu_item_call> + <menu_item_separator /> <menu_item_call enabled="false" diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index c6ae844d676dc6385f8181134975fd69f924cce0..59faf6a9f58664872e5498e75bf022dec8f550c2 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -99,6 +99,19 @@ name="Edit Outfit"> <menu_item_call.on_enable function="Edit.EnableHoverHeight" /> </menu_item_call> + <menu_item_call label="Reset Skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + <menu_item_call label="Reset Skeleton And Animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> + </menu_item_call> + <menu_item_call label="My Friends" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml index fadacbf3cb79122f42ec226343fab8bd2b8d7f68..ddfff234100b30cd41e99d8459ac4e66419ab714 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml @@ -40,6 +40,22 @@ function="Avatar.InviteToGroup" /> </menu_item_call> + <menu_item_separator /> + + <menu_item_call label="Reset Skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + + <menu_item_call label="Reset Skeleton And Animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> + </menu_item_call> + <menu_item_separator /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index d3b0b07f700f461fc7c55619de2443b61a9bcfb9..9e181d0b6d139f372285bf41b97eaea760efe32b 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -237,6 +237,18 @@ <menu_item_call.on_enable function="Edit.EnableHoverHeight" /> </menu_item_call> + <menu_item_call label="Reset Skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + <menu_item_call label="Reset Skeleton And Animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> + </menu_item_call> <menu_item_call label="My Friends" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml new file mode 100755 index 0000000000000000000000000000000000000000..1b08767edc16bc38da743d06fd17c6d58e946dcc --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml @@ -0,0 +1,255 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<context_menu + layout="topleft" + name="Outfit"> + <menu_item_call + label="Wear - Replace Current Outfit" + layout="topleft" + name="wear_replace"> + <on_click + function="Outfit.WearReplace" /> + <on_enable + function="Outfit.OnEnable" + parameter="wear_replace" /> + <on_visible + function="Outfit.OnVisible" + parameter="wear_replace" /> + </menu_item_call> + <menu_item_call + label="Wear - Add to Current Outfit" + layout="topleft" + name="wear_add"> + <on_click + function="Outfit.WearAdd" /> + <on_enable + function="Outfit.OnEnable" + parameter="wear_add" /> + <on_visible + function="Outfit.OnVisible" + parameter="wear_add" /> + </menu_item_call> + <menu_item_call + label="Take Off - Remove from Current Outfit" + layout="topleft" + name="take_off"> + <on_click + function="Outfit.TakeOff" /> + <on_enable + function="Outfit.OnEnable" + parameter="take_off" /> + <on_visible + function="Outfit.OnVisible" + parameter="take_off" /> + </menu_item_call> + <menu_item_call + label="Upload Photo (L$10)" + layout="topleft" + name="upload_photo"> + <on_click + function="Outfit.UploadPhoto" /> + </menu_item_call> + <menu_item_call + label="Select Photo" + layout="topleft" + name="select_photo"> + <on_click + function="Outfit.SelectPhoto" /> + </menu_item_call> + <menu_item_call + label="Take a Snapshot" + layout="topleft" + name="take_snapshot"> + <on_click + function="Outfit.TakeSnapshot" /> + </menu_item_call> + <menu_item_call + label="Remove Photo" + layout="topleft" + name="remove_photo"> + <on_click + function="Outfit.RemovePhoto" /> + <on_visible + function="Outfit.OnVisible" + parameter="remove_photo" /> + </menu_item_call> + <menu_item_separator name="sepatator1" /> + <menu + height="175" + label="New Clothes" + layout="topleft" + left_delta="0" + mouse_opaque="false" + name="New Clothes" + top_pad="514" + width="125"> + <menu_item_call + label="New Shirt" + layout="topleft" + name="New Shirt"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="shirt" /> + </menu_item_call> + <menu_item_call + label="New Pants" + layout="topleft" + name="New Pants"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="pants" /> + </menu_item_call> + <menu_item_call + label="New Shoes" + layout="topleft" + name="New Shoes"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="shoes" /> + </menu_item_call> + <menu_item_call + label="New Socks" + layout="topleft" + name="New Socks"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="socks" /> + </menu_item_call> + <menu_item_call + label="New Jacket" + layout="topleft" + name="New Jacket"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="jacket" /> + </menu_item_call> + <menu_item_call + label="New Skirt" + layout="topleft" + name="New Skirt"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="skirt" /> + </menu_item_call> + <menu_item_call + label="New Gloves" + layout="topleft" + name="New Gloves"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="gloves" /> + </menu_item_call> + <menu_item_call + label="New Undershirt" + layout="topleft" + name="New Undershirt"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="undershirt" /> + </menu_item_call> + <menu_item_call + label="New Underpants" + layout="topleft" + name="New Underpants"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="underpants" /> + </menu_item_call> + <menu_item_call + label="New Alpha" + layout="topleft" + name="New Alpha"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="alpha" /> + </menu_item_call> + <menu_item_call + label="New Physics" + layout="topleft" + name="New Physics"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="physics" /> + </menu_item_call> + <menu_item_call + label="New Tattoo" + layout="topleft" + name="New Tattoo"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="tattoo" /> + </menu_item_call> + </menu> + <menu + height="85" + label="New Body Parts" + layout="topleft" + left_delta="0" + mouse_opaque="false" + name="New Body Parts" + top_pad="514" + width="118"> + <menu_item_call + label="New Shape" + layout="topleft" + name="New Shape"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="shape" /> + </menu_item_call> + <menu_item_call + label="New Skin" + layout="topleft" + name="New Skin"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="skin" /> + </menu_item_call> + <menu_item_call + label="New Hair" + layout="topleft" + name="New Hair"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="hair" /> + </menu_item_call> + <menu_item_call + label="New Eyes" + layout="topleft" + name="New Eyes"> + <menu_item_call.on_click + function="Outfit.Create" + parameter="eyes" /> + </menu_item_call> + </menu> + <menu_item_separator name="sepatator2" /> + <menu_item_call + label="Edit Outfit" + layout="topleft" + name="edit"> + <on_click + function="Outfit.Edit" /> + <on_visible + function="Outfit.OnVisible" + parameter="edit" /> + </menu_item_call> + <menu_item_call + label="Rename Outfit" + layout="topleft" + name="rename"> + <on_click + function="Outfit.Rename" /> + <on_enable + function="Outfit.OnEnable" + parameter="rename" /> + </menu_item_call> + <menu_item_call + label="Delete Outfit" + layout="topleft" + name="delete"> + <on_click + function="Outfit.Delete" /> + <on_visible + function="Outfit.OnVisible" + parameter="delete" /> + </menu_item_call> +</context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 61002bf1b56c2dee33c6873f6f842040abfb4c2d..5b8a9413bf3f5e1defdba1228b08143137d51316 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -457,6 +457,14 @@ function="Inventory.DoToSelected" parameter="removefromoutfit" /> </menu_item_call> + <menu_item_call + label="Copy outfit list to clipboard" + layout="topleft" + name="Copy outfit list to clipboard"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="copyoutfittoclipboard" /> + </menu_item_call> <menu_item_separator layout="topleft" name="Outfit Separator" /> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml index 06d0b849a3e8ebc3cbc5f5a02242f70182c7a8f5..61cc9dfe77f50045b03e377f85038f265bdc2fcb 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml @@ -95,6 +95,9 @@ <on_click function="Inventory.GearDefault.Custom.Action" parameter="empty_lostnfound" /> + <on_enable + function="Inventory.GearDefault.Enable" + parameter="empty_lostnfound" /> </menu_item_call> <menu_item_separator layout="topleft" /> @@ -152,5 +155,8 @@ <on_click function="Inventory.GearDefault.Custom.Action" parameter="empty_trash" /> + <on_enable + function="Inventory.GearDefault.Enable" + parameter="empty_trash" /> </menu_item_call> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index dcf2da52f140dbbb7e60e28542cdca0134d9f35e..a39ee5fddd8d2a9f6fdd37adb2230ed472f91c29 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -225,11 +225,11 @@ parameter="message_critical" /> </menu_item_call> <menu_item_call - label="Web Content Floater Debug Test" - name="Web Content Floater Debug Test"> + label="Media Browser" + name="Media Browser"> <menu_item_call.on_click function="Advanced.WebContentTest" - parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> + parameter="http://google.com"/> </menu_item_call> <menu create_jump_keys="true" diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index 3b8ace6308697a8daea29684c4b7c5f7709c8825..7faa4f3d71f1b9aff2af82e18aa77a7bb33070a2 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -39,8 +39,35 @@ function="Gear.OnVisible" parameter="take_off" /> </menu_item_call> - - <menu_item_separator name="sepatator1" /> + <menu_item_call + label="Upload Photo (L$10)" + layout="topleft" + name="upload_photo"> + <on_click + function="Gear.UploadPhoto" /> + </menu_item_call> + <menu_item_call + label="Select Photo" + layout="topleft" + name="select_photo"> + <on_click + function="Gear.SelectPhoto" /> + </menu_item_call> + <menu_item_call + label="Take a Snapshot" + layout="topleft" + name="take_snapshot"> + <on_click + function="Gear.TakeSnapshot" /> + </menu_item_call> + <menu_item_call + label="Remove Photo" + layout="topleft" + name="remove_photo"> + <on_click + function="Gear.RemovePhoto" /> + </menu_item_call> + <menu_item_separator name="sepatator1" /> <!-- copied (with minor modifications) from menu_inventory_add.xml --> <!-- *TODO: generate dynamically? --> <menu @@ -234,4 +261,15 @@ function="Gear.OnVisible" parameter="delete" /> </menu_item_call> + <menu_item_separator name="sepatator3" /> + <menu_item_check + label="Sort Folders Always by Name" + layout="topleft" + name="sort_folders_by_name"> + <on_click + function="Gear.SortByName" /> + <on_check + function="CheckControl" + parameter="OutfitGallerySortByName" /> + </menu_item_check> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index b189d1038fa7aade97566327c68992788db68e75..f911c2da7bdea55b59762fd7e2ca8b3072115dbe 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -448,7 +448,7 @@ parameter="mini_map" /> </menu_item_check> <menu_item_check - label="Search" + label="Search..." name="Search" shortcut="control|F"> <menu_item_check.on_check @@ -885,12 +885,12 @@ </menu_item_check> <menu create_jump_keys="true" - label="Select Linked Parts" - name="Select Linked Parts" + label="Select Elements" + name="Select Elements" tear_off="true"> <menu_item_call - label="Select Next Part" - name="Select Next Part" + label="Select Next Part or Face" + name="Select Next Part or Face" shortcut="control|."> <menu_item_call.on_click function="Tools.SelectNextPart" @@ -899,8 +899,8 @@ function="Tools.EnableSelectNextPart" /> </menu_item_call> <menu_item_call - label="Select Previous Part" - name="Select Previous Part" + label="Select Previous Part or Face" + name="Select Previous Part or Face" shortcut="control|,"> <menu_item_call.on_click function="Tools.SelectNextPart" @@ -909,8 +909,8 @@ function="Tools.EnableSelectNextPart" /> </menu_item_call> <menu_item_call - label="Include Next Part" - name="Include Next Part" + label="Include Next Part or Face" + name="Include Next Part or Face" shortcut="control|shift|."> <menu_item_call.on_click function="Tools.SelectNextPart" @@ -919,8 +919,8 @@ function="Tools.EnableSelectNextPart" /> </menu_item_call> <menu_item_call - label="Include Previous Part" - name="Include Previous Part" + label="Include Previous Part or Face" + name="Include Previous Part or Face" shortcut="control|shift|,"> <menu_item_call.on_click function="Tools.SelectNextPart" @@ -3141,30 +3141,13 @@ label="UI" name="UI" tear_off="true"> - <!-- <menu_item_check - label="New Bottom Bar" - name="New Bottom Bar"> - <menu_item_check.on_check - function="CheckControl" - parameter="BottomPanelNew" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="BottomPanelNew" /> - </menu_item_check>--> - <menu_item_call - label="Media Browser Test" - name="Web Browser Test"> - <menu_item_call.on_click - function="Advanced.WebBrowserTest" - parameter="http://secondlife.com/app/search/slurls.html"/> - </menu_item_call> <menu_item_call - label="Web Content Browser" - name="Web Content Browser" - shortcut="control|shift|Z"> + label="Media Browser" + name="Media Browser" + shortcut="control|alt|shift|Z"> <menu_item_call.on_click function="Advanced.WebContentTest" - parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> + parameter="http://google.com"/> </menu_item_call> <menu_item_call label="FB Connect Test" @@ -3527,6 +3510,16 @@ function="Advanced.ToggleInfoDisplay" parameter="collision skeleton" /> </menu_item_check> + <menu_item_check + label="Show Bones" + name="Show Bones"> + <menu_item_check.on_check + function="Advanced.CheckInfoDisplay" + parameter="joints" /> + <menu_item_check.on_click + function="Advanced.ToggleInfoDisplay" + parameter="joints" /> + </menu_item_check> <menu_item_check label="Display Agent Target" name="Display Agent Target"> diff --git a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml index 44b2727671c609f2dee6b5eb40dd9c62493a6b1a..75c1de24aa229a2f68c2698b3cdbc22c7d632e29 100644 --- a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml @@ -27,6 +27,13 @@ <on_click function="Wearing.Edit" /> </menu_item_call> + <menu_item_call + label="Edit" + layout="topleft" + name="edit_item"> + <on_click + function="Wearing.EditItem" /> + </menu_item_call> <menu_item_call label="Show Original" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/mime_types.xml b/indra/newview/skins/default/xui/en/mime_types.xml index 7cb4a6e53b17d6f23f8e00eb0fe1e555eb41d2ef..8d8d546b249b2c0c4ae2c3513f9aafa91356b688 100644 --- a/indra/newview/skins/default/xui/en/mime_types.xml +++ b/indra/newview/skins/default/xui/en/mime_types.xml @@ -130,10 +130,21 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </scheme> - <mimetype name="blank"> + <scheme name="libvlc"> + <label name="libvlc_label"> + LibVLC supported media + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_libvlc + </impl> + </scheme> + <mimetype name="blank"> <label name="blank_label"> - None - </label> @@ -163,7 +174,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/*"> @@ -174,7 +185,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="image/*"> @@ -196,7 +207,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="application/javascript"> @@ -218,7 +229,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_cef </impl> </mimetype> <mimetype name="application/pdf"> @@ -295,7 +306,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_cef </impl> </mimetype> <mimetype name="audio/mpeg"> @@ -306,7 +317,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="audio/x-aiff"> @@ -317,7 +328,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="audio/x-wav"> @@ -328,7 +339,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype menu="1" name="image/bmp"> @@ -438,7 +449,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/mp4"> @@ -449,10 +460,21 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> - <mimetype menu="1" name="video/quicktime"> + <mimetype name="application/octet-stream"> + <label name="video/octet-stream"> + Movie + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_libvlc + </impl> + </mimetype> + <mimetype menu="1" name="video/quicktime"> <label name="video/quicktime_label"> Movie (QuickTime) </label> @@ -460,7 +482,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/x-ms-asf"> @@ -471,7 +493,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/x-ms-wmv"> @@ -482,7 +504,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="video/x-msvideo"> @@ -493,7 +515,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_cef </impl> </mimetype> </mimetypes> diff --git a/indra/newview/skins/default/xui/en/mime_types_linux.xml b/indra/newview/skins/default/xui/en/mime_types_linux.xml index 84aeaf3b54b1a858c9ecfa652899fff85f4cf2f0..7188b1e69937899213ce1bf737d156e017981b20 100644 --- a/indra/newview/skins/default/xui/en/mime_types_linux.xml +++ b/indra/newview/skins/default/xui/en/mime_types_linux.xml @@ -130,7 +130,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </scheme> <mimetype name="blank"> @@ -163,7 +163,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/*"> @@ -174,7 +174,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype name="image/*"> @@ -196,7 +196,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype name="application/javascript"> @@ -218,7 +218,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype name="application/pdf"> @@ -295,7 +295,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype name="audio/mpeg"> @@ -306,7 +306,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype name="audio/x-aiff"> @@ -317,7 +317,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype name="audio/x-wav"> @@ -328,7 +328,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype menu="1" name="image/bmp"> @@ -438,7 +438,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/mp4"> @@ -449,7 +449,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype menu="1" name="video/quicktime"> @@ -460,7 +460,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/x-ms-asf"> @@ -471,7 +471,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/x-ms-wmv"> @@ -482,7 +482,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> <mimetype menu="1" name="video/x-msvideo"> @@ -493,7 +493,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_libvlc </impl> </mimetype> </mimetypes> diff --git a/indra/newview/skins/default/xui/en/mime_types_mac.xml b/indra/newview/skins/default/xui/en/mime_types_mac.xml index f71c24b2e4312f5a297ec8474c969bad59acf034..2d96708b86a220d32805b318aa65781678d20c32 100644 --- a/indra/newview/skins/default/xui/en/mime_types_mac.xml +++ b/indra/newview/skins/default/xui/en/mime_types_mac.xml @@ -130,7 +130,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </scheme> <mimetype name="blank"> @@ -141,7 +141,7 @@ none </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="none/none"> @@ -163,7 +163,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/*"> @@ -174,7 +174,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="image/*"> @@ -196,7 +196,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="application/javascript"> @@ -218,7 +218,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="application/pdf"> @@ -295,7 +295,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="audio/mpeg"> @@ -306,7 +306,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="audio/x-aiff"> @@ -317,7 +317,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="audio/x-wav"> @@ -328,7 +328,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype menu="1" name="image/bmp"> @@ -438,7 +438,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/mp4"> @@ -449,7 +449,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype menu="1" name="video/quicktime"> @@ -460,7 +460,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/x-ms-asf"> @@ -471,7 +471,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype name="video/x-ms-wmv"> @@ -482,7 +482,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> <mimetype menu="1" name="video/x-msvideo"> @@ -493,7 +493,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_libvlc </impl> </mimetype> </mimetypes> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index dfde38bc5f2b4b9727c55f6b2fd14ac2bcc78fc0..512deed054cf1f8edf852c53a61f90c0fe5a8db3 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -831,6 +831,13 @@ If you no longer wish to have these abilities granted to this role, disable them yestext="Ban"/> </notification> + <notification + icon="notify.tga" + name="GroupBanUserOnBanlist" + type="notify"> +Some residents have not been sent an invite due to being banned from the group. + </notification> + <notification icon="alertmodal.tga" name="AttachmentDrop" @@ -1430,6 +1437,13 @@ Note: This will clear the cache. Port settings take effect after you restart [APP_NAME]. </notification> + <notification + icon="alertmodal.tga" + name="ChangeDeferredDebugSetting" + type="alertmodal"> +This debug setting change will take effect after you restart [APP_NAME]. + </notification> + <notification icon="alertmodal.tga" name="ChangeSkin" @@ -1476,6 +1490,7 @@ Save Changes? icon="alertmodal.tga" name="DeleteNotecard" type="alertmodal"> + <unique/> Delete Notecard? <tag>confirm</tag> <usetemplate @@ -1483,7 +1498,20 @@ Delete Notecard? notext="Cancel" yestext="OK"/> </notification> - + + <notification + icon="alertmodal.tga" + name="LoadPreviousReportScreenshot" + type="alertmodal"> + <unique/> +Do you want to use previous screenshot for your report? + <tag>confirm</tag> + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="OK"/> + </notification> + <notification icon="alertmodal.tga" name="GestureSaveFailedTooManySteps" @@ -1631,52 +1659,14 @@ Visit [_URL] for more information? <notification icon="alertmodal.tga" - name="IntelOldDriver" + name="OldGPUDriver" type="alertmodal"> There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. - Visit [_URL] to check for driver updates? - <tag>confirm</tag> - <url option="0" name="url"> - http://www.intel.com/p/en_US/support/detect/graphics - </url> - <usetemplate - ignoretext="My graphics driver is out of date" - name="okcancelignore" - notext="No" - yestext="Yes"/> - <tag>fail</tag> - </notification> - - <notification - icon="alertmodal.tga" - name="AMDOldDriver" - type="alertmodal"> - There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. - - Visit [_URL] to check for driver updates? - <tag>confirm</tag> - <url option="0" name="url"> - http://support.amd.com/us/Pages/AMDSupportHub.aspx - </url> - <usetemplate - ignoretext="My graphics driver is out of date" - name="okcancelignore" - notext="No" - yestext="Yes"/> - <tag>fail</tag> - </notification> - - <notification - icon="alertmodal.tga" - name="NVIDIAOldDriver" - type="alertmodal"> - There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. - - Visit [_URL] to check for driver updates? + Visit [URL] to check for driver updates? <tag>confirm</tag> <url option="0" name="url"> - http://www.nvidia.com/Download/index.aspx?lang=en-us + [URL] </url> <usetemplate ignoretext="My graphics driver is out of date" @@ -1686,7 +1676,6 @@ Visit [_URL] for more information? <tag>fail</tag> </notification> - <notification icon="alertmodal.tga" name="UnknownGPU" @@ -1904,7 +1893,16 @@ Go to [_URL] for information on purchasing L$? notext="Cancel" yestext="OK"/> </notification> - + + <notification + icon="alertmodal.tga" + name="MuteLimitReached" + persist="false" + type="notify"> +Unable to add new entry to block list because you reached the limit of [MUTE_LIMIT] entries. + <tag>fail</tag> + </notification> + <notification icon="alertmodal.tga" name="UnableToLinkObjects" @@ -3349,6 +3347,23 @@ Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Renderin <context>AgentComplexityNotice</context> </unique> Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] is [AGENT_COMPLEXITY]. + <usetemplate + ignoretext="Warn me about my avatar complexity changes" + name="notifyignore"/> + </notification> + + <notification + icon = "notifytip.tga" + name = "HUDComplexityWarning" + type = "notifytip" + log_to_chat = "false"> + <unique combine = "cancel_old"> + <context>HUDComplexityWarning</context> + </unique> + [HUD_REASON], it is likely to negatively affect your performance. + <usetemplate + ignoretext="Warn me when my HUD complexity is too high" + name="notifyignore"/> </notification> <notification @@ -3663,6 +3678,13 @@ You can only have [MAX_MANAGER] Estate Managers. Can't add estate owner to estate 'Banned Resident' list. </notification> + <notification + icon="alertmodal.tga" + name="ProblemAddingEstateManagerBanned" + type="alertmodal"> +Unable to add banned resident to estate manager list. + </notification> + <notification icon="alertmodal.tga" name="CanNotChangeAppearanceUntilLoaded" @@ -4057,6 +4079,18 @@ Do you want to open your Web browser to view this content? yestext="OK"/> </notification> + <notification + icon="alertmodal.tga" + name="SystemUIScaleFactorChanged" + type="alertmodal"> +System UI size factor has changed since last run. Do you want to open UI size adjustment settings page? + <tag>confirm</tag> + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="OK"/> + </notification> + <notification icon="alertmodal.tga" name="WebLaunchJoinNow" @@ -4177,6 +4211,14 @@ Leave Group? yestext="OK"/> </notification> + <notification + icon="notify.tga" + name="GroupDepart" + type="notify"> +You have left the group '[group_name]'. + <tag>group</tag> + </notification> + <notification icon="alertmodal.tga" name="OwnerCannotLeaveGroup" @@ -4188,6 +4230,17 @@ Leave Group? yestext="OK"/> </notification> + <notification + icon="alertmodal.tga" + name="GroupDepartError" + type="alertmodal"> + Unable to leave group. + <tag>group</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification icon="alert.tga" name="ConfirmKick" @@ -5303,6 +5356,17 @@ You won't receive any more notifications that you're about to visit a region wit name="TooManyPrimsSelected" type="alertmodal"> There are too many prims selected. Please select [MAX_PRIM_COUNT] or fewer prims and try again + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="TooManyScriptsSelected" + type="alertmodal"> +Too many scripts in the objects selected. Please select fewer objects and try again <tag>fail</tag> <usetemplate name="okbutton" @@ -5726,6 +5790,17 @@ Warning: The 'Pay object' click action has been set, but it will only yestext="OK"/> </notification> + <notification + icon="alertmodal.tga" + name="PaymentBlockedButtonMismatch" + type="alertmodal"> + Payment stopped: the price paid does not match any of the pay buttons set for this object. + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification icon="alertmodal.tga" name="OpenObjectCannotCopy" @@ -5830,7 +5905,20 @@ You cannot undo this action. notext="Cancel" yestext="Unlink"/> </notification> - + + <notification + icon="alertmodal.tga" + name="HelpReportAbuseConfirm" + type="alertmodal"> + <unique/> +Thank you for taking the time to inform us of this issue. +We will review your report for possible violations and take +the appropriate action. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification icon="alertmodal.tga" name="HelpReportAbuseSelectCategory" @@ -6083,6 +6171,7 @@ Link to this from a web page to give others easy access to this location, or try icon="alertmodal.tga" name="WLSavePresetAlert" type="alertmodal"> + <unique/> Do you wish to overwrite the saved preset? <tag>confirm</tag> <usetemplate @@ -7339,7 +7428,8 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th name="TeleportOffered_MaturityExceeded" log_to_im="true" log_to_chat="false" - type="offer"> + type="offer" + sound="UISndNewIncomingIMSession"> [NAME_SLURL] has offered to teleport you to their location: “[MESSAGE]†@@ -7364,7 +7454,8 @@ This region contains [REGION_CONTENT_MATURITY] content, but your current prefere name="TeleportOffered_MaturityBlocked" log_to_im="true" log_to_chat="false" - type="notifytip"> + type="notifytip" + sound="UISndNewIncomingIMSession"> [NAME_SLURL] has offered to teleport you to their location: “[MESSAGE]†@@ -8803,23 +8894,6 @@ Click and drag anywhere on the world to rotate your view SL will quit in 30 seconds due to out of memory. </notification> - <notification - name="PopupAttempt" - icon="Popup_Caution" - type="browser"> - A pop-up was prevented from opening. - <form name="form"> - <ignore name="ignore" - control="MediaEnablePopups" - invert_control="true" - text="Enable all pop-ups"/> - <button default="true" - index="0" - name="open" - text="Open pop-up window"/> - </form> - </notification> - <notification icon="alertmodal.tga" name="SOCKS_NOT_PERMITTED" @@ -9800,6 +9874,14 @@ Can't move object '[OBJECT_NAME]' to [OBJ_POSITION] in region [REGION_NAME] because there are not enough resources for this object on this parcel. </notification> + <notification + icon="alertmodal.tga" + name="NoParcelPermsNoObject" + type="notify"> + <tag>fail</tag> +Copy failed because you lack access to that parcel. + </notification> + <notification icon="alertmodal.tga" name="CantMoveObjectRegionVersion" @@ -9835,6 +9917,17 @@ Can't move object '[OBJECT_NAME]' to You don't have permission to modify that object </notification> + <notification + icon="alertmodal.tga" + name="TooMuchObjectInventorySelected" + type="alertmodal"> + <tag>fail</tag> + Too many objects with large inventory are selected. Please select fewer objects and try again. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification icon="alertmodal.tga" name="CantEnablePhysObjContributesToNav" @@ -9932,6 +10025,22 @@ Cannot save to object contents: Item with that name already exists in inventory Cannot save to object contents: This would modify the attachment permissions. </notification> + <notification + icon="alertmodal.tga" + name="AttachmentHasTooMuchInventory" + type="notify"> + <tag>fail</tag> +Your attachments contain too much inventory to add more. + </notification> + + <notification + icon="alertmodal.tga" + name="IllegalAttachment" + type="notify"> + <tag>fail</tag> +The attachment has requested a nonexistent point on the avatar. It has been attached to the chest instead. + </notification> + <notification icon="alertmodal.tga" name="TooManyScripts" @@ -10181,6 +10290,22 @@ You have been teleported by the object '[OBJECT_NAME]' owned by [OWNER_ID] You have been teleported by the object '[OBJECT_NAME]' owned by an unknown user. </notification> + <notification + icon="alertmodal.tga" + name="StandDeniedByObject" + type="notify"> + <tag>fail</tag> +'[OBJECT_NAME]' will not allow you to stand at this time. + </notification> + + <notification + icon="alertmodal.tga" + name="ResitDeniedByObject" + type="notify"> + <tag>fail</tag> +'[OBJECT_NAME]' will not allow you to change your seat at this time. + </notification> + <notification icon="alertmodal.tga" name="CantCreateObjectRegionFull" @@ -10405,6 +10530,14 @@ Not enough script resources available to attach object! Cannot attach object because it is already being removed. </notification> + <notification + icon="alertmodal.tga" + name="IllegalAttachment" + type="notify"> + <tag>fail</tag> + The attachment has requested a nonexistent point on the avatar. It has been attached to the chest instead. + </notification> + <notification icon="alertmodal.tga" name="CantDropItemTrialUser" @@ -10970,6 +11103,14 @@ Unable to find object. Money transfers to objects are currently disabled in this region. </notification> + <notification + icon="alertmodal.tga" + name="DroppedMoneyTransferRequest" + type="notify"> + <tag>fail</tag> +Unable to make payment due to system load. + </notification> + <notification icon="alertmodal.tga" name="CantPayNoAgent" @@ -11068,4 +11209,16 @@ Cannot create large prims that intersect other players. Please re-try when othe yestext="OK"/> </notification> + + <notification + icon="alert.tga" + name="OutfitPhotoLoadError" + type="alertmodal"> + [REASON] + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + </notifications> diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index ae8e78a9d688518ee52dcf132d372102683f4645..3a34bcbe21c5e8dc749fcf9b78faafc9ecf8aa99 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -15,7 +15,6 @@ <layout_stack follows="left|right|top" height="172" - min_height="172" left="0" name="ui_stack" orientation="horizontal" @@ -50,7 +49,7 @@ label="Username" combo_editor.font="SansSerifLarge" max_chars="128" - commit_on_focus_lost="false" + combo_editor.commit_on_focus_lost="false" combo_editor.prevalidate_callback="ascii" tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" name="username_combo" @@ -67,7 +66,7 @@ follows="left|top" height="32" left_pad="-11" - max_length_bytes="64" + max_length_chars="16" text_pad_left="8" name="password_edit" label="Password" @@ -107,7 +106,7 @@ follows="left|top" image_unselected="PushButton_Login" image_pressed="PushButton_Login_Pressed" - image_hover="PushButton_Login_Over" + image_hover_unselected="PushButton_Login_Over" label="Log In" label_color="White" font="SansSerifMedium" diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml index dc6e27a1ee580acaba87074f5bc056d914112629..35b80c56abe7cc0f2837fa2905b1065e0d6699fa 100644 --- a/indra/newview/skins/default/xui/en/panel_login_first.xml +++ b/indra/newview/skins/default/xui/en/panel_login_first.xml @@ -124,7 +124,7 @@ width="200" height="32" left="220" - max_length_bytes="64" + max_length_chars="16" name="password_edit" label="Password" text_pad_left="8" diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml index 94c468e1bb0d06e189cc7d6cfeeee4ae94a13f8d..4d9316768b05d0614b1c1be197f3bb7612e7f16d 100644 --- a/indra/newview/skins/default/xui/en/panel_notification.xml +++ b/indra/newview/skins/default/xui/en/panel_notification.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel background_opaque="false" - border_visible="false" + border_visible="false" background_visible="true" bg_alpha_color="PanelNotificationBackground" bg_opaque_color="PanelNotificationBackground" @@ -10,18 +10,17 @@ left="0" name="notification_panel" chrome="true" - show_title="false" top="0" - height="140" + height="140" translate="false" width="305"> <!-- THIS PANEL CONTROLS TOAST HEIGHT? --> <panel - border_visible="false" - bevel_style="none" + border_visible="false" + bevel_style="none" background_visible="true" - bg_alpha_color="ToastBackground" - bg_opaque_color="ToastBackground" + bg_alpha_color="ToastBackground" + bg_opaque_color="ToastBackground" follows="left|right|top" height="100" label="info_panel" diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml new file mode 100644 index 0000000000000000000000000000000000000000..e3790ae09b26679fa8b1c510e7dabf658a90d4f2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_visible="true" + bg_alpha_color="DkGray" + border="false" + follows="all" + height="430" + name="Outfit Gallery" + layout="topleft" + left="0" + top="0" + width="318"> + <string name="outfit_photo_string"> + Photo of "[OUTFIT_NAME]" outfit + </string> + <string name="no_outfits_msg"> + You don't have any outfits yet. Try [secondlife:///app/search/all/ Search] + </string> + <string name="no_matched_outfits_msg"> + Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search]. + </string> + <text + type="string" + clip_partial="false" + follows="left|top" + layout="topleft" + left="13" + name="no_outfits_txt" + top="0" + height="32" + valign="center" + parse_urls="true" + wrap="true"> + Searching... + </text> + <scroll_container + follows="all" + height="400" + width="312" + layout="topleft" + left="4" + top="0" + name="gallery_scroll_panel" + opaque="false" + top_pad="0"> + <!--outfit_gallery_item + layout="topleft" + left="10" + name="preview_outfit1" + height="175" + width="150" + follows="left|top"/--> + <!--layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="0" name="top_gallery_stack" orientation="horizontal"> + <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel"> + <outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/> + </layout_panel> + <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel"> + <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/> + </layout_panel> + <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel"> + <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/> + </layout_panel> + </layout_stack> + <layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="190" name="top_gallery_stack" orientation="horizontal"> + <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel"> + <outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/> + </layout_panel> + <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel"> + <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/> + </layout_panel> + <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel"> + <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/> + </layout_panel> + </layout_stack> + <layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="380" name="top_gallery_stack" orientation="horizontal"> + <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel"> + <outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/> + </layout_panel> + <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel"> + <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/> + </layout_panel> + <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel"> + <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/> + </layout_panel> + </layout_stack--> + <!--</panel>--> + </scroll_container> + <panel + background_visible="true" + follows="bottom|left|right" + height="28" + layout="topleft" + left="4" + top_pad="0" + visible="true" + name="bottom_panel" + width="312"> + <menu_button + follows="bottom|left" + tool_tip="Show additional options" + height="25" + image_hover_unselected="Toolbar_Left_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Left_Selected" + image_unselected="Toolbar_Left_Off" + layout="topleft" + left="0" + name="options_gear_btn" + top="1" + width="31" /> + <icon + follows="bottom|left|right" + height="25" + image_name="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="dummy_icon" + width="243"/> + <button + follows="bottom|right" + height="25" + image_hover_unselected="Toolbar_Right_Over" + image_overlay="TrashItem_Off" + image_selected="Toolbar_Right_Selected" + image_unselected="Toolbar_Right_Off" + layout="topleft" + left_pad="1" + name="trash_btn" + tool_tip="Delete selected outfit" + width="31"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml new file mode 100644 index 0000000000000000000000000000000000000000..e3f0f1128b6a57c70ea42d28985f6cc91cf1c1ae --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_visible="false" + background_opaque="false" + bg_alpha_color="FrogGreen" + bg_opaque_color="FrogGreen" + border="false" + bevel_style="none" + follows="left|top" + height="169" + width="150" + name="gallery_item_panel" + layout="topleft" + left="0" + top="0" + > + <string name="worn_string"> + (worn) + </string> + <icon + left="1" + top="0" + layout="topleft" + name="preview_outfit" + height="149" + width="147" + follows="left|top" + visible="true" + image_name="Default_Outfit_Photo" + /> + <panel + background_visible="false" + background_opaque="true" + bg_opaque_color="OutfitGalleryItemSelected" + border="false" + bevel_style="none" + follows="left|top" + left="0" + top="149" + height="25" + width="148" + name="text_bg_panel" + > + <text + read_only="true" + length="1" + follows="left|top" + left="1" + height="10" + layout="topleft" + name="outfit_name" + top="2" + width="150" + use_ellipses="true"> + Summer hipster, Pierce Pierce Pierce Pierce + </text> + <text + read_only="true" + length="1" + follows="left|top" + left="1" + height="10" + layout="topleft" + name="outfit_worn_text" + top="12" + width="150"> + (worn) + </text> + </panel> + +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml new file mode 100644 index 0000000000000000000000000000000000000000..800faabc2abe701a954e1ffe423c0175251f01f5 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="380" + layout="topleft" + name="panel_outfit_snapshot_inventory" + width="490"> + <icon + follows="top|left" + height="18" + image_name="Snapshot_Inventory" + layout="topleft" + left="12" + mouse_opaque="true" + name="title_icon" + top="6" + width="18" /> + <text + follows="top|left|right" + font="SansSerifBold" + height="14" + layout="topleft" + left_pad="12" + length="1" + name="title" + right="-10" + text_color="white" + type="string" + top_delta="3"> + Inventory + </text> + <view_border + bevel_style="in" + follows="left|top|right" + height="1" + left="9" + layout="topleft" + name="hr" + right="-5" + top_pad="5" + /> + <text + follows="top|left" + font="SansSerif" + height="56" + layout="topleft" + left="10" + length="1" + name="hint_lbl" + top_pad="6" + width="200" + type="string" + word_wrap="true"> + Uploading an image to your inventory costs L$[UPLOAD_COST]. + </text> + <button + follows="right|bottom" + height="23" + label="Cancel" + layout="topleft" + name="cancel_btn" + right="-5" + top="337" + width="97"> + <button.commit_callback + function="Inventory.SaveOutfitCancel" /> + </button> + <button + follows="left|bottom" + height="23" + label="UPLOAD L$10" + layout="topleft" + left="10" + name="save_btn" + top_delta="0" + width="97"> + <button.commit_callback + function="Inventory.SaveOutfitPhoto" /> + </button> +</panel> \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index 405d9513db34520224b387d8936bb1f2e2f63443..ff0714adbbc64d355e282612bc5831c97f3f0d04 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -32,6 +32,17 @@ halign="center" top="8" width="315"> + <panel + class="outfit_gallery" + filename="panel_outfit_gallery.xml" + height="520" + name="outfit_gallery_tab" + background_visible="true" + help_topic="outfit_gallery_tab" + follows="all" + label="OUTFIT GALLERY" + layout="topleft" + width="315" /> <panel class="outfits_list" filename="panel_outfits_list.xml" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml index d85b778db2174ab3f0a7a8cdd59e4c1203998355..42a79743169aba8c1364624ea0ea42173ba4ee7c 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml @@ -9,6 +9,26 @@ name="Wearing" top="0" width="312"> +<panel.string + name="no_attachments"> + No attachments worn. + </panel.string> + <accordion + fit_parent="true" + follows="all" + height="400" + layout="topleft" + left="0" + single_expansion="true" + top="0" + name="wearables_accordion" + background_visible="true" + bg_alpha_color="DkGray2" + width="309"> + <accordion_tab + layout="topleft" + name="tab_wearables" + title="Wearables"> <wearable_items_list follows="all" height="400" @@ -20,6 +40,27 @@ top="0" width="309" worn_indication_enabled="false" /> + </accordion_tab> + <accordion_tab + layout="topleft" + name="tab_temp_attachments" + title="Temporary attachments"> + <scroll_list + draw_heading="false" + left="3" + width="309" + height="400" + follows="all" + name="temp_attachments_list"> + <scroll_list.columns + name="icon" + width="15" /> + <scroll_list.columns + name="text" + width="210" /> + </scroll_list> + </accordion_tab> + </accordion> <panel background_visible="true" follows="bottom|left|right" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index 4a5117adacf766635e572422a73f4f594d53ca98..0cd56af6d7e437d259d1d391ec4b95a762f7e8f1 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -138,7 +138,7 @@ initial_value="1" layout="topleft" left_pad="0" - max_val="2.0" + max_val="4.0" min_val="0.75" name="ui_scale_slider" top_pad="-14" @@ -157,7 +157,6 @@ enabled_control="ShowScriptErrors" control_name="ShowScriptErrorsLocation" follows="top|left" - draw_border="false" height="16" layout="topleft" left_delta="50" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index a9b8e197bc4c6780f0541ad404b3ee611c6abf06..32cbbff8b772cb5280241dff48ce6be9888c3a2c 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -2,7 +2,7 @@ <panel border="true" follows="left|top|right|bottom" - height="418" + height="438" label="Graphics" layout="topleft" left="102" @@ -233,7 +233,7 @@ <slider control_name="IndirectMaxComplexity" - tool_tip="Controls at what point a visually complex avatar is drawn as a jelly doll" + tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll" follows="left|top" height="16" initial_value="101" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 323da2be38be875d17dc5f9634754ca5f01ddf3d..284688d4d15b4026bcb2ff9ca62e82acbdb3d681 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -16,7 +16,7 @@ </panel.string> <button - follows="left|bottom" + follows="left|top" height="23" label="Clear History" tool_tip="Clear login image, last location, teleport history, web, and texture cache" @@ -75,7 +75,7 @@ top_pad="10" width="350" /> <button - follows="left|bottom" + follows="left|top" height="23" label="Block list" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index 0b605cf6f7e33a6238b7e1422c500a337d110d95..71e4009571bf1857756b7fc159cbc7d1aabdb2ab 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -140,7 +140,6 @@ <radio_group control_name="PreferredBrowserBehavior" - draw_border="false" follows="left|top" height="60" layout="topleft" @@ -273,6 +272,18 @@ name="update_willing_to_test" width="400" top_pad="5"/> + <check_box + top_delta="4" + enabled="true" + follows="left|top" + height="14" + control_name="UpdaterShowReleaseNotes" + label="Show Release Notes after update" + left_delta="0" + mouse_opaque="true" + name="update_show_release_notes" + width="400" + top_pad="5"/> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index 615abbaa895c6bbfe42f17451ac966a67feeeeb3..8f2e81b9f7481538d2a1f607925ec85ad2971eea 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -2,7 +2,7 @@ <panel border="true" follows="all" - height="408" + height="438" label="Sounds" layout="topleft" left="102" @@ -394,7 +394,6 @@ <radio_group enabled_control="EnableVoiceChat" control_name="VoiceEarLocation" - draw_border="false" follows="left|top" layout="topleft" left_delta="-168" diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml index eb67d076016e279c0774ce3def8d3e26744d0b76..068e4420bc02296149b93cad7a02f54a121fe272 100644 --- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml @@ -374,9 +374,11 @@ layout="topleft" tool_tip="Movie play progress" width="200"> - <slider_bar.commit_callback - function="MediaCtrl.JumpProgress" /> - </slider_bar> + <slider_bar.mouse_down_callback + function="MediaCtrl.MouseDown" /> + <slider_bar.mouse_up_callback + function="MediaCtrl.MouseUp" /> + </slider_bar> </layout_panel> <layout_panel name="skip_back" diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml index 489d286e67fb69e190e8be84259e8f711910028d..898e92e0305421adbd11f201d2003751899e966f 100644 --- a/indra/newview/skins/default/xui/en/panel_region_general.xml +++ b/indra/newview/skins/default/xui/en/panel_region_general.xml @@ -51,7 +51,7 @@ left_delta="50" name="version_channel_text" top_delta="0" - width="200"> + width="225"> unknown </text> <text @@ -73,7 +73,7 @@ left_delta="50" name="region_type" top_delta="0" - width="200"> + width="225"> unknown </text> <check_box diff --git a/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml index 629d8567d10d5bfa2810979bb42933b48002eb66..2c2803a503cd7bd20f2a306b0815f96ef248762a 100644 --- a/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml +++ b/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml @@ -8,7 +8,7 @@ left="0" name="script_limits_my_avatar_panel" top="0" - width="480"> + width="620"> <text type="string" length="1" @@ -19,7 +19,7 @@ name="script_memory" top_pad="24" text_color="White" - width="480"> + width="620"> Avatar Script Usage </text> <text @@ -31,7 +31,7 @@ left="30" name="memory_used" top_delta="18" - width="480"> + width="620"> </text> <text @@ -43,7 +43,7 @@ left="30" name="urls_used" top_delta="18" - width="480"> + width="620"> </text> <text @@ -56,7 +56,7 @@ name="loading_text" top="80" text_color="EmphasisColor" - width="480"> + width="620"> Loading... </text> <scroll_list @@ -68,7 +68,7 @@ multi_select="true" name="scripts_list" top="100" - width="460"> + width="600"> <scroll_list.columns label="Size (kb)" name="size" diff --git a/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml index c5e8bf5803dc57358e56a4599ef39908d5a7c8b2..79bb781bc6ff77bb73c3afb5a8cb2bb6e958967f 100644 --- a/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml +++ b/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml @@ -8,7 +8,7 @@ name="script_limits_region_memory_panel" top="0" left="0" - width="480"> + width="620"> <text type="string" length="1" @@ -19,7 +19,7 @@ name="script_memory" top_pad="24" text_color="White" - width="480"> + width="620"> Parcel Script Memory </text> <text @@ -32,7 +32,7 @@ name="parcels_listed" top_delta="18" visible="true" - width="480"> + width="620"> </text> <text @@ -44,7 +44,7 @@ left="30" name="memory_used" top_delta="18" - width="480"> + width="620"> </text> <text @@ -56,7 +56,7 @@ left="30" name="urls_used" top_delta="18" - width="480"> + width="620"> </text> <text @@ -69,7 +69,7 @@ name="loading_text" top_delta="12" text_color="EmphasisColor" - width="480"> + width="620"> Loading... </text> <scroll_list @@ -83,7 +83,7 @@ sort_ascending="true" name="scripts_list" top_delta="16" - width="460"> + width="600"> <scroll_list.columns label="Size (kb)" name="size" @@ -120,23 +120,23 @@ left="10" width="100" /> <button - follows="bottom|right" + follows="bottom|left" height="19" - label="Highlight" + label="Return" visible="false" - layout="bottomright" - left="370" - name="highlight_btn" + layout="bottomleft" + name="return_btn" top="34" + left_delta="390" width="100" /> <button - follows="bottom|right" + follows="bottom|left" height="19" - label="Return" + label="Highlight" visible="false" - layout="bottomright" - name="return_btn" + layout="bottomleft" + left_delta="105" + name="highlight_btn" top="34" - left_delta="-105" width="100" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml index 975b08be053713600d025efb189e8d6467622826..8e9255292173f715f7fedecb39d6bcb520686416 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml @@ -61,8 +61,7 @@ right="-2" height="319" follows="all" - halign="center" - use_highlighting_on_hover="true"> + halign="center"> <panel follows="all" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index d3e24a19efd5502edb580a39aeed4e1891b12ab4..9995523e61935ba7b38c071356ee3b78fd01888e 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -59,7 +59,6 @@ name="inbox_layout_panel" visible="false" min_dim="35" - max_dim="235" expanded_min_dim="90" height="235"> <panel diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index b19c6756bc12ab9c962e192335cb276dffcc8fe4..6b3422d8926035cde535030987754426a3e707e7 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -22,7 +22,7 @@ <!-- about dialog/support string--> <string name="AboutHeader"> -[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) +[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="BuildConfig">Build Configuration [BUILD_CONFIG]</string> @@ -45,19 +45,31 @@ Graphics Card Vendor: [GRAPHICS_CARD_VENDOR] Graphics Card: [GRAPHICS_CARD] </string> <string name="AboutDriver">Windows Graphics Driver Version: [GRAPHICS_DRIVER_VERSION]</string> + <string name="AboutOGL">OpenGL Version: [OPENGL_VERSION]</string> + <string name="AboutSettings"> +Window size: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Font Size Adjustment: [FONT_SIZE_ADJUSTMENT]pt +UI Scaling: [UI_SCALE] +Draw distance: [DRAW_DISTANCE]m +Bandwidth: [NET_BANDWITH]kbit/s +LOD factor: [LOD_FACTOR] +Render quality: [RENDER_QUALITY] / 7 +Advanced Lighting Model: [GPU_SHADERS] +Texture memory: [TEXTURE_MEMORY]MB +VFS (cache) creation time: [VFS_TIME] + </string> <string name="AboutLibs"> -OpenGL Version: [OPENGL_VERSION] - J2C Decoder Version: [J2C_VERSION] Audio Driver Version: [AUDIO_DRIVER_VERSION] LLCEFLib/CEF Version: [LLCEFLIB_VERSION] +LibVLC Version: [LIBVLC_VERSION] Voice Server Version: [VOICE_VERSION] </string> <string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string> <string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string> <string name="ErrorFetchingServerReleaseNotesURL">Error fetching server release notes URL.</string> <string name="BuildConfiguration">Build Configuration</string> - + <!-- progress --> <string name="ProgressRestoring">Restoring...</string> <string name="ProgressChangingResolution">Changing resolution...</string> @@ -499,6 +511,7 @@ Please try logging in again in a minute.</string> <string name="TeleportYourAgent">Teleport you</string> <string name="ManageEstateSilently">Manage your estates silently</string> <string name="ChangeYourDefaultAnimations">Change your default animations</string> + <string name="ForceSitAvatar">Force your avatar to sit</string> <string name="NotConnected">Not Connected</string> <string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name --> @@ -2256,6 +2269,7 @@ For AI Character: Get the closest navigable point to the point provided. <string name="BodyPartsLeftLeg">Left Leg</string> <string name="BodyPartsTorso">Torso</string> <string name="BodyPartsRightLeg">Right Leg</string> + <string name="BodyPartsEnhancedSkeleton">Enhanced Skeleton</string> <!-- slider --> <string name="GraphicsQualityLow">Low</string> @@ -2477,8 +2491,23 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f <string name="Stomach">Stomach</string> <string name="Left Pec">Left Pec</string> <string name="Right Pec">Right Pec</string> - <string name="Neck">Neck</string> - <string name="Avatar Center">Avatar Center</string> + <string name="Neck">Neck</string> + <string name="Avatar Center">Avatar Center</string> + <string name="Left Ring Finger">Left Ring Finger</string> + <string name="Right Ring Finger">Right Ring Finger</string> + <string name="Tail Base">Tail Base</string> + <string name="Tail Tip">Tail Tip</string> + <string name="Left Wing">Left Wing</string> + <string name="Right Wing">Right Wing</string> + <string name="Jaw">Jaw</string> + <string name="Alt Left Ear">Alt Left Ear</string> + <string name="Alt Right Ear">Alt Right Ear</string> + <string name="Alt Left Eye">Alt Left Eye</string> + <string name="Alt Right Eye">Alt Right Eye</string> + <string name="Tongue">Tongue</string> + <string name="Groin">Groin</string> + <string name="Left Hind Foot">Left Hind Foot</string> + <string name="Right Hind Foot">Right Hind Foot</string> <string name="Invalid Attachment">Invalid Attachment Point</string> <string name="ATTACHMENT_MISSING_ITEM">Error: missing item</string> <string name="ATTACHMENT_MISSING_BASE_ITEM">Error: missing base item</string> @@ -2499,6 +2528,15 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f <string name="av_render_most_of">You may not be rendered by most of those around you.</string> <string name="av_render_anyone">You may not be rendered by anyone around you.</string> + <!-- HUD complexity rendering messages, see llavatarrendernotifier. --> + <string name="hud_description_total">Your HUD</string> + <string name="hud_name_with_joint">[OBJ_NAME] (worn on [JNT_NAME])</string> + <string name="hud_render_memory_warning">[HUD_DETAILS] uses a lot of texture memory</string> + <string name="hud_render_cost_warning">[HUD_DETAILS] contains a lot of expensive objects and textures</string> + <string name="hud_render_heavy_textures_warning">[HUD_DETAILS] contains a lot of large textures</string> + <string name="hud_render_cramped_warning">[HUD_DETAILS] contains too many objects</string> + <string name="hud_render_textures_warning">[HUD_DETAILS] contains too many textures</string> + <!-- AgeYearsA = singular, AgeYearsB = plural, AgeYearsC = plural for non-English languages like Russian @@ -2566,7 +2604,8 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f <string name="SaveComplete">Save complete.</string> <string name="UploadFailed">File upload failed: </string> <string name="ObjectOutOfRange">Script (object out of range)</string> - + <string name="ScriptWasDeleted">Script (deleted from inventory)</string> + <!-- god tools --> <string name="GodToolsObjectOwnedBy">Object [OBJECT] owned by [OWNER]</string> @@ -2654,8 +2693,8 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f <string name="ATTACH_LULEG">Left Upper Leg</string> <string name="ATTACH_LLLEG">Left Lower Leg</string> <string name="ATTACH_BELLY">Belly</string> - <string name="ATTACH_RPEC">Right Pec</string> - <string name="ATTACH_LPEC">Left Pec</string> + <string name="ATTACH_LEFT_PEC">Left Pec</string> + <string name="ATTACH_RIGHT_PEC">Right Pec</string> <string name="ATTACH_HUD_CENTER_2">HUD Center 2</string> <string name="ATTACH_HUD_TOP_RIGHT">HUD Top Right</string> <string name="ATTACH_HUD_TOP_CENTER">HUD Top Center</string> @@ -2666,6 +2705,21 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f <string name="ATTACH_HUD_BOTTOM_RIGHT">HUD Bottom Right</string> <string name="ATTACH_NECK">Neck</string> <string name="ATTACH_AVATAR_CENTER">Avatar Center</string> + <string name="ATTACH_LHAND_RING1">Left Ring Finger</string> + <string name="ATTACH_RHAND_RING1">Right Ring Finger</string> + <string name="ATTACH_TAIL_BASE">Tail Base</string> + <string name="ATTACH_TAIL_TIP">Tail Tip</string> + <string name="ATTACH_LWING">Left Wing</string> + <string name="ATTACH_RWING">Right Wing</string> + <string name="ATTACH_FACE_JAW">Jaw</string> + <string name="ATTACH_FACE_LEAR">Alt Left Ear</string> + <string name="ATTACH_FACE_REAR">Alt Right Ear</string> + <string name="ATTACH_FACE_LEYE">Alt Left Eye</string> + <string name="ATTACH_FACE_REYE">Alt Right Eye</string> + <string name="ATTACH_FACE_TONGUE">Tongue</string> + <string name="ATTACH_GROIN">Groin</string> + <string name="ATTACH_HIND_LFOOT">Left Hind Foot</string> + <string name="ATTACH_HIND_RFOOT">Right Hind Foot</string> <!-- script editor --> <string name="CursorPos">Line [LINE], Column [COLUMN]</string> @@ -2834,6 +2888,12 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh <string name="Multiple Media">Multiple Media</string> <string name="Play Media">Play/Pause Media</string> + <!-- Drivers support/update pages --> + <string name="IntelDriverPage">http://www.intel.com/p/en_US/support/detect/graphics</string> + <string name="NvidiaDriverPage">http://www.nvidia.com/Download/index.aspx?lang=en-us</string> + <string name="AMDDriverPage">http://support.amd.com/us/Pages/AMDSupportHub.aspx</string> + + <!-- OSMessageBox messages --> <string name="MBCmdLineError"> An error was found parsing the command line. @@ -3680,12 +3740,15 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <!-- Financial operations strings --> <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT] [REASON].</string> + <string name="paid_you_ldollars_gift">[NAME] paid you L$[AMOUNT]: [REASON]</string> <string name="paid_you_ldollars_no_reason">[NAME] paid you L$[AMOUNT].</string> <string name="you_paid_ldollars">You paid [NAME] L$[AMOUNT] [REASON].</string> + <string name="you_paid_ldollars_gift">You paid [NAME] L$[AMOUNT]: [REASON]</string> <string name="you_paid_ldollars_no_info">You paid L$[AMOUNT].</string> <string name="you_paid_ldollars_no_reason">You paid [NAME] L$[AMOUNT].</string> <string name="you_paid_ldollars_no_name">You paid L$[AMOUNT] [REASON].</string> <string name="you_paid_failure_ldollars">You failed to pay [NAME] L$[AMOUNT] [REASON].</string> + <string name="you_paid_failure_ldollars_gift">You failed to pay [NAME] L$[AMOUNT]: [REASON]</string> <string name="you_paid_failure_ldollars_no_info">You failed to pay L$[AMOUNT].</string> <string name="you_paid_failure_ldollars_no_reason">You failed to pay [NAME] L$[AMOUNT].</string> <string name="you_paid_failure_ldollars_no_name">You failed to pay L$[AMOUNT] [REASON].</string> @@ -3807,6 +3870,9 @@ Abuse Report</string> <string name="DefaultMimeType">none/none</string> <string name="texture_load_dimensions_error">Can't load images larger than [WIDTH]*[HEIGHT]</string> + <string name="outfit_photo_load_dimensions_error">Max outfit photo size is [WIDTH]*[HEIGHT]. Please resize or use another image</string> + <string name="outfit_photo_select_dimensions_error">Max outfit photo size is [WIDTH]*[HEIGHT]. Please select another texture</string> + <string name="outfit_photo_verify_dimensions_error">Cannot verify photo dimensions. Please wait until photo size is displayed in picker</string> <!-- language specific white-space characters, delimiters, spacers, item separation symbols --> <string name="sentences_separator" value=" "></string> @@ -4017,6 +4083,7 @@ Try enclosing path to the editor with double quotes. <string name="Command_Places_Label">Places</string> <string name="Command_Preferences_Label">Preferences</string> <string name="Command_Profile_Label">Profile</string> + <string name="Command_Report_Abuse_Label">Report Abuse</string> <string name="Command_Search_Label">Search</string> <string name="Command_Snapshot_Label">Snapshot</string> <string name="Command_Speak_Label">Speak</string> @@ -4048,6 +4115,7 @@ Try enclosing path to the editor with double quotes. <string name="Command_Places_Tooltip">Places you've saved</string> <string name="Command_Preferences_Tooltip">Preferences</string> <string name="Command_Profile_Tooltip">Edit or view your profile</string> + <string name="Command_Report_Abuse_Tooltip">Report Abuse</string> <string name="Command_Search_Tooltip">Find places, events, people</string> <string name="Command_Snapshot_Tooltip">Take a picture</string> <string name="Command_Speak_Tooltip">Speak with people nearby using your microphone</string> @@ -4132,6 +4200,9 @@ Try enclosing path to the editor with double quotes. Loading... </string> + <!-- Statistics --> + <string name="na">n/a</string> + <!-- Presets graphic/camera --> <string name="preset_combo_label">-Empty list-</string> <string name="Default">Default</string> diff --git a/indra/newview/skins/default/xui/en/widgets/slider.xml b/indra/newview/skins/default/xui/en/widgets/slider.xml index f735d09476e973416b85227f7f554fa8e691845e..6cceafc9aeb43cdf55d8654812ea95d167c2b1c1 100644 --- a/indra/newview/skins/default/xui/en/widgets/slider.xml +++ b/indra/newview/skins/default/xui/en/widgets/slider.xml @@ -8,7 +8,6 @@ text_color="LabelTextColor" text_disabled_color="LabelDisabledColor"> <slider.value_editor name="slider editor" - max_length="10" follows="left|bottom"/> <slider.value_text name="slider text" follows="left|bottom"/> diff --git a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml index ba2fdf4f1fe39d66d2e8214cc9b77e0ead036766..1511116ba690a819c0dbc307bee4616e97acf1ad 100644 --- a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml +++ b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml @@ -5,8 +5,7 @@ follows="left|top" > <multiselect_text font="SansSerifSmall"/> - <caption_text text="Multiple" - halign="center" + <caption_text halign="center" font="SansSerifSmall" v_pad="2"/> <border bevel_style="in"/> diff --git a/indra/newview/skins/default/xui/es/floater_model_preview.xml b/indra/newview/skins/default/xui/es/floater_model_preview.xml index a5229cd48c8041b917f3c072daaf1afe01390c8e..a269add08a8e44a4080148fd5ff59ae9352debdd 100644 --- a/indra/newview/skins/default/xui/es/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/es/floater_model_preview.xml @@ -245,6 +245,7 @@ </text> <check_box label="Incluir el peso de la piel" name="upload_skin"/> <check_box label="Incluir posturas de las articulaciones" name="upload_joints"/> + <check_box label="Bloquear la escala si está definida la posición de la articulación" name="lock_scale_if_joint_position"/> <text name="pelvis_offset_label"> Desplazamiento Z (subir o bajar el avatar): </text> diff --git a/indra/newview/skins/default/xui/es/floater_pay.xml b/indra/newview/skins/default/xui/es/floater_pay.xml index 567f980446123c61417d2c5d527f95c1584df7d4..61a898adad18370528c923e1daf191cab4ab1637 100644 --- a/indra/newview/skins/default/xui/es/floater_pay.xml +++ b/indra/newview/skins/default/xui/es/floater_pay.xml @@ -1,9 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Give Money" title=""> - <string name="payee_group">Pagar al grupo</string> - <string name="payee_resident">Pagar al residente</string> - <text name="paying_text">Vas a pagar:</text> - <text left="115" name="payee_name">Nombre de prueba demasiado largo para comprobar la función de recorte</text> + <string name="payee_group"> + Pagar al grupo + </string> + <string name="payee_resident"> + Pagar al residente + </string> + <text name="paying_text"> + Vas a pagar: + </text> + <text left="115" name="payee_name"> + Nombre de prueba demasiado largo para comprobar la función de recorte + </text> + <text name="payment_message_label"> + Descripción (opcional): + </text> <panel label="Buscar" name="PatternsPanel"> <button label="Pagar 1 L$" label_selected="Pagar 1 L$" name="fastpay 1"/> <button label="Pagar 5 L$" label_selected="Pagar 5 L$" name="fastpay 5"/> @@ -11,7 +22,9 @@ <button label="Pagar 20 L$" label_selected="Pagar 20 L$" name="fastpay 20"/> </panel> <panel label="Buscar" name="InputPanel"> - <text name="amount text">Otra cantidad:</text> + <text name="amount text"> + Otra cantidad: + </text> <button label="Pagar" label_selected="Pagar" name="pay btn"/> <button label="Cancelar" label_selected="Cancelar" name="cancel btn"/> </panel> diff --git a/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml index dda95ad0707a1788b8a8d9b96b46a31f29c16eb7..84b256c8e3ab86b441bc4a9614d86e95197370c4 100644 --- a/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Complejidad máxima:" name="IndirectMaxComplexity" tool_tip="Controla en qué momento un avatar visualmente complejo se dibuja como una sombra de color sólido"/> + <slider label="Complejidad máxima:" name="IndirectMaxComplexity" tool_tip="Controla en qué momento un avatar visualmente complejo se dibuja como un "JellyDoll""/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/es/floater_script_queue.xml b/indra/newview/skins/default/xui/es/floater_script_queue.xml index 39c84103c49dbacaa4ad10cbf182299f1f833c03..2dbc59e9032b8d285fa4ba2f935795cad5a2681a 100644 --- a/indra/newview/skins/default/xui/es/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/es/floater_script_queue.xml @@ -15,5 +15,11 @@ <floater.string name="NotRunning"> Sin ejecutarse </floater.string> + <floater.string name="Timeout"> + Tiempo de espera: [OBJECT_NAME] + </floater.string> + <floater.string name="LoadingObjInv"> + Cargando inventario de: [OBJECT_NAME] + </floater.string> <button label="Cerrar" label_selected="Cerrar" name="close"/> </floater> diff --git a/indra/newview/skins/default/xui/es/floater_web_content.xml b/indra/newview/skins/default/xui/es/floater_web_content.xml index 5e02fad2dd9ef84fd13a42f9fbaae6ac98252604..3f3e2bb01e27205f68a0e9e3f4694df95dcdd1ff 100644 --- a/indra/newview/skins/default/xui/es/floater_web_content.xml +++ b/indra/newview/skins/default/xui/es/floater_web_content.xml @@ -10,5 +10,9 @@ <icon name="media_secure_lock_flag" tool_tip="Navegación segura"/> <button name="popexternal" tool_tip="Abrir URL actual en tu navegador de escritorio"/> </layout_panel> + <layout_panel name="debug_controls"> + <button name="web_test_home_page" tool_tip="Página principal de pruebas web"/> + <button name="VLC Plugin Test" tool_tip="Prueba de vÃdeo MPEG4"/> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/es/menu_attachment_other.xml b/indra/newview/skins/default/xui/es/menu_attachment_other.xml index 772b27c9ba53dc7c62eaa9dd7989b9c673eac30c..f1394dad0580def4e4bf85ad64583a45623e9c0f 100644 --- a/indra/newview/skins/default/xui/es/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/es/menu_attachment_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="MI" name="Send IM..."/> <menu_item_call label="Llamada" name="Call"/> <menu_item_call label="Invitar al grupo" name="Invite..."/> + <menu_item_call label="Restablecer esqueleto" name="Reset Skeleton"/> + <menu_item_call label="Restablecer esqueleto y animaciones" name="Reset Skeleton And Animations"/> <menu_item_call label="Ignorar" name="Avatar Mute"/> <menu_item_call label="Denunciar" name="abuse"/> <menu_item_call label="Congelar" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/es/menu_attachment_self.xml b/indra/newview/skins/default/xui/es/menu_attachment_self.xml index 02819e6816d40847e75394b7f5827153879fd9a6..7805db3ab4e97fed7fbc83fb9c4c2d3556cd54f2 100644 --- a/indra/newview/skins/default/xui/es/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/es/menu_attachment_self.xml @@ -9,6 +9,8 @@ <menu_item_call label="Editar mi vestuario" name="Edit Outfit"/> <menu_item_call label="Editar mi anatomÃa" name="Edit My Shape"/> <menu_item_call label="Altura del avatar" name="Hover Height"/> + <menu_item_call label="Restablecer esqueleto" name="Reset Skeleton"/> + <menu_item_call label="Restablecer esqueleto y animaciones" name="Reset Skeleton And Animations"/> <menu_item_call label="Mis amigos" name="Friends..."/> <menu_item_call label="Mis grupos" name="Groups..."/> <menu_item_call label="Mi perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/es/menu_avatar_other.xml b/indra/newview/skins/default/xui/es/menu_avatar_other.xml index 75cbf5a0223305a5bc6645fdc88d1f5bb8195734..80f16d3e829d60bc0d45a62745f6af5594c8d23f 100644 --- a/indra/newview/skins/default/xui/es/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/es/menu_avatar_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="MI" name="Send IM..."/> <menu_item_call label="Llamada" name="Call"/> <menu_item_call label="Invitar al grupo" name="Invite..."/> + <menu_item_call label="Restablecer esqueleto" name="Reset Skeleton"/> + <menu_item_call label="Restablecer esqueleto y animaciones" name="Reset Skeleton And Animations"/> <menu_item_call label="Ignorar" name="Avatar Mute"/> <menu_item_call label="Denunciar" name="abuse"/> <menu_item_call label="Congelar" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/es/menu_avatar_self.xml b/indra/newview/skins/default/xui/es/menu_avatar_self.xml index d60a3434cf30b79f92ddb216246baf5f254432aa..bdb4771d172f6cb6b7c6fb93644b1c5eb6cd0caf 100644 --- a/indra/newview/skins/default/xui/es/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/es/menu_avatar_self.xml @@ -26,6 +26,8 @@ <menu_item_call label="Editar mi vestuario" name="Edit Outfit"/> <menu_item_call label="Editar mi anatomÃa" name="Edit My Shape"/> <menu_item_call label="Altura del avatar" name="Hover Height"/> + <menu_item_call label="Restablecer esqueleto" name="Reset Skeleton"/> + <menu_item_call label="Restablecer esqueleto y animaciones" name="Reset Skeleton And Animations"/> <menu_item_call label="Mis amigos" name="Friends..."/> <menu_item_call label="Mis grupos" name="Groups..."/> <menu_item_call label="Mi perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/es/menu_login.xml b/indra/newview/skins/default/xui/es/menu_login.xml index 44e8f3ffeb3aa7d01f71ecaf63737eb60f7bb56d..d9f8f23576bb9a5dafad0d2d0de118d3fe97d748 100644 --- a/indra/newview/skins/default/xui/es/menu_login.xml +++ b/indra/newview/skins/default/xui/es/menu_login.xml @@ -20,12 +20,11 @@ <menu_item_check label="Mostrar el menú 'Debug'" name="Show Debug Menu"/> <menu label="Depurar" name="Debug"> <menu_item_call label="Mostrar las configuraciones del depurador" name="Debug Settings"/> - <menu_item_call label="Configuraciones del Visor/Color" name="UI/Color Settings"/> <menu label="Pruebas de la interfaz" name="UI Tests"/> <menu_item_call label="Definir el tamaño de la ventana..." name="Set Window Size..."/> <menu_item_call label="Mostrar los 'TOS'" name="TOS"/> <menu_item_call label="Mostrar mensaje crÃtico" name="Critical"/> - <menu_item_call label="Prueba de depuración de ventanas de contenido web" name="Web Content Floater Debug Test"/> + <menu_item_call label="Navegador de medios" name="Media Browser"/> <menu label="Configurar el nivel de registro" name="Set Logging Level"> <menu_item_check label="Depurar" name="Debug"/> <menu_item_check label="Información" name="Info"/> diff --git a/indra/newview/skins/default/xui/es/menu_object_icon.xml b/indra/newview/skins/default/xui/es/menu_object_icon.xml index a99c889bb0604c2ed97b45250eda7497847ddea9..f80eb4db74d5d3e1ffa4326b96607f160f393435 100644 --- a/indra/newview/skins/default/xui/es/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/es/menu_object_icon.xml @@ -2,6 +2,7 @@ <menu name="Object Icon Menu"> <menu_item_call label="Perfil del objeto..." name="Object Profile"/> <menu_item_call label="Ignorar..." name="Block"/> + <menu_item_call label="No ignorar" name="Unblock"/> <menu_item_call label="Mostrar en el mapa" name="show_on_map"/> <menu_item_call label="Teleportarse a la posición del objeto" name="teleport_to_object"/> </menu> diff --git a/indra/newview/skins/default/xui/es/menu_outfit_gear.xml b/indra/newview/skins/default/xui/es/menu_outfit_gear.xml index 56e64c729f78057938fa320568a17ed5852752d7..b3f2b789d78387d47202039ab7898c5e4afcc0e5 100644 --- a/indra/newview/skins/default/xui/es/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/es/menu_outfit_gear.xml @@ -3,6 +3,10 @@ <menu_item_call label="Ponerme - Reemplazar el vestuario actual" name="wear"/> <menu_item_call label="Ponerme - Añadir al vestuario actual" name="wear_add"/> <menu_item_call label="Quitarme - Quitar del vestuario actual" name="take_off"/> + <menu_item_call label="Subir una foto (10 L$)" name="upload_photo"/> + <menu_item_call label="Seleccionar foto" name="select_photo"/> + <menu_item_call label="Hacer una foto" name="take_snapshot"/> + <menu_item_call label="Quitar foto" name="remove_photo"/> <menu label="Ropas nuevas" name="New Clothes"> <menu_item_call label="Camisa nueva" name="New Shirt"/> <menu_item_call label="Pantalón nuevo" name="New Pants"/> @@ -27,4 +31,5 @@ <menu_item_call label="Cerrar todas las carpetas" name="collapse"/> <menu_item_call label="Renombrar el vestuario" name="rename"/> <menu_item_call label="Borrar el vestuario" name="delete_outfit"/> + <menu_item_check label="Ordenar las carpetas siempre alfabéticamente" name="sort_folders_by_name"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/es/menu_people_friends_view.xml b/indra/newview/skins/default/xui/es/menu_people_friends_view.xml index ad896c1b74e21bc6e376c8fc8964919ea9d6c152..75a5aa3cadf29ab7b6cac73930ea9f93d7a5459e 100644 --- a/indra/newview/skins/default/xui/es/menu_people_friends_view.xml +++ b/indra/newview/skins/default/xui/es/menu_people_friends_view.xml @@ -4,5 +4,6 @@ <menu_item_check label="Ordenar por estatus" name="sort_status"/> <menu_item_check label="Ver los iconos de la gente" name="view_icons"/> <menu_item_check label="Ver permisos concedidos" name="view_permissions"/> + <menu_item_check label="Ocultar nombres de usuario" name="view_usernames"/> <menu_item_check label="Ver el registro de conversaciones..." name="view_conversation"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/es/menu_people_nearby.xml b/indra/newview/skins/default/xui/es/menu_people_nearby.xml index 09bb119d5ad150fc6a150ad7e86e4f6df117530e..9e9f2b819175d46de8d21398f665357b4a94ebda 100644 --- a/indra/newview/skins/default/xui/es/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/es/menu_people_nearby.xml @@ -13,4 +13,6 @@ <menu_item_call label="Compartir" name="share"/> <menu_item_call label="Pagar" name="pay"/> <menu_item_check label="Ignorar / No ignorar" name="block_unblock"/> + <menu_item_call label="Congelar" name="freeze"/> + <menu_item_call label="Expulsar" name="eject"/> </context_menu> diff --git a/indra/newview/skins/default/xui/es/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/es/menu_people_nearby_view.xml index c2fb360dd1c0b5ef90234e8bd6b81cbb9d2660ff..c51047f04a88d87e3be043f8c6ef3b2df119d9c8 100644 --- a/indra/newview/skins/default/xui/es/menu_people_nearby_view.xml +++ b/indra/newview/skins/default/xui/es/menu_people_nearby_view.xml @@ -5,4 +5,5 @@ <menu_item_check label="Ordenar según distancia" name="sort_distance"/> <menu_item_check label="Ver los iconos de la gente" name="view_icons"/> <menu_item_check label="Ver mapa" name="view_map"/> + <menu_item_check label="Ocultar nombres de usuario" name="view_usernames"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/es/menu_url_objectim.xml b/indra/newview/skins/default/xui/es/menu_url_objectim.xml index c3c8439ea2ae53f7ce93d9a18c57d1f7cb061e6d..51803e93c55d57c3d5fa9c5420f0acb1677702e3 100644 --- a/indra/newview/skins/default/xui/es/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/es/menu_url_objectim.xml @@ -2,6 +2,7 @@ <context_menu name="Url Popup"> <menu_item_call label="Perfil del objeto..." name="show_object"/> <menu_item_call label="Ignorar..." name="block_object"/> + <menu_item_call label="Desbloquear" name="unblock_object"/> <menu_item_call label="Mostrar en el mapa" name="show_on_map"/> <menu_item_call label="Teleportarse a la posición del objeto" name="teleport_to_object"/> <menu_item_call label="Copiar el nombre del objeto al portapapeles" name="url_copy_label"/> diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml index fd248116b8728a3ef012c001d5bb36304e6edc2b..c4986821f178387cb66d4356c67772e2da0785a9 100644 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -113,11 +113,11 @@ <menu_item_call label="Enlazar" name="Link"/> <menu_item_call label="Desenlazar" name="Unlink"/> <menu_item_check label="Editar las partes enlazadas" name="Edit Linked Parts"/> - <menu label="Seleccionar las partes enlazadas" name="Select Linked Parts"> - <menu_item_call label="Seleccionar la parte siguiente" name="Select Next Part"/> - <menu_item_call label="Seleccionar la parte previa" name="Select Previous Part"/> - <menu_item_call label="Incluir la parte siguiente" name="Include Next Part"/> - <menu_item_call label="Incluir la parte previa" name="Include Previous Part"/> + <menu label="Seleccionar elementos" name="Select Elements"> + <menu_item_call label="Seleccionar la parte o cara siguiente" name="Select Next Part or Face"/> + <menu_item_call label="Seleccionar la parte o cara anterior" name="Select Previous Part or Face"/> + <menu_item_call label="Incluir la parte o cara siguiente" name="Include Next Part or Face"/> + <menu_item_call label="Incluir la parte o cara anterior" name="Include Previous Part or Face"/> </menu> <menu_item_call label="Linksets..." name="pathfinding_linkset_menu_item"/> <menu_item_call label="Visión en lo seleccionado" name="Focus on Selection"/> @@ -332,8 +332,7 @@ <menu_item_call label="Volcar la caché de objetos de la región" name="Dump Region Object Cache"/> </menu> <menu label="UI" name="UI"> - <menu_item_call label="Prueba de navegadores de medios" name="Web Browser Test"/> - <menu_item_call label="Navegador de contenido web" name="Web Content Browser"/> + <menu_item_call label="Navegador de medios" name="Media Browser"/> <menu_item_call label="Print Selected Object Info" name="Print Selected Object Info"/> <menu_item_check label="Debug Clicks" name="Debug Clicks"/> <menu_item_check label="Debug Mouse Events" name="Debug Mouse Events"/> @@ -367,6 +366,7 @@ <menu_item_check label="Animation Info" name="Animation Info"/> <menu_item_check label="Disable Level Of Detail" name="Disable LOD"/> <menu_item_check label="Show Collision Skeleton" name="Show Collision Skeleton"/> + <menu_item_check label="Mostrar los huesos" name="Show Bones"/> <menu_item_check label="Display Agent Target" name="Display Agent Target"/> <menu_item_call label="Debug Avatar Textures" name="Debug Avatar Textures"/> </menu> diff --git a/indra/newview/skins/default/xui/es/menu_wearing_tab.xml b/indra/newview/skins/default/xui/es/menu_wearing_tab.xml index 64fd7ce4cf743c014b47403879af9092939dce0b..637a14cf5b5dce97072374bc2c4b153a69f32185 100644 --- a/indra/newview/skins/default/xui/es/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/es/menu_wearing_tab.xml @@ -3,4 +3,6 @@ <menu_item_call label="Quitarme" name="take_off"/> <menu_item_call label="Quitar" name="detach"/> <menu_item_call label="Editar el vestuario" name="edit"/> + <menu_item_call label="Editar" name="edit_item"/> + <menu_item_call label="Mostrar original" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/es/mime_types.xml b/indra/newview/skins/default/xui/es/mime_types.xml index eb212344ce094766e237d821a8aab273ebef1d61..74e447c70746a1b4c5b6e7c5d708f9558d31f484 100644 --- a/indra/newview/skins/default/xui/es/mime_types.xml +++ b/indra/newview/skins/default/xui/es/mime_types.xml @@ -22,14 +22,6 @@ Ver la pelÃcula </playtip> </widgetset> - <widgetset name="none"> - <label name="none_label"> - No hay contenido - </label> - <tooltip name="none_tooltip"> - Aquà no hay contenido multimedia - </tooltip> - </widgetset> <widgetset name="image"> <label name="image_label"> Imagen @@ -52,11 +44,24 @@ Escuchar el audio de esta localización </playtip> </widgetset> + <widgetset name="none"> + <label name="none_label"> + No hay contenido + </label> + <tooltip name="none_tooltip"> + Aquà no hay contenido multimedia + </tooltip> + </widgetset> <scheme name="rtsp"> <label name="rtsp_label"> Real Time Streaming </label> </scheme> + <scheme name="libvlc"> + <label name="libvlc_label"> + Medios compatibles con LibVLC + </label> + </scheme> <mimetype name="blank"> <label name="blank_label"> - Ninguno - @@ -127,11 +132,6 @@ Macromedia Director </label> </mimetype> - <mimetype name="application/x-shockwave-flash"> - <label name="application/x-shockwave-flash_label"> - Flash - </label> - </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> Audio (MIDI) @@ -207,6 +207,11 @@ PelÃcula (MP4) </label> </mimetype> + <mimetype name="application/octet-stream"> + <label name="video/octet-stream"> + PelÃcula + </label> + </mimetype> <mimetype name="video/quicktime"> <label name="video/quicktime_label"> PelÃcula (QuickTime) diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index b52497eb85ebe2d0e2f38f330801df9b85f16673..d6e686df423e1fe9a3224e3c407894685063d807 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -326,6 +326,9 @@ Si no quieres que este rol siga teniendo dichas capacidades, deshabilÃtalas inm Te dispones a expulsar a [COUNT] miembros del grupo. <usetemplate ignoretext="Confirma la expulsión de varios miembros del grupo" name="okcancelignore" notext="Cancelar" yestext="Prohibir el acceso"/> </notification> + <notification name="GroupBanUserOnBanlist"> + No se ha enviado una invitación a algunos residentes porque están expulsados del grupo. + </notification> <notification name="AttachmentDrop"> Vas a soltar tu anexado. ¿Estás seguro de que quieres continuar? @@ -454,6 +457,12 @@ debes estar dentro de ella. <notification name="ErrorEncodingSnapshot"> Error al codificar la foto. </notification> + <notification name="ErrorPhotoCannotAfford"> + Necesitas [COST] L$ para guardar una foto en el inventario. Puedes comprar L$ o bien guardar la foto en tu equipo. + </notification> + <notification name="ErrorTextureCannotAfford"> + Necesitas [COST] L$ para guardar una textura en el inventario. Puedes comprar L$ o bien guardar la foto en tu equipo. + </notification> <notification name="ErrorUploadingPostcard"> Hubo un problema al enviar la foto por la siguiente razón: [REASON] </notification> @@ -477,6 +486,9 @@ Se ha superado el lÃmite máximo de [MAX_ATTACHMENTS] objetos. Por favor, quÃt <notification name="CannotWearInfoNotComplete"> No puedes vestirte este Ãtem porque aún no se ha cargado. Por favor, inténtalo de nuevo en un minuto. </notification> + <notification name="MustEnterPasswordToLogIn"> + Escribe la contraseña para poder iniciar sesión. + </notification> <notification name="MustHaveAccountToLogIn"> Lo sentimos. Se ha quedado algún espacio en blanco. Tienes que volver a introducir el nombre de usuario de tu avatar. @@ -545,6 +557,9 @@ Nota: esto vaciará la caché. <notification name="ChangeConnectionPort"> La configuración del puerto tendrá efecto cuando reinicies [APP_NAME]. </notification> + <notification name="ChangeDeferredDebugSetting"> + El cambio de configuración del depurador se activará cuando reinicies [APP_NAME]. + </notification> <notification name="ChangeSkin"> Verás la nueva apariencia cuando reinicies [APP_NAME]. </notification> @@ -564,6 +579,10 @@ o hacer una puja? ¿Deseas borrar la nota? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> + <notification name="LoadPreviousReportScreenshot"> + ¿Deseas incluir la foto anterior en la denuncia? + <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Aceptar"/> + </notification> <notification name="GestureSaveFailedTooManySteps"> Fallo al guardar el gesto. Este gesto tiene demasiados pasos. @@ -624,30 +643,12 @@ El objeto debe de haber sido borrado o estar fuera de rango ('out of range& </url> <usetemplate ignoretext="El hardware de mi ordenador no está admitido" name="okcancelignore" notext="No" yestext="SÃ"/> </notification> - <notification name="IntelOldDriver"> - Probablemente ya existe un controlador más reciente para tu procesador de gráficos. La actualización del controlador de gráficos puede mejorar sustancialmente el rendimiento. - - ¿Deseas visitar [_URL] para comprobar si hay controladores actualizados? - <url name="url"> - http://www.intel.com/p/es_XL/support/detect/graphics - </url> - <usetemplate ignoretext="Mi controlador de gráficos no está actualizado" name="okcancelignore" notext="No" yestext="SÃ"/> - </notification> - <notification name="AMDOldDriver"> - Probablemente ya existe un controlador más reciente para tu procesador de gráficos. La actualización del controlador de gráficos puede mejorar sustancialmente el rendimiento. - - ¿Deseas visitar [_URL] para comprobar si hay controladores actualizados? - <url name="url"> - http://support.amd.com/us/Pages/AMDSupportHub.aspx - </url> - <usetemplate ignoretext="Mi controlador de gráficos no está actualizado" name="okcancelignore" notext="No" yestext="SÃ"/> - </notification> - <notification name="NVIDIAOldDriver"> + <notification name="OldGPUDriver"> Probablemente ya existe un controlador más reciente para tu procesador de gráficos. La actualización del controlador de gráficos puede mejorar sustancialmente el rendimiento. - ¿Deseas visitar [_URL] para comprobar si hay controladores actualizados? + ¿Deseas visitar [URL] para buscar controladores actualizados? <url name="url"> - http://www.nvidia.com/Download/index.aspx?lang=es + [URL] </url> <usetemplate ignoretext="Mi controlador de gráficos no está actualizado" name="okcancelignore" notext="No" yestext="SÃ"/> </notification> @@ -740,6 +741,9 @@ misma región. </url> <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> + <notification name="MuteLimitReached"> + No se puede añadir una entrada nueva a la lista de bloqueados porque has alcanzado el lÃmite de [MUTE_LIMIT] entradas. + </notification> <notification name="UnableToLinkObjects"> No se pudo enlazar estos [COUNT] objetos. Puedes enlazar [MAX] objetos como máximo. @@ -1370,12 +1374,18 @@ Puedes usar [SECOND_LIFE] de forma normal; los demás residentes te verán corre <ignore name="ignore" text="La ropa está tardando mucho en descargarse"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - Tu [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complejidad visual] es [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + La [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complejidad de tu avatar] es [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Avisarme si la complejidad de mi avatar puede ser excesiva" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - Tu [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complejidad visual] es [AGENT_COMPLEXITY]. + La [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complejidad de tu avatar] es [AGENT_COMPLEXITY]. + <usetemplate ignoretext="Advertirme cuando cambie la complejidad de mi avatar" name="notifyignore"/> + </notification> + <notification name="HUDComplexityWarning"> + [HUD_REASON], es probable que afecte negativamente al rendimiento. + <usetemplate ignoretext="Avisarme si la complejidad de mi HUD es excesiva" name="notifyignore"/> </notification> <notification name="FirstRun"> Se ha completado la instalación de [SECOND_LIFE]. @@ -1468,6 +1478,10 @@ Por favor, selecciona sólo uno y vuelve a intentarlo. ¿Teleportar a tu base a todos los residentes en esta región? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> + <notification name="ChangeObjectBonusFactor"> + Si disminuyes el plus de objetos cuando ya se han establecido construcciones en una región, algunos objetos se podrÃan eliminar o devolver. ¿Estás seguro de que quieres cambiar el plus de objetos? + <usetemplate ignoretext="Confirmar el cambio del factor de plus del objeto" name="okcancelignore" notext="Cancelar" yestext="Aceptar"/> + </notification> <notification name="EstateObjectReturn"> ¿Estás seguro de que quieres devolver los objetos propiedad de [USER_NAME] ? @@ -1492,6 +1506,10 @@ Cambia la textura [TEXTURE_NUM] por una imagen de 24-bit y 512x512 o menor, y pu ¿Realmente quieres predeterminar el terreno actual, haciéndolo el centro de los limites para elevarlo y rebajarlo, y el terreno por defecto para la herramienta 'Revertir'? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + Vas a usar valores inferiores más grandes que los de Intervalos de elevación. ¿Quieres continuar? + <usetemplate canceltext="No preguntar" name="yesnocancelbuttons" notext="Cancelar" yestext="Aceptar"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Sólo puedes tener [MAX_AGENTS] residentes autorizados. </notification> @@ -1512,6 +1530,9 @@ Se superan en [NUM_EXCESS] los [MAX_AGENTS] permitidos en [LIST_TYPE]. <notification name="OwnerCanNotBeDenied"> No se puede añadir a la lista de residentes no admitidos al propietario del estado. </notification> + <notification name="ProblemAddingEstateManagerBanned"> + No se puede añadir un residente expulsado a la lista de administradores de estado. + </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> No puedes cambiar la apariencia hasta que no se carguen la ropa y la forma. </notification> @@ -1686,6 +1707,10 @@ Si estás impaciente por probar las nuevas funciones y correcciones, lee la pág ¿Quieres abrir tu navegador para ver este contenido? <usetemplate ignoretext="Abrir mi navegador para ver una página web" name="okcancelignore" notext="Cancelar" yestext="OK"/> </notification> + <notification name="SystemUIScaleFactorChanged"> + El factor de tamaño de IU del sistema ha cambiado desde la última ejecución. ¿Deseas abrir la página de ajustes de tamaño de la IU? + <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Aceptar"/> + </notification> <notification name="WebLaunchJoinNow"> ¿Ir al [http://secondlife.com/account/ Panel de Control] para administrar tu cuenta? <usetemplate ignoretext="Abrir mi navegador para administrar mi cuenta" name="okcancelignore" notext="Cancelar" yestext="OK"/> @@ -1725,17 +1750,16 @@ Si estás impaciente por probar las nuevas funciones y correcciones, lee la pág ¿Deseas abandonar el grupo? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> + <notification name="GroupDepart"> + Has abandonado el grupo '[group_name]'. + </notification> <notification name="OwnerCannotLeaveGroup"> No es posible abandonar el grupo. No puedes abandonarlo porque eres su último propietario. Antes tienes que asignar el papel de propietario a otro miembro. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="GroupDepartError"> - No se puede abandonar el grupo: [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Has abandonado el grupo [group_name]. - <usetemplate name="okbutton" yestext="OK"/> + No se puede abandonar el grupo. + <usetemplate name="okbutton" yestext="Aceptar"/> </notification> <notification name="ConfirmKick"> ¿Quieres realmente expulsar a todos los residentes de la cuadrÃcula? @@ -2137,6 +2161,10 @@ Se cambiarán miles de regiones, y se provocará un colapso en el espacio del se Hay demasiados prims seleccionados. Por favor, selecciona [MAX_PRIM_COUNT] o menos y vuelve a intentarlo <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="TooManyScriptsSelected"> + Los objetos seleccionados tienen demasiados scripts. Selecciona menos objetos y repite la operación + <usetemplate name="okbutton" yestext="Aceptar"/> + </notification> <notification name="ProblemImportingEstateCovenant"> Hay problemas al importar el contrato del estado. <usetemplate name="okbutton" yestext="OK"/> @@ -2305,6 +2333,10 @@ Dado que estos objetos tienen scripts, moverlos a tu inventario puede provocar u Error en el pago: no se encuentra el objeto. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="PaymentBlockedButtonMismatch"> + Pago suspendido: el precio pagado no coincide con ninguno de los botones de pago asociados a este objeto. + <usetemplate name="okbutton" yestext="Aceptar"/> + </notification> <notification name="OpenObjectCannotCopy"> En este objeto, no hay Ãtems que estés autorizado a copiar. </notification> @@ -2340,6 +2372,12 @@ Esta acción no se puede deshacer. La selección es grande y contiene linksets. Si la desenlazas, quizás no puedas volver establecer los vÃnculos. Puede ser conveniente guardar copias de los linksets como medida de precaución. <usetemplate ignoretext="Confirmar que desenlazas un linkset" name="okcancelignore" notext="Cancelar" yestext="Desenlazar"/> </notification> + <notification name="HelpReportAbuseConfirm"> + Gracias por informarnos de este asunto. +Comprobaremos si tu denuncia contiene posibles transgresiones +y tomaremos las medidas oportunas. + <usetemplate name="okbutton" yestext="Aceptar"/> + </notification> <notification name="HelpReportAbuseSelectCategory"> Por favor, elige una categorÃa para esta denuncia de infracción. Seleccionar una categorÃa nos ayuda a clasificar y procesar las denuncias de infracciones. @@ -2409,6 +2447,10 @@ Linden Lab ¿Estás seguro de que quieres borrar de forma permanente el contenido de la Papelera? <usetemplate ignoretext="Confirmar antes de vaciar la Papelera del inventario" name="okcancelignore" notext="Cancelar" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + La papelera está completamente llena. Esto puede causar problemas a la hora de iniciar sesión. + <usetemplate name="okcancelbuttons" notext="Vaciaré la papelera más adelante" yestext="Vaciar la papelera"/> + </notification> <notification name="ConfirmClearBrowserCache"> ¿Estás seguro de que quieres borrar tu historial web, de viajes y de búsquedas? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> @@ -2763,6 +2805,10 @@ Aquà no puedes volar. <notification name="PathfindingDirty"> La región contiene cambios de pathfinding pendientes. Si tienes derechos de construcción, puedes recargarla pulsando el botón “Recargar regiónâ€. </notification> + <notification name="PathfindingDirtyRebake"> + La región contiene cambios de pathfinding pendientes. Si tienes derechos de construcción, puedes recargarla pulsando el botón “Recargar regiónâ€. + <usetemplate name="okbutton" yestext="Recargar la región"/> + </notification> <notification name="DynamicPathfindingDisabled"> Esta región no tiene activado el pathfinding dinámico. Los objetos programados que utilicen llamadas LSL de pathfinding pueden tener un comportamiento inesperado en ella. </notification> @@ -2996,7 +3042,7 @@ Si permaneces en esta región serás desconectado. [MESSAGE] -Del objeto: <nolink>[OBJECTNAME]</nolink>, propietario: [NAME_SLURL] +De objeto: <nolink>[OBJECTNAME]</nolink>, propietario: [NAME_SLURL] <form name="form"> <button name="Gotopage" text="Cargar"/> <button name="Cancel" text="Cancelar"/> @@ -3258,6 +3304,12 @@ Por tu seguridad, serán bloqueadas durante unos segundos. <notification name="AttachmentSaved"> Se ha guardado el adjunto. </notification> + <notification name="AppearanceToXMLSaved"> + El aspecto se ha guardado como XML en [PATH] + </notification> + <notification name="AppearanceToXMLFailed"> + Error al guardar el aspecto en XML. + </notification> <notification name="PresetNotSaved"> Error al guardar el valor predefinido [NAME]. </notification> @@ -3469,13 +3521,6 @@ Al ocultar el botón Hablar se desactiva la función de voz. <notification name="ForceQuitDueToLowMemory"> SL saldrá en 30 segundos porque no hay memoria suficiente. </notification> - <notification name="PopupAttempt"> - Se ha impedido que se abriera una ventana emergente. - <form name="form"> - <ignore name="ignore" text="Permitir todas las ventanas emergentes"/> - <button name="open" text="Abrir ventana emergente"/> - </form> - </notification> <notification name="SOCKS_NOT_PERMITTED"> El proxy SOCKS 5 "[HOST]:[PORT]" ha rechazado la conexión, no está permitida por el juego de reglas. <usetemplate name="okbutton" yestext="OK"/> @@ -3850,6 +3895,9 @@ Prueba otra vez dentro de un minuto. No se puede mover el objeto '[OBJECT_NAME]' a [OBJ_POSITION] de la región [REGION_NAME] porque no hay suficientes recursos para este objeto en esta parcela. </notification> + <notification name="NoParcelPermsNoObject"> + Error al copiar: no tienes acceso a esa parcela. + </notification> <notification name="CantMoveObjectRegionVersion"> No se puede mover el objeto '[OBJECT_NAME]' a [OBJ_POSITION] de la región [REGION_NAME] porque la otra región ejecuta una versión más antigua que no admite la recepción de este objeto atravesando regiones. @@ -3865,6 +3913,10 @@ Prueba otra vez dentro de un minuto. <notification name="NoPermModifyObject"> No tienes permiso para modificar ese objeto </notification> + <notification name="TooMuchObjectInventorySelected"> + Están seleccionados demasiados objetos con un inventario grande. Selecciona menos objetos y repite la operación. + <usetemplate name="okbutton" yestext="Aceptar"/> + </notification> <notification name="CantEnablePhysObjContributesToNav"> No se puede habilitar la fÃsica para un objeto que contribuye al navmesh. </notification> @@ -3901,6 +3953,12 @@ Prueba otra vez dentro de un minuto. <notification name="CantSaveModifyAttachment"> No se puede guardar en el contenido del objeto: se modificarÃan los permisos de anexo. </notification> + <notification name="AttachmentHasTooMuchInventory"> + El inventario de tus anexos ya es excesivo, por lo que no se puede añadir más. + </notification> + <notification name="IllegalAttachment"> + El anexo ha solicitado un punto que no existe en el avatar. Por tanto, se ha anexado al pecho. + </notification> <notification name="TooManyScripts"> Demasiados scripts. </notification> @@ -3993,6 +4051,12 @@ Prueba otra vez dentro de un minuto. <notification name="TeleportedByObjectUnknownUser"> Has sido teleportado por el objeto '[OBJECT_NAME]' cuyo propietario es un usuario desconocido. </notification> + <notification name="StandDeniedByObject"> + '[OBJECT_NAME]' no te permite ponerte de pie en este momento. + </notification> + <notification name="ResitDeniedByObject"> + '[OBJECT_NAME]' no te permite cambiar de asiento en este momento. + </notification> <notification name="CantCreateObjectRegionFull"> No se puede crear el objeto solicitado. La región está llena. </notification> @@ -4289,6 +4353,9 @@ Prueba a seleccionar un terreno más pequeño. <notification name="CantTransfterMoneyRegionDisabled"> En esta región actualmente no están activadas las transferencias de dinero a los objetos. </notification> + <notification name="DroppedMoneyTransferRequest"> + No se puede efectuar el pago por sobrecarga del sistema. + </notification> <notification name="CantPayNoAgent"> No se ha averiguado a quién se debe pagar. </notification> @@ -4324,4 +4391,8 @@ Prueba a seleccionar un terreno más pequeño. El archivo de historial de chat todavÃa está realizando la operación anterior. Repite la operación dentro de unos minutos o inicia un chat con otra persona. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="OutfitPhotoLoadError"> + [REASON] + <usetemplate name="okbutton" yestext="Aceptar"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/es/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/es/panel_outfits_inventory.xml index 1107e72b549aa7c95f2767d9d104246aafd95e1c..5fff5b07c6946bf6db2391abc341d7e47e3c6901 100644 --- a/indra/newview/skins/default/xui/es/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/es/panel_outfits_inventory.xml @@ -7,6 +7,7 @@ Ponerme Ãtems seleccionados </panel.string> <tab_container name="appearance_tabs"> + <panel label="GALERÃA DE VESTUARIO" name="outfit_gallery_tab"/> <panel label="MIS VESTUARIOS" name="outfitslist_tab"/> <panel label="PUESTO" name="cof_tab"/> </tab_container> diff --git a/indra/newview/skins/default/xui/es/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/es/panel_outfits_wearing.xml index 8cea619bd59b4a0f948e50dab5674ca9aa914818..508267a327ac2ca1091aac84bc3c36f11fc9a94e 100644 --- a/indra/newview/skins/default/xui/es/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/es/panel_outfits_wearing.xml @@ -1,6 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Wearing"> + <panel.string name="no_attachments"> + No tienes puestos anexos. + </panel.string> + <accordion name="wearables_accordion"> + <accordion_tab name="tab_wearables" title="ArtÃculos de vestir"/> + <accordion_tab name="tab_temp_attachments" title="Anexos temporales"/> + </accordion> <panel name="bottom_panel"> - <button name="options_gear_btn" tool_tip="Ver más opciones"/> + <menu_button name="options_gear_btn" tool_tip="Ver más opciones"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml index f34edf149e57319e9d9e8b408751f53b4ae11ad3..c5b27ae766d342b6d5ea352d6e8c40f7017e922f 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Avisarme: </text> - <check_box label="Cuando gaste o consiga L$" name="notify_money_change_checkbox"/> + <check_box label="Cuando gaste L$" name="notify_money_spend_checkbox"/> <check_box label="Cuando mis amigos se conecten o desconecten" name="friends_online_notify_checkbox"/> + <check_box label="Cuando gane L$" name="notify_money_received_checkbox"/> <text name="show_label" width="300"> Mostrar siempre: </text> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml index f7fb8ab70d73fb62ab01a54b6b1a23ad13a5c476..2db4274e44d66de49772ab481556d4271a4c67d4 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> Más calidad </text> + <slider label="Complejidad máxima de avatar:" name="IndirectMaxComplexity" tool_tip="Controla en qué momento un avatar visualmente complejo se dibuja como un "JellyDoll""/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Shaders de la atmósfera" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="Modelo de iluminación avanzado" name="UseLightShaders"/> <button label="Guardar configuración como valor predefinido..." name="PrefSaveButton"/> <button label="Cargar predefinido..." name="PrefLoadButton"/> + min_val="0.125" <button label="Eliminar predefinido..." name="PrefDeleteButton"/> <button label="Restablecer la configuración recomendada" name="Defaults"/> <button label="Configuración avanzada..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml index 4fc973614b3b5bde4b5b1306e8af15f0f98e6e66..0b3ca03bcc23d8279a88b08b2bb6e9fcd66ad6d3 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml @@ -30,6 +30,7 @@ <combo_box.item label="Descargaré e instalaré manualmente las actualizaciones" name="Install_manual"/> </combo_box> <check_box label="Admitir candidatos a la versión comercial a la hora de realizar actualizaciones" name="update_willing_to_test"/> + <check_box label="Mostrar las notas de la versión después de la actualización" name="update_show_release_notes"/> <text name="Proxy Settings:"> Configuración de proxy: </text> diff --git a/indra/newview/skins/default/xui/es/panel_sound_devices.xml b/indra/newview/skins/default/xui/es/panel_sound_devices.xml index 9531b99cc8007adda8705005c0434a609dfe319c..109dcb565a3fff5afcc45a786b7e1318b69678a6 100644 --- a/indra/newview/skins/default/xui/es/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/es/panel_sound_devices.xml @@ -16,9 +16,9 @@ Salida </text> <text name="My volume label"> - Mi volumen: + Volumen de mic.: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Cambia el volumen usando este deslizable"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Cambia el volumen del micrófono con este controlador deslizante"/> <text name="wait_text"> Por favor, espera </text> diff --git a/indra/newview/skins/default/xui/es/panel_status_bar.xml b/indra/newview/skins/default/xui/es/panel_status_bar.xml index 8ea56c52628f9811025f4750017c5be7b759a05b..8aaa236475fee4626c99070a8be2b5e828cfe48b 100644 --- a/indra/newview/skins/default/xui/es/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/es/panel_status_bar.xml @@ -5,7 +5,7 @@ <panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string> <panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string> <panel.string name="buycurrencylabel">[AMT] L$</panel.string> - <panel left="-410" name="balance_bg" width="200"> + <panel left="-431" name="balance_bg" width="200"> <text name="balance" tool_tip="Haz clic para actualizar tu saldo en L$" value="L$??"/> <button label="Comprar L$" name="buyL" tool_tip="Pulsa para comprar más L$"/> <button label="Comprar" name="goShop" tool_tip="Abrir el mercado de Second Life" width="80"/> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index ea6cea060b31996cecebb2a57dd21e4144e817f6..192d32c267496bba7e30d4820c2557001a59016c 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -32,6 +32,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> + <string name="BuildConfig"> + Configuración de constitución [BUILD_CONFIG] + </string> <string name="AboutPosition"> Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1], de [REGION], alojada en <nolink>[HOSTNAME]</nolink> ([HOSTIP]) SLURL: <nolink>[SLURL]</nolink> @@ -49,20 +52,40 @@ Tarjeta gráfica: [GRAPHICS_CARD] <string name="AboutDriver"> Versión de Windows Graphics Driver: [GRAPHICS_DRIVER_VERSION] </string> - <string name="AboutLibs"> + <string name="AboutOGL"> Versión de OpenGL: [OPENGL_VERSION] - -Versión de J2C Decoder: [J2C_VERSION] + </string> + <string name="AboutSettings"> + Tamaño de la ventana: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Ajuste de tamaño de fuente: [FONT_SIZE_ADJUSTMENT]pt +Ajuste de escala de IU: [UI_SCALE] +Distancia de dibujo: [DRAW_DISTANCE]m +Ancho de banda: [NET_BANDWITH]kbit/s +Factor de LOD: [LOD_FACTOR] +Calidad de renderizado: [RENDER_QUALITY] / 7 +Modelo de iluminación avanzado: [GPU_SHADERS] +Memoria de textura: [TEXTURE_MEMORY]MB +Tiempo de creación de VFS (caché): [VFS_TIME] + </string> + <string name="AboutLibs"> + Versión de J2C Decoder: [J2C_VERSION] Versión de Audio Driver: [AUDIO_DRIVER_VERSION] Versión de LLCEFLib/CEF: [LLCEFLIB_VERSION] -Versión del servidor de voz: [VOICE_VERSION] +Versión de LibVLC: [LLCEFLIB_VERSION] +Versión de Voice Server: [VOICE_VERSION] </string> <string name="AboutTraffic"> Paquetes perdidos: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) </string> + <string name="AboutTime"> + [mes, fecha_hora, slt] [dÃa, fecha_hora, slt] [año, fecha_hora, slt] [hora, fecha_hora, slt]:[min, fecha_hora, slt]:[segundo,fecha_hora,slt] + </string> <string name="ErrorFetchingServerReleaseNotesURL"> Error al obtener la URL de las notas de la versión del servidor. </string> + <string name="BuildConfiguration"> + Configuración de constitución + </string> <string name="ProgressRestoring"> Restaurando... </string> @@ -1068,6 +1091,9 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="TeleportYourAgent"> Teleportarte </string> + <string name="ForceSitAvatar"> + Forzar que el avatar se siente + </string> <string name="AgentNameSubst"> (Tú) </string> @@ -1372,6 +1398,9 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="BodyPartsRightLeg"> Pierna der. </string> + <string name="BodyPartsEnhancedSkeleton"> + Esqueleto mejorado + </string> <string name="GraphicsQualityLow"> Bajo </string> @@ -1814,6 +1843,51 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="Avatar Center"> Centro del avatar </string> + <string name="Left Ring Finger"> + Dedo anular izquierdo + </string> + <string name="Right Ring Finger"> + Dedo anular derecho + </string> + <string name="Tail Base"> + Base de la cola + </string> + <string name="Tail Tip"> + Extremo de la cola + </string> + <string name="Left Wing"> + Ala izquierda + </string> + <string name="Right Wing"> + Ala derecha + </string> + <string name="Jaw"> + MandÃbula + </string> + <string name="Alt Left Ear"> + Oreja izquierda alternativa + </string> + <string name="Alt Right Ear"> + Oreja derecha alternativa + </string> + <string name="Alt Left Eye"> + Ojo izquierdo alternativo + </string> + <string name="Alt Right Eye"> + Ojo derecho alternativo + </string> + <string name="Tongue"> + Lengua + </string> + <string name="Groin"> + Ingle + </string> + <string name="Left Hind Foot"> + Pata trasera izquierda + </string> + <string name="Right Hind Foot"> + Pata trasera derecha + </string> <string name="Invalid Attachment"> Punto de colocación no válido </string> @@ -1859,6 +1933,27 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="av_render_anyone"> Es posible que ninguno de los que están próximos pueda renderizarte. </string> + <string name="hud_description_total"> + Tu HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (lo llevas en [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] usa mucha memoria de textura + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] contiene muchas texturas y objetos complicados + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] contiene muchas texturas grandes + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] contiene demasiados objetos + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] contiene demasiadas texturas + </string> <string name="AgeYearsA"> [COUNT] año </string> @@ -2018,6 +2113,9 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="ObjectOutOfRange"> Script (objeto fuera de rango) </string> + <string name="ScriptWasDeleted"> + Script (eliminado del inventario) + </string> <string name="GodToolsObjectOwnedBy"> El objeto [OBJECT] es propiedad de [OWNER] </string> @@ -2203,11 +2301,11 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="ATTACH_BELLY"> Vientre </string> - <string name="ATTACH_RPEC"> - Pecho derecho + <string name="ATTACH_LEFT_PEC"> + Pectoral izquierdo </string> - <string name="ATTACH_LPEC"> - Pecho izquierdo + <string name="ATTACH_RIGHT_PEC"> + Pectoral derecho </string> <string name="ATTACH_HUD_CENTER_2"> HUD: Centro 2 @@ -2239,6 +2337,51 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="ATTACH_AVATAR_CENTER"> Centro del avatar </string> + <string name="ATTACH_LHAND_RING1"> + Dedo anular izquierdo + </string> + <string name="ATTACH_RHAND_RING1"> + Dedo anular derecho + </string> + <string name="ATTACH_TAIL_BASE"> + Base de la cola + </string> + <string name="ATTACH_TAIL_TIP"> + Extremo de la cola + </string> + <string name="ATTACH_LWING"> + Ala izquierda + </string> + <string name="ATTACH_RWING"> + Ala derecha + </string> + <string name="ATTACH_FACE_JAW"> + MandÃbula + </string> + <string name="ATTACH_FACE_LEAR"> + Oreja izquierda alternativa + </string> + <string name="ATTACH_FACE_REAR"> + Oreja derecha alternativa + </string> + <string name="ATTACH_FACE_LEYE"> + Ojo izquierdo alternativo + </string> + <string name="ATTACH_FACE_REYE"> + Ojo derecho alternativo + </string> + <string name="ATTACH_FACE_TONGUE"> + Lengua + </string> + <string name="ATTACH_GROIN"> + Ingle + </string> + <string name="ATTACH_HIND_LFOOT"> + Pata trasera izquierda + </string> + <string name="ATTACH_HIND_RFOOT"> + Pata trasera derecha + </string> <string name="CursorPos"> LÃnea [LINE], Columna [COLUMN] </string> @@ -2543,6 +2686,15 @@ Se esperaba .wav, .tga, .bmp, .jpg, .jpeg, o .bvh <string name="Play Media"> Play/Pausa los media </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=es + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> <string name="MBCmdLineError"> Ha habido un error analizando la lÃnea de comando. Por favor, consulta: http://wiki.secondlife.com/wiki/Client_parameters @@ -4165,6 +4317,12 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE]. <string name="OfflineStatus"> Desconectado/a </string> + <string name="not_online_msg"> + El usuario no está conectado: el mensaje se almacenará para entregárselo más tarde. + </string> + <string name="not_online_inventory"> + El usuario no está conectado: el inventario se ha guardado. + </string> <string name="answered_call"> Han respondido a tu llamada </string> @@ -4288,12 +4446,18 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE]. <string name="paid_you_ldollars"> [NAME] te ha pagado [AMOUNT] L$ [REASON]. </string> + <string name="paid_you_ldollars_gift"> + [NAME] te ha pagado [AMOUNT] L$: [REASON] + </string> <string name="paid_you_ldollars_no_reason"> [NAME] te ha pagado [AMOUNT] L$. </string> <string name="you_paid_ldollars"> Has pagado [AMOUNT] L$ a [NAME] por [REASON]. </string> + <string name="you_paid_ldollars_gift"> + Has pagado [AMOUNT] L$ a [NAME]: [REASON] + </string> <string name="you_paid_ldollars_no_info"> Has pagado[AMOUNT] L$ </string> @@ -4306,6 +4470,9 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE]. <string name="you_paid_failure_ldollars"> No has pagado a [NAME] [AMOUNT] L$ [REASON]. </string> + <string name="you_paid_failure_ldollars_gift"> + No has pagado a [NAME] [AMOUNT] L$: [REASON] + </string> <string name="you_paid_failure_ldollars_no_info"> No has pagado [AMOUNT] L$. </string> @@ -4632,6 +4799,15 @@ Denuncia de infracción <string name="texture_load_dimensions_error"> No se puede subir imágenes mayores de [WIDTH]*[HEIGHT] </string> + <string name="outfit_photo_load_dimensions_error"> + La foto del vestuario puede tener como máx. un tamaño de [WIDTH]*[HEIGHT]. Cambia el tamaño o utiliza otra imagen + </string> + <string name="outfit_photo_select_dimensions_error"> + La foto del vestuario puede tener como máx. un tamaño de [WIDTH]*[HEIGHT]. Selecciona otra textura + </string> + <string name="outfit_photo_verify_dimensions_error"> + No se pueden verificar las dimensiones de la foto. Espera hasta que aparezca el tamaño de la foto en el selector + </string> <string name="words_separator" value=","/> <string name="server_is_down"> Parece que hay algún problema que ha escapado a nuestros controles. @@ -5136,6 +5312,9 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas <string name="Command_Profile_Label"> Perfil </string> + <string name="Command_Report_Abuse_Label"> + Denunciar una infracción + </string> <string name="Command_Search_Label"> Buscar </string> @@ -5226,6 +5405,9 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas <string name="Command_Profile_Tooltip"> Consulta o edita tu perfil </string> + <string name="Command_Report_Abuse_Tooltip"> + Denunciar una infracción + </string> <string name="Command_Search_Tooltip"> Buscar lugares, eventos y personas </string> diff --git a/indra/newview/skins/default/xui/fr/floater_model_preview.xml b/indra/newview/skins/default/xui/fr/floater_model_preview.xml index d3d941ff5c0dde797c454f58e8ff367bac9deef0..4ebc196fd1018a8696dfc816ae653e37ade4a991 100644 --- a/indra/newview/skins/default/xui/fr/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/fr/floater_model_preview.xml @@ -245,6 +245,7 @@ </text> <check_box label="Inclure pondération de la peau :" name="upload_skin"/> <check_box label="Inclure position des articulations :" name="upload_joints"/> + <check_box label="Verrouiller l’échelle si la position des articulations est définie" name="lock_scale_if_joint_position"/> <text name="pelvis_offset_label"> Décalage Z (élever/abaisser l'avatar) : </text> diff --git a/indra/newview/skins/default/xui/fr/floater_pay.xml b/indra/newview/skins/default/xui/fr/floater_pay.xml index bbd20e868cafd16ee5078a233e2ca6da32d25bf5..190a1f53699d34e90b4010ea771644ca6a91ac16 100644 --- a/indra/newview/skins/default/xui/fr/floater_pay.xml +++ b/indra/newview/skins/default/xui/fr/floater_pay.xml @@ -1,9 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Give Money" title=""> - <string name="payee_group">Payer le groupe</string> - <string name="payee_resident">Payer le résident</string> - <text name="paying_text">Vous payez :</text> - <text name="payee_name">Test Name That Is Extremely Long To Check Clipping</text> + <string name="payee_group"> + Payer le groupe + </string> + <string name="payee_resident"> + Payer le résident + </string> + <text name="paying_text"> + Vous payez : + </text> + <text name="payee_name"> + Test Name That Is Extremely Long To Check Clipping + </text> + <text name="payment_message_label"> + Description (facultative) : + </text> <panel label="Rechercher" name="PatternsPanel"> <button label="Payer 1 L$" label_selected="Payer 1 L$" name="fastpay 1"/> <button label="Payer 5 L$" label_selected="Payer 5 L$" name="fastpay 5"/> @@ -11,7 +22,9 @@ <button label="Payer 20 L$" label_selected="Payer 20 L$" name="fastpay 20"/> </panel> <panel label="Rechercher" name="InputPanel"> - <text name="amount text">Autre montant :</text> + <text name="amount text"> + Autre montant : + </text> <button label="Payer" label_selected="Payer" name="pay btn"/> <button label="Annuler" label_selected="Annuler" name="cancel btn"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml index 5c5af022cadd0fef7b78cd5e945f72f97c06b608..42cc2e6dac9a9cc30843a1339abcb79c3ae65902 100644 --- a/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Complexité max. :" name="IndirectMaxComplexity" tool_tip="Contrôle à quel moment un avatar complexe est représenté comme un « jelly doll » (forme de couleur unie)"/> + <slider label="Complexité max. :" name="IndirectMaxComplexity" tool_tip="Contrôle à quel moment un avatar complexe est représenté comme un « JellyDoll »"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/fr/floater_script_queue.xml b/indra/newview/skins/default/xui/fr/floater_script_queue.xml index b9a81654576e639eac7feaf6826d62b5e7203007..15cc182ff9ff1cb5aa4245d3f0f9a0546483aa76 100644 --- a/indra/newview/skins/default/xui/fr/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/fr/floater_script_queue.xml @@ -15,5 +15,11 @@ <floater.string name="NotRunning"> Arrêt </floater.string> + <floater.string name="Timeout"> + Délai : [OBJECT_NAME] + </floater.string> + <floater.string name="LoadingObjInv"> + Chargement de l’inventaire pour : [OBJECT_NAME] + </floater.string> <button label="Fermer" label_selected="Fermer" name="close"/> </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_web_content.xml b/indra/newview/skins/default/xui/fr/floater_web_content.xml index 65dfafe760340f0ab2f71dc9df544bdcd1192168..015396b2dd93d4701bfc95c4815bbf1b0902bdfa 100644 --- a/indra/newview/skins/default/xui/fr/floater_web_content.xml +++ b/indra/newview/skins/default/xui/fr/floater_web_content.xml @@ -10,5 +10,9 @@ <icon name="media_secure_lock_flag" tool_tip="Navigation sécurisée"/> <button name="popexternal" tool_tip="Ouvrir l'URL actuelle dans votre navigateur de bureau"/> </layout_panel> + <layout_panel name="debug_controls"> + <button name="web_test_home_page" tool_tip="Tests Web de la page d’accueil"/> + <button name="VLC Plugin Test" tool_tip="Test vidéo MPEG4"/> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/fr/menu_attachment_other.xml b/indra/newview/skins/default/xui/fr/menu_attachment_other.xml index 20de34250a6e56abd529c3cdbf5b13204aa3f874..ae19e78d54af6836ee7053cb96204bb9b27a0981 100644 --- a/indra/newview/skins/default/xui/fr/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/fr/menu_attachment_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Appeler" name="Call"/> <menu_item_call label="Inviter dans le groupe" name="Invite..."/> + <menu_item_call label="Réinitialiser le squelette" name="Reset Skeleton"/> + <menu_item_call label="Réinitialiser le squelette et les animations" name="Reset Skeleton And Animations"/> <menu_item_call label="Ignorer" name="Avatar Mute"/> <menu_item_call label="Signaler" name="abuse"/> <menu_item_call label="Figer" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/fr/menu_attachment_self.xml b/indra/newview/skins/default/xui/fr/menu_attachment_self.xml index 1ccba0809915c342171cf303b5b2687a7c35fe96..f354cf38966817598505c9bf19f998ca59cafbc3 100644 --- a/indra/newview/skins/default/xui/fr/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/fr/menu_attachment_self.xml @@ -9,6 +9,8 @@ <menu_item_call label="Modifier ma tenue" name="Edit Outfit"/> <menu_item_call label="Modifier ma silhouette" name="Edit My Shape"/> <menu_item_call label="Hauteur de sustentation" name="Hover Height"/> + <menu_item_call label="Réinitialiser le squelette" name="Reset Skeleton"/> + <menu_item_call label="Réinitialiser le squelette et les animations" name="Reset Skeleton And Animations"/> <menu_item_call label="Mes amis" name="Friends..."/> <menu_item_call label="Mes groupes" name="Groups..."/> <menu_item_call label="Mon profil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/fr/menu_avatar_other.xml b/indra/newview/skins/default/xui/fr/menu_avatar_other.xml index d31f205efb2cdd3265fb3f42d9eddf3d6e4220a6..2a0ae386058062ad5e863cb05f9f52c4c713efea 100644 --- a/indra/newview/skins/default/xui/fr/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/fr/menu_avatar_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Appeler" name="Call"/> <menu_item_call label="Inviter dans le groupe" name="Invite..."/> + <menu_item_call label="Réinitialiser le squelette" name="Reset Skeleton"/> + <menu_item_call label="Réinitialiser le squelette et les animations" name="Reset Skeleton And Animations"/> <menu_item_call label="Ignorer" name="Avatar Mute"/> <menu_item_call label="Signaler" name="abuse"/> <menu_item_call label="Figer" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/fr/menu_avatar_self.xml b/indra/newview/skins/default/xui/fr/menu_avatar_self.xml index 1c768a078c82a3c5af2e1a3c1565e37cd38f000e..2d0a17832f5e633686ac47fe9cfdcd279acc8c8e 100644 --- a/indra/newview/skins/default/xui/fr/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/fr/menu_avatar_self.xml @@ -26,6 +26,8 @@ <menu_item_call label="Modifier ma tenue" name="Edit Outfit"/> <menu_item_call label="Modifier ma silhouette" name="Edit My Shape"/> <menu_item_call label="Hauteur de sustentation" name="Hover Height"/> + <menu_item_call label="Réinitialiser le squelette" name="Reset Skeleton"/> + <menu_item_call label="Réinitialiser le squelette et les animations" name="Reset Skeleton And Animations"/> <menu_item_call label="Mes amis" name="Friends..."/> <menu_item_call label="Mes groupes" name="Groups..."/> <menu_item_call label="Mon profil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/fr/menu_login.xml b/indra/newview/skins/default/xui/fr/menu_login.xml index c425e6cee7529a37694fbae6966bf29a6608ed27..7fd68baf6784415a611f400865c069ee2ee614bd 100644 --- a/indra/newview/skins/default/xui/fr/menu_login.xml +++ b/indra/newview/skins/default/xui/fr/menu_login.xml @@ -20,13 +20,12 @@ <menu_item_check label="Afficher le menu de débogage" name="Show Debug Menu"/> <menu label="Débogage" name="Debug"> <menu_item_call label="Afficher les paramètres de débogage" name="Debug Settings"/> - <menu_item_call label="Paramètres de couleurs/interface" name="UI/Color Settings"/> <menu_item_call label="Outil d'aperçu XUI" name="UI Preview Tool"/> <menu label="Tests de l'interface" name="UI Tests"/> <menu_item_call label="Définir la taille de la fenêtre..." name="Set Window Size..."/> <menu_item_call label="Afficher les conditions d'utilisation" name="TOS"/> <menu_item_call label="Afficher le message critique" name="Critical"/> - <menu_item_call label="Test de débogage de la fenêtre flottante du contenu Web" name="Web Content Floater Debug Test"/> + <menu_item_call label="Navigateur de médias" name="Media Browser"/> <menu label="Définir le niveau de connexion" name="Set Logging Level"> <menu_item_check label="Débogage" name="Debug"/> <menu_item_check label="Infos" name="Info"/> diff --git a/indra/newview/skins/default/xui/fr/menu_object_icon.xml b/indra/newview/skins/default/xui/fr/menu_object_icon.xml index 7c949301600b36768db7f7c5b0618d262402defc..5d41ff5103847233ce777520e325edbb288a4da6 100644 --- a/indra/newview/skins/default/xui/fr/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/fr/menu_object_icon.xml @@ -2,6 +2,7 @@ <menu name="Object Icon Menu"> <menu_item_call label="Profil de l'objet..." name="Object Profile"/> <menu_item_call label="Ignorer..." name="Block"/> + <menu_item_call label="Ne plus ignorer" name="Unblock"/> <menu_item_call label="Voir sur la carte" name="show_on_map"/> <menu_item_call label="Me téléporter à l’emplacement de l'objet" name="teleport_to_object"/> </menu> diff --git a/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml b/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml index 21b19eded6327be4027dd8fedf7b676443cb44fb..28ae2f74ad38173083439d771b5b80a0b9eb1a9e 100644 --- a/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml @@ -3,6 +3,10 @@ <menu_item_call label="Porter - Remplacer la tenue actuelle" name="wear"/> <menu_item_call label="Porter - Ajouter à la tenue actuelle" name="wear_add"/> <menu_item_call label="Enlever - Supprimer de la tenue actuelle" name="take_off"/> + <menu_item_call label="Charger la photo (10 L$)" name="upload_photo"/> + <menu_item_call label="Sélectionner une photo" name="select_photo"/> + <menu_item_call label="Prendre une photo" name="take_snapshot"/> + <menu_item_call label="Supprimer la photo" name="remove_photo"/> <menu label="Nouveaux habits" name="New Clothes"> <menu_item_call label="Nouvelle chemise" name="New Shirt"/> <menu_item_call label="Nouveau pantalon" name="New Pants"/> @@ -27,4 +31,5 @@ <menu_item_call label="Réduire tous les dossiers" name="collapse"/> <menu_item_call label="Renommer la tenue" name="rename"/> <menu_item_call label="Supprimer la tenue" name="delete_outfit"/> + <menu_item_check label="Toujours trier les dossiers par nom" name="sort_folders_by_name"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/fr/menu_people_friends_view.xml b/indra/newview/skins/default/xui/fr/menu_people_friends_view.xml index cc81172462f611206f64fd781958e8b8a07dcbe0..45cb646b9a8c047cc2941068ebab344e907f4ec5 100644 --- a/indra/newview/skins/default/xui/fr/menu_people_friends_view.xml +++ b/indra/newview/skins/default/xui/fr/menu_people_friends_view.xml @@ -4,5 +4,6 @@ <menu_item_check label="Trier par statut" name="sort_status"/> <menu_item_check label="Afficher les icônes des résidents" name="view_icons"/> <menu_item_check label="Afficher les droits octroyés" name="view_permissions"/> + <menu_item_check label="Masquer les noms d’utilisateur" name="view_usernames"/> <menu_item_check label="Afficher le journal des conversations..." name="view_conversation"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/fr/menu_people_nearby.xml b/indra/newview/skins/default/xui/fr/menu_people_nearby.xml index 6f7d02ef74305950fa016e32bf76b9bf4da92141..cbc3156a8f8555f2b084f861f86c66ff9dd762a9 100644 --- a/indra/newview/skins/default/xui/fr/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/fr/menu_people_nearby.xml @@ -13,4 +13,6 @@ <menu_item_call label="Partager" name="share"/> <menu_item_call label="Payer" name="pay"/> <menu_item_check label="Ignorer/Ne plus ignorer" name="block_unblock"/> + <menu_item_call label="Figer" name="freeze"/> + <menu_item_call label="Expulser" name="eject"/> </context_menu> diff --git a/indra/newview/skins/default/xui/fr/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/fr/menu_people_nearby_view.xml index 086002dce5e7f3767889a8761e05990744644ab2..9da915fcc57064f10194bf72bd37c39c24509466 100644 --- a/indra/newview/skins/default/xui/fr/menu_people_nearby_view.xml +++ b/indra/newview/skins/default/xui/fr/menu_people_nearby_view.xml @@ -5,4 +5,5 @@ <menu_item_check label="Trier par distance" name="sort_distance"/> <menu_item_check label="Afficher les icônes des résidents" name="view_icons"/> <menu_item_check label="Afficher la carte" name="view_map"/> + <menu_item_check label="Masquer les noms d’utilisateur" name="view_usernames"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/fr/menu_url_objectim.xml b/indra/newview/skins/default/xui/fr/menu_url_objectim.xml index 5d745ef5f899a3f4d903340ae9f5c87624e060d7..95310dd1f10b1073e0d1a9a762231f315bbab954 100644 --- a/indra/newview/skins/default/xui/fr/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/fr/menu_url_objectim.xml @@ -2,6 +2,7 @@ <context_menu name="Url Popup"> <menu_item_call label="Profil de l'objet…" name="show_object"/> <menu_item_call label="Ignorer…" name="block_object"/> + <menu_item_call label="Ne plus ignorer" name="unblock_object"/> <menu_item_call label="Voir sur la carte" name="show_on_map"/> <menu_item_call label="Me téléporter à l'emplacement de l'objet" name="teleport_to_object"/> <menu_item_call label="Copier le nom de l'objet dans le presse-papiers" name="url_copy_label"/> diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index 9b1f195391eba2626faf195f32b94969b09dd045..d40e979d08e4de4ffde64977caf0b60a387d5f14 100644 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Ne pas déranger" name="Do Not Disturb"/> </menu> <menu_item_call label="Acheter des L$..." name="Buy and Sell L$"/> - <menu_item_call label="Boîte d'envoi vendeur..." name="MerchantOutbox"/> <menu_item_call label="Annonces de Place du marché..." name="MarketplaceListings"/> <menu_item_call label="Page d'accueil du compte..." name="Manage My Account"> <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=fr"/> @@ -114,11 +113,11 @@ <menu_item_call label="Lien" name="Link"/> <menu_item_call label="Annuler le lien" name="Unlink"/> <menu_item_check label="Modifier les parties liées" name="Edit Linked Parts"/> - <menu label="Sélectionner les parties liées" name="Select Linked Parts"> - <menu_item_call label="Sélectionner la partie suivante" name="Select Next Part"/> - <menu_item_call label="Sélectionner la partie précédente" name="Select Previous Part"/> - <menu_item_call label="Inclure la partie suivante" name="Include Next Part"/> - <menu_item_call label="Inclure la partie précédente" name="Include Previous Part"/> + <menu label="Sélectionner des éléments" name="Select Elements"> + <menu_item_call label="Sélectionner la partie suivante ou le visage" name="Select Next Part or Face"/> + <menu_item_call label="Sélectionner la partie précédente ou le visage" name="Select Previous Part or Face"/> + <menu_item_call label="Inclure la partie suivante ou le visage" name="Include Next Part or Face"/> + <menu_item_call label="Inclure la partie précédente ou le visage" name="Include Previous Part or Face"/> </menu> <menu_item_call label="Groupes de liens..." name="pathfinding_linkset_menu_item"/> <menu_item_call label="Point central sur la sélection" name="Focus on Selection"/> @@ -369,8 +368,7 @@ <menu_item_call label="Vidage de cache d'objet de la région" name="Dump Region Object Cache"/> </menu> <menu label="Interface" name="UI"> - <menu_item_call label="Test du navigateur de médias" name="Web Browser Test"/> - <menu_item_call label="Navigateur du contenu Web" name="Web Content Browser"/> + <menu_item_call label="Navigateur de médias" name="Media Browser"/> <menu_item_call label="Dump SelectMgr" name="Dump SelectMgr"/> <menu_item_call label="Dump inventaire" name="Dump Inventory"/> <menu_item_call label="Dump Timers" name="Dump Timers"/> @@ -421,6 +419,7 @@ <menu_item_check label="Désactiver LOD" name="Disable LOD"/> <menu_item_check label="Debogage Character Vis" name="Debug Character Vis"/> <menu_item_check label="Afficher le squelette de collision" name="Show Collision Skeleton"/> + <menu_item_check label="Voir les os" name="Show Bones"/> <menu_item_check label="Afficher la cible de l'avatar" name="Display Agent Target"/> <menu_item_call label="Dump Attachments" name="Dump Attachments"/> <menu_item_call label="Débogage des textures des avatars" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml b/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml index 4d884455069e959664bba9e49e8c489b60069115..5a7193a7cc9366a7811065065a0508e89bb7e1d8 100644 --- a/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml @@ -3,4 +3,6 @@ <menu_item_call label="Enlever" name="take_off"/> <menu_item_call label="Détacher" name="detach"/> <menu_item_call label="Modifier la tenue" name="edit"/> + <menu_item_call label="Modifier" name="edit_item"/> + <menu_item_call label="Afficher l’original" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/fr/mime_types.xml b/indra/newview/skins/default/xui/fr/mime_types.xml index 322887fb76a6c59c32ca3acfac36612b1da5626a..15b1dc5a23a6fe9828fc522396e6942a26b609f8 100644 --- a/indra/newview/skins/default/xui/fr/mime_types.xml +++ b/indra/newview/skins/default/xui/fr/mime_types.xml @@ -22,14 +22,6 @@ Jouer le film </playtip> </widgetset> - <widgetset name="none"> - <label name="none_label"> - Aucun contenu - </label> - <tooltip name="none_tooltip"> - Aucun média ici - </tooltip> - </widgetset> <widgetset name="image"> <label name="image_label"> Image @@ -52,11 +44,24 @@ Jouer le contenu audio qui se trouve ici </playtip> </widgetset> + <widgetset name="none"> + <label name="none_label"> + Aucun contenu + </label> + <tooltip name="none_tooltip"> + Aucun média ici + </tooltip> + </widgetset> <scheme name="rtsp"> <label name="rtsp_label"> Flux en temps réel </label> </scheme> + <scheme name="libvlc"> + <label name="libvlc_label"> + Médias pris en charge par LibVLC + </label> + </scheme> <mimetype name="blank"> <label name="blank_label"> - Aucun - @@ -127,11 +132,6 @@ Macromedia Director </label> </mimetype> - <mimetype name="application/x-shockwave-flash"> - <label name="application/x-shockwave-flash_label"> - Flash - </label> - </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> Audio (MIDI) @@ -207,6 +207,11 @@ Film (MP4) </label> </mimetype> + <mimetype name="application/octet-stream"> + <label name="video/octet-stream"> + Film + </label> + </mimetype> <mimetype name="video/quicktime"> <label name="video/quicktime_label"> Film (Quicktime) diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 080ea741c5ac0071a97f6ec845bf69530cf6b106..b7efaad37627b8481c5a7e559f8b35c6bc34e172 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -329,6 +329,9 @@ Si vous ne voulez plus que ce rôle dispose de ces pouvoirs, désactivez-les imm Vous allez bannir [COUNT] membres du groupe. <usetemplate ignoretext="Confirmer le bannissement de plusieurs membres du groupe" name="okcancelignore" notext="Annuler" yestext="Bannir"/> </notification> + <notification name="GroupBanUserOnBanlist"> + Il est possible qu’une invitation n’ait pas été envoyée à certains résidents, car ils sont bannis du groupe. + </notification> <notification name="AttachmentDrop"> Vous êtes sur le point d'abandonner l'élément joint. Voulez-vous vraiment continuer ? @@ -456,6 +459,12 @@ Pour ne placer le média que sur une seule face, choisissez Sélectionner une fa <notification name="ErrorEncodingSnapshot"> Erreur d'encodage de la photo. </notification> + <notification name="ErrorPhotoCannotAfford"> + Il vous faut [COST] L$ pour enregistrer une photo dans votre inventaire. Vous pouvez acheter des L$ ou enregistrer la photo sur votre ordinateur. + </notification> + <notification name="ErrorTextureCannotAfford"> + Il vous faut [COST] L$ pour enregistrer une texture dans votre inventaire. Vous pouvez acheter des L$ ou enregistrer la photo sur votre ordinateur. + </notification> <notification name="ErrorUploadingPostcard"> Une erreur est survenue lors du chargement du script compilé, suite au problème suivant : [REASON] </notification> @@ -479,6 +488,9 @@ La limite de [MAX_ATTACHMENTS] objets joints a été dépassée. Veuillez commen <notification name="CannotWearInfoNotComplete"> Vous ne pouvez pas porter cet article car il n'a pas encore été chargé. Veuillez réessayer dans une minute. </notification> + <notification name="MustEnterPasswordToLogIn"> + Veuillez saisir votre mot de passe pour vous connecter. + </notification> <notification name="MustHaveAccountToLogIn"> Zut ! Vous avez oublié de fournir certaines informations. Vous devez saisir le nom d'utilisateur de votre avatar. @@ -547,6 +559,9 @@ Remarque : cela videra le cache. <notification name="ChangeConnectionPort"> Les paramètres du port prendront effet après le redémarrage de [APP_NAME]. </notification> + <notification name="ChangeDeferredDebugSetting"> + Le changement de paramètre de débogage sera effectué au redémarrage de [APP_NAME]. + </notification> <notification name="ChangeSkin"> Le nouveau thème apparaîtra après le redémarrage de [APP_NAME]. </notification> @@ -568,6 +583,10 @@ Remarque : cela videra le cache. Supprimer la note ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> + <notification name="LoadPreviousReportScreenshot"> + Voulez-vous utiliser la capture d’écran précédente pour votre rapport ? + <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> + </notification> <notification name="GestureSaveFailedTooManySteps"> L'enregistrement du geste a échoué. Il y a trop d'étapes dans ce geste. @@ -628,30 +647,12 @@ Consulter [_URL] pour en savoir plus ? </url> <usetemplate ignoretext="Mon matériel n'est pas pris en charge" name="okcancelignore" notext="Non" yestext="Oui"/> </notification> - <notification name="IntelOldDriver"> - Il existe probablement un pilote plus récent pour votre puce graphique. La mise à jour des pilotes graphiques est susceptible d'améliorer considérablement les performances. - - Visiter la page [_URL] pour rechercher d'éventuelles mises à jour de pilotes ? - <url name="url"> - http://www.intel.com/p/fr_FR/support/detect/graphics - </url> - <usetemplate ignoretext="Mon pilote graphique est obsolète." name="okcancelignore" notext="Non" yestext="Oui"/> - </notification> - <notification name="AMDOldDriver"> - Il existe probablement un pilote plus récent pour votre puce graphique. La mise à jour des pilotes graphiques est susceptible d'améliorer considérablement les performances. - - Visiter la page [_URL] pour rechercher d'éventuelles mises à jour de pilotes ? - <url name="url"> - http://support.amd.com/us/Pages/AMDSupportHub.aspx - </url> - <usetemplate ignoretext="Mon pilote graphique est obsolète." name="okcancelignore" notext="Non" yestext="Oui"/> - </notification> - <notification name="NVIDIAOldDriver"> - Il existe probablement un pilote plus récent pour votre puce graphique. La mise à jour des pilotes graphiques est susceptible d'améliorer considérablement les performances. + <notification name="OldGPUDriver"> + Il existe probablement un pilote plus récent pour votre puce graphique. La mise à jour des pilotes graphiques est susceptible d’améliorer considérablement les performances. - Visiter la page [_URL] pour rechercher d'éventuelles mises à jour de pilotes ? + Visiter la page [URL] pour rechercher d’éventuelles mises à jour de pilotes ? <url name="url"> - http://www.nvidia.com/Download/index.aspx?lang=fr + [URL] </url> <usetemplate ignoretext="Mon pilote graphique est obsolète." name="okcancelignore" notext="Non" yestext="Oui"/> </notification> @@ -742,6 +743,9 @@ Aller sur [_URL] pour obtenir des informations sur l'achat de L$ ? </url> <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> + <notification name="MuteLimitReached"> + Impossible d’ajouter une nouvelle entrée à la liste des ignorés car vous avez atteint la limite de [MUTE_LIMIT] entrées. + </notification> <notification name="UnableToLinkObjects"> Impossible de lier ces [COUNT] objets. Vous pouvez lier un maximum de [MAX] objets. @@ -1361,12 +1365,18 @@ Vous pouvez utiliser [SECOND_LIFE] normalement, les autres résidents vous voien <ignore name="ignore" text="Vos habits prennent du temps à télécharger"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - Votre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexité visuelle] est [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + Votre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexité de l'avatar] est [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="M'avertir si la complexité de l'avatar est trop élevée" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - Votre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexité visuelle] est [AGENT_COMPLEXITY]. + Votre [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexité de l'avatar] est [AGENT_COMPLEXITY]. + <usetemplate ignoretext="M’avertir quand la complexité de mon avatar change" name="notifyignore"/> + </notification> + <notification name="HUDComplexityWarning"> + [HUD_REASON], cela risque d’avoir un impact négatif sur votre performance. + <usetemplate ignoretext="M’avertir quand la complexité de mon HUD est trop élevée" name="notifyignore"/> </notification> <notification name="FirstRun"> L'installation de [APP_NAME] est terminée. @@ -1459,6 +1469,10 @@ Veuillez ne sélectionner qu'un seul objet. Téléporter tous les résidents de cette région chez eux ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> + <notification name="ChangeObjectBonusFactor"> + Si vous réduisez le bonus objets après que des constructions ont été établies dans une région, certains objets risquent d’être renvoyés ou supprimés. Voulez-vous vraiment modifier le bonus objets ? + <usetemplate ignoretext="Confirmer la modification du facteur Bonus objets" name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> <notification name="EstateObjectReturn"> Etes-vous certain de vouloir renvoyer les objets appartenant à [USER_NAME] ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> @@ -1483,6 +1497,10 @@ suivant votre vitesse de connexion. Etes-vous sûr(e) de vouloir figer le relief actuel, en faire le point central des limites d'élévation/abaissement de relief et la valeur par défaut du bouton Annuler modification ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + Vous vous apprêtez à utiliser des valeurs plus élevées que les limites d'élévation supérieures. Continuer ? + <usetemplate canceltext="Ne pas demander" name="yesnocancelbuttons" notext="Annuler" yestext="OK"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Vous ne pouvez pas autoriser plus de [MAX_AGENTS] résidents. </notification> @@ -1503,6 +1521,9 @@ Dépasse la limite fixée à [MAX_AGENTS] [LIST_TYPE] de [NUM_EXCESS]. <notification name="OwnerCanNotBeDenied"> Impossible d'ajouter le propriétaire du domaine à la liste des résidents bannis. </notification> + <notification name="ProblemAddingEstateManagerBanned"> + Impossible d’ajouter un résident banni à la liste des gérants de domaine. + </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> Impossible de changer d'apparence jusqu'à ce que les habits et la silhouette soient chargés. </notification> @@ -1677,6 +1698,10 @@ Si vous êtes impatients de découvrir les dernières fonctionnalités et correc Voulez-vous ouvrir votre navigateur web système pour afficher ce contenu ? <usetemplate ignoretext="Ouvrir mon navigateur pour consulter une page web" name="okcancelignore" notext="Annuler" yestext="OK"/> </notification> + <notification name="SystemUIScaleFactorChanged"> + Le facteur de taille de l’interface système a changé depuis la dernière exécution. Voulez-vous ouvrir la page des paramètres d’ajustement de la taille de l’interface ? + <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> + </notification> <notification name="WebLaunchJoinNow"> Accéder à votre [http://secondlife.com/account/ Page d'accueil] pour gérer votre compte ? <usetemplate ignoretext="Lancer mon navigateur pour gérer mon compte" name="okcancelignore" notext="Annuler" yestext="OK"/> @@ -1716,16 +1741,15 @@ Si vous êtes impatients de découvrir les dernières fonctionnalités et correc Quitter le groupe ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> + <notification name="GroupDepart"> + Vous avez quitté le groupe « [group_name] ». + </notification> <notification name="OwnerCannotLeaveGroup"> Impossible de quitter le groupe. Vous ne pouvez pas quitter le groupe car vous en êtes le dernier propriétaire. Vous devez d'abord affecter le rôle de propriétaire à un autre membre. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="GroupDepartError"> - Impossible de quitter le groupe : [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Vous avez quitté le groupe [group_name]. + Impossible de quitter le groupe. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="ConfirmKick"> @@ -2127,6 +2151,10 @@ Cette action modifiera des milliers de régions et sera difficile à digérer po Vous avez sélectionné trop de prims. Veuillez sélectionner au maximum [MAX_PRIM_COUNT] prims et réessayer. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="TooManyScriptsSelected"> + Trop de scripts dans les objets sélectionnés. Sélectionnez moins d’objets et réessayez. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="ProblemImportingEstateCovenant"> Problème lors de l'importation du règlement du domaine. <usetemplate name="okbutton" yestext="OK"/> @@ -2295,6 +2323,10 @@ Déplacer les objets de l'inventaire ? Échec de paiement : objet introuvable. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="PaymentBlockedButtonMismatch"> + Paiement interrompu : le prix payé ne correspond à aucun des boutons de paiement pour cet objet. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="OpenObjectCannotCopy"> Vous n'êtes autorisé à copier aucun élément dans cet objet. </notification> @@ -2330,6 +2362,12 @@ Vous ne pouvez pas l'annuler. C’est une vaste sélection avec des groupes de liens. Si vous annulez les liens, vous risquez de ne pas pouvoir les rétablir. Vous devriez peut-être faire des copies des groupes de liens dans votre inventaire par mesure de précaution. <usetemplate ignoretext="Confirmer l’annulation des liens d’un groupe de liens" name="okcancelignore" notext="Annuler" yestext="Annuler le lien"/> </notification> + <notification name="HelpReportAbuseConfirm"> + Nous vous remercions d’avoir pris le temps de nous signaler ce problème. +Nous lirons votre rapport pour identifier toute violation potentielle et prendrons +les mesures nécessaires. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="HelpReportAbuseSelectCategory"> Veuillez choisir une catégorie pour ce rapport d'infraction. Le choix d'une catégorie nous permet de traiter les rapports d'infraction plus rapidement. @@ -2400,6 +2438,10 @@ Voulez-vous désactiver Ne pas déranger avant de terminer cette transaction ? Êtes-vous certain de vouloir supprimer le contenu de votre corbeille de manière permanente ? <usetemplate ignoretext="Confirmer avant de vider la corbeille" name="okcancelignore" notext="Annuler" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + Votre corbeille déborde. Cela risque de provoquer des problèmes lors de la connexion. + <usetemplate name="okcancelbuttons" notext="Je viderai la corbeille plus tard" yestext="Vider la corbeille"/> + </notification> <notification name="ConfirmClearBrowserCache"> Êtes-vous certain de vouloir supprimer l'historique de vos visites et recherches ? <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> @@ -2755,6 +2797,10 @@ Vous ne pouvez pas voler ici. <notification name="PathfindingDirty"> Des modifications de recherche de chemin sont en attente concernant cette région. Si vous disposez de droits de construction, vous pouvez la figer de nouveau en cliquant sur le bouton Refiger la région. </notification> + <notification name="PathfindingDirtyRebake"> + Des modifications de recherche de chemin sont en attente concernant cette région. Si vous disposez de droits de construction, vous pouvez la figer de nouveau en cliquant sur le bouton Refiger la région. + <usetemplate name="okbutton" yestext="Refiger la région"/> + </notification> <notification name="DynamicPathfindingDisabled"> La recherche de chemin dynamique n'est pas activée dans cette région. Il se peut que les objets scriptés utilisant des appels LSL de recherche de chemin ne fonctionnent pas comme prévu pour cette région. </notification> @@ -2984,11 +3030,11 @@ Si vous restez dans cette région, vous serez déconnecté(e). Si vous restez dans cette région, vous serez déconnecté(e). </notification> <notification name="LoadWebPage"> - Charger la page Web [URL] ? + Charger la page Web [URL] ? [MESSAGE] -Venant de l'objet : <nolink>[OBJECTNAME]</nolink>, propriétaire : [NAME_SLURL] +Venant de l'objet : <nolink>[OBJECTNAME]</nolink>, propriétaire : [NAME_SLURL] <form name="form"> <button name="Gotopage" text="Charger"/> <button name="Cancel" text="Annuler"/> @@ -3257,6 +3303,12 @@ Elles vont être bloquées pendant quelques secondes pour votre sécurité. <notification name="AttachmentSaved"> L'élément joint a été sauvegardé. </notification> + <notification name="AppearanceToXMLSaved"> + L'apparence a été enregistrée en XML vers [PATH] + </notification> + <notification name="AppearanceToXMLFailed"> + Échec de l’enregistrement de l’apparence au format XML. + </notification> <notification name="PresetNotSaved"> Erreur d’enregistrement du préréglage [NAME]. </notification> @@ -3471,13 +3523,6 @@ Cliquez sur un point dans le monde et faites glisser votre souris pour faire tou <notification name="ForceQuitDueToLowMemory"> Mémoire insuffisante : fermeture de SL dans 30 secondes. </notification> - <notification name="PopupAttempt"> - Impossible d'ouvrir une fenêtre popup. - <form name="form"> - <ignore name="ignore" text="Activer toutes les fenêtres popup"/> - <button name="open" text="Ouvrir la fenêtre popup"/> - </form> - </notification> <notification name="SOCKS_NOT_PERMITTED"> Le proxy SOCKS 5 "[HOST]:[PORT]" a refusé la connexion, non autorisée par le jeu de règles défini. <usetemplate name="okbutton" yestext="OK"/> @@ -3851,6 +3896,9 @@ Veuillez réessayer dans une minute. Impossible de déplacer [OBJECT_NAME] jusqu'à [OBJ_POSITION] dans la région [REGION_NAME] car il n'y a pas suffisamment de ressources pour cet objet sur cette parcelle. </notification> + <notification name="NoParcelPermsNoObject"> + La copie a échoué car vous n’avez pas accès à cette parcelle. + </notification> <notification name="CantMoveObjectRegionVersion"> Impossible de déplacer [OBJECT_NAME] jusqu'à [OBJ_POSITION] dans la région [REGION_NAME] car l'autre région exécute une version plus ancienne qui ne prend pas en charge la réception de cet objet via le passage à une autre région. @@ -3866,6 +3914,10 @@ Veuillez réessayer dans une minute. <notification name="NoPermModifyObject"> Vous n'êtes pas autorisé à modifier cet objet. </notification> + <notification name="TooMuchObjectInventorySelected"> + Trop d’objets avec un inventaire volumineux sont sélectionnés. Sélectionnez moins d’objets et réessayez. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="CantEnablePhysObjContributesToNav"> Impossible d'activer les propriétés physiques pour un objet qui contribue au maillage de navigation. </notification> @@ -3902,6 +3954,12 @@ Veuillez réessayer dans une minute. <notification name="CantSaveModifyAttachment"> Impossible d'enregistrer dans le contenu des objets : cela modifierait les droits d'attache. </notification> + <notification name="AttachmentHasTooMuchInventory"> + Vos éléments attachés contiennent trop d’articles d’inventaire, impossible d’en ajouter plus. + </notification> + <notification name="IllegalAttachment"> + La pièce jointe a demandé un point non existant sur l'avatar. Il a été fixé sur la poitrine. + </notification> <notification name="TooManyScripts"> Trop de scripts. </notification> @@ -3994,6 +4052,12 @@ Veuillez réessayer dans une minute. <notification name="TeleportedByObjectUnknownUser"> Vous avez été téléporté par l'objet [OBJECT_NAME] appartenant à un utilisateur inconnu. </notification> + <notification name="StandDeniedByObject"> + [OBJECT_NAME] ne vous permet pas de vous tenir debout actuellement. + </notification> + <notification name="ResitDeniedByObject"> + « [OBJECT_NAME] » ne vous permet pas de changer de place actuellement. + </notification> <notification name="CantCreateObjectRegionFull"> Création de l'objet demandé impossible. La région est pleine. </notification> @@ -4290,6 +4354,9 @@ Veuillez sélectionner un terrain plus petit. <notification name="CantTransfterMoneyRegionDisabled"> Les transferts d'argent aux objets sont actuellement désactivés dans cette région. </notification> + <notification name="DroppedMoneyTransferRequest"> + Impossible d’effectuer le paiement à cause de la charge système. + </notification> <notification name="CantPayNoAgent"> Impossible de savoir qui payer. </notification> @@ -4325,4 +4392,8 @@ Veuillez sélectionner un terrain plus petit. Le fichier d'historique des chats est occupé à traiter l'opération précédente. Réessayez dans quelques minutes ou choisissez une autre personne pour le chat. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="OutfitPhotoLoadError"> + [REASON] + <usetemplate name="okbutton" yestext="OK"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/fr/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/fr/panel_outfits_inventory.xml index 1bc553c8c0fe69fa62c170eb6f7f0b4f0dfd8ba9..05c689dd3443d53e7aed0a82a7963ce660940dfe 100644 --- a/indra/newview/skins/default/xui/fr/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/fr/panel_outfits_inventory.xml @@ -7,6 +7,7 @@ Porter les articles sélectionnés </panel.string> <tab_container name="appearance_tabs"> + <panel label="GALERIE DES TENUES" name="outfit_gallery_tab"/> <panel label="MES TENUES" name="outfitslist_tab"/> <panel label="PORTÉ" name="cof_tab"/> </tab_container> diff --git a/indra/newview/skins/default/xui/fr/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/fr/panel_outfits_wearing.xml index 874bab2daa4c5ae3beee41f37486aad936be82e6..1752f9dfdf67bdf059f38986f0cc6a02035e5621 100644 --- a/indra/newview/skins/default/xui/fr/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/fr/panel_outfits_wearing.xml @@ -1,6 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Wearing"> + <panel.string name="no_attachments"> + Aucun élément attaché porté. + </panel.string> + <accordion name="wearables_accordion"> + <accordion_tab name="tab_wearables" title="Articles à porter"/> + <accordion_tab name="tab_temp_attachments" title="Éléments attachés temporaires"/> + </accordion> <panel name="bottom_panel"> - <button name="options_gear_btn" tool_tip="Afficher d'autres options"/> + <menu_button name="options_gear_btn" tool_tip="Afficher d'autres options"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml index 901a92ed1bb4efbe2eb7ad4ce2c2f01f39d36116..85cd958f498625e2cb0ebb4bd6c5fc5e466a77b9 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Me prévenir : </text> - <check_box label="Quand je dépense ou que je reçois des L$" name="notify_money_change_checkbox"/> + <check_box label="Quand je dépense des L$" name="notify_money_spend_checkbox"/> <check_box label="Quand mes amis se connectent ou se déconnectent" name="friends_online_notify_checkbox"/> + <check_box label="Quand je reçois des L$" name="notify_money_received_checkbox"/> <text name="show_label"> Toujours afficher : </text> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml index 01d89f03f881b8b3ad7abe9d35fb07a37bbea497..60cdd5df413ef8417d4f0e26a3d5bce2582f22d9 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> Meilleure </text> + <slider label="Complexité max. de l'avatar :" name="IndirectMaxComplexity" tool_tip="Contrôle à quel moment un avatar complexe est représenté comme un « JellyDoll »"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Effets atmosphériques" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="Modèle d’éclairage avancé" name="UseLightShaders"/> <button label="Enregistrer les paramètres comme préréglage..." name="PrefSaveButton"/> <button label="Charger un préréglage..." name="PrefLoadButton"/> + min_val="0,125" <button label="Supprimer un préréglage..." name="PrefDeleteButton"/> <button label="Réinitialiser les paramètres recommandés" name="Defaults"/> <button label="Paramètres avancés" name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml b/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml index bd21f9782d60c2a0cbd1b6ab390ad80a0437de8d..3b819b40c80a4fbb182e79cdb83b3bb84dd0decd 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml @@ -30,6 +30,7 @@ <combo_box.item label="Je téléchargerai et installerai les mises à jour manuellement" name="Install_manual"/> </combo_box> <check_box label="Accepte de passer aux versions avant sortie officielle" name="update_willing_to_test"/> + <check_box label="Afficher les notes de version après la mise à jour" name="update_show_release_notes"/> <text name="Proxy Settings:"> Paramètres de proxy : </text> diff --git a/indra/newview/skins/default/xui/fr/panel_sound_devices.xml b/indra/newview/skins/default/xui/fr/panel_sound_devices.xml index 460b269f7ca4e9c47b57b259010698625f9aad41..720aaaf3e068ebc6a75996af6a968f542ce2606c 100644 --- a/indra/newview/skins/default/xui/fr/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/fr/panel_sound_devices.xml @@ -16,9 +16,9 @@ Sortie </text> <text name="My volume label"> - Mon volume : + Volume du micro : </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Régler le volume avec le curseur."/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Régler le volume du micro avec le curseur."/> <text name="wait_text"> Veuillez patienter </text> diff --git a/indra/newview/skins/default/xui/fr/panel_status_bar.xml b/indra/newview/skins/default/xui/fr/panel_status_bar.xml index e2f05a525e53840ceff92fb4d8c99720c5fe19bd..fef0379c2ceccbdbb31792f5c61366decc521597 100644 --- a/indra/newview/skins/default/xui/fr/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/fr/panel_status_bar.xml @@ -5,7 +5,7 @@ <panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string> <panel.string name="timeTooltip">[weekday, datetime, slt] [sday, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string> <panel.string name="buycurrencylabel">[AMT] L$</panel.string> - <panel left="-405" name="balance_bg" width="195"> + <panel left="-426" name="balance_bg" width="195"> <text name="balance" tool_tip="Cliquer sur ce bouton pour actualiser votre solde en L$." value="L$ ??"/> <button label="Acheter L$" name="buyL" tool_tip="Cliquer pour acheter plus de L$."/> <button label="Achats" name="goShop" tool_tip="Ouvrir la Place du marché Second Life." width="75"/> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index ae091aba3933508a81bed0f20e2b6d4fff5f5d23..40a41b93abb4844b71ef92a7f2a05d3f2df2b6e3 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -41,6 +41,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [Notes de version]] </string> + <string name="BuildConfig"> + Configuration de la construction [BUILD_CONFIG] + </string> <string name="AboutPosition"> Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à <nolink>[HOSTNAME]</nolink> ([HOSTIP]) SLURL : <nolink>[SLURL]</nolink> @@ -58,20 +61,40 @@ Carte graphique : [GRAPHICS_CARD] <string name="AboutDriver"> Version Windows Graphics Driver : [GRAPHICS_DRIVER_VERSION] </string> - <string name="AboutLibs"> + <string name="AboutOGL"> Version OpenGL : [OPENGL_VERSION] - -Version J2C Decoder : [J2C_VERSION] + </string> + <string name="AboutSettings"> + Taille de la fenêtre : [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Ajustement de la taille de la police : [FONT_SIZE_ADJUSTMENT] pts +Échelle de l’interface : [UI_SCALE] +Limite d’affichage : [DRAW_DISTANCE] m +Bande passante : [NET_BANDWITH] kbit/s +Facteur LOD (niveau de détail) : [LOD_FACTOR] +Qualité de rendu : [RENDER_QUALITY] / 7 +Modèle d’éclairage avancé : [GPU_SHADERS] +Mémoire textures : [TEXTURE_MEMORY] Mo +Durée de création VFS (cache) : [VFS_TIME] + </string> + <string name="AboutLibs"> + Version J2C Decoder : [J2C_VERSION] Version Audio Driver : [AUDIO_DRIVER_VERSION] Version LLCEFLib/CEF : [LLCEFLIB_VERSION] +Version LibVLC : [LIBVLC_VERSION] Version serveur vocal : [VOICE_VERSION] </string> <string name="AboutTraffic"> Paquets perdus : [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> <string name="ErrorFetchingServerReleaseNotesURL"> Erreur lors de la récupération de l'URL des notes de version du serveur. </string> + <string name="BuildConfiguration"> + Configuration de la construction + </string> <string name="ProgressRestoring"> Restauration... </string> @@ -1083,6 +1106,9 @@ Veuillez réessayer de vous connecter dans une minute. <string name="TeleportYourAgent"> Vous téléporter </string> + <string name="ForceSitAvatar"> + Forcez votre avatar à s’asseoir + </string> <string name="NotConnected"> Pas connecté(e) </string> @@ -1390,6 +1416,9 @@ Veuillez réessayer de vous connecter dans une minute. <string name="BodyPartsRightLeg"> Jambe droite </string> + <string name="BodyPartsEnhancedSkeleton"> + Squelette amélioré + </string> <string name="GraphicsQualityLow"> Faible </string> @@ -1838,6 +1867,51 @@ Veuillez réessayer de vous connecter dans une minute. <string name="Avatar Center"> Centre de l'avatar </string> + <string name="Left Ring Finger"> + Annulaire gauche + </string> + <string name="Right Ring Finger"> + Annulaire droit + </string> + <string name="Tail Base"> + Base de la queue + </string> + <string name="Tail Tip"> + Bout de la queue + </string> + <string name="Left Wing"> + Aile gauche + </string> + <string name="Right Wing"> + Aile droite + </string> + <string name="Jaw"> + Mâchoire + </string> + <string name="Alt Left Ear"> + Oreille gauche différente + </string> + <string name="Alt Right Ear"> + Oreille droite différente + </string> + <string name="Alt Left Eye"> + Å’il gauche différent + </string> + <string name="Alt Right Eye"> + Å’il droit différent + </string> + <string name="Tongue"> + Langue + </string> + <string name="Groin"> + Aine + </string> + <string name="Left Hind Foot"> + Pied arrière gauche + </string> + <string name="Right Hind Foot"> + Pied arrière droit + </string> <string name="Invalid Attachment"> Point d'attache non valide </string> @@ -1883,6 +1957,27 @@ Veuillez réessayer de vous connecter dans une minute. <string name="av_render_anyone"> Vous risquez de n’être rendu par aucune des personnes qui vous entourent. </string> + <string name="hud_description_total"> + Votre HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (porté sur [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] utilise beaucoup de mémoire textures + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] contient beaucoup de textures et d’objets volumineux + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] contient beaucoup de textures volumineuses + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] contient trop d’objets + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] contient trop de textures + </string> <string name="AgeYearsA"> [COUNT] an </string> @@ -2042,6 +2137,9 @@ Veuillez réessayer de vous connecter dans une minute. <string name="ObjectOutOfRange"> Script (objet hors de portée) </string> + <string name="ScriptWasDeleted"> + Script (supprimé de l’inventaire) + </string> <string name="GodToolsObjectOwnedBy"> Objet [OBJECT] appartenant à [OWNER] </string> @@ -2227,12 +2325,12 @@ Veuillez réessayer de vous connecter dans une minute. <string name="ATTACH_BELLY"> Ventre </string> - <string name="ATTACH_RPEC"> - Pectoral droit - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Pectoral gauche </string> + <string name="ATTACH_RIGHT_PEC"> + Pectoral droit + </string> <string name="ATTACH_HUD_CENTER_2"> HUD centre 2 </string> @@ -2263,6 +2361,51 @@ Veuillez réessayer de vous connecter dans une minute. <string name="ATTACH_AVATAR_CENTER"> Centre de l'avatar </string> + <string name="ATTACH_LHAND_RING1"> + Annulaire gauche + </string> + <string name="ATTACH_RHAND_RING1"> + Annulaire droit + </string> + <string name="ATTACH_TAIL_BASE"> + Base de la queue + </string> + <string name="ATTACH_TAIL_TIP"> + Bout de la queue + </string> + <string name="ATTACH_LWING"> + Aile gauche + </string> + <string name="ATTACH_RWING"> + Aile droite + </string> + <string name="ATTACH_FACE_JAW"> + Mâchoire + </string> + <string name="ATTACH_FACE_LEAR"> + Oreille gauche différente + </string> + <string name="ATTACH_FACE_REAR"> + Oreille droite différente + </string> + <string name="ATTACH_FACE_LEYE"> + Å’il gauche différent + </string> + <string name="ATTACH_FACE_REYE"> + Å’il droit différent + </string> + <string name="ATTACH_FACE_TONGUE"> + Langue + </string> + <string name="ATTACH_GROIN"> + Aine + </string> + <string name="ATTACH_HIND_LFOOT"> + Pied arrière gauche + </string> + <string name="ATTACH_HIND_RFOOT"> + Pied arrière droit + </string> <string name="CursorPos"> Ligne [LINE], colonne [COLUMN] </string> @@ -2609,6 +2752,15 @@ Veuillez réessayer de vous connecter dans une minute. <string name="Play Media"> Lire/pauser le média </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/fr_FR/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=fr + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> <string name="MBCmdLineError"> Une erreur est survenue lors de la lecture de la ligne de commande. Merci de consulter : http://wiki.secondlife.com/wiki/Client_parameters @@ -4252,6 +4404,12 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. <string name="OfflineStatus"> Hors ligne </string> + <string name="not_online_msg"> + Utilisateur non connecté - le message sera enregistré et livré plus tard. + </string> + <string name="not_online_inventory"> + Utilisateur non connecté - l'inventaire a été enregistré + </string> <string name="answered_call"> Votre appel a fait l'objet d'une réponse </string> @@ -4378,12 +4536,18 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. <string name="paid_you_ldollars"> [NAME] vous a payé [AMOUNT] L$ [REASON]. </string> + <string name="paid_you_ldollars_gift"> + [NAME] vous a payé [AMOUNT] L$ : [REASON] + </string> <string name="paid_you_ldollars_no_reason"> [NAME] vous a payé [AMOUNT] L$. </string> <string name="you_paid_ldollars"> Vous avez payé à [AMOUNT] L$ [REASON]. </string> + <string name="you_paid_ldollars_gift"> + Vous avez payé à [NAME] [AMOUNT] L$ : [REASON] + </string> <string name="you_paid_ldollars_no_info"> Vous avez payé [AMOUNT] L$. </string> @@ -4396,6 +4560,9 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. <string name="you_paid_failure_ldollars"> Votre paiement de [AMOUNT] L$ à [NAME] [REASON] a échoué. </string> + <string name="you_paid_failure_ldollars_gift"> + Votre paiement de [AMOUNT] L$ à [NAME] a échoué : [REASON] + </string> <string name="you_paid_failure_ldollars_no_info"> Votre paiement de [AMOUNT] L$ a échoué. </string> @@ -4722,6 +4889,15 @@ du rapport d'infraction <string name="texture_load_dimensions_error"> Impossible de charger des images de taille supérieure à [WIDTH]*[HEIGHT] </string> + <string name="outfit_photo_load_dimensions_error"> + Taille max. de la photo de la tenue : [WIDTH]*[HEIGHT]. Redimensionnez l’image ou utilisez-en une autre. + </string> + <string name="outfit_photo_select_dimensions_error"> + Taille max. de la photo de la tenue : [WIDTH]*[HEIGHT]. Sélectionnez une autre texture. + </string> + <string name="outfit_photo_verify_dimensions_error"> + Impossible de vérifier les dimensions de la photo. Attendez que la taille de la photo s’affiche dans le sélecteur. + </string> <string name="words_separator" value=","/> <string name="server_is_down"> Malgré nos efforts, une erreur inattendue s'est produite. @@ -5226,6 +5402,9 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles <string name="Command_Profile_Label"> Profil </string> + <string name="Command_Report_Abuse_Label"> + Signaler une infraction + </string> <string name="Command_Search_Label"> Recherche </string> @@ -5316,6 +5495,9 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles <string name="Command_Profile_Tooltip"> Modifier ou afficher votre profil </string> + <string name="Command_Report_Abuse_Tooltip"> + Signaler une infraction + </string> <string name="Command_Search_Tooltip"> Trouver des lieux, personnes, événements </string> diff --git a/indra/newview/skins/default/xui/it/floater_model_preview.xml b/indra/newview/skins/default/xui/it/floater_model_preview.xml index 1fe2659e4b2ed4f5c0b89519133ae791f93e870d..95fe4aaf4c27f53ef7e26559ce450370398ea1d3 100644 --- a/indra/newview/skins/default/xui/it/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/it/floater_model_preview.xml @@ -245,6 +245,7 @@ </text> <check_box label="Includi peso pelle" name="upload_skin"/> <check_box label="Includi posizioni giunti" name="upload_joints"/> + <check_box label="Blocca scala se è definita la posizione dei giunti" name="lock_scale_if_joint_position"/> <text name="pelvis_offset_label"> Spostamento Z (sposta l'avatar in alto o in basso): </text> diff --git a/indra/newview/skins/default/xui/it/floater_pay.xml b/indra/newview/skins/default/xui/it/floater_pay.xml index ef24fc850d6c6e463269e75d4288d03c91d25a36..fc2e7c676c0669e88fea9df2a33cf768c6ef7fb4 100644 --- a/indra/newview/skins/default/xui/it/floater_pay.xml +++ b/indra/newview/skins/default/xui/it/floater_pay.xml @@ -1,9 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Give Money" title=""> - <string name="payee_group">Paga gruppo</string> - <string name="payee_resident">Paga residente</string> - <text name="paying_text">Stai pagando:</text> - <text left="115" name="payee_name">Nome di test che è troppo lungo per controllare il taglio</text> + <string name="payee_group"> + Paga gruppo + </string> + <string name="payee_resident"> + Paga residente + </string> + <text name="paying_text"> + Stai pagando: + </text> + <text left="115" name="payee_name"> + Nome di test che è troppo lungo per controllare il taglio + </text> + <text name="payment_message_label"> + Descrizione (facoltativa): + </text> <panel label="Cerca" name="PatternsPanel"> <button label="Paga 1 L$" label_selected="Paga 1 L$" name="fastpay 1"/> <button label="Paga 5 L$" label_selected="Paga 5 L$" name="fastpay 5"/> @@ -11,7 +22,9 @@ <button label="Paga 20 L$" label_selected="Paga 20 L$" name="fastpay 20"/> </panel> <panel label="Cerca" name="InputPanel"> - <text name="amount text">Altro importo:</text> + <text name="amount text"> + Altro importo: + </text> <button label="Paga" label_selected="Paga" name="pay btn"/> <button label="Annulla" label_selected="Annulla" name="cancel btn"/> </panel> diff --git a/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml index 5baba9fcedcf2526c24044838b43d952af45698d..056889126432a1aa8f18426a667d50759e0e36e1 100644 --- a/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Complessità massima:" name="IndirectMaxComplexity" tool_tip="Definisce il punto in cui un avatar dall'aspetto complesso viene visualizzato come una forma senza dettagli"/> + <slider label="Complessità massima:" name="IndirectMaxComplexity" tool_tip="Definisce il punto in cui un avatar dall'aspetto complesso viene visualizzato come JellyDoll"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/it/floater_script_queue.xml b/indra/newview/skins/default/xui/it/floater_script_queue.xml index f4117d30a2055805bd29ee43902ee96508884887..d0d01232833b395d91da75465e97438db0bcf08c 100644 --- a/indra/newview/skins/default/xui/it/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/it/floater_script_queue.xml @@ -15,5 +15,11 @@ <floater.string name="NotRunning"> Non in esecuzione </floater.string> + <floater.string name="Timeout"> + Timeout: [OBJECT_NAME] + </floater.string> + <floater.string name="LoadingObjInv"> + Caricamento inventario per: [OBJECT_NAME] + </floater.string> <button label="Chiudi" label_selected="Chiudi" name="close"/> </floater> diff --git a/indra/newview/skins/default/xui/it/floater_web_content.xml b/indra/newview/skins/default/xui/it/floater_web_content.xml index 5603e85417a3c57a0f5d12505424db82f98ebc9d..87bbf07937cc28d0c9dee21e9442a049034a2438 100644 --- a/indra/newview/skins/default/xui/it/floater_web_content.xml +++ b/indra/newview/skins/default/xui/it/floater_web_content.xml @@ -10,5 +10,9 @@ <icon name="media_secure_lock_flag" tool_tip="Navigazione sicura"/> <button name="popexternal" tool_tip="Apri URL corrente nel browser del computer"/> </layout_panel> + <layout_panel name="debug_controls"> + <button name="web_test_home_page" tool_tip="Home page test web"/> + <button name="VLC Plugin Test" tool_tip="Test video MPEG4"/> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/it/menu_attachment_other.xml b/indra/newview/skins/default/xui/it/menu_attachment_other.xml index 60cdd2a91dc3f269dc3d0ac0ce3e1aa6efcbb11b..183240029876645edc74cb44160dfc57e8c937df 100644 --- a/indra/newview/skins/default/xui/it/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/it/menu_attachment_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Chiama" name="Call"/> <menu_item_call label="Invita al gruppo" name="Invite..."/> + <menu_item_call label="Ripristina scheletro" name="Reset Skeleton"/> + <menu_item_call label="Ripristina scheletro e animazioni" name="Reset Skeleton And Animations"/> <menu_item_call label="Blocca" name="Avatar Mute"/> <menu_item_call label="Segnala" name="abuse"/> <menu_item_call label="Congela" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/it/menu_attachment_self.xml b/indra/newview/skins/default/xui/it/menu_attachment_self.xml index 1539fbafa19a6c31148b4c4f389874d18f65f27b..f25a289a62c969084383a7fdf1d5e2f2d5dfbedc 100644 --- a/indra/newview/skins/default/xui/it/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/it/menu_attachment_self.xml @@ -9,6 +9,8 @@ <menu_item_call label="Modifica il mio vestiario" name="Edit Outfit"/> <menu_item_call label="Modifica la figura corporea" name="Edit My Shape"/> <menu_item_call label="Altezza di volo" name="Hover Height"/> + <menu_item_call label="Ripristina scheletro" name="Reset Skeleton"/> + <menu_item_call label="Ripristina scheletro e animazioni" name="Reset Skeleton And Animations"/> <menu_item_call label="I miei amici..." name="Friends..."/> <menu_item_call label="I miei gruppi" name="Groups..."/> <menu_item_call label="Il mio profilo" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/it/menu_avatar_other.xml b/indra/newview/skins/default/xui/it/menu_avatar_other.xml index 7042e5294386c943c711ff09a35052d89828b5ce..f3b4075a29e477f9257c0fe569f95371405004ed 100644 --- a/indra/newview/skins/default/xui/it/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/it/menu_avatar_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Chiama" name="Call"/> <menu_item_call label="Invita al gruppo" name="Invite..."/> + <menu_item_call label="Ripristina scheletro" name="Reset Skeleton"/> + <menu_item_call label="Ripristina scheletro e animazioni" name="Reset Skeleton And Animations"/> <menu_item_call label="Blocca" name="Avatar Mute"/> <menu_item_call label="Segnala" name="abuse"/> <menu_item_call label="Congela" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/it/menu_avatar_self.xml b/indra/newview/skins/default/xui/it/menu_avatar_self.xml index 0c9663fd4c6bbcf23944fabb261abca7b6c23363..85de7f4e307c4b278e860ffe170dac0d3a0a18ad 100644 --- a/indra/newview/skins/default/xui/it/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/it/menu_avatar_self.xml @@ -26,6 +26,8 @@ <menu_item_call label="Modifica il mio vestiario" name="Edit Outfit"/> <menu_item_call label="Modifica la figura corporea" name="Edit My Shape"/> <menu_item_call label="Altezza di volo" name="Hover Height"/> + <menu_item_call label="Ripristina scheletro" name="Reset Skeleton"/> + <menu_item_call label="Ripristina scheletro e animazioni" name="Reset Skeleton And Animations"/> <menu_item_call label="I miei amici..." name="Friends..."/> <menu_item_call label="I miei gruppi" name="Groups..."/> <menu_item_call label="Il mio profilo" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/it/menu_login.xml b/indra/newview/skins/default/xui/it/menu_login.xml index 33fa25cd38fcceba5b087f67668cd1585c4007e7..3d2a556fe2ec7dc139802e7e2e7c50826e3df778 100644 --- a/indra/newview/skins/default/xui/it/menu_login.xml +++ b/indra/newview/skins/default/xui/it/menu_login.xml @@ -20,12 +20,11 @@ <menu_item_check label="Mostra menu Debug" name="Show Debug Menu"/> <menu label="Debug" name="Debug"> <menu_item_call label="Mostra impostazioni di debug" name="Debug Settings"/> - <menu_item_call label="Impostazioni colori interfaccia" name="UI/Color Settings"/> <menu label="Test interfaccia utente" name="UI Tests"/> <menu_item_call label="Imposta dimensioni della finestra..." name="Set Window Size..."/> <menu_item_call label="Mostra i Termini del servizio (TOS)" name="TOS"/> <menu_item_call label="Mostra messaggio critico" name="Critical"/> - <menu_item_call label="Test debug finestra contenuti Web" name="Web Content Floater Debug Test"/> + <menu_item_call label="Browser multimedia" name="Media Browser"/> <menu label="Imposta livello di registrazione" name="Set Logging Level"> <menu_item_check label="Debug" name="Debug"/> <menu_item_check label="Info" name="Info"/> diff --git a/indra/newview/skins/default/xui/it/menu_object_icon.xml b/indra/newview/skins/default/xui/it/menu_object_icon.xml index 9623775af46e63a796bae942d1946b51241b1532..a574757fd0493e0bdc1ef6ec5da5c18d94047900 100644 --- a/indra/newview/skins/default/xui/it/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/it/menu_object_icon.xml @@ -2,6 +2,7 @@ <menu name="Object Icon Menu"> <menu_item_call label="Profilo oggetto..." name="Object Profile"/> <menu_item_call label="Blocca..." name="Block"/> + <menu_item_call label="Sblocca" name="Unblock"/> <menu_item_call label="Mostra sulla mappa" name="show_on_map"/> <menu_item_call label="Teleport sul luogo dell'oggetto" name="teleport_to_object"/> </menu> diff --git a/indra/newview/skins/default/xui/it/menu_outfit_gear.xml b/indra/newview/skins/default/xui/it/menu_outfit_gear.xml index 3ac0c5ce698169615911f2089294b734d6002474..62c6d53e1c6aec40382a54562a1594bc595eb7e9 100644 --- a/indra/newview/skins/default/xui/it/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/it/menu_outfit_gear.xml @@ -3,6 +3,10 @@ <menu_item_call label="Indossa - Sostituisci vestiario attuale" name="wear"/> <menu_item_call label="Indossa - Aggiungi al vestiario attuale" name="wear_add"/> <menu_item_call label="Togli - Rimuovi dal vestiario attuale" name="take_off"/> + <menu_item_call label="Carica foto (L$ 10)" name="upload_photo"/> + <menu_item_call label="Seleziona foto" name="select_photo"/> + <menu_item_call label="Scatta un'istantanea" name="take_snapshot"/> + <menu_item_call label="Rimuovi foto" name="remove_photo"/> <menu label="Nuovi abiti" name="New Clothes"> <menu_item_call label="Nuova camicia" name="New Shirt"/> <menu_item_call label="Nuovi pantaloni" name="New Pants"/> @@ -27,4 +31,5 @@ <menu_item_call label="Chiudi tutte le cartelle" name="collapse"/> <menu_item_call label="Cambia nome del vestiario" name="rename"/> <menu_item_call label="Elimina vestito" name="delete_outfit"/> + <menu_item_check label="Ordina le cartelle sempre in base al nome" name="sort_folders_by_name"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/it/menu_people_friends_view.xml b/indra/newview/skins/default/xui/it/menu_people_friends_view.xml index 972e359cfe567f7c7e60c966a305ae7f54fe8827..1cfe14b86b0787af8b64965276214e4d70d4ac3f 100644 --- a/indra/newview/skins/default/xui/it/menu_people_friends_view.xml +++ b/indra/newview/skins/default/xui/it/menu_people_friends_view.xml @@ -4,5 +4,6 @@ <menu_item_check label="Ordina in base allo stato" name="sort_status"/> <menu_item_check label="Mostra le icone delle persone" name="view_icons"/> <menu_item_check label="Mostra le autorizzazioni concesse" name="view_permissions"/> + <menu_item_check label="Nascondi nomi utenti" name="view_usernames"/> <menu_item_check label="Mostra il registro conversazioni..." name="view_conversation"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/it/menu_people_nearby.xml b/indra/newview/skins/default/xui/it/menu_people_nearby.xml index 1c09b1cfe25686d03840b42a2a4b3c787b3a96d5..3b9f9c89f813a0b9d12d1aa0bf0b45db3e7b7059 100644 --- a/indra/newview/skins/default/xui/it/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/it/menu_people_nearby.xml @@ -13,4 +13,6 @@ <menu_item_call label="Condividi" name="share"/> <menu_item_call label="Paga" name="pay"/> <menu_item_check label="Blocca/Sblocca" name="block_unblock"/> + <menu_item_call label="Congela" name="freeze"/> + <menu_item_call label="Espelli" name="eject"/> </context_menu> diff --git a/indra/newview/skins/default/xui/it/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/it/menu_people_nearby_view.xml index 223d88fee1c7ac37dd692b355e0d13de74629132..d0891903f51e1aeaf011c1ee8df2a2bbb73c253e 100644 --- a/indra/newview/skins/default/xui/it/menu_people_nearby_view.xml +++ b/indra/newview/skins/default/xui/it/menu_people_nearby_view.xml @@ -5,4 +5,5 @@ <menu_item_check label="Ordina in base alla distanza" name="sort_distance"/> <menu_item_check label="Mostra le icone delle persone" name="view_icons"/> <menu_item_check label="Mostra mappa" name="view_map"/> + <menu_item_check label="Nascondi nomi utenti" name="view_usernames"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/it/menu_url_objectim.xml b/indra/newview/skins/default/xui/it/menu_url_objectim.xml index 116b6521727aa80028fb67871970ed62b9bcf048..67bc34a5d7431419c8f88e1ce4ddbe9b7031f456 100644 --- a/indra/newview/skins/default/xui/it/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/it/menu_url_objectim.xml @@ -2,6 +2,7 @@ <context_menu name="Url Popup"> <menu_item_call label="Profilo oggetto..." name="show_object"/> <menu_item_call label="Blocca..." name="block_object"/> + <menu_item_call label="Sblocca" name="unblock_object"/> <menu_item_call label="Mostra sulla mappa" name="show_on_map"/> <menu_item_call label="Teleport sul luogo dell'oggetto" name="teleport_to_object"/> <menu_item_call label="Copia nome oggetto negli Appunti" name="url_copy_label"/> diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index d52b022c496521f834fcb2ff620b1c8514dd10b1..96f06d5f98aac9598c3d227bb3293e5703d6b07d 100644 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Non disturbare" name="Do Not Disturb"/> </menu> <menu_item_call label="Acquista L$..." name="Buy and Sell L$"/> - <menu_item_call label="Casella venditore in uscita..." name="MerchantOutbox"/> <menu_item_call label="Annunci Marketplace..." name="MarketplaceListings"/> <menu_item_call label="Dashboard dell'account..." name="Manage My Account"> <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=it"/> @@ -114,11 +113,11 @@ <menu_item_call label="Collegamento" name="Link"/> <menu_item_call label="Scollega" name="Unlink"/> <menu_item_check label="Modifica le parti collegate" name="Edit Linked Parts"/> - <menu label="Seleziona parti collegate" name="Select Linked Parts"> - <menu_item_call label="Seleziona parte successiva" name="Select Next Part"/> - <menu_item_call label="Seleziona parte precedente" name="Select Previous Part"/> - <menu_item_call label="Includi parte successiva" name="Include Next Part"/> - <menu_item_call label="Includi parte precedente" name="Include Previous Part"/> + <menu label="Seleziona elementi" name="Select Elements"> + <menu_item_call label="Seleziona parte o faccia successiva" name="Select Next Part or Face"/> + <menu_item_call label="Seleziona parte o faccia precedente" name="Select Previous Part or Face"/> + <menu_item_call label="Includi parte o faccia successiva" name="Include Next Part or Face"/> + <menu_item_call label="Includi parte o faccia precedente" name="Include Previous Part or Face"/> </menu> <menu_item_call label="Set collegati..." name="pathfinding_linkset_menu_item"/> <menu_item_call label="Ingrandisci selezione" name="Focus on Selection"/> @@ -333,8 +332,7 @@ <menu_item_call label="Dump della cache oggetti regione" name="Dump Region Object Cache"/> </menu> <menu label="Interfaccia utente" name="UI"> - <menu_item_call label="Test browser multimedia" name="Web Browser Test"/> - <menu_item_call label="Browser contenuto Web" name="Web Content Browser"/> + <menu_item_call label="Browser multimedia" name="Media Browser"/> <menu_item_call label="Stampa informazioni oggetto selezionato" name="Print Selected Object Info"/> <menu_item_check label="Debug clic" name="Debug Clicks"/> <menu_item_check label="Debug eventi mouse" name="Debug Mouse Events"/> @@ -368,6 +366,7 @@ <menu_item_check label="Informazioni sull'animazione" name="Animation Info"/> <menu_item_check label="Disabilita livello di dettaglio" name="Disable LOD"/> <menu_item_check label="Mostra schemi collisione" name="Show Collision Skeleton"/> + <menu_item_check label="Mostra ossa" name="Show Bones"/> <menu_item_check label="Mostra bersaglio" name="Display Agent Target"/> <menu_item_call label="Debug texture dell'avatar" name="Debug Avatar Textures"/> </menu> diff --git a/indra/newview/skins/default/xui/it/menu_wearing_tab.xml b/indra/newview/skins/default/xui/it/menu_wearing_tab.xml index 4a5366091f19ef5cd21fc194ef6ec91e4ffac8ca..ec375e524037f5e649fa552eb24fb2700c753ed1 100644 --- a/indra/newview/skins/default/xui/it/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/it/menu_wearing_tab.xml @@ -3,4 +3,6 @@ <menu_item_call label="Togli" name="take_off"/> <menu_item_call label="Stacca" name="detach"/> <menu_item_call label="Modifica vestiario" name="edit"/> + <menu_item_call label="Modifica" name="edit_item"/> + <menu_item_call label="Mostra originale" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/it/mime_types.xml b/indra/newview/skins/default/xui/it/mime_types.xml index df119263b7782b7657c4cb0126503031bf0e7add..7e528b0688445f45163c88a87cc576166fb1971a 100644 --- a/indra/newview/skins/default/xui/it/mime_types.xml +++ b/indra/newview/skins/default/xui/it/mime_types.xml @@ -22,14 +22,6 @@ Riproduci video </playtip> </widgetset> - <widgetset name="none"> - <label name="none_label"> - Nessun contenuto - </label> - <tooltip name="none_tooltip"> - Nessun contenuto multimediale qui - </tooltip> - </widgetset> <widgetset name="image"> <label name="image_label"> Immagine @@ -52,11 +44,24 @@ Riproduci l'audio di questo posto </playtip> </widgetset> + <widgetset name="none"> + <label name="none_label"> + Nessun contenuto + </label> + <tooltip name="none_tooltip"> + Nessun contenuto multimediale qui + </tooltip> + </widgetset> <scheme name="rtsp"> <label name="rtsp_label"> Streaming in tempo reale </label> </scheme> + <scheme name="libvlc"> + <label name="libvlc_label"> + Media supportati da LibVLC + </label> + </scheme> <mimetype name="blank"> <label name="blank_label"> - Nessuno - @@ -127,11 +132,6 @@ Macromedia Director </label> </mimetype> - <mimetype name="application/x-shockwave-flash"> - <label name="application/x-shockwave-flash_label"> - Flash - </label> - </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> Audio (MIDI) @@ -207,6 +207,11 @@ Video (MP4) </label> </mimetype> + <mimetype name="application/octet-stream"> + <label name="video/octet-stream"> + Filmato + </label> + </mimetype> <mimetype name="video/quicktime"> <label name="video/quicktime_label"> Video (QuickTime) diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index 358f38a137285e0db96c20d5a2a329813ed7e8f2..3621b3bc62be3240078abb8ae10973a96b8a52c3 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -330,6 +330,9 @@ Se non desideri che queste abilità siano assegnate a questo ruolo, disattivale Stai per espellere [COUNT] membri dal gruppo. <usetemplate ignoretext="Conferma l'espulsione di vari partecipanti dal gruppo" name="okcancelignore" notext="Annulla" yestext="Espelli"/> </notification> + <notification name="GroupBanUserOnBanlist"> + Ad alcuni residenti non è stato inviato l'invito perché espulsi dal gruppo. + </notification> <notification name="AttachmentDrop"> Stai per abbandonare il tuo accessorio. Vuoi continuare? @@ -457,6 +460,12 @@ Per collocare il media su una sola faccia, scegli Seleziona faccia, clicca su un <notification name="ErrorEncodingSnapshot"> Errore nella codifica della fotografia. </notification> + <notification name="ErrorPhotoCannotAfford"> + Hai bisogno di L$ [COST] per salvare una foto nel tuo inventario. Puoi acquistare L$ o salvare la foto sul tuo computer. + </notification> + <notification name="ErrorTextureCannotAfford"> + Hai bisogno di L$ [COST] per salvare una texture nel tuo inventario. Puoi acquistare L$ o salvare la foto sul tuo computer. + </notification> <notification name="ErrorUploadingPostcard"> C'è stato un problema inviando la fotografia per il seguente motivo: [REASON] </notification> @@ -480,6 +489,9 @@ Superato il limite di oggetti collegati [MAX_ATTACHMENTS]. Per favore prima stac <notification name="CannotWearInfoNotComplete"> Non puoi indossare quell'elemento perchè non è ancora stato caricato. Riprova fra un minuto. </notification> + <notification name="MustEnterPasswordToLogIn"> + Inserisci la tua password per accedere. + </notification> <notification name="MustHaveAccountToLogIn"> Spiacenti. Un campo è vuoto. Inserisci il Nome utente del tuo avatar. @@ -548,6 +560,9 @@ Nota: questa operazione cancellerà la cache. <notification name="ChangeConnectionPort"> Le impostazioni della porta avranno effetto dopo il riavvio di [APP_NAME]. </notification> + <notification name="ChangeDeferredDebugSetting"> + La modifica della impostazione di debug avrà effetto dopo il riavvio di [APP_NAME]. + </notification> <notification name="ChangeSkin"> La nuova pelle comparirà dopo il riavvio di [APP_NAME]. </notification> @@ -566,6 +581,10 @@ Nota: questa operazione cancellerà la cache. Vuoi eliminare il biglietto? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> </notification> + <notification name="LoadPreviousReportScreenshot"> + Vuoi usare la precedente schermata per il tuo rapporto? + <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> + </notification> <notification name="GestureSaveFailedTooManySteps"> Il salvataggio della Gesture è fallito. La gesture ha troppi passi. @@ -626,30 +645,12 @@ Visitare [_URL] per ulteriori informazioni? </url> <usetemplate ignoretext="L'hardware di questo computer non è compatibile" name="okcancelignore" notext="No" yestext="Si"/> </notification> - <notification name="IntelOldDriver"> - È probabile che ci sia un driver aggiornato per il processore grafico. L'aggiornamento dei driver della grafica può migliorare le prestazioni in maniera significativa. - - Visitare [_URL] per cercare un aggiornamento del driver? - <url name="url"> - http://www.intel.com/p/it_IT/support/detect/graphics - </url> - <usetemplate ignoretext="Driver grafica obsoleto" name="okcancelignore" notext="No" yestext="Sì"/> - </notification> - <notification name="AMDOldDriver"> - È probabile che ci sia un driver aggiornato per il processore grafico. L'aggiornamento dei driver della grafica può migliorare le prestazioni in maniera significativa. - - Visitare [_URL] per cercare un aggiornamento del driver? - <url name="url"> - http://support.amd.com/it/Pages/AMDSupportHub.aspx - </url> - <usetemplate ignoretext="Driver grafica obsoleto" name="okcancelignore" notext="No" yestext="Sì"/> - </notification> - <notification name="NVIDIAOldDriver"> - È probabile che ci sia un driver aggiornato per il processore grafico. L'aggiornamento dei driver della grafica può migliorare le prestazioni in maniera significativa. + <notification name="OldGPUDriver"> + È probabile che ci sia un driver aggiornato per il processore grafico. L'aggiornamento dei driver della grafica può migliorare le prestazioni in maniera significativa. - Visitare [_URL] per cercare un aggiornamento del driver? + Visitare [URL] per cercare un aggiornamento del driver? <url name="url"> - http://www.nvidia.it/Download/index.aspx?lang=it + [URL] </url> <usetemplate ignoretext="Driver grafica obsoleto" name="okcancelignore" notext="No" yestext="Sì"/> </notification> @@ -741,6 +742,9 @@ Vai su [_URL] per informazioni sull'acquisto di L$? </url> <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> </notification> + <notification name="MuteLimitReached"> + Impossibile aggiungere il nuovo elemento alla lista dei bloccati perché hai raggiunto il limite di [MUTE_LIMIT] immissioni. + </notification> <notification name="UnableToLinkObjects"> Impossibile unire questi [COUNT] oggetti. Puoi unire al massimo [MAX] oggetti. @@ -1366,12 +1370,18 @@ Puoi comunque usare [SECOND_LIFE] normalmente e gli altri residenti ti vedranno <ignore name="ignore" text="Lo scaricamento sta richiedendo parecchio tempo"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - La tua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complessità visiva] è [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + La [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complessità del tuo avatar] è [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Avvisami se la complessità del mio avatar è eccessiva" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - La tua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complessità visiva] è [AGENT_COMPLEXITY]. + La [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complessità del tuo avatar] è [AGENT_COMPLEXITY]. + <usetemplate ignoretext="Avvisami in caso di cambiamenti della complessità del mio avatar" name="notifyignore"/> + </notification> + <notification name="HUDComplexityWarning"> + [HUD_REASON], è probabile che influisca negativamente sulle tue prestazioni. + <usetemplate ignoretext="Avvisami quando la complessità del mio HUD è eccessiva" name="notifyignore"/> </notification> <notification name="FirstRun"> L'installazione di [APP_NAME] è terminata. @@ -1463,6 +1473,10 @@ Scegli solo un oggetto e riprova. Teleporta a casa tutti i residenti in questa regione? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> </notification> + <notification name="ChangeObjectBonusFactor"> + La riduzione del bonus oggetti dopo aver costruito in una regione può causare la restituzione o l'eliminazione di oggetti. Vuoi comunque cambiare il bonus oggetti? + <usetemplate ignoretext="Conferma cambiamento fattore bonus oggetti" name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> <notification name="EstateObjectReturn"> Confermi di voler restituire gli oggetti di proprietà di [USER_NAME] ? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> @@ -1486,6 +1500,10 @@ Sostituisci la texture [TEXTURE_NUM] con una a 24-bit 512x512 oppure con una imm Vuoi veramente impostare come base il terreno corrente, impostarlo come riferimento per i limiti dei rialzi/abbassamenti di tutto il territorio ed il suo valore impostato come base per lo strumento 'Ripristina'? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + Stai per usare valori bassi maggiori dei valori alti di Intervalli altitudine. Vuoi procedere? + <usetemplate canceltext="Non chiedere" name="yesnocancelbuttons" notext="Annulla" yestext="OK"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Puoi avere al massimo [MAX_AGENTS] residenti consentiti. </notification> @@ -1506,6 +1524,9 @@ Eccede il [MAX_AGENTS] [LIST_TYPE] limite di [NUM_EXCESS]. <notification name="OwnerCanNotBeDenied"> Impossibile aggiungere i proprietari della proprietà immobiliare alla lista dei residenti bloccati. </notification> + <notification name="ProblemAddingEstateManagerBanned"> + Impossibile aggiungere il residente espulso alla lista dei gestori delle proprietà . + </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> Impossibile cambiare l'aspetto fisico finchè gli abiti e i vestiti non sono caricati. </notification> @@ -1681,6 +1702,10 @@ Per provare le funzioni e modifiche più recenti, visita la pagina Alternate Vie Vuoi aprire il browser per vedere questi contenuti? <usetemplate ignoretext="Lancia il browser per consultare una pagina web" name="okcancelignore" notext="Annulla" yestext="OK"/> </notification> + <notification name="SystemUIScaleFactorChanged"> + Il fattore dimensioni UI del sistema è cambiato rispetto all'ultima sessione. Vuoi aprire la pagina delle impostazioni di regolazione delle dimensioni UI? + <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> + </notification> <notification name="WebLaunchJoinNow"> Vuoi andare su [http://secondlife.com/account/ Dashboard] per gestire il tuo account? <usetemplate ignoretext="Lancia il browser per gestire il mio account" name="okcancelignore" notext="Annulla" yestext="OK"/> @@ -1720,16 +1745,15 @@ Per provare le funzioni e modifiche più recenti, visita la pagina Alternate Vie Lasciare il gruppo? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> </notification> + <notification name="GroupDepart"> + Hai abbandonato il gruppo "[group_name]". + </notification> <notification name="OwnerCannotLeaveGroup"> Impossibile abbandonare il gruppo. Non puoi abbandonare il gruppo perché sei l'ultimo proprietario del gruppo. Devi prima assegnare a un altro membro il ruolo di proprietario. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="GroupDepartError"> - Impossibile abbandonare il gruppo: [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Hai abbandonato il gruppo [group_name]. + Impossibile abbandonare il gruppo. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="ConfirmKick"> @@ -2132,6 +2156,10 @@ Cambierà migliaia di regioni e produrrà seri problemi ai vari server. Hai selezionato troppi prim. Seleziona non più di [MAX_PRIM_COUNT] prim e riprova <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="TooManyScriptsSelected"> + Troppi script negli oggetti selezionati. Seleziona meno oggetti e riprova. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="ProblemImportingEstateCovenant"> Problemi nell'importazione del regolamento della proprietà . <usetemplate name="okbutton" yestext="OK"/> @@ -2301,6 +2329,10 @@ Trasferisci gli elementi nell'inventario? Pagamento non riuscito: oggetto non trovato. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="PaymentBlockedButtonMismatch"> + Pagamento interrotto: il prezzo pagato non corrisponde a nessuno dei pulsanti di pagamento impostati per questo oggetto. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="OpenObjectCannotCopy"> Non ci sono elementi in questo oggetto che tu possa copiare. </notification> @@ -2336,6 +2368,11 @@ Questa azione non può essere ripristinata Questa è una selezione di grandi dimensioni con set collegati. Se viene scollegata, potrebbe non essere possibile ricollegarla. Come precauzione ti consigliamo di salvare copie dei set collegati nel tuo inventario. <usetemplate ignoretext="Conferma per scollegare un set collegato" name="okcancelignore" notext="Annulla" yestext="Scollega"/> </notification> + <notification name="HelpReportAbuseConfirm"> + Ti ringraziamo della segnalazione. +Esamineremo il tuo rapporto e, in caso di violazioni, prenderemo le misure appropriate. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="HelpReportAbuseSelectCategory"> Scegli una categoria per questa segnalazione di abuso. Scegliere una categoria, ci aiuta a gestire ed elaborare le segnalazioni di abuso. @@ -2406,6 +2443,10 @@ Vuoi disattivare la modalità Non disturbare prima di completare questa transazi Vuoi veramente eliminare in modo permanente il contenuto del tuo Cestino? <usetemplate ignoretext="Conferma prima di svuotare la cartella del Cestino inventario" name="okcancelignore" notext="Annulla" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + Il cestino è troppo pieno. Ciò potrebbe causare problemi durante l'accesso. + <usetemplate name="okcancelbuttons" notext="Svuota il cestino più tardi" yestext="Svuota il cestino adesso"/> + </notification> <notification name="ConfirmClearBrowserCache"> Vuoi veramente eliminare la cronologia viaggi, web e ricerche fatte? <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> @@ -2760,6 +2801,10 @@ Qui non puoi volare. <notification name="PathfindingDirty"> La regione ha modifiche di pathfinding in sospeso. Se hai le autorizzazioni necessarie per la costruzione puoi eseguire il rebake facendo clic sul pulsante “Rebake regioneâ€. </notification> + <notification name="PathfindingDirtyRebake"> + La regione ha modifiche di pathfinding in sospeso. Se hai le autorizzazioni necessarie per la costruzione, puoi eseguire il rebake facendo clic sul pulsante “Rebake regioneâ€. + <usetemplate name="okbutton" yestext="Rebake regione"/> + </notification> <notification name="DynamicPathfindingDisabled"> Il pathfinding dinamico non è attivato in questa regione. Gli oggetti scriptati che usano chiamate LSL di pathfinding potrebbero non funzionare come previsto in questa regione. </notification> @@ -3262,6 +3307,12 @@ Per sicurezza, verranno bloccati per alcuni secondi. <notification name="AttachmentSaved"> L'elemento da collegare è stato salvato. </notification> + <notification name="AppearanceToXMLSaved"> + L'aspetto è stato salvato in XML su [PATH] + </notification> + <notification name="AppearanceToXMLFailed"> + Salvataggio aspetto in formato XML non riuscito. + </notification> <notification name="PresetNotSaved"> Errore durante il salvataggio del valore predefinito [NAME]. </notification> @@ -3476,13 +3527,6 @@ Clicca e trascina dovunque nel mondo per ruotare la visuale <notification name="ForceQuitDueToLowMemory"> SL verrà interrotto tra 30 secondi a causa di spazio di memoria insufficiente. </notification> - <notification name="PopupAttempt"> - Non è stato possibile aprire una finestra pop-up. - <form name="form"> - <ignore name="ignore" text="Attiva tutti i pop-up"/> - <button name="open" text="Apri finestra pop-up"/> - </form> - </notification> <notification name="SOCKS_NOT_PERMITTED"> Il proxy SOCKS 5 "[HOST]:[PORT]" ha rifiutato il collegamento, che non è consentito dalle regole. <usetemplate name="okbutton" yestext="OK"/> @@ -3857,6 +3901,9 @@ Riprova tra un minuto. Impossibile muovere l'oggetto '[OBJECT_NAME]' a [OBJ_POSITION] nella regione [REGION_NAME] perché non ci sono risorse sufficienti per l'oggetto su questo lotto. </notification> + <notification name="NoParcelPermsNoObject"> + Copia non riuscita perché non hai accesso a quel lotto. + </notification> <notification name="CantMoveObjectRegionVersion"> Impossibile muovere l'oggetto '[OBJECT_NAME]' a [OBJ_POSITION] nella regione [REGION_NAME] perché nell'altra regione è in esecuzione una versione precedente che non consente la ricezione di questo oggetto attraverso i confini tra regioni. @@ -3872,6 +3919,10 @@ Riprova tra un minuto. <notification name="NoPermModifyObject"> Non hai l'autorizzazione necessaria per modificare questa immagine </notification> + <notification name="TooMuchObjectInventorySelected"> + Selezionati troppi oggetti con tanti elementi di inventario. Seleziona meno oggetti e riprova. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="CantEnablePhysObjContributesToNav"> Non è possibile attivare la fisica per un oggetto che contribuisce al navmesh. </notification> @@ -3908,6 +3959,12 @@ Riprova tra un minuto. <notification name="CantSaveModifyAttachment"> Impossibile salvare i contenuti dell'oggetto: Verrebbero modificate le autorizzazioni per il collegamento. </notification> + <notification name="AttachmentHasTooMuchInventory"> + Gli allegati contengono troppi elementi di inventario e non puoi aggiungerne altri. + </notification> + <notification name="IllegalAttachment"> + Il collegamento ha richiesto un punto sull'avatar che non esiste. È stato collegato al petto. + </notification> <notification name="TooManyScripts"> Troppi script. </notification> @@ -4000,6 +4057,12 @@ Riprova tra un minuto. <notification name="TeleportedByObjectUnknownUser"> Sei stato teleportato dall'oggetto '[OBJECT_NAME]' di proprietà di un utente sconosciuto. </notification> + <notification name="StandDeniedByObject"> + Al momento, "[OBJECT_NAME]" non ti permette di stare in piedi. + </notification> + <notification name="ResitDeniedByObject"> + Al momento, "[OBJECT_NAME]" non ti permette di cambiare il posto a sedere. + </notification> <notification name="CantCreateObjectRegionFull"> Impossibile creare l'oggetto richiesto. La regione è piena. </notification> @@ -4296,6 +4359,9 @@ Prova a selezionare un pezzo di terreno più piccolo. <notification name="CantTransfterMoneyRegionDisabled"> Il trasferimento di denaro agli oggetti è attualmente disattivato in questa regione. </notification> + <notification name="DroppedMoneyTransferRequest"> + Impossibile effettuare il pagamento a causa del carico del sistema. + </notification> <notification name="CantPayNoAgent"> Non si capisce chi deve essere pagato. </notification> @@ -4331,4 +4397,8 @@ Prova a selezionare un pezzo di terreno più piccolo. Il file della cronologia del file sta ancora eseguendo l'operazione precedente. Riprova nuovamente tra qualche minuto oppure chatta con un'altra persona. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="OutfitPhotoLoadError"> + [REASON] + <usetemplate name="okbutton" yestext="OK"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml index c7821bc363947338c269cefc8aa655779d83672f..a19fa4eb18c4a089cb709361c5c83a1504ebd912 100644 --- a/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml @@ -7,6 +7,7 @@ Indossa capi selezionati </panel.string> <tab_container name="appearance_tabs"> + <panel label="GALLERIA VESTIARIO" name="outfit_gallery_tab"/> <panel label="I MIEI ABITI" name="outfitslist_tab"/> <panel label="INDOSSA" name="cof_tab"/> </tab_container> diff --git a/indra/newview/skins/default/xui/it/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/it/panel_outfits_wearing.xml index 3bbf2446f553463e8605b64d64766daa5c0375bf..0efed03e650348a86981413f3b15ba5c3a4330c1 100644 --- a/indra/newview/skins/default/xui/it/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/it/panel_outfits_wearing.xml @@ -1,6 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Wearing"> + <panel.string name="no_attachments"> + Nessun allegato indossato. + </panel.string> + <accordion name="wearables_accordion"> + <accordion_tab name="tab_wearables" title="Indossabili"/> + <accordion_tab name="tab_temp_attachments" title="Allegati temporanei"/> + </accordion> <panel name="bottom_panel"> - <button name="options_gear_btn" tool_tip="Mostra ulteriori opzioni"/> + <menu_button name="options_gear_btn" tool_tip="Mostra ulteriori opzioni"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml index fd1fd57761bec461c12035b7a77918410f852cea..ca83490b02df02fbe9fa374300b9f85a909117fe 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Avvisami: </text> - <check_box label="Quando spendo o ottengo L$" name="notify_money_change_checkbox"/> + <check_box label="Quando spendo $" name="notify_money_spend_checkbox"/> <check_box label="Quando i miei amici entrano o escono da Second Life" name="friends_online_notify_checkbox"/> + <check_box label="Quando ottengo $" name="notify_money_received_checkbox"/> <text name="show_label"> Mostra sempre: </text> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml index a042c43431d310fd9999fb96c47aedf253763994..4fa1835b0eb322cecd52471a32ce441d2be39fac 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> Migliore </text> + <slider label="Massima conplessità dell'avatar:" name="IndirectMaxComplexity" tool_tip="Definisce il punto in cui un avatar dall'aspetto complesso viene visualizzato come JellyDoll"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Shader atmosfera..." name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="Modello illuminazione avanzato" name="UseLightShaders"/> <button label="Salva impostazioni come valori predefiniti..." name="PrefSaveButton"/> <button label="Carica valore predefinito..." name="PrefLoadButton"/> + min_val="0.125" <button label="Elimina valore predefinito..." name="PrefDeleteButton"/> <button label="Ripristina impostazioni consigliate" name="Defaults"/> <button label="Impostazioni avanzate..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml index 093f7fc411dc1ae523a1ef2bd1b8f3c444f86e6f..d34bb7c3a4444008e4df4749f4fc0de77767345c 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml @@ -30,6 +30,7 @@ <combo_box.item label="Scarica e installa manualmente gli aggiornamenti" name="Install_manual"/> </combo_box> <check_box label="Disponibile agli aggiornamenti con versioni non rilasciate" name="update_willing_to_test"/> + <check_box label="Mostra note di release dopo l'aggiornamento" name="update_show_release_notes"/> <text name="Proxy Settings:"> Impostazioni proxy: </text> diff --git a/indra/newview/skins/default/xui/it/panel_sound_devices.xml b/indra/newview/skins/default/xui/it/panel_sound_devices.xml index b1934fd515cd00ef6edec6fdd56d63c1477187d2..83df46f38167db4dcaac72d90f7f010a096ece36 100644 --- a/indra/newview/skins/default/xui/it/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/it/panel_sound_devices.xml @@ -16,9 +16,9 @@ Output </text> <text name="My volume label"> - Il mio volume: + Volume microfono: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Cambia il volume utilizzando questa barra"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Cambia il livello del microfono utilizzando questa barra"/> <text name="wait_text"> Attendi </text> diff --git a/indra/newview/skins/default/xui/it/panel_status_bar.xml b/indra/newview/skins/default/xui/it/panel_status_bar.xml index 83d2ae5babfe68e07d5ae7bbd48ebc83c7fc1eb7..295ca8d9f2df0f47afc939559477eda0e1b078ba 100644 --- a/indra/newview/skins/default/xui/it/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/it/panel_status_bar.xml @@ -5,7 +5,7 @@ <panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string> <panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string> <panel.string name="buycurrencylabel">L$ [AMT]</panel.string> - <panel left="-405" name="balance_bg" width="195"> + <panel left="-426" name="balance_bg" width="195"> <text name="balance" tool_tip="Clicca per aggiornare il tuo saldo in L$" value="L$ ??"/> <button label="Acquista L$" name="buyL" tool_tip="Clicca per acquistare più L$"/> <button label="Acquisti" name="goShop" tool_tip="Apri Mercato Second Life" width="75"/> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index effd6f50402b14c9e90ff90a619861d998f14d4a..8246f91d17eac6b6277799498e737fc51bcd784f 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -38,6 +38,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> + <string name="BuildConfig"> + Configurazione struttura [BUILD_CONFIG] + </string> <string name="AboutPosition"> Tu sei a [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a <nolink>[HOSTNAME]</nolink> ([HOSTIP]) SLURL: <nolink>[SLURL]</nolink> @@ -55,20 +58,40 @@ Scheda grafica: [GRAPHICS_CARD] <string name="AboutDriver"> Versione driver Windows per grafica: [GRAPHICS_DRIVER_VERSION] </string> - <string name="AboutLibs"> + <string name="AboutOGL"> Versione OpenGL: [OPENGL_VERSION] - -Versione J2C Decoder: [J2C_VERSION] + </string> + <string name="AboutSettings"> + Dimensione finestra: [WINDOW_WIDTH] x [WINDOW_HEIGHT] +Regolazione dimensioni carattere: [FONT_SIZE_ADJUSTMENT] punti +Scala UI: [UI_SCALE] +Distanza visualizzazione: [DRAW_DISTANCE] m +Larghezza banda: [NET_BANDWITH] kbit/s +Fattore livello di dettaglio: [LOD_FACTOR] +Qualità di rendering: [RENDER_QUALITY] / 7 +Modello illuminazione avanzato: [GPU_SHADERS] +Memoria texture: [TEXTURE_MEMORY] MB +Data/ora creazione VFS (cache): [VFS_TIME] + </string> + <string name="AboutLibs"> + Versione J2C Decoder: [J2C_VERSION] Versione Driver audio: [AUDIO_DRIVER_VERSION] Versione LLCEFLib/CEF: [LLCEFLIB_VERSION] -Versione server voce: [VOICE_VERSION] +Versione LibVLC: [LIBVLC_VERSION] +Versione Server voice: [VOICE_VERSION] </string> <string name="AboutTraffic"> Pacchetti perduti: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) </string> + <string name="AboutTime"> + [day, datetime, slt] [month, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> <string name="ErrorFetchingServerReleaseNotesURL"> Errore nel recupero URL note rilascio versione </string> + <string name="BuildConfiguration"> + Costruisci configurazione + </string> <string name="ProgressRestoring"> Ripristino in corso... </string> @@ -1077,6 +1100,9 @@ Prova ad accedere nuovamente tra un minuto. <string name="TeleportYourAgent"> Teleportarti </string> + <string name="ForceSitAvatar"> + Forza l'avatar a sedersi + </string> <string name="AgentNameSubst"> (Tu) </string> @@ -1381,6 +1407,9 @@ Prova ad accedere nuovamente tra un minuto. <string name="BodyPartsRightLeg"> Gamba destra </string> + <string name="BodyPartsEnhancedSkeleton"> + Scheletro avanzato + </string> <string name="GraphicsQualityLow"> Basso </string> @@ -1823,6 +1852,51 @@ Prova ad accedere nuovamente tra un minuto. <string name="Avatar Center"> Centro avatar </string> + <string name="Left Ring Finger"> + Anulare sinistro + </string> + <string name="Right Ring Finger"> + Anulare destro + </string> + <string name="Tail Base"> + Base della coda + </string> + <string name="Tail Tip"> + Punta della coda + </string> + <string name="Left Wing"> + Ala sinistra + </string> + <string name="Right Wing"> + Ala destra + </string> + <string name="Jaw"> + Mandibola + </string> + <string name="Alt Left Ear"> + Altro orecchio sinistro + </string> + <string name="Alt Right Ear"> + Altro orecchio destro + </string> + <string name="Alt Left Eye"> + Altro occhio sinistro + </string> + <string name="Alt Right Eye"> + Altro occhio destro + </string> + <string name="Tongue"> + Lingua + </string> + <string name="Groin"> + Inguine + </string> + <string name="Left Hind Foot"> + Piede posteriore sinistro + </string> + <string name="Right Hind Foot"> + Piede posteriore destro + </string> <string name="Invalid Attachment"> Punto di collegamento non valido </string> @@ -1868,6 +1942,27 @@ Prova ad accedere nuovamente tra un minuto. <string name="av_render_anyone"> Tutte le persone vicine a te potrebbero non eseguire il tuo rendering. </string> + <string name="hud_description_total"> + Il tuo HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (indossato su [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] fa uso di molta memoria texture + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] contiene molti oggetti e texture che occupano una grande quantità di risorse + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] contiene molte texture di grandi dimensioni + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] contiene troppi oggetti + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] contiene troppe texture + </string> <string name="AgeYearsA"> [COUNT] anno </string> @@ -2027,6 +2122,9 @@ Prova ad accedere nuovamente tra un minuto. <string name="ObjectOutOfRange"> Script (oggetto fuori portata) </string> + <string name="ScriptWasDeleted"> + Script (eliminato da inventario) + </string> <string name="GodToolsObjectOwnedBy"> Oggetto [OBJECT] di proprietà di [OWNER] </string> @@ -2212,12 +2310,12 @@ Prova ad accedere nuovamente tra un minuto. <string name="ATTACH_BELLY"> Addome </string> - <string name="ATTACH_RPEC"> - Petto destro - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Petto sinistro </string> + <string name="ATTACH_RIGHT_PEC"> + Petto destro + </string> <string name="ATTACH_HUD_CENTER_2"> HUD in centro 2 </string> @@ -2248,6 +2346,51 @@ Prova ad accedere nuovamente tra un minuto. <string name="ATTACH_AVATAR_CENTER"> Centro avatar </string> + <string name="ATTACH_LHAND_RING1"> + Anulare sinistro + </string> + <string name="ATTACH_RHAND_RING1"> + Anulare destro + </string> + <string name="ATTACH_TAIL_BASE"> + Base della coda + </string> + <string name="ATTACH_TAIL_TIP"> + Punta della coda + </string> + <string name="ATTACH_LWING"> + Ala sinistra + </string> + <string name="ATTACH_RWING"> + Ala destra + </string> + <string name="ATTACH_FACE_JAW"> + Mandibola + </string> + <string name="ATTACH_FACE_LEAR"> + Altro orecchio sinistro + </string> + <string name="ATTACH_FACE_REAR"> + Altro orecchio destro + </string> + <string name="ATTACH_FACE_LEYE"> + Altro occhio sinistro + </string> + <string name="ATTACH_FACE_REYE"> + Altro occhio destro + </string> + <string name="ATTACH_FACE_TONGUE"> + Lingua + </string> + <string name="ATTACH_GROIN"> + Inguine + </string> + <string name="ATTACH_HIND_LFOOT"> + Piede posteriore sinistro + </string> + <string name="ATTACH_HIND_RFOOT"> + Piede posteriore destro + </string> <string name="CursorPos"> Riga [LINE], Colonna [COLUMN] </string> @@ -2552,6 +2695,15 @@ Tipi conosciuti .wav, .tga, .bmp, .jpg, .jpeg, or .bvh <string name="Play Media"> Riproduci/Pausa supporto </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=en-us + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> <string name="MBCmdLineError"> Un errore è stato riscontrato analizzando la linea di comando. Per informazioni: http://wiki.secondlife.com/wiki/Client_parameters @@ -4174,6 +4326,12 @@ Se il messaggio persiste, contatta [SUPPORT_SITE]. <string name="OfflineStatus"> Offline </string> + <string name="not_online_msg"> + Utente non online - il messaggio verrà memorizzato e inviato più tardi. + </string> + <string name="not_online_inventory"> + Utente non online - l'inventario è stato salvato + </string> <string name="answered_call"> Risposto alla chiamata </string> @@ -4291,12 +4449,18 @@ Se il messaggio persiste, contatta [SUPPORT_SITE]. <string name="paid_you_ldollars"> [NAME] ti ha inviato un pagamento di L$[AMOUNT] [REASON]. </string> + <string name="paid_you_ldollars_gift"> + [NAME] ti ha inviato un pagamento di L$ [AMOUNT]: [REASON] + </string> <string name="paid_you_ldollars_no_reason"> [NAME] ti ha inviato un pagamento di L$[AMOUNT]. </string> <string name="you_paid_ldollars"> Hai inviato un pagamento di L$[AMOUNT] a [NAME] [REASON]. </string> + <string name="you_paid_ldollars_gift"> + Hai inviato un pagamento di L$ [AMOUNT] a [NAME]: [REASON] + </string> <string name="you_paid_ldollars_no_info"> Hai pagato L$ [AMOUNT]. </string> @@ -4309,6 +4473,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE]. <string name="you_paid_failure_ldollars"> Non hai pagato [NAME] L$[AMOUNT] [REASON]. </string> + <string name="you_paid_failure_ldollars_gift"> + Non hai inviato un pagamento di L$ [AMOUNT] a [NAME]: [REASON] + </string> <string name="you_paid_failure_ldollars_no_info"> Non hai pagato L$ [AMOUNT]. </string> @@ -4635,6 +4802,15 @@ Segnala abuso <string name="texture_load_dimensions_error"> Impossibile caricare immagini di dimensioni superiori a [WIDTH]*[HEIGHT] </string> + <string name="outfit_photo_load_dimensions_error"> + Le dimensioni massime delle foto di vestiario sono [WIDTH]*[HEIGHT]. Ridimensiona l'immagine o usane un'altra + </string> + <string name="outfit_photo_select_dimensions_error"> + Le dimensioni massime delle foto di vestiario sono [WIDTH]*[HEIGHT]. Seleziona un'altra texture + </string> + <string name="outfit_photo_verify_dimensions_error"> + Impossibile verificare le dimensioni della foto. Attendi che le dimensioni siano visualizzate nel selettore. + </string> <string name="words_separator" value=","/> <string name="server_is_down"> Nonostante i nostri tentativi, si è verificato un errore imprevisto. @@ -5139,6 +5315,9 @@ Prova a racchiudere il percorso dell'editor in doppie virgolette. <string name="Command_Profile_Label"> Profilo </string> + <string name="Command_Report_Abuse_Label"> + Segnala abuso + </string> <string name="Command_Search_Label"> Ricerca </string> @@ -5229,6 +5408,9 @@ Prova a racchiudere il percorso dell'editor in doppie virgolette. <string name="Command_Profile_Tooltip"> Modifica o visualizza il tuo profilo </string> + <string name="Command_Report_Abuse_Tooltip"> + Segnala abuso + </string> <string name="Command_Search_Tooltip"> Trova luoghi, eventi, persone </string> diff --git a/indra/newview/skins/default/xui/ja/floater_model_preview.xml b/indra/newview/skins/default/xui/ja/floater_model_preview.xml index 108892dd6db208ca4c9ef437b34afd86e9cff6b2..c22aaaf4c411ae20fb8cdf116c69fcba72da9c51 100644 --- a/indra/newview/skins/default/xui/ja/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/ja/floater_model_preview.xml @@ -245,6 +245,7 @@ </text> <check_box label="スã‚ンã®é‡ã•ã‚’å«ã‚€" name="upload_skin"/> <check_box label="ジョイントãƒã‚¸ã‚·ãƒ§ãƒ³ã‚’å«ã‚€" name="upload_joints"/> + <check_box label="ジョイントä½ç½®ãŒå®šç¾©ã•ã‚Œã¦ã„ã‚‹å ´åˆã€ã‚¹ã‚±ãƒ¼ãƒ«ã‚’ãƒãƒƒã‚¯" name="lock_scale_if_joint_position"/> <text name="pelvis_offset_label"> Z オフセット(アãƒã‚¿ãƒ¼ã‚’上下調整): </text> diff --git a/indra/newview/skins/default/xui/ja/floater_pay.xml b/indra/newview/skins/default/xui/ja/floater_pay.xml index 0ca0990bd43fe24a0e1f2dc48cbcacce65cb34ad..7807fdf7b4d89a61af7e19730610398945c54f27 100644 --- a/indra/newview/skins/default/xui/ja/floater_pay.xml +++ b/indra/newview/skins/default/xui/ja/floater_pay.xml @@ -1,9 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Give Money" title=""> - <string name="payee_group">グループã«æ”¯æ‰•ã†</string> - <string name="payee_resident">ä½äººã«æ”¯æ‰•ã†</string> - <text name="paying_text">支払ä¸:</text> - <text name="payee_name">éžå¸¸ã«é•·ã„åå‰ãŒé€”ä¸ã§åˆ‡ã‚Œã¦ã„ãªã„ã‹ã‚’テストã—ã¦ç¢ºèª</text> + <string name="payee_group"> + グループã«æ”¯æ‰•ã† + </string> + <string name="payee_resident"> + ä½äººã«æ”¯æ‰•ã† + </string> + <text name="paying_text"> + 支払ä¸: + </text> + <text name="payee_name"> + éžå¸¸ã«é•·ã„åå‰ãŒé€”ä¸ã§åˆ‡ã‚Œã¦ã„ãªã„ã‹ã‚’テストã—ã¦ç¢ºèª + </text> + <text name="payment_message_label"> + 説明(任æ„é …ç›®ï¼‰ï¼š + </text> <panel label="検索" name="PatternsPanel"> <button label="L$ 1 支払ã†" label_selected="L$ 1 支払ã†" name="fastpay 1"/> <button label="L$ 5 支払ã†" label_selected="L$ 5 支払ã†" name="fastpay 5"/> @@ -11,7 +22,9 @@ <button label="L$ 20 支払ã†" label_selected="L$ 20 支払ã†" name="fastpay 20"/> </panel> <panel label="検索" name="InputPanel"> - <text name="amount text">ãã®ä»–ã®é‡‘é¡:</text> + <text name="amount text"> + ãã®ä»–ã®é‡‘é¡: + </text> <button label="支払ã„" label_selected="支払ã„" name="pay btn"/> <button label="å–り消ã—" label_selected="å–り消ã—" name="cancel btn"/> </panel> diff --git a/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml index a95c45c275f2e051bb4e9c98a672d92dc1d4981d..db4e086c13a1db33eb2454e6b99f92a7567ec428 100644 --- a/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> ã‚¢ãƒã‚¿ãƒ¼ </text> - <slider label="最大ã®è¤‡é›‘ã•ï¼š" name="IndirectMaxComplexity" tool_tip="ã©ã®æ™‚点ã§è¤‡é›‘ãªè¡¨ç¤ºã®ã‚¢ãƒã‚¿ãƒ¼ã‚’ベタ色ã®äººå½¢ã¨ã—ã¦è¡¨ç¤ºã™ã‚‹ã‹ã‚’管ç†ã—ã¾ã™"/> + <slider label="最大ã®è¤‡é›‘ã•ï¼š" name="IndirectMaxComplexity" tool_tip="ã©ã®ç‚¹ã§è¦–覚的ã«è¤‡é›‘ãªã‚¢ãƒã‚¿ãƒ¼ã‚’ JellyDoll ã¨ã—ã¦æãã‹ã‚’制御ã—ã¾ã™"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/ja/floater_script_queue.xml b/indra/newview/skins/default/xui/ja/floater_script_queue.xml index 97e79fb483fa3f061ab6166c0871a113aa9300a8..de0c4469c1f56f5932a1e38cad156eb7efb5d035 100644 --- a/indra/newview/skins/default/xui/ja/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/ja/floater_script_queue.xml @@ -15,5 +15,11 @@ <floater.string name="NotRunning"> 実行ã•ã‚Œã¦ã„ã¾ã›ã‚“ </floater.string> + <floater.string name="Timeout"> + タイムアウト: [OBJECT_NAME] + </floater.string> + <floater.string name="LoadingObjInv"> + 次ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚’ãƒãƒ¼ãƒ‰ä¸ï¼š [OBJECT_NAME] + </floater.string> <button label="é–‰ã˜ã‚‹" label_selected="é–‰ã˜ã‚‹" name="close"/> </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_web_content.xml b/indra/newview/skins/default/xui/ja/floater_web_content.xml index 48fe8aee78db3aa169c6d6b9d078f20c15dedfce..d57cd4e297f05e6c4eac68bcbf557b19727c6c4f 100644 --- a/indra/newview/skins/default/xui/ja/floater_web_content.xml +++ b/indra/newview/skins/default/xui/ja/floater_web_content.xml @@ -10,5 +10,9 @@ <icon name="media_secure_lock_flag" tool_tip="安全ãªé–²è¦§"/> <button name="popexternal" tool_tip="ã“ã® URL をブラウザã§é–‹ã"/> </layout_panel> + <layout_panel name="debug_controls"> + <button name="web_test_home_page" tool_tip="Web テストã®ãƒ›ãƒ¼ãƒ ページ"/> + <button name="VLC Plugin Test" tool_tip="MPEG4 ビデオテスト"/> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/ja/menu_attachment_other.xml b/indra/newview/skins/default/xui/ja/menu_attachment_other.xml index 7705dd909030cf66d5e7347f01cd5f3e55f41641..23357ebbc2b2b60972f5e078e4758bcfbac0d196 100644 --- a/indra/newview/skins/default/xui/ja/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/ja/menu_attachment_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="コール" name="Call"/> <menu_item_call label="グループã«æ‹›å¾…" name="Invite..."/> + <menu_item_call label="スケルトンをリセット" name="Reset Skeleton"/> + <menu_item_call label="スケルトンã¨ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’リセット" name="Reset Skeleton And Animations"/> <menu_item_call label="ブãƒãƒƒã‚¯" name="Avatar Mute"/> <menu_item_call label="å ±å‘Š" name="abuse"/> <menu_item_call label="フリーズ" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/ja/menu_attachment_self.xml b/indra/newview/skins/default/xui/ja/menu_attachment_self.xml index e7aa3cfc301783cae87fc22e340705322a306b84..fa1137c7c5887cc97cad3a0b3c70b84783afe661 100644 --- a/indra/newview/skins/default/xui/ja/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/ja/menu_attachment_self.xml @@ -9,6 +9,8 @@ <menu_item_call label="アウトフィットã®ç·¨é›†" name="Edit Outfit"/> <menu_item_call label="シェイプã®ç·¨é›†" name="Edit My Shape"/> <menu_item_call label="ホãƒãƒ¼é«˜ã•" name="Hover Height"/> + <menu_item_call label="スケルトンをリセット" name="Reset Skeleton"/> + <menu_item_call label="スケルトンã¨ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’リセット" name="Reset Skeleton And Animations"/> <menu_item_call label="フレンド" name="Friends..."/> <menu_item_call label="グループ" name="Groups..."/> <menu_item_call label="プãƒãƒ•ã‚£ãƒ¼ãƒ«" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/ja/menu_avatar_other.xml b/indra/newview/skins/default/xui/ja/menu_avatar_other.xml index 482f2bdaa5f21e4923fb4bb16e07512502ed46c2..1902c9b359f7dd2b78cb2c39ab2734ef557ce0dc 100644 --- a/indra/newview/skins/default/xui/ja/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/ja/menu_avatar_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="コール" name="Call"/> <menu_item_call label="グループã«æ‹›å¾…" name="Invite..."/> + <menu_item_call label="スケルトンをリセット" name="Reset Skeleton"/> + <menu_item_call label="スケルトンã¨ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’リセット" name="Reset Skeleton And Animations"/> <menu_item_call label="ブãƒãƒƒã‚¯" name="Avatar Mute"/> <menu_item_call label="å ±å‘Š" name="abuse"/> <menu_item_call label="フリーズ" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/ja/menu_avatar_self.xml b/indra/newview/skins/default/xui/ja/menu_avatar_self.xml index a14cfd58767bc4e9b6948725e85ae391149db52c..b0a619bcb09e9933b705a95c7e7bc913d236f50b 100644 --- a/indra/newview/skins/default/xui/ja/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/ja/menu_avatar_self.xml @@ -26,6 +26,8 @@ <menu_item_call label="アウトフィットを編集" name="Edit Outfit"/> <menu_item_call label="シェイプを編集" name="Edit My Shape"/> <menu_item_call label="ホãƒãƒ¼é«˜ã•" name="Hover Height"/> + <menu_item_call label="スケルトンをリセット" name="Reset Skeleton"/> + <menu_item_call label="スケルトンã¨ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’リセット" name="Reset Skeleton And Animations"/> <menu_item_call label="フレンド" name="Friends..."/> <menu_item_call label="グループ" name="Groups..."/> <menu_item_call label="プãƒãƒ•ã‚£ãƒ¼ãƒ«" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/ja/menu_login.xml b/indra/newview/skins/default/xui/ja/menu_login.xml index abf7bce067f65b847b50685d5ecdd538e6ac0f68..71f36b17be547a2afeb95e4a1d98526b4cd45f0c 100644 --- a/indra/newview/skins/default/xui/ja/menu_login.xml +++ b/indra/newview/skins/default/xui/ja/menu_login.xml @@ -20,13 +20,12 @@ <menu_item_check label="デãƒãƒƒã‚°ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚’表示ã™ã‚‹" name="Show Debug Menu"/> <menu label="デãƒãƒƒã‚°" name="Debug"> <menu_item_call label="デãƒãƒƒã‚°è¨å®šã‚’表示" name="Debug Settings"/> - <menu_item_call label="UI/色ã®è¨å®š" name="UI/Color Settings"/> <menu_item_call label="XUI プレビューツール" name="UI Preview Tool"/> <menu label="UI テスト" name="UI Tests"/> <menu_item_call label="ウィンドウã®ã‚µã‚¤ã‚ºã‚’è¨å®š..." name="Set Window Size..."/> <menu_item_call label="利用è¦ç´„を表示" name="TOS"/> <menu_item_call label="クリティカルメッセージを表示" name="Critical"/> - <menu_item_call label="Web コンテンツフãƒãƒ¼ã‚¿ãƒ¼ã®ãƒ‡ãƒãƒƒã‚°ãƒ†ã‚¹ãƒˆ" name="Web Content Floater Debug Test"/> + <menu_item_call label="メディアブラウザ" name="Media Browser"/> <menu label="ãƒã‚°ãƒ¬ãƒ™ãƒ«ã‚’è¨å®š" name="Set Logging Level"> <menu_item_check label="デãƒãƒƒã‚°" name="Debug"/> <menu_item_check label="æƒ…å ±" name="Info"/> diff --git a/indra/newview/skins/default/xui/ja/menu_object_icon.xml b/indra/newview/skins/default/xui/ja/menu_object_icon.xml index 6448e9244ecdca6831aa9ff5f6382bd14449c59f..7b55a64eefaf2c0ae408a336417a663afd46116c 100644 --- a/indra/newview/skins/default/xui/ja/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/ja/menu_object_icon.xml @@ -2,6 +2,7 @@ <menu name="Object Icon Menu"> <menu_item_call label="オブジェクトã®ãƒ—ãƒãƒ•ã‚£ãƒ¼ãƒ«..." name="Object Profile"/> <menu_item_call label="ブãƒãƒƒã‚¯..." name="Block"/> + <menu_item_call label="ブãƒãƒƒã‚¯è§£é™¤" name="Unblock"/> <menu_item_call label="地図ã«è¡¨ç¤º" name="show_on_map"/> <menu_item_call label="オブジェクトã®å ´æ‰€ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆ" name="teleport_to_object"/> </menu> diff --git a/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml b/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml index 1969ae2a102598320eda1d269e51b4eb2cd9f4e0..5e02fd3b8f39ade54572ca4509daf729dee8a9d3 100644 --- a/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml @@ -3,6 +3,10 @@ <menu_item_call label="ç€ã‚‹ - ç€ç”¨ä¸ã®ã‚¢ã‚¦ãƒˆãƒ•ã‚£ãƒƒãƒˆã‚’入れ替ãˆã‚‹" name="wear"/> <menu_item_call label="ç€ã‚‹ - ç€ç”¨ä¸ã®ã‚¢ã‚¦ãƒˆãƒ•ã‚£ãƒƒãƒˆã«è¿½åŠ ã™ã‚‹" name="wear_add"/> <menu_item_call label="å–り外㙠- ç€ç”¨ä¸ã®ã‚¢ã‚¦ãƒˆãƒ•ã‚£ãƒƒãƒˆã‹ã‚‰å–り除ã" name="take_off"/> + <menu_item_call label="写真をアップãƒãƒ¼ãƒ‰ï¼ˆL$10)" name="upload_photo"/> + <menu_item_call label="写真をé¸æŠž" name="select_photo"/> + <menu_item_call label="スナップショットを撮る" name="take_snapshot"/> + <menu_item_call label="写真を削除" name="remove_photo"/> <menu label="衣類" name="New Clothes"> <menu_item_call label="シャツ" name="New Shirt"/> <menu_item_call label="パンツ" name="New Pants"/> @@ -27,4 +31,5 @@ <menu_item_call label="フォルダをã™ã¹ã¦é–‰ã˜ã‚‹" name="collapse"/> <menu_item_call label="アウトフィットã®åå‰ã‚’変更ã™ã‚‹" name="rename"/> <menu_item_call label="アウトフィットを削除ã™ã‚‹" name="delete_outfit"/> + <menu_item_check label="フォルダを常ã«åå‰é †ã«ä¸¦ã¹ã‚‹" name="sort_folders_by_name"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/ja/menu_people_friends_view.xml b/indra/newview/skins/default/xui/ja/menu_people_friends_view.xml index b95d11fdbdcfed97f5d53b73cbdb60f1d809e22d..f290bec652bd0c6ee8b1d7152052c383ebaf2cd8 100644 --- a/indra/newview/skins/default/xui/ja/menu_people_friends_view.xml +++ b/indra/newview/skins/default/xui/ja/menu_people_friends_view.xml @@ -4,5 +4,6 @@ <menu_item_check label="オンライン状æ³ã§ä¸¦ã¹æ›¿ãˆ" name="sort_status"/> <menu_item_check label="人ã®ã‚¢ã‚¤ã‚³ãƒ³è¡¨ç¤º" name="view_icons"/> <menu_item_check label="与ãˆã‚‰ã‚ŒãŸæ¨©é™ã‚’表示" name="view_permissions"/> + <menu_item_check label="ユーザーåã‚’éžè¡¨ç¤º" name="view_usernames"/> <menu_item_check label="会話ãƒã‚°ã‚’表示..." name="view_conversation"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/ja/menu_people_nearby.xml b/indra/newview/skins/default/xui/ja/menu_people_nearby.xml index 972ab767bf4bb6a58731c4c9b9be1237a05f5449..87f1d26ca43b0495b1a3ab328f10db32ba55a7d4 100644 --- a/indra/newview/skins/default/xui/ja/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/ja/menu_people_nearby.xml @@ -13,4 +13,6 @@ <menu_item_call label="共有" name="share"/> <menu_item_call label="支払ã„" name="pay"/> <menu_item_check label="ブãƒãƒƒã‚¯ãƒ»ãƒ–ãƒãƒƒã‚¯è§£é™¤" name="block_unblock"/> + <menu_item_call label="フリーズ" name="freeze"/> + <menu_item_call label="追放" name="eject"/> </context_menu> diff --git a/indra/newview/skins/default/xui/ja/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/ja/menu_people_nearby_view.xml index b7cccc4396d660b5367a944b0bc21b3d3ac90742..9330a8e4848881da91e50cd3d9b2cfd7e28b48a5 100644 --- a/indra/newview/skins/default/xui/ja/menu_people_nearby_view.xml +++ b/indra/newview/skins/default/xui/ja/menu_people_nearby_view.xml @@ -5,4 +5,5 @@ <menu_item_check label="è·é›¢ã§ä¸¦ã¹æ›¿ãˆ" name="sort_distance"/> <menu_item_check label="人ã®ã‚¢ã‚¤ã‚³ãƒ³è¡¨ç¤º" name="view_icons"/> <menu_item_check label="地図を表示" name="view_map"/> + <menu_item_check label="ユーザーåã‚’éžè¡¨ç¤º" name="view_usernames"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/ja/menu_url_objectim.xml b/indra/newview/skins/default/xui/ja/menu_url_objectim.xml index a02ca8415d3fc665ffba504144237484a8bcdb24..96f8b3f7b1b881d427cc819670d0893c92e4f1bd 100644 --- a/indra/newview/skins/default/xui/ja/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/ja/menu_url_objectim.xml @@ -2,6 +2,7 @@ <context_menu name="Url Popup"> <menu_item_call label="オブジェクトã®ãƒ—ãƒãƒ•ã‚£ãƒ¼ãƒ«..." name="show_object"/> <menu_item_call label="ブãƒãƒƒã‚¯..." name="block_object"/> + <menu_item_call label="ブãƒãƒƒã‚¯è§£é™¤" name="unblock_object"/> <menu_item_call label="地図ã«è¡¨ç¤º" name="show_on_map"/> <menu_item_call label="オブジェクトã®å ´æ‰€ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆ" name="teleport_to_object"/> <menu_item_call label="オブジェクトåをクリップボードã«ã‚³ãƒ”ー" name="url_copy_label"/> diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml index 3c2e29486837521acd6d8074b99a54229b4a9dec..e0834eb12d8a0ce514961278618f45b6315b9fce 100644 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="ç€ä¿¡æ‹’å¦" name="Do Not Disturb"/> </menu> <menu_item_call label="L$ ã®è³¼å…¥..." name="Buy and Sell L$"/> - <menu_item_call label="マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹..." name="MerchantOutbox"/> <menu_item_call label="マーケティングプレイスã®ãƒªã‚¹ãƒˆ..." name="MarketplaceListings"/> <menu_item_call label="マイアカウント..." name="Manage My Account"> <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=ja"/> @@ -114,11 +113,11 @@ <menu_item_call label="リンク" name="Link"/> <menu_item_call label="リンクを外ã™" name="Unlink"/> <menu_item_check label="リンクã—ãŸéƒ¨åˆ†ã‚’編集" name="Edit Linked Parts"/> - <menu label="リンクã—ãŸéƒ¨åˆ†ã‚’é¸æŠžã™ã‚‹" name="Select Linked Parts"> - <menu_item_call label="次ã®éƒ¨åˆ†ã‚’é¸æŠžã™ã‚‹" name="Select Next Part"/> - <menu_item_call label="å‰å›žã®éƒ¨åˆ†ã‚’é¸æŠžã™ã‚‹" name="Select Previous Part"/> - <menu_item_call label="次ã®éƒ¨åˆ†ã‚’å«ã‚ã‚‹" name="Include Next Part"/> - <menu_item_call label="å‰å›žã®éƒ¨åˆ†ã‚’å«ã‚ã‚‹" name="Include Previous Part"/> + <menu label="è¦ç´ ã‚’é¸æŠž" name="Select Elements"> + <menu_item_call label="次ã®ãƒ‘ーツã¾ãŸã¯é¢ã‚’é¸æŠž" name="Select Next Part or Face"/> + <menu_item_call label="å‰ã®ãƒ‘ーツã¾ãŸã¯é¢ã‚’é¸æŠž" name="Select Previous Part or Face"/> + <menu_item_call label="次ã®ãƒ‘ーツã¾ãŸã¯é¢ã‚’å«ã‚ã‚‹" name="Include Next Part or Face"/> + <menu_item_call label="å‰ã®ãƒ‘ーツã¾ãŸã¯é¢ã‚’å«ã‚ã‚‹" name="Include Previous Part or Face"/> </menu> <menu_item_call label="リンクセット..." name="pathfinding_linkset_menu_item"/> <menu_item_call label="é¸æŠžã—ãŸã‚‚ã®ã«ç„¦ç‚¹ã‚’åˆã‚ã›ã‚‹" name="Focus on Selection"/> @@ -369,8 +368,7 @@ <menu_item_call label="リージョンオブジェクトã®ã‚ャッシュをダンプ" name="Dump Region Object Cache"/> </menu> <menu label="UI" name="UI"> - <menu_item_call label="メディアブラウザã®ãƒ†ã‚¹ãƒˆ" name="Web Browser Test"/> - <menu_item_call label="Web コンテンツブラウザ" name="Web Content Browser"/> + <menu_item_call label="メディアブラウザ" name="Media Browser"/> <menu_item_call label="SelectMgr をダンプ" name="Dump SelectMgr"/> <menu_item_call label="インベントリã®å‡ºåŠ›" name="Dump Inventory"/> <menu_item_call label="タイマーをダンプ" name="Dump Timers"/> @@ -421,6 +419,7 @@ <menu_item_check label="LOD を無効ã«ã™ã‚‹" name="Disable LOD"/> <menu_item_check label="ã‚ャラクター Vis ã®ãƒ‡ãƒãƒƒã‚°" name="Debug Character Vis"/> <menu_item_check label="骨組ã¿ã®è¡çªåˆ¤å®šã‚’表示ã™ã‚‹" name="Show Collision Skeleton"/> + <menu_item_check label="骨を表示" name="Show Bones"/> <menu_item_check label="エージェントã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚’表示ã™ã‚‹" name="Display Agent Target"/> <menu_item_call label="アタッãƒãƒ¡ãƒ³ãƒˆã‚’ダンプ" name="Dump Attachments"/> <menu_item_call label="ã‚¢ãƒã‚¿ãƒ¼ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’デãƒãƒƒã‚°" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml b/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml index 9effed1f42b52a8036a806680ef2f59a057d102a..bf8e72e4572615ddf7dced052d8e570194c17cac 100644 --- a/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml @@ -3,4 +3,6 @@ <menu_item_call label="å–り外ã™" name="take_off"/> <menu_item_call label="å–り外ã™" name="detach"/> <menu_item_call label="アウトフットã®ç·¨é›†" name="edit"/> + <menu_item_call label="編集" name="edit_item"/> + <menu_item_call label="オリジナルを表示" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/ja/mime_types.xml b/indra/newview/skins/default/xui/ja/mime_types.xml index bfc8d0b724440adb65bcf884ac39d2f443798432..6de9244b40283d1cc2f469292e4c0a32681d1487 100644 --- a/indra/newview/skins/default/xui/ja/mime_types.xml +++ b/indra/newview/skins/default/xui/ja/mime_types.xml @@ -22,14 +22,6 @@ ムービーå†ç”Ÿ </playtip> </widgetset> - <widgetset name="none"> - <label name="none_label"> - コンテンツãªã— - </label> - <tooltip name="none_tooltip"> - ã“ã“ã«ãƒ¡ãƒ‡ã‚£ã‚¢ãªã— - </tooltip> - </widgetset> <widgetset name="image"> <label name="image_label"> ç”»åƒ @@ -52,11 +44,24 @@ ã“ã“ã®ã‚ªãƒ¼ãƒ‡ã‚£ã‚ªã‚’å†ç”Ÿã™ã‚‹ </playtip> </widgetset> + <widgetset name="none"> + <label name="none_label"> + コンテンツãªã— + </label> + <tooltip name="none_tooltip"> + ã“ã“ã«ãƒ¡ãƒ‡ã‚£ã‚¢ãªã— + </tooltip> + </widgetset> <scheme name="rtsp"> <label name="rtsp_label"> リアルタイム・ストリーミング </label> </scheme> + <scheme name="libvlc"> + <label name="libvlc_label"> + LibVLC 対応メディア + </label> + </scheme> <mimetype name="blank"> <label name="blank_label"> -- ãªã— -- @@ -127,11 +132,6 @@ Macromedia Director </label> </mimetype> - <mimetype name="application/x-shockwave-flash"> - <label name="application/x-shockwave-flash_label"> - Flash - </label> - </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> オーディオ (MIDI) @@ -207,6 +207,11 @@ ムービー (MP4) </label> </mimetype> + <mimetype name="application/octet-stream"> + <label name="video/octet-stream"> + ムービー + </label> + </mimetype> <mimetype menu="1" name="video/quicktime"> <label name="video/quicktime_label"> ムービー (QuickTime) diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index a573e86e5f6e6f532f65dbb6a5f4276a7f60eaab..00d9b3ca5c5590dc27b3067a2ed02a819fe48a2f 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -337,6 +337,9 @@ [COUNT] åã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’グループã‹ã‚‰è¿½æ”¾ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ <usetemplate ignoretext="グループã‹ã‚‰ã®è¤‡æ•°ã®ãƒ¡ãƒ³ãƒãƒ¼ã®è¿½æ”¾ã‚’確èªã—ã¾ã™" name="okcancelignore" notext="å–り消ã—" yestext="ç¦æ¢"/> </notification> + <notification name="GroupBanUserOnBanlist"> + 一部ã®ä½äººãŒã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰è¿½æ”¾ã•ã‚ŒãŸãŸã‚ã€æ‹›å¾…状ãŒé€ã‚‰ã‚Œã¾ã›ã‚“ã§ã—ãŸã€‚ + </notification> <notification name="AttachmentDrop"> アタッãƒãƒ¡ãƒ³ãƒˆã‚’下ã«ç½®ã“ã†ã¨ã—ã¦ã„ã¾ã™ã€‚ 続ã‘ã¾ã™ã‹ï¼Ÿ @@ -475,6 +478,12 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ã <notification name="ErrorEncodingSnapshot"> スナップショットã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰åŒ–ã§ã‚¨ãƒ©ãƒ¼ãŒå‡ºã¾ã—ãŸï¼ </notification> + <notification name="ErrorPhotoCannotAfford"> + インベントリã«å†™çœŸã‚’ä¿å˜ã™ã‚‹ã«ã¯ L$[COST] ãŒå¿…è¦ã§ã™ã€‚L$ を購入ã™ã‚‹ã‹ã€ä»£ã‚ã‚Šã«å†™çœŸã‚’ã£ã‚³ãƒ³ãƒ”ュータã«ä¿å˜ã§ãã¾ã™ã€‚ + </notification> + <notification name="ErrorTextureCannotAfford"> + インベントリã«ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’ä¿å˜ã™ã‚‹ã«ã¯ L$[COST] ãŒå¿…è¦ã§ã™ã€‚L$ を購入ã™ã‚‹ã‹ã€ä»£ã‚ã‚Šã«å†™çœŸã‚’コンピュータã«ä¿å˜ã§ãã¾ã™ã€‚ + </notification> <notification name="ErrorUploadingPostcard"> 次ã®ç†ç”±ã§ã€ã‚¹ãƒŠãƒƒãƒ—ショットã®é€ä¿¡æ™‚ã«å•é¡ŒãŒèµ·ã“ã‚Šã¾ã—ãŸï¼š [REASON] </notification> @@ -498,6 +507,9 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ã <notification name="CannotWearInfoNotComplete"> ã¾ã èªã¿è¾¼ã¾ã‚Œã¦ã„ãªã„ãŸã‚ã€ãã®ã‚¢ã‚¤ãƒ†ãƒ を装ç€ã§ãã¾ã›ã‚“。後ã§ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。 </notification> + <notification name="MustEnterPasswordToLogIn"> + ãƒã‚°ã‚¤ãƒ³ã™ã‚‹ãŸã‚ã«ãƒ‘スワードを入力ã—ã¦ãã ã•ã„ + </notification> <notification name="MustHaveAccountToLogIn"> 注æ„:記入æ¼ã‚Œã®ç®‡æ‰€ãŒã‚ã‚Šã¾ã™ã€‚ ã‚¢ãƒã‚¿ãƒ¼ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åを入力ã—ã¦ãã ã•ã„。 @@ -566,6 +578,9 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ã <notification name="ChangeConnectionPort"> ãƒãƒ¼ãƒˆã®è¨å®šã¯ [APP_NAME] ã‚’å†èµ·å‹•å¾Œã«åæ˜ ã•ã‚Œã¾ã™ã€‚ </notification> + <notification name="ChangeDeferredDebugSetting"> + デãƒãƒƒã‚°è¨å®šã®å¤‰æ›´ã¯ [APP_NAME] ã‚’å†èµ·å‹•å¾Œã«åæ˜ ã•ã‚Œã¾ã™ã€‚ + </notification> <notification name="ChangeSkin"> æ–°ã—ã„スã‚ン㯠[APP_NAME] ã‚’å†èµ·å‹•å¾Œã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚ </notification> @@ -587,6 +602,10 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ã ノートカードを削除ã—ã¾ã™ã‹? <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> + <notification name="LoadPreviousReportScreenshot"> + 以å‰ã®ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã‚’レãƒãƒ¼ãƒˆã«ä½¿ç”¨ã—ã¾ã™ã‹? + <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> + </notification> <notification name="GestureSaveFailedTooManySteps"> ジェスãƒãƒ£ãƒ¼ã®ä¿å˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ ステップãŒå¤šã™ãŽã¾ã™ã€‚ @@ -647,32 +666,14 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ã </url> <usetemplate ignoretext="使用ä¸ã®ã‚³ãƒ³ãƒ”ューターã®ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„ã¨ã" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> </notification> - <notification name="IntelOldDriver"> - ãŠãらããŠä½¿ã„ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒãƒƒãƒ—用ã®æ–°ã—ã„ドライãƒãŒå…¥æ‰‹å¯èƒ½ã§ã™ã€‚グラフィックドライãƒã‚’æ›´æ–°ã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€ãƒ‘フォーマンスãŒå¤§å¹…ã«å‘上ã™ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚ - -[_URL] ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦æ›´æ–°ç‰ˆã®ãƒ‰ãƒ©ã‚¤ãƒãŒã‚ã‚‹ã‹ã©ã†ã‹ã‚’確èªã—ã¾ã™ã‹ï¼Ÿ - <url name="url"> - http://www.intel.com/p/ja_JP/support/detect/graphics - </url> - <usetemplate ignoretext="使用ã—ã¦ã„るグラフィックドライãƒãŒå¤ã„å ´åˆ" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> - </notification> - <notification name="AMDOldDriver"> - ãŠä½¿ã„ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒãƒƒãƒ—ã«ã¯æœ€æ–°ã®ãƒ‰ãƒ©ã‚¤ãƒãŒå˜åœ¨ã™ã‚‹ã‚ˆã†ã§ã™ã€‚グラフィックドライãƒã‚’æ›´æ–°ã™ã‚‹ã¨ã€ãƒ‘フォーマンスãŒå¤§å¹…ã«æ”¹å–„ã•ã‚Œã¾ã™ã€‚ - -[_URL] ã¸ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ã€ãƒ‰ãƒ©ã‚¤ãƒãƒ¼ã‚’æ›´æ–°ã—ã¾ã™ã‹ã€‚ - <url name="url"> - http://support.amd.com/us/Pages/AMDSupportHub.aspx - </url> - <usetemplate ignoretext="自分ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒ‰ãƒ©ã‚¤ãƒãŒæ—§ããªã‚Šã¾ã—ãŸã€‚" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> - </notification> - <notification name="NVIDIAOldDriver"> - ãŠä½¿ã„ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒãƒƒãƒ—ã«ã¯æœ€æ–°ã®ãƒ‰ãƒ©ã‚¤ãƒãŒå˜åœ¨ã™ã‚‹ã‚ˆã†ã§ã™ã€‚グラフィックドライãƒã‚’æ›´æ–°ã™ã‚‹ã¨ã€ãƒ‘フォーマンスãŒå¤§å¹…ã«æ”¹å–„ã•ã‚Œã¾ã™ã€‚ + <notification name="OldGPUDriver"> + グラフィックスãƒãƒƒãƒ—ã«æœ€æ–°ã®ãƒ‰ãƒ©ã‚¤ãƒãŒã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚グラフィックドライãƒã‚’æ›´æ–°ã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€å¤§å¹…ã«ãƒ‘フォーマンスãŒå‘上ã—ã¾ã™ã€‚ -[_URL] ã¸ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ã€ãƒ‰ãƒ©ã‚¤ãƒãƒ¼ã‚’æ›´æ–°ã—ã¾ã™ã‹ã€‚ + ドライãƒã®æ›´æ–°ã‚’確èªã™ã‚‹ãŸã‚ã« [URL] ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¾ã™ã‹? <url name="url"> - http://www.nvidia.com/Download/index.aspx?lang=en-us + [URL] </url> - <usetemplate ignoretext="自分ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒ‰ãƒ©ã‚¤ãƒãŒæ—§ããªã‚Šã¾ã—ãŸã€‚" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> + <usetemplate ignoretext="使用ä¸ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒ‰ãƒ©ã‚¤ãƒãŒå¤ããªã£ã¦ã„ã¾ã™" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/> </notification> <notification name="UnknownGPU"> ãŠä½¿ã„ã®ã‚·ã‚¹ãƒ†ãƒ ã«ã¯ã€[APP_NAME] ãŒèªè˜ã§ããªã„グラフィックカードãŒæ載ã•ã‚Œã¦ã„ã¾ã™ã€‚ @@ -761,6 +762,9 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚åŠ ã™ã‚‹ã“ã¨ãŒã§ã </url> <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> + <notification name="MuteLimitReached"> + [MUTE_LIMIT] エントリã®åˆ¶é™ã«é”ã—ãŸãŸã‚ã€ãƒ–ãƒãƒƒã‚¯ãƒªã‚¹ãƒˆã«æ–°ã—ã„ã‚¨ãƒ³ãƒˆãƒªã‚’è¿½åŠ ã§ãã¾ã›ã‚“。 + </notification> <notification name="UnableToLinkObjects"> [COUNT] 個ã®ã‚ªãƒ–ジェクトをリンクã§ãã¾ã›ã‚“。 リンクã§ãã‚‹ã®ã¯æœ€å¤§ [MAX] 個ã§ã™ã€‚ @@ -1395,12 +1399,18 @@ https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries ã‚’å‚ç…§ã—ã¦ã <ignore name="ignore" text="衣類ãŒãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã•ã‚Œã‚‹ã¾ã§æ™‚é–“ãŒã‹ã‹ã£ã¦ã„ã‚‹ã¨ã"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - ã”使用㮠[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 表示ã®è¤‡é›‘ã•] 㯠[AGENT_COMPLEXITY] ã§ã™ã€‚ + <notification name="AgentComplexityWithVisibility"> + ã‚ãªãŸã® [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] 㯠[AGENT_COMPLEXITY] ã§ã™ã€‚ [OVERLIMIT_MSG] + <usetemplate ignoretext="ã‚¢ãƒã‚¿ãƒ¼ã®è¤‡é›‘度ãŒé«˜ã™ãŽã‚‹å ´åˆã¯è¦å‘Šã™ã‚‹" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - ã”使用㮠[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 表示ã®è¤‡é›‘ã•] 㯠[AGENT_COMPLEXITY] ã§ã™ã€‚ + ã‚ãªãŸã® [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] 㯠[AGENT_COMPLEXITY] ã§ã™ã€‚ + <usetemplate ignoretext="ã‚¢ãƒã‚¿ãƒ¼ã®è¤‡é›‘ã•ã®å¤‰æ›´ã«ã¤ã„ã¦è¦å‘Šã™ã‚‹" name="notifyignore"/> + </notification> + <notification name="HUDComplexityWarning"> + [HUD_REASON]ã€ãƒ‘フォーマンスã«æ‚ªå½±éŸ¿ã‚’与ãˆã‚‹æã‚ŒãŒã‚ã‚Šã¾ã™ã€‚ + <usetemplate ignoretext="HUD ãŒè¤‡é›‘ã™ãŽã‚‹å ´åˆã¯ãŠçŸ¥ã‚‰ã›ãã ã•ã„" name="notifyignore"/> </notification> <notification name="FirstRun"> [APP_NAME] ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå®Œäº†ã—ã¾ã—ãŸã€‚ @@ -1494,6 +1504,10 @@ SHA1 フィンガープリント: [MD5_DIGEST] ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ã„ã‚‹å…¨ã¦ã®ä½äººã‚’ホームã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> + <notification name="ChangeObjectBonusFactor"> + 地域(リージョン)内ã§ãƒ“ルドãŒç¢ºç«‹ã•ã‚ŒãŸå¾Œã«ã‚ªãƒ–ジェクトボーナスを下ã’ã‚‹ã¨ã€ã‚ªãƒ–ジェクトãŒè¿”ã•ã‚ŒãŸã‚Šã€å‰Šé™¤ã•ã‚ŒãŸã‚Šã—ã¾ã™ã€‚本当ã«ã‚ªãƒ–ジェクトボーナスを変更ã—ã¾ã™ã‹? + <usetemplate ignoretext="オブジェクトボーナス係数ã®å¤‰æ›´ã‚’確èª" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> + </notification> <notification name="EstateObjectReturn"> [USER_NAME] ãŒæ‰€æœ‰ã—ã¦ã„るオブジェクトを返å´ã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="ã‚ャンセル" yestext="OK"/> @@ -1519,6 +1533,10 @@ SHA1 フィンガープリント: [MD5_DIGEST] æ“作を続行ã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + 使用ã—よã†ã¨ã—ã¦ã„る隆起範囲ã®ä½Žã„値ã¯é«˜ã„値よりも大ãããªã£ã¦ã„ã¾ã™ã€‚ãã‚Œã§ã‚‚続ã‘ã¾ã™ã‹ï¼Ÿ + <usetemplate canceltext="èžã‹ãªã„ã§ãã ã•ã„" name="yesnocancelbuttons" notext="å–り消ã—" yestext="Ok"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> 許å¯ä½äººã¯ [MAX_AGENTS] 人ã¾ã§ã§ã™ã€‚ </notification> @@ -1538,6 +1556,9 @@ SHA1 フィンガープリント: [MD5_DIGEST] <notification name="OwnerCanNotBeDenied"> ä¸å‹•ç”£ã‚ªãƒ¼ãƒŠãƒ¼ã‚’ä¸å‹•ç”£ã®ã€Œç¦æ¢ä½äººã€ãƒªã‚¹ãƒˆã«è¿½åŠ ã§ãã¾ã›ã‚“。 </notification> + <notification name="ProblemAddingEstateManagerBanned"> + 追放ã•ã‚ŒãŸä½äººã‚’ä¸å‹•ç”£ç®¡ç†è€…リストã«è¿½åŠ ã§ãã¾ã›ã‚“。 + </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> 衣類ãŠã‚ˆã³ã‚·ã‚§ã‚¤ãƒ—ãŒèªã¿è¾¼ã¾ã‚Œã‚‹ã¾ã§ã¯ã€å®¹å§¿ã®å¤‰æ›´ã¯ã§ãã¾ã›ã‚“。 </notification> @@ -1709,6 +1730,10 @@ http://secondlife.com/download ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ Web ブラウザを開ã„ã¦ã“ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„を表示ã—ã¾ã™ã‹ï¼Ÿ <usetemplate ignoretext="ブラウザを起動ã—㦠Web ページを見るã¨ã" name="okcancelignore" notext="ã‚ャンセル" yestext="OK"/> </notification> + <notification name="SystemUIScaleFactorChanged"> + å‰å›žå®Ÿè¡Œæ™‚ã‹ã‚‰ã‚·ã‚¹ãƒ†ãƒ UI サイズ係数ãŒå¤‰æ›´ã•ã‚Œã¦ã„ã¾ã™ã€‚UI サイズ調整è¨å®šãƒšãƒ¼ã‚¸ã‚’é–‹ãã¾ã™ã‹? + <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> + </notification> <notification name="WebLaunchJoinNow"> [http://jp.secondlife.com/account/ マイアカウント] ページã«ç§»å‹•ã—ã¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’管ç†ã—ã¾ã™ã‹ï¼Ÿ <usetemplate ignoretext="ブラウザを起動ã—ã¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’管ç†ã™ã‚‹ã¨ã" name="okcancelignore" notext="å–り消ã—" yestext="OK"/> @@ -1750,16 +1775,15 @@ http://secondlife.com/download ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ グループã‹ã‚‰è„±é€€ã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/> </notification> + <notification name="GroupDepart"> + グループ '[group_name]' を抜ã‘ã¾ã—ãŸã€‚ + </notification> <notification name="OwnerCannotLeaveGroup"> グループを抜ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。グループã®æœ€å¾Œã®ã‚ªãƒ¼ãƒŠãƒ¼ã§ã‚ã‚‹ãŸã‚ã€ã‚°ãƒ«ãƒ¼ãƒ—を抜ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。最åˆã«ã€åˆ¥ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’オーナーã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã¦ãã ã•ã„。 <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="GroupDepartError"> - グループを抜ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“: [reason]。 - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - グループ [group_name] を抜ã‘ã¾ã—ãŸã€‚ + グループを抜ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="ConfirmKick"> @@ -2162,6 +2186,10 @@ http://wiki.secondlife.com/wiki/Setting_your_display_name ã‚’å‚ç…§ã—ã¦ãã é¸æŠžã—ãŸãƒ—リムãŒå¤šã™ãŽã¾ã™ã€‚ [MAX_PRIM_COUNT] 個é¸æŠžã™ã‚‹ã‹ã€ãƒ—リム数を減らã—ã¦ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。 <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="TooManyScriptsSelected"> + スクリプト内ã§é¸æŠžã•ã‚ŒãŸã‚ªãƒ–ジェクトãŒå¤šã™ãŽã¾ã™ã€‚é¸æŠžã™ã‚‹ã‚ªãƒ–ジェクトを減らã—ã¦ã€ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。 + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="ProblemImportingEstateCovenant"> ä¸å‹•ç”£ç´„款ã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆæ™‚ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ <usetemplate name="okbutton" yestext="OK"/> @@ -2334,6 +2362,10 @@ L$ [AMOUNT] ã§ã€ã“ã®ã‚¯ãƒ©ã‚·ãƒ•ã‚¡ã‚¤ãƒ‰åºƒå‘Šã‚’今ã™ã公開ã—ã¾ã™ 支払ã„ãŒå¤±æ•—ã—ã¾ã—ãŸï¼š オブジェクトãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚ <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="PaymentBlockedButtonMismatch"> + 支払ã„ãŒåœæ¢ã•ã‚Œã¾ã—ãŸï¼š 支払ã‚ã‚ŒãŸä¾¡æ ¼ãŒã“ã®ã‚ªãƒ–ジェクトã«è¨å®šã•ã‚ŒãŸæ”¯æ‰•ã„ボタンã®ã©ã‚Œã¨ã‚‚一致ã—ã¾ã›ã‚“。 + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="OpenObjectCannotCopy"> ã“ã®ã‚ªãƒ–ジェクトã«ã¯ã€ã‚ãªãŸãŒã‚³ãƒ”ーã§ãるアイテムã¯ã‚ã‚Šã¾ã›ã‚“。 </notification> @@ -2369,6 +2401,12 @@ L$ [AMOUNT] ã§ã€ã“ã®ã‚¯ãƒ©ã‚·ãƒ•ã‚¡ã‚¤ãƒ‰åºƒå‘Šã‚’今ã™ã公開ã—ã¾ã™ ã“ã‚Œã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã«ã‚ˆã‚‹åºƒç¯„囲ã®é¸æŠžã§ã™ã€‚リンクを解除ã™ã‚‹ã¨ã€ã‚‚ã†ä¸€åº¦ãƒªãƒ³ã‚¯ã§ããªããªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ãã®ã‚ˆã†ãªå ´åˆã«å‚™ãˆã¦ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã‚’自分ã®æŒã¡ç‰©ã«ã‚³ãƒ”ーã§ãã¾ã™ã€‚ <usetemplate ignoretext="リンクセットã®ãƒªãƒ³ã‚¯ã‚’解除ã™ã‚‹ã¨ãã«ç¢ºèªã™ã‚‹" name="okcancelignore" notext="å–り消ã—" yestext="リンクを外ã™"/> </notification> + <notification name="HelpReportAbuseConfirm"> + ã“ã®å•é¡Œã®ã”å ±å‘Šã«ãŠæ™‚間を割ã„ã¦ã„ãŸã ãã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ +ãŠçŸ¥ã‚‰ã›ã„ãŸã ã„ãŸå†…容ã«ã¤ã„ã¦é•åãŒãªã„ã‹ç¢ºèªã—ã€é©åˆ‡ã« +対処ã„ãŸã—ã¾ã™ã€‚ + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="HelpReportAbuseSelectCategory"> å«ŒãŒã‚‰ã›å ±å‘Šã®ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã—ã¦ãã ã•ã„。 カテゴリをé¸æŠžã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€å«ŒãŒã‚‰ã›å ±å‘Šã®å‡¦ç†ã‚„ä¿ç®¡ã«å¤§å¤‰å½¹ç«‹ã¡ã¾ã™ã€‚ @@ -2442,6 +2480,10 @@ Linden Lab ã”ã¿ç®±ã®ä¸èº«ã‚’ã™ã¹ã¦å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ <usetemplate ignoretext="インベントリã®ã”ã¿ç®±ãƒ•ã‚©ãƒ«ãƒ€ã‚’空ã«ã™ã‚‹å‰ã®ç¢ºèª" name="okcancelignore" notext="ã‚ャンセル" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + ゴミ箱ãŒã‚ãµã‚Œã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯ãƒã‚°ã‚¤ãƒ³æ™‚ã«å•é¡Œã‚’引ãèµ·ã“ã—ã¾ã™ã€‚ + <usetemplate name="okcancelbuttons" notext="後ã§ã‚´ãƒŸç®±ã‚’空ã«ã™ã‚‹" yestext="今ã™ãゴミ箱を空ã«ã™ã‚‹"/> + </notification> <notification name="ConfirmClearBrowserCache"> トラベルã€Webã€æ¤œç´¢ã®å±¥æ´ã‚’ã™ã¹ã¦å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ <usetemplate name="okcancelbuttons" notext="ã‚ャンセル" yestext="OK"/> @@ -2799,6 +2841,10 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚» <notification name="PathfindingDirty"> ã“ã®å€¤åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯ã€ä¿ç•™ä¸ã®ãƒ‘スファインディングã®å¤‰æ›´ãŒã‚ã‚Šã¾ã™ã€‚制作権ãŒã‚ã‚‹å ´åˆã¯ã€ã€Œåœ°åŸŸã®å†æ§‹ç¯‰ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ã€åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’å†æ§‹ç¯‰ã§ãã¾ã™ã€‚ </notification> + <notification name="PathfindingDirtyRebake"> + ã“ã®å€¤åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯ã€ä¿ç•™ä¸ã®ãƒ‘スファインディングã®å¤‰æ›´ãŒã‚ã‚Šã¾ã™ã€‚制作権ãŒã‚ã‚‹å ´åˆã¯ã€ã€Œåœ°åŸŸã®å†æ§‹ç¯‰ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ã€åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’å†æ§‹ç¯‰ã§ãã¾ã™ã€‚ + <usetemplate name="okbutton" yestext="地域ã®å†æ§‹ç¯‰"/> + </notification> <notification name="DynamicPathfindingDisabled"> ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ‘スファインディングãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã›ã‚“。パスファインディング LSL 呼ã³å‡ºã—を使用ã™ã‚‹ã‚¹ã‚¯ãƒªãƒ—ト化ã•ã‚ŒãŸã‚ªãƒ–ジェクトãŒã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ã¯å‹•ä½œã§ãã¾ã›ã‚“。 </notification> @@ -3032,7 +3078,7 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚» [MESSAGE] -é€ä¿¡å…ƒã®ã‚ªãƒ–ジェクト:<nolink>[OBJECTNAME]</nolink>ã€æ‰€æœ‰è€…:[NAME_SLURL] +é€ä¿¡å…ƒã®ã‚ªãƒ–ジェクト:<nolink>[OBJECTNAME]</nolink>ã€æ‰€æœ‰è€…:[NAME_SLURL] <form name="form"> <button name="Gotopage" text="ページã«ç§»å‹•"/> <button name="Cancel" text="å–り消ã—"/> @@ -3298,11 +3344,17 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <notification name="AttachmentSaved"> アタッãƒãƒ¡ãƒ³ãƒˆãŒä¿å˜ã•ã‚Œã¾ã—ãŸã€‚ </notification> + <notification name="AppearanceToXMLSaved"> + 外観㌠XML 㧠[PATH] ã«ä¿å˜ã•ã‚Œã¾ã—㟠+ </notification> + <notification name="AppearanceToXMLFailed"> + 外観を XML ã«ä¿å˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ + </notification> <notification name="PresetNotSaved"> - プリセット [NAME] ã®ä¿å˜ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ + プリセット [NAME] ã®ä¿å˜ã‚¨ãƒ©ãƒ¼ã€‚ </notification> <notification name="PresetNotDeleted"> - プリセット [NAME] ã®å‰Šé™¤ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ + プリセット [NAME] ã®å‰Šé™¤ã‚¨ãƒ©ãƒ¼ã€‚ </notification> <notification name="UnableToFindHelpTopic"> ヘルプトピックãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚ @@ -3512,13 +3564,6 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <notification name="ForceQuitDueToLowMemory"> メモリä¸è¶³ã®ãŸã‚ 30 秒以内㫠SL ã¯çµ‚了ã—ã¾ã™ã€‚ </notification> - <notification name="PopupAttempt"> - ãƒãƒƒãƒ—アップãŒãƒ–ãƒãƒƒã‚¯ã•ã‚Œã¾ã—ãŸã€‚ - <form name="form"> - <ignore name="ignore" text="å…¨ã¦ã®ãƒãƒƒãƒ—アップを有効ã«ã™ã‚‹"/> - <button name="open" text="ãƒãƒƒãƒ—アップウィンドウを開ã"/> - </form> - </notification> <notification name="SOCKS_NOT_PERMITTED"> ルールセットã«ã‚ˆã£ã¦è¨±å¯ã•ã‚Œã¦ã„ãªã„ãŸã‚ã€SOCKS 5 プãƒã‚ã‚· "[HOST]:[PORT]" ãŒæŽ¥ç¶šã‚’拒絶ã—ã¾ã—ãŸã€‚ <usetemplate name="okbutton" yestext="OK"/> @@ -3889,6 +3934,9 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <notification name="CantMoveObjectParcelResources"> ã“ã®åŒºç”»ã§ã“ã®ã‚ªãƒ–ジェクトã®ãƒªã‚½ãƒ¼ã‚¹ãŒä¸è¶³ã—ã¦ã„ã‚‹ãŸã‚ã€ã‚ªãƒ–ジェクト '[OBJECT_NAME]' をリージョン [REGION_NAME] 内㮠[OBJ_POSITION] ã«ç§»å‹•ã§ãã¾ã›ã‚“。 </notification> + <notification name="NoParcelPermsNoObject"> + ãã®åŒºç”»ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ãŒãªã„ãŸã‚ã€ã‚³ãƒ”ーãŒå¤±æ•—ã—ã¾ã—ãŸã€‚ + </notification> <notification name="CantMoveObjectRegionVersion"> オブジェクト '[OBJECT_NAME]' をリージョン [REGION_NAME] 内㮠[OBJ_POSITION] ã«ç§»å‹•ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。他ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã®å¢ƒç•Œã‚’ã¾ãŸã„ã ã“ã®ã‚ªãƒ–ジェクトをå—ä¿¡ã™ã‚‹ã“ã¨ãŒã§ããªã„å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’実行ã—ã¦ã„ã‚‹ãŸã‚ã§ã™ã€‚ </notification> @@ -3902,6 +3950,10 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <notification name="NoPermModifyObject"> ãã®ã‚ªãƒ–ジェクトを変更ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“ </notification> + <notification name="TooMuchObjectInventorySelected"> + 大ããªã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚’æŒã¤ã‚ªãƒ–ジェクトã®é¸æŠžãŒå¤šã™ãŽã¾ã™ã€‚é¸æŠžã™ã‚‹ã‚ªãƒ–ジェクトを減らã—ã¦ã€ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。 + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="CantEnablePhysObjContributesToNav"> ナビメッシュã«è²¢çŒ®ã™ã‚‹ã‚ªãƒ–ジェクトã«å¯¾ã—ã¦ç‰©ç†ã‚’有効ã«ã§ãã¾ã›ã‚“。 </notification> @@ -3938,6 +3990,12 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <notification name="CantSaveModifyAttachment"> オブジェクトã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã«ä¿å˜ã§ãã¾ã›ã‚“。ã“ã®ãŸã‚ã€ã‚¢ã‚¿ãƒƒãƒãƒ¡ãƒ³ãƒˆã®æ¨©é™ãŒå¤‰æ›´ã•ã‚Œã¾ã™ã€‚ </notification> + <notification name="AttachmentHasTooMuchInventory"> + ã”使用ã®ã‚¢ã‚¿ãƒƒãƒãƒ¡ãƒ³ãƒˆã«å«ã¾ã‚Œã‚‹ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªãŒå¤šã™ãŽã‚‹ãŸã‚ã€ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚’è¿½åŠ ã§ãã¾ã›ã‚“。 + </notification> + <notification name="IllegalAttachment"> + 添付ファイルã¯ã‚¢ãƒã‚¿ãƒ¼ã®å˜åœ¨ã—ãªã„点をè¦æ±‚ã—ã¾ã—ãŸã€‚代ã‚ã‚Šã«èƒ¸ã«æ·»ä»˜ã•ã‚Œã¦ã„ã¾ã—ãŸã€‚ + </notification> <notification name="TooManyScripts"> スクリプトãŒå¤šã™ãŽã¾ã™ã€‚ </notification> @@ -4030,6 +4088,12 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <notification name="TeleportedByObjectUnknownUser"> ä¸æ˜Žãªãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒæ‰€æœ‰ã—ã¦ã„るオブジェクト '[OBJECT_NAME]' ã«ã‚ˆã£ã¦ã€ã‚ãªãŸã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã™ã€‚ </notification> + <notification name="StandDeniedByObject"> + '[OBJECT_NAME]' ã¯ã“ã®æ™‚点ã§ã‚ãªãŸãŒç«‹ã¤ã“ã¨ã‚’許å¯ã—ã¾ã›ã‚“。 + </notification> + <notification name="ResitDeniedByObject"> + '[OBJECT_NAME]' ã¯ã“ã®æ™‚点ã§ã‚ãªãŸãŒå¸ã‚’変更ã™ã‚‹ã“ã¨ã‚’許å¯ã—ã¾ã›ã‚“。 + </notification> <notification name="CantCreateObjectRegionFull"> リクエストã•ã‚ŒãŸã‚ªãƒ–ジェクトを作æˆã§ãã¾ã›ã‚“。リージョンãŒåŸ‹ã¾ã£ã¦ã„ã¾ã™ã€‚ </notification> @@ -4326,6 +4390,9 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ <notification name="CantTransfterMoneyRegionDisabled"> オブジェクトã¸ã®é€é‡‘ã¯ã€ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ç¾åœ¨ç„¡åŠ¹ã«ã•ã‚Œã¦ã„ã¾ã™ã€‚ </notification> + <notification name="DroppedMoneyTransferRequest"> + システムãƒãƒ¼ãƒ‰ã«ã‚ˆã‚Šã€æ”¯æ‰•ã„を実行ã§ãã¾ã›ã‚“。 + </notification> <notification name="CantPayNoAgent"> 支払ã„ã®ç›¸æ‰‹ã‚’把æ¡ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ </notification> @@ -4361,4 +4428,8 @@ M ã‚ーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚ ãƒãƒ£ãƒƒãƒˆå±¥æ´ãƒ•ã‚¡ã‚¤ãƒ«ãŒå‰ã®æ“作ã§ãƒ“ジーã§ã™ã€‚2ã€3 分経ã£ã¦ã‹ã‚‰ã‚‚ã†ä¸€åº¦è©¦ã™ã‹ã€åˆ¥ã®äººã¨ã®ãƒãƒ£ãƒƒãƒˆã‚’é¸æŠžã—ã¦ãã ã•ã„。 <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="OutfitPhotoLoadError"> + [REASON] + <usetemplate name="okbutton" yestext="OK"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml index 93df0ba2bd41de1c9a10d640ceca1d27fe691106..8633bfb2ad78a83305055f19c404473227410f2c 100644 --- a/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="ã‚‚ã®" name="Outfits"> <panel.string name="wear_outfit_tooltip"> é¸æŠžã—ãŸã‚¢ã‚¦ãƒˆãƒ•ã‚£ãƒƒãƒˆã‚’ç€ç”¨ã™ã‚‹ @@ -7,6 +7,7 @@ é¸æŠžã—ãŸã‚¢ã‚¤ãƒ†ãƒ ã‚’ç€ç”¨ </panel.string> <tab_container name="appearance_tabs"> + <panel label="アウトフィットギャラリー" name="outfit_gallery_tab"/> <panel label="マイ アウトフィット" name="outfitslist_tab"/> <panel label="ç€ç”¨ä¸" name="cof_tab"/> </tab_container> diff --git a/indra/newview/skins/default/xui/ja/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/ja/panel_outfits_wearing.xml index fd03e6b89e331a9334c2da7efa8ab3adc81d6e98..a6fbaae58d26b340815390b4e0c6c7dbc527c351 100644 --- a/indra/newview/skins/default/xui/ja/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/ja/panel_outfits_wearing.xml @@ -1,6 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Wearing"> + <panel.string name="no_attachments"> + ç€ç”¨ã—ã¦ã„るアタッãƒãƒ¡ãƒ³ãƒˆã¯ã‚ã‚Šã¾ã›ã‚“。 + </panel.string> + <accordion name="wearables_accordion"> + <accordion_tab name="tab_wearables" title="ç€ç”¨ç‰©"/> + <accordion_tab name="tab_temp_attachments" title="一時的ãªã‚¢ã‚¿ãƒƒãƒãƒ¡ãƒ³ãƒˆ"/> + </accordion> <panel name="bottom_panel"> - <button name="options_gear_btn" tool_tip="オプションを表示ã—ã¾ã™"/> + <menu_button name="options_gear_btn" tool_tip="オプションを表示ã—ã¾ã™"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml index 7fd2e316982ffc091db75c11db006de4f13e57b5..4c2906cc1870962c7d7f5c29202c24f775dcfd59 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> 知らã›ã‚‹ï¼š </text> - <check_box label="リンデンドルを使用・å—ã‘å–ã‚‹ã¨ã" name="notify_money_change_checkbox"/> + <check_box label="L$ を使用ã™ã‚‹å ´åˆ" name="notify_money_spend_checkbox"/> <check_box label="フレンドãŒãƒã‚°ã‚¤ãƒ³ãƒ»ãƒã‚°ã‚¢ã‚¦ãƒˆã™ã‚‹ã¨ã" name="friends_online_notify_checkbox"/> + <check_box label="L$ を手ã«å…¥ã‚Œã‚‹å ´åˆ" name="notify_money_received_checkbox"/> <text name="show_label" width="300"> 常ã«è¡¨ç¤ºã™ã‚‹ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ï¼š </text> diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml index 8fbe9b56b9cca1b153d3d3406fb8716cecb861f5..61d914135db7efe41dab20388b35ff9013963191 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> é…ã„ </text> + <slider label="ã‚¢ãƒã‚¿ãƒ¼ã®æœ€å¤§è¤‡é›‘度:" name="IndirectMaxComplexity" tool_tip="ã©ã®ç‚¹ã§è¦–覚的ã«è¤‡é›‘ãªã‚¢ãƒã‚¿ãƒ¼ã‚’ JellyDoll ã¨ã—ã¦æãã‹ã‚’制御ã—ã¾ã™"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="周囲 (大気) シェーダー" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="高度ãªãƒ©ã‚¤ãƒ†ã‚£ãƒ³ã‚°ãƒ¢ãƒ‡ãƒ«" name="UseLightShaders"/> <button label="è¨å®šã‚’プリセットã¨ã—ã¦ä¿å˜..." name="PrefSaveButton"/> <button label="プリセットをãƒãƒ¼ãƒ‰..." name="PrefLoadButton"/> + min_val="0.125" <button label="事å‰è¨å®šã‚’削除..." name="PrefDeleteButton"/> <button label="推奨è¨å®šã«ãƒªã‚»ãƒƒãƒˆ" name="Defaults"/> <button label="詳細è¨å®š..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml index be823938a2496a4afdfe8b7e9d4d8badf6a91591..4c40ba7f7b64d9cc235188308f7020317d78ed43 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml @@ -30,6 +30,7 @@ <combo_box.item label="更新を手動ã§ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã—ã¦ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™" name="Install_manual"/> </combo_box> <check_box label="release candidate ã«ã‚¢ãƒƒãƒ—グレードã—ã¾ã™" name="update_willing_to_test"/> + <check_box label="更新後ã«ãƒªãƒªãƒ¼ã‚¹ãƒŽãƒ¼ãƒˆã‚’表示ã™ã‚‹" name="update_show_release_notes"/> <text name="Proxy Settings:"> プãƒã‚ã‚·è¨å®šï¼š </text> diff --git a/indra/newview/skins/default/xui/ja/panel_sound_devices.xml b/indra/newview/skins/default/xui/ja/panel_sound_devices.xml index 08245042350e5baf1e747e99d2474d33d1534db2..d57e6c796c1755a3c7ed86da5bbcd782e2626e69 100644 --- a/indra/newview/skins/default/xui/ja/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/ja/panel_sound_devices.xml @@ -16,9 +16,9 @@ 出力 </text> <text name="My volume label"> - ç§ã®éŸ³é‡ï¼š + マイク音é‡: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="スライダーを使ã£ã¦éŸ³é‡ã‚’調節ã—ã¾ã™"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="スライダーを使ã£ã¦ãƒžã‚¤ã‚¯ãƒ¬ãƒ™ãƒ«ã‚’調節ã—ã¾ã™"/> <text name="wait_text"> ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„。 </text> diff --git a/indra/newview/skins/default/xui/ja/panel_status_bar.xml b/indra/newview/skins/default/xui/ja/panel_status_bar.xml index 2e1446d45093de620f18d5ec157a5d391b69487f..3f3845e491bdcd4454e6343c5f1c228bf36eec01 100644 --- a/indra/newview/skins/default/xui/ja/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/ja/panel_status_bar.xml @@ -5,7 +5,7 @@ <panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string> <panel.string name="timeTooltip">[year, datetime, slt] [month, datetime, slt] [day, datetime, slt] ([weekday, datetime, slt])</panel.string> <panel.string name="buycurrencylabel">L$ [AMT]</panel.string> - <panel left="-370" name="balance_bg" width="160"> + <panel left="-391" name="balance_bg" width="160"> <text name="balance" tool_tip="クリックã—㦠L$ 残高を更新" value="L$??"/> <button label="L$ ã®è³¼å…¥" name="buyL" tool_tip="クリックã—㦠L$ を購入ã—ã¾ã™"/> <button label="店" name="goShop" tool_tip="Second Life マーケットプレイスを開ã" width="40"/> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index 1ad977fe88550f4721af9115726165654148a45e..586b8ab2d357d9c6fdb3c4870dc6adea3a787e61 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -38,7 +38,11 @@ グラフィックをåˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚グラフィックドライãƒã‚’æ›´æ–°ã—ã¦ãã ã•ã„。 </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL])[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + ãƒ“ãƒ«ãƒ‰æ§‹æˆ [BUILD_CONFIG] </string> <string name="AboutPosition"> ã‚ãªãŸã®ç¾åœ¨åœ°ã¯ã€[POSITION_LOCAL_0,number,1]ã€[POSITION_LOCAL_1,number,1]ã€[POSITION_LOCAL_2,number,1] ã® [REGION] ã§ã™ã€‚ä½ç½®ã¯ <nolink>[HOSTNAME]</nolink> ã§ã™ã€‚([HOSTIP]) @@ -57,20 +61,40 @@ OS ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š[OS_VERSION] <string name="AboutDriver"> Windows グラフィックドライãƒãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š[GRAPHICS_DRIVER_VERSION] </string> - <string name="AboutLibs"> + <string name="AboutOGL"> OpenGL ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š[OPENGL_VERSION] - -J2C デコーダãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š[J2C_VERSION] + </string> + <string name="AboutSettings"> + ウィンドウサイズ: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +フォントサイズã®èª¿æ•´ï¼š [FONT_SIZE_ADJUSTMENT]pt +UI スケーリング: [UI_SCALE] +æç”»è·é›¢ï¼š[DRAW_DISTANCE]m +帯域幅:[NET_BANDWITH]kbit/s +LOD 係数: [LOD_FACTOR] +表示å“質: [RENDER_QUALITY] / 7 +高度ãªãƒ©ã‚¤ãƒ†ã‚£ãƒ³ã‚°ãƒ¢ãƒ‡ãƒ«ï¼š [GPU_SHADERS] +テクスãƒãƒ£ãƒ¡ãƒ¢ãƒªï¼š [TEXTURE_MEMORY]MB +VFS(ã‚ャッシュ)作æˆæ™‚間: [VFS_TIME] + </string> + <string name="AboutLibs"> + J2C デコーダãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š[J2C_VERSION] オーディオドライãƒãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š[AUDIO_DRIVER_VERSION] LLCEFLib/CEF ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š [LLCEFLIB_VERSION] -ボイスサーãƒãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š [VOICE_VERSION] +LibVLC ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š [LIBVLC_VERSION] +ボイスサーãƒãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š[VOICE_VERSION] </string> <string name="AboutTraffic"> パケットãƒã‚¹ï¼š[PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> <string name="ErrorFetchingServerReleaseNotesURL"> サーãƒãƒ¼ã®ãƒªãƒªãƒ¼ã‚¹ãƒŽãƒ¼ãƒˆã® URL ã‚’å–å¾—ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ </string> + <string name="BuildConfiguration"> + ãƒ“ãƒ«ãƒ‰æ§‹æˆ + </string> <string name="ProgressRestoring"> 復元ä¸ã§ã™... </string> @@ -1082,6 +1106,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="TeleportYourAgent"> ã‚ãªãŸã‚’テレãƒãƒ¼ãƒˆ </string> + <string name="ForceSitAvatar"> + ã‚¢ãƒã‚¿ãƒ¼ã‚’強制的ã«åº§ã‚‰ã›ã‚‹ + </string> <string name="NotConnected"> 接続ã•ã‚Œã¦ã„ã¾ã›ã‚“ </string> @@ -1389,6 +1416,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="BodyPartsRightLeg"> å³è„š </string> + <string name="BodyPartsEnhancedSkeleton"> + 拡張スケルトン + </string> <string name="GraphicsQualityLow"> 低 </string> @@ -1837,6 +1867,51 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="Avatar Center"> ã‚¢ãƒã‚¿ãƒ¼ã®ä¸å¤® </string> + <string name="Left Ring Finger"> + 左薬指 + </string> + <string name="Right Ring Finger"> + å³è–¬æŒ‡ + </string> + <string name="Tail Base"> + ã—ã£ã½ã®ãƒ™ãƒ¼ã‚¹ + </string> + <string name="Tail Tip"> + ã—ã£ã½ã®å…ˆ + </string> + <string name="Left Wing"> + å·¦ã®ç¿¼ + </string> + <string name="Right Wing"> + å³ã®ç¿¼ + </string> + <string name="Jaw"> + é¡Ž + </string> + <string name="Alt Left Ear"> + 代ã‚ã‚Šã®å·¦è€³ + </string> + <string name="Alt Right Ear"> + 代ã‚ã‚Šã®å³è€³ + </string> + <string name="Alt Left Eye"> + 代ã‚ã‚Šã®å·¦ç›® + </string> + <string name="Alt Right Eye"> + 代ã‚ã‚Šã®å³ç›® + </string> + <string name="Tongue"> + 舌 + </string> + <string name="Groin"> + è„šã®ä»˜ã‘æ ¹ + </string> + <string name="Left Hind Foot"> + 左後足 + </string> + <string name="Right Hind Foot"> + å³å¾Œè¶³ + </string> <string name="Invalid Attachment"> 装ç€å…ˆãŒæ£ã—ãã‚ã‚Šã¾ã›ã‚“ </string> @@ -1882,6 +1957,27 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="av_render_anyone"> ã‚ãªãŸã®ã¾ã‚ã‚Šã®èª°ã«ã‚‚ã‚ãªãŸãŒè¦‹ãˆãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ </string> + <string name="hud_description_total"> + ã”利用㮠HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME]([JNT_NAME] ã«è£…ç€ä¸ï¼‰ + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] ã¯ãŸãã•ã‚“ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ãƒ¡ãƒ¢ãƒªã‚’使用ã—ã¾ã™ + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] ã«ã¯é«˜ä¾¡ãªã‚ªãƒ–ジェクトやテクスãƒãƒ£ãŒãŸãã•ã‚“å«ã¾ã‚Œã¦ã„ã¾ã™ + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] ã¯å¤§ããªãƒ†ã‚¯ã‚¹ãƒãƒ£ãŒãŸãã•ã‚“å«ã¾ã‚Œã¦ã„ã¾ã™ + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] ã«å«ã¾ã‚Œã‚‹ã‚ªãƒ–ジェクトãŒå¤šã™ãŽã¾ã™ + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] ã«å«ã¾ã‚Œã‚‹ãƒ†ã‚¯ã‚¹ãƒãƒ£ãŒå¤šã™ãŽã¾ã™ + </string> <string name="AgeYearsA"> [COUNT] å¹´ </string> @@ -2041,6 +2137,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="ObjectOutOfRange"> スクリプト(オブジェクトãŒç¯„囲外ã«ã‚ã‚Šã¾ã™ï¼‰ </string> + <string name="ScriptWasDeleted"> + スクリプト(インベントリã‹ã‚‰å‰Šé™¤æ¸ˆã¿ï¼‰ + </string> <string name="GodToolsObjectOwnedBy"> [OWNER] 所有ã®ã‚ªãƒ–ジェクト「[OBJECT]〠</string> @@ -2226,12 +2325,12 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="ATTACH_BELLY"> ãŠè…¹ </string> - <string name="ATTACH_RPEC"> - å³èƒ¸ç‹ - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> å·¦èƒ¸ç‹ </string> + <string name="ATTACH_RIGHT_PEC"> + å³èƒ¸ç‹ + </string> <string name="ATTACH_HUD_CENTER_2"> HUD(ä¸å¤® 2) </string> @@ -2262,6 +2361,51 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="ATTACH_AVATAR_CENTER"> ã‚¢ãƒã‚¿ãƒ¼ã®ä¸å¤® </string> + <string name="ATTACH_LHAND_RING1"> + 左薬指 + </string> + <string name="ATTACH_RHAND_RING1"> + å³è–¬æŒ‡ + </string> + <string name="ATTACH_TAIL_BASE"> + ã—ã£ã½ã®ãƒ™ãƒ¼ã‚¹ + </string> + <string name="ATTACH_TAIL_TIP"> + ã—ã£ã½ã®å…ˆ + </string> + <string name="ATTACH_LWING"> + å·¦ã®ç¿¼ + </string> + <string name="ATTACH_RWING"> + å³ã®ç¿¼ + </string> + <string name="ATTACH_FACE_JAW"> + é¡Ž + </string> + <string name="ATTACH_FACE_LEAR"> + 代ã‚ã‚Šã®å·¦è€³ + </string> + <string name="ATTACH_FACE_REAR"> + 代ã‚ã‚Šã®å³è€³ + </string> + <string name="ATTACH_FACE_LEYE"> + 代ã‚ã‚Šã®å·¦ç›® + </string> + <string name="ATTACH_FACE_REYE"> + 代ã‚ã‚Šã®å³ç›® + </string> + <string name="ATTACH_FACE_TONGUE"> + 舌 + </string> + <string name="ATTACH_GROIN"> + è„šã®ä»˜ã‘æ ¹ + </string> + <string name="ATTACH_HIND_LFOOT"> + 左後足 + </string> + <string name="ATTACH_HIND_RFOOT"> + å³å¾Œè¶³ + </string> <string name="CursorPos"> [LINE] 行目ã€[COLUMN] 列目 </string> @@ -2608,6 +2752,15 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="Play Media"> メディアをå†ç”Ÿ/一時åœæ¢ </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=en-us + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> <string name="MBCmdLineError"> コマンドラインã«ã‚¨ãƒ©ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚ リンク先をå‚ç…§ã—ã¦ãã ã•ã„: http://wiki.secondlife.com/wiki/Client_parameters @@ -4251,6 +4404,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã <string name="OfflineStatus"> オフライン </string> + <string name="not_online_msg"> + ユーザーãŒã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§ã‚ã‚Šã¾ã›ã‚“ - メッセージã¯ä¿å˜ã•ã‚Œã€å¾Œã§é…ä¿¡ã•ã‚Œã¾ã™ã€‚ + </string> + <string name="not_online_inventory"> + ユーザーãŒã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§ã‚ã‚Šã¾ã›ã‚“ - インベントリãŒä¿å˜ã•ã‚Œã¾ã—ãŸã€‚ + </string> <string name="answered_call"> 相手ãŒã‚³ãƒ¼ãƒ«ã‚’å—ã‘ã¾ã—㟠</string> @@ -4377,12 +4536,18 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã <string name="paid_you_ldollars"> [NAME] 㯠[REASON] ã®ãŸã‚ã« L$[AMOUNT] を支払ã„ã¾ã—ãŸã€‚ </string> + <string name="paid_you_ldollars_gift"> + [NAME] 㯠L$[AMOUNT] 支払ã„ã¾ã—ãŸï¼š[REASON] + </string> <string name="paid_you_ldollars_no_reason"> [NAME] 㯠L$[AMOUNT] を支払ã„ã¾ã—ãŸã€‚ </string> <string name="you_paid_ldollars"> [NAME] ã« L$ [AMOUNT] を支払ã„ã¾ã—ãŸï¼š[REASON] </string> + <string name="you_paid_ldollars_gift"> + [NAME] ã« L$ [AMOUNT] を支払ã„ã¾ã—ãŸï¼š[REASON] + </string> <string name="you_paid_ldollars_no_info"> L$ [AMOUNT] を支払ã„ã¾ã—ãŸã€‚ </string> @@ -4395,6 +4560,9 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã <string name="you_paid_failure_ldollars"> [NAME] ã« [REASON] ã®ä»£é‡‘ L$ [AMOUNT] を支払ãˆã¾ã›ã‚“ã§ã—ãŸã€‚ </string> + <string name="you_paid_failure_ldollars_gift"> + [NAME] ã« L$ [AMOUNT] を支払ãˆã¾ã›ã‚“ã§ã—ãŸï¼š[REASON] + </string> <string name="you_paid_failure_ldollars_no_info"> L$ [AMOUNT] を支払ãˆã¾ã›ã‚“ã§ã—ãŸã€‚ </string> @@ -4721,6 +4889,15 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã <string name="texture_load_dimensions_error"> [WIDTH]*[HEIGHT] 以上ã®ç”»åƒã¯èªã¿è¾¼ã‚ã¾ã›ã‚“ </string> + <string name="outfit_photo_load_dimensions_error"> + 最大アウトフィット写真サイズ㯠[WIDTH]*[HEIGHT] ã§ã™ã€‚ç”»åƒã®ã‚µã‚¤ã‚ºã‚’調整ã™ã‚‹ã‹ã€åˆ¥ã®ç”»åƒã‚’使用ã—ã¦ãã ã•ã„ + </string> + <string name="outfit_photo_select_dimensions_error"> + 最大アウトフィット写真サイズ㯠[WIDTH]*[HEIGHT] ã§ã™ã€‚別ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’é¸æŠžã—ã¦ãã ã•ã„ + </string> + <string name="outfit_photo_verify_dimensions_error"> + 写真ã®å¯¸æ³•ã‚’確èªã§ãã¾ã›ã‚“。写真サイズãŒãƒ”ッカーã«è¡¨ç¤ºã•ã‚Œã‚‹ã¾ã§ãŠå¾…ã¡ãã ã•ã„ + </string> <string name="words_separator" value=","/> <string name="server_is_down"> 大変申ã—訳ã”ã–ã„ã¾ã›ã‚“ãŒã€äºˆæœŸã—ãªã„å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ @@ -5225,6 +5402,9 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã <string name="Command_Profile_Label"> プãƒãƒ•ã‚£ãƒ¼ãƒ« </string> + <string name="Command_Report_Abuse_Label"> + å«ŒãŒã‚‰ã›ã®å ±å‘Š + </string> <string name="Command_Search_Label"> 検索 </string> @@ -5315,6 +5495,9 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã <string name="Command_Profile_Tooltip"> プãƒãƒ•ã‚£ãƒ¼ãƒ«ã‚’編集・表示 </string> + <string name="Command_Report_Abuse_Tooltip"> + å«ŒãŒã‚‰ã›ã®å ±å‘Š + </string> <string name="Command_Search_Tooltip"> å ´æ‰€ã€ã‚¤ãƒ™ãƒ³ãƒˆã€äººã‚’検索 </string> diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index dd85f1eb9bcd454cd66b3796f66fff834aa16bbb..e9dd18043d698c0a5c07a28f2fd16fd8b27af40d 100644 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -44,6 +44,7 @@ Wersja OpenGL: [OPENGL_VERSION] Wersja dekodera J2C: [J2C_VERSION] Wersja sterownika dźwiÄ™ku (Audio Driver): [AUDIO_DRIVER_VERSION] Wersja LLCEFLib/CEF: [LLCEFLIB_VERSION] +Wersja LibVLC: [LIBVLC_VERSION] Wersja serwera gÅ‚osu (Voice Server): [VOICE_VERSION] </string> <string name="AboutTraffic"> diff --git a/indra/newview/skins/default/xui/pt/floater_model_preview.xml b/indra/newview/skins/default/xui/pt/floater_model_preview.xml index 35cee93ad1d0030af75d123112abddfe5d047455..70ba647d301186c8639bb1b46c577c9d565e686c 100644 --- a/indra/newview/skins/default/xui/pt/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/pt/floater_model_preview.xml @@ -245,6 +245,7 @@ </text> <check_box label="Incluir peso da pele" name="upload_skin"/> <check_box label="Incluir posições de junções" name="upload_joints"/> + <check_box label="Travar escala se posição de articulação estiver definida" name="lock_scale_if_joint_position"/> <text name="pelvis_offset_label"> Desvio Z (subir ou baixar avatar): </text> diff --git a/indra/newview/skins/default/xui/pt/floater_pay.xml b/indra/newview/skins/default/xui/pt/floater_pay.xml index 77e814b5755956baa6e00820c4545e51b1949a5b..21cb91dc962f1c056bc224e3aa7f88101b13748c 100644 --- a/indra/newview/skins/default/xui/pt/floater_pay.xml +++ b/indra/newview/skins/default/xui/pt/floater_pay.xml @@ -1,9 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Give Money" title=""> - <string name="payee_group">Pagar grupo</string> - <string name="payee_resident">Pagar residente</string> - <text name="paying_text">Você está pagando:</text> - <text name="payee_name">Test Name That Is Extremely Long To Check Clipping</text> + <string name="payee_group"> + Pagar grupo + </string> + <string name="payee_resident"> + Pagar residente + </string> + <text name="paying_text"> + Você está pagando: + </text> + <text name="payee_name"> + Test Name That Is Extremely Long To Check Clipping + </text> + <text name="payment_message_label"> + Descrição (opcional): + </text> <panel label="Buscar" name="PatternsPanel"> <button label="Pagar L$ 1" label_selected="Pagar L$ 1" name="fastpay 1"/> <button label="Pagar L$ 5" label_selected="Pagar L$ 5" name="fastpay 5"/> @@ -11,7 +22,9 @@ <button label="Pagar L$ 20" label_selected="Pagar L$ 20" name="fastpay 20"/> </panel> <panel label="Buscar" name="InputPanel"> - <text name="amount text">Outro valor:</text> + <text name="amount text"> + Outro valor: + </text> <button label="Pagar" label_selected="Pagar" name="pay btn"/> <button label="Cancelar" label_selected="Cancelar" name="cancel btn"/> </panel> diff --git a/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml index c5e19b2281c47fd1e0c3d8c6d600a450f5f5a811..6fa25262ea858c4ced4751a5c401603d51cda4e3 100644 --- a/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Complexidade máxima:" name="IndirectMaxComplexity" tool_tip="Controla o ponto no qual um avatar visualmente complexo é desenhado como avatar de cor sólida"/> + <slider label="Complexidade máxima:" name="IndirectMaxComplexity" tool_tip="Controla o ponto no qual um avatar visualmente complexo é desenhado como uma JellyDoll"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/pt/floater_script_queue.xml b/indra/newview/skins/default/xui/pt/floater_script_queue.xml index 5fb6dd1c35118ea72c046c36add522f4d9c2b89a..b9fc9d4713af6e4988bb66da52ab08581a3c8f13 100644 --- a/indra/newview/skins/default/xui/pt/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/pt/floater_script_queue.xml @@ -15,5 +15,11 @@ <floater.string name="NotRunning"> Inerte </floater.string> + <floater.string name="Timeout"> + Limite de tempo: [OBJECT_NAME] + </floater.string> + <floater.string name="LoadingObjInv"> + Carregando inventário de: [OBJECT_NAME] + </floater.string> <button label="Fechar" label_selected="Fechar" name="close"/> </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_web_content.xml b/indra/newview/skins/default/xui/pt/floater_web_content.xml index 5101579c6f21e8fde127f7e08487b5f6c50a29b4..2b22d3ec3cb4cc734ccda725a40bbf8baaadfe00 100644 --- a/indra/newview/skins/default/xui/pt/floater_web_content.xml +++ b/indra/newview/skins/default/xui/pt/floater_web_content.xml @@ -10,5 +10,9 @@ <icon name="media_secure_lock_flag" tool_tip="Navegação segura"/> <button name="popexternal" tool_tip="Abrir a URL atual no navegador do seu computador"/> </layout_panel> + <layout_panel name="debug_controls"> + <button name="web_test_home_page" tool_tip="Página inicial de testes de Web"/> + <button name="VLC Plugin Test" tool_tip="Teste de vÃdeo MPEG4"/> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/pt/menu_attachment_other.xml b/indra/newview/skins/default/xui/pt/menu_attachment_other.xml index 031f6b605aa560b4fd8b8e0c65911659fbadd3a6..d991c89f61df7be22481e0886dc0c5374cc4420f 100644 --- a/indra/newview/skins/default/xui/pt/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/pt/menu_attachment_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="MI" name="Send IM..."/> <menu_item_call label="Ligar" name="Call"/> <menu_item_call label="Convidar para entrar no grupo" name="Invite..."/> + <menu_item_call label="Redefinir esqueleto" name="Reset Skeleton"/> + <menu_item_call label="Redefinir esqueleto e animações" name="Reset Skeleton And Animations"/> <menu_item_call label="Bloquear" name="Avatar Mute"/> <menu_item_call label="Denunciar" name="abuse"/> <menu_item_call label="Congelar" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_attachment_self.xml b/indra/newview/skins/default/xui/pt/menu_attachment_self.xml index ac7942211039fee43bb438257eae526bb3a64c49..e2403fa86f7bd71267c2cd8bfcb924a231c201fd 100644 --- a/indra/newview/skins/default/xui/pt/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/pt/menu_attachment_self.xml @@ -9,6 +9,8 @@ <menu_item_call label="Editar meu look" name="Edit Outfit"/> <menu_item_call label="Editar meu corpo" name="Edit My Shape"/> <menu_item_call label="Altura de foco" name="Hover Height"/> + <menu_item_call label="Redefinir esqueleto" name="Reset Skeleton"/> + <menu_item_call label="Redefinir esqueleto e animações" name="Reset Skeleton And Animations"/> <menu_item_call label="Meus amigos" name="Friends..."/> <menu_item_call label="Meus grupos" name="Groups..."/> <menu_item_call label="Meu perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_avatar_other.xml b/indra/newview/skins/default/xui/pt/menu_avatar_other.xml index e32f9059f52cffa8980aa3053d9226ab21a5e9a7..cba849cd05a5aca080c7644ceec5eb57f7d83b29 100644 --- a/indra/newview/skins/default/xui/pt/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/pt/menu_avatar_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="MI" name="Send IM..."/> <menu_item_call label="Ligar" name="Call"/> <menu_item_call label="Convidar para entrar no grupo" name="Invite..."/> + <menu_item_call label="Redefinir esqueleto" name="Reset Skeleton"/> + <menu_item_call label="Redefinir esqueleto e animações" name="Reset Skeleton And Animations"/> <menu_item_call label="Bloquear" name="Avatar Mute"/> <menu_item_call label="Denunciar" name="abuse"/> <menu_item_call label="Congelar" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_avatar_self.xml b/indra/newview/skins/default/xui/pt/menu_avatar_self.xml index a0ac71e0186d56d1e69c11cee2087f9159dd7c96..50a1996d62ee012fe78ea144c12af985ed4206a6 100644 --- a/indra/newview/skins/default/xui/pt/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/pt/menu_avatar_self.xml @@ -26,6 +26,8 @@ <menu_item_call label="Editar meu look" name="Edit Outfit"/> <menu_item_call label="Editar meu corpo" name="Edit My Shape"/> <menu_item_call label="Altura de foco" name="Hover Height"/> + <menu_item_call label="Redefinir esqueleto" name="Reset Skeleton"/> + <menu_item_call label="Redefinir esqueleto e animações" name="Reset Skeleton And Animations"/> <menu_item_call label="Meus amigos" name="Friends..."/> <menu_item_call label="Meus grupos" name="Groups..."/> <menu_item_call label="Meu perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_login.xml b/indra/newview/skins/default/xui/pt/menu_login.xml index a65dfddb0512b66084db9f5d853ef55f9d2bf553..44cfae236b1717a58e0b314a1193d95b8c06bfe8 100644 --- a/indra/newview/skins/default/xui/pt/menu_login.xml +++ b/indra/newview/skins/default/xui/pt/menu_login.xml @@ -20,12 +20,11 @@ <menu_item_check label="Exibir menu de depuração" name="Show Debug Menu"/> <menu label="Depurar" name="Debug"> <menu_item_call label="Mostrar configurações" name="Debug Settings"/> - <menu_item_call label="Configurações da interface e cor" name="UI/Color Settings"/> <menu label="Testes de UI" name="UI Tests"/> <menu_item_call label="Definir tamanho da janela:" name="Set Window Size..."/> <menu_item_call label="Mostrar TOS" name="TOS"/> <menu_item_call label="Mostrar mensagem crÃtica" name="Critical"/> - <menu_item_call label="Test de Bugs de Conteúdo Web" name="Web Content Floater Debug Test"/> + <menu_item_call label="Navegador de MÃdia" name="Media Browser"/> <menu label="Configurar nÃvel de registro em log" name="Set Logging Level"> <menu_item_check label="Depurar" name="Debug"/> <menu_item_check label="Info" name="Info"/> diff --git a/indra/newview/skins/default/xui/pt/menu_object_icon.xml b/indra/newview/skins/default/xui/pt/menu_object_icon.xml index df224a88fa290564617d86c3d178ee9719e0f372..c6a1ca72f2dfc167bde9d5a87267da3839aeb6d3 100644 --- a/indra/newview/skins/default/xui/pt/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/pt/menu_object_icon.xml @@ -2,6 +2,7 @@ <menu name="Object Icon Menu"> <menu_item_call label="Perfil do objeto..." name="Object Profile"/> <menu_item_call label="Bloquear..." name="Block"/> + <menu_item_call label="Desbloquear" name="Unblock"/> <menu_item_call label="Mostrar no mapa" name="show_on_map"/> <menu_item_call label="Teletransportar para lugar do objeto" name="teleport_to_object"/> </menu> diff --git a/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml b/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml index 3602bdaac42b979ad96b6c928acfdc5a5bb9a880..ccf65ae5664e49c8abc742b6b8ac56d28ee16578 100644 --- a/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml @@ -3,6 +3,10 @@ <menu_item_call label="Vestir - Substituir look atual" name="wear"/> <menu_item_call label="Vestir - Adicionar ao look atual" name="wear_add"/> <menu_item_call label="Tirar - Tirar do look atual" name="take_off"/> + <menu_item_call label="Carregar foto (L$ 10)" name="upload_photo"/> + <menu_item_call label="Selecionar foto" name="select_photo"/> + <menu_item_call label="Tirar uma foto" name="take_snapshot"/> + <menu_item_call label="Remover foto" name="remove_photo"/> <menu label="Roupas novas" name="New Clothes"> <menu_item_call label="Nova camisa" name="New Shirt"/> <menu_item_call label="Novas calças" name="New Pants"/> @@ -27,4 +31,5 @@ <menu_item_call label="Recolher todas as pastas" name="collapse"/> <menu_item_call label="Renomear look" name="rename"/> <menu_item_call label="Excluir visual" name="delete_outfit"/> + <menu_item_check label="Sempre ordenar pastas por nome" name="sort_folders_by_name"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/pt/menu_people_friends_view.xml b/indra/newview/skins/default/xui/pt/menu_people_friends_view.xml index 46caeae31059b781bc3750678678047e8afef321..35315abfe6799e63ce146518623637d093f3b7af 100644 --- a/indra/newview/skins/default/xui/pt/menu_people_friends_view.xml +++ b/indra/newview/skins/default/xui/pt/menu_people_friends_view.xml @@ -4,5 +4,6 @@ <menu_item_check label="Ordenar por status" name="sort_status"/> <menu_item_check label="Exibir Ãcones de pessoas" name="view_icons"/> <menu_item_check label="Exibir permissões concedidas" name="view_permissions"/> + <menu_item_check label="Ocultar nomes de usuários" name="view_usernames"/> <menu_item_check label="Exibir registro de conversas..." name="view_conversation"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/pt/menu_people_nearby.xml b/indra/newview/skins/default/xui/pt/menu_people_nearby.xml index 51464fed68fa366210af49d57b5cec4b31a2b904..bd8afae1b5d309d2f1ee7423dd3428aba2c7a8d8 100644 --- a/indra/newview/skins/default/xui/pt/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/pt/menu_people_nearby.xml @@ -13,4 +13,6 @@ <menu_item_call label="Compartilhar" name="share"/> <menu_item_call label="Pagar" name="pay"/> <menu_item_check label="Bloquear/desbloquear" name="block_unblock"/> + <menu_item_call label="Congelar" name="freeze"/> + <menu_item_call label="Expulsar" name="eject"/> </context_menu> diff --git a/indra/newview/skins/default/xui/pt/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/pt/menu_people_nearby_view.xml index bce015e732c7b2c0ce4a15a97778183d9a0d08d8..2c49f5e2fd022aae12083ca421123c122084f078 100644 --- a/indra/newview/skins/default/xui/pt/menu_people_nearby_view.xml +++ b/indra/newview/skins/default/xui/pt/menu_people_nearby_view.xml @@ -5,4 +5,5 @@ <menu_item_check label="Ordenar por distância" name="sort_distance"/> <menu_item_check label="Exibir Ãcones de pessoas" name="view_icons"/> <menu_item_check label="Exibir mapa" name="view_map"/> + <menu_item_check label="Ocultar nomes de usuários" name="view_usernames"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/pt/menu_url_objectim.xml b/indra/newview/skins/default/xui/pt/menu_url_objectim.xml index 2cd0f52ef31cf23b87b22ff914150525d55b17d5..0ebb358b12f6858dcc512a88bade839210985d56 100644 --- a/indra/newview/skins/default/xui/pt/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/pt/menu_url_objectim.xml @@ -2,6 +2,7 @@ <context_menu name="Url Popup"> <menu_item_call label="Perfil do objeto..." name="show_object"/> <menu_item_call label="Bloquear..." name="block_object"/> + <menu_item_call label="Desbloquear" name="unblock_object"/> <menu_item_call label="Mostrar no mapa" name="show_on_map"/> <menu_item_call label="Teletransportar para lugar do objeto" name="teleport_to_object"/> <menu_item_call label="Copiar nome do objeto para área de transferência" name="url_copy_label"/> diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index 2df78c6287bb6fdd2118d3a1c6a7533fff2977cb..6964941f0ae4a7f9b48d21981a21c4687e176196 100644 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Não perturbe" name="Do Not Disturb"/> </menu> <menu_item_call label="Comprar L$..." name="Buy and Sell L$"/> - <menu_item_call label="Caixa de saÃda do lojista..." name="MerchantOutbox"/> <menu_item_call label="Listagens do Marketplace..." name="MarketplaceListings"/> <menu_item_call label="Painel da conta..." name="Manage My Account"> <menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=pt"/> @@ -114,11 +113,11 @@ <menu_item_call label="Link" name="Link"/> <menu_item_call label="Desconectar links" name="Unlink"/> <menu_item_check label="Editar partes linkadas" name="Edit Linked Parts"/> - <menu label="Selecionar partes conectadas" name="Select Linked Parts"> - <menu_item_call label="Selecionar próxima parte" name="Select Next Part"/> - <menu_item_call label="Selecionar parte anterior" name="Select Previous Part"/> - <menu_item_call label="Incluir próxima parte" name="Include Next Part"/> - <menu_item_call label="Incluir parte anterior" name="Include Previous Part"/> + <menu label="Selecionar elementos" name="Select Elements"> + <menu_item_call label="Selecionar próxima parte ou face" name="Select Next Part or Face"/> + <menu_item_call label="Selecionar parte anterior ou face" name="Select Previous Part or Face"/> + <menu_item_call label="Incluir próxima parte ou face" name="Include Next Part or Face"/> + <menu_item_call label="Incluir parte anterior ou face" name="Include Previous Part or Face"/> </menu> <menu_item_call label="Linksets..." name="pathfinding_linkset_menu_item"/> <menu_item_call label="Enfocar seleção" name="Focus on Selection"/> @@ -333,8 +332,7 @@ <menu_item_call label="Descartar cache do objeto de região" name="Dump Region Object Cache"/> </menu> <menu label="Interface" name="UI"> - <menu_item_call label="Teste de mÃdia do navegador" name="Web Browser Test"/> - <menu_item_call label="Navegador de conteúdo web" name="Web Content Browser"/> + <menu_item_call label="Navegador de MÃdia" name="Media Browser"/> <menu_item_call label="Print Selected Object Info" name="Print Selected Object Info"/> <menu_item_check label="Debug Clicks" name="Debug Clicks"/> <menu_item_check label="Debug Mouse Events" name="Debug Mouse Events"/> @@ -368,6 +366,7 @@ <menu_item_check label="Dados da animação" name="Animation Info"/> <menu_item_check label="Disable Level Of Detail" name="Disable LOD"/> <menu_item_check label="Show Collision Skeleton" name="Show Collision Skeleton"/> + <menu_item_check label="Exibir ossos" name="Show Bones"/> <menu_item_check label="Display Agent Target" name="Display Agent Target"/> <menu_item_call label="Depurar texturas do avatar" name="Debug Avatar Textures"/> </menu> diff --git a/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml b/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml index 4e6e52ebc7010f91d6fe21a9b448eeb45126305c..42aa3862154d692ebc0e1d2b0b2424aa30a4ed7d 100644 --- a/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml @@ -3,4 +3,6 @@ <menu_item_call label="Tirar" name="take_off"/> <menu_item_call label="Tirar" name="detach"/> <menu_item_call label="Editar look" name="edit"/> + <menu_item_call label="Editar" name="edit_item"/> + <menu_item_call label="Mostrar original" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/pt/mime_types.xml b/indra/newview/skins/default/xui/pt/mime_types.xml index be387088bd87bccb083814381c73b60619af0698..54902f165bcda539bc0d0f861a150603ef525014 100644 --- a/indra/newview/skins/default/xui/pt/mime_types.xml +++ b/indra/newview/skins/default/xui/pt/mime_types.xml @@ -22,14 +22,6 @@ Iniciar filme </playtip> </widgetset> - <widgetset name="none"> - <label name="none_label"> - Sem conteúdo - </label> - <tooltip name="none_tooltip"> - Sem mÃdia aqui - </tooltip> - </widgetset> <widgetset name="image"> <label name="image_label"> Imagem @@ -52,11 +44,24 @@ Iniciar áudio disponÃvel neste local </playtip> </widgetset> + <widgetset name="none"> + <label name="none_label"> + Sem conteúdo + </label> + <tooltip name="none_tooltip"> + Sem mÃdia aqui + </tooltip> + </widgetset> <scheme name="rtsp"> <label name="rtsp_label"> Transmissão em tempo real </label> </scheme> + <scheme name="libvlc"> + <label name="libvlc_label"> + MÃdia com suporte a LibVLC + </label> + </scheme> <mimetype name="blank"> <label name="blank_label"> - Nenhum - @@ -127,11 +132,6 @@ Macromedia Director </label> </mimetype> - <mimetype name="application/x-shockwave-flash"> - <label name="application/x-shockwave-flash_label"> - Flash - </label> - </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> Ãudio (MIDI) @@ -207,6 +207,11 @@ Filme (MP4) </label> </mimetype> + <mimetype name="application/octet-stream"> + <label name="video/octet-stream"> + Filme + </label> + </mimetype> <mimetype name="video/quicktime"> <label name="video/quicktime_label"> Filme (QuickTime) diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index cf7400117d6a7c1ef181cad15293ba0eb521f4e4..53a418a1d8c7938521cbd7858413aeb13ac33780 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -329,6 +329,9 @@ Se você não quiser que essas funções sejam concedidas a esse cargo, desative Você está prestes a banir [COUNT] membros do grupo. <usetemplate ignoretext="Confirmar banimento de diversos membros do grupo" name="okcancelignore" notext="Cancelar" yestext="Banir"/> </notification> + <notification name="GroupBanUserOnBanlist"> + Alguns residentes não receberam convite porque foram banidos do grupo. + </notification> <notification name="AttachmentDrop"> Você está prestes a largar seu anexo. Tem certeza de que quer prosseguir? @@ -455,6 +458,12 @@ Para colocar a mÃdia em só uma face, selecione Selecionar face e clique na fac <notification name="ErrorEncodingSnapshot"> Erro ao codificar a foto. </notification> + <notification name="ErrorPhotoCannotAfford"> + Você precisa de L$ [COST] para salvar uma foto em seu inventário. Você pode comprar L$ ou salvar a foto em seu computador. + </notification> + <notification name="ErrorTextureCannotAfford"> + Você precisa de L$ [COST] para salvar uma textura em seu inventário. Você pode comprar L$ ou salvar a foto em seu computador. + </notification> <notification name="ErrorUploadingPostcard"> Houve um problema ao enviar a foto devido à seguinte razão: [REASON] </notification> @@ -477,6 +486,9 @@ Ele ultrapassa o limite de anexos, de [MAX_ATTACHMENTS] objetos. Remova um objet <notification name="CannotWearInfoNotComplete"> Você não pode vestir este item porque ele ainda não carregou. Tente novamente em um minuto. </notification> + <notification name="MustEnterPasswordToLogIn"> + Informe sua senha para fazer o login. + </notification> <notification name="MustHaveAccountToLogIn"> Opa! Alguma coisa ficou em branco. Digite o nome de usuário de seu avatar. @@ -545,6 +557,9 @@ Nota: Este procedimento limpa o cache. <notification name="ChangeConnectionPort"> Reinicie o [APP_NAME] para ativar a reconfiguração da porta. </notification> + <notification name="ChangeDeferredDebugSetting"> + Essa alteração nas configurações de depuração será aplicada depois que você reiniciar o [APP_NAME]. + </notification> <notification name="ChangeSkin"> Reinicie o [APP_NAME] para ativar a pele nova. </notification> @@ -563,6 +578,10 @@ Nota: Este procedimento limpa o cache. Excluir nota? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> + <notification name="LoadPreviousReportScreenshot"> + Você deseja usar a captura de tela anterior em seu relatório? + <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> + </notification> <notification name="GestureSaveFailedTooManySteps"> Falha ao salvar Gesto. Este gesto possui muitos passos. @@ -623,30 +642,12 @@ Consultar [_URL] para mais informações? </url> <usetemplate ignoretext="O hardware do meu computador não é suportado" name="okcancelignore" notext="Não" yestext="Sim"/> </notification> - <notification name="IntelOldDriver"> - Provavelmente, há um driver mais recente para o seu chip gráfico. A atualização dos drivers gráficos pode melhorar significativamente o desempenho. - - Visitar [_URL] para verificar se há atualizações do driver? - <url name="url"> - http://www.intel.com/p/pt_BR/support/detect/graphics - </url> - <usetemplate ignoretext="Meu driver gráfico está desatualizado" name="okcancelignore" notext="Não" yestext="Sim"/> - </notification> - <notification name="AMDOldDriver"> - Provavelmente, há um driver mais recente para o seu chip gráfico. A atualização dos drivers gráficos pode melhorar significativamente o desempenho. - - Visitar [_URL] para verificar se há atualizações do driver? - <url name="url"> - http://support.amd.com/us/Pages/AMDSupportHub.aspx - </url> - <usetemplate ignoretext="Meu driver gráfico está desatualizado" name="okcancelignore" notext="Não" yestext="Sim"/> - </notification> - <notification name="NVIDIAOldDriver"> + <notification name="OldGPUDriver"> Provavelmente, há um driver mais recente para o seu chip gráfico. A atualização dos drivers gráficos pode melhorar significativamente o desempenho. - Visitar [_URL] para verificar se há atualizações do driver? + Visitar [URL] para verificar se há atualizações do driver? <url name="url"> - http://www.nvidia.com.br/Download/index.aspx?lang=br + [URL] </url> <usetemplate ignoretext="Meu driver gráfico está desatualizado" name="okcancelignore" notext="Não" yestext="Sim"/> </notification> @@ -737,6 +738,9 @@ Para mais informações sobre como comprar L$, consulte [_URL]. </url> <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Ir até a página"/> </notification> + <notification name="MuteLimitReached"> + Não foi possÃvel adicionar uma nova entrada à lista de bloqueados porque você atingiu o limite de [MUTE_LIMIT] entradas. + </notification> <notification name="UnableToLinkObjects"> Não é possÃvel unir estes [COUNT] objetos. Você pode unir um máximo de [MAX] objetos. @@ -1359,12 +1363,18 @@ Enquando isso, use o [SECOND_LIFE] normalmente. Seu visual será exibido correta <ignore name="ignore" text="A roupa está demorando para chegar"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - Sua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexidade visual] é [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + Sua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] é [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Avise-me se a complexidade do meu avatar for muito alta" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - Sua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 complexidade visual] é [AGENT_COMPLEXITY]. + Sua [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] é [AGENT_COMPLEXITY]. + <usetemplate ignoretext="Avise-me se a complexidade do meu avatar for alterada" name="notifyignore"/> + </notification> + <notification name="HUDComplexityWarning"> + [HUD_REASON], provavelmente afetará negativamente seu desempenho. + <usetemplate ignoretext="Avise-me quando a complexidade do meu HUD estiver muito alta" name="notifyignore"/> </notification> <notification name="FirstRun"> A instalação do [APP_NAME] está pronta. @@ -1455,6 +1465,10 @@ Isso é realmente útil apenas para depuração. Teletransportar para o inÃcio todos os residentes nesta região? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> + <notification name="ChangeObjectBonusFactor"> + Reduzir o bônus do objeto depois que as construções tiverem sido estabelecidas em uma região pode fazer com que os objetos sejam devolvidos ou excluÃdos. Tem certeza de que deseja alterar o bônus do objeto? + <usetemplate ignoretext="Confirmar alteração do fator de bônus de objeto" name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> <notification name="EstateObjectReturn"> Você tem certeza que deseja retornar os objetos pertencentes a [USER_NAME] ? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> @@ -1478,6 +1492,10 @@ Substituir textura [TEXTURE_NUM], com uma imagem de 24-bit 512x512 ou menor e em Você realmente deseja nivelar o terreno selecionado a partir do centro elevando/reduzindo os limites e o padrão para a ferramenta ´Reverter´? <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Executar"/> </notification> + <notification name="ConfirmTextureHeights"> + Você está prestes a usar valores baixos maiores que os valores altos para os intervalos de elevação. Deseja prosseguir? + <usetemplate canceltext="Não perguntar" name="yesnocancelbuttons" notext="Cancelar" yestext="Ok"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Você pode ter somente [MAX_AGENTS] residentes permitidos. </notification> @@ -1498,6 +1516,9 @@ Ultrapassa o limite de [MAX_AGENTS] [LIST_TYPE] de [NUM_EXCESS]. <notification name="OwnerCanNotBeDenied"> Não é possÃvel adicionar o dono da propriedade na lista de residentes banidos. </notification> + <notification name="ProblemAddingEstateManagerBanned"> + Não foi possÃvel adicionar residentes banidos à lista de gerentes de propriedades. + </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> Não é possÃvel alterar a aparência até que as roupas e formas estejam carregadas. </notification> @@ -1672,6 +1693,10 @@ Se você estiver muito ansioso para experimentar os novos recursos e correções Abrir uma janela do navegador para ver essas informações? <usetemplate ignoretext="Abrir o navegador para acessar uma página na web" name="okcancelignore" notext="Cancelar" yestext="OK"/> </notification> + <notification name="SystemUIScaleFactorChanged"> + O fator de tamanho da interface do sistema foi alterado desde a última execução. Deseja abrir a página de configurações de ajuste de tamanho da interface? + <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> + </notification> <notification name="WebLaunchJoinNow"> Deseja abrir o [http://secondlife.com/account/ Painel] para gerenciar sua conta? <usetemplate ignoretext="Abrir o navegador para acessar minha conta" name="okcancelignore" notext="Cancelar" yestext="OK"/> @@ -1710,16 +1735,15 @@ Se você estiver muito ansioso para experimentar os novos recursos e correções Você é atualmente um membro do grupo <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Sair"/> </notification> + <notification name="GroupDepart"> + Você deixou o grupo '[group_name]'. + </notification> <notification name="OwnerCannotLeaveGroup"> Não foi possÃvel deixar o grupo. Você não pode deixar o grupo pois é o último proprietário dele. Primeiramente, atribua outro membro à função de proprietário. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="GroupDepartError"> - Não foi possÃvel deixar o grupo: [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Você deixou o grupo [group_name]. + Não foi possÃvel deixar o grupo. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="ConfirmKick"> @@ -2120,6 +2144,10 @@ Isto mudará milhares de regiões e fará o spaceserver soluçar. Muitos prims foram selecionados. Selecione [MAX_PRIM_COUNT] ou menos prims, e tente de novo <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="TooManyScriptsSelected"> + Muitos scripts nos objetos selecionados. Selecione menos objetos e tente novamente. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="ProblemImportingEstateCovenant"> Problemas encontrados ao importar o Corretor da propriedade. <usetemplate name="okbutton" yestext="OK"/> @@ -2288,6 +2316,10 @@ Mover para o inventário o(s) item(s)? Falha no pagamento: objeto não encontrado. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="PaymentBlockedButtonMismatch"> + Pagamento interrompido: o valor pago não corresponde aos botões de pagamento definidos para esse objeto. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="OpenObjectCannotCopy"> Não há itens neste objeto que você está autorizado a copiar. </notification> @@ -2323,6 +2355,12 @@ Não é possÃvel desfazer essa ação. Essa é uma seleção ampla com linksets. Se você desvinculá-la, pode não ser possÃvel vinculá-la novamente. Como precaução, pode ser interessante fazer cópias dos linksets no seu inventário. <usetemplate ignoretext="Confirmar quando desvincular um linkset" name="okcancelignore" notext="Cancelar" yestext="Desvincular"/> </notification> + <notification name="HelpReportAbuseConfirm"> + Obrigado por nos informar sobre esse problema. +Nós analisaremos seu relatório em busca de possÃveis violações e +tomaremos as medidas cabÃveis. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="HelpReportAbuseSelectCategory"> Por favor, selecione uma categoria para a reportagem deste abuso. A seleção de uma categoria nos ajuda a arquivar e processar as reportagens de abuso. @@ -2393,6 +2431,10 @@ Deseja desativar o Não perturbe antes de concluir esta transação? Tem certeza de que deseja excluir o conteúdo da Lixeira? Para sempre? <usetemplate ignoretext="Confirmar antes de esvaziar a pasta Lixeira" name="okcancelignore" notext="Não" yestext="Sim"/> </notification> + <notification name="TrashIsFull"> + Sua lixeira está transbordando. Isso pode causar problemas no logon. + <usetemplate name="okcancelbuttons" notext="Esvaziarei a lixeira mais tarde" yestext="Esvaziar lixeira agora"/> + </notification> <notification name="ConfirmClearBrowserCache"> Tem certeza de que quer apagar todo o histórico de viagens, web e buscas? <usetemplate name="okcancelbuttons" notext="Não" yestext="OK"/> @@ -2744,6 +2786,10 @@ Logo, não é possÃvel voar aqui. <notification name="PathfindingDirty"> A região possui alterações de pathfinding pendentes. Se você possui direitos de construção, poderá recarregar a região clicando no botão “Recarregar regiãoâ€. </notification> + <notification name="PathfindingDirtyRebake"> + A região possui alterações de pathfinding pendentes. Se você possui direitos de construção, poderá recarregar a região clicando no botão “Recarregar regiãoâ€. + <usetemplate name="okbutton" yestext="Recarregar região"/> + </notification> <notification name="DynamicPathfindingDisabled"> O pathfinding dinâmico não está habilitado nesta região. Os objetos com script usando chamadas LSL de pathfinding podem não operar como o esperado na região. </notification> @@ -2977,7 +3023,7 @@ Se permanecer aqui, você será desconectado. [MESSAGE] -Do objeto: <nolink>[OBJECTNAME]</nolink>, de: [NAME_SLURL] +Do objeto: <nolink>[OBJECTNAME]</nolink>, proprietário: [NAME_SLURL] <form name="form"> <button name="Gotopage" text="Carregar"/> <button name="Cancel" text="Cancelar"/> @@ -3246,6 +3292,12 @@ Para sua segurança, os SLurls serão bloqueados por alguns instantes. <notification name="AttachmentSaved"> Anexo salvo. </notification> + <notification name="AppearanceToXMLSaved"> + A aparência foi salva como XML em [PATH] + </notification> + <notification name="AppearanceToXMLFailed"> + Falha ao salvar a aparência como XML. + </notification> <notification name="PresetNotSaved"> Erro ao salvar predefinição [NAME]. </notification> @@ -3458,13 +3510,6 @@ Se o botão Falar for ocultado, o recurso de voz será desabilitado. <notification name="ForceQuitDueToLowMemory"> O SL será encerrado em 30 segundos devido falta de memória. </notification> - <notification name="PopupAttempt"> - Um pop-up foi bloqueado. - <form name="form"> - <ignore name="ignore" text="Ativar todos os pop-ups"/> - <button name="open" text="Abrir pop-up"/> - </form> - </notification> <notification name="SOCKS_NOT_PERMITTED"> O proxy SOCKS 5 "[HOST]:[PORT]" recusou a conexão, não permitida pelo conjunto de regras. <usetemplate name="okbutton" yestext="OK"/> @@ -3839,6 +3884,9 @@ Tente novamente em instantes. Não é possÃvel mover '[OBJECT_NAME]' para [OBJ_POSITION] na região [REGION_NAME] porque não há recursos suficientes para este objeto neste lote. </notification> + <notification name="NoParcelPermsNoObject"> + A cópia falhou porque você não tem acesso a esse lote. + </notification> <notification name="CantMoveObjectRegionVersion"> Não é possÃvel mover '[OBJECT_NAME]' para [OBJ_POSITION] na região [REGION_NAME] porque outra região está executando uma versão mais antiga, que não dá suporte o recebimento deste objeto por meio de passagem de regiões. @@ -3854,6 +3902,10 @@ Tente novamente em instantes. <notification name="NoPermModifyObject"> Você não está autorizado a modificar este objeto </notification> + <notification name="TooMuchObjectInventorySelected"> + Há muitos objetos com inventário grande selecionados. Selecione menos objetos e tente novamente. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="CantEnablePhysObjContributesToNav"> Não é possÃvel ativar propriedades fÃsicas para um objeto que contribui para o navmesh. </notification> @@ -3890,6 +3942,12 @@ Tente novamente em instantes. <notification name="CantSaveModifyAttachment"> Não é possÃvel salvar no conteúdo do objeto: isso modificaria as permissões de anexo. </notification> + <notification name="AttachmentHasTooMuchInventory"> + Seus anexos têm muitos itens de inventário. Não é possÃvel adicionar mais itens. + </notification> + <notification name="IllegalAttachment"> + O anexo solicitou um ponto não existente no avatar. Ele foi anexado ao peito. + </notification> <notification name="TooManyScripts"> Muitos scripts. </notification> @@ -3982,6 +4040,12 @@ Tente novamente em instantes. <notification name="TeleportedByObjectUnknownUser"> Você foi teletransportado pelo objeto '[OBJECT_NAME]' de propriedade de um usuário desconhecido. </notification> + <notification name="StandDeniedByObject"> + '[OBJECT_NAME]' não permite que você fique de pé no momento. + </notification> + <notification name="ResitDeniedByObject"> + '[OBJECT_NAME]' não permite que você altere seu assento no momento. + </notification> <notification name="CantCreateObjectRegionFull"> Não foi possÃvel criar o objeto solicitado. A região está cheia. </notification> @@ -4278,6 +4342,9 @@ Tente selecionar uma quantidade menor de terreno. <notification name="CantTransfterMoneyRegionDisabled"> Transferências de dinheiro para objetos estão desativadas para esta região no momento. </notification> + <notification name="DroppedMoneyTransferRequest"> + Não foi possÃvel fazer o pagamento devido a uma sobrecarga do sistema. + </notification> <notification name="CantPayNoAgent"> Não foi possÃvel descobrir a quem pagar. </notification> @@ -4313,4 +4380,8 @@ Tente selecionar uma quantidade menor de terreno. O arquivo de histórico de bate-papo está ocupado com uma operação anterior. Tente novamente em alguns minutos ou selecione outra pessoa para bater papo. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="OutfitPhotoLoadError"> + [REASON] + <usetemplate name="okbutton" yestext="OK"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/pt/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/pt/panel_outfits_inventory.xml index 816a9bc46efa19d7d98cd873564bef613a4c7318..8d055f476eecefa9f7c63074ac08c192967a006f 100644 --- a/indra/newview/skins/default/xui/pt/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/pt/panel_outfits_inventory.xml @@ -7,6 +7,7 @@ Vestir itens selecionados </panel.string> <tab_container name="appearance_tabs"> + <panel label="GALERIA DE LOOKS" name="outfit_gallery_tab"/> <panel label="MEUS LOOKS" name="outfitslist_tab"/> <panel label="EM USO" name="cof_tab"/> </tab_container> diff --git a/indra/newview/skins/default/xui/pt/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/pt/panel_outfits_wearing.xml index 9224ec47420950d17a91ba6ba6b5dd027288ba17..87bb04ff591432c90ed9e26d38f78697ad5cb6f8 100644 --- a/indra/newview/skins/default/xui/pt/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/pt/panel_outfits_wearing.xml @@ -1,6 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Wearing"> + <panel.string name="no_attachments"> + Nenhum anexo vestido. + </panel.string> + <accordion name="wearables_accordion"> + <accordion_tab name="tab_wearables" title="Itens de vestuário"/> + <accordion_tab name="tab_temp_attachments" title="Anexos temporários"/> + </accordion> <panel name="bottom_panel"> - <button name="options_gear_btn" tool_tip="Mostrar opções adicionais"/> + <menu_button name="options_gear_btn" tool_tip="Mostrar opções adicionais"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml index 2ffe720ccf863256a3572ef029d95f66883c560d..c865de0d08611d781c047c68e84bad7aa9473abb 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Avisar: </text> - <check_box label="Quando eu gasto ou recebo L$" name="notify_money_change_checkbox"/> + <check_box label="Quando eu gastar L$" name="notify_money_spend_checkbox"/> <check_box label="Quando meus amigos entram e saem" name="friends_online_notify_checkbox"/> + <check_box label="Quando eu receber L$" name="notify_money_received_checkbox"/> <text name="show_label"> Mostrar sempre: </text> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml index 4d3fb89b37ff9e946a5fff0d3219143025462ef8..fa17a4ff110e9907183060dfbb890bfd2cbf2474 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml @@ -25,10 +25,15 @@ rápido <text name="BetterText"> Melhor </text> + <slider label="Complexidade máxima do avatar:" name="IndirectMaxComplexity" tool_tip="Controla o ponto no qual um avatar visualmente complexo é desenhado como uma JellyDoll"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Tonalidades atmosféricas" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="Modelo avançado de luzes" name="UseLightShaders"/> <button label="Salvar configurações como predefinição..." name="PrefSaveButton"/> <button label="Carregar predefinição..." name="PrefLoadButton"/> + min_val="0.125" <button label="Excluir predefinição..." name="PrefDeleteButton"/> <button label="Redefinir para configurações recomendadas" left="110" name="Defaults"/> <button label="Configurações avançadas..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml index 6308d133bba13a33d1427741d15d747cfd5cbfa0..c6f6bba320a455557f522e3833fb7cf89d422961 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml @@ -30,6 +30,7 @@ <combo_box.item label="Baixarei e instalarei as atualizações manualmente" name="Install_manual"/> </combo_box> <check_box label="Disposto a atualizar para candidatos da versão" name="update_willing_to_test"/> + <check_box label="Mostrar notas de versão após atualização" name="update_show_release_notes"/> <text name="Proxy Settings:"> Configurações de proxy: </text> diff --git a/indra/newview/skins/default/xui/pt/panel_sound_devices.xml b/indra/newview/skins/default/xui/pt/panel_sound_devices.xml index 66db89f48f4b0391bbce295d0a65721c275668bf..97d6c0ef3639604d806f5b22eeb2656f59ab8c35 100644 --- a/indra/newview/skins/default/xui/pt/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/pt/panel_sound_devices.xml @@ -16,9 +16,9 @@ SaÃda </text> <text name="My volume label"> - Meu volume: + Volume do microfone: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Mude o volume usando o controle deslizante"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Mude o volume do microfone usando o controle deslizante"/> <text name="wait_text"> Aguarde </text> diff --git a/indra/newview/skins/default/xui/pt/panel_status_bar.xml b/indra/newview/skins/default/xui/pt/panel_status_bar.xml index cfe52ff404012b82b4358f401807dc468ad1a3cb..c35863734fb2a0f50826861290b93799904b3799 100644 --- a/indra/newview/skins/default/xui/pt/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/pt/panel_status_bar.xml @@ -5,7 +5,7 @@ <panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string> <panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string> <panel.string name="buycurrencylabel">L$ [AMT]</panel.string> - <panel left="-410" name="balance_bg" width="200"> + <panel left="-431" name="balance_bg" width="200"> <text name="balance" tool_tip="Atualizar saldo de L$" value="L$??"/> <button label="Comprar L$" name="buyL" tool_tip="Comprar mais L$"/> <button label="Comprar" name="goShop" tool_tip="Abrir Mercado do Second Life" width="80"/> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 50bb9b7e669891b0a0c99c90a7ad87706d6d2867..207b4e709707464024c9d4699ee45aa3461c5e37 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -30,7 +30,10 @@ </string> <string name="AboutHeader"> [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) -[[VIEWER_RELEASE_NOTES_URL] [Notas da versão]] +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + Configuração do corpo [BUILD_CONFIG] </string> <string name="AboutPosition"> Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em <nolink>[HOSTNAME]</nolink> ([HOSTIP]) @@ -49,20 +52,40 @@ Placa gráfica: [GRAPHICS_CARD] <string name="AboutDriver"> Versão do driver de vÃdeo Windows: [GRAPHICS_CARD_VENDOR] </string> - <string name="AboutLibs"> + <string name="AboutOGL"> Versão do OpenGL: [OPENGL_VERSION] - -Versão do J2C Decoder: [J2C_VERSION] + </string> + <string name="AboutSettings"> + Tamanho da janela: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Ajuste do tamanho de fonte: [FONT_SIZE_ADJUSTMENT]pt +Escala de interface: [UI_SCALE] +Dist. máxima: [DRAW_DISTANCE]m +Largura de banda: [NET_BANDWITH]kbit/s +Fator LOD: [LOD_FACTOR] +Qualidade de renderização: [RENDER_QUALITY] / 7 +Modelo de iluminação avançado: [GPU_SHADERS] +Memória de textura: [TEXTURE_MEMORY]MB +Tempo de criação de VFS (cache): [VFS_TIME] + </string> + <string name="AboutLibs"> + Versão do J2C Decoder: [J2C_VERSION] Versão do driver de áudio: [AUDIO_DRIVER_VERSION] Versão de LLCEFLib/CEF: [LLCEFLIB_VERSION] +Versão da LibVLC: [LIBVLC_VERSION] Versão do servidor de voz: [VOICE_VERSION] </string> <string name="AboutTraffic"> Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> <string name="ErrorFetchingServerReleaseNotesURL"> Erro ao obter URL de notas de versão do servidor. </string> + <string name="BuildConfiguration"> + Configuração do corpo + </string> <string name="ProgressRestoring"> Restaurando... </string> @@ -1032,6 +1055,9 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="TeleportYourAgent"> Teletransportá-lo </string> + <string name="ForceSitAvatar"> + Forçar o avatar a sentar + </string> <string name="AgentNameSubst"> (Você) </string> @@ -1336,6 +1362,9 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="BodyPartsRightLeg"> Perna direita </string> + <string name="BodyPartsEnhancedSkeleton"> + Esqueleto aprimorado + </string> <string name="GraphicsQualityLow"> Baixo </string> @@ -1778,6 +1807,51 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="Avatar Center"> Centro do avatar </string> + <string name="Left Ring Finger"> + Anelar esquerdo + </string> + <string name="Right Ring Finger"> + Anelar direito + </string> + <string name="Tail Base"> + Base do rabo + </string> + <string name="Tail Tip"> + Ponta do rabo + </string> + <string name="Left Wing"> + Asa esquerda + </string> + <string name="Right Wing"> + Asa direita + </string> + <string name="Jaw"> + Maxilar + </string> + <string name="Alt Left Ear"> + Orelha esquerda alt. + </string> + <string name="Alt Right Ear"> + Orelha direita alt. + </string> + <string name="Alt Left Eye"> + Olho esquerdo alt. + </string> + <string name="Alt Right Eye"> + Olho direito alt. + </string> + <string name="Tongue"> + LÃngua + </string> + <string name="Groin"> + Virilha + </string> + <string name="Left Hind Foot"> + Pata esq. traseira + </string> + <string name="Right Hind Foot"> + Pata dir. traseira + </string> <string name="Invalid Attachment"> Ponto de encaixe inválido </string> @@ -1823,6 +1897,27 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="av_render_anyone"> Sua renderização pode não acontecer para ninguém ao seu redor. </string> + <string name="hud_description_total"> + Seu HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (vestido em [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] usa muita memória de textura + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] contém muitos objetos e texturas que utilizam o máximo de recursos + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] contém muitas texturas grandes + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] contém muitos objetos + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] contém muitas texturas + </string> <string name="AgeYearsA"> [COUNT] ano </string> @@ -1982,6 +2077,9 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="ObjectOutOfRange"> Script (objeto fora de alcance) </string> + <string name="ScriptWasDeleted"> + Script (excluÃdo do inventário) + </string> <string name="GodToolsObjectOwnedBy"> Objeto [OBJECT] de propriedade de [OWNER] </string> @@ -2167,12 +2265,12 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="ATTACH_BELLY"> Barriga </string> - <string name="ATTACH_RPEC"> - Peitorais D - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Peitorais E </string> + <string name="ATTACH_RIGHT_PEC"> + Peitorais D + </string> <string name="ATTACH_HUD_CENTER_2"> HUD Central 2 </string> @@ -2203,6 +2301,51 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="ATTACH_AVATAR_CENTER"> Centro do avatar </string> + <string name="ATTACH_LHAND_RING1"> + Anelar esquerdo + </string> + <string name="ATTACH_RHAND_RING1"> + Anelar direito + </string> + <string name="ATTACH_TAIL_BASE"> + Base do rabo + </string> + <string name="ATTACH_TAIL_TIP"> + Ponta do rabo + </string> + <string name="ATTACH_LWING"> + Asa esquerda + </string> + <string name="ATTACH_RWING"> + Asa direita + </string> + <string name="ATTACH_FACE_JAW"> + Maxilar + </string> + <string name="ATTACH_FACE_LEAR"> + Orelha esquerda alt. + </string> + <string name="ATTACH_FACE_REAR"> + Orelha direita alt. + </string> + <string name="ATTACH_FACE_LEYE"> + Olho esquerdo alt. + </string> + <string name="ATTACH_FACE_REYE"> + Olho direito alt. + </string> + <string name="ATTACH_FACE_TONGUE"> + LÃngua + </string> + <string name="ATTACH_GROIN"> + Virilha + </string> + <string name="ATTACH_HIND_LFOOT"> + Pata esq. traseira + </string> + <string name="ATTACH_HIND_RFOOT"> + Pata dir. traseira + </string> <string name="CursorPos"> Linha [LINE], Coluna [COLUMN] </string> @@ -2507,6 +2650,15 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh <string name="Play Media"> Tocar/Pausar mÃdia </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com.br/Download/index.aspx?lang=br + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> <string name="MBCmdLineError"> Um erro foi encontrado analisando a linha de comando. Consulte: http://wiki.secondlife.com/wiki/Client_parameters @@ -4128,6 +4280,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="OfflineStatus"> Desconectado </string> + <string name="not_online_msg"> + O usuário não está online. As mensagens serão armazenadas e enviadas mais tarde. + </string> + <string name="not_online_inventory"> + O usuário não está online. O inventário foi salvo. + </string> <string name="answered_call"> Ligação atendida </string> @@ -4248,12 +4406,18 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="paid_you_ldollars"> [NAME] lhe pagou L$ [AMOUNT] [REASON]. </string> + <string name="paid_you_ldollars_gift"> + [NAME] lhe pagou L$ [AMOUNT]: [REASON] + </string> <string name="paid_you_ldollars_no_reason"> [NAME] lhe pagou L$ [AMOUNT] </string> <string name="you_paid_ldollars"> Você pagou L$[AMOUNT] por [REASON] a [NAME]. </string> + <string name="you_paid_ldollars_gift"> + Você pagou L$[AMOUNT] a [NAME]: [REASON] + </string> <string name="you_paid_ldollars_no_info"> Você acaba de pagar L$[AMOUNT]. </string> @@ -4266,6 +4430,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="you_paid_failure_ldollars"> Você não pagou L$[AMOUNT] a [NAME] referentes a [REASON]. </string> + <string name="you_paid_failure_ldollars_gift"> + Você não pagou L$[AMOUNT] a [NAME]: [REASON] + </string> <string name="you_paid_failure_ldollars_no_info"> Você não pagou L$[AMOUNT]. </string> @@ -4592,6 +4759,15 @@ Denunciar abuso <string name="texture_load_dimensions_error"> A imagem excede o limite [WIDTH]*[HEIGHT] </string> + <string name="outfit_photo_load_dimensions_error"> + O tamanho máx. do look é [WIDTH]*[HEIGHT]. Redimensione ou use outra imagem + </string> + <string name="outfit_photo_select_dimensions_error"> + O tamanho máx. do look é [WIDTH]*[HEIGHT]. Selecione outra textura + </string> + <string name="outfit_photo_verify_dimensions_error"> + Não foi possÃvel confirmar as dimensões da foto. Aguarde até que o tamanho da foto seja exibido no seletor + </string> <string name="words_separator" value=","/> <string name="server_is_down"> Aconteceu algo inesperado, apesar de termos tentado impedir isso. @@ -5096,6 +5272,9 @@ Tente colocar o caminho do editor entre aspas. <string name="Command_Profile_Label"> Perfil </string> + <string name="Command_Report_Abuse_Label"> + Relatar abuso + </string> <string name="Command_Search_Label"> Buscar </string> @@ -5186,6 +5365,9 @@ Tente colocar o caminho do editor entre aspas. <string name="Command_Profile_Tooltip"> Edite ou visualize seu perfil </string> + <string name="Command_Report_Abuse_Tooltip"> + Relatar abuso + </string> <string name="Command_Search_Tooltip"> Encontre lugares, eventos, pessoas </string> diff --git a/indra/newview/skins/default/xui/ru/floater_model_preview.xml b/indra/newview/skins/default/xui/ru/floater_model_preview.xml index d660dd97b5fcf34b12d8a16b86df7766dd53e1c3..94aa7218560b20f72875f247ed2383e862d6cd5d 100644 --- a/indra/newview/skins/default/xui/ru/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/ru/floater_model_preview.xml @@ -245,6 +245,7 @@ </text> <check_box label="Включить Ð²ÐµÑ ÐºÐ¾Ð¶Ð¸" name="upload_skin"/> <check_box label="Включить Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑуÑтавов" name="upload_joints"/> + <check_box label="ФикÑировать маÑштаб, еÑли определено положение ÑуÑтава" name="lock_scale_if_joint_position"/> <text name="pelvis_offset_label"> Смещение по Z (поднÑÑ‚ÑŒ или опуÑтить аватар): </text> diff --git a/indra/newview/skins/default/xui/ru/floater_pay.xml b/indra/newview/skins/default/xui/ru/floater_pay.xml index 0a269b9e000c7e5101db51ac37323ddf8206e79c..990ebb873f1f0305ecdacd9460f407d965aaa9b0 100644 --- a/indra/newview/skins/default/xui/ru/floater_pay.xml +++ b/indra/newview/skins/default/xui/ru/floater_pay.xml @@ -1,9 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Give Money"> - <string name="payee_group">Заплатить группе</string> - <string name="payee_resident">Заплатить жителю</string> - <text name="paying_text">Ð’Ñ‹ платите:</text> - <text name="payee_name">Слишком длинное теÑтовое Ð¸Ð¼Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ обрезаниÑ</text> + <string name="payee_group"> + Заплатить группе + </string> + <string name="payee_resident"> + Заплатить жителю + </string> + <text name="paying_text"> + Ð’Ñ‹ платите: + </text> + <text name="payee_name"> + Слишком длинное теÑтовое Ð¸Ð¼Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ Ð¾Ð±Ñ€ÐµÐ·Ð°Ð½Ð¸Ñ + </text> + <text name="payment_message_label"> + ОпиÑание (не обÑзательно): + </text> <panel label="ПоиÑк" name="PatternsPanel"> <button label="Оплатить L$ 1" label_selected="Оплатить L$ 1" name="fastpay 1"/> <button label="Оплатить L$ 5" label_selected="Оплатить L$ 5" name="fastpay 5"/> @@ -11,7 +22,9 @@ <button label="Оплатить L$ 20" label_selected="Оплатить L$ 20" name="fastpay 20"/> </panel> <panel label="ПоиÑк" name="InputPanel"> - <text name="amount text">Ð”Ñ€ÑƒÐ³Ð°Ñ Ñумма:</text> + <text name="amount text"> + Ð”Ñ€ÑƒÐ³Ð°Ñ Ñумма: + </text> <button label="Оплатить" label_selected="Оплатить" name="pay btn"/> <button label="Отмена" label_selected="Отмена" name="cancel btn"/> </panel> diff --git a/indra/newview/skins/default/xui/ru/floater_script_queue.xml b/indra/newview/skins/default/xui/ru/floater_script_queue.xml index 4f2e389b19f944b913a2cdc5ed73bc4ad4191d55..90c1f2f49ce9ef6f79f7547f1dcbb3c03264fff5 100644 --- a/indra/newview/skins/default/xui/ru/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/ru/floater_script_queue.xml @@ -15,5 +15,11 @@ <floater.string name="NotRunning"> Ðе запущен </floater.string> + <floater.string name="Timeout"> + Задержка: [OBJECT_NAME] + </floater.string> + <floater.string name="LoadingObjInv"> + Загрузка Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð´Ð»Ñ: [OBJECT_NAME] + </floater.string> <button label="Закрыть" label_selected="Закрыть" name="close"/> </floater> diff --git a/indra/newview/skins/default/xui/ru/floater_web_content.xml b/indra/newview/skins/default/xui/ru/floater_web_content.xml index 403ab0ef5dcdf5aa81cd650c2e30d94ed4ef835c..d572a54b5baacbab04269e3d9d00248c109b9653 100644 --- a/indra/newview/skins/default/xui/ru/floater_web_content.xml +++ b/indra/newview/skins/default/xui/ru/floater_web_content.xml @@ -10,5 +10,9 @@ <icon name="media_secure_lock_flag" tool_tip="БезопаÑный проÑмотр"/> <button name="popexternal" tool_tip="Открыть текущий URL-Ð°Ð´Ñ€ÐµÑ Ð² вашем браузере"/> </layout_panel> + <layout_panel name="debug_controls"> + <button name="web_test_home_page" tool_tip="Ð“Ð»Ð°Ð²Ð½Ð°Ñ Ñтраница веб-теÑтированиÑ"/> + <button name="VLC Plugin Test" tool_tip="ТеÑÑ‚ видео MPEG4"/> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/ru/menu_attachment_other.xml b/indra/newview/skins/default/xui/ru/menu_attachment_other.xml index bd1ed8d1fa2d4f96faf6ff9b9b2334a4cd62cb6b..63b0698c6b6497237c168c5f6fc7d296718aed3f 100644 --- a/indra/newview/skins/default/xui/ru/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/ru/menu_attachment_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Звонок" name="Call"/> <menu_item_call label="ПриглаÑить в группу" name="Invite..."/> + <menu_item_call label="Ð¡Ð±Ñ€Ð¾Ñ Ñкелета" name="Reset Skeleton"/> + <menu_item_call label="ВоÑÑтановить Ñкелет и анимации" name="Reset Skeleton And Animations"/> <menu_item_call label="Заблокировать" name="Avatar Mute"/> <menu_item_call label="ПожаловатьÑÑ" name="abuse"/> <menu_item_call label="Заморозить" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/ru/menu_attachment_self.xml b/indra/newview/skins/default/xui/ru/menu_attachment_self.xml index 033d36484b2e3fb091dc0a77c09a45b1e35ab9ee..f33ef1d4ee53b4462e68307ba9fb53c05b6dc731 100644 --- a/indra/newview/skins/default/xui/ru/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/ru/menu_attachment_self.xml @@ -9,6 +9,8 @@ <menu_item_call label="Изменить коÑтюм" name="Edit Outfit"/> <menu_item_call label="Изменить фигуру" name="Edit My Shape"/> <menu_item_call label="Ð’Ñ‹Ñота парениÑ" name="Hover Height"/> + <menu_item_call label="Ð¡Ð±Ñ€Ð¾Ñ Ñкелета" name="Reset Skeleton"/> + <menu_item_call label="ВоÑÑтановить Ñкелет и анимации" name="Reset Skeleton And Animations"/> <menu_item_call label="Мои друзьÑ" name="Friends..."/> <menu_item_call label="Мои группы" name="Groups..."/> <menu_item_call label="Мой профиль" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/ru/menu_avatar_other.xml b/indra/newview/skins/default/xui/ru/menu_avatar_other.xml index 74f1a396581b5f21de8c1c7e6b96b47973c387d7..de35264055ff277f761d5f5bc03952012cd97f2f 100644 --- a/indra/newview/skins/default/xui/ru/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/ru/menu_avatar_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="Звонок" name="Call"/> <menu_item_call label="ПриглаÑить в группу" name="Invite..."/> + <menu_item_call label="Ð¡Ð±Ñ€Ð¾Ñ Ñкелета" name="Reset Skeleton"/> + <menu_item_call label="ВоÑÑтановить Ñкелет и анимации" name="Reset Skeleton And Animations"/> <menu_item_call label="Заблокировать" name="Avatar Mute"/> <menu_item_call label="ПожаловатьÑÑ" name="abuse"/> <menu_item_call label="Заморозить" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/ru/menu_avatar_self.xml b/indra/newview/skins/default/xui/ru/menu_avatar_self.xml index 8feaa3b99a258e01fe389091db9c5c0f3b02367d..cd75551b5d2be6a28721c2a70f53ca28e5a9e0cb 100644 --- a/indra/newview/skins/default/xui/ru/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/ru/menu_avatar_self.xml @@ -26,6 +26,8 @@ <menu_item_call label="Изменить коÑтюм" name="Edit Outfit"/> <menu_item_call label="Изменить фигуру" name="Edit My Shape"/> <menu_item_call label="Ð’Ñ‹Ñота парениÑ" name="Hover Height"/> + <menu_item_call label="Ð¡Ð±Ñ€Ð¾Ñ Ñкелета" name="Reset Skeleton"/> + <menu_item_call label="ВоÑÑтановить Ñкелет и анимации" name="Reset Skeleton And Animations"/> <menu_item_call label="Мои друзьÑ" name="Friends..."/> <menu_item_call label="Мои группы" name="Groups..."/> <menu_item_call label="Мой профиль" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/ru/menu_login.xml b/indra/newview/skins/default/xui/ru/menu_login.xml index 2deab04d81df64602abd4761a8ef396a2132e01d..2d1fe282421b5d0bfb2a08720ad3dc6d29050c49 100644 --- a/indra/newview/skins/default/xui/ru/menu_login.xml +++ b/indra/newview/skins/default/xui/ru/menu_login.xml @@ -20,13 +20,12 @@ <menu_item_check label="Показать меню отладки" name="Show Debug Menu"/> <menu label="Отладка" name="Debug"> <menu_item_call label="ÐаÑтройки отладки" name="Debug Settings"/> - <menu_item_call label="ÐаÑтройки интерфейÑа/цвета" name="UI/Color Settings"/> <menu_item_call label="ПроÑмотр XUI" name="UI Preview Tool"/> <menu label="ТеÑÑ‚ UI" name="UI Tests"/> <menu_item_call label="Задать размер окна..." name="Set Window Size..."/> <menu_item_call label="Показать лицензионное Ñоглашение" name="TOS"/> <menu_item_call label="Показать Ñообщение об ошибке" name="Critical"/> - <menu_item_call label="ТеÑÑ‚ отладки плавающего окна Ñ Ð²ÐµÐ±-контентом" name="Web Content Floater Debug Test"/> + <menu_item_call label="Медиа-браузер" name="Media Browser"/> <menu label="Уровень журнала" name="Set Logging Level"> <menu_item_check label="Отладка" name="Debug"/> <menu_item_check label="ИнформациÑ" name="Info"/> diff --git a/indra/newview/skins/default/xui/ru/menu_object_icon.xml b/indra/newview/skins/default/xui/ru/menu_object_icon.xml index 0c50abcfbdf904471c6b386dc70b004a58bd43dd..bb97fb2ef75b1fd237393e8b999191beb8850a5c 100644 --- a/indra/newview/skins/default/xui/ru/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/ru/menu_object_icon.xml @@ -2,6 +2,7 @@ <menu name="Object Icon Menu"> <menu_item_call label="Профиль объекта..." name="Object Profile"/> <menu_item_call label="Блокировать..." name="Block"/> + <menu_item_call label="Разблокировать" name="Unblock"/> <menu_item_call label="Показать на карте" name="show_on_map"/> <menu_item_call label="Телепорт в меÑтоположение объекта" name="teleport_to_object"/> </menu> diff --git a/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml b/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml index d379a172166bdf85138c908240c6675bac659935..24d780ba1c625422d1bea682bd253d5e0e05afeb 100644 --- a/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml @@ -3,6 +3,10 @@ <menu_item_call label="Ðадеть – Заменить текущий коÑтюм" name="wear"/> <menu_item_call label="Ðадеть – Добавить к текущему коÑтюму" name="wear_add"/> <menu_item_call label="СнÑÑ‚ÑŒ – Убрать из текущего коÑтюма" name="take_off"/> + <menu_item_call label="Загрузить фото (L$10)" name="upload_photo"/> + <menu_item_call label="Выбрать фото" name="select_photo"/> + <menu_item_call label="Сделать Ñнимок" name="take_snapshot"/> + <menu_item_call label="Удалить фото" name="remove_photo"/> <menu label="ÐÐ¾Ð²Ð°Ñ Ð¾Ð´ÐµÐ¶Ð´Ð°" name="New Clothes"> <menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ñ€ÑƒÐ±Ð°ÑˆÐºÐ°" name="New Shirt"/> <menu_item_call label="Ðовые брюки" name="New Pants"/> @@ -27,4 +31,5 @@ <menu_item_call label="Закрыть вÑе папки" name="collapse"/> <menu_item_call label="Переименовать коÑтюм" name="rename"/> <menu_item_call label="Удалить коÑтюм" name="delete_outfit"/> + <menu_item_check label="Ð’Ñегда Ñортировать папки по имени" name="sort_folders_by_name"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/ru/menu_people_friends_view.xml b/indra/newview/skins/default/xui/ru/menu_people_friends_view.xml index 7b2dba0539620e8d21e974425dd399a6cd8ff8a2..fd04810dff91a9cb75ae6977f30a5a440c3e942d 100644 --- a/indra/newview/skins/default/xui/ru/menu_people_friends_view.xml +++ b/indra/newview/skins/default/xui/ru/menu_people_friends_view.xml @@ -4,5 +4,6 @@ <menu_item_check label="Сортировать по ÑтатуÑу" name="sort_status"/> <menu_item_check label="Показывать значки людей" name="view_icons"/> <menu_item_check label="Показывать разрешенные дейÑтвиÑ" name="view_permissions"/> + <menu_item_check label="Скрывать имена пользователей" name="view_usernames"/> <menu_item_check label="ПоÑмотреть журнал разговора..." name="view_conversation"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/ru/menu_people_nearby.xml b/indra/newview/skins/default/xui/ru/menu_people_nearby.xml index d05b7e7d012c53ae2e266bbfc4c31417b9949332..952e9b1687ee0de1c0df87c65dd14753f8e2312f 100644 --- a/indra/newview/skins/default/xui/ru/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/ru/menu_people_nearby.xml @@ -13,4 +13,6 @@ <menu_item_call label="ПоделитьÑÑ" name="share"/> <menu_item_call label="Заплатить" name="pay"/> <menu_item_check label="Черный ÑпиÑок" name="block_unblock"/> + <menu_item_call label="Заморозить" name="freeze"/> + <menu_item_call label="Выкинуть" name="eject"/> </context_menu> diff --git a/indra/newview/skins/default/xui/ru/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/ru/menu_people_nearby_view.xml index 2bc353ad5831ddc278c3dd4399ea994f5196f3da..0e949cedff1458654b9fb4552688c95e147ba30e 100644 --- a/indra/newview/skins/default/xui/ru/menu_people_nearby_view.xml +++ b/indra/newview/skins/default/xui/ru/menu_people_nearby_view.xml @@ -5,4 +5,5 @@ <menu_item_check label="Сортировать по раÑÑтоÑнию" name="sort_distance"/> <menu_item_check label="Показывать значки людей" name="view_icons"/> <menu_item_check label="Смотреть карту" name="view_map"/> + <menu_item_check label="Скрывать имена пользователей" name="view_usernames"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/ru/menu_url_objectim.xml b/indra/newview/skins/default/xui/ru/menu_url_objectim.xml index 4f5361b2e364ce93dfb342a46a4d3b18457c5b80..1b77770e1c480ea128d9ae75a659ee8be15091d6 100644 --- a/indra/newview/skins/default/xui/ru/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/ru/menu_url_objectim.xml @@ -2,6 +2,7 @@ <context_menu name="Url Popup"> <menu_item_call label="Профиль объекта..." name="show_object"/> <menu_item_call label="Блокировать..." name="block_object"/> + <menu_item_call label="Разблокировать" name="unblock_object"/> <menu_item_call label="Показать на карте" name="show_on_map"/> <menu_item_call label="Телепорт в меÑтоположение объекта" name="teleport_to_object"/> <menu_item_call label="Копировать название объекта в буфер обмена" name="url_copy_label"/> diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml index 2044844c588b56aa8f1d56d7aee76919ce835f50..e5e484173d151f9e36539319f76d177a7a3c63c3 100644 --- a/indra/newview/skins/default/xui/ru/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Ðе беÑпокоить" name="Do Not Disturb"/> </menu> <menu_item_call label="Купить L$..." name="Buy and Sell L$"/> - <menu_item_call label="Торговые иÑходÑщие..." name="MerchantOutbox"/> <menu_item_call label="СпиÑки товаров торгового центра..." name="MarketplaceListings"/> <menu_item_call label="Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ аккаунта..." name="Manage My Account"/> <menu_item_call label="ÐаÑтройки..." name="Preferences"/> @@ -112,11 +111,11 @@ <menu_item_call label="Объединить" name="Link"/> <menu_item_call label="Разъединить" name="Unlink"/> <menu_item_check label="Редактировать объединенные чаÑти" name="Edit Linked Parts"/> - <menu label="Выбрать объединенные чаÑти" name="Select Linked Parts"> - <menu_item_call label="Выбрать Ñледующую" name="Select Next Part"/> - <menu_item_call label="Выбрать предыдущую" name="Select Previous Part"/> - <menu_item_call label="Включить Ñледующую" name="Include Next Part"/> - <menu_item_call label="Включить предыдущую" name="Include Previous Part"/> + <menu label="Выберите Ñлементы" name="Select Elements"> + <menu_item_call label="Выбрать Ñледующую чаÑÑ‚ÑŒ или лицо" name="Select Next Part or Face"/> + <menu_item_call label="Выбрать предыдущую чаÑÑ‚ÑŒ или лицо" name="Select Previous Part or Face"/> + <menu_item_call label="Включить Ñледующую чаÑÑ‚ÑŒ или лицо" name="Include Next Part or Face"/> + <menu_item_call label="Включить предыдущую чаÑÑ‚ÑŒ или лицо" name="Include Previous Part or Face"/> </menu> <menu_item_call label="Ðаборы ÑвÑзей..." name="pathfinding_linkset_menu_item"/> <menu_item_call label="Ð¤Ð¾ÐºÑƒÑ Ð½Ð° выбранном" name="Focus on Selection"/> @@ -366,8 +365,7 @@ <menu_item_call label="Вывод кÑша региональных объектов" name="Dump Region Object Cache"/> </menu> <menu label="Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" name="UI"> - <menu_item_call label="Проверка медиабраузера" name="Web Browser Test"/> - <menu_item_call label="Браузер Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра веб-контента" name="Web Content Browser"/> + <menu_item_call label="Браузер Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра медиа" name="Media Browser"/> <menu_item_call label="Вывод SelectMgr" name="Dump SelectMgr"/> <menu_item_call label="Вывод инвентарÑ" name="Dump Inventory"/> <menu_item_call label="Вывод таймеров" name="Dump Timers"/> @@ -418,6 +416,7 @@ <menu_item_check label="Отключить детализацию" name="Disable LOD"/> <menu_item_check label="Отладка видимоÑти перÑонажа" name="Debug Character Vis"/> <menu_item_check label="Показать Ñкелет" name="Show Collision Skeleton"/> + <menu_item_check label="Показать коÑти" name="Show Bones"/> <menu_item_check label="Отобразить дейÑтвие агента" name="Display Agent Target"/> <menu_item_call label="Вывод приÑоединений" name="Dump Attachments"/> <menu_item_call label="Отладка текÑтур аватара" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml b/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml index f178b39c774d858d0844db878b4dbde16742f01d..1e32090c2afe5a2e31ad88184cebf8bf1cb92f6b 100644 --- a/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml @@ -3,4 +3,6 @@ <menu_item_call label="СнÑÑ‚ÑŒ" name="take_off"/> <menu_item_call label="ОтÑоединить" name="detach"/> <menu_item_call label="Изменить коÑтюм" name="edit"/> + <menu_item_call label="Изменить" name="edit_item"/> + <menu_item_call label="Показать оригинал" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/ru/mime_types.xml b/indra/newview/skins/default/xui/ru/mime_types.xml index 9b120f2f4084a85c78b0d52e97b6236a97c62f2c..9c3ce00c5e705c9354c43a41df65f3b336e40cb1 100644 --- a/indra/newview/skins/default/xui/ru/mime_types.xml +++ b/indra/newview/skins/default/xui/ru/mime_types.xml @@ -57,6 +57,11 @@ Поток RealTime </label> </scheme> + <scheme name="libvlc"> + <label name="libvlc_label"> + Медиа Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹ LibVLC + </label> + </scheme> <mimetype name="blank"> <label name="blank_label"> - Ðичего - @@ -202,6 +207,11 @@ Видео (MP4) </label> </mimetype> + <mimetype name="application/octet-stream"> + <label name="video/octet-stream"> + Видео + </label> + </mimetype> <mimetype name="video/quicktime"> <label name="video/quicktime_label"> Видео (QuickTime) diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml index fabc0645251eeff2b3608312ec99bb7a18b6545b..50931fc9b86a0ff29e85d3e18d04ab1ecacfa901 100644 --- a/indra/newview/skins/default/xui/ru/notifications.xml +++ b/indra/newview/skins/default/xui/ru/notifications.xml @@ -330,6 +330,9 @@ Ð’Ñ‹ ÑобираетеÑÑŒ запретить [COUNT] учаÑтникам доÑтуп в группу. <usetemplate ignoretext="Подтвердите запрет доÑтупа учаÑтникам в группу" name="okcancelignore" notext="Отмена" yestext="Бан"/> </notification> + <notification name="GroupBanUserOnBanlist"> + Ðекоторым резидентам не отправлено приглашение, так как они иÑключены из группы. + </notification> <notification name="AttachmentDrop"> Ð’Ñ‹ ÑобираетеÑÑŒ ÑброÑить Ñвое приÑоединение. Продолжить? @@ -457,6 +460,12 @@ <notification name="ErrorEncodingSnapshot"> Ошибка при кодировке Ñнимка. </notification> + <notification name="ErrorPhotoCannotAfford"> + ТребуетÑÑ L$[COST] Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñ„Ð¾Ñ‚Ð¾ в вашем инвентаре. Купите L$ или Ñохраните фото на компьютере. + </notification> + <notification name="ErrorTextureCannotAfford"> + ТребуетÑÑ L$[COST] Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑтуры в вашем инвентаре. Купите L$ или Ñохраните фото на компьютере. + </notification> <notification name="ErrorUploadingPostcard"> Ошибка при отправке Ñнимка по Ñледующей причине: [REASON] </notification> @@ -480,6 +489,9 @@ <notification name="CannotWearInfoNotComplete"> ÐÐµÐ»ÑŒÐ·Ñ Ð½Ð°Ð´ÐµÑ‚ÑŒ Ñту вещь, так как она еще не загружена. Повторите попытку через минуту. </notification> + <notification name="MustEnterPasswordToLogIn"> + Введите пароль Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в мир. + </notification> <notification name="MustHaveAccountToLogIn"> Ðй-Ñй-Ñй! Что-то оÑталоÑÑŒ незаполненным. Ðеобходимо ввеÑти Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ аватара. @@ -548,6 +560,9 @@ <notification name="ChangeConnectionPort"> ÐаÑтройки порта начнут дейÑтвовать поÑле перезапуÑка [APP_NAME]. </notification> + <notification name="ChangeDeferredDebugSetting"> + Ðта наÑтройка отладки вÑтупит в Ñилу поÑле перезапуÑка [APP_NAME]. + </notification> <notification name="ChangeSkin"> ÐÐ¾Ð²Ð°Ñ ÐºÐ¾Ð¶Ð° будет видна поÑле перезапуÑка [APP_NAME]. </notification> @@ -569,6 +584,10 @@ Удалить заметку? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> </notification> + <notification name="LoadPreviousReportScreenshot"> + ИÑпользовать Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ отчета предыдущий Ñнимок Ñкрана? + <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> + </notification> <notification name="GestureSaveFailedTooManySteps"> Ðе удалоÑÑŒ Ñохранить жеÑÑ‚. ЖеÑÑ‚ Ñодержит Ñлишком много Ñтапов. @@ -629,30 +648,12 @@ </url> <usetemplate ignoretext="Оборудование моего компьютера не поддерживаетÑÑ" name="okcancelignore" notext="Ðет" yestext="Да"/> </notification> - <notification name="IntelOldDriver"> - Возможно, Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ видеокарты имеетÑÑ Ð±Ð¾Ð»ÐµÐµ новый драйвер. Обновление драйвера может ÑущеÑтвенно повыÑить быÑтродейÑтвие. - - Проверить наличие Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð° по адреÑу [_URL]? - <url name="url"> - http://www.intel.com/p/ru_RU/support/detect/graphics - </url> - <usetemplate ignoretext="Мой графичеÑкий драйвер уÑтарел" name="okcancelignore" notext="Ðет" yestext="Да"/> - </notification> - <notification name="AMDOldDriver"> - Возможно, Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ видеокарты имеетÑÑ Ð±Ð¾Ð»ÐµÐµ новый драйвер. Обновление драйвера может ÑущеÑтвенно повыÑить быÑтродейÑтвие. - - Проверить наличие Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð° по адреÑу [_URL]? - <url name="url"> - http://support.amd.com/us/Pages/AMDSupportHub.aspx - </url> - <usetemplate ignoretext="Мой графичеÑкий драйвер уÑтарел" name="okcancelignore" notext="Ðет" yestext="Да"/> - </notification> - <notification name="NVIDIAOldDriver"> + <notification name="OldGPUDriver"> Возможно, Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ видеокарты имеетÑÑ Ð±Ð¾Ð»ÐµÐµ новый драйвер. Обновление драйвера может ÑущеÑтвенно повыÑить быÑтродейÑтвие. - Проверить наличие Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð° по адреÑу [_URL]? + Проверить наличие Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð° по адреÑу [URL]? <url name="url"> - http://www.nvidia.com/Download/index.aspx?lang=ru-ru + [URL] </url> <usetemplate ignoretext="Мой графичеÑкий драйвер уÑтарел" name="okcancelignore" notext="Ðет" yestext="Да"/> </notification> @@ -743,6 +744,9 @@ </url> <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> </notification> + <notification name="MuteLimitReached"> + Ðевозможно добавить новый пункт в ÑпиÑок заблокированных: доÑтигнуто предельное чиÑло пунктов [MUTE_LIMIT]. + </notification> <notification name="UnableToLinkObjects"> Ðевозможно объединить Ñти [COUNT] объектов. Можно объединÑÑ‚ÑŒ не более [MAX] объектов. @@ -1366,12 +1370,18 @@ <ignore name="ignore" text="Загрузка одежды занимает значительное времÑ"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - Ваша [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Ð²Ð¸Ð·ÑƒÐ°Ð»ÑŒÐ½Ð°Ñ ÑложноÑÑ‚ÑŒ]: [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + Ваша [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 ÑложноÑÑ‚ÑŒ аватара]: [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Предупреждать о превышении ÑложноÑти аватара" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - Ваша [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Ð²Ð¸Ð·ÑƒÐ°Ð»ÑŒÐ½Ð°Ñ ÑложноÑÑ‚ÑŒ]: [AGENT_COMPLEXITY]. + Ваша [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 ÑложноÑÑ‚ÑŒ аватара]: [AGENT_COMPLEXITY]. + <usetemplate ignoretext="Предупреждать Ð¼ÐµÐ½Ñ Ð¾Ð± изменении ÑложноÑти аватара" name="notifyignore"/> + </notification> + <notification name="HUDComplexityWarning"> + [HUD_REASON], возможно, отрицательно влиÑет на быÑтродейÑтвие. + <usetemplate ignoretext="Предупреждать о чрезмерной ÑложноÑти данных в игре" name="notifyignore"/> </notification> <notification name="FirstRun"> УÑтановка [APP_NAME] завершена. @@ -1463,6 +1473,10 @@ Телепортировать вÑех жителей в Ñтом регионе домой? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> </notification> + <notification name="ChangeObjectBonusFactor"> + Снижение бонуÑа за объекты поÑле ÑÐ¾Ð¾Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð¿Ð¾Ñтроек в регионе может вызвать возврат или удаление объектов. ДейÑтвительно изменить Ð±Ð¾Ð½ÑƒÑ Ð·Ð° объекты? + <usetemplate ignoretext="Подтвердите изменение бонуÑного Ð¼Ð½Ð¾Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð²" name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> <notification name="EstateObjectReturn"> Ð’Ñ‹ дейÑтвительно хотите вернуть объекты, принадлежащие [USER_NAME]? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> @@ -1486,6 +1500,10 @@ Ð’Ñ‹ дейÑтвительно хотите зафикÑировать текущий ландшафт, Ñделать его выÑоту Ñредней точкой Ð´Ð»Ñ Ð²ÐµÑ€Ñ…Ð½ÐµÐ¹ и нижней точек ландшафта и принÑÑ‚ÑŒ по умолчанию Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ «Вернуть»? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> </notification> + <notification name="ConfirmTextureHeights"> + Ð’Ñ‹ ÑобираетеÑÑŒ иÑпользовать минимальные значениÑ, которые больше, чем макÑимальные Ð´Ð»Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° выÑот. Ðачать? + <usetemplate canceltext="Ðе Ñпрашивать" name="yesnocancelbuttons" notext="Отмена" yestext="OK"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> У Ð²Ð°Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть не более [MAX_AGENTS] допущенных жителей. </notification> @@ -1506,6 +1524,9 @@ <notification name="OwnerCanNotBeDenied"> ÐÐµÐ»ÑŒÐ·Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ землевладельца в ÑпиÑок забаненных жителей его же земли. </notification> + <notification name="ProblemAddingEstateManagerBanned"> + Ðевозможно добавить заблокированного Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð² ÑпиÑок менеджеров землевладениÑ. + </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> ÐÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ внешноÑÑ‚ÑŒ, пока загружаютÑÑ Ð¾Ð´ÐµÐ¶Ð´Ð° и фигура. </notification> @@ -1680,6 +1701,10 @@ http://secondlife.com/download. Открыть браузер Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра Ñтого контента? <usetemplate ignoretext="ЗапуÑтить браузер Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра веб-Ñтраницы" name="okcancelignore" notext="Отмена" yestext="OK"/> </notification> + <notification name="SystemUIScaleFactorChanged"> + Со времени поÑледнего запуÑка изменилÑÑ ÑиÑтемный коÑффициент размера интерфейÑа. Открыть Ñтраницу наÑтроек размера интерфейÑа? + <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> + </notification> <notification name="WebLaunchJoinNow"> Перейти на [http://secondlife.com/account/ информационную панель] Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐ¸Ð¼ аккаунтом? <usetemplate ignoretext="ЗапуÑтить браузер Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð¾Ð¼" name="okcancelignore" notext="Отмена" yestext="OK"/> @@ -1719,16 +1744,15 @@ http://secondlife.com/download. Хотите покинуть группу? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> </notification> + <notification name="GroupDepart"> + Ð’Ñ‹ покинули группу «[group_name]». + </notification> <notification name="OwnerCannotLeaveGroup"> Ðевозможно покинуть группу. Ð’Ñ‹ не можете покинуть группу, так как вы ее поÑледний владелец. Сначала назначьте владельцем другого учаÑтника. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="GroupDepartError"> - Ðевозможно покинуть группу: [reason]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="GroupDepart"> - Ð’Ñ‹ покинули группу [group_name]. + Ðевозможно покинуть группу. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="ConfirmKick"> @@ -2128,6 +2152,10 @@ http://secondlife.com/download. Выбрано Ñлишком много примитивов. Выберите [MAX_PRIM_COUNT] или меньше примитивов и повторите попытку. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="TooManyScriptsSelected"> + Ð’ выбранных объектах Ñлишком много Ñкриптов. Выберите меньше объектов и повторите попытку. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="ProblemImportingEstateCovenant"> Проблема при импорте ÑÐ¾Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð¾ землевладении. <usetemplate name="okbutton" yestext="OK"/> @@ -2295,6 +2323,10 @@ http://secondlife.com/download. Ðе удалоÑÑŒ выполнить оплату: объект не найден. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="PaymentBlockedButtonMismatch"> + Платеж оÑтановлен: ÑƒÐ¿Ð»Ð°Ñ‡ÐµÐ½Ð½Ð°Ñ Ñумма не ÑоответÑтвует ни одной из кнопок оплаты, заданных Ð´Ð»Ñ Ñтого объекта. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="OpenObjectCannotCopy"> Ð’ Ñтом объекте нет вещей, которые вам разрешено копировать. </notification> @@ -2330,6 +2362,12 @@ http://secondlife.com/download. Ðто большое выделение Ñ Ð½Ð°Ð±Ð¾Ñ€Ð°Ð¼Ð¸ ÑвÑзей. ЕÑли разъединить его, повторное Ñоединение может отказатьÑÑ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñ‹Ð¼. Ð’ качеÑтве меры предоÑторожноÑти попробуйте Ñкопировать наборы ÑвÑзей в инвентарь. <usetemplate ignoretext="Подтверждать при разъединении набора ÑвÑзей" name="okcancelignore" notext="Отмена" yestext="Разъединить"/> </notification> + <notification name="HelpReportAbuseConfirm"> + СпаÑибо за информирование об Ñтой проблеме. +Мы проверим возможные Ð½Ð°Ñ€ÑƒÑˆÐµÐ½Ð¸Ñ ÑоглаÑно вашему отчету и примем +ÑоответÑтвующие меры. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="HelpReportAbuseSelectCategory"> Выберите категорию Ð´Ð»Ñ Ñтого ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾ нарушении. Категории облегчают региÑтрацию и обработку уведомлений. @@ -2400,6 +2438,10 @@ http://secondlife.com/download. Ð’Ñ‹ дейÑтвительно хотите необратимо удалить Ñодержимое корзины? <usetemplate ignoretext="Подтверждать перед опорожнением корзины инвентарÑ" name="okcancelignore" notext="Отмена" yestext="OK"/> </notification> + <notification name="TrashIsFull"> + Ваша корзина переполнена. Ðто может вызвать проблемы при входе. + <usetemplate name="okcancelbuttons" notext="Я очищу корзину позже" yestext="ОчиÑтить корзину ÑейчаÑ"/> + </notification> <notification name="ConfirmClearBrowserCache"> Ð’Ñ‹ дейÑтвительно хотите удалить журнал Ñвоих перемещений, веб-Ñтраниц и поиÑка? <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> @@ -2755,6 +2797,10 @@ http://secondlife.com/download. <notification name="PathfindingDirty"> Ð’ регионе еÑÑ‚ÑŒ незавершенные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð¸Ñка пути. ЕÑли у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ права на ÑтроительÑтво, воÑÑтановите регион, нажав кнопку «ВоÑÑтановить регион». </notification> + <notification name="PathfindingDirtyRebake"> + Ð’ регионе еÑÑ‚ÑŒ незавершенные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð¸Ñка пути. ЕÑли у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ права на ÑтроительÑтво, воÑÑтановите регион, нажав кнопку «ВоÑÑтановить регион». + <usetemplate name="okbutton" yestext="ВоÑÑтановить регион"/> + </notification> <notification name="DynamicPathfindingDisabled"> Ð’ Ñтом регионе не разрешен динамичеÑкий поиÑк пути. Возможны Ð½Ð°Ñ€ÑƒÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñкриптовых объектов Ñ Ð¸Ñпользованием вызовов LSL поиÑка пути. </notification> @@ -3257,6 +3303,12 @@ http://secondlife.com/download. <notification name="AttachmentSaved"> ПриÑоединение Ñохранено. </notification> + <notification name="AppearanceToXMLSaved"> + ВнешноÑÑ‚ÑŒ Ñохранена в формате XML в [PATH] + </notification> + <notification name="AppearanceToXMLFailed"> + Ðе удалоÑÑŒ Ñохранить внешноÑÑ‚ÑŒ в XML. + </notification> <notification name="PresetNotSaved"> Ошибка при Ñохранении преÑета [NAME]. </notification> @@ -3471,13 +3523,6 @@ http://secondlife.com/download. <notification name="ForceQuitDueToLowMemory"> Через 30 Ñекунд Second Life завершит работу: нехватка памÑти. </notification> - <notification name="PopupAttempt"> - Ð’Ñплывающее окно Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ. - <form name="form"> - <ignore name="ignore" text="Разрешить вÑе вÑплывающие окна"/> - <button name="open" text="Открыть вÑплывающее окно"/> - </form> - </notification> <notification name="SOCKS_NOT_PERMITTED"> ПрокÑи SOCKS 5 "[HOST]:[PORT]" отклонил попытку подключениÑ; не разрешено набором правил. <usetemplate name="okbutton" yestext="OK"/> @@ -3851,6 +3896,9 @@ http://secondlife.com/download. ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить объект «[OBJECT_NAME]» в позицию «[OBJ_POSITION]» региона [REGION_NAME]: на Ñтом учаÑтке недоÑтаточно реÑурÑов Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ объекта. </notification> + <notification name="NoParcelPermsNoObject"> + Ðе удалоÑÑŒ Ñкопировать: у Ð²Ð°Ñ Ð½ÐµÑ‚ доÑтупа к Ñтому учаÑтку. + </notification> <notification name="CantMoveObjectRegionVersion"> ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить объект «[OBJECT_NAME]» в позицию [OBJ_POSITION] региона [REGION_NAME]: в другом регионе работает ÑÑ‚Ð°Ñ€Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ ÑимулÑтора, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ поддерживает прием Ñтого объекта через границу регионов. @@ -3866,6 +3914,10 @@ http://secondlife.com/download. <notification name="NoPermModifyObject"> У Ð²Ð°Ñ Ð½ÐµÑ‚ прав на изменение Ñтого объекта </notification> + <notification name="TooMuchObjectInventorySelected"> + Выбрано Ñлишком много объектов Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ð¼ инвентарем. Выберите меньше объектов и повторите попытку. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="CantEnablePhysObjContributesToNav"> ÐÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ физику Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°, который отноÑитÑÑ Ðº навигационной Ñетке. </notification> @@ -3902,6 +3954,12 @@ http://secondlife.com/download. <notification name="CantSaveModifyAttachment"> ÐÐµÐ»ÑŒÐ·Ñ Ñохранить в Ñодержимом объекта: Ñто приведет к изменению разрешений прикрепленного объекта. </notification> + <notification name="AttachmentHasTooMuchInventory"> + Прикрепленные объекты Ñодержат Ñлишком много инвентарÑ. Добавление невозможно. + </notification> + <notification name="IllegalAttachment"> + ПрикреплÑемый объект потребовал неÑущеÑтвующей точки на аватаре. Он был прикреплен к груди. + </notification> <notification name="TooManyScripts"> Слишком много Ñкриптов. </notification> @@ -3994,6 +4052,12 @@ http://secondlife.com/download. <notification name="TeleportedByObjectUnknownUser"> Ð’Ñ‹ были телепортированы объектом «[OBJECT_NAME]», владелец неизвеÑтен. </notification> + <notification name="StandDeniedByObject"> + «[OBJECT_NAME]» не позволит вам ÑтоÑÑ‚ÑŒ в Ñто времÑ. + </notification> + <notification name="ResitDeniedByObject"> + «[OBJECT_NAME]» не позволит вам ÑÐµÐ¹Ñ‡Ð°Ñ Ñменить меÑто. + </notification> <notification name="CantCreateObjectRegionFull"> Ðевозможно Ñоздать запрошенный объект. Регион уже заполнен. </notification> @@ -4290,6 +4354,9 @@ http://secondlife.com/download. <notification name="CantTransfterMoneyRegionDisabled"> Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð² Ñтом регионе запрещен перевод денег на объекты. </notification> + <notification name="DroppedMoneyTransferRequest"> + Ðевозможно произвеÑти платеж из-за нагрузки на ÑиÑтему. + </notification> <notification name="CantPayNoAgent"> ÐепонÑтно, кому платить. </notification> @@ -4325,4 +4392,8 @@ http://secondlife.com/download. Файл журнала чата занÑÑ‚ предыдущей операцией. Повторите попытку через неÑколько минут или выберите чат Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼ лицом. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="OutfitPhotoLoadError"> + [REASON] + <usetemplate name="okbutton" yestext="OK"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/ru/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/ru/panel_outfits_inventory.xml index 4d0e13fca2c883fc75572b904518e30362c86e49..2c02df23c06c9ef4369f302afe8ad8a6963c64ea 100644 --- a/indra/newview/skins/default/xui/ru/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/ru/panel_outfits_inventory.xml @@ -7,6 +7,7 @@ Ðадеть выбранные вещи </panel.string> <tab_container name="appearance_tabs"> + <panel label="ГÐЛЕРЕЯ КОСТЮМОВ" name="outfit_gallery_tab"/> <panel label="МОИ КОСТЮМЫ" name="outfitslist_tab"/> <panel label="ÐÐДЕТО" name="cof_tab"/> </tab_container> diff --git a/indra/newview/skins/default/xui/ru/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/ru/panel_outfits_wearing.xml index 7ed6bf35c047f8d1a908aa8278d6ee3a43b512a4..748903b3df3eb6fa5f4819201fad421fd439a61a 100644 --- a/indra/newview/skins/default/xui/ru/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/ru/panel_outfits_wearing.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Wearing"> + <panel.string name="no_attachments"> + Ðет прикрепленных объектов. + </panel.string> + <accordion name="wearables_accordion"> + <accordion_tab name="tab_wearables" title="ÐоÑимые вещи"/> + <accordion_tab name="tab_temp_attachments" title="Временные прикрепленные объекты"/> + </accordion> <panel name="bottom_panel"> <menu_button name="options_gear_btn" tool_tip="Показать дополнительные параметры"/> </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml index 9d7ae546fd4e78fc36206478d5ce117bd3288233..48e03b98e897f23af3a964241dd6e8df81893eed 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Сообщать мне: </text> - <check_box label="о раÑходах и доходах" name="notify_money_change_checkbox"/> + <check_box label="О раÑходах" name="notify_money_spend_checkbox"/> <check_box label="о входе и выходе моих друзей" name="friends_online_notify_checkbox"/> + <check_box label="О доходах" name="notify_money_received_checkbox"/> <text name="show_label"> Ð’Ñегда показывать: </text> diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml index 31c9b2135d4aef5f44273869d599e5d77109b3be..200241bd4dcbc53ee6da7c81d3dcc3745874cbc0 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> КачеÑтвенней </text> + <slider label="МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ ÑложноÑÑ‚ÑŒ аватара:" name="IndirectMaxComplexity" tool_tip="Указывает раÑÑтоÑние, Ð½Ð°Ñ‡Ð¸Ð½Ð°Ñ Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ визуально Ñложный аватар риÑуетÑÑ ÐºÐ°Ðº мармеладный мишка"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="ÐтмоÑферные шейдеры" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="РаÑÑˆÐ¸Ñ€ÐµÐ½Ð½Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»ÑŒ оÑвещениÑ" name="UseLightShaders"/> <button label="Сохранить наÑтройки как преÑет..." name="PrefSaveButton"/> <button label="Загрузить преÑет..." name="PrefLoadButton"/> + min_val="0,125" <button label="Удалить преÑет..." name="PrefDeleteButton"/> <button label="Вернуть рекомендуемые наÑтройки" name="Defaults"/> <button label="РаÑширенные наÑтройки..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml index fd13abbe27029a2617ac2d8979048a39b26cdd66..e1b185e8efaff559bde86f9c9d6723a66c9dfb68 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml @@ -30,6 +30,7 @@ <combo_box.item label="Я буду загружать и уÑтанавливать Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ñ€ÑƒÑ‡Ð½ÑƒÑŽ" name="Install_manual"/> </combo_box> <check_box label="УÑтанавливать бета-верÑии" name="update_willing_to_test"/> + <check_box label="Показать заметки о выпуÑке поÑле обновлениÑ" name="update_show_release_notes"/> <text name="Proxy Settings:"> ÐаÑтройки прокÑи-Ñервера: </text> diff --git a/indra/newview/skins/default/xui/ru/panel_sound_devices.xml b/indra/newview/skins/default/xui/ru/panel_sound_devices.xml index 98dab288a36c7e623faff66a90980893d5193de5..3de84fb937f5b3bcf4ee21cc887d359f1ecab5e1 100644 --- a/indra/newview/skins/default/xui/ru/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/ru/panel_sound_devices.xml @@ -16,9 +16,9 @@ Выход </text> <text name="My volume label"> - ÐœÐ¾Ñ Ð³Ñ€Ð¾Ð¼ÐºÐ¾ÑÑ‚ÑŒ: + ГромкоÑÑ‚ÑŒ микрофона: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Измените значение, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¿Ð¾Ð»Ð·ÑƒÐ½Ð¾Ðº"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Измените уровень в микрофоне, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¿Ð¾Ð»Ð·ÑƒÐ½Ð¾Ðº"/> <text name="wait_text"> Подождите </text> diff --git a/indra/newview/skins/default/xui/ru/panel_status_bar.xml b/indra/newview/skins/default/xui/ru/panel_status_bar.xml index 630925fa6024f4afeb8cfc627e36bcbe3993a454..49c48ae6545618ec910b36426122ae28978494d1 100644 --- a/indra/newview/skins/default/xui/ru/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/ru/panel_status_bar.xml @@ -5,7 +5,7 @@ <panel.string name="time">[hour, datetime, slt]:[min, datetime, slt] [timezone,datetime, slt]</panel.string> <panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string> <panel.string name="buycurrencylabel">L$ [AMT]</panel.string> - <panel left="-450" name="balance_bg" width="240"> + <panel left="-471" name="balance_bg" width="240"> <text name="balance" tool_tip="Щелкните Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ баланÑа L$" value="L$??"/> <button label="Купить L$" name="buyL" tool_tip="Щелкните Ð´Ð»Ñ Ð¿Ð¾ÐºÑƒÐ¿ÐºÐ¸ L$"/> <button label="Торговый центр" name="goShop" tool_tip="Открыть торговый центр Second Life" width="121"/> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 04bb55c965b3cef71a0d57a02962f0711d92a9d3..e44d63b3b97d421c28a14353e0cb1e3a23311b76 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -41,6 +41,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> + <string name="BuildConfig"> + ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ [BUILD_CONFIG] + </string> <string name="AboutPosition"> Ð’Ñ‹ в точке [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] в регионе «[REGION]», раÑположенном на <nolink>[HOSTNAME]</nolink> ([HOSTIP]) SLURL: <nolink>[SLURL]</nolink> @@ -58,20 +61,40 @@ SLURL: <nolink>[SLURL]</nolink> <string name="AboutDriver"> ВерÑÐ¸Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑкого драйвера Windows: [GRAPHICS_DRIVER_VERSION] </string> - <string name="AboutLibs"> + <string name="AboutOGL"> ВерÑÐ¸Ñ OpenGL: [OPENGL_VERSION] - -ВерÑÐ¸Ñ Ð´ÐµÐºÐ¾Ð´ÐµÑ€Ð° J2C: [J2C_VERSION] + </string> + <string name="AboutSettings"> + Размер окна: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° шрифта: [FONT_SIZE_ADJUSTMENT]pt +МаÑштаб интерфейÑа: [UI_SCALE] +ДальноÑÑ‚ÑŒ отриÑовки: [DRAW_DISTANCE] м +Ширина канала: [NET_BANDWITH] кбит/Ñ +КоÑффициент детализации: [LOD_FACTOR] +КачеÑтво визуализации: [RENDER_QUALITY] / 7 +РаÑÑˆÐ¸Ñ€ÐµÐ½Ð½Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»ÑŒ оÑвещениÑ: [GPU_SHADERS] +ПамÑÑ‚ÑŒ текÑтур: [TEXTURE_MEMORY] МБ +Ð’Ñ€ÐµÐ¼Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ VFS (кÑш): [VFS_TIME] + </string> + <string name="AboutLibs"> + ВерÑÐ¸Ñ Ð´ÐµÐºÐ¾Ð´ÐµÑ€Ð° J2C: [J2C_VERSION] ВерÑÐ¸Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð° звука: [AUDIO_DRIVER_VERSION] ВерÑÐ¸Ñ LLCEFLib/CEF: [LLCEFLIB_VERSION] +ВерÑÐ¸Ñ LibVLC: [LIBVLC_VERSION] ВерÑÐ¸Ñ Ð³Ð¾Ð»Ð¾Ñового Ñервера: [VOICE_VERSION] </string> <string name="AboutTraffic"> ПотерÑно пакетов: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> <string name="ErrorFetchingServerReleaseNotesURL"> Ошибка при получении URL-адреÑа заметок о выпуÑке Ñервера. </string> + <string name="BuildConfiguration"> + ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ + </string> <string name="ProgressRestoring"> ВоÑÑтановление... </string> @@ -1080,6 +1103,9 @@ support@secondlife.com. <string name="TeleportYourAgent"> Телепортировать Ð²Ð°Ñ </string> + <string name="ForceSitAvatar"> + ЗаÑтавьте аватар ÑеÑÑ‚ÑŒ + </string> <string name="NotConnected"> Ðет Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ </string> @@ -1387,6 +1413,9 @@ support@secondlife.com. <string name="BodyPartsRightLeg"> ÐŸÑ€Ð°Ð²Ð°Ñ Ð½Ð¾Ð³Ð° </string> + <string name="BodyPartsEnhancedSkeleton"> + Улучшенный Ñкелет + </string> <string name="GraphicsQualityLow"> Ð½Ð¸Ð·ÐºÐ°Ñ </string> @@ -1835,6 +1864,51 @@ support@secondlife.com. <string name="Avatar Center"> Центр аватара </string> + <string name="Left Ring Finger"> + Левый безымÑнный палец + </string> + <string name="Right Ring Finger"> + Правый безымÑнный палец + </string> + <string name="Tail Base"> + ОÑнование хвоÑта + </string> + <string name="Tail Tip"> + Кончик хвоÑта + </string> + <string name="Left Wing"> + Левое крыло + </string> + <string name="Right Wing"> + Правое крыло + </string> + <string name="Jaw"> + ПаÑÑ‚ÑŒ + </string> + <string name="Alt Left Ear"> + Ðльт. левое ухо + </string> + <string name="Alt Right Ear"> + Ðльт. правое ухо + </string> + <string name="Alt Left Eye"> + Ðльт. левый глаз + </string> + <string name="Alt Right Eye"> + Ðльт. правый глаз + </string> + <string name="Tongue"> + Язык + </string> + <string name="Groin"> + Пах + </string> + <string name="Left Hind Foot"> + Ð›ÐµÐ²Ð°Ñ Ð·Ð°Ð´Ð½ÑÑ Ð½Ð¾Ð³Ð° + </string> + <string name="Right Hind Foot"> + ÐŸÑ€Ð°Ð²Ð°Ñ Ð·Ð°Ð´Ð½ÑÑ Ð½Ð¾Ð³Ð° + </string> <string name="Invalid Attachment"> ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ </string> @@ -1880,6 +1954,27 @@ support@secondlife.com. <string name="av_render_anyone"> Ðикто из окружающих учаÑтников не может отриÑовать ваÑ. </string> + <string name="hud_description_total"> + Ваши данные в игре + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (ноÑитÑÑ Ð½Ð° [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] иÑпользует большой объем памÑти текÑтур + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] Ñодержит много объемиÑÑ‚Ñ‹Ñ… объектов и текÑтур + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] Ñодержит много больших текÑтур + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] Ñодержит Ñлишком много объектов + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] Ñодержит Ñлишком много текÑтур + </string> <string name="AgeYearsA"> [COUNT] год </string> @@ -2039,6 +2134,9 @@ support@secondlife.com. <string name="ObjectOutOfRange"> Скрипт (объект вне облаÑти) </string> + <string name="ScriptWasDeleted"> + Скрипт (удален из инвентарÑ) + </string> <string name="GodToolsObjectOwnedBy"> Объект [OBJECT] Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ [OWNER] </string> @@ -2224,12 +2322,12 @@ support@secondlife.com. <string name="ATTACH_BELLY"> Живот </string> - <string name="ATTACH_RPEC"> - ÐŸÑ€Ð°Ð²Ð°Ñ Ð³Ñ€ÑƒÐ´ÑŒ - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Ð›ÐµÐ²Ð°Ñ Ð³Ñ€ÑƒÐ´ÑŒ </string> + <string name="ATTACH_RIGHT_PEC"> + ÐŸÑ€Ð°Ð²Ð°Ñ Ð³Ñ€ÑƒÐ´ÑŒ + </string> <string name="ATTACH_HUD_CENTER_2"> Данные в игре в центре 2 </string> @@ -2260,6 +2358,51 @@ support@secondlife.com. <string name="ATTACH_AVATAR_CENTER"> Центр аватара </string> + <string name="ATTACH_LHAND_RING1"> + Левый безымÑнный палец + </string> + <string name="ATTACH_RHAND_RING1"> + Правый безымÑнный палец + </string> + <string name="ATTACH_TAIL_BASE"> + ОÑнование хвоÑта + </string> + <string name="ATTACH_TAIL_TIP"> + Кончик хвоÑта + </string> + <string name="ATTACH_LWING"> + Левое крыло + </string> + <string name="ATTACH_RWING"> + Правое крыло + </string> + <string name="ATTACH_FACE_JAW"> + ПаÑÑ‚ÑŒ + </string> + <string name="ATTACH_FACE_LEAR"> + Ðльт. левое ухо + </string> + <string name="ATTACH_FACE_REAR"> + Ðльт. правое ухо + </string> + <string name="ATTACH_FACE_LEYE"> + Ðльт. левый глаз + </string> + <string name="ATTACH_FACE_REYE"> + Ðльт. правый глаз + </string> + <string name="ATTACH_FACE_TONGUE"> + Язык + </string> + <string name="ATTACH_GROIN"> + Пах + </string> + <string name="ATTACH_HIND_LFOOT"> + Ð›ÐµÐ²Ð°Ñ Ð·Ð°Ð´Ð½ÑÑ Ð½Ð¾Ð³Ð° + </string> + <string name="ATTACH_HIND_RFOOT"> + ÐŸÑ€Ð°Ð²Ð°Ñ Ð·Ð°Ð´Ð½ÑÑ Ð½Ð¾Ð³Ð° + </string> <string name="CursorPos"> Строка [LINE], Ñтолбец [COLUMN] </string> @@ -2606,6 +2749,15 @@ support@secondlife.com. <string name="Play Media"> Мультимедиа – воÑпроизведение/пауза </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=ru-ru + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> <string name="MBCmdLineError"> Ошибка при анализе командной Ñтроки. См.: http://wiki.secondlife.com/wiki/Client_parameters @@ -4247,10 +4399,10 @@ support@secondlife.com. Оффлайн </string> <string name="not_online_msg"> - Пользователь оффлайн - Ñообщение будет Ñохранено и доÑтавлено позже. + Пользователь не в онлайне - Ñообщение будет Ñохранено и доÑтавлено позже. </string> <string name="not_online_inventory"> - Пользователь оффлайн - инвентарь Ñохранен. + Пользователь не в онлайне - инвентарь Ñохранен. </string> <string name="answered_call"> Ðа ваш звонок ответили @@ -4378,12 +4530,18 @@ support@secondlife.com. <string name="paid_you_ldollars"> Житель [NAME] заплатил вам L$[AMOUNT] за [REASON]. </string> + <string name="paid_you_ldollars_gift"> + Пользователь [NAME] заплатил вам L$[AMOUNT]: [REASON] + </string> <string name="paid_you_ldollars_no_reason"> Житель [NAME] заплатил вам L$[AMOUNT]. </string> <string name="you_paid_ldollars"> Ð’Ñ‹ заплатили жителю [NAME] L$[AMOUNT] за [REASON]. </string> + <string name="you_paid_ldollars_gift"> + Ð’Ñ‹ заплатили пользователю [NAME] L$[AMOUNT]: [REASON] + </string> <string name="you_paid_ldollars_no_info"> Ð’Ñ‹ заплатили L$[AMOUNT]. </string> @@ -4396,6 +4554,9 @@ support@secondlife.com. <string name="you_paid_failure_ldollars"> Ð’Ñ‹ не Ñмогли заплатить пользователю [NAME] L$[AMOUNT]: [REASON]. </string> + <string name="you_paid_failure_ldollars_gift"> + Ð’Ñ‹ не Ñмогли заплатить пользователю [NAME] L$[AMOUNT]: [REASON] + </string> <string name="you_paid_failure_ldollars_no_info"> Ð’Ñ‹ не Ñмогли заплатить L$[AMOUNT] </string> @@ -4722,6 +4883,15 @@ support@secondlife.com. <string name="texture_load_dimensions_error"> ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð³Ñ€ÑƒÐ¶Ð°Ñ‚ÑŒ изображениÑ, размер которых превышает [WIDTH]*[HEIGHT] </string> + <string name="outfit_photo_load_dimensions_error"> + МакÑимальный размер фото коÑтюма [WIDTH]*[HEIGHT]. Измените размер или иÑпользуйте другое изображение + </string> + <string name="outfit_photo_select_dimensions_error"> + МакÑимальный размер фото коÑтюма [WIDTH]*[HEIGHT]. Выберите другую текÑтуру. + </string> + <string name="outfit_photo_verify_dimensions_error"> + Ðевозможно проверить размеры фото. Подождите, пока размеры фото не будут показаны в окне выбора + </string> <string name="words_separator" value=","/> <string name="server_is_down"> ÐеÑÐ¼Ð¾Ñ‚Ñ€Ñ Ð½Ð° наши уÑилиÑ, что-то неожиданно пошло не так. @@ -5238,6 +5408,9 @@ support@secondlife.com. <string name="Command_Profile_Label"> Профиль </string> + <string name="Command_Report_Abuse_Label"> + Жалоба + </string> <string name="Command_Search_Label"> ПоиÑк </string> @@ -5328,6 +5501,9 @@ support@secondlife.com. <string name="Command_Profile_Tooltip"> Редактирование или проÑмотр вашего Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ </string> + <string name="Command_Report_Abuse_Tooltip"> + Жалоба + </string> <string name="Command_Search_Tooltip"> ПоиÑк меÑÑ‚, Ñобытий, людей </string> diff --git a/indra/newview/skins/default/xui/tr/floater_model_preview.xml b/indra/newview/skins/default/xui/tr/floater_model_preview.xml index 29a56bae7e95271443c3b9b1b99d2ef43e332bca..3c00b67c50f295c1955a67cf0bc5e56f977a788e 100644 --- a/indra/newview/skins/default/xui/tr/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/tr/floater_model_preview.xml @@ -245,6 +245,7 @@ </text> <check_box label="Dış katman ağırlığını dahil et" name="upload_skin"/> <check_box label="Eklem konumlarını dahil et" name="upload_joints"/> + <check_box label="Eklem konumu tanımlandıysa ölçeÄŸi kilitle" name="lock_scale_if_joint_position"/> <text name="pelvis_offset_label"> Z kayması (avatarı kaldırmak veya indirmek için): </text> diff --git a/indra/newview/skins/default/xui/tr/floater_pay.xml b/indra/newview/skins/default/xui/tr/floater_pay.xml index 63334db91097babbbcea9943845747704de608b9..8ed8c895efc4c57cbc40e76bb1bbfe9a5d600123 100644 --- a/indra/newview/skins/default/xui/tr/floater_pay.xml +++ b/indra/newview/skins/default/xui/tr/floater_pay.xml @@ -1,9 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Give Money"> - <string name="payee_group">Gruba Öde</string> - <string name="payee_resident">Sakine Öde</string> - <text name="paying_text">ÖdeyeceÄŸiniz miktar:</text> - <text name="payee_name">Kırpmayı Kontrol İçin Test Adı Çok Uzun</text> + <string name="payee_group"> + Gruba Öde + </string> + <string name="payee_resident"> + Sakine Öde + </string> + <text name="paying_text"> + ÖdeyeceÄŸiniz miktar: + </text> + <text name="payee_name"> + Kırpmayı Kontrol İçin Test Adı Çok Uzun + </text> + <text name="payment_message_label"> + Açıklama (isteÄŸe baÄŸlı): + </text> <panel label="Ara" name="PatternsPanel"> <button label="1 L$ Öde" label_selected="1 L$ Öde" name="fastpay 1"/> <button label="5 L$ Öde" label_selected="5 L$ Öde" name="fastpay 5"/> @@ -11,7 +22,9 @@ <button label="20 L$ Öde" label_selected="20 L$ Öde" name="fastpay 20"/> </panel> <panel label="Ara" name="InputPanel"> - <text name="amount text">DiÄŸer bir tutar:</text> + <text name="amount text"> + DiÄŸer bir tutar: + </text> <button label="Öde" label_selected="Öde" name="pay btn"/> <button label="Ä°ptal" label_selected="Ä°ptal" name="cancel btn"/> </panel> diff --git a/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml index 53938117fde29ca6fb0e5f0bd4d1a7f1f073a689..72c897ad47f87abf86306e74e72829475f982d7b 100644 --- a/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> Avatar </text> - <slider label="Maksimum karmaşıklık:" name="IndirectMaxComplexity" tool_tip="Görsel olarak karmaşık yapıdaki bir avatarın hangi noktada jelibon gibi tek renkli olarak çizileceÄŸini kontrol eder"/> + <slider label="Maksimum karmaşıklık:" name="IndirectMaxComplexity" tool_tip="Görsel olarak karmaşık bir avatarın ne zaman JellyDoll olarak çizileceÄŸini belirler"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/tr/floater_script_queue.xml b/indra/newview/skins/default/xui/tr/floater_script_queue.xml index c1d98b717adefd8c746381415840bbe2f9bd09de..9004ad2e73bd454384347c72b5054d375a7b1078 100644 --- a/indra/newview/skins/default/xui/tr/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/tr/floater_script_queue.xml @@ -15,5 +15,11 @@ <floater.string name="NotRunning"> Çalışmıyor </floater.string> + <floater.string name="Timeout"> + Zaman aşımı: [OBJECT_NAME] + </floater.string> + <floater.string name="LoadingObjInv"> + Åžu öğe için envanter yükleniyor: [OBJECT_NAME] + </floater.string> <button label="Kapat" label_selected="Kapat" name="close"/> </floater> diff --git a/indra/newview/skins/default/xui/tr/floater_web_content.xml b/indra/newview/skins/default/xui/tr/floater_web_content.xml index 93491b80fbec710248553f8a8036e630ae18efcd..dd5f18e2ad2b0c53e71f34d5e3fc204f7ab7fd2c 100644 --- a/indra/newview/skins/default/xui/tr/floater_web_content.xml +++ b/indra/newview/skins/default/xui/tr/floater_web_content.xml @@ -10,5 +10,9 @@ <icon name="media_secure_lock_flag" tool_tip="Güvenli Tarama"/> <button name="popexternal" tool_tip="Mevcut URL'yi masaüstü tarayıcıda aç"/> </layout_panel> + <layout_panel name="debug_controls"> + <button name="web_test_home_page" tool_tip="Web testleri ana sayfası"/> + <button name="VLC Plugin Test" tool_tip="MPEG4 Video Testi"/> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/tr/menu_attachment_other.xml b/indra/newview/skins/default/xui/tr/menu_attachment_other.xml index 8a669a28f7e7ba92b4d2743c56986c0f6be94d86..cef661dbf42672d1f929c3b6ee0cee73b29062e2 100644 --- a/indra/newview/skins/default/xui/tr/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/tr/menu_attachment_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="AÄ°" name="Send IM..."/> <menu_item_call label="Ara" name="Call"/> <menu_item_call label="Gruba Davet Et" name="Invite..."/> + <menu_item_call label="Ä°skeleti Sıfırla" name="Reset Skeleton"/> + <menu_item_call label="Ä°skeleti ve Animasyonları Sıfırla" name="Reset Skeleton And Animations"/> <menu_item_call label="Engelle" name="Avatar Mute"/> <menu_item_call label="Raporla" name="abuse"/> <menu_item_call label="Dondur" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/tr/menu_attachment_self.xml b/indra/newview/skins/default/xui/tr/menu_attachment_self.xml index c49f817a45af21526bd64dab321ae7040d2e4fa5..fd166ddd68ed3455d3272d560e5d451b73a4bfc1 100644 --- a/indra/newview/skins/default/xui/tr/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/tr/menu_attachment_self.xml @@ -9,6 +9,8 @@ <menu_item_call label="Dış Görünümümü Düzenle" name="Edit Outfit"/> <menu_item_call label="Åžeklimi Düzenle" name="Edit My Shape"/> <menu_item_call label="Konum YüksekliÄŸi" name="Hover Height"/> + <menu_item_call label="Ä°skeleti Sıfırla" name="Reset Skeleton"/> + <menu_item_call label="Ä°skeleti ve Animasyonları Sıfırla" name="Reset Skeleton And Animations"/> <menu_item_call label="ArkadaÅŸlarım" name="Friends..."/> <menu_item_call label="Gruplarım" name="Groups..."/> <menu_item_call label="Profilim" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/tr/menu_avatar_other.xml b/indra/newview/skins/default/xui/tr/menu_avatar_other.xml index e4ba3a56167bae34569c6a25b4eb862f67e526f4..87b0d3b7eb3561d7b420d21b235e49bc80e8897f 100644 --- a/indra/newview/skins/default/xui/tr/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/tr/menu_avatar_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="AÄ°" name="Send IM..."/> <menu_item_call label="Ara" name="Call"/> <menu_item_call label="Gruba Davet Et" name="Invite..."/> + <menu_item_call label="Ä°skeleti Sıfırla" name="Reset Skeleton"/> + <menu_item_call label="Ä°skeleti ve Animasyonları Sıfırla" name="Reset Skeleton And Animations"/> <menu_item_call label="Engelle" name="Avatar Mute"/> <menu_item_call label="Raporla" name="abuse"/> <menu_item_call label="Dondur" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/tr/menu_avatar_self.xml b/indra/newview/skins/default/xui/tr/menu_avatar_self.xml index 4dfa42c3470517e7ce23b259af185930f5b3786c..d60d894ed8746f45c5ae50ca368fb18dd707a74a 100644 --- a/indra/newview/skins/default/xui/tr/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/tr/menu_avatar_self.xml @@ -26,6 +26,8 @@ <menu_item_call label="Dış Görünümümü Düzenle" name="Edit Outfit"/> <menu_item_call label="Åžeklimi Düzenle" name="Edit My Shape"/> <menu_item_call label="Konum YüksekliÄŸi" name="Hover Height"/> + <menu_item_call label="Ä°skeleti Sıfırla" name="Reset Skeleton"/> + <menu_item_call label="Ä°skeleti ve Animasyonları Sıfırla" name="Reset Skeleton And Animations"/> <menu_item_call label="ArkadaÅŸlarım" name="Friends..."/> <menu_item_call label="Gruplarım" name="Groups..."/> <menu_item_call label="Profilim" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/tr/menu_login.xml b/indra/newview/skins/default/xui/tr/menu_login.xml index a9406357786850afd13ba48d21220b1ccaeea840..60f81c323784a707738b416d3b265153628c0422 100644 --- a/indra/newview/skins/default/xui/tr/menu_login.xml +++ b/indra/newview/skins/default/xui/tr/menu_login.xml @@ -20,13 +20,12 @@ <menu_item_check label="Hata Ayıklama Menüsünü Göster" name="Show Debug Menu"/> <menu label="Hata ayıkla" name="Debug"> <menu_item_call label="Hata Ayıklama Ayarlarını Göster" name="Debug Settings"/> - <menu_item_call label="KA/Renk Ayarları" name="UI/Color Settings"/> <menu_item_call label="XKA Önizleme Aracı" name="UI Preview Tool"/> <menu label="KA Testleri" name="UI Tests"/> <menu_item_call label="Pencere Büyüklüğünü Ayarla..." name="Set Window Size..."/> <menu_item_call label="Hizmet Åžartlarını Göster" name="TOS"/> <menu_item_call label="Kritik Ä°letiyi Göster" name="Critical"/> - <menu_item_call label="Web İçeriÄŸi Gezdiricisi Hata Ayıklama Testi" name="Web Content Floater Debug Test"/> + <menu_item_call label="Ortam Tarayıcı" name="Media Browser"/> <menu label="Günlük Tutma Seviyesini Seç" name="Set Logging Level"> <menu_item_check label="Hata ayıkla" name="Debug"/> <menu_item_check label="Bilgi" name="Info"/> diff --git a/indra/newview/skins/default/xui/tr/menu_object_icon.xml b/indra/newview/skins/default/xui/tr/menu_object_icon.xml index 3d5c68d9d3df50e0ef1629e1b65f08c28525fcf1..57a44f02eac4b94c9ece90af9118f891a3bbb091 100644 --- a/indra/newview/skins/default/xui/tr/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/tr/menu_object_icon.xml @@ -2,6 +2,7 @@ <menu name="Object Icon Menu"> <menu_item_call label="Nesne Profili..." name="Object Profile"/> <menu_item_call label="Engelle..." name="Block"/> + <menu_item_call label="Engellemeyi Kaldır" name="Unblock"/> <menu_item_call label="Haritada Göster" name="show_on_map"/> <menu_item_call label="Nesne Konumuna Işınla" name="teleport_to_object"/> </menu> diff --git a/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml b/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml index 674041e9c9b03f0c5b790d9666f8ce5f43d4acf8..1b73032a5d3b0f999d52cea805036e2ebe5ceab5 100644 --- a/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml @@ -3,6 +3,10 @@ <menu_item_call label="Giysi - Mevcut Dış Görünümü DeÄŸiÅŸtir" name="wear"/> <menu_item_call label="Giysi - Mevcut Dış Görünüme Ekle" name="wear_add"/> <menu_item_call label="Çıkar - Mevcut Dış Görünümden Kaldır" name="take_off"/> + <menu_item_call label="Karşıya FotoÄŸraf Yükleyin (10 L$)" name="upload_photo"/> + <menu_item_call label="FotoÄŸraf Seçin" name="select_photo"/> + <menu_item_call label="Anlık Görüntü Al" name="take_snapshot"/> + <menu_item_call label="FotoÄŸrafı Kaldır" name="remove_photo"/> <menu label="Yeni Giysiler" name="New Clothes"> <menu_item_call label="Yeni Gömlek" name="New Shirt"/> <menu_item_call label="Yeni Pantolon" name="New Pants"/> @@ -27,4 +31,5 @@ <menu_item_call label="Tüm klasörleri daralt" name="collapse"/> <menu_item_call label="Dış Görünümü Yeniden Adlandır" name="rename"/> <menu_item_call label="Dış Görünümü Sil" name="delete_outfit"/> + <menu_item_check label="Klasörleri Her Zaman Ada Göre Sırala" name="sort_folders_by_name"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/tr/menu_people_friends_view.xml b/indra/newview/skins/default/xui/tr/menu_people_friends_view.xml index 609584d6a60d97f51a09aa38fac97aa3f814d18b..65e5cd2ba6a829e8b09d88566b115e457a10dfdf 100644 --- a/indra/newview/skins/default/xui/tr/menu_people_friends_view.xml +++ b/indra/newview/skins/default/xui/tr/menu_people_friends_view.xml @@ -4,5 +4,6 @@ <menu_item_check label="Duruma Göre Sırala" name="sort_status"/> <menu_item_check label="KiÅŸi Simgelerini Göster" name="view_icons"/> <menu_item_check label="Verilen Ä°zinleri Göster" name="view_permissions"/> + <menu_item_check label="Kullanıcı adlarını gizle" name="view_usernames"/> <menu_item_check label="Sohbet Günlüğünü Göster..." name="view_conversation"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/tr/menu_people_nearby.xml b/indra/newview/skins/default/xui/tr/menu_people_nearby.xml index 2d61461c9193a3a34e7492bcff308f89028b2c8f..d7f61dd2cdbca2e0da1f3fb8b7d6da75afb71c9f 100644 --- a/indra/newview/skins/default/xui/tr/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/tr/menu_people_nearby.xml @@ -13,4 +13,6 @@ <menu_item_call label="PaylaÅŸ" name="share"/> <menu_item_call label="Öde" name="pay"/> <menu_item_check label="Engelle/Engeli Kaldır" name="block_unblock"/> + <menu_item_call label="Dondur" name="freeze"/> + <menu_item_call label="Çıkar" name="eject"/> </context_menu> diff --git a/indra/newview/skins/default/xui/tr/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/tr/menu_people_nearby_view.xml index 59ea7c145f624e32e02db1bbd8b7a5e55a10b317..5c1fe0952443d22ca8673dee5d198b21bd0157fa 100644 --- a/indra/newview/skins/default/xui/tr/menu_people_nearby_view.xml +++ b/indra/newview/skins/default/xui/tr/menu_people_nearby_view.xml @@ -5,4 +5,5 @@ <menu_item_check label="Mesafeye Göre Sırala" name="sort_distance"/> <menu_item_check label="KiÅŸi Simgelerini Göster" name="view_icons"/> <menu_item_check label="Haritayı Göster" name="view_map"/> + <menu_item_check label="Kullanıcı adlarını gizle" name="view_usernames"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/tr/menu_url_objectim.xml b/indra/newview/skins/default/xui/tr/menu_url_objectim.xml index ae6866960576caca03eeb3bf364956add943b773..211ff6dcbfc0600b0d6b8f1fea547d1cec8986ea 100644 --- a/indra/newview/skins/default/xui/tr/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/tr/menu_url_objectim.xml @@ -2,6 +2,7 @@ <context_menu name="Url Popup"> <menu_item_call label="Nesne Profili..." name="show_object"/> <menu_item_call label="Engelle..." name="block_object"/> + <menu_item_call label="Engellemeyi Kaldır" name="unblock_object"/> <menu_item_call label="Haritada Göster" name="show_on_map"/> <menu_item_call label="Nesne Konumuna Işınla" name="teleport_to_object"/> <menu_item_call label="Nesne Adını panoya kopyala" name="url_copy_label"/> diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml index 324e549a757a048fe87ee00a6f67f7649de5affa..f55bb3fbad4ccd715ce5240a2f7ca284f46f5632 100644 --- a/indra/newview/skins/default/xui/tr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="Rahatsız Etme" name="Do Not Disturb"/> </menu> <menu_item_call label="L$ Satın Al..." name="Buy and Sell L$"/> - <menu_item_call label="Satıcı Giden Kutusu..." name="MerchantOutbox"/> <menu_item_call label="Pazaryeri ilanları..." name="MarketplaceListings"/> <menu_item_call label="Hesap kontrol paneli..." name="Manage My Account"/> <menu_item_call label="Tercihler..." name="Preferences"/> @@ -112,11 +111,11 @@ <menu_item_call label="BaÄŸla" name="Link"/> <menu_item_call label="BaÄŸlnty. Kopar" name="Unlink"/> <menu_item_check label="BaÄŸlantılı Parçaları Düzenle" name="Edit Linked Parts"/> - <menu label="BaÄŸlantılı Parçaları Seç" name="Select Linked Parts"> - <menu_item_call label="Sonraki Parçayı Seç" name="Select Next Part"/> - <menu_item_call label="Önceki Parçayı Seç" name="Select Previous Part"/> - <menu_item_call label="Sonraki Parçayı Dahil Et" name="Include Next Part"/> - <menu_item_call label="Önceki Parçayı Dahil Et" name="Include Previous Part"/> + <menu label="Öğeleri Seçin" name="Select Elements"> + <menu_item_call label="Sonraki Parçayı veya Yüzü Seçin" name="Select Next Part or Face"/> + <menu_item_call label="Önceki Parçayı veya Yüzü Seçin" name="Select Previous Part or Face"/> + <menu_item_call label="Sonraki Parçayı veya Yüzü Dahil Et" name="Include Next Part or Face"/> + <menu_item_call label="Önceki Parçayı veya Yüzü Dahil Et" name="Include Previous Part or Face"/> </menu> <menu_item_call label="BaÄŸlantı kümeleri..." name="pathfinding_linkset_menu_item"/> <menu_item_call label="Seçime Odaklan" name="Focus on Selection"/> @@ -367,8 +366,7 @@ <menu_item_call label="Bölge Nesne ÖnbelleÄŸinin Dökümünü Al" name="Dump Region Object Cache"/> </menu> <menu label="KA" name="UI"> - <menu_item_call label="Ortam Tarayıcı Testi" name="Web Browser Test"/> - <menu_item_call label="Web İçerik Tarayıcısı" name="Web Content Browser"/> + <menu_item_call label="Ortam Tarayıcı" name="Media Browser"/> <menu_item_call label="SelectMgr'i Dökümünü Al" name="Dump SelectMgr"/> <menu_item_call label="Envanterin Dökümünü Al" name="Dump Inventory"/> <menu_item_call label="Zamanlayıcıların Dökümünü Al" name="Dump Timers"/> @@ -419,6 +417,7 @@ <menu_item_check label="Ayrıntı Seviyesi Bilgisini Devre Dışı Bırak" name="Disable LOD"/> <menu_item_check label="Debug Character Vis" name="Debug Character Vis"/> <menu_item_check label="Çarpışma Ä°skeletini Göster" name="Show Collision Skeleton"/> + <menu_item_check label="Kemikleri Göster" name="Show Bones"/> <menu_item_check label="Aracı Hedefini Göster" name="Display Agent Target"/> <menu_item_call label="Aksesuarların Dökümünü Al" name="Dump Attachments"/> <menu_item_call label="Avatar Dokuları İçin Hata Ayıklama" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml b/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml index 97965465598eae81cec274e17d29daf2132ccc41..1db95c17e1fdc3698611db8e6e0fcea6046bc4a4 100644 --- a/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml @@ -3,4 +3,6 @@ <menu_item_call label="Çıkar" name="take_off"/> <menu_item_call label="Ayır" name="detach"/> <menu_item_call label="Dış Görünümü Düzenle" name="edit"/> + <menu_item_call label="Düzenle" name="edit_item"/> + <menu_item_call label="Orijinali Göster" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/tr/mime_types.xml b/indra/newview/skins/default/xui/tr/mime_types.xml index fa554d34fc70233804f9a2375ac91657dfbc1abb..5b13b0059af9be70565e7c2caa770f8178e0a064 100644 --- a/indra/newview/skins/default/xui/tr/mime_types.xml +++ b/indra/newview/skins/default/xui/tr/mime_types.xml @@ -57,6 +57,11 @@ Gerçek Zamanlı Akış </label> </scheme> + <scheme name="libvlc"> + <label name="libvlc_label"> + LibVLC destekli ortam + </label> + </scheme> <mimetype name="blank"> <label name="blank_label"> - Hiçbiri - @@ -202,6 +207,11 @@ Film (MP4) </label> </mimetype> + <mimetype name="application/octet-stream"> + <label name="video/octet-stream"> + Film + </label> + </mimetype> <mimetype name="video/quicktime"> <label name="video/quicktime_label"> Film (QuickTime) diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml index a982dc03ed29aec39d20bd18bb74800a77bec0a9..0f222d49cc45f69fc1ec4ca9d3a1f56fb563501f 100644 --- a/indra/newview/skins/default/xui/tr/notifications.xml +++ b/indra/newview/skins/default/xui/tr/notifications.xml @@ -330,6 +330,9 @@ Bu yeteneklerin artık bu rolde bulunmasını istemiyorsanız, onları hemen dev [COUNT] üyeyi grubun yasaklı listesine eklemek üzeresiniz. <usetemplate ignoretext="Gruptan birden çok üyenin yasaklanmasını doÄŸrulayın" name="okcancelignore" notext="Ä°ptal" yestext="Yasakla"/> </notification> + <notification name="GroupBanUserOnBanlist"> + Bazı sakinlere, gruptan çıkartıldıkları için davetiye gönderilmedi. + </notification> <notification name="AttachmentDrop"> Aksesuarınızı çıkarmak üzeresiniz. Devam etmek istediÄŸinize emin misiniz? @@ -457,6 +460,12 @@ Ortamı sadece bir yüze yerleÅŸtirmek için, Yüz Seç'i seçin ve ardınd <notification name="ErrorEncodingSnapshot"> Anlık görüntü kodlanırken hata oluÅŸtu. </notification> + <notification name="ErrorPhotoCannotAfford"> + Envanterinize bir fotoÄŸraf kaydedebilmek için [COST] L$ paraya ihtiyacınız var. L$ satın alabilir veya bunun yerine fotoÄŸrafı bilgisayarınıza kaydedebilirsiniz. + </notification> + <notification name="ErrorTextureCannotAfford"> + Envanterinize bir doku kaydedebilmek için [COST] L$ paraya ihtiyacınız var. L$ satın alabilir veya bunun yerine fotoÄŸrafı bilgisayarınıza kaydedebilirsiniz. + </notification> <notification name="ErrorUploadingPostcard"> AÅŸağıdaki nedenden dolayı, anlık görüntü gönderilirken bir sorun oluÅŸtu: [REASON] </notification> @@ -480,6 +489,9 @@ Dış görünüm klasöründe hiç giysi, vücut bölümü ya da aksesuar yok. <notification name="CannotWearInfoNotComplete"> Bu öğe henüz yüklenmediÄŸi için kullanamazsınız. Lütfen bir dakika sonra tekrar deneyin. </notification> + <notification name="MustEnterPasswordToLogIn"> + Oturum açmak için lütfen parolanızı girin. + </notification> <notification name="MustHaveAccountToLogIn"> Hata! BoÅŸ bırakılan alan(lar) var. Avatarınızın Kullanıcı adını girmeniz gerekmektedir. @@ -548,6 +560,9 @@ Not: Bu iÅŸlem önbelleÄŸi temizleyecek. <notification name="ChangeConnectionPort"> Port ayarları, [APP_NAME] uygulamasını yeniden baÅŸlattıktan sonra geçerli olur. </notification> + <notification name="ChangeDeferredDebugSetting"> + Bu hata ayıklama ayarı deÄŸiÅŸikliÄŸi [APP_NAME] uygulamasını yeniden baÅŸlattıktan sonra geçerli olacak. + </notification> <notification name="ChangeSkin"> Yeni dış katman [APP_NAME] uygulamasını yeniden baÅŸlattıktan sonra görüntülenecek. </notification> @@ -569,6 +584,10 @@ Not: Bu iÅŸlem önbelleÄŸi temizleyecek. Not kartı silinsin mi? <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> </notification> + <notification name="LoadPreviousReportScreenshot"> + Raporunuz için önceki anlık görüntüyü kullanmak ister misiniz? + <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> + </notification> <notification name="GestureSaveFailedTooManySteps"> Mimik kaydedilemedi. Bu mimikte çok fazla adım var. @@ -629,30 +648,12 @@ Daha fazla bilgi için [_URL] adresini ziyaret etmek ister misiniz? </url> <usetemplate ignoretext="Bilgisayar donanımım desteklenmiyor" name="okcancelignore" notext="Hayır" yestext="Evet"/> </notification> - <notification name="IntelOldDriver"> - Grafik yonganız için muhtemelen daha yeni bir sürücü mevcut. Grafik sürücüleri güncellemek performansınızı kayda deÄŸer ÅŸekilde artırabilir. - - Sürücü güncellemeleri için [_URL] adresini ziyaret etmek ister misiniz? - <url name="url"> - http://www.intel.com/p/en_US/support/detect/graphics - </url> - <usetemplate ignoretext="Grafik sürücüm güncel deÄŸil" name="okcancelignore" notext="Hayır" yestext="Evet"/> - </notification> - <notification name="AMDOldDriver"> - Grafik yonganız için muhtemelen daha yeni bir sürücü mevcut. Grafik sürücüleri güncellemek performansınızı kayda deÄŸer ÅŸekilde artırabilir. - - Sürücü güncellemeleri için [_URL] adresini ziyaret etmek ister misiniz? - <url name="url"> - http://support.amd.com/us/Pages/AMDSupportHub.aspx - </url> - <usetemplate ignoretext="Grafik sürücüm güncel deÄŸil" name="okcancelignore" notext="Hayır" yestext="Evet"/> - </notification> - <notification name="NVIDIAOldDriver"> + <notification name="OldGPUDriver"> Grafik yonganız için muhtemelen daha yeni bir sürücü mevcut. Grafik sürücüleri güncellemek performansınızı kayda deÄŸer ÅŸekilde artırabilir. - Sürücü güncellemeleri için [_URL] adresini ziyaret etmek ister misiniz? + Sürücü güncellemesi olup olmadığına bakmak için [URL] adresini ziyaret etmek ister misiniz? <url name="url"> - http://www.nvidia.com/Download/index.aspx?lang=en-us + [URL] </url> <usetemplate ignoretext="Grafik sürücüm güncel deÄŸil" name="okcancelignore" notext="Hayır" yestext="Evet"/> </notification> @@ -743,6 +744,9 @@ L$ satın alma ile ilgili bilgi edinmek için [_URL] adresine gidilsin mi? </url> <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> </notification> + <notification name="MuteLimitReached"> + [MUTE_LIMIT] giriÅŸ limitine ulaÅŸtığınız için, engelleme listesine yeni giriÅŸ eklenemiyor. + </notification> <notification name="UnableToLinkObjects"> Bu [COUNT] nesne birbirine baÄŸlanamıyor. En fazla [MAX] nesneyi birbirine baÄŸlayabilirsiniz. @@ -1366,12 +1370,18 @@ Yeni bir ana konum ayarlamak isteyebilirsiniz. <ignore name="ignore" text="Giysilerin karşıdan yüklenmesi uzun zaman alıyor"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Görsel karmaşıklık] seviyeniz: [AGENT_COMPLEXITY]. + <notification name="AgentComplexityWithVisibility"> + [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] düzeyiniz [AGENT_COMPLEXITY]. [OVERLIMIT_MSG] + <usetemplate ignoretext="Avatarımın karmaşıklık düzeyi çok yüksekse beni uyar" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 Görsel karmaşıklık] seviyeniz: [AGENT_COMPLEXITY]. + [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] düzeyiniz [AGENT_COMPLEXITY]. + <usetemplate ignoretext="Avatar karmaşıklık seviyem deÄŸiÅŸince beni uyar" name="notifyignore"/> + </notification> + <notification name="HUDComplexityWarning"> + [HUD_REASON], büyük olasılıkla performansınızı olumsuz etkiliyor. + <usetemplate ignoretext="BÃœG karmaşıklık seviyem çok yükselince beni uyar" name="notifyignore"/> </notification> <notification name="FirstRun"> [APP_NAME] yüklemesi tamamlandı. @@ -1463,6 +1473,10 @@ Lütfen sadece bir nesne seçin ve tekrar deneyin. Bu bölgedeki tüm Sakinler ana konumlarına ışınlansın mı? <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> </notification> + <notification name="ChangeObjectBonusFactor"> + Bir bölgede binalar inÅŸa edildikten sonra nesne bonusunun azaltılması nesnelerin iade edilmesine veya silinmesine neden olabilir. Nesne bonusunu deÄŸiÅŸtirmek istediÄŸinize emin misiniz? + <usetemplate ignoretext="Nesne bonusu faktörünü deÄŸiÅŸtirmeyi doÄŸrulayın" name="okcancelignore" notext="Ä°ptal" yestext="Tamam"/> + </notification> <notification name="EstateObjectReturn"> [USER_NAME] kullanıcısının sahip olduÄŸu tüm nesneleri iade etmek istediÄŸinize emin misiniz? <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> @@ -1486,6 +1500,10 @@ Lütfen sadece bir nesne seçin ve tekrar deneyin. Geçerli yüzeyi bu ÅŸekilde kaydetmeyi, yüzey yükseltme/alçaltma sınırları için merkez olarak kullanmayı ve 'Geri Çevir' aracı için varsayılan olarak ayarlamayı gerçekten istiyor musunuz? <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> </notification> + <notification name="ConfirmTextureHeights"> + Yükselti Ayarları için girdiÄŸiniz düşük deÄŸer, yüksek deÄŸerden daha fazla. Devam edilsin mi? + <usetemplate canceltext="Tekrar Sorma" name="yesnocancelbuttons" notext="Ä°ptal Et" yestext="Tamam"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> Sadece [MAX_AGENTS] tane Ä°zin Verilen Sakin belirleyebilirsiniz. </notification> @@ -1506,6 +1524,9 @@ Lütfen sadece bir nesne seçin ve tekrar deneyin. <notification name="OwnerCanNotBeDenied"> Gayrimenkul sahibi, gayrimenkulün 'Yasaklı Sakin' listesine eklenemez. </notification> + <notification name="ProblemAddingEstateManagerBanned"> + EngellenmiÅŸ sakin, gayrimenkul yöneticisi listesine eklenemez. + </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> Giysi ve ÅŸekil yüklenene kadar görünüm deÄŸiÅŸtirilemez. </notification> @@ -1680,6 +1701,10 @@ En yeni özellikleri ve düzeltmeleri görmek için sabırsızlanıyorsanız Alt Bu içeriÄŸi görüntülemek için Web tarayıcınızı açmak istiyor musunuz? <usetemplate ignoretext="Bir web sayfasını görüntülemek için tarayıcımı baÅŸlat" name="okcancelignore" notext="Ä°ptal" yestext="Tamam"/> </notification> + <notification name="SystemUIScaleFactorChanged"> + Sistem kullanıcı arayüzü faktörü son çalıştırmadan bu yana deÄŸiÅŸti. Kullanıcı arayüzü büyüklük deÄŸiÅŸtirme ayarları sayfasını açmak istiyor musunuz? + <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> + </notification> <notification name="WebLaunchJoinNow"> Hesabınızı yönetmek için [http://secondlife.com/account/ Kontrol Paneli] adresine gidilsin mi? <usetemplate ignoretext="Hesabımı yönetmek için tarayıcımı baÅŸlat" name="okcancelignore" notext="Ä°ptal" yestext="Tamam"/> @@ -1719,16 +1744,15 @@ En yeni özellikleri ve düzeltmeleri görmek için sabırsızlanıyorsanız Alt Gruptan ayrılmak istiyor musunuz? <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> </notification> + <notification name="GroupDepart"> + "[group_name]" grubundan ayrıldınız. + </notification> <notification name="OwnerCannotLeaveGroup"> Gruptan ayrılınamıyor. Gruptan ayrılamazsınız çünkü grubun son sahibisiniz. Lütfen önce sahip rolüne baÅŸka bir üye atayın. <usetemplate name="okbutton" yestext="Tamam"/> </notification> <notification name="GroupDepartError"> - Gruptan ayrılma iÅŸlemi yapılamıyor: [reason]. - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> - <notification name="GroupDepart"> - [group_name] grubundan ayrıldınız. + Gruptan ayrılınamıyor. <usetemplate name="okbutton" yestext="Tamam"/> </notification> <notification name="ConfirmKick"> @@ -2128,6 +2152,10 @@ Binlerce bölgeyi deÄŸiÅŸtirecek ve alan sunucusunu kesintiye uÄŸratacaktır. Çok fazla prim seçilmiÅŸ. Lütfen [MAX_PRIM_COUNT] ya da daha az prim seçin ve tekrar deneyin <usetemplate name="okbutton" yestext="Tamam"/> </notification> + <notification name="TooManyScriptsSelected"> + Seçili nesnelerde çok fazla komut dosyası var. Lütfen daha az nesne seçip tekrar deneyin + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> <notification name="ProblemImportingEstateCovenant"> Gayrimenkul sözleÅŸmesi içeriye aktarılırken problem oluÅŸtu. <usetemplate name="okbutton" yestext="Tamam"/> @@ -2295,6 +2323,10 @@ Envanter öğesi/öğeleri taşınsın mı? Ödeme baÅŸarısız: nesne bulunamadı. <usetemplate name="okbutton" yestext="Tamam"/> </notification> + <notification name="PaymentBlockedButtonMismatch"> + Ödeme durduruldu: Ödenen fiyat, bu nesne için belirtilen ödeme düğmelerinden hiçbiriyle eÅŸleÅŸmiyor + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> <notification name="OpenObjectCannotCopy"> Bu nesne içinde kopyalama izniniz olan bir öğe yok. </notification> @@ -2330,6 +2362,11 @@ Bu eylemi geri alamazsınız. Bu, geniÅŸ bir baÄŸlantı kümeleri seçimi. BaÄŸlantıyı kaldırırsanız tekrar baÄŸlayamayabilirsiniz. Tedbiren, envanterinizdeki baÄŸlantı kümelerinin bir kopyasını almayı isteyebilirsiniz. <usetemplate ignoretext="Bir baÄŸlantı kümesinin bağının kaldırılmasını onayla" name="okcancelignore" notext="Ä°ptal" yestext="BaÄŸlantıyı Kopar"/> </notification> + <notification name="HelpReportAbuseConfirm"> + Bu konuyu bize bildirmek için zaman ayırdığınız için teÅŸekkür ederiz. +Raporunuzda olası ihlalleri inceleyip gerekli önlemleri alacağız. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> <notification name="HelpReportAbuseSelectCategory"> Lütfen bu kötüye kullanım bildirimi için bir kategori seçin. Kategori seçimi, kötüye kullanım bildirimlerini dosyalamamıza ve iÅŸleme almamıza yardımcı olmaktadır. @@ -2400,6 +2437,10 @@ Bu iÅŸlemi tamamlamadan önce Rahatsız Etme'yi kapatmak ister misiniz? Çöp kutunuzun içeriÄŸini kalıcı olarak silmek istediÄŸinize emin misiniz? <usetemplate ignoretext="Envanter Çöp Kutusu klasörünü boÅŸaltmadan önce doÄŸrulama iste" name="okcancelignore" notext="Ä°ptal" yestext="Tamam"/> </notification> + <notification name="TrashIsFull"> + Çöpte yer kalmamış. Bu durum oturum açma sırasında sorun yaÅŸamanıza neden olabilir. + <usetemplate name="okcancelbuttons" notext="Çöpü daha sonra boÅŸaltacağım" yestext="Çöp kutusunu ÅŸimdi boÅŸalt"/> + </notification> <notification name="ConfirmClearBrowserCache"> Seyahat, web ve arama geçmiÅŸinizi silmek istediÄŸinize emin misiniz? <usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/> @@ -2755,6 +2796,10 @@ Burada uçamazsınız. <notification name="PathfindingDirty"> Bu bölgede bekleyen yol bulma deÄŸiÅŸiklikleri var. EÄŸer oluÅŸturma haklarına sahipseniz, “Bölgeyi yeniden kaydet†düğmesine tıklayarak bölgeyi yeniden kaydedebilirsiniz. </notification> + <notification name="PathfindingDirtyRebake"> + Bu bölgede bekleyen yol bulma deÄŸiÅŸiklikleri var. EÄŸer oluÅŸturma haklarına sahipseniz, “Bölgeyi yeniden kaydet†düğmesine tıklayarak bölgeyi yeniden kaydedebilirsiniz. + <usetemplate name="okbutton" yestext="Bölgeyi yeniden kaydet"/> + </notification> <notification name="DynamicPathfindingDisabled"> Bu bölgede dinamik yol bulma etkin deÄŸil. Yol bulma LSL çaÄŸrılarını kullanan komut dosyalı nesneler, bu bölgede beklendiiÄŸi gibi çalışmayabilir. </notification> @@ -2984,7 +3029,7 @@ Bu bölgede kalmaya devam ederseniz oturumunuz sonlandırılacak. Bu bölgede kalmaya devam ederseniz oturumunuz sonlandırılacak. </notification> <notification name="LoadWebPage"> - [URL] web sayfası yüklensin mi? + Bu web sayfası yüklensin mi: [URL] ? [MESSAGE] @@ -3257,11 +3302,17 @@ GüvenliÄŸiniz için birkaç saniye engellenecek. <notification name="AttachmentSaved"> Aksesuar kaydedildi. </notification> + <notification name="AppearanceToXMLSaved"> + Görünüm XML olarak [PATH] konumuna kaydedildi + </notification> + <notification name="AppearanceToXMLFailed"> + Görünüm XML'e kaydedilemedi. + </notification> <notification name="PresetNotSaved"> - [NAME] ön ayarı kaydedilirken hata oluÅŸtu. + Ön ayar ([NAME]) kaydedilirken hata oluÅŸtu. </notification> <notification name="PresetNotDeleted"> - [NAME] ön ayarı silinirken hata oluÅŸtu. + Ön ayar ([NAME]) silinirken hata oluÅŸtu. </notification> <notification name="UnableToFindHelpTopic"> Bu öğe için yardım baÅŸlığı bulunamıyor. @@ -3471,13 +3522,6 @@ Görünümünüzü döndürmek için dünya üzerindeki herhangi bir yeri tıkla <notification name="ForceQuitDueToLowMemory"> Yetersiz bellek nedeniyle SL 30 saniye içerisinde kapanacak. </notification> - <notification name="PopupAttempt"> - Açılır bir pencerenin açılması engellendi. - <form name="form"> - <ignore name="ignore" text="Tüm açılır pencerelere izin ver"/> - <button name="open" text="Açılır pencereyi aç"/> - </form> - </notification> <notification name="SOCKS_NOT_PERMITTED"> SOCKS 5 proxy'si "[HOST]:[PORT]" baÄŸlantıyı reddetti; kural kümesi izin vermiyor. <usetemplate name="okbutton" yestext="Tamam"/> @@ -3848,6 +3892,9 @@ Lütfen bir dakika sonra tekrar deneyin. <notification name="CantMoveObjectParcelResources"> [REGION_NAME] bölgesinde '[OBJECT_NAME]' nesnesi [OBJ_POSITION] konumuna hareket ettirilemiyor, çünkü bu parselde bu nesne için yeterli kaynak yok. </notification> + <notification name="NoParcelPermsNoObject"> + Bu parsele eriÅŸiminiz olmadığı için kopyalama iÅŸlemi yapılamadı. + </notification> <notification name="CantMoveObjectRegionVersion"> [REGION_NAME] bölgesinde '[OBJECT_NAME]' nesnesi [OBJ_POSITION] konumuna hareket ettirilemiyor çünkü bölgede çalıştırılan eski versiyon, bölge deÄŸiÅŸtirme üzerinden bu nesnenin alınmasını desteklemiyor. </notification> @@ -3860,6 +3907,10 @@ Lütfen bir dakika sonra tekrar deneyin. <notification name="NoPermModifyObject"> Bu nesneyi deÄŸiÅŸtirme izniniz yok </notification> + <notification name="TooMuchObjectInventorySelected"> + Büyük envanterli çok fazla nesne seçildi. Lütfen daha az nesne seçip tekrar deneyin. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> <notification name="CantEnablePhysObjContributesToNav"> Navmesh'e katkıda bulunan bir nesne için fizik etkinleÅŸtirilemez. </notification> @@ -3896,6 +3947,12 @@ Lütfen bir dakika sonra tekrar deneyin. <notification name="CantSaveModifyAttachment"> Nesne içeriklerine kaydedilemedi: Bu, aksesuar izinlerini deÄŸiÅŸtirmeyi gerektirirdi. </notification> + <notification name="AttachmentHasTooMuchInventory"> + Aksesuarlarınızda çok fazla envanter olduÄŸu için daha fazlası eklenemiyor. + </notification> + <notification name="IllegalAttachment"> + Aksesuar avatarda var olmayan bir noktaya karşılık geliyor. Bunun yerine göğüs kısmına eklendi. + </notification> <notification name="TooManyScripts"> Çok fazla komut dosyası. </notification> @@ -3988,6 +4045,12 @@ Lütfen bir dakika sonra tekrar deneyin. <notification name="TeleportedByObjectUnknownUser"> Bilinmeyen bir sahibi olan '[OBJECT_NAME]' nesnesi tarafından ışınlandınız. </notification> + <notification name="StandDeniedByObject"> + "[OBJECT_NAME]" ÅŸu anda durmanıza izin vermeyecek. + </notification> + <notification name="ResitDeniedByObject"> + "[OBJECT_NAME]" ÅŸu anda koltuÄŸunuzu deÄŸiÅŸtirmenize izin vermeyecek. + </notification> <notification name="CantCreateObjectRegionFull"> Talep edilen nesne oluÅŸturulamıyor. Bölge dolu. </notification> @@ -4284,6 +4347,9 @@ Daha küçük bir arazi parçası seçmeyi deneyin. <notification name="CantTransfterMoneyRegionDisabled"> Nesnelere para transferleri bölgede ÅŸu anda devre dışı bırakılmış durumda. </notification> + <notification name="DroppedMoneyTransferRequest"> + Sistem yüklemesi nedeniyle, ödeme yapılamıyor. + </notification> <notification name="CantPayNoAgent"> Kime ödeme yapılacağı belirlenemedi. </notification> @@ -4319,4 +4385,8 @@ Daha küçük bir arazi parçası seçmeyi deneyin. Sohbet geçmiÅŸi dosyası önceki iÅŸlemi gerçekleÅŸtirmekle meÅŸgul. Lütfen bir kaç dakika sonra tekrar deneyin veya baÅŸka bir kiÅŸiyle sohbet etmeyi deneyin. <usetemplate name="okbutton" yestext="Tamam"/> </notification> + <notification name="OutfitPhotoLoadError"> + [REASON] + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/tr/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/tr/panel_outfits_inventory.xml index 550f7ebf10588897a47a724c818c44f77cdde497..c7d3d0dfed4a969541d9cdae52b0fa55457e6cbd 100644 --- a/indra/newview/skins/default/xui/tr/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/tr/panel_outfits_inventory.xml @@ -7,6 +7,7 @@ Seçilen öğeleri giy </panel.string> <tab_container name="appearance_tabs"> + <panel label="DIÅž GÖRÃœNÃœM GALERÄ°SÄ°" name="outfit_gallery_tab"/> <panel label="DIÅž GÖRÃœNÃœMLERÄ°M" name="outfitslist_tab"/> <panel label="GÄ°YÄ°LEN" name="cof_tab"/> </tab_container> diff --git a/indra/newview/skins/default/xui/tr/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/tr/panel_outfits_wearing.xml index 462926738f68c3c6cc3c1466e17a6638b8805026..e5a6d83166dc58bafa530a6f27f83380d81893a7 100644 --- a/indra/newview/skins/default/xui/tr/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/tr/panel_outfits_wearing.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Wearing"> + <panel.string name="no_attachments"> + Giyilen aksesuar yok. + </panel.string> + <accordion name="wearables_accordion"> + <accordion_tab name="tab_wearables" title="Giyilebilir Öğeler"/> + <accordion_tab name="tab_temp_attachments" title="Geçici aksesuarlar"/> + </accordion> <panel name="bottom_panel"> <menu_button name="options_gear_btn" tool_tip="Ä°lave seçenekleri göster"/> </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml index 46a4793c5314592d305a1d98b94dbd0fc57a4337..b0f026b285a3c00980f5e5e4e54ad6ee0d157321 100644 --- a/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> Bana söyle: </text> - <check_box label="L$ harcadığımda veya aldığımda" name="notify_money_change_checkbox"/> + <check_box label="L$ harcadığımda" name="notify_money_spend_checkbox"/> <check_box label="ArkadaÅŸlarım oturum açtığında veya kapattığında" name="friends_online_notify_checkbox"/> + <check_box label="L$ aldığımda" name="notify_money_received_checkbox"/> <text name="show_label"> Daima göster: </text> diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml index 13984c2792d804dde8b6498bc210a24202af86fa..235a90a2450eb4e17a9a6b1876c1878314a6a5c3 100644 --- a/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> Daha iyi </text> + <slider label="Avatarın Maksimum Karmaşıklığı:" name="IndirectMaxComplexity" tool_tip="Görsel olarak karmaşık bir avatarın ne zaman JellyDoll olarak çizileceÄŸini belirler"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="Atmosferik gölgeleyiciler" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="GeliÅŸmiÅŸ Aydınlatma Modeli" name="UseLightShaders"/> <button label="Ayarları ön ayar olarak kaydet..." name="PrefSaveButton"/> <button label="Ön ayarı yükle..." name="PrefLoadButton"/> + min_val="0,125" <button label="Ön ayarı sil..." name="PrefDeleteButton"/> <button label="Önerilen ayarlara dön" name="Defaults"/> <button label="GeliÅŸmiÅŸ Ayarlar..." name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml b/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml index 8f74c8ef7e75484ab7dcdc53c341b0add1925790..39a7ce99737b5db836de619c5eaf13d1b43e4960 100644 --- a/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml @@ -30,6 +30,7 @@ <combo_box.item label="Güncellemeleri manuel olarak indirip yükleyeceÄŸim" name="Install_manual"/> </combo_box> <check_box label="Sürüm adaylarına güncelleme yapmaya gönüllü" name="update_willing_to_test"/> + <check_box label="Güncellemeden sonra Sürüm Notlarını göster" name="update_show_release_notes"/> <text name="Proxy Settings:"> Proxy Ayarları: </text> diff --git a/indra/newview/skins/default/xui/tr/panel_sound_devices.xml b/indra/newview/skins/default/xui/tr/panel_sound_devices.xml index 982ef2ea3bf28e08b1d14c948e0ce10bfb027f77..be3299b89c342677aae63802efe8dc6f0acaf520 100644 --- a/indra/newview/skins/default/xui/tr/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/tr/panel_sound_devices.xml @@ -16,9 +16,9 @@ Çıktı </text> <text name="My volume label"> - Ses düzeyim: + Mik. ses düzeyi: </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Bu kaydırıcıyı kullanarak ses düzeyini deÄŸiÅŸtirin"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Bu kaydırma butonunu kullanarak mikrofonun ses düzeyini deÄŸiÅŸtirin"/> <text name="wait_text"> Lütfen bekleyin </text> diff --git a/indra/newview/skins/default/xui/tr/panel_status_bar.xml b/indra/newview/skins/default/xui/tr/panel_status_bar.xml index 9e2669ec2b38280e3a07523fdf14f2c2b35c3a5e..7c7bfc7e144061af06e7c33ae4013898bd5dea2c 100644 --- a/indra/newview/skins/default/xui/tr/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/tr/panel_status_bar.xml @@ -5,7 +5,7 @@ <panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string> <panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string> <panel.string name="buycurrencylabel">L$ [AMT]</panel.string> - <panel left="-425" name="balance_bg" width="215"> + <panel left="-446" name="balance_bg" width="215"> <text name="balance" tool_tip="L$ bakiyenizi yenilemek için buraya tıklayın" value="L$??"/> <button label="L$ Satın Al" name="buyL" tool_tip="Daha fazla L$ satın almak için tıklayın"/> <button label="AlışveriÅŸ yap" name="goShop" tool_tip="Second Life Pazaryeri Aç" width="95"/> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index 67c91979077000c144bdf046e796b288f005c63d..7b4bf1fca6344bd7163f5fbccb5da036f322611d 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -39,7 +39,10 @@ </string> <string name="AboutHeader"> [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) -[[VIEWER_RELEASE_NOTES_URL] [Sürüm Notları]] +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + Yapı Konfigürasyonu [BUILD_CONFIG] </string> <string name="AboutPosition"> <nolink>[HOSTNAME]</nolink> ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] konumundasınız @@ -58,20 +61,40 @@ Grafik Kartı: [GRAPHICS_CARD] <string name="AboutDriver"> Windows Grafik Sürücüsü Sürümü: [GRAPHICS_DRIVER_VERSION] </string> - <string name="AboutLibs"> + <string name="AboutOGL"> OpenGL Sürümü: [OPENGL_VERSION] - -J2C Kod Çözücü Sürümü: [J2C_VERSION] + </string> + <string name="AboutSettings"> + Pencere büyüklüğü: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Font Büyüklüğü Ayarı: [FONT_SIZE_ADJUSTMENT] pt +Kullanıcı Arayüzü Ölçekleme: [UI_SCALE] +Çizme mesafesi: [DRAW_DISTANCE] m +Bant geniÅŸliÄŸi: [NET_BANDWITH] kbit/sn +Ayrıntı seviyesi faktörü: [LOD_FACTOR] +Ä°ÅŸleme kalitesi: [RENDER_QUALITY] / 7 +GeliÅŸmiÅŸ Aydınlatma Modeli: [GPU_SHADERS] +Doku belleÄŸi: [TEXTURE_MEMORY]MB +VFS (önbellek) oluÅŸturma zamanı: [VFS_TIME] + </string> + <string name="AboutLibs"> + J2C Kod Çözücü Sürümü: [J2C_VERSION] Ses Sürücüsü Sürümü: [AUDIO_DRIVER_VERSION] LLCEFLib/CEF Sürümü: [LLCEFLIB_VERSION] +LibVLC Sürümü: [LIBVLC_VERSION] Ses Sunucusu Sürümü: [VOICE_VERSION] </string> <string name="AboutTraffic"> Kaybolan Paketler: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> <string name="ErrorFetchingServerReleaseNotesURL"> Sunucu sürümü notları URL'si alınırken hata oluÅŸtu. </string> + <string name="BuildConfiguration"> + Yapı Konfigürasyonu + </string> <string name="ProgressRestoring"> Geri yükleniyor... </string> @@ -1080,6 +1103,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="TeleportYourAgent"> Sizi ışınlama </string> + <string name="ForceSitAvatar"> + Avatarınızı oturmaya zorlayın + </string> <string name="NotConnected"> BaÄŸlı DeÄŸil </string> @@ -1387,6 +1413,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="BodyPartsRightLeg"> SaÄŸ Bacak </string> + <string name="BodyPartsEnhancedSkeleton"> + GeliÅŸmiÅŸ Ä°skelet + </string> <string name="GraphicsQualityLow"> Düşük </string> @@ -1835,6 +1864,51 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="Avatar Center"> Avatar Merkezi </string> + <string name="Left Ring Finger"> + Sol Yüzük Parmağı + </string> + <string name="Right Ring Finger"> + SaÄŸ Yüzük Parmağı + </string> + <string name="Tail Base"> + Kuyruk Tabanı + </string> + <string name="Tail Tip"> + Kuyruk Ucu + </string> + <string name="Left Wing"> + Sol Kanat + </string> + <string name="Right Wing"> + SaÄŸ Kanat + </string> + <string name="Jaw"> + Pençe + </string> + <string name="Alt Left Ear"> + Altrntf Sol Kulak + </string> + <string name="Alt Right Ear"> + Altrntf SaÄŸ Kulak + </string> + <string name="Alt Left Eye"> + Altrntf Sol Göz + </string> + <string name="Alt Right Eye"> + Altrntf SaÄŸ Göz + </string> + <string name="Tongue"> + Dil + </string> + <string name="Groin"> + Kasık + </string> + <string name="Left Hind Foot"> + Sol Arka Ayak + </string> + <string name="Right Hind Foot"> + SaÄŸ Arka Ayak + </string> <string name="Invalid Attachment"> Geçersiz Aksesuar Noktası </string> @@ -1880,6 +1954,27 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="av_render_anyone"> Çevrenizdeki kimse sizi iÅŸleyemeyebilir. </string> + <string name="hud_description_total"> + BÃœG'niz + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] ([JNT_NAME] üzerinde) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] yüksek miktarda doku belleÄŸi kullanıyor + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] çok sayıda pahalı nesne ve doku içeriyor + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] çok sayıda büyük doku içeriyor + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] çok fazla nesne içeriyor + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] çok fazla doku içeriyor + </string> <string name="AgeYearsA"> [COUNT] yıl </string> @@ -2039,6 +2134,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="ObjectOutOfRange"> Komut dosyası (nesne kapsam dışı) </string> + <string name="ScriptWasDeleted"> + Komut Dosyası (envanterden silindi) + </string> <string name="GodToolsObjectOwnedBy"> [OWNER] mülkiyetindeki [OBJECT] nesnesi </string> @@ -2224,12 +2322,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="ATTACH_BELLY"> Göbek </string> - <string name="ATTACH_RPEC"> - SaÄŸ Göğüs - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> Sol Göğüs </string> + <string name="ATTACH_RIGHT_PEC"> + SaÄŸ Göğüs + </string> <string name="ATTACH_HUD_CENTER_2"> BÃœG 2. Merkez </string> @@ -2260,6 +2358,51 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="ATTACH_AVATAR_CENTER"> Avatar Merkezi </string> + <string name="ATTACH_LHAND_RING1"> + Sol Yüzük Parmağı + </string> + <string name="ATTACH_RHAND_RING1"> + SaÄŸ Yüzük Parmağı + </string> + <string name="ATTACH_TAIL_BASE"> + Kuyruk Tabanı + </string> + <string name="ATTACH_TAIL_TIP"> + Kuyruk Ucu + </string> + <string name="ATTACH_LWING"> + Sol Kanat + </string> + <string name="ATTACH_RWING"> + SaÄŸ Kanat + </string> + <string name="ATTACH_FACE_JAW"> + Pençe + </string> + <string name="ATTACH_FACE_LEAR"> + Altrntf Sol Kulak + </string> + <string name="ATTACH_FACE_REAR"> + Altrntf SaÄŸ Kulak + </string> + <string name="ATTACH_FACE_LEYE"> + Altrntf Sol Göz + </string> + <string name="ATTACH_FACE_REYE"> + Altrntf SaÄŸ Göz + </string> + <string name="ATTACH_FACE_TONGUE"> + Dil + </string> + <string name="ATTACH_GROIN"> + Kasık + </string> + <string name="ATTACH_HIND_LFOOT"> + Sol Arka Ayak + </string> + <string name="ATTACH_HIND_RFOOT"> + SaÄŸ Arka Ayak + </string> <string name="CursorPos"> Satır [LINE], Sütun [COLUMN] </string> @@ -2606,6 +2749,15 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="Play Media"> Ortamı Oynat/Durdur </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=en-us + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> <string name="MBCmdLineError"> Komut satırı ayrıştırılırken bir hata oluÅŸtu. Lütfen bakınız: http://wiki.secondlife.com/wiki/Client_parameters @@ -4249,6 +4401,12 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne baÅŸvurun. <string name="OfflineStatus"> Çevrimdışı </string> + <string name="not_online_msg"> + Kullanıcı çevrimiçi deÄŸil - mesaj saklanıp daha sonra iletilecek. + </string> + <string name="not_online_inventory"> + Kullanıcı çevrimiçi deÄŸil - envanter kaydedildi. + </string> <string name="answered_call"> Aramanız yanıtlandı </string> @@ -4375,12 +4533,18 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne baÅŸvurun. <string name="paid_you_ldollars"> [NAME] size [REASON] L$[AMOUNT] ödedi. </string> + <string name="paid_you_ldollars_gift"> + [NAME] size [AMOUNT] L$ ödedi: [REASON] + </string> <string name="paid_you_ldollars_no_reason"> [NAME] size L$[AMOUNT] ödedi. </string> <string name="you_paid_ldollars"> [NAME]'e [REASON] L$[AMOUNT] ödediniz. </string> + <string name="you_paid_ldollars_gift"> + [NAME] adlı kullanıcıya [AMOUNT] L$ ödediniz. [REASON] + </string> <string name="you_paid_ldollars_no_info"> L$[AMOUNT] ödediniz. </string> @@ -4393,6 +4557,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne baÅŸvurun. <string name="you_paid_failure_ldollars"> [REASON] [NAME]'e L$[AMOUNT] ödeyemediniz. </string> + <string name="you_paid_failure_ldollars_gift"> + [NAME] adlı kullanıcıya [AMOUNT] L$ ödeyemediniz. [REASON] + </string> <string name="you_paid_failure_ldollars_no_info"> L$[AMOUNT] ödeyemediniz. </string> @@ -4717,6 +4884,15 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne baÅŸvurun. <string name="texture_load_dimensions_error"> [WIDTH]*[HEIGHT] çözünürlüğünden büyük görüntüler yüklenemez </string> + <string name="outfit_photo_load_dimensions_error"> + Maksimum dış görünüm fotoÄŸrafı büyüklüğü: [WIDTH]*[HEIGHT]. Lütfen büyüklüğü deÄŸiÅŸtirin veya baÅŸka bir görüntü kullanın + </string> + <string name="outfit_photo_select_dimensions_error"> + Maksimum dış görünüm fotoÄŸrafı büyüklüğü: [WIDTH]*[HEIGHT]. Lütfen baÅŸka bir doku seçin + </string> + <string name="outfit_photo_verify_dimensions_error"> + FotoÄŸraf boyutları doÄŸrulanamıyor. FotoÄŸraf boyutu seçicide görüntülenene kadar lütfen bekleyin + </string> <string name="words_separator" value=","/> <string name="server_is_down"> Tüm çabalarımıza raÄŸmen beklenmeyen bir hata meydana geldi. @@ -5233,6 +5409,9 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin. <string name="Command_Profile_Label"> Profil </string> + <string name="Command_Report_Abuse_Label"> + Kötüye Kullanımı Bildir + </string> <string name="Command_Search_Label"> Ara </string> @@ -5323,6 +5502,9 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin. <string name="Command_Profile_Tooltip"> Profilinizi düzenleyin veya görüntüleyin </string> + <string name="Command_Report_Abuse_Tooltip"> + Kötüye Kullanımı Bildir + </string> <string name="Command_Search_Tooltip"> Yerler, etkinlikler ve kiÅŸiler bulmak </string> diff --git a/indra/newview/skins/default/xui/zh/floater_model_preview.xml b/indra/newview/skins/default/xui/zh/floater_model_preview.xml index 817b1af88dc998c85f5e822e62f3b257a71a123a..4223b76d909b2a5139ab1cad456118396ba5025d 100644 --- a/indra/newview/skins/default/xui/zh/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/zh/floater_model_preview.xml @@ -245,6 +245,7 @@ </text> <check_box label="包å«è¡¨çš®é‡é‡" name="upload_skin"/> <check_box label="包å«æŽ¥é»žä½ç½®" name="upload_joints"/> + <check_box label="若接點ä½ç½®å·²å®šç¾©ï¼Œå°±éŽ–ä½æ¯”例" name="lock_scale_if_joint_position"/> <text name="pelvis_offset_label"> Z åè·ï¼ˆå‡é«˜æˆ–é™ä½ŽåŒ–身): </text> diff --git a/indra/newview/skins/default/xui/zh/floater_pay.xml b/indra/newview/skins/default/xui/zh/floater_pay.xml index 026ead957438c8087d41d88fc93145306c801aba..5eb0fe5362d6a9c3478b229560d9e5322d2c5914 100644 --- a/indra/newview/skins/default/xui/zh/floater_pay.xml +++ b/indra/newview/skins/default/xui/zh/floater_pay.xml @@ -1,9 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Give Money"> - <string name="payee_group">支付群組</string> - <string name="payee_resident">支付居民</string> - <text name="paying_text">ä½ æ£åœ¨æ”¯ä»˜ï¼š</text> - <text name="payee_name">測試一個長度éžå¸¸éžå¸¸éžå¸¸é•·çš„å稱,檢查是å¦è¢«åˆ‡æ–·</text> + <string name="payee_group"> + 支付群組 + </string> + <string name="payee_resident"> + 支付居民 + </string> + <text name="paying_text"> + ä½ æ£åœ¨æ”¯ä»˜ï¼š + </text> + <text name="payee_name"> + 測試一個長度éžå¸¸éžå¸¸éžå¸¸é•·çš„å稱,檢查是å¦è¢«åˆ‡æ–· + </text> + <text name="payment_message_label"> + 說明(å¯ç•™ç©ºï¼‰ï¼š + </text> <panel label="æœå°‹" name="PatternsPanel"> <button label="支付 L$ 1" label_selected="支付 L$ 1" name="fastpay 1"/> <button label="支付 L$ 5" label_selected="支付 L$ 5" name="fastpay 5"/> @@ -11,7 +22,9 @@ <button label="支付 L$ 20" label_selected="支付 L$ 20" name="fastpay 20"/> </panel> <panel label="æœå°‹" name="InputPanel"> - <text name="amount text">其他金é¡ï¼š</text> + <text name="amount text"> + 其他金é¡ï¼š + </text> <button label="支付" label_selected="支付" name="pay btn"/> <button label="å–消" label_selected="å–消" name="cancel btn"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml index f9c2fe47e7d86590b63cdd7c7c3b5effef891888..bbc16dd7e520acc738f1b18f5fa38924a964c813 100644 --- a/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml @@ -15,7 +15,7 @@ <text name="AvatarText"> 化身 </text> - <slider label="最大複雜度:" name="IndirectMaxComplexity" tool_tip="控制在何時機下讓複雜化身呈åƒç‚ºã€Œå–®è‰²è»Ÿç³–娃娃ã€"/> + <slider label="最大複雜度:" name="IndirectMaxComplexity" tool_tip="控制在何時機下讓複雜化身呈åƒç‚ºã€ŒJellyDollã€"/> <text name="IndirectMaxComplexityText"> 0 </text> diff --git a/indra/newview/skins/default/xui/zh/floater_script_queue.xml b/indra/newview/skins/default/xui/zh/floater_script_queue.xml index 7c253aa74c50debbbca9c19976909bb4a3ccc690..22af0dc5859d15ba4c1da6e995118508021a0583 100644 --- a/indra/newview/skins/default/xui/zh/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/zh/floater_script_queue.xml @@ -15,5 +15,11 @@ <floater.string name="NotRunning"> éžåŸ·è¡Œä¸ </floater.string> + <floater.string name="Timeout"> + 逾時:[OBJECT_NAME] + </floater.string> + <floater.string name="LoadingObjInv"> + æ£è¼‰å…¥ä»¥ä¸‹ç‰©é …的收ç´å€ï¼š[OBJECT_NAME] + </floater.string> <button label="關閉" label_selected="關閉" name="close"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_web_content.xml b/indra/newview/skins/default/xui/zh/floater_web_content.xml index be6bf8bb2764b8bb7014df3cc6149c16bee34126..5b7bcd99162ee9919d34ede4143cf3c1354f08df 100644 --- a/indra/newview/skins/default/xui/zh/floater_web_content.xml +++ b/indra/newview/skins/default/xui/zh/floater_web_content.xml @@ -10,5 +10,9 @@ <icon name="media_secure_lock_flag" tool_tip="åŠ å¯†çš„ç€è¦½"/> <button name="popexternal" tool_tip="åœ¨ä½ çš„æ¡Œé¢ç€è¦½å™¨ä¸é–‹å•Ÿç›®å‰çš„ URL ä½å€"/> </layout_panel> + <layout_panel name="debug_controls"> + <button name="web_test_home_page" tool_tip="網路測試主é "/> + <button name="VLC Plugin Test" tool_tip="MPEG4影片測試"/> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_other.xml b/indra/newview/skins/default/xui/zh/menu_attachment_other.xml index ace1302250d19bb8f0ba6a3a16098a61951a4c12..f104caeeafd8824a1c863b29ad06cc2f4e5df9b9 100644 --- a/indra/newview/skins/default/xui/zh/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/zh/menu_attachment_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="通話" name="Call"/> <menu_item_call label="é‚€è«‹åŠ å…¥ç¾¤çµ„" name="Invite..."/> + <menu_item_call label="é‡è¨éª¨æž¶" name="Reset Skeleton"/> + <menu_item_call label="é‡è¨éª¨æž¶å’Œå‹•ä½œ" name="Reset Skeleton And Animations"/> <menu_item_call label="å°éŽ–" name="Avatar Mute"/> <menu_item_call label="å›žå ±" name="abuse"/> <menu_item_call label="å‡çµ" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml index d9e6eff897a2842fbc3996434162849f3888f55a..040ec94aad3a43c830d37bc063d21676157a968a 100644 --- a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml @@ -9,6 +9,8 @@ <menu_item_call label="編輯我的è£æ‰®" name="Edit Outfit"/> <menu_item_call label="編輯我的體形" name="Edit My Shape"/> <menu_item_call label="懸浮高度" name="Hover Height"/> + <menu_item_call label="é‡è¨éª¨æž¶" name="Reset Skeleton"/> + <menu_item_call label="é‡è¨éª¨æž¶å’Œå‹•ä½œ" name="Reset Skeleton And Animations"/> <menu_item_call label="我的朋å‹" name="Friends..."/> <menu_item_call label="我的群組" name="Groups..."/> <menu_item_call label="我的個人檔案" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml index 0e0d1cc3d2c31dc0ffd63cdd5e01e7e653904af2..2e9ef8bcf1a78e5a4677ee2db8d713d7a8498532 100644 --- a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml @@ -6,6 +6,8 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="通話" name="Call"/> <menu_item_call label="é‚€è«‹åŠ å…¥ç¾¤çµ„" name="Invite..."/> + <menu_item_call label="é‡è¨éª¨æž¶" name="Reset Skeleton"/> + <menu_item_call label="é‡è¨éª¨æž¶å’Œå‹•ä½œ" name="Reset Skeleton And Animations"/> <menu_item_call label="å°éŽ–" name="Avatar Mute"/> <menu_item_call label="å›žå ±" name="abuse"/> <menu_item_call label="å‡çµ" name="Freeze..."/> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml index a644a45df6888d16b481f4b9b9261b0d489b29eb..bad17a11b8ba6b6ca611821520067098d5ba10dd 100644 --- a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml @@ -26,6 +26,8 @@ <menu_item_call label="編輯我的è£æ‰®" name="Edit Outfit"/> <menu_item_call label="編輯我的體形" name="Edit My Shape"/> <menu_item_call label="懸浮高度" name="Hover Height"/> + <menu_item_call label="é‡è¨éª¨æž¶" name="Reset Skeleton"/> + <menu_item_call label="é‡è¨éª¨æž¶å’Œå‹•ä½œ" name="Reset Skeleton And Animations"/> <menu_item_call label="我的朋å‹" name="Friends..."/> <menu_item_call label="我的群組" name="Groups..."/> <menu_item_call label="我的個人檔案" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/zh/menu_login.xml b/indra/newview/skins/default/xui/zh/menu_login.xml index 7ef9240e830946eb250e5a8e9f33d15d2f35686b..8dd89db7bace26c94717bdf0d2df5f909a7e79b8 100644 --- a/indra/newview/skins/default/xui/zh/menu_login.xml +++ b/indra/newview/skins/default/xui/zh/menu_login.xml @@ -20,13 +20,12 @@ <menu_item_check label="顯示除錯é¸å–®" name="Show Debug Menu"/> <menu label="除錯" name="Debug"> <menu_item_call label="顯示除錯è¨å®š" name="Debug Settings"/> - <menu_item_call label="UI / é¡è‰² è¨å®š" name="UI/Color Settings"/> <menu_item_call label="XUI é 覽工具" name="UI Preview Tool"/> <menu label="UI 測試" name="UI Tests"/> <menu_item_call label="è¨å®šè¦–窗大å°..." name="Set Window Size..."/> <menu_item_call label="顯示 TOS" name="TOS"/> <menu_item_call label="顯示嚴é‡è¨Šæ¯" name="Critical"/> - <menu_item_call label="網é 內容浮動視窗除錯測試" name="Web Content Floater Debug Test"/> + <menu_item_call label="媒體ç€è¦½å™¨" name="Media Browser"/> <menu label="è¨å®šè¨˜éŒ„細節" name="Set Logging Level"> <menu_item_check label="除錯" name="Debug"/> <menu_item_check label="資訊" name="Info"/> diff --git a/indra/newview/skins/default/xui/zh/menu_object_icon.xml b/indra/newview/skins/default/xui/zh/menu_object_icon.xml index 9655732f2e06449069361605ec4a54dda30fb860..d0a3457ae86fb2fe68475616a066ff07969587d7 100644 --- a/indra/newview/skins/default/xui/zh/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/zh/menu_object_icon.xml @@ -2,6 +2,7 @@ <menu name="Object Icon Menu"> <menu_item_call label="物件檔案..." name="Object Profile"/> <menu_item_call label="å°éŽ–…" name="Block"/> + <menu_item_call label="解除å°éŽ–" name="Unblock"/> <menu_item_call label="顯示在地圖上" name="show_on_map"/> <menu_item_call label="瞬間傳é€åˆ°ç‰©ä»¶ä½ç½®" name="teleport_to_object"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml index 258d0d6b20e934f324c74c89caaab856132e8ad3..124598a09828cf61af89b0837867561f0d8da156 100644 --- a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml @@ -3,6 +3,10 @@ <menu_item_call label="穿上 ï¼ å–代目å‰è£æ‰®" name="wear"/> <menu_item_call label="穿上 ï¼ æ·»åŠ åˆ°ç›®å‰è£æ‰®" name="wear_add"/> <menu_item_call label="脫下 ï¼ ç”±ç›®å‰è£æ‰®ç§»é™¤" name="take_off"/> + <menu_item_call label="上傳相片(L$10)" name="upload_photo"/> + <menu_item_call label="é¸æ“‡ç›¸ç‰‡" name="select_photo"/> + <menu_item_call label="æ‹æ”å¿«ç…§" name="take_snapshot"/> + <menu_item_call label="移除相片" name="remove_photo"/> <menu label="æ–°è¡£æœ" name="New Clothes"> <menu_item_call label="新襯衫" name="New Shirt"/> <menu_item_call label="新褲å" name="New Pants"/> @@ -27,4 +31,5 @@ <menu_item_call label="摺疊全部資料夾" name="collapse"/> <menu_item_call label="è£æ‰®æ›´å" name="rename"/> <menu_item_call label="刪除è£æ‰®" name="delete_outfit"/> + <menu_item_check label="總是由å稱排åºè³‡æ–™å¤¾" name="sort_folders_by_name"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_friends_view.xml b/indra/newview/skins/default/xui/zh/menu_people_friends_view.xml index 4251238fd95f8791449a97f688addffca95a5a53..9e27520d3682573f6bc3965cc6ccec3f8a157cd5 100644 --- a/indra/newview/skins/default/xui/zh/menu_people_friends_view.xml +++ b/indra/newview/skins/default/xui/zh/menu_people_friends_view.xml @@ -4,5 +4,6 @@ <menu_item_check label="ä¾ç‹€æ…‹æŽ’åº" name="sort_status"/> <menu_item_check label="察看人群圖示" name="view_icons"/> <menu_item_check label="察看許å¯æ¬Šé™" name="view_permissions"/> + <menu_item_check label="éš±è—使用者å稱" name="view_usernames"/> <menu_item_check label="檢視交談記錄……" name="view_conversation"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml index d25adaf8fb5cb673ab405b7272e09a823bd299ec..4ad755c02832260a52e989bb4e7b89c24fd3f1b9 100644 --- a/indra/newview/skins/default/xui/zh/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml @@ -13,4 +13,6 @@ <menu_item_call label="分享" name="share"/> <menu_item_call label="支付" name="pay"/> <menu_item_check label="å°éŽ–/ä¸å†å°éŽ–" name="block_unblock"/> + <menu_item_call label="å‡çµ" name="freeze"/> + <menu_item_call label="踢出" name="eject"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby_view.xml index 9bc56384726b26454c0fca498263cadcbb2c655a..9c82e204976f3b12ad51019a20ee730db8a18792 100644 --- a/indra/newview/skins/default/xui/zh/menu_people_nearby_view.xml +++ b/indra/newview/skins/default/xui/zh/menu_people_nearby_view.xml @@ -5,4 +5,5 @@ <menu_item_check label="ä¾è·é›¢æŽ’åº" name="sort_distance"/> <menu_item_check label="察看人群圖示" name="view_icons"/> <menu_item_check label="察看地圖" name="view_map"/> + <menu_item_check label="éš±è—使用者å稱" name="view_usernames"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_objectim.xml b/indra/newview/skins/default/xui/zh/menu_url_objectim.xml index ac366f92efcfbe62c056f64434f28d1a5068323e..c830e5554b453be4a9e71a0ce9e8c89d4bdc641b 100644 --- a/indra/newview/skins/default/xui/zh/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/zh/menu_url_objectim.xml @@ -2,6 +2,7 @@ <context_menu name="Url Popup"> <menu_item_call label="物件檔案..." name="show_object"/> <menu_item_call label="å°éŽ–…" name="block_object"/> + <menu_item_call label="解除å°éŽ–" name="unblock_object"/> <menu_item_call label="顯示在地圖上" name="show_on_map"/> <menu_item_call label="瞬間傳é€åˆ°ç‰©ä»¶ä½ç½®" name="teleport_to_object"/> <menu_item_call label="覆製物件å稱到剪貼簿" name="url_copy_label"/> diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml index 41590d60c70e8cf000977baec747e1cff4f319ae..38686460503a2e2576ac34a0dc2c085beeb68f51 100644 --- a/indra/newview/skins/default/xui/zh/menu_viewer.xml +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -22,7 +22,6 @@ <menu_item_check label="請勿打擾" name="Do Not Disturb"/> </menu> <menu_item_call label="購買 L$…" name="Buy and Sell L$"/> - <menu_item_call label="商家發件匣…" name="MerchantOutbox"/> <menu_item_call label="Marketplace 刊登…" name="MarketplaceListings"/> <menu_item_call label="帳戶主控臺…" name="Manage My Account"/> <menu_item_call label="å好è¨å®šâ€¦" name="Preferences"/> @@ -112,11 +111,11 @@ <menu_item_call label="è¯çµ" name="Link"/> <menu_item_call label="å–消è¯çµ" name="Unlink"/> <menu_item_check label="編輯è¯çµéƒ¨ä½" name="Edit Linked Parts"/> - <menu label="é¸æ“‡è¯çµéƒ¨ä½" name="Select Linked Parts"> - <menu_item_call label="é¸æ“‡ä¸‹ä¸€éƒ¨ä½" name="Select Next Part"/> - <menu_item_call label="é¸æ“‡ä¸Šä¸€éƒ¨ä½" name="Select Previous Part"/> - <menu_item_call label="包括下一部ä½" name="Include Next Part"/> - <menu_item_call label="包括上一部ä½" name="Include Previous Part"/> + <menu label="é¸æ“‡å…ƒç´ " name="Select Elements"> + <menu_item_call label="é¸æ“‡ä¸‹ä¸€éƒ¨ä½æˆ–臉" name="Select Next Part or Face"/> + <menu_item_call label="é¸æ“‡ä¸Šä¸€éƒ¨ä½æˆ–臉" name="Select Previous Part or Face"/> + <menu_item_call label="包括下一部ä½æˆ–臉" name="Include Next Part or Face"/> + <menu_item_call label="包括上一部ä½æˆ–臉" name="Include Previous Part or Face"/> </menu> <menu_item_call label="è¯çµé›†â€¦" name="pathfinding_linkset_menu_item"/> <menu_item_call label="èšç„¦æ–¼æ‰€é¸éƒ¨ä½" name="Focus on Selection"/> @@ -367,8 +366,7 @@ <menu_item_call label="傾å°åœ°å€ç‰©ä»¶å¿«å–" name="Dump Region Object Cache"/> </menu> <menu label="使用者界é¢" name="UI"> - <menu_item_call label="媒體ç€è¦½å™¨æ¸¬è©¦" name="Web Browser Test"/> - <menu_item_call label="網é 內容ç€è¦½å™¨" name="Web Content Browser"/> + <menu_item_call label="媒體ç€è¦½å™¨" name="Media Browser"/> <menu_item_call label="å‚¾å° SelectMgr" name="Dump SelectMgr"/> <menu_item_call label="傾å°æ”¶ç´å€" name="Dump Inventory"/> <menu_item_call label="傾å°ç¢¼éŒ¶" name="Dump Timers"/> @@ -419,6 +417,7 @@ <menu_item_check label="åœç”¨ç´°ç¯€å±¤æ¬¡" name="Disable LOD"/> <menu_item_check label="除錯å—å…ƒå¯è¦‹æ€§" name="Debug Character Vis"/> <menu_item_check label="顯示碰撞骨架" name="Show Collision Skeleton"/> + <menu_item_check label="顯示骨é " name="Show Bones"/> <menu_item_check label="顯示用戶目標" name="Display Agent Target"/> <menu_item_call label="傾å°é™„件" name="Dump Attachments"/> <menu_item_call label="除錯化身æ質" name="Debug Avatar Textures"/> diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml b/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml index c7d2853995f76ef8f446748cdf44a0fe19e3e297..dc9adcbd25fb49435ca669d433be5ce149cc1d16 100644 --- a/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml @@ -3,4 +3,6 @@ <menu_item_call label="脫下" name="take_off"/> <menu_item_call label="å¸ä¸‹" name="detach"/> <menu_item_call label="編輯è£æ‰®" name="edit"/> + <menu_item_call label="編輯" name="edit_item"/> + <menu_item_call label="顯示原件" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/mime_types.xml b/indra/newview/skins/default/xui/zh/mime_types.xml index 8967475abb2de890b96b147661250ae6f7c302e8..f4b68227784b10bc3892bdc6a4e96d3bdf82db6d 100644 --- a/indra/newview/skins/default/xui/zh/mime_types.xml +++ b/indra/newview/skins/default/xui/zh/mime_types.xml @@ -57,6 +57,11 @@ å³æ™‚ä¸²æµ </label> </scheme> + <scheme name="libvlc"> + <label name="libvlc_label"> + LibVLC支æŒçš„媒體 + </label> + </scheme> <mimetype name="blank"> <label name="blank_label"> - ç„¡ - @@ -202,6 +207,11 @@ è¦–é »ï¼ˆMP4) </label> </mimetype> + <mimetype name="application/octet-stream"> + <label name="video/octet-stream"> + 影片 + </label> + </mimetype> <mimetype name="video/quicktime"> <label name="video/quicktime_label"> è¦–é »ï¼ˆQuickTime) diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml index 3f08496a6826984d56d809869a7f4bb6bfdc4f8f..5c794afd65fcf89d5f075c5ef4e2989c56d03844 100644 --- a/indra/newview/skins/default/xui/zh/notifications.xml +++ b/indra/newview/skins/default/xui/zh/notifications.xml @@ -330,6 +330,9 @@ ä½ å³å°‡ç¦æ¢[COUNT]個人留在群組。 <usetemplate ignoretext="確定è¦ç¦æ¢å¤šåæˆå“¡çºŒç•™æ¤ç¾¤çµ„" name="okcancelignore" notext="å–消" yestext="ç¦æ¢"/> </notification> + <notification name="GroupBanUserOnBanlist"> + æœ‰äº›å±…æ°‘å› ç‚ºè¢«å°éŽ–所以沒有收到邀請。 + </notification> <notification name="AttachmentDrop"> ä½ å³å°‡å¸é™¤ä½ 的附件。 ä½ ç¢ºå®šä½ è¦ç¹¼çºŒï¼Ÿ @@ -457,6 +460,12 @@ <notification name="ErrorEncodingSnapshot"> 為快照編碼時出錯。 </notification> + <notification name="ErrorPhotoCannotAfford"> + ä½ éœ€è¦L$[COST]æ‰èƒ½æŠŠç…§ç‰‡å˜å…¥ä½ 的收ç´å€ã€‚ ä½ å¯ä»¥è³¼è²·L$,或者ä¸å˜å…¥æ”¶ç´å€ï¼Œè€ŒæŠŠç›¸ç‰‡å˜åˆ°ä½ 的電腦。 + </notification> + <notification name="ErrorTextureCannotAfford"> + ä½ éœ€è¦L$[COST]æ‰èƒ½æŠŠæ質å˜å…¥ä½ 的收ç´å€ã€‚ ä½ å¯ä»¥è³¼è²·L$,或者ä¸å˜å…¥æ”¶ç´å€ï¼Œè€ŒæŠŠç›¸ç‰‡å˜åˆ°ä½ 的電腦。 + </notification> <notification name="ErrorUploadingPostcard"> 發é€å¿«ç…§æ™‚出å•é¡Œï¼ŒåŽŸå› :[REASON] </notification> @@ -480,6 +489,9 @@ <notification name="CannotWearInfoNotComplete"> 無法穿戴該物件,它尚未完æˆè¼‰å…¥ã€‚ è«‹ç¨å€™å†è©¦ã€‚ </notification> + <notification name="MustEnterPasswordToLogIn"> + 請輸入密碼以便登入。 + </notification> <notification name="MustHaveAccountToLogIn"> ç³Ÿç³•ï¼ ç™¼ç¾æœ‰å…§å®¹ç•™ç™½ã€‚ ä½ å¿…é ˆç‚ºåŒ–èº«è¼¸å…¥ä¸€å€‹ä½¿ç”¨è€…å稱。 @@ -548,6 +560,9 @@ <notification name="ChangeConnectionPort"> é‡æ–°å•Ÿå‹• [APP_NAME] å¾Œå°‡å•Ÿç”¨æ–°çš„åŸ è¨å®šã€‚ </notification> + <notification name="ChangeDeferredDebugSetting"> + 這個除錯è¨å®šå°‡åœ¨é‡æ–°å•Ÿå‹• [APP_NAME] 後啟用。 + </notification> <notification name="ChangeSkin"> é‡æ–°å•Ÿå‹• [APP_NAME] 後將顯ç¾æ–°çš„皮膚。 </notification> @@ -569,6 +584,10 @@ 刪除記事å¡ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> </notification> + <notification name="LoadPreviousReportScreenshot"> + ä½ è¦ä½¿ç”¨ä¹‹å‰çš„èž¢å¹•æˆªåœ–ä¾†èˆ‰å ±å—Žï¼Ÿ + <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> + </notification> <notification name="GestureSaveFailedTooManySteps"> 姿勢儲å˜å¤±æ•—。 這個姿勢æ¥é©Ÿå¤ªå¤šã€‚ @@ -629,32 +648,14 @@ </url> <usetemplate ignoretext="我的電腦硬體並ä¸æ”¯æ´" name="okcancelignore" notext="å¦" yestext="是"/> </notification> - <notification name="IntelOldDriver"> + <notification name="OldGPUDriver"> ä½ çš„é¡¯ç¤ºå¡å¾ˆå¯èƒ½æœ‰æ–°ç‰ˆçš„驅動程å¼ã€‚ 更新顯示驅動程å¼æœƒå¤§å¹…改善性能。 - å‰å¾€ [_URL] 察看是å¦æœ‰æ–°ç‰ˆé©…動程å¼ï¼Ÿ + å‰å¾€[URL]察看是å¦æœ‰æ–°ç‰ˆé©…動程å¼ï¼Ÿ <url name="url"> - http://www.intel.com/p/en_US/support/detect/graphics + [URL] </url> - <usetemplate ignoretext="我的顯示驅動程å¼å¤ªè€èˆŠ" name="okcancelignore" notext="å¦" yestext="是"/> - </notification> - <notification name="AMDOldDriver"> - ä½ çš„é¡¯ç¤ºå¡å¾ˆå¯èƒ½æœ‰æ–°ç‰ˆçš„驅動程å¼ã€‚ 更新顯示驅動程å¼æœƒå¤§å¹…改善性能。 - - å‰å¾€ [_URL] 察看是å¦æœ‰æ–°ç‰ˆé©…動程å¼ï¼Ÿ - <url name="url"> - http://support.amd.com/us/Pages/AMDSupportHub.aspx - </url> - <usetemplate ignoretext="我的顯示驅動程å¼å¤ªè€èˆŠ" name="okcancelignore" notext="å¦" yestext="是"/> - </notification> - <notification name="NVIDIAOldDriver"> - ä½ çš„é¡¯ç¤ºå¡å¾ˆå¯èƒ½æœ‰æ–°ç‰ˆçš„驅動程å¼ã€‚ 更新顯示驅動程å¼æœƒå¤§å¹…改善性能。 - - å‰å¾€ [_URL] 察看是å¦æœ‰æ–°ç‰ˆé©…動程å¼ï¼Ÿ - <url name="url"> - http://www.nvidia.com/Download/index.aspx?lang=tw - </url> - <usetemplate ignoretext="我的顯示驅動程å¼å¤ªè€èˆŠ" name="okcancelignore" notext="å¦" yestext="是"/> + <usetemplate ignoretext="我的顯示驅動程å¼å¤ªè€èˆŠ" name="okcancelignore" notext="å–消" yestext="是"/> </notification> <notification name="UnknownGPU"> ä½ çš„ç³»çµ±å«æœ‰ä¸€å€‹ [APP_NAME] 無法辨èªçš„顯åƒå¡ã€‚ @@ -743,6 +744,9 @@ </url> <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> </notification> + <notification name="MuteLimitReached"> + å°éŽ–清單åé¡ç„¡æ³•å¢žåŠ ï¼Œå› ç‚ºä½ å·²é”[MUTE_LIMIT]å的上é™ã€‚ + </notification> <notification name="UnableToLinkObjects"> 無法è¯çµé€™ [COUNT] 個物件。 ä½ æœ€å¤šå¯ä»¥è¯çµ [MAX] 個物件。 @@ -1359,12 +1363,18 @@ <ignore name="ignore" text="æœè£èŠ±å¤ªå¤šæ™‚間下載"/> </form> </notification> - <notification name="RegionAndAgentComplexity"> - ä½ çš„[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 視覺複雜度]是[AGENT_COMPLEXITY]。 + <notification name="AgentComplexityWithVisibility"> + ä½ çš„[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 化身複雜度]是[AGENT_COMPLEXITY]。 [OVERLIMIT_MSG] + <usetemplate ignoretext="è¦å‘Šæˆ‘化身的複雜度是å¦å¯èƒ½éŽé«˜" name="notifyignore"/> </notification> <notification name="AgentComplexity"> - ä½ çš„[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 視覺複雜度]是[AGENT_COMPLEXITY]。 + ä½ çš„[https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 化身複雜度]是[AGENT_COMPLEXITY]。 + <usetemplate ignoretext="發出è¦å‘Šï¼Œå‘ŠçŸ¥æˆ‘化身複雜度有了改變" name="notifyignore"/> + </notification> + <notification name="HUDComplexityWarning"> + [HUD_REASON],å¯èƒ½è² é¢å½±éŸ¿ä½ 的性能。 + <usetemplate ignoretext="è¦å‘Šæˆ‘HUD的複雜度是å¦å¯èƒ½éŽé«˜" name="notifyignore"/> </notification> <notification name="FirstRun"> [APP_NAME] 安è£å®Œæˆã€‚ @@ -1456,6 +1466,10 @@ SHA1 指紋:[MD5_DIGEST] 確定è¦å¼·åˆ¶çž¬é–“傳é€é€™åœ°å€æ‰€æœ‰å±…民回家? <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> </notification> + <notification name="ChangeObjectBonusFactor"> + 在地å€å…§å®Œæˆå»ºè£½å¾Œå†é™ä½Žç‰©ä»¶è² è·å€æ•¸ï¼Œå¯èƒ½å°Žè‡´ç‰©ä»¶è¢«é€è¿”或刪除。 繼續è¦è®Šæ›´ç‰©ä»¶è² è·å€æ•¸ï¼Ÿ + <usetemplate ignoretext="ç¢ºå®šè®Šæ›´ç‰©ä»¶è² è·å€æ•¸" name="okcancelignore" notext="å–消" yestext="確定"/> + </notification> <notification name="EstateObjectReturn"> ä½ ç¢ºå®šè¦é€è¿” [USER_NAME] 所æ“有的物件? <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> @@ -1479,6 +1493,10 @@ SHA1 指紋:[MD5_DIGEST] ä½ çœŸçš„è¦ç¢ºå®šç”¢å‡ºç›®å‰åœ°å½¢ï¼Œä½¿å…¶æˆç‚ºåœ°å½¢å‡/é™æ¥µé™çš„ä¸é–“值,並è¨ç‚ºã€Œå¾©åŽŸã€å·¥å…·çš„é è¨å€¼ï¼Ÿ <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> </notification> + <notification name="ConfirmTextureHeights"> + ä½ è¨çš„海拔範åœå€¼ï¼Œä½Žå€¼å¤§æ–¼é«˜å€¼ã€‚  繼續? + <usetemplate canceltext="ä¸è¦å•" name="yesnocancelbuttons" notext="å–消" yestext="確定"/> + </notification> <notification name="MaxAllowedAgentOnRegion"> ä½ æœ€å¤šåªèƒ½æœ‰ [MAX_AGENTS] ä½å…許居民。 </notification> @@ -1499,6 +1517,9 @@ SHA1 指紋:[MD5_DIGEST] <notification name="OwnerCanNotBeDenied"> ç„¡æ³•æ·»åŠ é ˜åœ°æ‰€æœ‰äººåˆ°é ˜åœ°çš„ '被å°éŽ–çš„å±…æ°‘' åå–®ä¸ã€‚ </notification> + <notification name="ProblemAddingEstateManagerBanned"> + 無法把被å°éŽ–çš„å±…æ°‘åŠ å…¥é ˜åœ°çš„ç®¡ç†äººå單。 + </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> 無法變更外觀,直到æœè£èˆ‡é«”形下載完畢。 </notification> @@ -1670,6 +1691,10 @@ SHA1 指紋:[MD5_DIGEST] ä½ ç¢ºå®šè¦é–‹å•Ÿç¶²é ç€è¦½å™¨åŽ»å¯Ÿçœ‹é€™å€‹å…§å®¹ï¼Ÿ <usetemplate ignoretext="啟動我的網é ç€è¦½å™¨åŽ»å¯Ÿçœ‹ç¶²é " name="okcancelignore" notext="å–消" yestext="確定"/> </notification> + <notification name="SystemUIScaleFactorChanged"> + 系統使用者介é¢çš„尺寸å€æ•¸è‡ªå¾žä¸Šæ¬¡åŸ·è¡Œå¾Œå·²ç¶“改變。 ä½ æƒ³è¦é–‹å•Ÿä½¿ç”¨è€…介é¢å°ºå¯¸èª¿æ•´çš„è¨å®šé 嗎? + <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> + </notification> <notification name="WebLaunchJoinNow"> å‰å¾€ä½ çš„[http://secondlife.com/account/ 塗鴉牆]以進行管ç†ä½ 的帳戶? <usetemplate ignoretext="啟動我的ç€è¦½å™¨ä»¥ç®¡ç†æˆ‘的帳戶" name="okcancelignore" notext="å–消" yestext="確定"/> @@ -1709,16 +1734,15 @@ SHA1 指紋:[MD5_DIGEST] 是å¦è¦é›¢é–‹ç¾¤çµ„? <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> </notification> + <notification name="GroupDepart"> + ä½ å·²ç¶“é›¢é–‹ã€Œ[group_name]ã€ç¾¤çµ„。 + </notification> <notification name="OwnerCannotLeaveGroup"> 無法離開群組。 ä½ æ˜¯æ¤ç¾¤çµ„僅å˜çš„所有人,ä¸å¾—離開群組。 請先把所有人è·éŠœæŒ‡æ´¾çµ¦å¦ä¸€äººã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="GroupDepartError"> - 無法離開群組:[reason]。 - <usetemplate name="okbutton" yestext="確定"/> - </notification> - <notification name="GroupDepart"> - ä½ å·²ç¶“é›¢é–‹[group_name]群組。 + 無法離開群組。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="ConfirmKick"> @@ -2118,6 +2142,10 @@ SHA1 指紋:[MD5_DIGEST] é¸æ“‡äº†å¤ªå¤šé …的幾何元件。 請至多é¸æ“‡ [MAX_PRIM_COUNT] é …å¹¾ä½•å…ƒä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> + <notification name="TooManyScriptsSelected"> + é¸å–的物件腳本太多。 請減少é¸å–的物件數,å†è©¦ä¸€æ¬¡ã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="ProblemImportingEstateCovenant"> åŒ¯å…¥é ˜åœ°å¥‘ç´„æ™‚å‡ºå•é¡Œã€‚ <usetemplate name="okbutton" yestext="確定"/> @@ -2285,6 +2313,10 @@ SHA1 指紋:[MD5_DIGEST] 付款失敗:找ä¸åˆ°ç‰©ä»¶ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> + <notification name="PaymentBlockedButtonMismatch"> + 付款ä¸æ¢ï¼šæ‰€ä»˜åƒ¹æ ¼èˆ‡æ¤ç‰©ä»¶è¨å®šçš„任何付款按鈕皆ä¸ç›¸ç¬¦ã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="OpenObjectCannotCopy"> 這物件ä¸æ²’æœ‰ä»»ä½•å‡†è¨±ä½ è¤‡è£½çš„ç‰©é …ã€‚ </notification> @@ -2320,6 +2352,12 @@ SHA1 指紋:[MD5_DIGEST] 這是一組包å«è¯çµé›†çš„巨大é¸å–é …ã€‚ ä¸€æ—¦ä½ å–消它的è¯çµï¼Œå¾ˆå¯èƒ½ä¸èƒ½å†é‡æ–°è¯çµã€‚ 為防è¬ä¸€ï¼Œå»ºè°ä½ 把è¯çµé›†è¤‡è£½åˆ°æ”¶ç´å€ã€‚ <usetemplate ignoretext="å–消è¯çµé›†è¯çµæ™‚,跟我確èª" name="okcancelignore" notext="å–消" yestext="å–消è¯çµ"/> </notification> + <notification name="HelpReportAbuseConfirm"> + è¬è¬ä½ 撥冗æå ±å•é¡Œã€‚ +æˆ‘å€‘æœƒæŸ¥æ ¸ä½ çš„èˆ‰å ±å…§å®¹æ±ºå®šæœ‰ç„¡é•è¦æƒ…事,並 +採å–é©ç•¶è¡Œå‹•ã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="HelpReportAbuseSelectCategory"> è«‹é¸æ“‡é©åˆé€™æ¬¡é•è¦èˆ‰å ±çš„類別。 é¸å°é¡žåˆ¥å¯ä»¥å¹«åŠ©æˆ‘們æ¸é¡žä¸¦è™•ç†é•è¦èˆ‰å ±ã€‚ @@ -2390,6 +2428,10 @@ SHA1 指紋:[MD5_DIGEST] ä½ ç¢ºå®šä½ è¦å°ä½ 垃圾ç’ä¸çš„內容進行刪除? <usetemplate ignoretext="在我清空收ç´å€åžƒåœ¾ç’資料夾å‰ç¢ºèª" name="okcancelignore" notext="å–消" yestext="確定"/> </notification> + <notification name="TrashIsFull"> + ä½ çš„åžƒåœ¾æ¡¶å¿«æ»¿äº†ã€‚ 這å¯èƒ½æœƒé€ æˆç™»å…¥çš„å•é¡Œã€‚ + <usetemplate name="okcancelbuttons" notext="我ç¨å¾Œå†æ¸…空垃圾桶" yestext="ç¾åœ¨æ¸…空垃圾桶"/> + </notification> <notification name="ConfirmClearBrowserCache"> ä½ ç¢ºå®šè¦åˆªé™¤ä½ çš„æ—…è¡Œã€ç¶²é åŠæœå°‹æ·å²ç´€éŒ„嗎? <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/> @@ -2744,6 +2786,10 @@ SHA1 指紋:[MD5_DIGEST] <notification name="PathfindingDirty"> 這地å€çš„尋徑功能有所變更,待儲å˜ã€‚ å¦‚æžœä½ æœ‰å»ºè£½æ¬Šï¼Œä½ å¯ä»¥é»žæŒ‰ã€Œé‡æ–°ç”¢å‡ºåœ°å€ã€æŒ‰éˆ•é‡æ–°ç”¢å‡ºåœ°å€ã€‚ </notification> + <notification name="PathfindingDirtyRebake"> + 這地å€çš„尋徑功能有所變更,待儲å˜ã€‚ å¦‚æžœä½ æœ‰å»ºè£½æ¬Šï¼Œä½ å¯ä»¥é»žæŒ‰ã€Œé‡æ–°ç”¢å‡ºåœ°å€ã€æŒ‰éˆ•é‡æ–°ç”¢å‡ºåœ°å€ã€‚ + <usetemplate name="okbutton" yestext="é‡æ–°ç”¢å‡ºåœ°å€"/> + </notification> <notification name="DynamicPathfindingDisabled"> 這地å€ä¸¦æœªå•Ÿç”¨å‹•æ…‹å°‹å¾‘。 使用尋徑 LSL 呼å«çš„帶腳本物件,在æ¤åœ°å€å¯èƒ½ç„¡æ³•æ£å¸¸é‹ä½œã€‚ </notification> @@ -2973,11 +3019,11 @@ SHA1 指紋:[MD5_DIGEST] å¦‚æžœä½ ç¹¼çºŒç•™åœ¨é€™åœ°å€ï¼Œä½ 將會被登出。 </notification> <notification name="LoadWebPage"> - 載入網é [URL]? + 載入網é [URL]? [MESSAGE] -來æºç‰©ä»¶ï¼š<nolink>[OBJECTNAME]</nolink>(所有人:[NAME_SLURL]) +來æºç‰©ä»¶ï¼š<nolink>[OBJECTNAME]</nolink>(所有人是[NAME_SLURL]) <form name="form"> <button name="Gotopage" text="å‰å¾€é é¢"/> <button name="Cancel" text="å–消"/> @@ -3246,6 +3292,12 @@ SHA1 指紋:[MD5_DIGEST] <notification name="AttachmentSaved"> 附件已儲å˜ã€‚ </notification> + <notification name="AppearanceToXMLSaved"> + 外觀已經å˜æˆä½æ–¼[PATH]çš„XML + </notification> + <notification name="AppearanceToXMLFailed"> + 將外觀å˜ç‚ºXML失敗。 + </notification> <notification name="PresetNotSaved"> 儲å˜é è¨å稱[NAME]時出錯。 </notification> @@ -3460,13 +3512,6 @@ SHA1 指紋:[MD5_DIGEST] <notification name="ForceQuitDueToLowMemory"> 記憶體ä¸è¶³ï¼Œç¬¬äºŒäººç”Ÿå°‡æ–¼ 30 秒後關閉離開。 </notification> - <notification name="PopupAttempt"> - 一個çªé¡¯å¼è¦–窗開啟時被阻擋。 - <form name="form"> - <ignore name="ignore" text="啟用全部的çªé¡¯å¼è¦–窗"/> - <button name="open" text="é–‹å•Ÿçªé¡¯å¼è¦–窗"/> - </form> - </notification> <notification name="SOCKS_NOT_PERMITTED"> SOCKS 5 代ç†ä¼ºæœå™¨ "[HOST]:[PORT]" 拒絕連通,è¦å‰‡é›†ä¸å…許。 <usetemplate name="okbutton" yestext="確定"/> @@ -3841,6 +3886,9 @@ SHA1 指紋:[MD5_DIGEST] 無法移動 '[OBJECT_NAME]' 物件到 [REGION_NAME] 地å€çš„ [OBJ_POSITION]ï¼Œå› ç‚ºæ¤åœ°æ®µè³‡æºä¸è¶³å®¹ç´æ¤ç‰©ä»¶ã€‚ </notification> + <notification name="NoParcelPermsNoObject"> + è¤‡è£½å¤±æ•—ï¼Œå› çˆ²ä½ ç„¡æ¬Šå‡ºå…¥è©²åœ°æ®µã€‚ + </notification> <notification name="CantMoveObjectRegionVersion"> 無法移動 '[OBJECT_NAME]' 物件到 [REGION_NAME] 地å€çš„ [OBJ_POSITION]ï¼Œå› ç‚ºè©²åœ°å€æ‰€åŸ·è¡Œçš„軟體版本éŽèˆŠï¼Œä¸æ”¯æ´è·¨åœ°å€æŽ¥å—這個物件。 @@ -3856,6 +3904,10 @@ SHA1 指紋:[MD5_DIGEST] <notification name="NoPermModifyObject"> ä½ ç„¡æ¬Šè®Šæ›´è©²ç‰©ä»¶ </notification> + <notification name="TooMuchObjectInventorySelected"> + é¸å–的物件包å«å¤ªå¤šå¤§çš„收ç´å€ã€‚ 請減少é¸å–的物件數,å†è©¦ä¸€æ¬¡ã€‚ + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="CantEnablePhysObjContributesToNav"> å°å°Žèˆªç¶²é¢æœ‰è²¢ç»çš„物件,無法啟用物ç†ã€‚ </notification> @@ -3892,6 +3944,12 @@ SHA1 指紋:[MD5_DIGEST] <notification name="CantSaveModifyAttachment"> 無法儲å˜åˆ°ç‰©ä»¶å…§å®¹ï¼šé€™éº¼åšå°‡ä¿®æ”¹é™„件的權é™ã€‚ </notification> + <notification name="AttachmentHasTooMuchInventory"> + ä½ çš„é™„ä»¶å·²ç¶“åŒ…å«å¤ªå¤šæ”¶ç´å€å…§å®¹ï¼Œä¸èƒ½å†å¢žåŠ 。 + </notification> + <notification name="IllegalAttachment"> + 這個附件è¦æ±‚了化身上ä¸å˜åœ¨çš„點。 å› æ¤å·²å°‡è©²é™„件附著到胸部。 + </notification> <notification name="TooManyScripts"> 腳本太多。 </notification> @@ -3984,6 +4042,12 @@ SHA1 指紋:[MD5_DIGEST] <notification name="TeleportedByObjectUnknownUser"> ä½ å·²æˆåŠŸè¢«æŸæœªçŸ¥ç”¨æˆ¶æ“有的物件 '[OBJECT_NAME]' 瞬間傳é€ã€‚ </notification> + <notification name="StandDeniedByObject"> + 「[OBJECT_NAME]ã€å°‡ä½¿ä½ 無法在æ¤æ™‚站立。 + </notification> + <notification name="ResitDeniedByObject"> + 「[OBJECT_NAME]ã€æ¤æ™‚無法å…è¨±ä½ æ”¹è®Šåº§ä½ã€‚ + </notification> <notification name="CantCreateObjectRegionFull"> 無法建立è¦æ±‚的物件。 地å€å·²æ»¿è¼‰ã€‚ </notification> @@ -4280,6 +4344,9 @@ SHA1 指紋:[MD5_DIGEST] <notification name="CantTransfterMoneyRegionDisabled"> æ¤åœ°å€ç›®å‰æœªå•Ÿç”¨è½‰ç§»é‡‘錢給物件的功能。 </notification> + <notification name="DroppedMoneyTransferRequest"> + ç³»çµ±è² è·å¤ªé‡ï¼Œç„¡æ³•é€²è¡Œä»˜æ¬¾ã€‚ + </notification> <notification name="CantPayNoAgent"> 無法決定付款給誰。 </notification> @@ -4315,4 +4382,8 @@ SHA1 指紋:[MD5_DIGEST] èŠå¤©ç´€éŒ„檔案還在處ç†å‰ä¸€å€‹å‹•ä½œã€‚ è«‹ç¨å€™å†è©¦ï¼Œæˆ–è«‹æ›ä¸€å€‹èŠå¤©å°è±¡ã€‚ <usetemplate name="okbutton" yestext="確定"/> </notification> + <notification name="OutfitPhotoLoadError"> + [REASON] + <usetemplate name="okbutton" yestext="確定"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml index 8dd93543c0028c8acdbaff931fb9633ddad84f6c..9b9a79a509fec8abaf2fb6d0e778bb345e87498a 100644 --- a/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml @@ -7,6 +7,7 @@ 穿上所é¸æ“‡çš„物件 </panel.string> <tab_container name="appearance_tabs"> + <panel label="è£æ‰®é™³åˆ—" name="outfit_gallery_tab"/> <panel label="我的è£æ‰®" name="outfitslist_tab"/> <panel label="ç›®å‰ç©¿è‘—" name="cof_tab"/> </tab_container> diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml index 693cdcdeca7ecbed5120816097891fc77af4812e..e3c62cfccf3e4c06188a9cd661e849483040ad96 100644 --- a/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Wearing"> + <panel.string name="no_attachments"> + 未穿著任何附件。 + </panel.string> + <accordion name="wearables_accordion"> + <accordion_tab name="tab_wearables" title="å¯ç©¿è£æ‰®"/> + <accordion_tab name="tab_temp_attachments" title="暫時附件"/> + </accordion> <panel name="bottom_panel"> <menu_button name="options_gear_btn" tool_tip="顯示é¡å¤–é¸é …"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml index 94eb3c1389471229e7c40ae7308ef911b6d37f95..212880df55492492b4c184d99a6f0a44ffa0fdd2 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml @@ -3,8 +3,9 @@ <text name="tell_me_label"> 告訴我: </text> - <check_box label="當我花費或å–å¾— L$" name="notify_money_change_checkbox"/> + <check_box label="當我花用 L$ 時" name="notify_money_spend_checkbox"/> <check_box label="當我的朋å‹ä¸Šç·šæˆ–離線" name="friends_online_notify_checkbox"/> + <check_box label="當我得到 L$ 時" name="notify_money_received_checkbox"/> <text name="show_label"> 總是顯示: </text> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml index 8c4d2f9c1824f172cd0e2d435df60fe5c88ea0fe..4eef62491079ed2553e52016b3a566b4251118ac 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml @@ -24,10 +24,15 @@ <text name="BetterText"> 最佳 </text> + <slider label="化身最大複雜度:" name="IndirectMaxComplexity" tool_tip="控制在何時機下讓複雜化身呈åƒç‚ºã€ŒJellyDollã€"/> + <text name="IndirectMaxComplexityText"> + 0 + </text> <check_box initial_value="true" label="大氣著色" name="WindLightUseAtmosShaders"/> <check_box initial_value="true" label="進階照明模型" name="UseLightShaders"/> <button label="å°‡è¨å®šå˜ç‚ºé è¨å€¼ …" name="PrefSaveButton"/> <button label="載入é è¨..." name="PrefLoadButton"/> + min_val="0.125" <button label="刪除自訂é…置…" name="PrefDeleteButton"/> <button label="é‡è¨ç‚ºæˆ‘們建è°çš„è¨å®š" name="Defaults"/> <button label="進階è¨å®šâ€¦" name="AdvancedSettings"/> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml index 942bd27140fa77857850b5488eab66f7a771dbd4..bdf980218cb692857723c7efcf85f4d4e27d8066 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml @@ -30,6 +30,7 @@ <combo_box.item label="讓我自己手動下載並安è£" name="Install_manual"/> </combo_box> <check_box label="願æ„在更新時æ¶å…ˆè©¦ç”¨é‡‹å‡ºå€™é¸ç‰ˆ" name="update_willing_to_test"/> + <check_box label="更新後顯示發行記事" name="update_show_release_notes"/> <text name="Proxy Settings:"> 代ç†ä¼ºæœå™¨è¨å®šï¼š </text> diff --git a/indra/newview/skins/default/xui/zh/panel_sound_devices.xml b/indra/newview/skins/default/xui/zh/panel_sound_devices.xml index fa4e24a6059d770fc8ca92ce19f2b603d6fc23e6..e29ffe31af7cdefc06dd4cfd93c2dc2de03c66fd 100644 --- a/indra/newview/skins/default/xui/zh/panel_sound_devices.xml +++ b/indra/newview/skins/default/xui/zh/panel_sound_devices.xml @@ -16,9 +16,9 @@ 輸出 </text> <text name="My volume label"> - 我的音é‡ï¼š + 麥克風音é‡ï¼š </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="用這控制æ¢æ”¹è®ŠéŸ³é‡"/> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="用這個控制æ¢èª¿æ•´éº¥å…‹é¢¨éŸ³é‡"/> <text name="wait_text"> è«‹ç¨å€™ </text> diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index 2ce310b2244755206af16492e10eeda7525fcf98..ec08c9f91e31d0f378cc8fbf7e73abf5e9aac942 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -41,6 +41,9 @@ [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> + <string name="BuildConfig"> + 建製è¨ç½® [BUILD_CONFIG] + </string> <string name="AboutPosition"> ä½ çš„æ–¹ä½æ˜¯ [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1],地å€å:[REGION],主機:<nolink>[HOSTNAME]</nolink> ([HOSTIP]) 第二人生URL:<nolink>[SLURL]</nolink> @@ -58,20 +61,40 @@ <string name="AboutDriver"> Windows 顯示驅動程å¼ç‰ˆæœ¬ï¼š[GRAPHICS_DRIVER_VERSION] </string> + <string name="AboutOGL"> + OpenGL版本:[OPENGL_VERSION] + </string> + <string name="AboutSettings"> + 視窗大å°ï¼š[WINDOW_WIDTH]x[WINDOW_HEIGHT] +å—體大å°èª¿æ•´ï¼š[FONT_SIZE_ADJUSTMENT]點 +使用者介é¢æ¯”例:[UI_SCALE] +æ繪è·é›¢ï¼š[DRAW_DISTANCE]公尺 +é »å¯¬ï¼š[NET_BANDWITH]åƒä½å…ƒ/秒 +細節層次率:[LOD_FACTOR] +呈åƒå“質:[RENDER_QUALITY] / 7 +進階照明模型:[GPU_SHADERS] +æ質記憶體:[TEXTURE_MEMORY]MB +VFS(快å–)建立時間:[VFS_TIME] + </string> <string name="AboutLibs"> - OpenGL 版本:[OPENGL_VERSION] - -J2C 解碼器版本: [J2C_VERSION] + J2C 解碼器版本: [J2C_VERSION] 音效驅動程å¼ç‰ˆæœ¬ï¼š [AUDIO_DRIVER_VERSION] LLCEFLib/CEF版本:[LLCEFLIB_VERSION] +LibVLC版本:[LIBVLC_VERSION]N] 語音伺æœå™¨ç‰ˆæœ¬ï¼š [VOICE_VERSION] </string> <string name="AboutTraffic"> å°åŒ…丟失:[PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> <string name="ErrorFetchingServerReleaseNotesURL"> æ“·å–伺æœå™¨ç‰ˆæœ¬èªªæ˜Ž URL 時出錯。 </string> + <string name="BuildConfiguration"> + 建製è¨ç½® + </string> <string name="ProgressRestoring"> 回å˜ä¸... </string> @@ -1075,6 +1098,9 @@ http://secondlife.com/viewer-access-faq <string name="TeleportYourAgent"> 瞬間傳é€ä½ 本人 </string> + <string name="ForceSitAvatar"> + å¼·è¿«ä½ çš„åŒ–èº«å下 + </string> <string name="NotConnected"> 未è¯æŽ¥ </string> @@ -1382,6 +1408,9 @@ http://secondlife.com/viewer-access-faq <string name="BodyPartsRightLeg"> å³è…¿ </string> + <string name="BodyPartsEnhancedSkeleton"> + 增強版骨架 + </string> <string name="GraphicsQualityLow"> 低 </string> @@ -1830,6 +1859,51 @@ http://secondlife.com/viewer-access-faq <string name="Avatar Center"> 化身ä¸å¿ƒ </string> + <string name="Left Ring Finger"> + 左無å指 + </string> + <string name="Right Ring Finger"> + å³ç„¡å指 + </string> + <string name="Tail Base"> + 尾巴基部 + </string> + <string name="Tail Tip"> + 尾巴末梢 + </string> + <string name="Left Wing"> + 左翼 + </string> + <string name="Right Wing"> + å³ç¿¼ + </string> + <string name="Jaw"> + é¡Ž + </string> + <string name="Alt Left Ear"> + 替代左耳 + </string> + <string name="Alt Right Ear"> + 替代å³è€³ + </string> + <string name="Alt Left Eye"> + 替代左眼 + </string> + <string name="Alt Right Eye"> + 替代å³çœ¼ + </string> + <string name="Tongue"> + 舌é + </string> + <string name="Groin"> + é¼ è¹Š + </string> + <string name="Left Hind Foot"> + 左後腳 + </string> + <string name="Right Hind Foot"> + å³å¾Œè…³ + </string> <string name="Invalid Attachment"> 無效的附接點 </string> @@ -1875,6 +1949,27 @@ http://secondlife.com/viewer-access-faq <string name="av_render_anyone"> ä½ æ怕ä¸èƒ½å‘ˆåƒçµ¦ä½ 周é的任何人。 </string> + <string name="hud_description_total"> + ä½ çš„æ“¡é 顯示 + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME](穿戴於[JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS]使用了很多æ質記憶體 + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS]包å«å¾ˆå¤šè€—用性能的物件和æ質 + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] 包å«å¾ˆå¤šå¤§çš„æ質 + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS]包å«éŽå¤šç‰©ä»¶ + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS]包å«å¤ªå¤šæ質 + </string> <string name="AgeYearsA"> [COUNT] å¹´ </string> @@ -2034,6 +2129,9 @@ http://secondlife.com/viewer-access-faq <string name="ObjectOutOfRange"> 腳本(物件超出範åœï¼‰ </string> + <string name="ScriptWasDeleted"> + 腳本(已從收ç´å€åˆªé™¤ï¼‰ + </string> <string name="GodToolsObjectOwnedBy"> 物件 [OBJECT] 為 [OWNER] 所æ“有 </string> @@ -2219,12 +2317,12 @@ http://secondlife.com/viewer-access-faq <string name="ATTACH_BELLY"> 腹部 </string> - <string name="ATTACH_RPEC"> - å³èƒ¸è‚Œ - </string> - <string name="ATTACH_LPEC"> + <string name="ATTACH_LEFT_PEC"> 左胸肌 </string> + <string name="ATTACH_RIGHT_PEC"> + å³èƒ¸è‚Œ + </string> <string name="ATTACH_HUD_CENTER_2"> æ“¡é 顯示ä¸å¤® 2 </string> @@ -2255,6 +2353,51 @@ http://secondlife.com/viewer-access-faq <string name="ATTACH_AVATAR_CENTER"> 化身ä¸å¿ƒ </string> + <string name="ATTACH_LHAND_RING1"> + 左無å指 + </string> + <string name="ATTACH_RHAND_RING1"> + å³ç„¡å指 + </string> + <string name="ATTACH_TAIL_BASE"> + 尾巴基部 + </string> + <string name="ATTACH_TAIL_TIP"> + 尾巴末梢 + </string> + <string name="ATTACH_LWING"> + 左翼 + </string> + <string name="ATTACH_RWING"> + å³ç¿¼ + </string> + <string name="ATTACH_FACE_JAW"> + é¡Ž + </string> + <string name="ATTACH_FACE_LEAR"> + 替代左耳 + </string> + <string name="ATTACH_FACE_REAR"> + 替代å³è€³ + </string> + <string name="ATTACH_FACE_LEYE"> + 替代左眼 + </string> + <string name="ATTACH_FACE_REYE"> + 替代å³çœ¼ + </string> + <string name="ATTACH_FACE_TONGUE"> + 舌é + </string> + <string name="ATTACH_GROIN"> + é¼ è¹Š + </string> + <string name="ATTACH_HIND_LFOOT"> + 左後腳 + </string> + <string name="ATTACH_HIND_RFOOT"> + å³å¾Œè…³ + </string> <string name="CursorPos"> æ©«è¡Œ [LINE],縱列 [COLUMN] </string> @@ -2601,6 +2744,15 @@ http://secondlife.com/viewer-access-faq <string name="Play Media"> æ’放/æš«åœåª’é«” </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=tw + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> <string name="MBCmdLineError"> 解æžå‘½ä»¤åˆ—時發ç¾éŒ¯èª¤ã€‚ è«‹åƒé–±ï¼š http://wiki.secondlife.com/wiki/Client_parameters @@ -4244,6 +4396,12 @@ http://secondlife.com/viewer-access-faq <string name="OfflineStatus"> 離線 </string> + <string name="not_online_msg"> + 使用者ä¸åœ¨ç·šä¸Š - 訊æ¯å°‡ç•™å˜ï¼Œç¨å¾Œå‚³éžã€‚ + </string> + <string name="not_online_inventory"> + 使用者ä¸åœ¨ç·šä¸Š - 收ç´å€å·²å„²å˜ã€‚ + </string> <string name="answered_call"> ä½ çš„é€šè©±å·²ç¶“æŽ¥é€š </string> @@ -4370,12 +4528,18 @@ http://secondlife.com/viewer-access-faq <string name="paid_you_ldollars"> [NAME] æ”¯ä»˜ä½ L$[AMOUNT]([REASON])。 </string> + <string name="paid_you_ldollars_gift"> + [NAME]æ”¯ä»˜ä½ L$[AMOUNT]:([REASON]) + </string> <string name="paid_you_ldollars_no_reason"> [NAME] æ”¯ä»˜ä½ L$[AMOUNT]。 </string> <string name="you_paid_ldollars"> ä½ æ”¯ä»˜ L$[AMOUNT] 給 [NAME]([REASON])。 </string> + <string name="you_paid_ldollars_gift"> + ä½ æ”¯ä»˜L$[AMOUNT]給[NAME]:[REASON] + </string> <string name="you_paid_ldollars_no_info"> ä½ æ”¯ä»˜äº† L$[AMOUNT]。 </string> @@ -4388,6 +4552,9 @@ http://secondlife.com/viewer-access-faq <string name="you_paid_failure_ldollars"> ä½ æ”¯ä»˜ L$[AMOUNT] 給 [NAME] 時出錯:[REASON]。 </string> + <string name="you_paid_failure_ldollars_gift"> + ä½ æ”¯ä»˜L$[AMOUNT]給[NAME]時出錯:[REASON] + </string> <string name="you_paid_failure_ldollars_no_info"> ä½ æ”¯ä»˜ L$[AMOUNT] 時出錯。 </string> @@ -4714,6 +4881,15 @@ http://secondlife.com/viewer-access-faq <string name="texture_load_dimensions_error"> 無法載入圖åƒå¤§æ–¼ [WIDTH]*[HEIGHT] </string> + <string name="outfit_photo_load_dimensions_error"> + è£æ‰®çš„最大照片大å°æ˜¯[WIDTH]*[HEIGHT]。 請變更尺寸或使用å¦ä¸€å€‹åœ–åƒ + </string> + <string name="outfit_photo_select_dimensions_error"> + è£æ‰®çš„最大照片大å°æ˜¯[WIDTH]*[HEIGHT]。 è«‹é¸æ“‡å¦ä¸€å€‹æ質 + </string> + <string name="outfit_photo_verify_dimensions_error"> + 無法驗è‰ç›¸ç‰‡å°ºå¯¸ã€‚ è«‹ç‰æŒ‘é¸å™¨é¡¯ç¤ºç›¸ç‰‡å°ºå¯¸å†è©¦ + </string> <string name="words_separator" value=","/> <string name="server_is_down"> 儘管我們努力é¿å…,還是發生æ„料外的錯誤。 @@ -5230,6 +5406,9 @@ http://secondlife.com/viewer-access-faq <string name="Command_Profile_Label"> 檔案 </string> + <string name="Command_Report_Abuse_Label"> + é•è¦èˆ‰å ± + </string> <string name="Command_Search_Label"> æœå°‹ </string> @@ -5320,6 +5499,9 @@ http://secondlife.com/viewer-access-faq <string name="Command_Profile_Tooltip"> ç·¨è¼¯æˆ–å¯Ÿçœ‹ä½ çš„å°æª”案 </string> + <string name="Command_Report_Abuse_Tooltip"> + é•è¦èˆ‰å ± + </string> <string name="Command_Search_Tooltip"> 尋找地點ã€æ´»å‹•ã€å…¶ä»–人 </string> diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index aa05897c0be0ba3e0d7d2347cd79e65b58370169..55dcb83567bb5b5269f306c5b821f1014a5956cf 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -136,6 +136,7 @@ void LLGridManager::addSystemGrid(const std::string& label, const std::string& helper, const std::string& login_page, const std::string& update_url_base, + const std::string& web_profile_url, const std::string& login_id) { } diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp index ea5014a59c2fa4c07319766567296d7204514a41..4f7f87b6b01ef39afd15e9453904ffdcf6f08080 100644 --- a/indra/newview/tests/llremoteparcelrequest_test.cpp +++ b/indra/newview/tests/llremoteparcelrequest_test.cpp @@ -34,6 +34,7 @@ #include "../llagent.h" #include "message.h" #include "llurlentry.h" +#include "llpounceable.h" namespace { const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111"); @@ -62,7 +63,7 @@ void LLMessageSystem::addUUID(char const *,LLUUID const &) { } void LLMessageSystem::addUUIDFast(char const *,LLUUID const &) { } void LLMessageSystem::nextBlockFast(char const *) { } void LLMessageSystem::newMessage(char const *) { } -LLMessageSystem * gMessageSystem; +LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; char const* const _PREHASH_AgentID = 0; // never dereferenced during this test char const* const _PREHASH_AgentData = 0; // never dereferenced during this test LLAgent gAgent; diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp index 6b0be29c2d284ab96b19ff4f8a2bff750196c8b9..f1f69f33f19b7ba2da08e56499e77434dce1e995 100644 --- a/indra/newview/tests/llversioninfo_test.cpp +++ b/indra/newview/tests/llversioninfo_test.cpp @@ -29,6 +29,13 @@ #include "../llversioninfo.h" +// LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The +// macro expands to the string name of the channel, but without quotes. We +// need to turn it into a quoted string. This macro trick does that. +#define stringize_inner(x) #x +#define stringize_outer(x) stringize_inner(x) +#define ll_viewer_channel stringize_outer(LL_VIEWER_CHANNEL) + namespace tut { struct versioninfo @@ -50,7 +57,7 @@ namespace tut mShortVersion = stream.str(); stream.str(""); - stream << LL_VIEWER_CHANNEL + stream << ll_viewer_channel << " " << mVersion; mVersionAndChannel = stream.str(); @@ -89,7 +96,7 @@ namespace tut LL_VIEWER_VERSION_BUILD); ensure_equals("Channel version", LLVersionInfo::getChannel(), - LL_VIEWER_CHANNEL); + ll_viewer_channel); ensure_equals("Version String", LLVersionInfo::getVersion(), mVersion); diff --git a/indra/newview/tests/test_llxmlrpc_peer.py b/indra/newview/tests/test_llxmlrpc_peer.py index 281b72a058fde3d9ad9bc5a2092c81116d052dca..cff40aa4c2516809595b78b31c3a1a10e0af0f1e 100755 --- a/indra/newview/tests/test_llxmlrpc_peer.py +++ b/indra/newview/tests/test_llxmlrpc_peer.py @@ -31,15 +31,23 @@ import os import sys -from threading import Thread from SimpleXMLRPCServer import SimpleXMLRPCServer mydir = os.path.dirname(__file__) # expected to be .../indra/newview/tests/ -sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) -sys.path.insert(1, os.path.join(mydir, os.pardir, os.pardir, "llmessage", "tests")) +sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "llmessage", "tests")) from testrunner import freeport, run, debug class TestServer(SimpleXMLRPCServer): + # This server_bind() override is borrowed and simplified from + # BaseHTTPServer.HTTPServer.server_bind(): we want to capture the actual + # server port. BaseHTTPServer.HTTPServer.server_bind() stores the actual + # port in a server_port attribute, but SimpleXMLRPCServer isn't derived + # from HTTPServer. So do it ourselves. + def server_bind(self): + """Override server_bind to store the server port.""" + SimpleXMLRPCServer.server_bind(self) + self.server_port = self.socket.getsockname()[1] + def _dispatch(self, method, params): try: func = getattr(self, method) @@ -67,15 +75,21 @@ def log_error(self, format, *args): pass if __name__ == "__main__": - # Instantiate a TestServer on the first free port in the specified port - # range. Doing this inline is better than in a daemon thread: if it blows - # up here, we'll get a traceback. If it blew up in some other thread, the - # traceback would get eaten and we'd run the subject test program anyway. - xmlrpcd, port = freeport(xrange(8000, 8020), - lambda port: TestServer(('127.0.0.1', port))) + # function to make a server with specified port + make_server = lambda port: TestServer(('127.0.0.1', port)) + + if not sys.platform.startswith("win"): + # Instantiate a TestServer on a port chosen by the runtime. + xmlrpcd = make_server(0) + else: + # "Then there's Windows" + # Instantiate a TestServer on the first free port in the specified + # port range. + xmlrpcd, port = freeport(xrange(8000, 8020), make_server) + # Pass the selected port number to the subject test program via the # environment. We don't want to impose requirements on the test program's # command-line parsing -- and anyway, for C++ integration tests, that's # performed in TUT code rather than our own. - os.environ["PORT"] = str(port) - sys.exit(run(server=Thread(name="xmlrpc", target=xmlrpcd.serve_forever), *sys.argv[1:])) + os.environ["PORT"] = str(xmlrpcd.server_port) + sys.exit(run(server_inst=xmlrpcd, *sys.argv[1:])) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 03a727468ed852d691042ef893bd52ee8ed48834..35d63c33fc8d428ab139f405a9b4b0ade2e6e9e0 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -42,10 +42,7 @@ # indra.util.llmanifest under their system Python! sys.path.insert(0, os.path.join(viewer_dir, os.pardir, "lib", "python")) from indra.util.llmanifest import LLManifest, main, path_ancestors, CHANNEL_VENDOR_BASE, RELEASE_CHANNEL, ManifestError -try: - from llbase import llsd -except ImportError: - from indra.base import llsd +from llbase import llsd class ViewerManifest(LLManifest): def is_packaging_viewer(self): @@ -288,7 +285,8 @@ def extract_names(self,src): random.shuffle(names) return ', '.join(names) -class Windows_i686_Manifest(ViewerManifest): + +class WindowsManifest(ViewerManifest): def final_exe(self): return self.app_name_oneword()+".exe" @@ -339,7 +337,7 @@ def test_for_no_msvcrt_manifest_and_copy_action(self, src, dst): print "Doesn't exist:", src def construct(self): - super(Windows_i686_Manifest, self).construct() + super(WindowsManifest, self).construct() pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') relpkgdir = os.path.join(pkgdir, "lib", "release") @@ -381,18 +379,15 @@ def construct(self): # Get fmodex dll, continue if missing try: - if self.args['configuration'].lower() == 'debug': - self.path("fmodexL.dll") + if(self.args['arch'].lower() == 'x86_64'): + self.path("fmodex64.dll") else: self.path("fmodex.dll") except: print "Skipping fmodex audio library(assuming other audio engine)" # For textures - if self.args['configuration'].lower() == 'debug': - self.path("openjpegd.dll") - else: - self.path("openjpeg.dll") + self.path("openjpeg.dll") # These need to be installed as a SxS assembly, currently a 'private' assembly. # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx @@ -437,19 +432,14 @@ def construct(self): self.path("featuretable.txt") self.path("featuretable_xp.txt") - # Media plugins - QuickTime - if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"): - self.path("media_plugin_quicktime.dll") - self.end_prefix() - # Media plugins - CEF if self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"): self.path("media_plugin_cef.dll") self.end_prefix() - # winmm.dll shim - if self.prefix(src='../media_plugins/winmmshim/%s' % self.args['configuration'], dst=""): - self.path("winmm.dll") + # Media plugins - LibVLC + if self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration'], dst="llplugin"): + self.path("media_plugin_libvlc.dll") self.end_prefix() # CEF runtime files - debug @@ -553,6 +543,12 @@ def construct(self): self.path("zh-TW.pak") self.end_prefix() + if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="llplugin"): + self.path("libvlc.dll") + self.path("libvlccore.dll") + self.path("plugins/") + self.end_prefix() + # pull in the crash logger and updater from other projects # tag:"crash-logger" here as a cue to the exporter self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'], @@ -663,7 +659,7 @@ def package_finish(self): while (not installer_created) and (nsis_attempts > 0): try: nsis_attempts-=1; - self.run_command('"' + NSIS_path + '" ' + self.dst_path_of(tempfile)) + self.run_command('"' + NSIS_path + '" /V2 ' + self.dst_path_of(tempfile)) installer_created=True # if no exception was raised, the codesign worked except ManifestError, err: if nsis_attempts: @@ -691,7 +687,17 @@ def package_finish(self): self.package_file = installer_file -class Darwin_i386_Manifest(ViewerManifest): +class Windows_i686_Manifest(WindowsManifest): + # specialize when we must + pass + + +class Windows_x86_64_Manifest(WindowsManifest): + # specialize when we must + pass + + +class DarwinManifest(ViewerManifest): def is_packaging_viewer(self): # darwin requires full app bundle packaging even for debugging. return True @@ -728,7 +734,7 @@ def construct(self): # most everything goes in the Resources directory if self.prefix(src="", dst="Resources"): - super(Darwin_i386_Manifest, self).construct() + super(DarwinManifest, self).construct() if self.prefix("cursors_mac"): self.path("*.tif") @@ -802,7 +808,7 @@ def path_optional(src, dst): "libapr-1.0.dylib", "libaprutil-1.0.dylib", "libcollada14dom.dylib", - "libexpat.1.5.2.dylib", + "libexpat.1.dylib", "libexception_handler.dylib", "libGLOD.dylib", ): @@ -860,15 +866,39 @@ def path_optional(src, dst): self.path2basename(relpkgdir, helperappfile) pluginframeworkpath = self.dst_path_of('Chromium Embedded Framework.framework'); + # Putting a Frameworks directory under Contents/MacOS + # isn't canonical, but the path baked into LLCefLib + # Helper.app/Contents/MacOS/LLCefLib Helper is: + # @executable_path/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework + # (notice, not @executable_path/../Frameworks/etc.) + # So we'll create a symlink (below) from there back to the + # Frameworks directory nested under SLPlugin.app. + helperframeworkpath = \ + self.dst_path_of('LLCefLib Helper.app/Contents/MacOS/' + 'Frameworks/Chromium Embedded Framework.framework') self.end_prefix() # SLPlugin plugins if self.prefix(src="", dst="llplugin"): - self.path2basename("../media_plugins/quicktime/" + self.args['configuration'], - "media_plugin_quicktime.dylib") self.path2basename("../media_plugins/cef/" + self.args['configuration'], "media_plugin_cef.dylib") + + # copy LibVLC plugin itself + self.path2basename("../media_plugins/libvlc/" + self.args['configuration'], + "media_plugin_libvlc.dylib") + + # copy LibVLC dynamic libraries + if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release' ), dst="lib"): + self.path( "libvlc*.dylib*" ) + self.end_prefix() + + # copy LibVLC plugins folder + if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release', 'plugins' ), dst="plugins"): + self.path( "lib*_plugin.dylib" ) + self.path( "plugins.dat" ) + self.end_prefix() + self.end_prefix("llplugin") self.end_prefix("Resources") @@ -888,16 +918,36 @@ def path_optional(src, dst): # this symlink, Second Life web media can't possibly work. # Real Framework folder: # Second Life.app/Contents/Frameworks/Chromium Embedded Framework.framework/ - # Location of symlink and why it'ds relative + # Location of symlink and why it's relative # Second Life.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework/ # Real Frameworks folder, with the symlink inside the bundled SLPlugin.app (and why it's relative) # <top level>.app/Contents/Frameworks/Chromium Embedded Framework.framework/ # <top level>.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework -> - frameworkpath = os.path.join(os.pardir, os.pardir, os.pardir, os.pardir, "Frameworks", "Chromium Embedded Framework.framework") + # It might seem simpler just to create a symlink Frameworks to + # the parent of Chromimum Embedded Framework.framework. But + # that would create a symlink cycle, which breaks our + # packaging step. So make a symlink from Chromium Embedded + # Framework.framework to the directory of the same name, which + # is NOT an ancestor of the symlink. + frameworkpath = os.path.join(os.pardir, os.pardir, os.pardir, + os.pardir, "Frameworks", + "Chromium Embedded Framework.framework") try: - symlinkf(frameworkpath, pluginframeworkpath) + # from SLPlugin.app/Contents/Frameworks/Chromium Embedded + # Framework.framework back to Second + # Life.app/Contents/Frameworks/Chromium Embedded Framework.framework + origin, target = pluginframeworkpath, frameworkpath + symlinkf(target, origin) + # from SLPlugin.app/Contents/Frameworks/LLCefLib + # Helper.app/Contents/MacOS/Frameworks/Chromium Embedded + # Framework.framework back to + # SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework + self.cmakedirs(os.path.dirname(helperframeworkpath)) + origin = helperframeworkpath + target = os.path.join(os.pardir, frameworkpath) + symlinkf(target, origin) except OSError as err: - print "Can't symlink %s -> %s: %s" % (frameworkpath, pluginframeworkpath, err) + print "Can't symlink %s -> %s: %s" % (origin, target, err) raise self.end_prefix("Contents") @@ -1055,6 +1105,20 @@ def package_finish(self): self.package_file = finalname self.remove(sparsename) + +class Darwin_i386_Manifest(DarwinManifest): + pass + + +class Darwin_i686_Manifest(DarwinManifest): + """alias in case arch is passed as i686 instead of i386""" + pass + + +class Darwin_x86_64_Manifest(DarwinManifest): + pass + + class LinuxManifest(ViewerManifest): def construct(self): super(LinuxManifest, self).construct() @@ -1112,8 +1176,18 @@ def construct(self): # plugins if self.prefix(src="", dst="bin/llplugin"): self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") + self.path("../media_plugins/libvlc/libmedia_plugin_libvlc.so", "libmedia_plugin_libvlc.so") self.end_prefix("bin/llplugin") + if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"): + self.path( "plugins.dat" ) + self.path( "*/*.so" ) + self.end_prefix() + + if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib' ), dst="lib"): + self.path( "libvlc*.so*" ) + self.end_prefix() + # llcommon if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"): print "Skipping llcommon.so (assuming llcommon was linked statically)" diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 55442b252160c55cff63a5b3f517a170b07f5f4a..8344cead57c32a8f80a01bea1a3f284b2fb11c52 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -102,7 +102,6 @@ target_link_libraries(lltest ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ${DL_LIBRARY} - ${GOOGLE_PERFTOOLS_LIBRARIES} ) if (WINDOWS) diff --git a/indra/test/llapp_tut.cpp b/indra/test/llapp_tut.cpp index aa5c0672e691eacfe7c6c096096d43a08ad966ff..98e714a497a961bb53ff1691f65d9e2280340e88 100644 --- a/indra/test/llapp_tut.cpp +++ b/indra/test/llapp_tut.cpp @@ -41,7 +41,7 @@ namespace tut public: virtual bool init() { return true; } virtual bool cleanup() { return true; } - virtual bool mainLoop() { return true; } + virtual bool frame() { return true; } }; LLTestApp* mApp; application() diff --git a/indra/test/llstreamtools_tut.cpp b/indra/test/llstreamtools_tut.cpp index 0f6436f0f4a8b51e5d517ff85d2840c4895126da..2f027b688f35a231e39e8c08ca5eed74dafe69c1 100644 --- a/indra/test/llstreamtools_tut.cpp +++ b/indra/test/llstreamtools_tut.cpp @@ -149,10 +149,9 @@ namespace tut is.clear(); is.str(str = "# \r\n # SecondLife is a 3D World. ##"); - skip_comments_and_emptyspace(is); - is.get(arr, 255, '\0'); - expected_result = ""; - ensure_equals("skip_comments_and_emptyspace: skip comment - 2", arr, expected_result); + ensure("should not be good()", ! skip_comments_and_emptyspace(is)); + ensure("should be at eof()", is.eof()); + // don't get(): given bad state, we can't rely on results is.clear(); is.str(str = " \r\n SecondLife is a 3D World. ##"); @@ -164,14 +163,12 @@ namespace tut is.clear(); is.str(str = ""); ret = skip_comments_and_emptyspace(is); - is.get(arr, 255, '\0'); - ensure("skip_comments_and_emptyspace: empty string", ret == false); + ensure("skip_comments_and_emptyspace: empty string", ! ret); is.clear(); is.str(str = " \r\n \t # SecondLife is a 3D World"); ret = skip_comments_and_emptyspace(is); - is.get(arr, 255, '\0'); - ensure("skip_comments_and_emptyspace: space newline comment empty", ret == false); + ensure("skip_comments_and_emptyspace: space newline comment empty", ! ret); } //testcases for skip_line() diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp index 8718360f0cb309caf0ad93f477348a4a1433f74b..76063e6db120b8d1a333fd2f30c7d643c9d76372 100644 --- a/indra/test/message_tut.cpp +++ b/indra/test/message_tut.cpp @@ -103,7 +103,7 @@ namespace tut ~LLMessageSystemTestData() { // not end_messaging_system() - delete gMessageSystem; + delete static_cast<LLMessageSystem*>(gMessageSystem); gMessageSystem = NULL; // rm contents of temp dir diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt deleted file mode 100644 index e682eacccaecf1098532be9ef707645014b4019e..0000000000000000000000000000000000000000 --- a/indra/test_apps/llplugintest/CMakeLists.txt +++ /dev/null @@ -1,336 +0,0 @@ -# -*- cmake -*- -project(llplugintest) - -include(00-Common) -include(OpenGL) -include(LLCommon) -include(LLPlugin) -include(Linking) -include(LLSharedLibs) -include(PluginAPI) -include(LLImage) -include(LLMath) -include(LLMessage) -include(LLRender) -include(LLWindow) -include(Glut) -include(Glui) - -include_directories( - ${LLPLUGIN_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} -) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) - -if (DARWIN) - include(CMakeFindFrameworks) - find_library(COREFOUNDATION_LIBRARY CoreFoundation) -endif (DARWIN) - -### demo_plugin - -#set(demo_plugin_SOURCE_FILES -# demo_plugin.cpp -# ) -# -#add_library(demo_plugin -# SHARED -# ${demo_plugin_SOURCE_FILES} -#) -# -#target_link_libraries(demo_plugin -# ${LLPLUGIN_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -# ${PLUGIN_API_WINDOWS_LIBRARIES} -#) -# -#add_dependencies(demo_plugin -# ${LLPLUGIN_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -#) -# -#if (DARWIN) -# # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name -# set_target_properties( -# demo_plugin -# PROPERTIES -# PREFIX "" -# BUILD_WITH_INSTALL_RPATH 1 -# INSTALL_NAME_DIR "@executable_path" -# ) -#endif (DARWIN) - -### plugin_host - -#set(plugin_host_SOURCE_FILES -# plugin_host.cpp -# ) -# -#add_executable(plugin_host -# WIN32 -# ${plugin_host_SOURCE_FILES} -#) -# -#set_target_properties(plugin_host -# PROPERTIES -# WIN32_EXECUTABLE -# FALSE -#) -# -#target_link_libraries(plugin_host -# ${LLPLUGIN_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -# ${PLUGIN_API_WINDOWS_LIBRARIES} -#) -# -#add_dependencies(plugin_host -# demo_plugin -# ${LLPLUGIN_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -#) - -### plugin_process_launcher - -#set(plugin_process_launcher_SOURCE_FILES -# plugin_process_launcher.cpp -# ) -# -#add_executable(plugin_process_launcher -# WIN32 -# ${plugin_process_launcher_SOURCE_FILES} -#) -# -#set_target_properties(plugin_process_launcher -# PROPERTIES -# WIN32_EXECUTABLE -# FALSE -#) -# -#target_link_libraries(plugin_process_launcher -# ${LLPLUGIN_LIBRARIES} -# ${LLMESSAGE_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -# ${PLUGIN_API_WINDOWS_LIBRARIES} -#) -# -#add_dependencies(plugin_process_launcher -# SLPlugin -# demo_plugin -# ${LLPLUGIN_LIBRARIES} -# ${LLMESSAGE_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -#) - -### media_simple_test - -#set(media_simple_test_SOURCE_FILES -# media_simple_test.cpp -# ) -# -#add_executable(media_simple_test -# WIN32 -# ${media_simple_test_SOURCE_FILES} -#) -# -#add_dependencies(media_simple_test stage_third_party_libs) -# -#set_target_properties(media_simple_test -# PROPERTIES -# WIN32_EXECUTABLE -# FALSE -#) -# -#target_link_libraries(media_simple_test -# ${GLUT_LIBRARY} -# ${OPENGL_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -#) - -### media_plugin_test - -#set(media_plugin_test_SOURCE_FILES -# media_plugin_test.cpp -# ) -# -#add_executable(media_plugin_test -# WIN32 -# ${media_plugin_test_SOURCE_FILES} -#) -# -#set_target_properties(media_plugin_test -# PROPERTIES -# WIN32_EXECUTABLE -# FALSE -#) -# -#target_link_libraries(media_plugin_test -# ${GLUT_LIBRARY} -# ${OPENGL_LIBRARIES} -# ${LLPLUGIN_LIBRARIES} -# ${LLMESSAGE_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -# ${PLUGIN_API_WINDOWS_LIBRARIES} -#) -# -#add_dependencies(media_plugin_test -# stage_third_party_libs -# SLPlugin -# demo_media_plugin -# ${LLPLUGIN_LIBRARIES} -# ${LLMESSAGE_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -#) - -### demo_media_plugin - -#set(demo_media_plugin_SOURCE_FILES -# demo_media_plugin.cpp -# ) -# -#add_library(demo_media_plugin -# SHARED -# ${demo_media_plugin_SOURCE_FILES} -#) -# -#target_link_libraries(demo_media_plugin -# ${LLPLUGIN_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -# ${PLUGIN_API_WINDOWS_LIBRARIES} -#) -# -#add_dependencies(demo_media_plugin -# ${LLPLUGIN_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -#) -# -#if (DARWIN) -# # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name -# set_target_properties( -# demo_media_plugin -# PROPERTIES -# PREFIX "" -# BUILD_WITH_INSTALL_RPATH 1 -# INSTALL_NAME_DIR "@executable_path" -# ) -#endif (DARWIN) - -### demo_media_plugin_2 - -#set(demo_media_plugin_2_SOURCE_FILES -# demo_media_plugin_2.cpp -# ) -# -#add_library(demo_media_plugin_2 -# SHARED -# ${demo_media_plugin_2_SOURCE_FILES} -#) -# -#target_link_libraries(demo_media_plugin_2 -# ${LLPLUGIN_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -# ${PLUGIN_API_WINDOWS_LIBRARIES} -#) -# -#add_dependencies(demo_media_plugin_2 -# ${LLPLUGIN_LIBRARIES} -# ${LLCOMMON_LIBRARIES} -#) -# -#if (DARWIN) -# # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name -# set_target_properties( -# demo_media_plugin_2 -# PROPERTIES -# PREFIX "" -# BUILD_WITH_INSTALL_RPATH 1 -# INSTALL_NAME_DIR "@executable_path" -# ) -#endif (DARWIN) - -# Gather build products of the various dependencies into the build directory for the testbed. - -if(WINDOWS) - #******************** - # Plugin test library deploy - # - # Debug config runtime files required for the plugin test mule - set(plugintest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}") - set(plugintest_debug_files - libeay32.dll - libglib-2.0-0.dll - libgmodule-2.0-0.dll - libgobject-2.0-0.dll - libgthread-2.0-0.dll - ssleay32.dll - ) - copy_if_different( - ${plugintest_debug_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/Debug" - out_targets - ${plugintest_debug_files} - ) - set(plugin_test_targets ${plugin_test_targets} ${out_targets}) - - # Release & ReleaseDebInfo config runtime files required for the plugin test mule - set(plugintest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") - set(plugintest_release_files - libeay32.dll - libglib-2.0-0.dll - libgmodule-2.0-0.dll - libgobject-2.0-0.dll - libgthread-2.0-0.dll - ssleay32.dll - ) - copy_if_different( - ${plugintest_release_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/Release" - out_targets - ${plugintest_release_files} - ) - set(plugin_test_targets ${plugin_test_targets} ${out_targets}) - - copy_if_different( - ${plugintest_release_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo" - out_targets - ${plugintest_release_files} - ) - set(plugin_test_targets ${plugin_test_targets} ${out_targets}) - - add_custom_target(copy_plugintest_libs ALL - DEPENDS - ${plugin_test_targets} - ) - -endif(WINDOWS) - -if (DARWIN) - set(plugintest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") - set(plugintest_release_files - libexception_handler.dylib - libaprutil-1.0.dylib - libapr-1.0.dylib - libexpat.1.5.2.dylib - ) - copy_if_different( - ${plugintest_release_src_dir} - "${PLUGINS_DESTINATION_DIR}" - out_targets - ${plugintest_release_files} - ) - set(plugin_test_targets ${plugin_test_targets} ${out_targets}) - - add_custom_target(copy_plugintest_libs ALL - DEPENDS - ${plugin_test_targets} - ) - -endif (DARWIN) - diff --git a/indra/test_apps/llplugintest/README.Linden b/indra/test_apps/llplugintest/README.Linden deleted file mode 100644 index 4a9f223c21f183528bc1edac3d1ba1f5592e84ae..0000000000000000000000000000000000000000 --- a/indra/test_apps/llplugintest/README.Linden +++ /dev/null @@ -1,21 +0,0 @@ - -1. Description - - Exercises SLPlugin. Demonstrates mediakit plugin reuse and - switchover as MIME type changes (web, quicktime, flash). - - -2. Running - - 2.1 Mac - - Make certain '.' is included in PATH. E.g.: - - PATH=.:"$PATH" open build-darwin-i386/test_apps/llmediaplugintest/RelWithDebInfo/llmediaplugintest.app - - Otherwise the program won't find SLPlugin and will timeout and - fail after 30 seconds and give you little information as to why. - - Running 'dtruss' on plugin test applications will give you a great - deal of insight into why they aren't activating. - diff --git a/indra/test_apps/llplugintest/bookmarks.txt b/indra/test_apps/llplugintest/bookmarks.txt deleted file mode 100644 index 2ff64f217f57aa331aee5b21c465c50b30e73d34..0000000000000000000000000000000000000000 --- a/indra/test_apps/llplugintest/bookmarks.txt +++ /dev/null @@ -1,37 +0,0 @@ -# format is description, url (don't put ',' chars in description :) -# if no ',' found, whole line is used for both description and url -(WK) Google Home Page,http://www.google.com -(WK) BBC News Home Page,http://news.bbc.co.uk -(WK) Second Life,http://secondlife.com -(WK) WebKit Home ,http://www.webkit.org -(WK) Yahoo News,http://news.yahoo.com -(WK) Canvas Paint (DHTML version of MS Paint),http://www.canvaspaint.org -(WK) DHTML Lemmings!,http://www.elizium.nu/scripts/lemmings/ -(WK) DHTML graphics demos,http://www.dhteumeuleu.com/ -(WK) Shared paint app,http://colorillo.com/ac79?1l0q6cp -(Flash) YouTube,http://youtube.com -(Flash) Vimeo,http://www.vimeo.com/1778399 -(Flash) Simple whiteboard,http://www.imaginationcubed.com/ -(Flash) Dabble Board,http://www.dabbleboard.com/draw -(Flash) Bubble Shooter game,http://www.wiicade.com/playGame.aspx?gameID=72&gameName=Bubble%20Shooter -(Flash) Pixlr photo editor,http://pixlr.com/editor/ -(Flash) Scribd,http://www.scribd.com/doc/14427744/Second-Life-Quickstart-Guide -(Flash) MAME,http://yvern.com/fMAME/fMAME.html -(QT) Local sample,file:///C|/Program Files/QuickTime/Sample.mov -(QT) Movie - Watchmen Trailer,http://trailers.apple.com/movies/wb/watchmen/watchmen-tlr2_480p.mov -(QT) Movie - Transformers - Revenge of the Fallen,http://trailers.apple.com/movies/paramount/transformers2/transformersrevengeofthefallen-tlr1_h.320.mov -(QT) Movie - Terminator Salvation,http://trailers.apple.com/movies/wb/terminatorsalvation/terminatorsalvation-tlr3_h.320.mov -(QT) Movie - Angels and Demons,http://trailers.apple.com/movies/sony_pictures/angelsanddemons/angelsanddemons-video_h.320.mov -(QT) Movie - Sin City Trailer,http://trailers.apple.com/movies/miramax/sin_city/sin_city_480.mov -(QT) Movie - The Incredibles Trailer,http://trailers.apple.com/movies/disney/the_incredibles/the_incredibles-tlr_a480.mov -(QT) Movie - Streaming Apple Event,http://stream.qtv.apple.com/events/mar/0903lajkszg/m_090374535329zdwg_650_ref.mov -(QT) Movie - MPEG-4 from Amazon S3,http://s3.amazonaws.com/callum-linden/flashdemo/interactive_flash_demo.mp4 -(QT) Movie - Star Trek,http://trailers.apple.com/movies/paramount/star_trek/startrek-tlr3_h.320.mov -(QT) Movie - Ice Age 3,http://trailers.apple.com/movies/fox/ice_age_iii/iceage3-tlrd_h.320.mov -(QT) Movie - AstroBoy,http://trailers.apple.com/movies/summit/astroboy/astroboy-tsr_h.320.mov -(QT) Movie - Ante Up,http://trailers.apple.com/movies/independent/anteup/anteup_h.320.mov -(QT) Movie - Every Little Step,http://trailers.apple.com/movies/sony/everylittlestep/everylittlestep-clip_h.320.mov -(QT) Movie - The Informers,http://trailers.apple.com/movies/independent/theinformers/theinformers_h.320.mov -(QT) Animated GIF,http://upload.wikimedia.org/wikipedia/commons/4/44/Optical.greysquares.arp-animated.gif -(QT) Apple Text Descriptors,http://ubrowser.com/tmp/apple_text.txt -(EX) Example Plugin,example://blah diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index 53d4acc9e0157ce76165ba54400aa94247254166..c767d52c7bd3aac30f2d33ec681ac549cf3d42b1 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -42,6 +42,8 @@ #include "llevents.h" #include "lleventfilter.h" #include "lleventcoro.h" +#include "llexception.h" +#include "stringize.h" //********************* // LLLogin @@ -128,30 +130,23 @@ void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params) void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params) { - try - { - LLSD printable_params = login_params; - //if(printable_params.has("params") - // && printable_params["params"].has("passwd")) - //{ - // printable_params["params"]["passwd"] = "*******"; - //} - LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName() + LLSD printable_params = login_params; + if (printable_params.has("params") + && printable_params["params"].has("passwd")) + { + printable_params["params"]["passwd"] = "*******"; + } + try + { + LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName() << " with uri '" << uri << "', parameters " << printable_params << LL_ENDL; - // Arriving in SRVRequest state - LLEventStream replyPump("SRVreply", true); - // Should be an array of one or more uri strings. - LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction")); // EXT-4193: use a DIFFERENT reply pump than for the SRV request. We used // to share them -- but the EXT-3934 fix made it possible for an abandoned // SRV response to arrive just as we were expecting the XMLRPC response. LLEventStream loginReplyPump("loginreply", true); - // Loop through the rewrittenURIs, counting attempts along the way. - // Because of possible redirect responses, we may make more than one - // attempt per rewrittenURIs entry. LLSD::Integer attempts = 0; LLSD request(login_params); @@ -167,11 +162,11 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params) LLSD progress_data; progress_data["attempt"] = attempts; progress_data["request"] = request; - if(progress_data["request"].has("params") - && progress_data["request"]["params"].has("passwd")) - { - progress_data["request"]["params"]["passwd"] = "*******"; - } + if (progress_data["request"].has("params") + && progress_data["request"]["params"].has("passwd")) + { + progress_data["request"]["params"]["passwd"] = "*******"; + } sendProgressEvent("offline", "authenticating", progress_data); // We expect zero or more "Downloading" status events, followed by @@ -189,8 +184,8 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params) // Still Downloading -- send progress update. sendProgressEvent("offline", "downloading"); } - - LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL; + + LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL; status = mAuthResponse["status"].asString(); // Okay, we've received our final status event for this @@ -202,7 +197,7 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params) break; } - sendProgressEvent("offline", "indeterminate", mAuthResponse["responses"]); + sendProgressEvent("offline", "indeterminate", mAuthResponse["responses"]); // Here the login service at the current URI is redirecting us // to some other URI ("indeterminate" -- why not "redirect"?). @@ -212,8 +207,7 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params) request["method"] = mAuthResponse["responses"]["next_method"].asString(); } // loop back to try the redirected URI - // Here we're done with redirects for the current rewrittenURIs - // entry. + // Here we're done with redirects. if (status == "Complete") { // StatusComplete does not imply auth success. Check the @@ -230,14 +224,14 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params) return; // Done! } -// /* Sometimes we end with "Started" here. Slightly slow server? -// * Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below. -// */ -// if( status == "Started") -// { -// LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL; -// continue; -// } +// /* Sometimes we end with "Started" here. Slightly slow server? +// * Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below. +// */ +// if( status == "Started") +// { +// LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL; +// continue; +// } // If we don't recognize status at all, trouble if (! (status == "CURLError" @@ -250,27 +244,25 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params) } // Here status IS one of the errors tested above. - - // Here we got through all the rewrittenURIs without succeeding. Tell - // caller this didn't work out so well. Of course, the only failure data - // we can reasonably show are from the last of the rewrittenURIs. - - // *NOTE: The response from LLXMLRPCListener's Poller::poll method returns an - // llsd with no "responses" node. To make the output from an incomplete login symmetrical - // to success, add a data/message and data/reason fields. - LLSD error_response; - error_response["reason"] = mAuthResponse["status"]; - error_response["errorcode"] = mAuthResponse["errorcode"]; - error_response["message"] = mAuthResponse["error"]; - if(mAuthResponse.has("certificate")) - { - error_response["certificate"] = mAuthResponse["certificate"]; - } - sendProgressEvent("offline", "fail.login", error_response); - } - catch (...) { - LL_ERRS() << "login exception caught" << LL_ENDL; - } + // Tell caller this didn't work out so well. + + // *NOTE: The response from LLXMLRPCListener's Poller::poll method returns an + // llsd with no "responses" node. To make the output from an incomplete login symmetrical + // to success, add a data/message and data/reason fields. + LLSD error_response; + error_response["reason"] = mAuthResponse["status"]; + error_response["errorcode"] = mAuthResponse["errorcode"]; + error_response["message"] = mAuthResponse["error"]; + if(mAuthResponse.has("certificate")) + { + error_response["certificate"] = mAuthResponse["certificate"]; + } + sendProgressEvent("offline", "fail.login", error_response); + } + catch (...) { + CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::instance().getName() + << "('" << uri << "', " << printable_params << ")")); + } } void LLLogin::Impl::disconnect() diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp index 23c29e6b18807be639d60bf2fe3c445da124addf..167acf6ac7b623745613429b08022ea8db981797 100644 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ b/indra/win_crash_logger/llcrashloggerwindows.cpp @@ -454,7 +454,7 @@ void LLCrashLoggerWindows::gatherPlatformSpecificFiles() //mDebugLog["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo(); //Not initialized. } -bool LLCrashLoggerWindows::mainLoop() +bool LLCrashLoggerWindows::frame() { LL_INFOS() << "CrashSubmitBehavior is " << mCrashBehavior << LL_ENDL; @@ -503,14 +503,14 @@ bool LLCrashLoggerWindows::mainLoop() TranslateMessage(&msg); DispatchMessage(&msg); } - return msg.wParam; + return true; // msg.wParam; } else { LL_WARNS() << "Unknown crash behavior " << mCrashBehavior << LL_ENDL; - return 1; + return true; // 1; } - return 0; + return true; // 0; } void LLCrashLoggerWindows::updateApplication(const std::string& message) diff --git a/indra/win_crash_logger/llcrashloggerwindows.h b/indra/win_crash_logger/llcrashloggerwindows.h index 1812e2737ec1d2f01a6fb46641ba8360a2bd8598..f89b8708dc9386567547b875c518a0ef07522e36 100644 --- a/indra/win_crash_logger/llcrashloggerwindows.h +++ b/indra/win_crash_logger/llcrashloggerwindows.h @@ -46,7 +46,7 @@ class LLCrashLoggerWindows : public LLCrashLogger static LLCrashLoggerWindows* sInstance; virtual bool init(); - virtual bool mainLoop(); + virtual bool frame(); virtual void updateApplication(const std::string& message = LLStringUtil::null); virtual bool cleanup(); virtual void gatherPlatformSpecificFiles(); diff --git a/indra/win_crash_logger/win_crash_logger.cpp b/indra/win_crash_logger/win_crash_logger.cpp index 366edd894b970766a0e621e5067b70c954b9f7d2..7466dbb76638a131d86d4f353a019ccd43d06eff 100644 --- a/indra/win_crash_logger/win_crash_logger.cpp +++ b/indra/win_crash_logger/win_crash_logger.cpp @@ -52,7 +52,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, } app.processingLoop(); - app.mainLoop(); + app.frame(); app.cleanup(); LL_INFOS() << "Crash reporter finished normally." << LL_ENDL; return 0; diff --git a/scripts/content_tools/anim_tool.py b/scripts/content_tools/anim_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..9b795f45fd878139c531a338f9c210a61605878d --- /dev/null +++ b/scripts/content_tools/anim_tool.py @@ -0,0 +1,602 @@ +#!runpy.sh + +"""\ + +This module contains tools for manipulating the .anim files supported +for Second Life animation upload. Note that this format is unrelated +to any non-Second Life formats of the same name. + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ +""" + +import sys +import os +import struct +import StringIO +import math +import argparse +import random +from lxml import etree + +U16MAX = 65535 +OOU16MAX = 1.0/(float)(U16MAX) + +LL_MAX_PELVIS_OFFSET = 5.0 + +class FilePacker(object): + def __init__(self): + self.data = StringIO.StringIO() + self.offset = 0 + + def write(self,filename): + f = open(filename,"wb") + f.write(self.data.getvalue()) + f.close() + + def pack(self,fmt,*args): + buf = struct.pack(fmt, *args) + self.offset += struct.calcsize(fmt) + self.data.write(buf) + + def pack_string(self,str,size=0): + buf = str + "\000" + if size and (len(buf) < size): + buf += "\000" * (size-len(buf)) + self.data.write(buf) + +class FileUnpacker(object): + def __init__(self, filename): + f = open(filename,"rb") + self.data = f.read() + self.offset = 0 + + def unpack(self,fmt): + result = struct.unpack_from(fmt, self.data, self.offset) + self.offset += struct.calcsize(fmt) + return result + + def unpack_string(self, size=0): + result = "" + i = 0 + while (self.data[self.offset+i] != "\000"): + result += self.data[self.offset+i] + i += 1 + i += 1 + if size: + # fixed-size field for the string + i = size + self.offset += i + return result + +# translated from the C++ version in lldefs.h +def llclamp(a, minval, maxval): + if a<minval: + return minval + if a>maxval: + return maxval + return a + +# translated from the C++ version in llquantize.h +def F32_to_U16(val, lower, upper): + val = llclamp(val, lower, upper); + # make sure that the value is positive and normalized to <0, 1> + val -= lower; + val /= (upper - lower); + + # return the U16 + return int(math.floor(val*U16MAX)) + +# translated from the C++ version in llquantize.h +def U16_to_F32(ival, lower, upper): + if ival < 0 or ival > U16MAX: + raise Exception("U16 out of range: "+ival) + val = ival*OOU16MAX + delta = (upper - lower) + val *= delta + val += lower + + max_error = delta*OOU16MAX; + + # make sure that zeroes come through as zero + if abs(val) < max_error: + val = 0.0 + return val; + +class BadFormat(Exception): + pass + +class RotKey(object): + def __init__(self): + pass + + def unpack(self, anim, fup): + (self.time_short, ) = fup.unpack("<H") + self.time = U16_to_F32(self.time_short, 0.0, anim.duration) + (x,y,z) = fup.unpack("<HHH") + self.rotation = [U16_to_F32(i, -1.0, 1.0) for i in (x,y,z)] + + def dump(self, f): + print >>f, " rot_key: t",self.time,"st",self.time_short,"rot",",".join([str(f) for f in self.rotation]) + + def pack(self, anim, fp): + if not hasattr(self,"time_short"): + self.time_short = F32_to_U16(self.time, 0.0, anim.duration) + fp.pack("<H",self.time_short) + (x,y,z) = [F32_to_U16(v, -1.0, 1.0) for v in self.rotation] + fp.pack("<HHH",x,y,z) + +class PosKey(object): + def __init__(self): + pass + + def unpack(self, anim, fup): + (self.time_short, ) = fup.unpack("<H") + self.time = U16_to_F32(self.time_short, 0.0, anim.duration) + (x,y,z) = fup.unpack("<HHH") + self.position = [U16_to_F32(i, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET) for i in (x,y,z)] + + def dump(self, f): + print >>f, " pos_key: t",self.time,"pos ",",".join([str(f) for f in self.position]) + + def pack(self, anim, fp): + if not hasattr(self,"time_short"): + self.time_short = F32_to_U16(self.time, 0.0, anim.duration) + fp.pack("<H",self.time_short) + (x,y,z) = [F32_to_U16(v, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET) for v in self.position] + fp.pack("<HHH",x,y,z) + +class Constraint(object): + def __init__(self): + pass + + def unpack(self, anim, fup): + (self.chain_length, self.constraint_type) = fup.unpack("<BB") + self.source_volume = fup.unpack_string(16) + self.source_offset = fup.unpack("<fff") + self.target_volume = fup.unpack_string(16) + self.target_offset = fup.unpack("<fff") + self.target_dir = fup.unpack("<fff") + fmt = "<ffff" + (self.ease_in_start, self.ease_in_stop, self.ease_out_start, self.ease_out_stop) = fup.unpack("<ffff") + + def pack(self, anim, fp): + fp.pack("<BB", self.chain_length, self.constraint_type) + fp.pack_string(self.source_volume, 16) + fp.pack("<fff", *self.source_offset) + fp.pack_string(self.target_volume, 16) + fp.pack("<fff", *self.target_offset) + fp.pack("<fff", *self.target_dir) + fp.pack("<ffff", self.ease_in_start, self.ease_in_stop, self.ease_out_start, self.ease_out_stop) + + def dump(self, f): + print >>f, " constraint:" + print >>f, " chain_length",self.chain_length + print >>f, " constraint_type",self.constraint_type + print >>f, " source_volume",self.source_volume + print >>f, " source_offset",self.source_offset + print >>f, " target_volume",self.target_volume + print >>f, " target_offset",self.target_offset + print >>f, " target_dir",self.target_dir + print >>f, " ease_in_start",self.ease_in_start + print >>f, " ease_in_stop",self.ease_in_stop + print >>f, " ease_out_start",self.ease_out_start + print >>f, " ease_out_stop",self.ease_out_stop + +class Constraints(object): + def __init__(self): + pass + + def unpack(self, anim, fup): + (self.num_constraints, ) = fup.unpack("<i") + self.constraints = [] + for i in xrange(self.num_constraints): + constraint = Constraint() + constraint.unpack(anim, fup) + self.constraints.append(constraint) + + def pack(self, anim, fp): + fp.pack("<i",self.num_constraints) + for c in self.constraints: + c.pack(anim,fp) + + def dump(self, f): + print >>f, "constraints:",self.num_constraints + for c in self.constraints: + c.dump(f) + +class PositionCurve(object): + def __init__(self): + self.num_pos_keys = 0 + self.keys = [] + + def is_static(self): + if self.keys: + k0 = self.keys[0] + for k in self.keys: + if k.position != k0.position: + return False + return True + + def unpack(self, anim, fup): + (self.num_pos_keys, ) = fup.unpack("<i") + self.keys = [] + for k in xrange(0,self.num_pos_keys): + pos_key = PosKey() + pos_key.unpack(anim, fup) + self.keys.append(pos_key) + + def pack(self, anim, fp): + fp.pack("<i",self.num_pos_keys) + for k in self.keys: + k.pack(anim, fp) + + def dump(self, f): + print >>f, " position_curve:" + print >>f, " num_pos_keys", self.num_pos_keys + for k in xrange(0,self.num_pos_keys): + self.keys[k].dump(f) + +class RotationCurve(object): + def __init__(self): + self.num_rot_keys = 0 + self.keys = [] + + def is_static(self): + if self.keys: + k0 = self.keys[0] + for k in self.keys: + if k.rotation != k0.rotation: + return False + return True + + def unpack(self, anim, fup): + (self.num_rot_keys, ) = fup.unpack("<i") + self.keys = [] + for k in xrange(0,self.num_rot_keys): + rot_key = RotKey() + rot_key.unpack(anim, fup) + self.keys.append(rot_key) + + def pack(self, anim, fp): + fp.pack("<i",self.num_rot_keys) + for k in self.keys: + k.pack(anim, fp) + + def dump(self, f): + print >>f, " rotation_curve:" + print >>f, " num_rot_keys", self.num_rot_keys + for k in xrange(0,self.num_rot_keys): + self.keys[k].dump(f) + +class JointInfo(object): + def __init__(self): + pass + + def unpack(self, anim, fup): + self.joint_name = fup.unpack_string() + (self.joint_priority, ) = fup.unpack("<i") + self.rotation_curve = RotationCurve() + self.rotation_curve.unpack(anim, fup) + self.position_curve = PositionCurve() + self.position_curve.unpack(anim, fup) + + def pack(self, anim, fp): + fp.pack_string(self.joint_name) + fp.pack("<i", self.joint_priority) + self.rotation_curve.pack(anim, fp) + self.position_curve.pack(anim, fp) + + def dump(self, f): + print >>f, "joint:" + print >>f, " joint_name:",self.joint_name + print >>f, " joint_priority:",self.joint_priority + self.rotation_curve.dump(f) + self.position_curve.dump(f) + +class Anim(object): + def __init__(self, filename=None): + if filename: + self.read(filename) + + def read(self, filename): + fup = FileUnpacker(filename) + self.unpack(fup) + + # various validity checks could be added - see LLKeyframeMotion::deserialize() + def unpack(self,fup): + (self.version, self.sub_version, self.base_priority, self.duration) = fup.unpack("@HHhf") + + if self.version == 0 and self.sub_version == 1: + self.old_version = True + raise BadFormat("old version not supported") + elif self.version == 1 and self.sub_version == 0: + self.old_version = False + else: + raise BadFormat("Bad combination of version, sub_version: %d %d" % (self.version, self.sub_version)) + + self.emote_name = fup.unpack_string() + + (self.loop_in_point, self.loop_out_point, self.loop, self.ease_in_duration, self.ease_out_duration, self.hand_pose, self.num_joints) = fup.unpack("@ffiffII") + + self.joints = [] + for j in xrange(0,self.num_joints): + joint_info = JointInfo() + joint_info.unpack(self, fup) + self.joints.append(joint_info) + print "unpacked joint",joint_info.joint_name + self.constraints = Constraints() + self.constraints.unpack(self, fup) + self.data = fup.data + + def pack(self, fp): + fp.pack("@HHhf", self.version, self.sub_version, self.base_priority, self.duration) + fp.pack_string(self.emote_name, 0) + fp.pack("@ffiffII", self.loop_in_point, self.loop_out_point, self.loop, self.ease_in_duration, self.ease_out_duration, self.hand_pose, self.num_joints) + for j in self.joints: + j.pack(anim, fp) + self.constraints.pack(anim, fp) + + def dump(self, filename="-"): + if filename=="-": + f = sys.stdout + else: + f = open(filename,"w") + print >>f, "versions: ", self.version, self.sub_version + print >>f, "base_priority: ", self.base_priority + print >>f, "duration: ", self.duration + print >>f, "emote_name: ", self.emote_name + print >>f, "loop_in_point: ", self.loop_in_point + print >>f, "loop_out_point: ", self.loop_out_point + print >>f, "loop: ", self.loop + print >>f, "ease_in_duration: ", self.ease_in_duration + print >>f, "ease_out_duration: ", self.ease_out_duration + print >>f, "hand_pose", self.hand_pose + print >>f, "num_joints", self.num_joints + for j in self.joints: + j.dump(f) + self.constraints.dump(f) + + def write(self, filename): + fp = FilePacker() + self.pack(fp) + fp.write(filename) + + def write_src_data(self, filename): + print "write file",filename + f = open(filename,"wb") + f.write(self.data) + f.close() + + def find_joint(self, name): + joints = [j for j in self.joints if j.joint_name == name] + if joints: + return joints[0] + else: + return None + + def add_joint(self, name, priority): + if not self.find_joint(name): + j = JointInfo() + j.joint_name = name + j.joint_priority = priority + j.rotation_curve = RotationCurve() + j.position_curve = PositionCurve() + self.joints.append(j) + self.num_joints = len(self.joints) + + def delete_joint(self, name): + j = self.find_joint(name) + if j: + anim.joints.remove(j) + anim.num_joints = len(self.joints) + + def summary(self): + nj = len(self.joints) + nz = len([j for j in self.joints if j.joint_priority > 0]) + nstatic = len([j for j in self.joints if j.rotation_curve.is_static() and j.position_curve.is_static()]) + print "summary: %d joints, non-zero priority %d, static %d" % (nj, nz, nstatic) + + def add_pos(self, joint_names, positions): + js = [joint for joint in self.joints if joint.joint_name in joint_names] + for j in js: + if args.verbose: + print "adding positions",j.joint_name,positions + j.joint_priority = 4 + j.position_curve.num_pos_keys = len(positions) + j.position_curve.keys = [] + for i,pos in enumerate(positions): + key = PosKey() + key.time = self.duration * i / (len(positions) - 1) + key.time_short = F32_to_U16(key.time, 0.0, self.duration) + key.position = pos + j.position_curve.keys.append(key) + + def add_rot(self, joint_names, rotations): + js = [joint for joint in self.joints if joint.joint_name in joint_names] + for j in js: + print "adding rotations",j.joint_name + j.joint_priority = 4 + j.rotation_curve.num_rot_keys = len(rotations) + j.rotation_curve.keys = [] + for i,pos in enumerate(rotations): + key = RotKey() + key.time = self.duration * i / (len(rotations) - 1) + key.time_short = F32_to_U16(key.time, 0.0, self.duration) + key.rotation = pos + j.rotation_curve.keys.append(key) + +def twistify(anim, joint_names, rot1, rot2): + js = [joint for joint in anim.joints if joint.joint_name in joint_names] + for j in js: + print "twisting",j.joint_name + print j.rotation_curve.num_rot_keys + j.joint_priority = 4 + j.rotation_curve.num_rot_keys = 2 + j.rotation_curve.keys = [] + key1 = RotKey() + key1.time_short = 0 + key1.time = U16_to_F32(key1.time_short, 0.0, anim.duration) + key1.rotation = rot1 + key2 = RotKey() + key2.time_short = U16MAX + key2.time = U16_to_F32(key2.time_short, 0.0, anim.duration) + key2.rotation = rot2 + j.rotation_curve.keys.append(key1) + j.rotation_curve.keys.append(key2) + +def float_triple(arg): + vals = arg.split() + if len(vals)==3: + return [float(x) for x in vals] + else: + raise Exception("arg %s does not resolve to a float triple" % arg) + +def get_joint_by_name(tree,name): + if tree is None: + return None + matches = [elt for elt in tree.getroot().iter() if \ + elt.get("name")==name and elt.tag in ["bone", "collision_volume", "attachment_point"]] + if len(matches)==1: + return matches[0] + elif len(matches)>1: + print "multiple matches for name",name + return None + else: + return None + +def get_elt_pos(elt): + if elt.get("pos"): + return float_triple(elt.get("pos")) + elif elt.get("position"): + return float_triple(elt.get("position")) + else: + return (0.0, 0.0, 0.0) + +def resolve_joints(names, skel_tree, lad_tree): + print "resolve joints, no_hud is",args.no_hud + if skel_tree and lad_tree: + all_elts = [elt for elt in skel_tree.getroot().iter()] + all_elts.extend([elt for elt in lad_tree.getroot().iter()]) + matches = [] + for elt in all_elts: + if elt.get("name") is None: + continue + print elt.get("name"),"hud",elt.get("hud") + if args.no_hud and elt.get("hud"): + print "skipping hud joint", elt.get("name") + continue + if elt.get("name") in names or elt.tag in names: + matches.append(elt.get("name")) + return list(set(matches)) + else: + return names + +if __name__ == "__main__": + + # default search location for config files is defined relative to + # the script location; assuming they live in the same viewer repo + pathname = os.path.dirname(sys.argv[0]) + path_to_skel = os.path.join(os.path.abspath(pathname),"..","..","indra","newview","character") + + parser = argparse.ArgumentParser(description="process SL animations") + parser.add_argument("--verbose", help="verbose flag", action="store_true") + parser.add_argument("--dump", help="dump to specified file") + parser.add_argument("--rot", help="specify sequence of rotations", type=float_triple, nargs="+") + parser.add_argument("--rand_pos", help="request random positions", action="store_true") + parser.add_argument("--reset_pos", help="request original positions", action="store_true") + parser.add_argument("--pos", help="specify sequence of positions", type=float_triple, nargs="+") + parser.add_argument("--num_pos", help="number of positions to create", type=int, default=2) + parser.add_argument("--delete_joints", help="specify joints to be deleted", nargs="+") + parser.add_argument("--joints", help="specify joints to be added or modified", nargs="+") + parser.add_argument("--summary", help="print summary of the output animation", action="store_true") + parser.add_argument("--skel", help="name of the avatar_skeleton file", default= os.path.join(path_to_skel,"avatar_skeleton.xml")) + parser.add_argument("--lad", help="name of the avatar_lad file", default= os.path.join(path_to_skel,"avatar_lad.xml")) + parser.add_argument("--set_version", nargs=2, type=int, help="set version and sub-version to specified values") + parser.add_argument("--no_hud", help="omit hud joints from list of attachments", action="store_true") + parser.add_argument("infilename", help="name of a .anim file to input") + parser.add_argument("outfilename", nargs="?", help="name of a .anim file to output") + args = parser.parse_args() + + print "anim_tool.py: " + " ".join(sys.argv) + print "dump is", args.dump + print "infilename",args.infilename,"outfilename",args.outfilename + print "rot",args.rot + print "pos",args.pos + print "joints",args.joints + + try: + anim = Anim(args.infilename) + skel_tree = None + lad_tree = None + joints = [] + if args.skel: + skel_tree = etree.parse(args.skel) + if skel_tree is None: + print "failed to parse",args.skel + exit(1) + if args.lad: + lad_tree = etree.parse(args.lad) + if lad_tree is None: + print "failed to parse",args.lad + exit(1) + if args.joints: + joints = resolve_joints(args.joints, skel_tree, lad_tree) + if args.verbose: + print "joints resolved to",joints + for name in joints: + anim.add_joint(name,0) + if args.delete_joints: + for name in args.delete_joints: + anim.delete_joint(name) + if joints and args.rot: + anim.add_rot(joints, args.rot) + if joints and args.pos: + anim.add_pos(joints, args.pos) + if joints and args.rand_pos: + for joint in joints: + pos_array = list(tuple(random.uniform(-1,1) for i in xrange(3)) for j in xrange(args.num_pos)) + pos_array.append(pos_array[0]) + anim.add_pos([joint], pos_array) + if joints and args.reset_pos: + for joint in joints: + elt = get_joint_by_name(skel_tree,joint) + if elt is None: + elt = get_joint_by_name(lad_tree,joint) + if elt is not None: + pos_array = [] + pos_array.append(get_elt_pos(elt)) + pos_array.append(pos_array[0]) + anim.add_pos([joint], pos_array) + else: + print "no elt or no pos data for",joint + if args.set_version: + anim.version = args.set_version[0] + anim.sub_version = args.set_version[1] + if args.dump: + anim.dump(args.dump) + if args.summary: + anim.summary() + if args.outfilename: + anim.write(args.outfilename) + except: + raise + diff --git a/scripts/content_tools/arche_tool.py b/scripts/content_tools/arche_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..23c96fc64ef40b605dbeb19a3dc9a09434986e3d --- /dev/null +++ b/scripts/content_tools/arche_tool.py @@ -0,0 +1,93 @@ +#!runpy.sh + +"""\ + +This module contains tools for comparing files output by LLVOAvatar::dumpArchetypeXML + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ +""" + +import argparse +from lxml import etree +from itertools import chain + +def node_key(e): + if e.tag == "param": + return e.tag + " " + e.get("id") + if e.tag == "texture": + return e.tag + " " + e.get("te") + if e.get("name"): + return e.tag + " " + e.get("name") + return None + +def compare_matched_nodes(key,items,summary): + tags = list(set([e.tag for e in items])) + if len(tags) != 1: + print "different tag types for key",key + summary.setdefault("tag_mismatch",0) + summary["tag_mismatch"] += 1 + return + all_attrib = list(set(chain.from_iterable([e.attrib.keys() for e in items]))) + #print key,"all_attrib",all_attrib + for attr in all_attrib: + vals = [e.get(attr) for e in items] + #print "key",key,"attr",attr,"vals",vals + if len(set(vals)) != 1: + print key,"- attr",attr,"multiple values",vals + summary.setdefault("attr",{}) + summary["attr"].setdefault(attr,0) + summary["attr"][attr] += 1 + +def compare_trees(file_trees): + print "compare_trees" + summary = {} + all_keys = list(set([node_key(e) for tree in file_trees for e in tree.getroot().iter() if node_key(e)])) + #print "keys",all_keys + tree_nodes = [] + for i,tree in enumerate(file_trees): + nodes = dict((node_key(e),e) for e in tree.getroot().iter() if node_key(e)) + tree_nodes.append(nodes) + for key in sorted(all_keys): + items = [] + for nodes in tree_nodes: + if not key in nodes: + print "file",i,"missing item for key",key + summary.setdefault("missing",0) + summary["missing"] += 1 + else: + items.append(nodes[key]) + compare_matched_nodes(key,items,summary) + print "Summary:" + print summary + + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(description="compare avatar XML archetype files") + parser.add_argument("--verbose", help="verbose flag", action="store_true") + parser.add_argument("files", nargs="+", help="name of one or more archtype files") + args = parser.parse_args() + + + print "files",args.files + file_trees = [etree.parse(filename) for filename in args.files] + compare_trees(file_trees) diff --git a/scripts/content_tools/dae_tool.py b/scripts/content_tools/dae_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..823f69cb854d1123cf1cb4a17c755e47ed78e3f6 --- /dev/null +++ b/scripts/content_tools/dae_tool.py @@ -0,0 +1,119 @@ +#!runpy.sh + +"""\ + +This module contains tools for manipulating collada files + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ +""" + +import argparse +import random + +# Need to pip install numpy and pycollada +import numpy as np +from collada import * +from lxml import etree + +def mesh_summary(mesh): + print "scenes",mesh.scenes + for scene in mesh.scenes: + print "scene",scene + for node in scene.nodes: + print "node",node + +def mesh_lock_offsets(tree, joints): + print "mesh_lock_offsets",tree,joints + for joint_node in tree.iter(): + if "node" not in joint_node.tag: + continue + if joint_node.get("type") != "JOINT": + continue + if joint_node.get("name") in joints or "bone" in joints: + for matrix_node in list(joint_node): + if "matrix" in matrix_node.tag: + floats = [float(x) for x in matrix_node.text.split()] + if len(floats) == 16: + floats[3] += 0.0001 + floats[7] += 0.0001 + floats[11] += 0.0001 + matrix_node.text = " ".join([str(f) for f in floats]) + print joint_node.get("name"),matrix_node.tag,"text",matrix_node.text,len(floats),floats + + +def mesh_random_offsets(tree, joints): + print "mesh_random_offsets",tree,joints + for joint_node in tree.iter(): + if "node" not in joint_node.tag: + continue + if joint_node.get("type") != "JOINT": + continue + if not joint_node.get("name"): + continue + if joint_node.get("name") in joints or "bone" in joints: + for matrix_node in list(joint_node): + if "matrix" in matrix_node.tag: + floats = [float(x) for x in matrix_node.text.split()] + print "randomizing",floats + if len(floats) == 16: + floats[3] += random.uniform(-1.0,1.0) + floats[7] += random.uniform(-1.0,1.0) + floats[11] += random.uniform(-1.0,1.0) + matrix_node.text = " ".join([str(f) for f in floats]) + print joint_node.get("name"),matrix_node.tag,"text",matrix_node.text,len(floats),floats + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="process SL animations") + parser.add_argument("--verbose", action="store_true",help="verbose flag") + parser.add_argument("infilename", help="name of a collada (dae) file to input") + parser.add_argument("outfilename", nargs="?", help="name of a collada (dae) file to output", default = None) + parser.add_argument("--lock_offsets", nargs="+", help="tweak position of listed joints to lock their offsets") + parser.add_argument("--random_offsets", nargs="+", help="random offset position for listed joints") + parser.add_argument("--summary", action="store_true", help="print summary info about input file") + args = parser.parse_args() + + mesh = None + tree = None + + if args.infilename: + print "reading",args.infilename + mesh = Collada(args.infilename) + tree = etree.parse(args.infilename) + + if args.summary: + print "summarizing",args.infilename + mesh_summary(mesh) + + if args.lock_offsets: + print "locking offsets for",args.lock_offsets + mesh_lock_offsets(tree, args.lock_offsets) + + if args.random_offsets: + print "adding random offsets for",args.random_offsets + mesh_random_offsets(tree, args.random_offsets) + + if args.outfilename: + print "writing",args.outfilename + f = open(args.outfilename,"w") + print >>f, etree.tostring(tree, pretty_print=True) #need update to get: , short_empty_elements=True) + diff --git a/scripts/content_tools/skel_tool.py b/scripts/content_tools/skel_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..26f63326f1d67822872c0405e746e22ef2df6691 --- /dev/null +++ b/scripts/content_tools/skel_tool.py @@ -0,0 +1,503 @@ +#!runpy.sh + +"""\ + +This module contains tools for manipulating and validating the avatar skeleton file. + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ +""" + +import argparse + +from lxml import etree + +def get_joint_names(tree): + joints = [element.get('name') for element in tree.getroot().iter() if element.tag in ['bone','collision_volume']] + print "joints:",joints + return joints + +def get_aliases(tree): + aliases = {} + alroot = tree.getroot() + for element in alroot.iter(): + for key in element.keys(): + if key == 'aliases': + name = element.get('name') + val = element.get('aliases') + aliases[name] = val + return aliases + +def fix_name(element): + pass + +def enforce_precision_rules(element): + pass + +def float_tuple(str, n=3): + try: + result = tuple(float(e) for e in str.split()) + if len(result)==n: + return result + else: + print "tuple length wrong:", str,"gave",result,"wanted len",n,"got len",len(result) + raise Exception() + except: + print "convert failed for:",str + raise + +def check_symmetry(name, field, vec1, vec2): + if vec1[0] != vec2[0]: + print name,field,"x match fail" + if vec1[1] != -vec2[1]: + print name,field,"y mirror image fail" + if vec1[2] != vec2[2]: + print name,field,"z match fail" + +def enforce_symmetry(tree, element, field, fix=False): + name = element.get("name") + if not name: + return + if "Right" in name: + left_name = name.replace("Right","Left") + left_element = get_element_by_name(tree, left_name) + pos = element.get(field) + left_pos = left_element.get(field) + pos_tuple = float_tuple(pos) + left_pos_tuple = float_tuple(left_pos) + check_symmetry(name,field,pos_tuple,left_pos_tuple) + +def get_element_by_name(tree,name): + if tree is None: + return None + matches = [elt for elt in tree.getroot().iter() if elt.get("name")==name] + if len(matches)==1: + return matches[0] + elif len(matches)>1: + print "multiple matches for name",name + return None + else: + return None + +def list_skel_tree(tree): + for element in tree.getroot().iter(): + if element.tag == "bone": + print element.get("name"),"-",element.get("support") + +def validate_child_order(tree, ogtree, fix=False): + unfixable = 0 + + #print "validate_child_order am failing for NO RAISIN!" + #unfixable += 1 + + tofix = set() + for element in tree.getroot().iter(): + if element.tag != "bone": + continue + og_element = get_element_by_name(ogtree,element.get("name")) + if og_element is not None: + for echild,ochild in zip(list(element),list(og_element)): + if echild.get("name") != ochild.get("name"): + print "Child ordering error, parent",element.get("name"),echild.get("name"),"vs",ochild.get("name") + if fix: + tofix.add(element.get("name")) + children = {} + for name in tofix: + print "FIX",name + element = get_element_by_name(tree,name) + og_element = get_element_by_name(ogtree,name) + children = [] + # add children matching the original joints first, in the same order + for og_elt in list(og_element): + elt = get_element_by_name(tree,og_elt.get("name")) + if elt is not None: + children.append(elt) + print "b:",elt.get("name") + else: + print "b missing:",og_elt.get("name") + # then add children that are not present in the original joints + for elt in list(element): + og_elt = get_element_by_name(ogtree,elt.get("name")) + if og_elt is None: + children.append(elt) + print "e:",elt.get("name") + # if we've done this right, we have a rearranged list of the same length + if len(children)!=len(element): + print "children",[e.get("name") for e in children] + print "element",[e.get("name") for e in element] + print "children changes for",name,", cannot reconcile" + else: + element[:] = children + + return unfixable + +# Checklist for the final file, started from SL-276: +# - new "end" attribute on all bones +# - new "connected" attribute on all bones +# - new "support" tag on all bones and CVs +# - aliases where appropriate for backward compatibility. rFoot and lFoot associated with mAnkle bones (not mFoot bones) +# - correct counts of bones and collision volumes in header +# - check all comments +# - old fields of old bones and CVs should be identical to their previous values. +# - old bones and CVs should retain their previous ordering under their parent, with new joints going later in any given child list +# - corresponding right and left joints should be mirror symmetric. +# - childless elements should be in short form (<bone /> instead of <bone></bone>) +# - digits of precision should be consistent (again, except for old joints) +# - new bones should have pos, pivot the same +def validate_skel_tree(tree, ogtree, reftree, fix=False): + print "validate_skel_tree" + (num_bones,num_cvs) = (0,0) + unfixable = 0 + defaults = {"connected": "false", + "group": "Face" + } + for element in tree.getroot().iter(): + og_element = get_element_by_name(ogtree,element.get("name")) + ref_element = get_element_by_name(reftree,element.get("name")) + # Preserve values from og_file: + for f in ["pos","rot","scale","pivot"]: + if og_element is not None and og_element.get(f) and (str(element.get(f)) != str(og_element.get(f))): + print element.get("name"),"field",f,"has changed:",og_element.get(f),"!=",element.get(f) + if fix: + element.set(f, og_element.get(f)) + + # Pick up any other fields that we can from ogtree and reftree + fields = [] + if element.tag in ["bone","collision_volume"]: + fields = ["support","group"] + if element.tag == 'bone': + fields.extend(["end","connected"]) + for f in fields: + if not element.get(f): + print element.get("name"),"missing required field",f + if fix: + if og_element is not None and og_element.get(f): + print "fix from ogtree" + element.set(f,og_element.get(f)) + elif ref_element is not None and ref_element.get(f): + print "fix from reftree" + element.set(f,ref_element.get(f)) + else: + if f in defaults: + print "fix by using default value",f,"=",defaults[f] + element.set(f,defaults[f]) + elif f == "support": + if og_element is not None: + element.set(f,"base") + else: + element.set(f,"extended") + else: + print "unfixable:",element.get("name"),"no value for field",f + unfixable += 1 + + fix_name(element) + enforce_precision_rules(element) + for field in ["pos","pivot"]: + enforce_symmetry(tree, element, field, fix) + if element.get("support")=="extended": + if element.get("pos") != element.get("pivot"): + print "extended joint",element.get("name"),"has mismatched pos, pivot" + + + if element.tag == "linden_skeleton": + num_bones = int(element.get("num_bones")) + num_cvs = int(element.get("num_collision_volumes")) + all_bones = [e for e in tree.getroot().iter() if e.tag=="bone"] + all_cvs = [e for e in tree.getroot().iter() if e.tag=="collision_volume"] + if num_bones != len(all_bones): + print "wrong bone count, expected",len(all_bones),"got",num_bones + if fix: + element.set("num_bones", str(len(all_bones))) + if num_cvs != len(all_cvs): + print "wrong cv count, expected",len(all_cvs),"got",num_cvs + if fix: + element.set("num_collision_volumes", str(len(all_cvs))) + + print "skipping child order code" + #unfixable += validate_child_order(tree, ogtree, fix) + + if fix and (unfixable > 0): + print "BAD FILE:", unfixable,"errs could not be fixed" + + +def slider_info(ladtree,skeltree): + for param in ladtree.iter("param"): + for skel_param in param.iter("param_skeleton"): + bones = [b for b in skel_param.iter("bone")] + if bones: + print "param",param.get("name"),"id",param.get("id") + value_min = float(param.get("value_min")) + value_max = float(param.get("value_max")) + neutral = 100.0 * (0.0-value_min)/(value_max-value_min) + print " neutral",neutral + for b in bones: + scale = float_tuple(b.get("scale","0 0 0")) + offset = float_tuple(b.get("offset","0 0 0")) + print " bone", b.get("name"), "scale", scale, "offset", offset + scale_min = [value_min * s for s in scale] + scale_max = [value_max * s for s in scale] + offset_min = [value_min * t for t in offset] + offset_max = [value_max * t for t in offset] + if (scale_min != scale_max): + print " Scale MinX", scale_min[0] + print " Scale MinY", scale_min[1] + print " Scale MinZ", scale_min[2] + print " Scale MaxX", scale_max[0] + print " Scale MaxY", scale_max[1] + print " Scale MaxZ", scale_max[2] + if (offset_min != offset_max): + print " Offset MinX", offset_min[0] + print " Offset MinY", offset_min[1] + print " Offset MinZ", offset_min[2] + print " Offset MaxX", offset_max[0] + print " Offset MaxY", offset_max[1] + print " Offset MaxZ", offset_max[2] + +# Check contents of avatar_lad file relative to a specified skeleton +def validate_lad_tree(ladtree,skeltree,orig_ladtree): + print "validate_lad_tree" + bone_names = [elt.get("name") for elt in skeltree.iter("bone")] + bone_names.append("mScreen") + bone_names.append("mRoot") + cv_names = [elt.get("name") for elt in skeltree.iter("collision_volume")] + #print "bones\n ","\n ".join(sorted(bone_names)) + #print "cvs\n ","\n ".join(sorted(cv_names)) + for att in ladtree.iter("attachment_point"): + att_name = att.get("name") + #print "attachment",att_name + joint_name = att.get("joint") + if not joint_name in bone_names: + print "att",att_name,"linked to invalid joint",joint_name + for skel_param in ladtree.iter("param_skeleton"): + skel_param_id = skel_param.get("id") + skel_param_name = skel_param.get("name") + #if not skel_param_name and not skel_param_id: + # print "strange skel_param" + # print etree.tostring(skel_param) + # for k,v in skel_param.attrib.iteritems(): + # print k,"->",v + for bone in skel_param.iter("bone"): + bone_name = bone.get("name") + if not bone_name in bone_names: + print "skel param references invalid bone",bone_name + print etree.tostring(bone) + bone_scale = float_tuple(bone.get("scale","0 0 0")) + bone_offset = float_tuple(bone.get("offset","0 0 0")) + param = bone.getparent().getparent() + if bone_scale==(0, 0, 0) and bone_offset==(0, 0, 0): + print "no-op bone",bone_name,"in param",param.get("id","-1") + # check symmetry of sliders + if "Right" in bone.get("name"): + left_name = bone_name.replace("Right","Left") + left_bone = None + for b in skel_param.iter("bone"): + if b.get("name")==left_name: + left_bone = b + if left_bone is None: + print "left_bone not found",left_name,"in",param.get("id","-1") + else: + left_scale = float_tuple(left_bone.get("scale","0 0 0")) + left_offset = float_tuple(left_bone.get("offset","0 0 0")) + if left_scale != bone_scale: + print "scale mismatch between",bone_name,"and",left_name,"in param",param.get("id","-1") + param_id = int(param.get("id","-1")) + if param_id in [661]: # shear + expected_offset = tuple([bone_offset[0],bone_offset[1],-bone_offset[2]]) + elif param_id in [30656, 31663, 32663]: # shift + expected_offset = bone_offset + else: + expected_offset = tuple([bone_offset[0],-bone_offset[1],bone_offset[2]]) + if left_offset != expected_offset: + print "offset mismatch between",bone_name,"and",left_name,"in param",param.get("id","-1") + + drivers = {} + for driven_param in ladtree.iter("driven"): + driver = driven_param.getparent().getparent() + driven_id = driven_param.get("id") + driver_id = driver.get("id") + actual_param = next(param for param in ladtree.iter("param") if param.get("id")==driven_id) + if not driven_id in drivers: + drivers[driven_id] = set() + drivers[driven_id].add(driver_id) + if (actual_param.get("value_min") != driver.get("value_min") or \ + actual_param.get("value_max") != driver.get("value_max")): + if args.verbose: + print "MISMATCH min max:",driver.get("id"),"drives",driven_param.get("id"),"min",driver.get("value_min"),actual_param.get("value_min"),"max",driver.get("value_max"),actual_param.get("value_max") + + for driven_id in drivers: + dset = drivers[driven_id] + if len(dset) != 1: + print "driven_id",driven_id,"has multiple drivers",dset + else: + if args.verbose: + print "driven_id",driven_id,"has one driver",dset + if orig_ladtree: + # make sure expected message format is unchanged + orig_message_params_by_id = dict((int(param.get("id")),param) for param in orig_ladtree.iter("param") if param.get("group") in ["0","3"]) + orig_message_ids = sorted(orig_message_params_by_id.keys()) + #print "orig_message_ids",orig_message_ids + message_params_by_id = dict((int(param.get("id")),param) for param in ladtree.iter("param") if param.get("group") in ["0","3"]) + message_ids = sorted(message_params_by_id.keys()) + #print "message_ids",message_ids + if (set(message_ids) != set(orig_message_ids)): + print "mismatch in message ids!" + print "added",set(message_ids) - set(orig_message_ids) + print "removed",set(orig_message_ids) - set(message_ids) + else: + print "message ids OK" + +def remove_joint_by_name(tree, name): + print "remove joint:",name + elt = get_element_by_name(tree,name) + while elt is not None: + children = list(elt) + parent = elt.getparent() + print "graft",[e.get("name") for e in children],"into",parent.get("name") + print "remove",elt.get("name") + #parent_children = list(parent) + loc = parent.index(elt) + parent[loc:loc+1] = children + elt[:] = [] + print "parent now:",[e.get("name") for e in list(parent)] + elt = get_element_by_name(tree,name) + +def compare_skel_trees(atree,btree): + diffs = {} + realdiffs = {} + a_missing = set() + b_missing = set() + a_names = set(e.get("name") for e in atree.getroot().iter() if e.get("name")) + b_names = set(e.get("name") for e in btree.getroot().iter() if e.get("name")) + print "a_names\n ",str("\n ").join(sorted(list(a_names))) + print + print "b_names\n ","\n ".join(sorted(list(b_names))) + all_names = set.union(a_names,b_names) + for name in all_names: + if not name: + continue + a_element = get_element_by_name(atree,name) + b_element = get_element_by_name(btree,name) + if a_element is None or b_element is None: + print "something not found for",name,a_element,b_element + if a_element is not None and b_element is not None: + all_attrib = set.union(set(a_element.attrib.keys()),set(b_element.attrib.keys())) + print name,all_attrib + for att in all_attrib: + if a_element.get(att) != b_element.get(att): + if not att in diffs: + diffs[att] = set() + diffs[att].add(name) + print "tuples",name,att,float_tuple(a_element.get(att)),float_tuple(b_element.get(att)) + if float_tuple(a_element.get(att)) != float_tuple(b_element.get(att)): + print "diff in",name,att + if not att in realdiffs: + realdiffs[att] = set() + realdiffs[att].add(name) + for att in diffs: + print "Differences in",att + for name in sorted(diffs[att]): + print " ",name + for att in realdiffs: + print "Real differences in",att + for name in sorted(diffs[att]): + print " ",name + a_missing = b_names.difference(a_names) + b_missing = a_names.difference(b_names) + if len(a_missing) or len(b_missing): + print "Missing from comparison" + for name in a_missing: + print " ",name + print "Missing from infile" + for name in b_missing: + print " ",name + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(description="process SL avatar_skeleton/avatar_lad files") + parser.add_argument("--verbose", action="store_true",help="verbose flag") + parser.add_argument("--ogfile", help="specify file containing base bones", default="avatar_skeleton_orig.xml") + parser.add_argument("--ref_file", help="specify another file containing replacements for missing fields") + parser.add_argument("--lad_file", help="specify avatar_lad file to check", default="avatar_lad.xml") + parser.add_argument("--orig_lad_file", help="specify avatar_lad file to compare to", default="avatar_lad_orig.xml") + parser.add_argument("--aliases", help="specify file containing bone aliases") + parser.add_argument("--validate", action="store_true", help="check specified input file for validity") + parser.add_argument("--fix", action="store_true", help="try to correct errors") + parser.add_argument("--remove", nargs="+", help="remove specified joints") + parser.add_argument("--list", action="store_true", help="list joint names") + parser.add_argument("--compare", help="alternate skeleton file to compare") + parser.add_argument("--slider_info", help="information about the lad file sliders and affected bones", action="store_true") + parser.add_argument("infilename", nargs="?", help="name of a skel .xml file to input", default="avatar_skeleton.xml") + parser.add_argument("outfilename", nargs="?", help="name of a skel .xml file to output") + args = parser.parse_args() + + tree = etree.parse(args.infilename) + + aliases = {} + if args.aliases: + altree = etree.parse(args.aliases) + aliases = get_aliases(altree) + + # Parse input files + ogtree = None + reftree = None + ladtree = None + orig_ladtree = None + + if args.ogfile: + ogtree = etree.parse(args.ogfile) + + if args.ref_file: + reftree = etree.parse(args.ref_file) + + if args.lad_file: + ladtree = etree.parse(args.lad_file) + + if args.orig_lad_file: + orig_ladtree = etree.parse(args.orig_lad_file) + + if args.remove: + for name in args.remove: + remove_joint_by_name(tree,name) + + # Do processing + if args.validate and ogtree: + validate_skel_tree(tree, ogtree, reftree) + + if args.validate and ladtree: + validate_lad_tree(ladtree, tree, orig_ladtree) + + if args.fix and ogtree: + validate_skel_tree(tree, ogtree, reftree, True) + + if args.list and tree: + list_skel_tree(tree) + + if args.compare and tree: + compare_tree = etree.parse(args.compare) + compare_skel_trees(compare_tree,tree) + + if ladtree and tree and args.slider_info: + slider_info(ladtree,tree) + + if args.outfilename: + f = open(args.outfilename,"w") + print >>f, etree.tostring(tree, pretty_print=True) #need update to get: , short_empty_elements=True) + diff --git a/scripts/packages-formatter.py b/scripts/packages-formatter.py index 928d340b69b3976e04d65f8b55df77c20483bcc2..f91f5819b790417b47a2601afc27906c50231902 100755 --- a/scripts/packages-formatter.py +++ b/scripts/packages-formatter.py @@ -29,6 +29,12 @@ import errno import re import subprocess +import argparse + +parser = argparse.ArgumentParser(description='Format dependency version and copyright information for the viewer About box content') +parser.add_argument('channel', help='viewer channel name') +parser.add_argument('version', help='viewer version number') +args = parser.parse_args() _autobuild=os.getenv('AUTOBUILD', 'autobuild') @@ -50,9 +56,8 @@ def autobuild(*args): # Don't attempt to interpret anything but ENOENT raise # Here it's ENOENT: subprocess can't find the autobuild executable. - print >>sys.stderr, "packages-formatter on %s: can't run autobuild:\n%s\n%s" % \ - (sys.platform, ' '.join(command), err) - sys.exit(1) + sys.exit("packages-formatter on %s: can't run autobuild:\n%s\n%s" % \ + (sys.platform, ' '.join(command), err)) # no exceptions yet, let caller read stdout return child.stdout @@ -84,6 +89,7 @@ def autobuild(*args): else: sys.exit("Unrecognized --copyrights output: %s" % line) +print "%s %s" % (args.channel, args.version) print viewer_copyright for pkg in sorted(version): print ': '.join([pkg, version[pkg]])