diff --git a/README b/README index 4a048e09c..a441bfedf 100644 --- a/README +++ b/README @@ -18,7 +18,7 @@ as those based upon the OpenSim platform. Singulariy is maintained by a small group of volunteers who can be contacted both, in-world (SingularityViewer group) as well on IRC (#SingularityViewer @ FreeNode). Bug requests and features requests can be submitted through our -Issue Tracket (http://code.google.com/p/singularity-viewer/issues/list or from +Issue Tracker (http://code.google.com/p/singularity-viewer/issues/list or from the viewer menu: Help --> Bug Reporting --> Singularity Issue Tracker...) @@ -33,6 +33,6 @@ As this Readme grows out of date, please refer to History The Singularity viewer was started by Siana Gearz in November 2010 by forking it -of the Ascent Viewer, by Balseraph Software Group, which in turn was based upon -source code released by Linden Lab. +from the Ascent Viewer, by Balseraph Software Group, which in turn was based upon +source code modified from the snowglobe source code released by Linden Lab. diff --git a/doc/contributions.txt b/doc/contributions.txt index 882dca18c..9eb4520cd 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -248,6 +248,7 @@ Celierra Darling VWR-6975 Cron Stardust VWR-10579 + STORM-1919 Cypren Christenson SNOW-129 SNOW-140 diff --git a/etc/message.xml b/etc/message.xml index 42bbef035..ea6fc8146 100644 --- a/etc/message.xml +++ b/etc/message.xml @@ -378,6 +378,14 @@ true + WindLightRefresh + + flavor + llsd + trusted-sender + true + + ParcelVoiceInfo flavor @@ -386,7 +394,6 @@ true - ParcelNavigateMedia flavor @@ -656,7 +663,7 @@ false RequestTextureDownload - false + true EventQueueGet false @@ -708,6 +715,9 @@ FetchLib2 true + + UploadBakedTexture + true messageBans diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 43d185b4f..cf777d652 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -48,6 +48,7 @@ add_custom_target(prepare DEPENDS ${prepare_depends}) add_subdirectory(cmake) add_subdirectory(${LIBS_OPEN_PREFIX}aistatemachine) add_subdirectory(${LIBS_OPEN_PREFIX}llaudio) +add_subdirectory(${LIBS_OPEN_PREFIX}llappearance) add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter) add_subdirectory(${LIBS_OPEN_PREFIX}llcommon) add_subdirectory(${LIBS_OPEN_PREFIX}llimage) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 5eaca5c32..f422ed4ae 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -29,7 +29,7 @@ if (WINDOWS) # Don't build DLLs. set(BUILD_SHARED_LIBS OFF) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /arch:SSE2" + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP /arch:SSE2" CACHE STRING "C++ compiler debug options" FORCE) set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /arch:SSE2" diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 2bb5ba88f..2fb187c18 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -41,6 +41,7 @@ set(cmake_SOURCE_FILES Hunspell.cmake JPEG.cmake LLAddBuildTest.cmake + LLAppearance.cmake LLAudio.cmake LLCharacter.cmake LLCommon.cmake diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake index 0a4bc0647..dbac0ebac 100644 --- a/indra/cmake/FMODEX.cmake +++ b/indra/cmake/FMODEX.cmake @@ -2,54 +2,52 @@ include(Linking) -if(INSTALL_PROPRIETARY) - include(Prebuilt) - use_prebuilt_binary(fmodex) -endif(INSTALL_PROPRIETARY) - -find_library(FMODEX_LIBRARY - NAMES fmodex fmodexL fmodex_vc fmodexL_vc - PATHS - optimized ${ARCH_PREBUILT_DIRS_RELEASE} - debug ${ARCH_PREBUILT_DIRS_DEBUG} - ) - if (NOT FMODEX_LIBRARY) set(FMODEX_SDK_DIR CACHE PATH "Path to the FMOD Ex SDK.") if (FMODEX_SDK_DIR) - find_library(FMODEX_LIBRARY - fmodex_vc fmodexL_vc fmodex fmodexL fmodex64 fmodexL64 - PATHS - ${FMODEX_SDK_DIR}/api/lib - ${FMODEX_SDK_DIR}/api - ${FMODEX_SDK_DIR}/lib - ${FMODEX_SDK_DIR} - ) - + if(WORD_SIZE EQUAL 32) + find_library(FMODEX_LIBRARY + fmodex_vc fmodexL_vc fmodex fmodexL + PATHS + "${FMODEX_SDK_DIR}/api/lib" + "${FMODEX_SDK_DIR}/api" + "${FMODEX_SDK_DIR}/lib" + "${FMODEX_SDK_DIR}" + ) + elseif(WORD_SIZE EQUAL 64) + find_library(FMODEX_LIBRARY + fmodex64 fmodexL64 + PATHS + "${FMODEX_SDK_DIR}/api/lib" + "${FMODEX_SDK_DIR}/api" + "${FMODEX_SDK_DIR}/lib" + "${FMODEX_SDK_DIR}" + ) + endif(WORD_SIZE EQUAL 32) endif(FMODEX_SDK_DIR) if(WINDOWS AND NOT FMODEX_LIBRARY) set(FMODEX_PROG_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows") find_library(FMODEX_LIBRARY fmodex_vc fmodexL_vc PATHS - ${FMODEX_PROG_DIR}/api/lib - ${FMODEX_PROG_DIR}/api - ${FMODEX_PROG_DIR} + "${FMODEX_PROG_DIR}/api/lib" + "${FMODEX_PROG_DIR}/api" + "${FMODEX_PROG_DIR}" ) if(FMODEX_LIBRARY) message(STATUS "Found fmodex in ${FMODEX_PROG_DIR}") - set(FMODEX_SDK_DIR ${FMODEX_PROG_DIR}) - set(FMODEX_SDK_DIR ${FMODEX_PROG_DIR} CACHE PATH "Path to the FMOD Ex SDK." FORCE) + set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}") + set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}" CACHE PATH "Path to the FMOD Ex SDK." FORCE) endif(FMODEX_LIBRARY) endif(WINDOWS AND NOT FMODEX_LIBRARY) endif (NOT FMODEX_LIBRARY) find_path(FMODEX_INCLUDE_DIR fmod.hpp - ${LIBS_PREBUILT_DIR}/include/fmodex - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/fmodex - ${FMODEX_SDK_DIR}/api/inc - ${FMODEX_SDK_DIR}/inc - ${FMODEX_SDK_DIR} + "${LIBS_PREBUILT_DIR}/include/fmodex" + "${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/fmodex" + "${FMODEX_SDK_DIR}/api/inc" + "${FMODEX_SDK_DIR}/inc" + "${FMODEX_SDK_DIR}" ) if(DARWIN) diff --git a/indra/cmake/FindJsonCpp.cmake b/indra/cmake/FindJsonCpp.cmake index 44ab0e769..a48c97396 100644 --- a/indra/cmake/FindJsonCpp.cmake +++ b/indra/cmake/FindJsonCpp.cmake @@ -3,16 +3,18 @@ # - Find JSONCpp # Find the JSONCpp includes and library # This module defines -# JSONCPP_INCLUDE_DIR, where to find json.h, etc. -# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp. -# JSONCPP_FOUND, If false, do not try to use jsoncpp. -# also defined, but not for general use are -# JSONCPP_LIBRARY, where to find the jsoncpp library. +# JSONCPP_FOUND, System has libjsoncpp. +# JSONCPP_INCLUDE_DIRS - The libjsoncpp include directories. +# JSONCPP_LIBRARIES - The libraries needed to use libjsoncpp. +# JSONCPP_DEFINITIONS - Compiler switches required for using libjsoncpp. -FIND_PATH(JSONCPP_INCLUDE_DIR json/json.h -/usr/local/include -/usr/include -) +FIND_PACKAGE(PkgConfig) +PKG_CHECK_MODULES(PC_JSONCPP jsoncpp) +SET(JSONCPP_DEFINITIONS ${PC_JSONCPP_CFLAGS_OTHER}) + +FIND_PATH(JSONCPP_INCLUDE_DIR json/reader.h + HINTS ${PC_JSONCPP_INCLUDE_DIR} ${PC_JSONCPP_INCLUDE_DIRS} + PATH_SUFFIXES jsoncpp) # Get the GCC compiler version EXEC_PROGRAM(${CMAKE_CXX_COMPILER} @@ -22,39 +24,16 @@ EXEC_PROGRAM(${CMAKE_CXX_COMPILER} ) # Try to find a library that was compiled with the same compiler version as we currently use. -SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so) -IF (STANDALONE) - # On standalone, assume that the system installed library was compiled with the used compiler. - SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson.so) -ENDIF (STANDALONE) FIND_LIBRARY(JSONCPP_LIBRARY - NAMES ${JSONCPP_NAMES} - PATHS /usr/lib /usr/local/lib - ) + NAMES libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so libjsoncpp.so + HINTS ${PC_JSONCPP_LIBDIR} ${PC_JSONCPP_LIBRARY_DIRS} + PATHS /usr/lib /usr/local/lib) -IF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR) - SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY}) - SET(JSONCPP_FOUND "YES") -ELSE (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR) - SET(JSONCPP_FOUND "NO") -ENDIF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR) +SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY}) +SET(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR}) +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(JSONCPP DEFAULT_MSG + JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR) -IF (JSONCPP_FOUND) - IF (NOT JSONCPP_FIND_QUIETLY) - MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}") - ENDIF (NOT JSONCPP_FIND_QUIETLY) -ELSE (JSONCPP_FOUND) - IF (JSONCPP_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find JSONCpp library") - ENDIF (JSONCPP_FIND_REQUIRED) -ENDIF (JSONCPP_FOUND) - -# Deprecated declarations. -SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARY} PATH) - -MARK_AS_ADVANCED( - JSONCPP_LIBRARY - JSONCPP_INCLUDE_DIR - ) +MARK_AS_ADVANCED(JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR) diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake index c102542e0..3ad669c94 100644 --- a/indra/cmake/GooglePerfTools.cmake +++ b/indra/cmake/GooglePerfTools.cmake @@ -11,10 +11,10 @@ else (STANDALONE) if (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64) use_prebuilt_binary(gperftools) endif (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64) - if (WINDOWS) + if (WINDOWS AND NOT DISABLE_TCMALLOC) set(TCMALLOC_LIBRARIES libtcmalloc_minimal.lib) set(TCMALLOC_LINKER_FLAGS "/INCLUDE:\"__tcmalloc\"") - endif (WINDOWS) + endif (WINDOWS AND NOT DISABLE_TCMALLOC) if (LINUX) if(USE_GOOGLE_PERFTOOLS) set(TCMALLOC_LIBRARIES tcmalloc) diff --git a/indra/cmake/JsonCpp.cmake b/indra/cmake/JsonCpp.cmake index 241db3570..2d7c16939 100644 --- a/indra/cmake/JsonCpp.cmake +++ b/indra/cmake/JsonCpp.cmake @@ -2,7 +2,7 @@ include(Prebuilt) -set(JSONCPP_FIND_QUIETLY ON) +set(JSONCPP_FIND_QUIETLY OFF) set(JSONCPP_FIND_REQUIRED ON) if (STANDALONE) diff --git a/indra/cmake/LLAppearance.cmake b/indra/cmake/LLAppearance.cmake new file mode 100644 index 000000000..ba0274a65 --- /dev/null +++ b/indra/cmake/LLAppearance.cmake @@ -0,0 +1,11 @@ +# -*- cmake -*- + +include(Variables) + +set(LLAPPEARANCE_INCLUDE_DIRS + ${LIBS_OPEN_DIR}/llappearance + ) + +set(LLAPPEARANCE_LIBRARIES llappearance) + + diff --git a/indra/cmake/OpenSSL.cmake b/indra/cmake/OpenSSL.cmake index 60cd40c8b..fffe868fd 100644 --- a/indra/cmake/OpenSSL.cmake +++ b/indra/cmake/OpenSSL.cmake @@ -4,9 +4,9 @@ include(Prebuilt) set(OpenSSL_FIND_QUIETLY ON) set(OpenSSL_FIND_REQUIRED ON) -if (STANDALONE) +if (STANDALONE OR USE_SYSTEM_OPENSSL) include(FindOpenSSL) -else (STANDALONE) +else (STANDALONE OR USE_SYSTEM_OPENSSL) use_prebuilt_binary(openSSL) if (WINDOWS) set(OPENSSL_LIBRARIES ssleay32 libeay32) @@ -14,7 +14,7 @@ else (STANDALONE) set(OPENSSL_LIBRARIES ssl) endif (WINDOWS) set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include) -endif (STANDALONE) +endif (STANDALONE OR USE_SYSTEM_OPENSSL) if (LINUX OR DARWIN) set(CRYPTO_LIBRARIES crypto) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index c6035597f..9e7d411a2 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -30,6 +30,7 @@ set(LIBS_SERVER_DIR ${CMAKE_SOURCE_DIR}/${LIBS_SERVER_PREFIX}) set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX}) set(SERVER_DIR ${CMAKE_SOURCE_DIR}/${SERVER_PREFIX}) set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX}) +set(DISABLE_TCMALLOC OFF CACHE BOOL "Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)") set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation)") set(VISTA_ICON OFF CACHE BOOL "Allow vista icon with pre 2008 Visual Studio IDEs. (Assumes replacement old rcdll.dll with new rcdll.dll from win sdk 7.0 or later)") diff --git a/indra/cwdebug/debug.cc b/indra/cwdebug/debug.cc index de14fa99f..17d86d77f 100644 --- a/indra/cwdebug/debug.cc +++ b/indra/cwdebug/debug.cc @@ -236,8 +236,10 @@ void stop_recording_backtraces(void) channel_ct backtrace DDCN("BACKTRACE"); //!< This debug channel is used for backtraces. channel_ct statemachine DDCN("STATEMACHINE"); //!< This debug channel is used for output related to class AIStateMachine. channel_ct caps DDCN("CAPS"); //!< This debug channel is used for output related to Capabilities. - channel_ct curl DDCN("CURL"); //!< This debug channel is used for output related to Curl. - channel_ct curlio DDCN("CURLIO"); //!< This debug channel is used to print debug output of libcurl. + channel_ct curl DDCN("CURL"); //!< This debug channel is used for output related to AICurl. + channel_ct curlio DDCN("CURLIO"); //!< This debug channel is used to print debug output of libcurl. This includes all HTTP network traffic. + channel_ct curltr DDCN("CURLTR"); //!< This debug channel is used to print libcurl API calls. + channel_ct snapshot DDCN("SNAPSHOT"); //!< This debug channel is used for output related to snapshots. } // namespace dc } // namespace DEBUGCHANNELS diff --git a/indra/cwdebug/debug.h b/indra/cwdebug/debug.h index 1deed2efb..329f0448e 100644 --- a/indra/cwdebug/debug.h +++ b/indra/cwdebug/debug.h @@ -207,6 +207,8 @@ extern CWD_API channel_ct statemachine; extern CWD_API channel_ct caps; extern CWD_API channel_ct curl; extern CWD_API channel_ct curlio; +extern CWD_API channel_ct curltr; +extern CWD_API channel_ct snapshot; #endif diff --git a/indra/develop.py b/indra/develop.py index 5e94ca125..a38758d39 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -782,13 +782,14 @@ Commands: Command-options for "configure": We use cmake variables to change the build configuration. - -DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc - -DVIEWER:BOOL=OFF Don't configure the viewer - -DPACKAGE:BOOL=ON Create "package" target to make installers - -DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language - -DLL_TESTS:BOOL=OFF Don't generate unit test projects - -DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project - -VISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!) + -DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc + -DVIEWER:BOOL=OFF Don't configure the viewer + -DPACKAGE:BOOL=ON Create "package" target to make installers + -DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language + -DLL_TESTS:BOOL=OFF Don't generate unit test projects + -DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project + -DDISABLE_TCMALLOC:BOOL=ON Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc) + -DVISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!) Examples: Set up a viewer-only project for your system: diff --git a/indra/libopenjpeg/CMakeLists.txt b/indra/libopenjpeg/CMakeLists.txt index 4325c7cc0..9ccc55126 100644 --- a/indra/libopenjpeg/CMakeLists.txt +++ b/indra/libopenjpeg/CMakeLists.txt @@ -7,14 +7,15 @@ include(00-Common) # OPENJPEG version number, useful for packaging and doxygen doc: set(OPENJPEG_VERSION_MAJOR 1) -set(OPENJPEG_VERSION_MINOR 4) -set(OPENJPEG_VERSION_BUILD 0) +set(OPENJPEG_VERSION_MINOR 5) +set(OPENJPEG_VERSION_BUILD 2) set(OPENJPEG_VERSION "${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}") set(openjpeg_SOURCE_FILES bio.c cio.c + cidx_manager.c dwt.c event.c image.c @@ -26,20 +27,26 @@ set(openjpeg_SOURCE_FILES mqc.c openjpeg.c pi.c + phix_manager.c + ppix_manager.c raw.c t1.c t2.c tcd.c tgt.c + thix_manager.c + tpix_manager.c ) set(openjpeg_HEADER_FILES bio.h cio.h + cidx_manager.h dwt.h - event.h + event.h fix.h image.h + indexbox_manager.h int.h j2k.h j2k_lib.h @@ -48,6 +55,7 @@ set(openjpeg_HEADER_FILES mct.h mqc.h openjpeg.h + opj_config.h opj_includes.h opj_malloc.h pi.h diff --git a/indra/libopenjpeg/cidx_manager.c b/indra/libopenjpeg/cidx_manager.c new file mode 100644 index 000000000..f3b251ffa --- /dev/null +++ b/indra/libopenjpeg/cidx_manager.c @@ -0,0 +1,211 @@ +/* + * $Id: cidx_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $ + * + * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2011, Professor Benoit Macq + * Copyright (c) 2003-2004, Yannick Verschueren + * Copyright (c) 2010-2011, Kaori Hagihara + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + + +/* + * Write CPTR Codestream finder box + * + * @param[in] coff offset of j2k codestream + * @param[in] clen length of j2k codestream + * @param[in] cio file output handle + */ +void write_cptr(int coff, int clen, opj_cio_t *cio); + + +/* + * Write main header index table (box) + * + * @param[in] coff offset of j2k codestream + * @param[in] cstr_info codestream information + * @param[in] cio file output handle + * @return length of mainmhix box + */ +int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio); + + +/* + * Check if EPH option is used + * + * @param[in] coff offset of j2k codestream + * @param[in] markers marker information + * @param[in] marknum number of markers + * @param[in] cio file output handle + * @return true if EPH is used + */ +opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio); + + +int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen) +{ + int len, i, lenp; + opj_jp2_box_t *box; + int num_box = 0; + opj_bool EPHused; + (void)image; /* unused ? */ + + lenp = -1; + box = (opj_jp2_box_t *)opj_calloc( 32, sizeof(opj_jp2_box_t)); + + for (i=0;i<2;i++){ + + if(i) + cio_seek( cio, lenp); + + lenp = cio_tell( cio); + + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_CIDX, 4); /* CIDX */ + write_cptr( offset, cstr_info.codestream_size, cio); + + write_manf( i, num_box, box, cio); + + num_box = 0; + box[num_box].length = write_mainmhix( offset, cstr_info, cio); + box[num_box].type = JPIP_MHIX; + num_box++; + + box[num_box].length = write_tpix( offset, cstr_info, j2klen, cio); + box[num_box].type = JPIP_TPIX; + num_box++; + + box[num_box].length = write_thix( offset, cstr_info, cio); + box[num_box].type = JPIP_THIX; + num_box++; + + EPHused = check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio); + + box[num_box].length = write_ppix( offset, cstr_info, EPHused, j2klen, cio); + box[num_box].type = JPIP_PPIX; + num_box++; + + box[num_box].length = write_phix( offset, cstr_info, EPHused, j2klen, cio); + box[num_box].type = JPIP_PHIX; + num_box++; + + len = cio_tell( cio)-lenp; + cio_seek( cio, lenp); + cio_write( cio, len, 4); /* L */ + cio_seek( cio, lenp+len); + } + + opj_free( box); + + return len; +} + +void write_cptr(int coff, int clen, opj_cio_t *cio) +{ + int len, lenp; + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_CPTR, 4); /* T */ + cio_write( cio, 0, 2); /* DR A PRECISER !! */ + cio_write( cio, 0, 2); /* CONT */ + cio_write( cio, coff, 8); /* COFF A PRECISER !! */ + cio_write( cio, clen, 8); /* CLEN */ + len = cio_tell( cio) - lenp; + cio_seek( cio, lenp); + cio_write( cio, len, 4); /* L */ + cio_seek( cio, lenp+len); +} + +void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio) +{ + int len, lenp, i; + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_MANF,4); /* T */ + + if (second){ /* Write only during the second pass */ + for( i=0; i> 2) & 1)) + EPHused = OPJ_TRUE; + cio_seek( cio, org_pos); + + break; + } + } + return EPHused; +} diff --git a/indra/libopenjpeg/cidx_manager.h b/indra/libopenjpeg/cidx_manager.h new file mode 100644 index 000000000..23eebd52b --- /dev/null +++ b/indra/libopenjpeg/cidx_manager.h @@ -0,0 +1,56 @@ +/* + * $Id: cidx_manager.h 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $ + * + * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2011, Professor Benoit Macq + * Copyright (c) 2003-2004, Yannick Verschueren + * Copyright (c) 2010-2011, Kaori Hagihara + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +/*! \file + * \brief Modification of jpip.h from 2KAN indexer + */ + + +#ifndef CIDX_MANAGER_H_ +# define CIDX_MANAGER_H_ + +#include "openjpeg.h" + + +/* + * Write Codestream index box (superbox) + * + * @param[in] offset offset of j2k codestream + * @param[in] cio file output handle + * @param[in] image image data + * @param[in] cstr_info codestream information + * @param[in] j2klen length of j2k codestream + * @return length of cidx box + */ +int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen); + + +#endif /* !CIDX_MANAGER_H_ */ diff --git a/indra/libopenjpeg/cio.c b/indra/libopenjpeg/cio.c index 2ac262a1f..c0cb02827 100644 --- a/indra/libopenjpeg/cio.c +++ b/indra/libopenjpeg/cio.c @@ -126,13 +126,13 @@ unsigned char *cio_getbp(opj_cio_t *cio) { /* * Write a byte. */ -bool cio_byteout(opj_cio_t *cio, unsigned char v) { +opj_bool cio_byteout(opj_cio_t *cio, unsigned char v) { if (cio->bp >= cio->end) { opj_event_msg(cio->cinfo, EVT_ERROR, "write error\n"); - return false; + return OPJ_FALSE; } *cio->bp++ = v; - return true; + return OPJ_TRUE; } /* @@ -152,7 +152,7 @@ unsigned char cio_bytein(opj_cio_t *cio) { * v : value to write * n : number of bytes to write */ -unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n) { +unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n) { int i; for (i = n - 1; i >= 0; i--) { if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) ) diff --git a/indra/libopenjpeg/cio.h b/indra/libopenjpeg/cio.h index 580bf9c0d..e62743141 100644 --- a/indra/libopenjpeg/cio.h +++ b/indra/libopenjpeg/cio.h @@ -31,6 +31,13 @@ #ifndef __CIO_H #define __CIO_H + +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define int64 __int64 +#else +#define int64 long long +#endif + /** @file cio.h @brief Implementation of a byte input-output process (CIO) @@ -63,7 +70,7 @@ Write some bytes @param n Number of bytes to write @return Returns the number of bytes written or 0 if an error occured */ -unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n); +unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n); /** Read some bytes @param cio CIO handle diff --git a/indra/libopenjpeg/dwt.c b/indra/libopenjpeg/dwt.c index 1d952c608..0fbfc2033 100644 --- a/indra/libopenjpeg/dwt.c +++ b/indra/libopenjpeg/dwt.c @@ -64,12 +64,12 @@ typedef struct v4dwt_local { int cas ; } v4dwt_t ; -static const float dwt_alpha = 1.586134342f; // 12994 -static const float dwt_beta = 0.052980118f; // 434 -static const float dwt_gamma = -0.882911075f; // -7233 -static const float dwt_delta = -0.443506852f; // -3633 +static const float dwt_alpha = 1.586134342f; /* 12994 */ +static const float dwt_beta = 0.052980118f; /* 434 */ +static const float dwt_gamma = -0.882911075f; /* -7233 */ +static const float dwt_delta = -0.443506852f; /* -3633 */ -static const float K = 1.230174105f; // 10078 +static const float K = 1.230174105f; /* 10078 */ /* FIXME: What is this constant? */ static const float c13318 = 1.625732422f; @@ -527,7 +527,7 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1 int w = tilec->x1 - tilec->x0; - h.mem = (int *)opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int)); + h.mem = (int*)opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int)); v.mem = h.mem; while( --numres) { @@ -570,7 +570,7 @@ static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, in int count = w->sn; int i, k; for(k = 0; k < 2; ++k){ - if (count + 3 * x < size && ((long) a & 0x0f) == 0 && ((long) bi & 0x0f) == 0 && (x & 0x0f) == 0) { + if (count + 3 * x < size && ((size_t) a & 0x0f) == 0 && ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0) { /* Fast code path */ for(i = 0; i < count; ++i){ int j = i; diff --git a/indra/libopenjpeg/event.c b/indra/libopenjpeg/event.c index 000b8a81c..38db33a94 100644 --- a/indra/libopenjpeg/event.c +++ b/indra/libopenjpeg/event.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2005, Herve Drolon, FreeImage Team * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,6 +26,42 @@ #include "opj_includes.h" +/* ========================================================== + Utility functions + ==========================================================*/ + +#ifdef OPJ_CODE_NOT_USED +#ifndef _WIN32 +static char* +i2a(unsigned i, char *a, unsigned r) { + if (i/r > 0) a = i2a(i/r,a,r); + *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r]; + return a+1; +} + +/** + Transforms integer i into an ascii string and stores the result in a; + string is encoded in the base indicated by r. + @param i Number to be converted + @param a String result + @param r Base of value; must be in the range 2 - 36 + @return Returns a +*/ +static char * +_itoa(int i, char *a, int r) { + r = ((r < 2) || (r > 36)) ? 10 : r; + if(i < 0) { + *a = '-'; + *i2a(-i, a+1, r) = 0; + } + else *i2a(i, a, r) = 0; + return a; +} + +#endif /* !_WIN32 */ +#endif +/* ----------------------------------------------------------------------- */ + opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context) { if(cinfo) { opj_event_mgr_t *previous = cinfo->event_mgr; @@ -37,7 +73,7 @@ opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_ return NULL; } -bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) { +opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) { #define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */ opj_msg_callback msg_handler = NULL; @@ -57,30 +93,29 @@ bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) { break; } if(msg_handler == NULL) { - return false; + return OPJ_FALSE; } } else { - return false; + return OPJ_FALSE; } if ((fmt != NULL) && (event_mgr != NULL)) { va_list arg; int str_length/*, i, j*/; /* UniPG */ char message[MSG_SIZE]; - memset(message, 0, MSG_SIZE); /* initialize the optional parameter list */ va_start(arg, fmt); - /* check the length of the format string */ - str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt); /* parse the format string and put the result in 'message' */ - vsprintf(message, fmt, arg); /* UniPG */ + str_length = vsnprintf(message, MSG_SIZE, fmt, arg); /* UniPG */ /* deinitialize the optional parameter list */ va_end(arg); /* output the message to the user program */ - msg_handler(message, cinfo->client_data); + if( str_length > -1 && str_length < MSG_SIZE ) + msg_handler(message, cinfo->client_data); + else return OPJ_FALSE; } - return true; + return OPJ_TRUE; } diff --git a/indra/libopenjpeg/event.h b/indra/libopenjpeg/event.h index 11910b0e4..9c59787ca 100644 --- a/indra/libopenjpeg/event.h +++ b/indra/libopenjpeg/event.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2005, Herve Drolon, FreeImage Team * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,7 +49,7 @@ Write formatted data to a string and send the string to a user callback. @param fmt Format-control string (plus optionnal arguments) @return Returns true if successful, returns false otherwise */ -bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...); +opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...); /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/indra/libopenjpeg/image.c b/indra/libopenjpeg/image.c index 5c89346f6..a4d2c010a 100644 --- a/indra/libopenjpeg/image.c +++ b/indra/libopenjpeg/image.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Herv Drolon, FreeImage Team + * Copyright (c) 2005, Herve Drolon, FreeImage Team * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,7 +28,6 @@ opj_image_t* opj_image_create0(void) { opj_image_t *image = (opj_image_t*)opj_calloc(1, sizeof(opj_image_t)); - image->comps=NULL; return image; } diff --git a/indra/libopenjpeg/image.h b/indra/libopenjpeg/image.h index 04c362eb8..f828b5b77 100644 --- a/indra/libopenjpeg/image.h +++ b/indra/libopenjpeg/image.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2005, Herve Drolon, FreeImage Team * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/indra/libopenjpeg/indexbox_manager.h b/indra/libopenjpeg/indexbox_manager.h new file mode 100644 index 000000000..7364df62c --- /dev/null +++ b/indra/libopenjpeg/indexbox_manager.h @@ -0,0 +1,118 @@ +/* + * $Id: indexbox_manager.h 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $ + * + * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2011, Professor Benoit Macq + * Copyright (c) 2003-2004, Yannick Verschueren + * Copyright (c) 2010-2011, Kaori Hagihara + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +/*! \file + * \brief Modification of jpip.c from 2KAN indexer + */ + +#ifndef INDEXBOX_MANAGER_H_ +# define INDEXBOX_MANAGER_H_ + +#include "openjpeg.h" +#include "j2k.h" /* needed to use jp2.h */ +#include "jp2.h" + +#define JPIP_CIDX 0x63696478 /* Codestream index */ +#define JPIP_CPTR 0x63707472 /* Codestream Finder Box */ +#define JPIP_MANF 0x6d616e66 /* Manifest Box */ +#define JPIP_FAIX 0x66616978 /* Fragment array Index box */ +#define JPIP_MHIX 0x6d686978 /* Main Header Index Table */ +#define JPIP_TPIX 0x74706978 /* Tile-part Index Table box */ +#define JPIP_THIX 0x74686978 /* Tile header Index Table box */ +#define JPIP_PPIX 0x70706978 /* Precinct Packet Index Table box */ +#define JPIP_PHIX 0x70686978 /* Packet Header index Table */ +#define JPIP_FIDX 0x66696478 /* File Index */ +#define JPIP_FPTR 0x66707472 /* File Finder */ +#define JPIP_PRXY 0x70727879 /* Proxy boxes */ +#define JPIP_IPTR 0x69707472 /* Index finder box */ +#define JPIP_PHLD 0x70686c64 /* Place holder */ + + +/* + * Write tile-part Index table box (superbox) + * + * @param[in] coff offset of j2k codestream + * @param[in] cstr_info codestream information + * @param[in] j2klen length of j2k codestream + * @param[in] cio file output handle + * @return length of tpix box + */ +int write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio); + + +/* + * Write tile header index table box (superbox) + * + * @param[in] coff offset of j2k codestream + * @param[in] cstr_info codestream information pointer + * @param[in] cio file output handle + * @return length of thix box + */ +int write_thix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio); + + +/* + * Write precinct packet index table box (superbox) + * + * @param[in] coff offset of j2k codestream + * @param[in] cstr_info codestream information + * @param[in] EPHused true if EPH option used + * @param[in] j2klen length of j2k codestream + * @param[in] cio file output handle + * @return length of ppix box + */ +int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio); + + +/* + * Write packet header index table box (superbox) + * + * @param[in] coff offset of j2k codestream + * @param[in] cstr_info codestream information + * @param[in] EPHused true if EPH option used + * @param[in] j2klen length of j2k codestream + * @param[in] cio file output handle + * @return length of ppix box + */ +int write_phix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio); + +/* + * Wriet manifest box (box) + * + * @param[in] second number to be visited + * @param[in] v number of boxes + * @param[in] box box to be manifested + * @param[in] cio file output handle + */ +void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio); + + +#endif /* !INDEXBOX_MANAGER_H_ */ diff --git a/indra/libopenjpeg/j2k.c b/indra/libopenjpeg/j2k.c index b4e9f5aba..21b462a34 100644 --- a/indra/libopenjpeg/j2k.c +++ b/indra/libopenjpeg/j2k.c @@ -6,6 +6,7 @@ * 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) 2010-2011, Kaori Hagihara * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -228,6 +229,23 @@ Read an unknown marker @param j2k J2K handle */ static void j2k_read_unk(opj_j2k_t *j2k); +/** +Add main header marker information +@param cstr_info Codestream information structure +@param type marker type +@param pos byte offset of marker segment +@param len length of marker segment + */ +static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len); +/** +Add tile header marker information +@param tileno tile index number +@param cstr_info Codestream information structure +@param type marker type +@param pos byte offset of marker segment +@param len length of marker segment + */ +static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len); /*@}*/ @@ -258,80 +276,6 @@ char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){ return po->str_prog; } -void j2k_dump_image(FILE *fd, opj_image_t * img) { - int compno; - fprintf(fd, "image {\n"); - fprintf(fd, " x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0, img->x1, img->y1); - fprintf(fd, " numcomps=%d\n", img->numcomps); - for (compno = 0; compno < img->numcomps; compno++) { - opj_image_comp_t *comp = &img->comps[compno]; - fprintf(fd, " comp %d {\n", compno); - fprintf(fd, " dx=%d, dy=%d\n", comp->dx, comp->dy); - fprintf(fd, " prec=%d\n", comp->prec); - //fprintf(fd, " bpp=%d\n", comp->bpp); - fprintf(fd, " sgnd=%d\n", comp->sgnd); - fprintf(fd, " }\n"); - } - fprintf(fd, "}\n"); -} - -void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) { - int tileno, compno, layno, bandno, resno, numbands; - fprintf(fd, "coding parameters {\n"); - fprintf(fd, " tx0=%d, ty0=%d\n", cp->tx0, cp->ty0); - fprintf(fd, " tdx=%d, tdy=%d\n", cp->tdx, cp->tdy); - fprintf(fd, " tw=%d, th=%d\n", cp->tw, cp->th); - for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { - opj_tcp_t *tcp = &cp->tcps[tileno]; - fprintf(fd, " tile %d {\n", tileno); - fprintf(fd, " csty=%x\n", tcp->csty); - fprintf(fd, " prg=%d\n", tcp->prg); - fprintf(fd, " numlayers=%d\n", tcp->numlayers); - fprintf(fd, " mct=%d\n", tcp->mct); - fprintf(fd, " rates="); - for (layno = 0; layno < tcp->numlayers; layno++) { - fprintf(fd, "%.1f ", tcp->rates[layno]); - } - fprintf(fd, "\n"); - for (compno = 0; compno < img->numcomps; compno++) { - opj_tccp_t *tccp = &tcp->tccps[compno]; - fprintf(fd, " comp %d {\n", compno); - fprintf(fd, " csty=%x\n", tccp->csty); - fprintf(fd, " numresolutions=%d\n", tccp->numresolutions); - fprintf(fd, " cblkw=%d\n", tccp->cblkw); - fprintf(fd, " cblkh=%d\n", tccp->cblkh); - fprintf(fd, " cblksty=%x\n", tccp->cblksty); - fprintf(fd, " qmfbid=%d\n", tccp->qmfbid); - fprintf(fd, " qntsty=%d\n", tccp->qntsty); - fprintf(fd, " numgbits=%d\n", tccp->numgbits); - fprintf(fd, " roishift=%d\n", tccp->roishift); - fprintf(fd, " stepsizes="); - numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2; - for (bandno = 0; bandno < numbands; bandno++) { - fprintf(fd, "(%d,%d) ", tccp->stepsizes[bandno].mant, - tccp->stepsizes[bandno].expn); - } - fprintf(fd, "\n"); - - if (tccp->csty & J2K_CCP_CSTY_PRT) { - fprintf(fd, " prcw="); - for (resno = 0; resno < tccp->numresolutions; resno++) { - fprintf(fd, "%d ", tccp->prcw[resno]); - } - fprintf(fd, "\n"); - fprintf(fd, " prch="); - for (resno = 0; resno < tccp->numresolutions; resno++) { - fprintf(fd, "%d ", tccp->prch[resno]); - } - fprintf(fd, "\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, "}\n"); -} - /* ----------------------------------------------------------------------- */ static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){ char *prog; @@ -371,6 +315,9 @@ static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){ /** mem allocation for TLM marker*/ int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t *j2k ){ int pino,tileno,totnum_tp=0; + + OPJ_ARG_NOT_USED(img_numcomp); + j2k->cur_totnum_tp = (int *) opj_malloc(cp->tw * cp->th * sizeof(int)); for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { int cur_totnum_tp = 0; @@ -399,12 +346,14 @@ static void j2k_write_soc(opj_j2k_t *j2k) { opj_cio_t *cio = j2k->cio; cio_write(cio, J2K_MS_SOC, 2); + if(j2k->cstr_info) + j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio), 0); + /* UniPG>> */ #ifdef USE_JPWL /* update markers struct */ j2k_add_marker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio) - 2, 2); - #endif /* USE_JPWL */ /* <cio; opj_image_t *image = j2k->image; opj_cp_t *cp = j2k->cp; - + cio_write(cio, J2K_MS_SIZ, 2); /* SIZ */ lenp = cio_tell(cio); cio_skip(cio, 2); @@ -448,6 +397,9 @@ static void j2k_write_siz(opj_j2k_t *j2k) { cio_seek(cio, lenp); cio_write(cio, len, 2); /* Lsiz */ cio_seek(cio, lenp + len); + + if(j2k->cstr_info) + j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SIZ, lenp, len); } static void j2k_read_siz(opj_j2k_t *j2k) { @@ -516,6 +468,12 @@ static void j2k_read_siz(opj_j2k_t *j2k) { } #endif /* USE_JPWL */ + /* prevent division by zero */ + if (!(cp->tdx * cp->tdy)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: invalid tile size (tdx: %d, tdy: %d)\n", cp->tdx, cp->tdy); + return; + } + image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t)); for (i = 0; i < image->numcomps; i++) { int tmp, w, h; @@ -554,6 +512,12 @@ static void j2k_read_siz(opj_j2k_t *j2k) { } #endif /* USE_JPWL */ + /* prevent division by zero */ + if (!(image->comps[i].dx * image->comps[i].dy)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: invalid component size (dx: %d, dy: %d)\n", image->comps[i].dx, image->comps[i].dy); + return; + } + /* TODO: unused ? */ w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx); h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy); @@ -606,7 +570,17 @@ static void j2k_read_siz(opj_j2k_t *j2k) { #endif /* USE_JPWL */ cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t)); + if (cp->tcps == NULL) + { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n"); + return; + } cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int)); + if (cp->tileno == NULL) + { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n"); + return; + } cp->tileno_size = 0; #ifdef USE_JPWL @@ -678,6 +652,11 @@ static void j2k_write_com(opj_j2k_t *j2k) { cio_seek(cio, lenp); cio_write(cio, len, 2); cio_seek(cio, lenp + len); + + + if(j2k->cstr_info) + j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COM, lenp, len); + } } @@ -721,12 +700,18 @@ static void j2k_read_cox(opj_j2k_t *j2k, int compno) { tccp->numresolutions = cio_read(cio, 1) + 1; /* SPcox (D) */ - // If user wants to remove more resolutions than the codestream contains, return error + /* If user wants to remove more resolutions than the codestream contains, return error*/ if (cp->reduce >= tccp->numresolutions) { opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number " - "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno); + "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno); j2k->state |= J2K_STATE_ERR; } + if( tccp->numresolutions > J2K_MAXRLVLS ) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions is too big: %d vs max= %d. Truncating.\n\n", + compno, tccp->numresolutions, J2K_MAXRLVLS); + j2k->state |= J2K_STATE_ERR; + tccp->numresolutions = J2K_MAXRLVLS; + } tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */ tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */ @@ -781,6 +766,10 @@ static void j2k_write_cod(opj_j2k_t *j2k) { cio_seek(cio, lenp); cio_write(cio, len, 2); /* Lcod */ cio_seek(cio, lenp + len); + + if(j2k->cstr_info) + j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COD, lenp, len); + } static void j2k_read_cod(opj_j2k_t *j2k) { @@ -846,6 +835,12 @@ static void j2k_read_coc(opj_j2k_t *j2k) { len = cio_read(cio, 2); /* Lcoc */ compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2); /* Ccoc */ + if (compno >= image->numcomps) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "bad component number in COC (%d out of a maximum of %d)\n", + compno, image->numcomps); + return; + } tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */ j2k_read_cox(j2k, compno); } @@ -909,6 +904,15 @@ static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) { }; }; + +#else + /* We check whether there are too many subbands */ + if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) { + opj_event_msg(j2k->cinfo, EVT_WARNING , + "bad number of subbands in Sqcx (%d) regarding to J2K_MAXBANDS (%d) \n" + "- limiting number of bands to J2K_MAXBANDS and try to move to the next markers\n", numbands, J2K_MAXBANDS); + } + #endif /* USE_JPWL */ for (bandno = 0; bandno < numbands; bandno++) { @@ -921,8 +925,10 @@ static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) { expn = tmp >> 11; mant = tmp & 0x7ff; } - tccp->stepsizes[bandno].expn = expn; - tccp->stepsizes[bandno].mant = mant; + if (bandno < J2K_MAXBANDS){ + tccp->stepsizes[bandno].expn = expn; + tccp->stepsizes[bandno].mant = mant; + } } /* Add Antonin : if scalar_derived -> compute other stepsizes */ @@ -950,6 +956,9 @@ static void j2k_write_qcd(opj_j2k_t *j2k) { cio_seek(cio, lenp); cio_write(cio, len, 2); /* Lqcd */ cio_seek(cio, lenp + len); + + if(j2k->cstr_info) + j2k_add_mhmarker(j2k->cstr_info, J2K_MS_QCD, lenp, len); } static void j2k_read_qcd(opj_j2k_t *j2k) { @@ -986,7 +995,7 @@ static void j2k_read_qcc(opj_j2k_t *j2k) { int len, compno; int numcomp = j2k->image->numcomps; opj_cio_t *cio = j2k->cio; - + len = cio_read(cio, 2); /* Lqcc */ compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */ @@ -1013,9 +1022,16 @@ static void j2k_read_qcc(opj_j2k_t *j2k) { /* keep your private count of tiles */ backup_compno++; - }; + } #endif /* USE_JPWL */ + if ((compno < 0) || (compno >= numcomp)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "bad component number in QCC (%d out of a maximum of %d)\n", + compno, j2k->image->numcomps); + return; + } + j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2)); } @@ -1271,6 +1287,10 @@ static void j2k_write_sot(opj_j2k_t *j2k) { j2k_add_marker(j2k->cstr_info, J2K_MS_SOT, j2k->sot_start, len + 2); #endif /* USE_JPWL */ /* <cstr_info && j2k->cur_tp_num==0){ + j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOT, lenp, len); + } } static void j2k_read_sot(opj_j2k_t *j2k) { @@ -1354,6 +1374,11 @@ static void j2k_read_sot(opj_j2k_t *j2k) { partno = cio_read(cio, 1); numparts = cio_read(cio, 1); + + if (partno >= numparts) { + opj_event_msg(j2k->cinfo, EVT_WARNING, "SOT marker inconsistency in tile %d: tile-part index greater (%d) than number of tile-parts (%d)\n", tileno, partno, numparts); + numparts = partno+1; + } j2k->curtileno = tileno; j2k->cur_tp_num = partno; @@ -1369,15 +1394,14 @@ static void j2k_read_sot(opj_j2k_t *j2k) { j2k->cstr_info->tile[tileno].tileno = tileno; j2k->cstr_info->tile[tileno].start_pos = cio_tell(cio) - 12; j2k->cstr_info->tile[tileno].end_pos = j2k->cstr_info->tile[tileno].start_pos + totlen - 1; - j2k->cstr_info->tile[tileno].num_tps = numparts; - if (numparts) - j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t)); - else - j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(10 * sizeof(opj_tp_info_t)); // Fixme (10) - } - else { + } else { j2k->cstr_info->tile[tileno].end_pos += totlen; - } + } + j2k->cstr_info->tile[tileno].num_tps = numparts; + if (numparts) + j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, numparts * sizeof(opj_tp_info_t)); + else + j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, 10 * sizeof(opj_tp_info_t)); /* Fixme (10)*/ j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = cio_tell(cio) - 12; j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos = j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1; @@ -1413,6 +1437,11 @@ static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) { tcd->cur_tp_num = j2k->cur_tp_num; cio_write(cio, J2K_MS_SOD, 2); + + if( j2k->cstr_info && j2k->cur_tp_num==0){ + j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOD, cio_tell(cio), 0); + } + if (j2k->curtileno == 0) { j2k->sod_start = cio_tell(cio) + j2k->pos_correction; } @@ -1487,7 +1516,7 @@ static void j2k_read_sod(opj_j2k_t *j2k) { if (len == cio_numbytesleft(cio) + 1) { truncate = 1; /* Case of a truncate codestream */ - } + } data = j2k->tile_data[curtileno]; data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char)); @@ -1548,6 +1577,13 @@ static void j2k_read_rgn(opj_j2k_t *j2k) { }; #endif /* USE_JPWL */ + if (compno >= numcomps) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "bad component number in RGN (%d out of a maximum of %d)\n", + compno, j2k->image->numcomps); + return; + } + tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */ } @@ -1566,7 +1602,7 @@ static void j2k_write_eoc(opj_j2k_t *j2k) { static void j2k_read_eoc(opj_j2k_t *j2k) { int i, tileno; - bool success; + opj_bool success = OPJ_FALSE; /* if packets should be decoded */ if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) { @@ -1574,12 +1610,17 @@ static void j2k_read_eoc(opj_j2k_t *j2k) { tcd_malloc_decode(tcd, j2k->image, j2k->cp); for (i = 0; i < j2k->cp->tileno_size; i++) { tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info); - tileno = j2k->cp->tileno[i]; - success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); - opj_free(j2k->tile_data[tileno]); - j2k->tile_data[tileno] = NULL; - tcd_free_decode_tile(tcd, i); - if (success == false) { + if (j2k->cp->tileno[i] != -1) + { + tileno = j2k->cp->tileno[i]; + success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); + opj_free(j2k->tile_data[tileno]); + j2k->tile_data[tileno] = NULL; + tcd_free_decode_tile(tcd, i); + } + else + success = OPJ_FALSE; + if (success == OPJ_FALSE) { j2k->state |= J2K_STATE_ERR; break; } @@ -1749,6 +1790,14 @@ void j2k_destroy_decompress(opj_j2k_t *j2k) { opj_free(j2k->tile_len); } if(j2k->tile_data != NULL) { + if(j2k->cp != NULL) { + for (i = 0; i < j2k->cp->tileno_size; i++) { + int tileno = j2k->cp->tileno[i]; + opj_free(j2k->tile_data[tileno]); + j2k->tile_data[tileno] = NULL; + } + } + opj_free(j2k->tile_data); } if(j2k->default_tcp != NULL) { @@ -1834,7 +1883,7 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c if (j2k->cp->correct) { int orig_pos = cio_tell(cio); - bool status; + opj_bool status; /* call the corrector */ status = jpwl_correct(j2k); @@ -1873,13 +1922,13 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c return 0; } e = j2k_dec_mstab_lookup(id); - // Check if the marker is known + /* Check if the marker is known*/ if (!(j2k->state & e->states)) { opj_image_destroy(image); opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); return 0; } - // Check if the decoding is limited to the main header + /* Check if the decoding is limited to the main header*/ if (e->id == J2K_MS_SOT && j2k->cp->limit_decoding == LIMIT_TO_MAIN_HEADER) { opj_event_msg(cinfo, EVT_INFO, "Main Header decoded.\n"); return image; @@ -1889,7 +1938,10 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c (*e->handler)(j2k); } if (j2k->state & J2K_STATE_ERR) + { + opj_image_destroy(image); return NULL; + } if (j2k->state == J2K_STATE_MT) { break; @@ -1905,7 +1957,6 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c if (j2k->state != J2K_STATE_MT) { opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); } - return image; } @@ -1917,9 +1968,10 @@ opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestre opj_image_t *image = NULL; opj_jpt_msg_header_t header; int position; - opj_common_ptr cinfo = j2k->cinfo; - + + OPJ_ARG_NOT_USED(cstr_info); + j2k->cio = cio; /* create an empty image */ @@ -2110,12 +2162,12 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ int i; /* set JPWL on */ - cp->epc_on = true; - cp->info_on = false; /* no informative technique */ + cp->epc_on = OPJ_TRUE; + cp->info_on = OPJ_FALSE; /* no informative technique */ /* set EPB on */ if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) { - cp->epb_on = true; + cp->epb_on = OPJ_TRUE; cp->hprot_MH = parameters->jpwl_hprot_MH; for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { @@ -2136,7 +2188,7 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ /* set ESD writing */ if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) { - cp->esd_on = true; + cp->esd_on = OPJ_TRUE; cp->sens_size = parameters->jpwl_sens_size; cp->sens_addr = parameters->jpwl_sens_addr; @@ -2150,10 +2202,10 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ } /* always set RED writing to false: we are at the encoder */ - cp->red_on = false; + cp->red_on = OPJ_FALSE; } else { - cp->epc_on = false; + cp->epc_on = OPJ_FALSE; } #endif /* USE_JPWL */ @@ -2226,10 +2278,10 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ if(parameters->cp_cinema) { - //Precinct size for lowest frequency subband=128 + /*Precinct size for lowest frequency subband=128*/ tccp->prcw[0] = 7; tccp->prch[0] = 7; - //Precinct size at all other resolutions = 256 + /*Precinct size at all other resolutions = 256*/ for (j = 1; j < tccp->numresolutions; j++) { tccp->prcw[j] = 8; tccp->prch[j] = 8; @@ -2271,7 +2323,7 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ } p++; /*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */ - } //end for + } /*end for*/ } else { for (j = 0; j < tccp->numresolutions; j++) { tccp->prcw[j] = 15; @@ -2285,7 +2337,7 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ } } -bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { +opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { int tileno, compno; opj_cp_t *cp = NULL; @@ -2296,8 +2348,6 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre cp = j2k->cp; - /* j2k_dump_cp(stdout, image, cp); */ - /* INDEX >> */ j2k->cstr_info = cstr_info; if (cstr_info) { @@ -2394,6 +2444,9 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre /* INDEX >> */ if(cstr_info) { cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction; + cstr_info->tile[j2k->curtileno].maxmarknum = 10; + cstr_info->tile[j2k->curtileno].marker = (opj_marker_info_t *) opj_malloc(cstr_info->tile[j2k->curtileno].maxmarknum * sizeof(opj_marker_info_t)); + cstr_info->tile[j2k->curtileno].marknum = 0; } /* << INDEX */ @@ -2500,11 +2553,46 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre } #endif /* USE_JPWL */ - return true; + return OPJ_TRUE; } +static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) { + if (!cstr_info) + return; + /* expand the list? */ + if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) { + cstr_info->maxmarknum = 100 + (int) ((float) cstr_info->maxmarknum * 1.0F); + cstr_info->marker = (opj_marker_info_t*)opj_realloc(cstr_info->marker, cstr_info->maxmarknum); + } + /* add the marker */ + cstr_info->marker[cstr_info->marknum].type = type; + cstr_info->marker[cstr_info->marknum].pos = pos; + cstr_info->marker[cstr_info->marknum].len = len; + cstr_info->marknum++; +} +static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) { + + opj_marker_info_t *marker; + + if (!cstr_info) + return; + + /* expand the list? */ + if ((cstr_info->tile[tileno].marknum + 1) > cstr_info->tile[tileno].maxmarknum) { + cstr_info->tile[tileno].maxmarknum = 100 + (int) ((float) cstr_info->tile[tileno].maxmarknum * 1.0F); + cstr_info->tile[tileno].marker = (opj_marker_info_t*)opj_realloc(cstr_info->tile[tileno].marker, cstr_info->maxmarknum); + } + + marker = &(cstr_info->tile[tileno].marker[cstr_info->tile[tileno].marknum]); + + /* add the marker */ + marker->type = type; + marker->pos = pos; + marker->len = len; + cstr_info->tile[tileno].marknum++; +} diff --git a/indra/libopenjpeg/j2k.h b/indra/libopenjpeg/j2k.h index bb86e348e..6338c290d 100644 --- a/indra/libopenjpeg/j2k.h +++ b/indra/libopenjpeg/j2k.h @@ -265,15 +265,15 @@ typedef struct opj_cp { /* UniPG>> */ #ifdef USE_JPWL /** enables writing of EPC in MH, thus activating JPWL */ - bool epc_on; + opj_bool epc_on; /** enables writing of EPB, in case of activated JPWL */ - bool epb_on; + opj_bool epb_on; /** enables writing of ESD, in case of activated JPWL */ - bool esd_on; + opj_bool esd_on; /** enables writing of informative techniques of ESD, in case of activated JPWL */ - bool info_on; + opj_bool info_on; /** enables writing of RED, in case of activated JPWL */ - bool red_on; + opj_bool red_on; /** error protection method for MH (0,1,16,32,37-128) */ int hprot_MH; /** tile number of header protection specification (>=0) */ @@ -299,7 +299,7 @@ typedef struct opj_cp { /** sensitivity methods for TPHs (-1,0-7) */ int sens_TPH[JPWL_MAX_NO_TILESPECS]; /** enables JPWL correction at the decoder */ - bool correct; + opj_bool correct; /** expected number of components at the decoder */ int exp_comps; /** maximum number of tiles at the decoder */ @@ -436,10 +436,8 @@ Encode an image into a JPEG-2000 codestream @param cstr_info Codestream information structure if required, NULL otherwise @return Returns true if successful, returns false otherwise */ -bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); +opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); -void j2k_dump_image(FILE *fd, opj_image_t * img); -void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp); /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/indra/libopenjpeg/j2k_lib.c b/indra/libopenjpeg/j2k_lib.c index 91aee0071..a66e31e9a 100644 --- a/indra/libopenjpeg/j2k_lib.c +++ b/indra/libopenjpeg/j2k_lib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2005, Herve Drolon, FreeImage Team * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,18 +24,18 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifdef WIN32 +#ifdef _WIN32 #include #else #include #include #include -#endif /* WIN32 */ +#endif /* _WIN32 */ #include "opj_includes.h" double opj_clock(void) { -#ifdef WIN32 - /* WIN32: use QueryPerformance (very accurate) */ +#ifdef _WIN32 + /* _WIN32: use QueryPerformance (very accurate) */ LARGE_INTEGER freq , t ; /* freq is the clock speed of the CPU */ QueryPerformanceFrequency(&freq) ; diff --git a/indra/libopenjpeg/j2k_lib.h b/indra/libopenjpeg/j2k_lib.h index 7df4d3677..5f3406e51 100644 --- a/indra/libopenjpeg/j2k_lib.h +++ b/indra/libopenjpeg/j2k_lib.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2005, Herve Drolon, FreeImage Team * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/indra/libopenjpeg/jp2.c b/indra/libopenjpeg/jp2.c index b2831cfb0..531bbfc92 100644 --- a/indra/libopenjpeg/jp2.c +++ b/indra/libopenjpeg/jp2.c @@ -5,6 +5,7 @@ * 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) 2010-2011, Kaori Hagihara * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,7 +29,6 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ - #include "opj_includes.h" /** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */ @@ -44,7 +44,7 @@ Read box headers @param box @return Returns true if successful, returns false otherwise */ -static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box); +static opj_bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box); /*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/ /** Read the IHDR box - Image Header box @@ -52,12 +52,11 @@ Read the IHDR box - Image Header box @param cio Input buffer stream @return Returns true if successful, returns false otherwise */ -static bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio); +static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio); static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio); static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); -static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); +static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio); -static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio); /** Write the FTYP box - File type box @param jp2 JP2 handle @@ -70,9 +69,9 @@ Read the FTYP box - File type box @param cio Input buffer stream @return Returns true if successful, returns false otherwise */ -static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); +static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); -static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset); +static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset); static void jp2_write_jp(opj_cio_t *cio); /** Read the JP box - JPEG 2000 signature @@ -80,29 +79,92 @@ Read the JP box - JPEG 2000 signature @param cio Input buffer stream @return Returns true if successful, returns false otherwise */ -static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio); +static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio); /** Decode the structure of a JP2 file @param jp2 JP2 handle @param cio Input buffer stream +@param color Collector for profile, cdef and pclr data @return Returns true if successful, returns false otherwise */ -static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio); - +static opj_bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio, + opj_jp2_color_t *color); +/** +Apply collected palette data +@param color Collector for profile, cdef and pclr data +@param image +*/ +static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image, opj_common_ptr cinfo); +/** +Collect palette data +@param jp2 JP2 handle +@param cio Input buffer stream +@param box +@param color Collector for profile, cdef and pclr data +@return Returns true if successful, returns false otherwise +*/ +static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio, + opj_jp2_box_t *box, opj_jp2_color_t *color); +/** +Collect component mapping data +@param jp2 JP2 handle +@param cio Input buffer stream +@param box +@param color Collector for profile, cdef and pclr data +@return Returns true if successful, returns false otherwise +*/ +static opj_bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio, + opj_jp2_box_t *box, opj_jp2_color_t *color); +/** +Collect colour specification data +@param jp2 JP2 handle +@param cio Input buffer stream +@param box +@param color Collector for profile, cdef and pclr data +@return Returns true if successful, returns false otherwise +*/ +static opj_bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio, + opj_jp2_box_t *box, opj_jp2_color_t *color); +/** +Write file Index (superbox) +@param[in] offset_jp2c offset of jp2c box +@param[in] length_jp2c length of jp2c box +@param[in] offset_idx offset of cidx box +@param[in] length_idx length of cidx box +@param[in] cio file output handle +@return length of fidx box +*/ +static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio); +/** +Write index Finder box +@param[in] offset offset of fidx box +@param[in] length length of fidx box +@param[in] cio file output handle +*/ +static void write_iptr( int offset, int length, opj_cio_t *cio); +/** +Write proxy box +@param[in] offset_jp2c offset of jp2c box +@param[in] length_jp2c length of jp2c box +@param[in] offset_idx offset of cidx box +@param[in] length_idx length of cidx box +@param[in] cio file output handle +*/ +static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio); /*@}*/ /*@}*/ /* ----------------------------------------------------------------------- */ -static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box) { +static opj_bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box) { box->init_pos = cio_tell(cio); box->length = cio_read(cio, 4); box->type = cio_read(cio, 4); if (box->length == 1) { if (cio_read(cio, 4) != 0) { opj_event_msg(cinfo, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n"); - return false; + return OPJ_FALSE; } box->length = cio_read(cio, 4); if (box->length == 0) @@ -111,8 +173,12 @@ static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t else if (box->length == 0) { box->length = cio_numbytesleft(cio) + 8; } + if (box->length < 0) { + opj_event_msg(cinfo, EVT_ERROR, "Integer overflow in box->length\n"); + return OPJ_FALSE; // TODO: actually check jp2_read_boxhdr's return value + } - return true; + return OPJ_TRUE; } #if 0 @@ -139,15 +205,18 @@ static void jp2_write_url(opj_cio_t *cio, char *Idx_file) { } #endif -static bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { +static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { opj_jp2_box_t box; opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); + if(jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n"); + return OPJ_FALSE; + } if (JP2_IHDR != box.type) { opj_event_msg(cinfo, EVT_ERROR, "Expected IHDR Marker\n"); - return false; + return OPJ_FALSE; } jp2->h = cio_read(cio, 4); /* HEIGHT */ @@ -163,10 +232,10 @@ static bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { if (cio_tell(cio) - box.init_pos != box.length) { opj_event_msg(cinfo, EVT_ERROR, "Error with IHDR Box\n"); - return false; + return OPJ_FALSE; } - return true; + return OPJ_TRUE; } static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { @@ -211,16 +280,19 @@ static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { } -static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { +static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { unsigned int i; opj_jp2_box_t box; opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n"); + return OPJ_FALSE; + } if (JP2_BPCC != box.type) { opj_event_msg(cinfo, EVT_ERROR, "Expected BPCC Marker\n"); - return false; + return OPJ_FALSE; } for (i = 0; i < jp2->numcomps; i++) { @@ -229,10 +301,10 @@ static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { if (cio_tell(cio) - box.init_pos != box.length) { opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n"); - return false; + return OPJ_FALSE; } - return true; + return OPJ_TRUE; } static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) { @@ -246,11 +318,10 @@ static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) { cio_write(cio, jp2->precedence, 1); /* PRECEDENCE */ cio_write(cio, jp2->approx, 1); /* APPROX */ - if (jp2->meth == 1) { - cio_write(cio, jp2->enumcs, 4); /* EnumCS */ - } else { - cio_write(cio, 0, 1); /* PROFILE (??) */ - } + if(jp2->meth == 2) + jp2->enumcs = 0; + + cio_write(cio, jp2->enumcs, 4); /* EnumCS */ box.length = cio_tell(cio) - box.init_pos; cio_seek(cio, box.init_pos); @@ -258,42 +329,483 @@ static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) { cio_seek(cio, box.init_pos + box.length); } -static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio) { - opj_jp2_box_t box; +static void jp2_free_pclr(opj_jp2_color_t *color) +{ + opj_free(color->jp2_pclr->channel_sign); + opj_free(color->jp2_pclr->channel_size); + opj_free(color->jp2_pclr->entries); + + if(color->jp2_pclr->cmap) opj_free(color->jp2_pclr->cmap); + + opj_free(color->jp2_pclr); color->jp2_pclr = NULL; +} + +static void free_color_data(opj_jp2_color_t *color) +{ + if(color->jp2_pclr) + { + jp2_free_pclr(color); + } + if(color->jp2_cdef) + { + if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info); + opj_free(color->jp2_cdef); + } + if(color->icc_profile_buf) opj_free(color->icc_profile_buf); +} + +static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image, opj_common_ptr cinfo) +{ + opj_image_comp_t *old_comps, *new_comps; + unsigned char *channel_size, *channel_sign; + unsigned int *entries; + opj_jp2_cmap_comp_t *cmap; + int *src, *dst; + unsigned int j, max; + unsigned short i, nr_channels, cmp, pcol; + int k, top_k; + + channel_size = color->jp2_pclr->channel_size; + channel_sign = color->jp2_pclr->channel_sign; + entries = color->jp2_pclr->entries; + cmap = color->jp2_pclr->cmap; + nr_channels = color->jp2_pclr->nr_channels; + + old_comps = image->comps; + new_comps = (opj_image_comp_t*) + opj_malloc(nr_channels * sizeof(opj_image_comp_t)); + + for(i = 0; i < nr_channels; ++i) + { + pcol = cmap[i].pcol; cmp = cmap[i].cmp; + + if( pcol < nr_channels ) + new_comps[pcol] = old_comps[cmp]; + else + { + opj_event_msg(cinfo, EVT_ERROR, "Error with pcol value %d (max: %d). skipping\n", pcol, nr_channels); + continue; + } + + if(cmap[i].mtyp == 0) /* Direct use */ + { + old_comps[cmp].data = NULL; continue; + } +/* Palette mapping: */ + new_comps[pcol].data = (int*) + opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(int)); + new_comps[pcol].prec = channel_size[i]; + new_comps[pcol].sgnd = channel_sign[i]; + } + top_k = color->jp2_pclr->nr_entries - 1; + + for(i = 0; i < nr_channels; ++i) + { +/* Direct use: */ + if(cmap[i].mtyp == 0) continue; + +/* Palette mapping: */ + cmp = cmap[i].cmp; pcol = cmap[i].pcol; + src = old_comps[cmp].data; + dst = new_comps[pcol].data; + max = new_comps[pcol].w * new_comps[pcol].h; + + for(j = 0; j < max; ++j) + { +/* The index */ + if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k; +/* The colour */ + dst[j] = entries[k * nr_channels + pcol]; + } + } + max = image->numcomps; + for(i = 0; i < max; ++i) + { + if(old_comps[i].data) opj_free(old_comps[i].data); + } + opj_free(old_comps); + image->comps = new_comps; + image->numcomps = nr_channels; + + jp2_free_pclr(color); + +}/* apply_pclr() */ + +static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio, + opj_jp2_box_t *box, opj_jp2_color_t *color) +{ + opj_jp2_pclr_t *jp2_pclr; + unsigned char *channel_size, *channel_sign; + unsigned int *entries; + unsigned short nr_entries, nr_channels; + unsigned short i, j; + unsigned char uc; + + OPJ_ARG_NOT_USED(box); + OPJ_ARG_NOT_USED(jp2); + +/* Part 1, I.5.3.4: 'There shall be at most one Palette box inside + * a JP2 Header box' : +*/ + if(color->jp2_pclr) return OPJ_FALSE; + + nr_entries = (unsigned short)cio_read(cio, 2); /* NE */ + nr_channels = (unsigned short)cio_read(cio, 1);/* NPC */ + + entries = (unsigned int*) + opj_malloc(nr_channels * nr_entries * sizeof(unsigned int)); + channel_size = (unsigned char*)opj_malloc(nr_channels); + channel_sign = (unsigned char*)opj_malloc(nr_channels); + + jp2_pclr = (opj_jp2_pclr_t*)opj_malloc(sizeof(opj_jp2_pclr_t)); + jp2_pclr->channel_sign = channel_sign; + jp2_pclr->channel_size = channel_size; + jp2_pclr->entries = entries; + jp2_pclr->nr_entries = nr_entries; + jp2_pclr->nr_channels = nr_channels; + jp2_pclr->cmap = NULL; + + color->jp2_pclr = jp2_pclr; + + for(i = 0; i < nr_channels; ++i) + { + uc = cio_read(cio, 1); /* Bi */ + channel_size[i] = (uc & 0x7f) + 1; + channel_sign[i] = (uc & 0x80)?1:0; + } + + for(j = 0; j < nr_entries; ++j) + { + for(i = 0; i < nr_channels; ++i) + { +/* Cji */ + *entries++ = cio_read(cio, (channel_size[i]+7)>>3); + } + } + + return OPJ_TRUE; +}/* jp2_read_pclr() */ + +static opj_bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio, + opj_jp2_box_t *box, opj_jp2_color_t *color) +{ + opj_jp2_cmap_comp_t *cmap; + unsigned short i, nr_channels; + + OPJ_ARG_NOT_USED(box); + OPJ_ARG_NOT_USED(jp2); + +/* Need nr_channels: */ + if(color->jp2_pclr == NULL) return OPJ_FALSE; + +/* Part 1, I.5.3.5: 'There shall be at most one Component Mapping box + * inside a JP2 Header box' : +*/ + if(color->jp2_pclr->cmap) return OPJ_FALSE; + + nr_channels = color->jp2_pclr->nr_channels; + cmap = (opj_jp2_cmap_comp_t*) + opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t)); + + for(i = 0; i < nr_channels; ++i) + { + cmap[i].cmp = (unsigned short)cio_read(cio, 2); + cmap[i].mtyp = cio_read(cio, 1); + cmap[i].pcol = cio_read(cio, 1); + + } + color->jp2_pclr->cmap = cmap; + + return OPJ_TRUE; +}/* jp2_read_cmap() */ + +static void jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color) +{ + opj_jp2_cdef_info_t *info; + int color_space; + unsigned short i, n, cn, typ, asoc, acn; + + color_space = image->color_space; + info = color->jp2_cdef->info; + n = color->jp2_cdef->n; + + for(i = 0; i < n; ++i) + { +/* WATCH: acn = asoc - 1 ! */ + if((asoc = info[i].asoc) == 0) continue; + + cn = info[i].cn; typ = info[i].typ; acn = asoc - 1; + + if(cn != acn) + { + opj_image_comp_t saved; + + memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t)); + memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t)); + memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t)); + + info[i].asoc = cn + 1; + info[acn].asoc = info[acn].cn + 1; + } + } + if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info); + + opj_free(color->jp2_cdef); color->jp2_cdef = NULL; + +}/* jp2_apply_cdef() */ + +static opj_bool jp2_read_cdef(opj_jp2_t *jp2, opj_cio_t *cio, + opj_jp2_box_t *box, opj_jp2_color_t *color) +{ + opj_jp2_cdef_info_t *info; + unsigned short i, n; + + OPJ_ARG_NOT_USED(box); + OPJ_ARG_NOT_USED(jp2); + +/* Part 1, I.5.3.6: 'The shall be at most one Channel Definition box + * inside a JP2 Header box.' +*/ + if(color->jp2_cdef) return OPJ_FALSE; + + if((n = (unsigned short)cio_read(cio, 2)) == 0) return OPJ_FALSE; /* szukw000: FIXME */ + + info = (opj_jp2_cdef_info_t*) + opj_malloc(n * sizeof(opj_jp2_cdef_info_t)); + + color->jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t)); + color->jp2_cdef->info = info; + color->jp2_cdef->n = n; + + for(i = 0; i < n; ++i) + { + info[i].cn = (unsigned short)cio_read(cio, 2); + info[i].typ = (unsigned short)cio_read(cio, 2); + info[i].asoc = (unsigned short)cio_read(cio, 2); + + } + return OPJ_TRUE; +}/* jp2_read_cdef() */ + +static opj_bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio, + opj_jp2_box_t *box, opj_jp2_color_t *color) +{ int skip_len; + opj_common_ptr cinfo; - opj_common_ptr cinfo = jp2->cinfo; +/* Part 1, I.5.3.3 : 'A conforming JP2 reader shall ignore all Colour + * Specification boxes after the first.' +*/ + if(color->jp2_has_colr) return OPJ_FALSE; - jp2_read_boxhdr(cinfo, cio, &box); - do { - if (JP2_COLR != box.type) { - cio_skip(cio, box.length - 8); - jp2_read_boxhdr(cinfo, cio, &box); - } - } while(JP2_COLR != box.type); + cinfo = jp2->cinfo; jp2->meth = cio_read(cio, 1); /* METH */ jp2->precedence = cio_read(cio, 1); /* PRECEDENCE */ jp2->approx = cio_read(cio, 1); /* APPROX */ - if (jp2->meth == 1) { - jp2->enumcs = cio_read(cio, 4); /* EnumCS */ - } else { - /* skip PROFILE */ - skip_len = box.init_pos + box.length - cio_tell(cio); - if (skip_len < 0) { - opj_event_msg(cinfo, EVT_ERROR, "Error with JP2H box size\n"); - return false; - } - cio_skip(cio, box.init_pos + box.length - cio_tell(cio)); - } + if (jp2->meth == 1) + { + jp2->enumcs = cio_read(cio, 4); /* EnumCS */ + } + else + if (jp2->meth == 2) + { +/* skip PROFILE */ + skip_len = box->init_pos + box->length - cio_tell(cio); + if (skip_len < 0) + { + opj_event_msg(cinfo, EVT_ERROR, "Error with COLR box size\n"); + return OPJ_FALSE; + } + if(skip_len > 0) + { + unsigned char *start; + + start = cio_getbp(cio); + color->icc_profile_buf = (unsigned char*)opj_malloc(skip_len); + color->icc_profile_len = skip_len; + + cio_skip(cio, box->init_pos + box->length - cio_tell(cio)); + + memcpy(color->icc_profile_buf, start, skip_len); + } + } + + if (cio_tell(cio) - box->init_pos != box->length) + { + opj_event_msg(cinfo, EVT_ERROR, "Error with COLR Box\n"); + return OPJ_FALSE; + } + color->jp2_has_colr = 1; + + return OPJ_TRUE; +}/* jp2_read_colr() */ + +opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color) +{ + opj_jp2_box_t box; + int jp2h_end; + + opj_common_ptr cinfo = jp2->cinfo; + + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + do { + if (JP2_JP2H != box.type) + { + if (box.type == JP2_JP2C) + { + opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n"); + return OPJ_FALSE; + } + if (box.length <= 8) return OPJ_FALSE; + cio_skip(cio, box.length - 8); + + if(cio->bp >= cio->end) return OPJ_FALSE; + + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + } + } while(JP2_JP2H != box.type); + + if (!jp2_read_ihdr(jp2, cio)) + return OPJ_FALSE; + jp2h_end = box.init_pos + box.length; + + if (jp2->bpc == 255) + { + if (!jp2_read_bpcc(jp2, cio)) + return OPJ_FALSE; + } + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + + while(cio_tell(cio) < jp2h_end) + { + if(box.type == JP2_COLR) + { + if( !jp2_read_colr(jp2, cio, &box, color)) + { + if (box.length <= 8) return OPJ_FALSE; + cio_seek(cio, box.init_pos + 8); + cio_skip(cio, box.length - 8); + } + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + continue; + } + if(box.type == JP2_CDEF && !jp2->ignore_pclr_cmap_cdef) + { + if( !jp2_read_cdef(jp2, cio, &box, color)) + { + if (box.length <= 8) return OPJ_FALSE; + cio_seek(cio, box.init_pos + 8); + cio_skip(cio, box.length - 8); + } + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + continue; + } + if(box.type == JP2_PCLR && !jp2->ignore_pclr_cmap_cdef) + { + if( !jp2_read_pclr(jp2, cio, &box, color)) + { + if (box.length <= 8) return OPJ_FALSE; + cio_seek(cio, box.init_pos + 8); + cio_skip(cio, box.length - 8); + } + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + continue; + } + if(box.type == JP2_CMAP && !jp2->ignore_pclr_cmap_cdef) + { + if( !jp2_read_cmap(jp2, cio, &box, color)) + { + if (box.length <= 8) return OPJ_FALSE; + cio_seek(cio, box.init_pos + 8); + cio_skip(cio, box.length - 8); + } + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + continue; + } + if (box.length <= 8) return OPJ_FALSE; + cio_seek(cio, box.init_pos + 8); + cio_skip(cio, box.length - 8); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; + + }/* while(cio_tell(cio) < box_end) */ + + cio_seek(cio, jp2h_end); + + /* Part 1, I.5.3.3 : 'must contain at least one' */ + return (color->jp2_has_colr == 1); + +}/* jp2_read_jp2h() */ + +opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, + opj_codestream_info_t *cstr_info) +{ + opj_common_ptr cinfo; + opj_image_t *image = NULL; + opj_jp2_color_t color; + + if(!jp2 || !cio) + { + return NULL; + } + memset(&color, 0, sizeof(opj_jp2_color_t)); + cinfo = jp2->cinfo; + +/* JP2 decoding */ + if(!jp2_read_struct(jp2, cio, &color)) + { + free_color_data(&color); + opj_event_msg(cinfo, EVT_ERROR, "Failed to decode jp2 structure\n"); + return NULL; + } + +/* J2K decoding */ + image = j2k_decode(jp2->j2k, cio, cstr_info); + + if(!image) + { + free_color_data(&color); + opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n"); + return NULL; + } + + if (!jp2->ignore_pclr_cmap_cdef){ + + /* Set Image Color Space */ + if (jp2->enumcs == 16) + image->color_space = CLRSPC_SRGB; + else if (jp2->enumcs == 17) + image->color_space = CLRSPC_GRAY; + else if (jp2->enumcs == 18) + image->color_space = CLRSPC_SYCC; + else + image->color_space = CLRSPC_UNKNOWN; + + if(color.jp2_cdef) + { + jp2_apply_cdef(image, &color); + } + if(color.jp2_pclr) + { +/* Part 1, I.5.3.4: Either both or none : */ + if( !color.jp2_pclr->cmap) + jp2_free_pclr(&color); + else + jp2_apply_pclr(&color, image, cinfo); + } + if(color.icc_profile_buf) + { + image->icc_profile_buf = color.icc_profile_buf; + color.icc_profile_buf = NULL; + image->icc_profile_len = color.icc_profile_len; + } + } + + return image; + +}/* opj_jp2_decode() */ - if (cio_tell(cio) - box.init_pos != box.length) { - opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n"); - return false; - } - return true; -} void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) { opj_jp2_box_t box; @@ -315,44 +827,6 @@ void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) { cio_seek(cio, box.init_pos + box.length); } -bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) { - opj_jp2_box_t box; - int skip_len; - - opj_common_ptr cinfo = jp2->cinfo; - - jp2_read_boxhdr(cinfo, cio, &box); - do { - if (JP2_JP2H != box.type) { - if (box.type == JP2_JP2C) { - opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n"); - return false; - } - cio_skip(cio, box.length - 8); - jp2_read_boxhdr(cinfo, cio, &box); - } - } while(JP2_JP2H != box.type); - - if (!jp2_read_ihdr(jp2, cio)) - return false; - - if (jp2->bpc == 255) { - if (!jp2_read_bpcc(jp2, cio)) - return false; - } - if (!jp2_read_colr(jp2, cio)) - return false; - - skip_len = box.init_pos + box.length - cio_tell(cio); - if (skip_len < 0) { - opj_event_msg(cinfo, EVT_ERROR, "Error with JP2H Box\n"); - return false; - } - cio_skip(cio, box.init_pos + box.length - cio_tell(cio)); - - return true; -} - static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { unsigned int i; opj_jp2_box_t box; @@ -374,17 +848,19 @@ static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { cio_seek(cio, box.init_pos + box.length); } -static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { +static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { int i; opj_jp2_box_t box; opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); - + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n"); + return OPJ_FALSE; + } if (JP2_FTYP != box.type) { opj_event_msg(cinfo, EVT_ERROR, "Expected FTYP Marker\n"); - return false; + return OPJ_FALSE; } jp2->brand = cio_read(cio, 4); /* BR */ @@ -398,10 +874,10 @@ static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { if (cio_tell(cio) - box.init_pos != box.length) { opj_event_msg(cinfo, EVT_ERROR, "Error with FTYP Box\n"); - return false; + return OPJ_FALSE; } - return true; + return OPJ_TRUE; } static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { @@ -433,23 +909,28 @@ static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, op return box.length; } -static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) { +static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) { opj_jp2_box_t box; opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n"); + return OPJ_FALSE; + } do { if(JP2_JP2C != box.type) { + if (box.length <= 8) return OPJ_FALSE; cio_skip(cio, box.length - 8); - jp2_read_boxhdr(cinfo, cio, &box); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE; } } while(JP2_JP2C != box.type); *j2k_codestream_offset = cio_tell(cio); + if (box.length <= 8) return OPJ_FALSE; *j2k_codestream_length = box.length - 8; - return true; + return OPJ_TRUE; } static void jp2_write_jp(opj_cio_t *cio) { @@ -466,42 +947,107 @@ static void jp2_write_jp(opj_cio_t *cio) { cio_seek(cio, box.init_pos + box.length); } -static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) { +static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) { opj_jp2_box_t box; opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(cinfo, cio, &box); + if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n"); + return OPJ_FALSE; + } if (JP2_JP != box.type) { opj_event_msg(cinfo, EVT_ERROR, "Expected JP Marker\n"); - return false; + return OPJ_FALSE; } if (0x0d0a870a != cio_read(cio, 4)) { opj_event_msg(cinfo, EVT_ERROR, "Error with JP Marker\n"); - return false; + return OPJ_FALSE; } if (cio_tell(cio) - box.init_pos != box.length) { opj_event_msg(cinfo, EVT_ERROR, "Error with JP Box size\n"); - return false; + return OPJ_FALSE; } - return true; + return OPJ_TRUE; } -static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio) { +static opj_bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio, + opj_jp2_color_t *color) { if (!jp2_read_jp(jp2, cio)) - return false; + return OPJ_FALSE; if (!jp2_read_ftyp(jp2, cio)) - return false; - if (!jp2_read_jp2h(jp2, cio)) - return false; + return OPJ_FALSE; + if (!jp2_read_jp2h(jp2, cio, color)) + return OPJ_FALSE; if (!jp2_read_jp2c(jp2, cio, &jp2->j2k_codestream_length, &jp2->j2k_codestream_offset)) - return false; + return OPJ_FALSE; - return true; + return OPJ_TRUE; } + +static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio) +{ + int len, lenp; + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_FIDX, 4); /* IPTR */ + + write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio); + + len = cio_tell( cio)-lenp; + cio_seek( cio, lenp); + cio_write( cio, len, 4); /* L */ + cio_seek( cio, lenp+len); + + return len; +} + +static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio) +{ + int len, lenp; + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_PRXY, 4); /* IPTR */ + + cio_write( cio, offset_jp2c, 8); /* OOFF */ + cio_write( cio, length_jp2c, 4); /* OBH part 1 */ + cio_write( cio, JP2_JP2C, 4); /* OBH part 2 */ + + cio_write( cio, 1,1); /* NI */ + + cio_write( cio, offset_idx, 8); /* IOFF */ + cio_write( cio, length_idx, 4); /* IBH part 1 */ + cio_write( cio, JPIP_CIDX, 4); /* IBH part 2 */ + + len = cio_tell( cio)-lenp; + cio_seek( cio, lenp); + cio_write( cio, len, 4); /* L */ + cio_seek( cio, lenp+len); +} + +static void write_iptr( int offset, int length, opj_cio_t *cio) +{ + int len, lenp; + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_IPTR, 4); /* IPTR */ + + cio_write( cio, offset, 8); + cio_write( cio, length, 8); + + len = cio_tell( cio)-lenp; + cio_seek( cio, lenp); + cio_write( cio, len, 4); /* L */ + cio_seek( cio, lenp+len); +} + + /* ----------------------------------------------------------------------- */ /* JP2 decoder interface */ /* ----------------------------------------------------------------------- */ @@ -539,42 +1085,7 @@ void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) { /* setup the J2K codec */ j2k_setup_decoder(jp2->j2k, parameters); /* further JP2 initializations go here */ -} - -opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { - opj_common_ptr cinfo; - opj_image_t *image = NULL; - - if(!jp2 || !cio) { - return NULL; - } - - cinfo = jp2->cinfo; - - /* JP2 decoding */ - if(!jp2_read_struct(jp2, cio)) { - opj_event_msg(cinfo, EVT_ERROR, "Failed to decode jp2 structure\n"); - return NULL; - } - - /* J2K decoding */ - image = j2k_decode(jp2->j2k, cio, cstr_info); - if(!image) { - opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n"); - return NULL; - } - - /* Set Image Color Space */ - if (jp2->enumcs == 16) - image->color_space = CLRSPC_SRGB; - else if (jp2->enumcs == 17) - image->color_space = CLRSPC_GRAY; - else if (jp2->enumcs == 18) - image->color_space = CLRSPC_SYCC; - else - image->color_space = CLRSPC_UNKNOWN; - - return image; + jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG; } /* ----------------------------------------------------------------------- */ @@ -664,30 +1175,23 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_ for (i = 0; i < image->numcomps; i++) { jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7); } - - /* Colour Specification box */ - - if ((image->numcomps == 1 || image->numcomps == 3) && (jp2->bpc != 255)) { - jp2->meth = 1; /* METH: Enumerated colourspace */ - } else { - jp2->meth = 2; /* METH: Restricted ICC profile */ - } - if (jp2->meth == 1) { - if (image->color_space == 1) - jp2->enumcs = 16; /* sRGB as defined by IEC 61966–2–1 */ - else if (image->color_space == 2) - jp2->enumcs = 17; /* greyscale */ - else if (image->color_space == 3) - jp2->enumcs = 18; /* YUV */ - } else { - jp2->enumcs = 0; /* PROFILE (??) */ - } + jp2->meth = 1; + if (image->color_space == 1) + jp2->enumcs = 16; /* sRGB as defined by IEC 61966-2.1 */ + else if (image->color_space == 2) + jp2->enumcs = 17; /* greyscale */ + else if (image->color_space == 3) + jp2->enumcs = 18; /* YUV */ jp2->precedence = 0; /* PRECEDENCE */ jp2->approx = 0; /* APPROX */ - + + jp2->jpip_on = parameters->jpip_on; } -bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { +opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { + + int pos_iptr, pos_cidx, pos_jp2c, len_jp2c, len_cidx, end_pos, pos_fidx, len_fidx; + pos_jp2c = pos_iptr = -1; /* remove a warning */ /* JP2 encoding */ @@ -698,14 +1202,34 @@ bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestre /* JP2 Header box */ jp2_write_jp2h(jp2, cio); - /* J2K encoding */ - - if(!jp2_write_jp2c(jp2, cio, image, cstr_info)) { - opj_event_msg(jp2->cinfo, EVT_ERROR, "Failed to encode image\n"); - return false; + if( jp2->jpip_on){ + pos_iptr = cio_tell( cio); + cio_skip( cio, 24); /* IPTR further ! */ + + pos_jp2c = cio_tell( cio); } - return true; + /* J2K encoding */ + if(!(len_jp2c = jp2_write_jp2c( jp2, cio, image, cstr_info))){ + opj_event_msg(jp2->cinfo, EVT_ERROR, "Failed to encode image\n"); + return OPJ_FALSE; + } + + if( jp2->jpip_on){ + pos_cidx = cio_tell( cio); + + len_cidx = write_cidx( pos_jp2c+8, cio, image, *cstr_info, len_jp2c-8); + + pos_fidx = cio_tell( cio); + len_fidx = write_fidx( pos_jp2c, len_jp2c, pos_cidx, len_cidx, cio); + + end_pos = cio_tell( cio); + + cio_seek( cio, pos_iptr); + write_iptr( pos_fidx, len_fidx, cio); + + cio_seek( cio, end_pos); + } + + return OPJ_TRUE; } - - diff --git a/indra/libopenjpeg/jp2.h b/indra/libopenjpeg/jp2.h index 7e363be2e..acb643cad 100644 --- a/indra/libopenjpeg/jp2.h +++ b/indra/libopenjpeg/jp2.h @@ -46,11 +46,64 @@ #define JP2_COLR 0x636f6c72 /**< Colour specification box */ #define JP2_JP2C 0x6a703263 /**< Contiguous codestream box */ #define JP2_URL 0x75726c20 /**< URL box */ -#define JP2_DBTL 0x6474626c /**< ??? */ +#define JP2_DTBL 0x6474626c /**< Data Reference box */ #define JP2_BPCC 0x62706363 /**< Bits per component box */ #define JP2_JP2 0x6a703220 /**< File type fields */ +#define JP2_PCLR 0x70636c72 /**< Palette box */ +#define JP2_CMAP 0x636d6170 /**< Component Mapping box */ +#define JP2_CDEF 0x63646566 /**< Channel Definition box */ /* ----------------------------------------------------------------------- */ +/** +Channel description: channel index, type, assocation +*/ +typedef struct opj_jp2_cdef_info +{ + unsigned short cn, typ, asoc; +} opj_jp2_cdef_info_t; + +/** +Channel descriptions and number of descriptions +*/ +typedef struct opj_jp2_cdef +{ + opj_jp2_cdef_info_t *info; + unsigned short n; +} opj_jp2_cdef_t; + +/** +Component mappings: channel index, mapping type, palette index +*/ +typedef struct opj_jp2_cmap_comp +{ + unsigned short cmp; + unsigned char mtyp, pcol; +} opj_jp2_cmap_comp_t; + +/** +Palette data: table entries, palette columns +*/ +typedef struct opj_jp2_pclr +{ + unsigned int *entries; + unsigned char *channel_sign; + unsigned char *channel_size; + opj_jp2_cmap_comp_t *cmap; + unsigned short nr_entries, nr_channels; +} opj_jp2_pclr_t; + +/** +Collector for ICC profile, palette, component mapping, channel description +*/ +typedef struct opj_jp2_color +{ + unsigned char *icc_profile_buf; + int icc_profile_len; + + opj_jp2_cdef_t *jp2_cdef; + opj_jp2_pclr_t *jp2_pclr; + unsigned char jp2_has_colr; +} opj_jp2_color_t; /** JP2 component @@ -87,6 +140,8 @@ typedef struct opj_jp2 { opj_jp2_comps_t *comps; unsigned int j2k_codestream_offset; unsigned int j2k_codestream_length; + opj_bool jpip_on; + opj_bool ignore_pclr_cmap_cdef; } opj_jp2_t; /** @@ -111,9 +166,10 @@ void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio); Read the JP2H box - JP2 Header box (used in MJ2) @param jp2 JP2 handle @param cio Input buffer stream +@param ext Collector for profile, cdef and pclr data @return Returns true if successful, returns false otherwise */ -bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio); +opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color); /** Creates a JP2 decompression structure @param cinfo Codec context info @@ -139,7 +195,7 @@ Decode an image from a JPEG-2000 file stream @param cstr_info Codestream information structure if required, NULL otherwise @return Returns a decoded image if successful, returns NULL otherwise */ -opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info); +opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info); /** Creates a JP2 compression structure @param cinfo Codec context info @@ -167,7 +223,8 @@ Encode an image into a JPEG-2000 file stream @param cstr_info Codestream information structure if required, NULL otherwise @return Returns true if successful, returns false otherwise */ -bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); +opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); + /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/indra/libopenjpeg/mqc.c b/indra/libopenjpeg/mqc.c index 5d25238ee..14129fbf4 100644 --- a/indra/libopenjpeg/mqc.c +++ b/indra/libopenjpeg/mqc.c @@ -521,22 +521,21 @@ void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) { unsigned int c; unsigned int *ip; unsigned char *end = mqc->end - 1; - mqc->buffer = opj_realloc(mqc->buffer, (2 * len + 1) * sizeof(unsigned int)); + mqc->buffer = opj_realloc(mqc->buffer, (len + 1) * sizeof(unsigned int)); ip = (unsigned int *) mqc->buffer; - while (bp != end) { + while (bp < end) { c = *(bp + 1); if (*bp == 0xff) { if (c > 0x8f) { - *ip = 0x0000ff18; + break; } else { - bp++; *ip = 0x00000017 | (c << 9); } } else { - bp++; *ip = 0x00000018 | (c << 8); } + bp++; ip++; } diff --git a/indra/libopenjpeg/openjpeg.c b/indra/libopenjpeg/openjpeg.c index 565c5caa0..180cc844a 100644 --- a/indra/libopenjpeg/openjpeg.c +++ b/indra/libopenjpeg/openjpeg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2005, Herve Drolon, FreeImage Team * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,17 +24,22 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifdef WIN32 +#ifdef _WIN32 #include -#endif /* WIN32 */ +#endif /* _WIN32 */ +#include "opj_config.h" #include "opj_includes.h" /* ---------------------------------------------------------------------- */ -#ifdef WIN32 +#ifdef _WIN32 #ifndef OPJ_STATIC BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { + + OPJ_ARG_NOT_USED(lpReserved); + OPJ_ARG_NOT_USED(hModule); + switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH : break; @@ -48,19 +53,19 @@ DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { return TRUE; } #endif /* OPJ_STATIC */ -#endif /* WIN32 */ +#endif /* _WIN32 */ /* ---------------------------------------------------------------------- */ const char* OPJ_CALLCONV opj_version(void) { - return OPENJPEG_VERSION; + return PACKAGE_VERSION; } opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) { opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_calloc(1, sizeof(opj_dinfo_t)); if(!dinfo) return NULL; - dinfo->is_decompressor = true; + dinfo->is_decompressor = OPJ_TRUE; switch(format) { case CODEC_J2K: case CODEC_JPT: @@ -120,9 +125,10 @@ void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *paramete parameters->decod_format = -1; parameters->cod_format = -1; + parameters->flags = 0; /* UniPG>> */ #ifdef USE_JPWL - parameters->jpwl_correct = false; + parameters->jpwl_correct = OPJ_FALSE; parameters->jpwl_exp_comps = JPWL_EXPECTED_COMPONENTS; parameters->jpwl_max_tiles = JPWL_MAXIMUM_TILES; #endif /* USE_JPWL */ @@ -159,7 +165,7 @@ opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *ci case CODEC_JPT: return j2k_decode_jpt_stream((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info); case CODEC_JP2: - return jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio, cstr_info); + return opj_jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio, cstr_info); case CODEC_UNKNOWN: default: break; @@ -171,7 +177,7 @@ opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *ci opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format) { opj_cinfo_t *cinfo = (opj_cinfo_t*)opj_calloc(1, sizeof(opj_cinfo_t)); if(!cinfo) return NULL; - cinfo->is_decompressor = false; + cinfo->is_decompressor = OPJ_FALSE; switch(format) { case CODEC_J2K: /* get a J2K coder handle */ @@ -243,10 +249,10 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *paramete parameters->cp_disto_alloc = 0; parameters->cp_fixed_alloc = 0; parameters->cp_fixed_quality = 0; - + parameters->jpip_on = OPJ_FALSE; /* UniPG>> */ #ifdef USE_JPWL - parameters->jpwl_epc_on = false; + parameters->jpwl_epc_on = OPJ_FALSE; parameters->jpwl_hprot_MH = -1; /* -1 means unassigned */ { int i; @@ -296,7 +302,7 @@ void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *param } } -bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) { +opj_bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) { if (index != NULL) opj_event_msg((opj_common_ptr)cinfo, EVT_WARNING, "Set index to NULL when calling the opj_encode function.\n" "To extract the index, use the opj_encode_with_info() function.\n" @@ -304,20 +310,20 @@ bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *im return opj_encode_with_info(cinfo, cio, image, NULL); } -bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { +opj_bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { if(cinfo && cio && image) { switch(cinfo->codec_format) { case CODEC_J2K: return j2k_encode((opj_j2k_t*)cinfo->j2k_handle, cio, image, cstr_info); case CODEC_JP2: - return jp2_encode((opj_jp2_t*)cinfo->jp2_handle, cio, image, cstr_info); + return opj_jp2_encode((opj_jp2_t*)cinfo->jp2_handle, cio, image, cstr_info); case CODEC_JPT: case CODEC_UNKNOWN: default: break; } } - return false; + return OPJ_FALSE; } void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) { @@ -328,6 +334,7 @@ void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) { opj_free(tile_info->thresh); opj_free(tile_info->packet); opj_free(tile_info->tp); + opj_free(tile_info->marker); } opj_free(cstr_info->tile); opj_free(cstr_info->marker); diff --git a/indra/libopenjpeg/openjpeg.h b/indra/libopenjpeg/openjpeg.h index e12bf0ae7..59147c8b3 100644 --- a/indra/libopenjpeg/openjpeg.h +++ b/indra/libopenjpeg/openjpeg.h @@ -6,6 +6,7 @@ * 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) 2010-2011, Kaori Hagihara * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,7 +33,6 @@ #ifndef OPENJPEG_H #define OPENJPEG_H -#define OPENJPEG_VERSION "1.4.0.635" /* ========================================================== @@ -40,7 +40,7 @@ ========================================================== */ -#if defined(OPJ_STATIC) || !(defined(WIN32) || defined(__WIN32__)) +#if defined(OPJ_STATIC) || !defined(_WIN32) #define OPJ_API #define OPJ_CALLCONV #else @@ -53,38 +53,19 @@ that uses this DLL. This way any other project whose source files include this f OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols defined with this macro as being exported. */ -#ifdef OPJ_EXPORTS +#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT) #define OPJ_API __declspec(dllexport) #else #define OPJ_API __declspec(dllimport) #endif /* OPJ_EXPORTS */ -#endif /* !OPJ_STATIC || !WIN32 */ +#endif /* !OPJ_STATIC || !_WIN32 */ -#ifndef __cplusplus -#if defined(HAVE_STDBOOL_H) -/* -The C language implementation does correctly provide the standard header -file "stdbool.h". - */ -#include -#else -/* -The C language implementation does not provide the standard header file -"stdbool.h" as required by ISO/IEC 9899:1999. Try to compensate for this -braindamage below. -*/ -#if !defined(bool) -#define bool int -#endif -#if !defined(true) -#define true 1 -#endif -#if !defined(false) -#define false 0 -#endif -#endif -#endif /* __cplusplus */ +typedef int opj_bool; +#define OPJ_TRUE 1 +#define OPJ_FALSE 0 +/* Avoid compile-time warning because parameter is not used */ +#define OPJ_ARG_NOT_USED(x) (void)(x) /* ========================================================== Useful constant definitions @@ -154,14 +135,18 @@ typedef enum COLOR_SPACE { CLRSPC_SYCC = 3 /**< YUV */ } OPJ_COLOR_SPACE; +#define ENUMCS_SRGB 16 +#define ENUMCS_GRAY 17 +#define ENUMCS_SYCC 18 + /** Supported codec */ typedef enum CODEC_FORMAT { CODEC_UNKNOWN = -1, /**< place-holder */ - CODEC_J2K = 0, /**< JPEG-2000 codestream : read/write */ - CODEC_JPT = 1, /**< JPT-stream (JPEG 2000, JPIP) : read only */ - CODEC_JP2 = 2 /**< JPEG-2000 file format : read/write */ + CODEC_J2K = 0, /**< JPEG-2000 codestream : read/write */ + CODEC_JPT = 1, /**< JPT-stream (JPEG 2000, JPIP) : read only */ + CODEC_JP2 = 2 /**< JPEG-2000 file format : read/write */ } OPJ_CODEC_FORMAT; /** @@ -244,7 +229,7 @@ Compression parameters */ typedef struct opj_cparameters { /** size of tile: tile_size_on = false (not in argument) or = true (in argument) */ - bool tile_size_on; + opj_bool tile_size_on; /** XTOsiz */ int cp_tx0; /** YTOsiz */ @@ -326,7 +311,7 @@ typedef struct opj_cparameters { /**@name JPWL encoding parameters */ /*@{*/ /** enables writing of EPC in MH, thus activating JPWL */ - bool jpwl_epc_on; + opj_bool jpwl_epc_on; /** error protection method for MH (0,1,16,32,37-128) */ int jpwl_hprot_MH; /** tile number of header protection specification (>=0) */ @@ -366,8 +351,12 @@ typedef struct opj_cparameters { char tp_flag; /** MCT (multiple component transform) */ char tcp_mct; + /** Enable JPIP indexing*/ + opj_bool jpip_on; } opj_cparameters_t; +#define OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG 0x0001 + /** Decompression parameters */ @@ -404,7 +393,7 @@ typedef struct opj_dparameters { /**@name JPWL decoding parameters */ /*@{*/ /** activates the JPWL correction capabilities */ - bool jpwl_correct; + opj_bool jpwl_correct; /** expected number of components */ int jpwl_exp_comps; /** maximum number of tiles */ @@ -420,6 +409,7 @@ typedef struct opj_dparameters { */ OPJ_LIMIT_DECODING cp_limit_decoding; + unsigned int flags; } opj_dparameters_t; /** Common fields between JPEG-2000 compression and decompression master structs. */ @@ -427,7 +417,7 @@ typedef struct opj_dparameters { #define opj_common_fields \ opj_event_mgr_t *event_mgr; /**< pointer to the event manager */\ void * client_data; /**< Available for use by application */\ - bool is_decompressor; /**< So common code can tell which is which */\ + opj_bool is_decompressor; /**< So common code can tell which is which */\ OPJ_CODEC_FORMAT codec_format; /**< selected codec */\ void *j2k_handle; /**< pointer to the J2K codec */\ void *jp2_handle; /**< pointer to the JP2 codec */\ @@ -555,6 +545,10 @@ typedef struct opj_image { OPJ_COLOR_SPACE color_space; /** image components */ opj_image_comp_t *comps; + /** 'restricted' ICC profile */ + unsigned char *icc_profile_buf; + /** size of ICC profile */ + int icc_profile_len; } opj_image_t; /** @@ -601,6 +595,21 @@ typedef struct opj_packet_info { double disto; } opj_packet_info_t; + +/* UniPG>> */ +/** +Marker structure +*/ +typedef struct opj_marker_info_t { + /** marker type */ + unsigned short int type; + /** position in codestream */ + int pos; + /** length, marker val included */ + int len; +} opj_marker_info_t; +/* <> */ -/** -Marker structure -*/ -typedef struct opj_marker_info_t { - /** marker type */ - unsigned short int type; - /** position in codestream */ - int pos; - /** length, marker val included */ - int len; -} opj_marker_info_t; -/* < Set to NULL. To extract index, used opj_encode_wci() @return Returns true if successful, returns false otherwise */ -OPJ_API bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index); +OPJ_API opj_bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index); /** Encode an image into a JPEG-2000 codestream and extract the codestream information @param cinfo compressor handle @@ -898,13 +899,14 @@ Encode an image into a JPEG-2000 codestream and extract the codestream informati @param cstr_info Codestream information structure if needed afterwards, NULL otherwise @return Returns true if successful, returns false otherwise */ -OPJ_API bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); +OPJ_API opj_bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); /** Destroy Codestream information after compression or decompression @param cstr_info Codestream information structure */ OPJ_API void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info); + #ifdef __cplusplus } #endif diff --git a/indra/libopenjpeg/opj_config.h b/indra/libopenjpeg/opj_config.h new file mode 100644 index 000000000..f8148c629 --- /dev/null +++ b/indra/libopenjpeg/opj_config.h @@ -0,0 +1,36 @@ +/* create config.h for CMake */ +#define PACKAGE_VERSION "1.5.2" + +#define HAVE_INTTYPES_H +#define HAVE_MEMORY_H +#define HAVE_STDINT_H +#define HAVE_STDLIB_H +#define HAVE_STRINGS_H +#define HAVE_STRING_H +#define HAVE_SYS_STAT_H +#define HAVE_SYS_TYPES_H +#define HAVE_UNISTD_H +/* #define HAVE_LIBPNG */ +/* #define HAVE_PNG_H */ +/* #define HAVE_LIBTIFF */ +/* #define HAVE_TIFF_H */ + +/* #undef HAVE_LIBLCMS1 */ +/* #undef HAVE_LIBLCMS2 */ +/* #undef HAVE_LCMS1_H */ +/* #undef HAVE_LCMS2_H */ + +/* Byte order. */ +/* All compilers that support Mac OS X define either __BIG_ENDIAN__ or + * __LITTLE_ENDIAN__ to match the endianness of the architecture being + * compiled for. This is not necessarily the same as the architecture of the + * machine doing the building. In order to support Universal Binaries on + * Mac OS X, we prefer those defines to decide the endianness. + * On other platforms we use the result of the TRY_RUN. */ +#if !defined(__APPLE__) +/* #undef OPJ_BIG_ENDIAN */ +#elif defined(__BIG_ENDIAN__) +# define OPJ_BIG_ENDIAN +#endif + + diff --git a/indra/libopenjpeg/opj_includes.h b/indra/libopenjpeg/opj_includes.h index 80d617e31..2b5866a99 100644 --- a/indra/libopenjpeg/opj_includes.h +++ b/indra/libopenjpeg/opj_includes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2005, Herve Drolon, FreeImage Team * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,20 +89,25 @@ Most compilers implement their own version of this keyword ... /* MSVC and Borland C do not have lrintf */ #if defined(_MSC_VER) || defined(__BORLANDC__) static INLINE long lrintf(float f){ - int i; - - _asm{ - fld f - fistp i - }; - - return i; +#ifdef _M_X64 + return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f)); +#else + int i; + + _asm{ + fld f + fistp i + }; + + return i; +#endif } #endif #include "j2k_lib.h" #include "opj_malloc.h" #include "event.h" +#include "bio.h" #include "cio.h" #include "image.h" @@ -123,9 +128,12 @@ static INLINE long lrintf(float f){ #include "int.h" #include "fix.h" +#include "cidx_manager.h" +#include "indexbox_manager.h" + /* JPWL>> */ #ifdef USE_JPWL -#include "../jpwl/jpwl.h" +#include "./jpwl/jpwl.h" #endif /* USE_JPWL */ /* < * All rights reserved. * @@ -69,7 +69,7 @@ Allocate memory aligned to a 16 byte boundry @return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available */ /* FIXME: These should be set with cmake tests, but we're currently not requiring use of cmake */ -#ifdef WIN32 +#ifdef _WIN32 /* Someone should tell the mingw people that their malloc.h ought to provide _mm_malloc() */ #ifdef __GNUC__ #include @@ -80,11 +80,13 @@ Allocate memory aligned to a 16 byte boundry #define HAVE_MM_MALLOC #endif #endif -#else /* Not WIN32 */ +#else /* Not _WIN32 */ #if defined(__sun) #define HAVE_MEMALIGN + #elif defined(__FreeBSD__) + #define HAVE_POSIX_MEMALIGN /* Linux x86_64 and OSX always align allocations to 16 bytes */ - #elif !defined(__amd64__) && !defined(__APPLE__) + #elif !defined(__amd64__) && !defined(__APPLE__) && !defined(_AIX) #define HAVE_MEMALIGN #include #endif @@ -130,22 +132,22 @@ Allocate memory aligned to a 16 byte boundry /** Reallocate memory blocks. -@param memblock Pointer to previously allocated memory block -@param size New size in bytes +@param m Pointer to previously allocated memory block +@param s New size in bytes @return Returns a void pointer to the reallocated (and possibly moved) memory block */ #ifdef ALLOC_PERF_OPT -void * OPJ_CALLCONV opj_realloc(void * _Memory, size_t NewSize); +void * OPJ_CALLCONV opj_realloc(void * m, size_t s); #else #define opj_realloc(m, s) realloc(m, s) #endif /** Deallocates or frees a memory block. -@param memblock Previously allocated memory block to be freed +@param m Previously allocated memory block to be freed */ #ifdef ALLOC_PERF_OPT -void OPJ_CALLCONV opj_free(void * _Memory); +void OPJ_CALLCONV opj_free(void * m); #else #define opj_free(m) free(m) #endif diff --git a/indra/libopenjpeg/phix_manager.c b/indra/libopenjpeg/phix_manager.c new file mode 100644 index 000000000..a04584785 --- /dev/null +++ b/indra/libopenjpeg/phix_manager.c @@ -0,0 +1,170 @@ +/* + * $Id: phix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $ + * + * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2011, Professor Benoit Macq + * Copyright (c) 2003-2004, Yannick Verschueren + * Copyright (c) 2010-2011, Kaori Hagihara + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +/*! \file + * \brief Modification of jpip.c from 2KAN indexer + */ + +#include +#include +#include "opj_includes.h" + +/* + * Write faix box of phix + * + * @param[in] coff offset of j2k codestream + * @param[in] compno component number + * @param[in] cstr_info codestream information + * @param[in] EPHused true if if EPH option used + * @param[in] j2klen length of j2k codestream + * @param[in] cio file output handle + * @return length of faix box + */ +int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio); + +int write_phix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio) +{ + int len, lenp=0, compno, i; + opj_jp2_box_t *box; + + box = (opj_jp2_box_t *)opj_calloc( cstr_info.numcomps, sizeof(opj_jp2_box_t)); + + for( i=0;i<2;i++){ + if (i) cio_seek( cio, lenp); + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_PHIX, 4); /* PHIX */ + + write_manf( i, cstr_info.numcomps, box, cio); + + for( compno=0; compno pow( 2.0, 32)){ + size_of_coding = 8; + version = 1; + } + else{ + size_of_coding = 4; + version = 0; + } + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_FAIX, 4); /* FAIX */ + cio_write( cio, version,1); /* Version 0 = 4 bytes */ + + nmax = 0; + for( i=0; i<=cstr_info.numdecompos[compno]; i++) + nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers; + + cio_write( cio, nmax, size_of_coding); /* NMAX */ + cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */ + + for( tileno=0; tilenopw[resno]*tile_Idx->ph[resno]; + for( precno=0; precnopacket[ ((layno*numOfres+resno)*cstr_info.numcomps+compno)*numOfprec+precno]; + break; + case RLCP: + packet = tile_Idx->packet[ ((resno*numOflayers+layno)*cstr_info.numcomps+compno)*numOfprec+precno]; + break; + case RPCL: + packet = tile_Idx->packet[ ((resno*numOfprec+precno)*cstr_info.numcomps+compno)*numOflayers+layno]; + break; + case PCRL: + packet = tile_Idx->packet[ ((precno*cstr_info.numcomps+compno)*numOfres+resno)*numOflayers + layno]; + break; + case CPRL: + packet = tile_Idx->packet[ ((compno*numOfprec+precno)*numOfres+resno)*numOflayers + layno]; + break; + default: + fprintf( stderr, "failed to ppix indexing\n"); + } + + cio_write( cio, packet.start_pos-coff, size_of_coding); /* start position */ + cio_write( cio, packet.end_ph_pos-packet.start_pos+1, size_of_coding); /* length */ + + num_packet++; + } + } + } + + /* PADDING */ + while( num_packet < nmax){ + cio_write( cio, 0, size_of_coding); /* start position */ + cio_write( cio, 0, size_of_coding); /* length */ + num_packet++; + } + } + + len = cio_tell( cio)-lenp; + cio_seek( cio, lenp); + cio_write( cio, len, 4); /* L */ + cio_seek( cio, lenp+len); + + return len; +} diff --git a/indra/libopenjpeg/pi.c b/indra/libopenjpeg/pi.c index 06e76af76..e8e33bfe6 100644 --- a/indra/libopenjpeg/pi.c +++ b/indra/libopenjpeg/pi.c @@ -43,31 +43,31 @@ Get next packet in layer-resolution-component-precinct order. @param pi packet iterator to modify @return returns false if pi pointed to the last packet or else returns true */ -static bool pi_next_lrcp(opj_pi_iterator_t * pi); +static opj_bool pi_next_lrcp(opj_pi_iterator_t * pi); /** Get next packet in resolution-layer-component-precinct order. @param pi packet iterator to modify @return returns false if pi pointed to the last packet or else returns true */ -static bool pi_next_rlcp(opj_pi_iterator_t * pi); +static opj_bool pi_next_rlcp(opj_pi_iterator_t * pi); /** Get next packet in resolution-precinct-component-layer order. @param pi packet iterator to modify @return returns false if pi pointed to the last packet or else returns true */ -static bool pi_next_rpcl(opj_pi_iterator_t * pi); +static opj_bool pi_next_rpcl(opj_pi_iterator_t * pi); /** Get next packet in precinct-component-resolution-layer order. @param pi packet iterator to modify @return returns false if pi pointed to the last packet or else returns true */ -static bool pi_next_pcrl(opj_pi_iterator_t * pi); +static opj_bool pi_next_pcrl(opj_pi_iterator_t * pi); /** Get next packet in component-precinct-resolution-layer order. @param pi packet iterator to modify @return returns false if pi pointed to the last packet or else returns true */ -static bool pi_next_cprl(opj_pi_iterator_t * pi); +static opj_bool pi_next_cprl(opj_pi_iterator_t * pi); /*@}*/ @@ -79,7 +79,7 @@ static bool pi_next_cprl(opj_pi_iterator_t * pi); ========================================================== */ -static bool pi_next_lrcp(opj_pi_iterator_t * pi) { +static opj_bool pi_next_lrcp(opj_pi_iterator_t * pi) { opj_pi_comp_t *comp = NULL; opj_pi_resolution_t *res = NULL; long index = 0; @@ -108,7 +108,7 @@ static bool pi_next_lrcp(opj_pi_iterator_t * pi) { index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { pi->include[index] = 1; - return true; + return OPJ_TRUE; } LABEL_SKIP:; } @@ -116,10 +116,10 @@ LABEL_SKIP:; } } - return false; + return OPJ_FALSE; } -static bool pi_next_rlcp(opj_pi_iterator_t * pi) { +static opj_bool pi_next_rlcp(opj_pi_iterator_t * pi) { opj_pi_comp_t *comp = NULL; opj_pi_resolution_t *res = NULL; long index = 0; @@ -147,7 +147,7 @@ static bool pi_next_rlcp(opj_pi_iterator_t * pi) { index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { pi->include[index] = 1; - return true; + return OPJ_TRUE; } LABEL_SKIP:; } @@ -155,10 +155,10 @@ LABEL_SKIP:; } } - return false; + return OPJ_FALSE; } -static bool pi_next_rpcl(opj_pi_iterator_t * pi) { +static opj_bool pi_next_rpcl(opj_pi_iterator_t * pi) { opj_pi_comp_t *comp = NULL; opj_pi_resolution_t *res = NULL; long index = 0; @@ -229,7 +229,7 @@ if (!pi->tp_on){ index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { pi->include[index] = 1; - return true; + return OPJ_TRUE; } LABEL_SKIP:; } @@ -238,10 +238,10 @@ LABEL_SKIP:; } } - return false; + return OPJ_FALSE; } -static bool pi_next_pcrl(opj_pi_iterator_t * pi) { +static opj_bool pi_next_pcrl(opj_pi_iterator_t * pi) { opj_pi_comp_t *comp = NULL; opj_pi_resolution_t *res = NULL; long index = 0; @@ -310,7 +310,7 @@ static bool pi_next_pcrl(opj_pi_iterator_t * pi) { index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { pi->include[index] = 1; - return true; + return OPJ_TRUE; } LABEL_SKIP:; } @@ -319,10 +319,10 @@ LABEL_SKIP:; } } - return false; + return OPJ_FALSE; } -static bool pi_next_cprl(opj_pi_iterator_t * pi) { +static opj_bool pi_next_cprl(opj_pi_iterator_t * pi) { opj_pi_comp_t *comp = NULL; opj_pi_resolution_t *res = NULL; long index = 0; @@ -389,7 +389,7 @@ static bool pi_next_cprl(opj_pi_iterator_t * pi) { index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { pi->include[index] = 1; - return true; + return OPJ_TRUE; } LABEL_SKIP:; } @@ -398,7 +398,7 @@ LABEL_SKIP:; } } - return false; + return OPJ_FALSE; } /* @@ -707,7 +707,7 @@ void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) { } } -bool pi_next(opj_pi_iterator_t * pi) { +opj_bool pi_next(opj_pi_iterator_t * pi) { switch (pi->poc.prg) { case LRCP: return pi_next_lrcp(pi); @@ -720,13 +720,13 @@ bool pi_next(opj_pi_iterator_t * pi) { case CPRL: return pi_next_cprl(pi); case PROG_UNKNOWN: - return false; + return OPJ_FALSE; } - return false; + return OPJ_FALSE; } -bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp){ +opj_bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp){ char prog[4]; int i; int incr_top=1,resetX=0; @@ -748,7 +748,7 @@ bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino, case RPCL: strncpy(prog, "RPCL",4); break; case PROG_UNKNOWN: - return true; + return OPJ_TRUE; } if(!(cp->tp_on && ((!cp->cinema && (t2_mode == FINAL_PASS)) || cp->cinema))){ @@ -958,6 +958,6 @@ bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino, } } } - return false; + return OPJ_FALSE; } diff --git a/indra/libopenjpeg/pi.h b/indra/libopenjpeg/pi.h index b5e0f6a4d..cf9135fd1 100644 --- a/indra/libopenjpeg/pi.h +++ b/indra/libopenjpeg/pi.h @@ -115,12 +115,14 @@ Modify the packet iterator for enabling tile part generation @param pi Handle to the packet iterator generated in pi_initialise_encode @param cp Coding parameters @param tileno Number that identifies the tile for which to list the packets +@param pino Iterator index for pi @param tpnum Tile part number of the current tile @param tppos The position of the tile part flag in the progression order +@param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass @param cur_totnum_tp The total number of tile parts in the current tile @return Returns true if an error is detected */ -bool pi_create_encode(opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp); +opj_bool pi_create_encode(opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp); /** Create a packet iterator for Decoder @param image Raw image for which the packets will be listed @@ -145,7 +147,7 @@ Modify the packet iterator to point to the next packet @param pi Packet iterator to modify @return Returns false if pi pointed to the last packet or else returns true */ -bool pi_next(opj_pi_iterator_t * pi); +opj_bool pi_next(opj_pi_iterator_t * pi); /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/indra/libopenjpeg/ppix_manager.c b/indra/libopenjpeg/ppix_manager.c new file mode 100644 index 000000000..0e9326024 --- /dev/null +++ b/indra/libopenjpeg/ppix_manager.c @@ -0,0 +1,173 @@ +/* + * $Id: ppix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $ + * + * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2011, Professor Benoit Macq + * Copyright (c) 2003-2004, Yannick Verschueren + * Copyright (c) 2010-2011, Kaori Hagihara + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +/*! \file + * \brief Modification of jpip.c from 2KAN indexer + */ + +#include +#include +#include +#include "opj_includes.h" + +/* + * Write faix box of ppix + * + * @param[in] coff offset of j2k codestream + * @param[in] compno component number + * @param[in] cstr_info codestream information + * @param[in] EPHused true if if EPH option used + * @param[in] j2klen length of j2k codestream + * @param[in] cio file output handle + * @return length of faix box + */ +int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio); + +int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio) +{ + int len, lenp, compno, i; + opj_jp2_box_t *box; + + /* printf("cstr_info.packno %d\n", cstr_info.packno); //NMAX? */ + + lenp = -1; + box = (opj_jp2_box_t *)opj_calloc( cstr_info.numcomps, sizeof(opj_jp2_box_t)); + + for (i=0;i<2;i++){ + if (i) cio_seek( cio, lenp); + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_PPIX, 4); /* PPIX */ + + write_manf( i, cstr_info.numcomps, box, cio); + + for (compno=0; compno pow( 2.0, 32)){ + size_of_coding = 8; + version = 1; + } + else{ + size_of_coding = 4; + version = 0; + } + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_FAIX, 4); /* FAIX */ + cio_write( cio, version, 1); /* Version 0 = 4 bytes */ + + nmax = 0; + for( i=0; i<=cstr_info.numdecompos[compno]; i++) + nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers; + + cio_write( cio, nmax, size_of_coding); /* NMAX */ + cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */ + + for( tileno=0; tilenopw[resno]*tile_Idx->ph[resno]; + for( precno=0; precnopacket[ ((layno*numOfres+resno)*cstr_info.numcomps+compno)*numOfprec+precno]; + break; + case RLCP: + packet = tile_Idx->packet[ ((resno*numOflayers+layno)*cstr_info.numcomps+compno)*numOfprec+precno]; + break; + case RPCL: + packet = tile_Idx->packet[ ((resno*numOfprec+precno)*cstr_info.numcomps+compno)*numOflayers+layno]; + break; + case PCRL: + packet = tile_Idx->packet[ ((precno*cstr_info.numcomps+compno)*numOfres+resno)*numOflayers + layno]; + break; + case CPRL: + packet = tile_Idx->packet[ ((compno*numOfprec+precno)*numOfres+resno)*numOflayers + layno]; + break; + default: + fprintf( stderr, "failed to ppix indexing\n"); + } + + cio_write( cio, packet.start_pos-coff, size_of_coding); /* start position */ + cio_write( cio, packet.end_pos-packet.start_pos+1, size_of_coding); /* length */ + + num_packet++; + } + } + } + + while( num_packet < nmax){ /* PADDING */ + cio_write( cio, 0, size_of_coding); /* start position */ + cio_write( cio, 0, size_of_coding); /* length */ + num_packet++; + } + } + + len = cio_tell( cio)-lenp; + cio_seek( cio, lenp); + cio_write( cio, len, 4); /* L */ + cio_seek( cio, lenp+len); + + return len; +} diff --git a/indra/libopenjpeg/t1.c b/indra/libopenjpeg/t1.c index 884f9f633..93b997b79 100644 --- a/indra/libopenjpeg/t1.c +++ b/indra/libopenjpeg/t1.c @@ -123,20 +123,20 @@ static void t1_enc_refpass_step( /** Decode refinement pass */ -static void INLINE t1_dec_refpass_step_raw( +static INLINE void t1_dec_refpass_step_raw( opj_t1_t *t1, flag_t *flagsp, int *datap, int poshalf, int neghalf, int vsc); -static void INLINE t1_dec_refpass_step_mqc( +static INLINE void t1_dec_refpass_step_mqc( opj_t1_t *t1, flag_t *flagsp, int *datap, int poshalf, int neghalf); -static void INLINE t1_dec_refpass_step_mqc_vsc( +static INLINE void t1_dec_refpass_step_mqc_vsc( opj_t1_t *t1, flag_t *flagsp, int *datap, @@ -240,6 +240,7 @@ Encode 1 code-block @param stepsize @param cblksty Code-block style @param numcomps +@param mct @param tile */ static void t1_encode_cblk( @@ -381,9 +382,10 @@ static INLINE void t1_dec_sigpass_step_raw( int vsc) { int v, flag; - opj_raw_t *raw = t1->raw; /* RAW component */ + OPJ_ARG_NOT_USED(orient); + flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { if (raw_decode(raw)) { @@ -822,9 +824,10 @@ static void t1_dec_clnpass_step_partial( int oneplushalf) { int v, flag; - opj_mqc_t *mqc = t1->mqc; /* MQC component */ + OPJ_ARG_NOT_USED(orient); + flag = *flagsp; mqc_setcurctx(mqc, t1_getctxno_sc(flag)); v = mqc_decode(mqc) ^ t1_getspb(flag); @@ -1115,7 +1118,7 @@ static double t1_getwmsedec( return wmsedec; } -static bool allocate_buffers( +static opj_bool allocate_buffers( opj_t1_t *t1, int w, int h) @@ -1127,7 +1130,7 @@ static bool allocate_buffers( opj_aligned_free(t1->data); t1->data = (int*) opj_aligned_malloc(datasize * sizeof(int)); if(!t1->data){ - return false; + return OPJ_FALSE; } t1->datasize=datasize; } @@ -1140,7 +1143,7 @@ static bool allocate_buffers( opj_aligned_free(t1->flags); t1->flags = (flag_t*) opj_aligned_malloc(flagssize * sizeof(flag_t)); if(!t1->flags){ - return false; + return OPJ_FALSE; } t1->flagssize=flagssize; } @@ -1149,7 +1152,7 @@ static bool allocate_buffers( t1->w=w; t1->h=h; - return true; + return OPJ_TRUE; } /** mod fixed_quality */ @@ -1425,6 +1428,7 @@ void t1_encode_cblks( for (bandno = 0; bandno < res->numbands; ++bandno) { opj_tcd_band_t* restrict band = &res->bands[bandno]; + int bandconst = 8192 * 8192 / ((int) floor(band->stepsize * 8192)); for (precno = 0; precno < res->pw * res->ph; ++precno) { opj_tcd_precinct_t *prc = &band->precincts[precno]; @@ -1475,7 +1479,7 @@ void t1_encode_cblks( datap[(j * cblk_w) + i] = fix_mul( tmp, - 8192 * 8192 / ((int) floor(band->stepsize * 8192))) >> (11 - T1_NMSEDEC_FRACBITS); + bandconst) >> (11 - T1_NMSEDEC_FRACBITS); } } } @@ -1586,6 +1590,7 @@ void t1_decode_cblks( opj_free(cblk->segs); } /* cblkno */ opj_free(precinct->cblks.dec); + precinct->cblks.dec = NULL; } /* precno */ } /* bandno */ } /* resno */ diff --git a/indra/libopenjpeg/t1.h b/indra/libopenjpeg/t1.h index 0b4294e1d..572ec88d2 100644 --- a/indra/libopenjpeg/t1.h +++ b/indra/libopenjpeg/t1.h @@ -135,8 +135,8 @@ void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); /** Decode the code-blocks of a tile @param t1 T1 handle -@param tile The tile to decode -@param tcp Tile coding parameters +@param tilec The tile to decode +@param tccp Tile coding parameters */ void t1_decode_cblks(opj_t1_t* t1, opj_tcd_tilecomp_t* tilec, opj_tccp_t* tccp); /* ----------------------------------------------------------------------- */ diff --git a/indra/libopenjpeg/t2.c b/indra/libopenjpeg/t2.c index a76f4ed26..cae29f09b 100644 --- a/indra/libopenjpeg/t2.c +++ b/indra/libopenjpeg/t2.c @@ -59,11 +59,12 @@ Encode a packet of a tile to a destination buffer */ static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_codestream_info_t *cstr_info, int tileno); /** -@param seg +@param cblk +@param index @param cblksty @param first */ -static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first); +static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first); /** Decode a packet of a tile from a source buffer @param t2 T2 handle @@ -72,6 +73,7 @@ Decode a packet of a tile from a source buffer @param tile Tile for which to write the packets @param tcp Tile coding parameters @param pi Packet identity +@param pack_info Packet information @return */ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, @@ -147,8 +149,8 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera c[1] = 145; c[2] = 0; c[3] = 4; - c[4] = (tile->packno % 65536) / 256; - c[5] = (tile->packno % 65536) % 256; + c[4] = (unsigned char)((tile->packno % 65536) / 256); + c[5] = (unsigned char)((tile->packno % 65536) % 256); c += 6; } /* */ @@ -253,8 +255,8 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera /* */ /* << INDEX */ - // End of packet header position. Currently only represents the distance to start of packet - // Will be updated later by incrementing with packet start value + /* End of packet header position. Currently only represents the distance to start of packet + // Will be updated later by incrementing with packet start value */ if(cstr_info && cstr_info->index_write) { opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno]; info_PK->end_ph_pos = (int)(c - dest); @@ -294,9 +296,17 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera return (c - dest); } -static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) { +static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) { opj_tcd_seg_t* seg; - cblk->segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t)); + opj_tcd_seg_t* segs; + segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t)); + + if (segs == NULL) + { + return OPJ_FALSE; + } + cblk->segs = segs; + seg = &cblk->segs[index]; seg->data = NULL; seg->dataindex = 0; @@ -314,6 +324,8 @@ static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int fi } else { seg->maxpasses = 109; } + + return OPJ_TRUE; } static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, @@ -401,8 +413,8 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t } /* << INDEX */ - // End of packet header position. Currently only represents the distance to start of packet - // Will be updated later by incrementing with packet start value + /* End of packet header position. Currently only represents the distance to start of packet + // Will be updated later by incrementing with packet start value*/ if(pack_info) { pack_info->end_ph_pos = (int)(c - src); } @@ -460,12 +472,22 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t cblk->numlenbits += increment; segno = 0; if (!cblk->numsegs) { - t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1); + if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1)) + { + opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n"); + bio_destroy(bio); + return -999; + } } else { segno = cblk->numsegs - 1; if (cblk->segs[segno].numpasses == cblk->segs[segno].maxpasses) { ++segno; - t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0); + if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0)) + { + opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n"); + bio_destroy(bio); + return -999; + } } } n = cblk->numnewpasses; @@ -476,7 +498,12 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t n -= cblk->segs[segno].numnewpasses; if (n > 0) { ++segno; - t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0); + if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0)) + { + opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n"); + bio_destroy(bio); + return -999; + } } } while (n > 0); } @@ -494,14 +521,15 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t if (tcp->csty & J2K_CP_CSTY_EPH) { if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n"); + return -999; } else { hd += 2; } } /* << INDEX */ - // End of packet header position. Currently only represents the distance to start of packet - // Will be updated later by incrementing with packet start value + /* End of packet header position. Currently only represents the distance to start of packet + // Will be updated later by incrementing with packet start value*/ if(pack_info) { pack_info->end_ph_pos = (int)(hd - src); } @@ -565,7 +593,7 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t #endif /* USE_JPWL */ - cblk->data = (unsigned char*) opj_realloc(cblk->data, (cblk->len + seg->newlen) * sizeof(unsigned char*)); + cblk->data = (unsigned char*) opj_realloc(cblk->data, (cblk->len + seg->newlen) * sizeof(unsigned char)); memcpy(cblk->data + cblk->len, c, seg->newlen); if (seg->numpasses == 0) { seg->data = &cblk->data; @@ -659,8 +687,8 @@ int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlaye info_PK->start_pos = ((cp->tp_on | tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1; } info_PK->end_pos = info_PK->start_pos + e - 1; - info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance - // to start of packet is incremented by value of start of packet + info_PK->end_ph_pos += info_PK->start_pos - 1; /* End of packet header which now only represents the distance + // to start of packet is incremented by value of start of packet*/ } cstr_info->packno++; @@ -711,7 +739,11 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj } else { e = 0; } - + if(e == -999) + { + pi_destroy(pi, cp, tileno); + return -999; + } /* progression in resolution */ image->comps[pi[pino].compno].resno_decoded = (e > 0) ? @@ -725,8 +757,9 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno]; if (!cstr_info->packno) { info_PK->start_pos = info_TL->end_header + 1; - } else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ // New tile part - info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; // Number of packets in previous tile-part + } else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ /* New tile part*/ + info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in previous tile-part*/ + info_TL->tp[curtp].tp_start_pack = tp_start_packno; tp_start_packno = cstr_info->packno; curtp++; info_PK->start_pos = cstr_info->tile[tileno].tp[curtp].tp_end_header+1; @@ -734,8 +767,8 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj info_PK->start_pos = (cp->tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1; } info_PK->end_pos = info_PK->start_pos + e - 1; - info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance - // to start of packet is incremented by value of start of packet + info_PK->end_ph_pos += info_PK->start_pos - 1; /* End of packet header which now only represents the distance + // to start of packet is incremented by value of start of packet*/ cstr_info->packno++; } /* << INDEX */ @@ -749,7 +782,8 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj } /* INDEX >> */ if(cstr_info) { - cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; // Number of packets in last tile-part + cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in last tile-part*/ + cstr_info->tile[tileno].tp[curtp].tp_start_pack = tp_start_packno; } /* << INDEX */ diff --git a/indra/libopenjpeg/t2.h b/indra/libopenjpeg/t2.h index b15b75200..2151ba67f 100644 --- a/indra/libopenjpeg/t2.h +++ b/indra/libopenjpeg/t2.h @@ -67,6 +67,7 @@ Encode the packets of a tile to a destination buffer @param cstr_info Codestream information structure @param tpnum Tile part number of the current tile @param tppos The position of the tile part flag in the progression order +@param pino @param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass @param cur_totnum_tp The total number of tile parts in the current tile */ @@ -78,6 +79,7 @@ Decode the packets of a tile from a source buffer @param len length of the source buffer @param tileno number that identifies the tile for which to decode the packets @param tile tile for which to decode the packets +@param cstr_info Codestream information structure */ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info); diff --git a/indra/libopenjpeg/tcd.c b/indra/libopenjpeg/tcd.c index d29a0157b..c19b3eb6a 100644 --- a/indra/libopenjpeg/tcd.c +++ b/indra/libopenjpeg/tcd.c @@ -30,10 +30,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#define _ISOC99_SOURCE /* lrintf is C99 */ #include "opj_includes.h" void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) { - int tileno, compno, resno, bandno, precno;//, cblkno; + int tileno, compno, resno, bandno, precno;/*, cblkno;*/ fprintf(fd, "image {\n"); fprintf(fd, " tw=%d, th=%d x0=%d x1=%d y0=%d y1=%d\n", @@ -290,6 +291,7 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c for (i = 0; i < res->pw * res->ph * 3; i++) { band->precincts[i].imsbtree = NULL; band->precincts[i].incltree = NULL; + band->precincts[i].cblks.enc = NULL; } for (precno = 0; precno < res->pw * res->ph; precno++) { @@ -332,8 +334,10 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c cblk->y0 = int_max(cblkystart, prc->y0); cblk->x1 = int_min(cblkxend, prc->x1); cblk->y1 = int_min(cblkyend, prc->y1); - cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char)); + cblk->data = (unsigned char*) opj_calloc(9728+2, sizeof(unsigned char)); /* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */ + cblk->data[0] = 0; + cblk->data[1] = 0; cblk->data += 2; cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t)); cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t)); @@ -593,6 +597,8 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur cblk->y1 = int_min(cblkyend, prc->y1); cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char)); /* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */ + cblk->data[0] = 0; + cblk->data[1] = 0; cblk->data += 2; cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t)); cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t)); @@ -613,7 +619,7 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) { tcd->image = image; tcd->tcd_image->tw = cp->tw; tcd->tcd_image->th = cp->th; - tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcd_tile_t)); + tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_calloc(cp->tw * cp->th, sizeof(opj_tcd_tile_t)); /* Allocate place to store the decoded data = final image @@ -656,7 +662,7 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) { tilec->y1 = int_ceildiv(tile->y1, image->comps[i].dy); x0 = j == 0 ? tilec->x0 : int_min(x0, (unsigned int) tilec->x0); - y0 = j == 0 ? tilec->y0 : int_min(y0, (unsigned int) tilec->x0); + y0 = j == 0 ? tilec->y0 : int_min(y0, (unsigned int) tilec->y0); x1 = j == 0 ? tilec->x1 : int_max(x1, (unsigned int) tilec->x1); y1 = j == 0 ? tilec->y1 : int_max(y1, (unsigned int) tilec->y1); } @@ -676,6 +682,8 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, opj_tcp_t *tcp; opj_tcd_tile_t *tile; + OPJ_ARG_NOT_USED(cstr_info); + tcd->cp = cp; tcp = &(cp->tcps[cp->tileno[tileno]]); @@ -687,6 +695,12 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, opj_tccp_t *tccp = &tcp->tccps[compno]; opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + if (tccp->numresolutions <= 0) + { + cp->tileno[tileno] = -1; + return; + } + /* border of each tile component (global) */ tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx); tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy); @@ -997,7 +1011,7 @@ void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) { } } -bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) { +opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) { int compno, resno, bandno, precno, cblkno, passno, layno; double min, max; double cumdisto[100]; /* fixed_quality */ @@ -1149,7 +1163,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre } if (!success) { - return false; + return OPJ_FALSE; } if(cstr_info) { /* Threshold for Marcela Index */ @@ -1161,7 +1175,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]); } - return true; + return OPJ_TRUE; } int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) { @@ -1313,7 +1327,7 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op return l; } -bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info) { +opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info) { int l; int compno; int eof = 0; @@ -1349,7 +1363,7 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op } else { cstr_info->tile[tileno].pdx[resno] = 15; - cstr_info->tile[tileno].pdx[resno] = 15; + cstr_info->tile[tileno].pdy[resno] = 15; } } } @@ -1373,14 +1387,24 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op t1_time = opj_clock(); /* time needed to decode a tile */ t1 = t1_create(tcd->cinfo); + if (t1 == NULL) + { + opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n"); + t1_destroy(t1); + return OPJ_FALSE; + } + for (compno = 0; compno < tile->numcomps; ++compno) { opj_tcd_tilecomp_t* tilec = &tile->comps[compno]; /* The +3 is headroom required by the vectorized DWT */ tilec->data = (int*) opj_aligned_malloc((((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0))+3) * sizeof(int)); - if(tilec->data) - t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]); - else - opj_event_msg(tcd->cinfo, EVT_ERROR, "tcd_decode: tile size invalid\n"); + if (tilec->data == NULL) + { + opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n"); + return OPJ_FALSE; + } + + t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]); } t1_destroy(t1); t1_time = opj_clock() - t1_time; @@ -1394,18 +1418,20 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op int numres2decode; if (tcd->cp->reduce != 0) { - tcd->image->comps[compno].resno_decoded = - tile->comps[compno].numresolutions - tcd->cp->reduce - 1; - if (tcd->image->comps[compno].resno_decoded < 0) { + if ( tile->comps[compno].numresolutions < ( tcd->cp->reduce - 1 ) ) { opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. The number of resolutions to remove [%d+1] is higher than the number " - " of resolutions in the original codestream [%d]\nModify the cp_reduce parameter.\n", tcd->cp->reduce, tile->comps[compno].numresolutions); - return false; + " of resolutions in the original codestream [%d]\nModify the cp_reduce parameter.\n", tcd->cp->reduce, tile->comps[compno].numresolutions); + return OPJ_FALSE; + } + else { + tcd->image->comps[compno].resno_decoded = + tile->comps[compno].numresolutions - tcd->cp->reduce - 1; } } if(!tilec->data) { - opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. null data\n"); - return false; + opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. null data\n"); + return OPJ_FALSE; } numres2decode = tcd->image->comps[compno].resno_decoded + 1; @@ -1424,18 +1450,23 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op if (tcd->tcp->mct) { int n = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0); - if (tcd->tcp->tccps[0].qmfbid == 1) { - mct_decode( - tile->comps[0].data, - tile->comps[1].data, - tile->comps[2].data, - n); - } else { - mct_decode_real( - (float*)tile->comps[0].data, - (float*)tile->comps[1].data, - (float*)tile->comps[2].data, - n); + + if (tile->numcomps >= 3 ){ + if (tcd->tcp->tccps[0].qmfbid == 1) { + mct_decode( + tile->comps[0].data, + tile->comps[1].data, + tile->comps[2].data, + n); + } else { + mct_decode_real( + (float*)tile->comps[0].data, + (float*)tile->comps[1].data, + (float*)tile->comps[2].data, + n); + } + } else{ + opj_event_msg(tcd->cinfo, EVT_WARNING,"Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",tile->numcomps); } } @@ -1459,6 +1490,11 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op if(!imagec->data){ imagec->data = (int*) opj_malloc(imagec->w * imagec->h * sizeof(int)); } + if (!imagec->data) + { + opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n"); + return OPJ_FALSE; + } if(tcd->tcp->tccps[compno].qmfbid == 1) { for(j = res->y0; j < res->y1; ++j) { for(i = res->x0; i < res->x1; ++i) { @@ -1484,40 +1520,59 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time); if (eof) { - return false; + return OPJ_FALSE; } - return true; + return OPJ_TRUE; } void tcd_free_decode(opj_tcd_t *tcd) { opj_tcd_image_t *tcd_image = tcd->tcd_image; + int i = 0; + for (i = 0; i < tcd_image->tw * tcd_image->th; i++) + { + tcd_free_decode_tile(tcd, i); + } + opj_free(tcd_image->tiles); } void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno) { - int compno,resno,bandno,precno; + int compno,resno,bandno,precno,cblkno; opj_tcd_image_t *tcd_image = tcd->tcd_image; opj_tcd_tile_t *tile = &tcd_image->tiles[tileno]; - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - for (resno = 0; resno < tilec->numresolutions; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - for (precno = 0; precno < res->ph * res->pw; precno++) { - opj_tcd_precinct_t *prec = &band->precincts[precno]; - if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree); - if (prec->incltree != NULL) tgt_destroy(prec->incltree); + if (tile->comps != NULL) { + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->ph * res->pw; precno++) { + opj_tcd_precinct_t *prec = &band->precincts[precno]; + if (prec->cblks.dec != NULL) { + for (cblkno = 0; cblkno < prec->cw * prec->ch; ++cblkno) { + opj_tcd_cblk_dec_t* cblk = &prec->cblks.dec[cblkno]; + opj_free(cblk->data); + opj_free(cblk->segs); + } + opj_free(prec->cblks.dec); + } + if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree); + if (prec->incltree != NULL) tgt_destroy(prec->incltree); + + + } + opj_free(band->precincts); } - opj_free(band->precincts); } + opj_free(tilec->resolutions); } - opj_free(tilec->resolutions); + opj_free(tile->comps); + tile->comps = NULL; } - opj_free(tile->comps); } diff --git a/indra/libopenjpeg/tcd.h b/indra/libopenjpeg/tcd.h index f0ac5619f..e3f93adc3 100644 --- a/indra/libopenjpeg/tcd.h +++ b/indra/libopenjpeg/tcd.h @@ -251,7 +251,7 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final); void tcd_rateallocate_fixed(opj_tcd_t *tcd); void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final); -bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info); +opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info); /** Encode a tile from the raw image into a buffer @param tcd TCD handle @@ -268,8 +268,9 @@ Decode a tile from a buffer into a raw image @param src Source buffer @param len Length of source buffer @param tileno Number that identifies one of the tiles to be decoded +@param cstr_info Codestream information structure */ -bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info); +opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info); /** Free the memory allocated for decoding @param tcd TCD handle diff --git a/indra/libopenjpeg/thix_manager.c b/indra/libopenjpeg/thix_manager.c new file mode 100644 index 000000000..aa55f217c --- /dev/null +++ b/indra/libopenjpeg/thix_manager.c @@ -0,0 +1,120 @@ +/* + * $Id: thix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $ + * + * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2011, Professor Benoit Macq + * Copyright (c) 2003-2004, Yannick Verschueren + * Copyright (c) 2010-2011, Kaori Hagihara + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +/*! \file + * \brief Modification of jpip.c from 2KAN indexer + */ + +#include +#include +#include +#include "opj_includes.h" + +/* + * Write tile-part headers mhix box + * + * @param[in] coff offset of j2k codestream + * @param[in] cstr_info codestream information + * @param[in] tileno tile number + * @param[in] cio file output handle + * @return length of mhix box + */ +int write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_cio_t *cio); + +int write_thix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio) +{ + int len, lenp, i; + int tileno; + opj_jp2_box_t *box; + + lenp = 0; + box = (opj_jp2_box_t *)opj_calloc( cstr_info.tw*cstr_info.th, sizeof(opj_jp2_box_t)); + + for ( i = 0; i < 2 ; i++ ){ + if (i) + cio_seek( cio, lenp); + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_THIX, 4); /* THIX */ + write_manf( i, cstr_info.tw*cstr_info.th, box, cio); + + for (tileno = 0; tileno < cstr_info.tw*cstr_info.th; tileno++){ + box[tileno].length = write_tilemhix( coff, cstr_info, tileno, cio); + box[tileno].type = JPIP_MHIX; + } + + len = cio_tell( cio)-lenp; + cio_seek( cio, lenp); + cio_write( cio, len, 4); /* L */ + cio_seek( cio, lenp+len); + } + + opj_free(box); + + return len; +} + +int write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_cio_t *cio) +{ + int i; + opj_tile_info_t tile; + opj_tp_info_t tp; + int len, lenp; + opj_marker_info_t *marker; + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_MHIX, 4); /* MHIX */ + + tile = cstr_info.tile[tileno]; + tp = tile.tp[0]; + + cio_write( cio, tp.tp_end_header-tp.tp_start_pos+1, 8); /* TLEN */ + + marker = cstr_info.tile[tileno].marker; + + for( i=0; i +#include "opj_includes.h" + +#define MAX(a,b) ((a)>(b)?(a):(b)) + + +/* + * Write faix box of tpix + * + * @param[in] coff offset of j2k codestream + * @param[in] compno component number + * @param[in] cstr_info codestream information + * @param[in] j2klen length of j2k codestream + * @param[in] cio file output handle + * @return length of faix box + */ +int write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio); + + +int write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio) +{ + int len, lenp; + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_TPIX, 4); /* TPIX */ + + write_tpixfaix( coff, 0, cstr_info, j2klen, cio); + + len = cio_tell( cio)-lenp; + cio_seek( cio, lenp); + cio_write( cio, len, 4); /* L */ + cio_seek( cio, lenp+len); + + return len; +} + + +/* + * Get number of maximum tile parts per tile + * + * @param[in] cstr_info codestream information + * @return number of maximum tile parts per tile + */ +int get_num_max_tile_parts( opj_codestream_info_t cstr_info); + +int write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio) +{ + int len, lenp; + int i, j; + int Aux; + int num_max_tile_parts; + int size_of_coding; /* 4 or 8 */ + opj_tp_info_t tp; + int version; + + num_max_tile_parts = get_num_max_tile_parts( cstr_info); + + if( j2klen > pow( 2.0, 32)){ + size_of_coding = 8; + version = num_max_tile_parts == 1 ? 1:3; + } + else{ + size_of_coding = 4; + version = num_max_tile_parts == 1 ? 0:2; + } + + lenp = cio_tell( cio); + cio_skip( cio, 4); /* L [at the end] */ + cio_write( cio, JPIP_FAIX, 4); /* FAIX */ + cio_write( cio, version, 1); /* Version 0 = 4 bytes */ + + cio_write( cio, num_max_tile_parts, size_of_coding); /* NMAX */ + cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */ + for (i = 0; i < cstr_info.tw*cstr_info.th; i++){ + for (j = 0; j < cstr_info.tile[i].num_tps; j++){ + tp = cstr_info.tile[i].tp[j]; + cio_write( cio, tp.tp_start_pos-coff, size_of_coding); /* start position */ + cio_write( cio, tp.tp_end_pos-tp.tp_start_pos+1, size_of_coding); /* length */ + if (version & 0x02){ + if( cstr_info.tile[i].num_tps == 1 && cstr_info.numdecompos[compno] > 1) + Aux = cstr_info.numdecompos[compno] + 1; + else + Aux = j + 1; + + cio_write( cio, Aux,4); + /*cio_write(img.tile[i].tile_parts[j].num_reso_AUX,4);*/ /* Aux_i,j : Auxiliary value */ + /* fprintf(stderr,"AUX value %d\n",Aux);*/ + } + /*cio_write(0,4);*/ + } + /* PADDING */ + while (j < num_max_tile_parts){ + cio_write( cio, 0, size_of_coding); /* start position */ + cio_write( cio, 0, size_of_coding); /* length */ + if (version & 0x02) + cio_write( cio, 0,4); /* Aux_i,j : Auxiliary value */ + j++; + } + } + + len = cio_tell( cio)-lenp; + cio_seek( cio, lenp); + cio_write( cio, len, 4); /* L */ + cio_seek( cio, lenp+len); + + return len; + +} + +int get_num_max_tile_parts( opj_codestream_info_t cstr_info) +{ + int num_max_tp = 0, i; + + for( i=0; i + +using namespace LLAvatarAppearanceDefines; + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +const std::string AVATAR_DEFAULT_CHAR = "avatar"; +const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0); + +/********************************************************************************* + ** ** + ** Begin private LLAvatarAppearance Support classes + ** + **/ + +//------------------------------------------------------------------------ +// LLAvatarBoneInfo +// Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton. +//------------------------------------------------------------------------ +class LLAvatarBoneInfo +{ + friend class LLAvatarAppearance; + friend class LLAvatarSkeletonInfo; +public: + LLAvatarBoneInfo() : mIsJoint(FALSE) {} + ~LLAvatarBoneInfo() + { + std::for_each(mChildList.begin(), mChildList.end(), DeletePointer()); + } + BOOL parseXml(LLXmlTreeNode* node); + +private: + std::string mName; + BOOL mIsJoint; + LLVector3 mPos; + LLVector3 mRot; + LLVector3 mScale; + LLVector3 mPivot; + typedef std::vector child_list_t; + child_list_t mChildList; +}; + +//------------------------------------------------------------------------ +// LLAvatarSkeletonInfo +// Overall avatar skeleton +//------------------------------------------------------------------------ +class LLAvatarSkeletonInfo +{ + friend class LLAvatarAppearance; +public: + LLAvatarSkeletonInfo() : + mNumBones(0), mNumCollisionVolumes(0) {} + ~LLAvatarSkeletonInfo() + { + std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer()); + } + BOOL parseXml(LLXmlTreeNode* node); + S32 getNumBones() const { return mNumBones; } + S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; } + +private: + S32 mNumBones; + S32 mNumCollisionVolumes; + typedef std::vector bone_info_list_t; + bone_info_list_t mBoneInfoList; +}; + +//----------------------------------------------------------------------------- +// LLAvatarXmlInfo +//----------------------------------------------------------------------------- + +LLAvatarAppearance::LLAvatarXmlInfo::LLAvatarXmlInfo() + : mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0) +{ +} + +LLAvatarAppearance::LLAvatarXmlInfo::~LLAvatarXmlInfo() +{ + std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer()); + std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer()); + std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer()); + deleteAndClear(mTexSkinColorInfo); + deleteAndClear(mTexHairColorInfo); + deleteAndClear(mTexEyeColorInfo); + std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer()); + std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer()); + std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer()); +} + + +/** + ** + ** End LLAvatarAppearance Support classes + ** ** + *********************************************************************************/ + +//----------------------------------------------------------------------------- +// Static Data +//----------------------------------------------------------------------------- +LLXmlTree LLAvatarAppearance::sXMLTree; +LLXmlTree LLAvatarAppearance::sSkeletonXMLTree; +LLAvatarSkeletonInfo* LLAvatarAppearance::sAvatarSkeletonInfo = NULL; +LLAvatarAppearance::LLAvatarXmlInfo* LLAvatarAppearance::sAvatarXmlInfo = NULL; + + +LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : + LLCharacter(), + mIsDummy(FALSE), + mTexSkinColor( NULL ), + mTexHairColor( NULL ), + mTexEyeColor( NULL ), + mPelvisToFoot(0.f), + mHeadOffset(), + mRoot(NULL), + mWearableData(wearable_data) +{ + LLMemType mt(LLMemType::MTYPE_AVATAR); + + llassert_always(mWearableData); + mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES); + for (U32 i = 0; i < mBakedTextureDatas.size(); i++ ) + { + mBakedTextureDatas[i].mLastTextureID = IMG_DEFAULT_AVATAR; + mBakedTextureDatas[i].mTexLayerSet = NULL; + mBakedTextureDatas[i].mIsLoaded = false; + mBakedTextureDatas[i].mIsUsed = false; + mBakedTextureDatas[i].mMaskTexName = 0; + mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i); + } + + mIsBuilt = FALSE; + + mNumCollisionVolumes = 0; + mCollisionVolumes = NULL; +} + +// virtual +void LLAvatarAppearance::initInstance() +{ + //------------------------------------------------------------------------- + // initialize joint, mesh and shape members + //------------------------------------------------------------------------- + mRoot = createAvatarJoint(); + mRoot->setName( "mRoot" ); + + for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end(); + ++iter) + { + const EMeshIndex mesh_index = iter->first; + const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second; + LLAvatarJoint* joint = createAvatarJoint(); + joint->setName(mesh_dict->mName); + joint->setMeshID(mesh_index); + mMeshLOD.push_back(joint); + + /* mHairLOD.setName("mHairLOD"); + mHairMesh0.setName("mHairMesh0"); + mHairMesh0.setMeshID(MESH_ID_HAIR); + mHairMesh1.setName("mHairMesh1"); */ + for (U32 lod = 0; lod < mesh_dict->mLOD; lod++) + { + LLAvatarJointMesh* mesh = createAvatarJointMesh(); + std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast(lod); + // We pre-pended an m - need to capitalize first character for camelCase + mesh_name[1] = toupper(mesh_name[1]); + mesh->setName(mesh_name); + mesh->setMeshID(mesh_index); + mesh->setPickName(mesh_dict->mPickName); + mesh->setIsTransparent(FALSE); + switch((int)mesh_index) + { + case MESH_ID_HAIR: + mesh->setIsTransparent(TRUE); + break; + case MESH_ID_SKIRT: + mesh->setIsTransparent(TRUE); + break; + case MESH_ID_EYEBALL_LEFT: + case MESH_ID_EYEBALL_RIGHT: + mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); + break; + } + + joint->mMeshParts.push_back(mesh); + } + } + + //------------------------------------------------------------------------- + // associate baked textures with meshes + //------------------------------------------------------------------------- + for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end(); + ++iter) + { + const EMeshIndex mesh_index = iter->first; + const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second; + const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID; + // Skip it if there's no associated baked texture. + if (baked_texture_index == BAKED_NUM_INDICES) continue; + + for (avatar_joint_mesh_list_t::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin(); + iter != mMeshLOD[mesh_index]->mMeshParts.end(); + ++iter) + { + LLAvatarJointMesh* mesh = (*iter); + mBakedTextureDatas[(int)baked_texture_index].mJointMeshes.push_back(mesh); + } + } + + if (gNoRender) + { + return; + } + buildCharacter(); + +} + +// virtual +LLAvatarAppearance::~LLAvatarAppearance() +{ + deleteAndClear(mTexSkinColor); + deleteAndClear(mTexHairColor); + deleteAndClear(mTexEyeColor); + + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + deleteAndClear(mBakedTextureDatas[i].mTexLayerSet); + mBakedTextureDatas[i].mJointMeshes.clear(); + + for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin(); + iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++) + { + LLMaskedMorph* masked_morph = (*iter2); + delete masked_morph; + } + } + + if (mRoot) mRoot->removeAllChildren(); + deleteAndClear(mRoot); + mJointMap.clear(); + + clearSkeleton(); + deleteAndClearArray(mCollisionVolumes); + + std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer()); + mPolyMeshes.clear(); + + for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin(); + jointIter != mMeshLOD.end(); + ++jointIter) + { + LLAvatarJoint* joint = *jointIter; + std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer()); + joint->mMeshParts.clear(); + } + std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer()); + mMeshLOD.clear(); +} + +//static +void LLAvatarAppearance::initClass() +{ + std::string xmlFile; + + xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml"; + BOOL success = sXMLTree.parseFile( xmlFile, FALSE ); + if (!success) + { + llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl; + } + + // now sanity check xml file + LLXmlTreeNode* root = sXMLTree.getRoot(); + if (!root) + { + llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl; + return; + } + + //------------------------------------------------------------------------- + // (root) + //------------------------------------------------------------------------- + if( !root->hasName( "linden_avatar" ) ) + { + llerrs << "Invalid avatar file header: " << xmlFile << llendl; + } + + std::string version; + static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); + if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) + { + llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl; + } + + S32 wearable_def_version = 1; + static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version"); + root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version ); + LLWearable::setCurrentDefinitionVersion( wearable_def_version ); + + std::string mesh_file_name; + + LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" ); + if (!skeleton_node) + { + llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl; + 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)) + { + llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl; + } + + std::string skeleton_path; + skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name); + if (!parseSkeletonFile(skeleton_path)) + { + llerrs << "Error parsing skeleton file: " << skeleton_path << llendl; + } + + // Process XML data + + // avatar_skeleton.xml + if (sAvatarSkeletonInfo) + { //this can happen if a login attempt failed + delete sAvatarSkeletonInfo; + } + sAvatarSkeletonInfo = new LLAvatarSkeletonInfo; + if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot())) + { + llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl; + } + // parse avatar_lad.xml + if (sAvatarXmlInfo) + { //this can happen if a login attempt failed + deleteAndClear(sAvatarXmlInfo); + } + sAvatarXmlInfo = new LLAvatarXmlInfo; + if (!sAvatarXmlInfo->parseXmlSkeletonNode(root)) + { + llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; + } + if (!sAvatarXmlInfo->parseXmlMeshNodes(root)) + { + llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; + } + if (!sAvatarXmlInfo->parseXmlColorNodes(root)) + { + llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; + } + if (!sAvatarXmlInfo->parseXmlLayerNodes(root)) + { + llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; + } + if (!sAvatarXmlInfo->parseXmlDriverNodes(root)) + { + llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; + } + if (!sAvatarXmlInfo->parseXmlMorphNodes(root)) + { + llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; + } +} + +void LLAvatarAppearance::cleanupClass() +{ + deleteAndClear(sAvatarXmlInfo); + deleteAndClear(sAvatarSkeletonInfo); + sSkeletonXMLTree.cleanup(); + sXMLTree.cleanup(); +} + +using namespace LLAvatarAppearanceDefines; + +//------------------------------------------------------------------------ +// The viewer can only suggest a good size for the agent, +// the simulator will keep it inside a reasonable range. +void LLAvatarAppearance::computeBodySize() +{ + LLVector3 pelvis_scale = mPelvisp->getScale(); + + // some of the joints have not been cached + LLVector3 skull = mSkullp->getPosition(); + //LLVector3 skull_scale = mSkullp->getScale(); + + LLVector3 neck = mNeckp->getPosition(); + LLVector3 neck_scale = mNeckp->getScale(); + + LLVector3 chest = mChestp->getPosition(); + LLVector3 chest_scale = mChestp->getScale(); + + // the rest of the joints have been cached + LLVector3 head = mHeadp->getPosition(); + LLVector3 head_scale = mHeadp->getScale(); + + LLVector3 torso = mTorsop->getPosition(); + LLVector3 torso_scale = mTorsop->getScale(); + + LLVector3 hip = mHipLeftp->getPosition(); + LLVector3 hip_scale = mHipLeftp->getScale(); + + LLVector3 knee = mKneeLeftp->getPosition(); + LLVector3 knee_scale = mKneeLeftp->getScale(); + + LLVector3 ankle = mAnkleLeftp->getPosition(); + LLVector3 ankle_scale = mAnkleLeftp->getScale(); + + LLVector3 foot = mFootLeftp->getPosition(); + + mPelvisToFoot = 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]; + + LLVector3 new_body_size; + new_body_size.mV[VZ] = mPelvisToFoot + + // 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; + + if (new_body_size != mBodySize) + { + mBodySize = new_body_size; + bodySizeChanged(); + } +} + +//----------------------------------------------------------------------------- +// parseSkeletonFile() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename) +{ + LLMemType mt(LLMemType::MTYPE_AVATAR); + + //------------------------------------------------------------------------- + // parse the file + //------------------------------------------------------------------------- + BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE ); + + if (!parsesuccess) + { + llerrs << "Can't parse skeleton file: " << filename << llendl; + return FALSE; + } + + // now sanity check xml file + LLXmlTreeNode* root = sSkeletonXMLTree.getRoot(); + if (!root) + { + llerrs << "No root node found in avatar skeleton file: " << filename << llendl; + return FALSE; + } + + if( !root->hasName( "linden_skeleton" ) ) + { + llerrs << "Invalid avatar skeleton file header: " << filename << llendl; + return FALSE; + } + + std::string version; + static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); + if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) + { + llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl; + return FALSE; + } + + return TRUE; +} + +//----------------------------------------------------------------------------- +// setupBone() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &volume_num, S32 &joint_num) +{ + LLMemType mt(LLMemType::MTYPE_AVATAR); + + LLJoint* joint = NULL; + + if (info->mIsJoint) + { + joint = getCharacterJoint(joint_num); + if (!joint) + { + llwarns << "Too many bones" << llendl; + return FALSE; + } + joint->setName( info->mName ); + } + else // collision volume + { + if (volume_num >= (S32)mNumCollisionVolumes) + { + llwarns << "Too many bones" << llendl; + return FALSE; + } + joint = (&mCollisionVolumes[volume_num]); + joint->setName( info->mName ); + } + + // add to parent + if (parent) + { + parent->addChild( joint ); + } + + joint->setPosition(info->mPos); + joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY], + info->mRot.mV[VZ], LLQuaternion::XYZ)); + joint->setScale(info->mScale); + + joint->setDefaultFromCurrentXform(); + + if (info->mIsJoint) + { + joint->setSkinOffset( info->mPivot ); + joint_num++; + } + else // collision volume + { + volume_num++; + } + + // setup children + LLAvatarBoneInfo::child_list_t::const_iterator iter; + for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter) + { + LLAvatarBoneInfo *child_info = *iter; + if (!setupBone(child_info, joint, volume_num, joint_num)) + { + return FALSE; + } + } + + return TRUE; +} + +//----------------------------------------------------------------------------- +// allocateCharacterJoints() +//----------------------------------------------------------------------------- +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.empty() || !mSkeleton[0]) + { + return FALSE; + } + + return TRUE; +} + + +//----------------------------------------------------------------------------- +// buildSkeleton() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info) +{ + LLMemType mt(LLMemType::MTYPE_AVATAR); + + + if (!info) + return FALSE; + //------------------------------------------------------------------------- + // allocate joints + //------------------------------------------------------------------------- + if (!allocateCharacterJoints(info->mNumBones)) + { + llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl; + return FALSE; + } + + //------------------------------------------------------------------------- + // allocate volumes + //------------------------------------------------------------------------- + if (info->mNumCollisionVolumes) + { + if (!allocateCollisionVolumes(info->mNumCollisionVolumes)) + { + llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl; + return FALSE; + } + } + + S32 current_joint_num = 0; + S32 current_volume_num = 0; + 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)) + { + llerrs << "Error parsing bone in skeleton file" << llendl; + return FALSE; + } + } + + return TRUE; +} + +//----------------------------------------------------------------------------- +// clearSkeleton() +//----------------------------------------------------------------------------- +void LLAvatarAppearance::clearSkeleton() +{ + std::for_each(mSkeleton.begin(), mSkeleton.end(), DeletePointer()); + mSkeleton.clear(); +} + +//----------------------------------------------------------------------------- +// LLAvatarAppearance::buildCharacter() +// Deferred initialization and rebuild of the avatar. +//----------------------------------------------------------------------------- +void LLAvatarAppearance::buildCharacter() +{ + LLMemType mt(LLMemType::MTYPE_AVATAR); + + //------------------------------------------------------------------------- + // remove all references to our existing skeleton + // so we can rebuild it + //------------------------------------------------------------------------- + flushAllMotions(); + + //------------------------------------------------------------------------- + // remove all of mRoot's children + //------------------------------------------------------------------------- + mRoot->removeAllChildren(); + mJointMap.clear(); + mIsBuilt = FALSE; + + //------------------------------------------------------------------------- + // clear mesh data + //------------------------------------------------------------------------- + for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin(); + jointIter != mMeshLOD.end(); ++jointIter) + { + LLAvatarJoint* joint = *jointIter; + for (avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin(); + meshIter != joint->mMeshParts.end(); ++meshIter) + { + LLAvatarJointMesh * mesh = *meshIter; + mesh->setMesh(NULL); + } + } + + //------------------------------------------------------------------------- + // (re)load our skeleton and meshes + //------------------------------------------------------------------------- + LLTimer timer; + + BOOL status = loadAvatar(); + stop_glerror(); + + if (gNoRender) + { + // Still want to load the avatar skeleton so visual parameters work. + return; + } + +// gPrintMessagesThisFrame = TRUE; + lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl; + + if (!status) + { + if (isSelf()) + { + llerrs << "Unable to load user's avatar" << llendl; + } + else + { + llwarns << "Unable to load other's avatar" << llendl; + } + return; + } + + //------------------------------------------------------------------------- + // initialize "well known" joint pointers + //------------------------------------------------------------------------- + mPelvisp = mRoot->findJoint("mPelvis"); + mTorsop = mRoot->findJoint("mTorso"); + mChestp = mRoot->findJoint("mChest"); + mNeckp = mRoot->findJoint("mNeck"); + mHeadp = mRoot->findJoint("mHead"); + mSkullp = mRoot->findJoint("mSkull"); + mHipLeftp = mRoot->findJoint("mHipLeft"); + mHipRightp = mRoot->findJoint("mHipRight"); + mKneeLeftp = mRoot->findJoint("mKneeLeft"); + mKneeRightp = mRoot->findJoint("mKneeRight"); + mAnkleLeftp = mRoot->findJoint("mAnkleLeft"); + mAnkleRightp = mRoot->findJoint("mAnkleRight"); + mFootLeftp = mRoot->findJoint("mFootLeft"); + mFootRightp = mRoot->findJoint("mFootRight"); + mWristLeftp = mRoot->findJoint("mWristLeft"); + mWristRightp = mRoot->findJoint("mWristRight"); + mEyeLeftp = mRoot->findJoint("mEyeLeft"); + mEyeRightp = mRoot->findJoint("mEyeRight"); + + //------------------------------------------------------------------------- + // Make sure "well known" pointers exist + //------------------------------------------------------------------------- + if (!(mPelvisp && + mTorsop && + mChestp && + mNeckp && + mHeadp && + mSkullp && + mHipLeftp && + mHipRightp && + mKneeLeftp && + mKneeRightp && + mAnkleLeftp && + mAnkleRightp && + mFootLeftp && + mFootRightp && + mWristLeftp && + mWristRightp && + mEyeLeftp && + mEyeRightp)) + { + llerrs << "Failed to create avatar." << llendl; + return; + } + + //------------------------------------------------------------------------- + // initialize the pelvis + //------------------------------------------------------------------------- + mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) ); + + mIsBuilt = TRUE; + stop_glerror(); + +} + +//----------------------------------------------------------------------------- +// loadAvatar() +//----------------------------------------------------------------------------- +//static LLFastTimer::DeclareTimer FTM_LOAD_AVATAR("Load Avatar"); + +BOOL LLAvatarAppearance::loadAvatar() +{ +// LLFastTimer t(FTM_LOAD_AVATAR); + + // avatar_skeleton.xml + if( !buildSkeleton(sAvatarSkeletonInfo) ) + { + llwarns << "avatar file: buildSkeleton() failed" << llendl; + return FALSE; + } + + // avatar_lad.xml : + if( !loadSkeletonNode() ) + { + llwarns << "avatar file: loadNodeSkeleton() failed" << llendl; + return FALSE; + } + + // avatar_lad.xml : + if( !loadMeshNodes() ) + { + llwarns << "avatar file: loadNodeMesh() failed" << llendl; + return FALSE; + } + + // avatar_lad.xml : + if( sAvatarXmlInfo->mTexSkinColorInfo ) + { + mTexSkinColor = new LLTexGlobalColor( this ); + if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) ) + { + llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl; + return FALSE; + } + } + else + { + llwarns << " name=\"skin_color\" not found" << llendl; + return FALSE; + } + if( sAvatarXmlInfo->mTexHairColorInfo ) + { + mTexHairColor = new LLTexGlobalColor( this ); + if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) ) + { + llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl; + return FALSE; + } + } + else + { + llwarns << " name=\"hair_color\" not found" << llendl; + return FALSE; + } + if( sAvatarXmlInfo->mTexEyeColorInfo ) + { + mTexEyeColor = new LLTexGlobalColor( this ); + if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) ) + { + llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl; + return FALSE; + } + } + else + { + llwarns << " name=\"eye_color\" not found" << llendl; + return FALSE; + } + + // avatar_lad.xml : + if (sAvatarXmlInfo->mLayerInfoList.empty()) + { + llwarns << "avatar file: missing node" << llendl; + return FALSE; + } + + if (sAvatarXmlInfo->mMorphMaskInfoList.empty()) + { + llwarns << "avatar file: missing node" << llendl; + return FALSE; + } + + // avatar_lad.xml : + for (LLAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin(); + iter != sAvatarXmlInfo->mMorphMaskInfoList.end(); + ++iter) + { + LLAvatarXmlInfo::LLAvatarMorphInfo *info = *iter; + + EBakedTextureIndex baked = LLAvatarAppearanceDictionary::findBakedByRegionName(info->mRegion); + if (baked != BAKED_NUM_INDICES) + { + LLVisualParam* morph_param; + const std::string *name = &info->mName; + morph_param = getVisualParam(name->c_str()); + if (morph_param) + { + BOOL invert = info->mInvert; + addMaskedMorph(baked, morph_param, invert, info->mLayer); + } + } + + } + + loadLayersets(); + + // avatar_lad.xml : + for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin(); + iter != sAvatarXmlInfo->mDriverInfoList.end(); + ++iter) + { + LLDriverParamInfo *info = *iter; + LLDriverParam* driver_param = new LLDriverParam( this ); + if (driver_param->setInfo(info)) + { + addVisualParam( driver_param ); + driver_param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER); + LLVisualParam*(LLAvatarAppearance::*avatar_function)(S32)const = &LLAvatarAppearance::getVisualParam; + if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLAvatarAppearance*)this,_1 ), false)) + { + llwarns << "could not link driven params for avatar " << this->getFullname() << " param id: " << driver_param->getID() << llendl; + continue; + } + } + else + { + delete driver_param; + llwarns << "avatar file: driver_param->parseData() failed" << llendl; + return FALSE; + } + } + + + return TRUE; +} + +//----------------------------------------------------------------------------- +// loadSkeletonNode(): loads node from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::loadSkeletonNode () +{ + mRoot->addChild( mSkeleton[0] ); + + // make meshes children before calling parent version of the function + for (avatar_joint_list_t::iterator iter = mMeshLOD.begin(); + iter != mMeshLOD.end(); + ++iter) + { + LLAvatarJoint *joint = *iter; + joint->mUpdateXform = FALSE; + joint->setMeshesToChildren(); + } + + mRoot->addChild(mMeshLOD[MESH_ID_HEAD]); + mRoot->addChild(mMeshLOD[MESH_ID_EYELASH]); + mRoot->addChild(mMeshLOD[MESH_ID_UPPER_BODY]); + mRoot->addChild(mMeshLOD[MESH_ID_LOWER_BODY]); + mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]); + mRoot->addChild(mMeshLOD[MESH_ID_HEAD]); + + LLAvatarJoint *skull = (LLAvatarJoint*)mRoot->findJoint("mSkull"); + if (skull) + { + skull->addChild(mMeshLOD[MESH_ID_HAIR] ); + } + + LLAvatarJoint *eyeL = (LLAvatarJoint*)mRoot->findJoint("mEyeLeft"); + if (eyeL) + { + eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] ); + } + + LLAvatarJoint *eyeR = (LLAvatarJoint*)mRoot->findJoint("mEyeRight"); + if (eyeR) + { + eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] ); + } + + // SKELETAL DISTORTIONS + { + LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter; + for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin(); + iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); + ++iter) + { + LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter; + LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this); + if (!param->setInfo(info)) + { + delete param; + return FALSE; + } + else + { + addVisualParam(param); + param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER); + } + } + } + + + return TRUE; +} + +//----------------------------------------------------------------------------- +// loadMeshNodes(): loads nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::loadMeshNodes() +{ + for (LLAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin(); + meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end(); + ++meshinfo_iter) + { + const LLAvatarXmlInfo::LLAvatarMeshInfo *info = *meshinfo_iter; + const std::string &type = info->mType; + S32 lod = info->mLOD; + + LLAvatarJointMesh* mesh = NULL; + U8 mesh_id = 0; + BOOL found_mesh_id = FALSE; + + /* if (type == "hairMesh") + switch(lod) + case 0: + mesh = &mHairMesh0; */ + for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin(); + mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end(); + ++mesh_iter) + { + const EMeshIndex mesh_index = mesh_iter->first; + const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = mesh_iter->second; + if (type.compare(mesh_dict->mName) == 0) + { + mesh_id = mesh_index; + found_mesh_id = TRUE; + break; + } + } + + if (found_mesh_id) + { + if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size()) + { + mesh = mMeshLOD[mesh_id]->mMeshParts[lod]; + } + else + { + llwarns << "Avatar file: has invalid lod setting " << lod << llendl; + return FALSE; + } + } + else + { + llwarns << "Ignoring unrecognized mesh type: " << type << llendl; + return FALSE; + } + + // llinfos << "Parsing mesh data for " << type << "..." << llendl; + + // If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings. + // Do not touch!!! + mesh->setColor( LLColor4::white ); + + LLPolyMesh *poly_mesh = NULL; + + if (!info->mReferenceMeshName.empty()) + { + polymesh_map_t::const_iterator polymesh_iter = mPolyMeshes.find(info->mReferenceMeshName); + if (polymesh_iter != mPolyMeshes.end()) + { + poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second); + poly_mesh->setAvatar(this); + } + else + { + // This should never happen + LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL; + } + } + else + { + poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName); + poly_mesh->setAvatar(this); + } + + if( !poly_mesh ) + { + llwarns << "Failed to load mesh of type " << type << llendl; + return FALSE; + } + + // Multimap insert + mPolyMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh)); + + mesh->setMesh( poly_mesh ); + mesh->setLOD( info->mMinPixelArea ); + + for (LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin(); + xmlinfo_iter != info->mPolyMorphTargetInfoList.end(); + ++xmlinfo_iter) + { + const LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter); + LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh()); + if (!param->setInfo((LLPolyMorphTargetInfo*)info_pair->first)) + { + delete param; + return FALSE; + } + else + { + if (info_pair->second) + { + addSharedVisualParam(param); + param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER); + } + else + { + addVisualParam(param); + param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER); + } + } + } + } + + return TRUE; +} + +//----------------------------------------------------------------------------- +// loadLayerSets() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::loadLayersets() +{ + BOOL success = TRUE; + for (LLAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin(); + layerset_iter != sAvatarXmlInfo->mLayerInfoList.end(); + ++layerset_iter) + { + LLTexLayerSetInfo *layerset_info = *layerset_iter; + if (isSelf()) + { + // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such. + LLTexLayerSet* layer_set = createTexLayerSet(); + + if (!layer_set->setInfo(layerset_info)) + { + stop_glerror(); + delete layer_set; + llwarns << "avatar file: layer_set->setInfo() failed" << llendl; + return FALSE; + } + + // scan baked textures and associate the layerset with the appropriate one + EBakedTextureIndex baked_index = BAKED_NUM_INDICES; + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin(); + baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end(); + ++baked_iter) + { + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; + if (layer_set->isBodyRegion(baked_dict->mName)) + { + baked_index = baked_iter->first; + // ensure both structures are aware of each other + mBakedTextureDatas[baked_index].mTexLayerSet = layer_set; + layer_set->setBakedTexIndex(baked_index); + break; + } + } + // if no baked texture was found, warn and cleanup + if (baked_index == BAKED_NUM_INDICES) + { + llwarns << " has invalid body_region attribute" << llendl; + delete layer_set; + return FALSE; + } + + // scan morph masks and let any affected layers know they have an associated morph + for (LLAvatarAppearance::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin(); + morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end(); + ++morph_iter) + { + LLMaskedMorph *morph = *morph_iter; + LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer); + if (layer) + { + layer->setHasMorph(TRUE); + } + else + { + llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl; + success = FALSE; + } + } + } + else // !isSelf() + { + // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such. + LLTexLayerSetInfo *layerset_info = *layerset_iter; + layerset_info->createVisualParams(this); + } + } + return success; +} + +//----------------------------------------------------------------------------- +// getCharacterJoint() +//----------------------------------------------------------------------------- +LLJoint *LLAvatarAppearance::getCharacterJoint( U32 num ) +{ + if ((S32)num >= mSkeleton.size() + || (S32)num < 0) + { + return NULL; + } + return mSkeleton[num]; +} + + +//----------------------------------------------------------------------------- +// getVolumePos() +//----------------------------------------------------------------------------- +LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_offset) +{ + if(joint_index < 0) + { + return LLVector3::zero; + } + + if (joint_index > mNumCollisionVolumes) + { + return LLVector3::zero; + } + + return mCollisionVolumes[joint_index].getVolumePos(volume_offset); +} + +//----------------------------------------------------------------------------- +// findCollisionVolume() +//----------------------------------------------------------------------------- +LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id) +{ + //SNOW-488: As mNumCollisionVolumes is a S32 and we are casting from a U32 to a S32 + //to compare we also need to be sure of the wrap around case producing (S32) <0 + //or in terms of the U32 an out of bounds index in the array. + if ((S32)volume_id > mNumCollisionVolumes || (S32)volume_id<0) + { + return NULL; + } + + return &mCollisionVolumes[volume_id]; +} + +//----------------------------------------------------------------------------- +// findCollisionVolume() +//----------------------------------------------------------------------------- +S32 LLAvatarAppearance::getCollisionVolumeID(std::string &name) +{ + for (S32 i = 0; i < mNumCollisionVolumes; i++) + { + if (mCollisionVolumes[i].getName() == name) + { + return i; + } + } + + return -1; +} + +//----------------------------------------------------------------------------- +// LLAvatarAppearance::getHeadMesh() +//----------------------------------------------------------------------------- +LLPolyMesh* LLAvatarAppearance::getHeadMesh() +{ + return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh(); +} + + +//----------------------------------------------------------------------------- +// LLAvatarAppearance::getUpperBodyMesh() +//----------------------------------------------------------------------------- +LLPolyMesh* LLAvatarAppearance::getUpperBodyMesh() +{ + return mMeshLOD[MESH_ID_UPPER_BODY]->mMeshParts[0]->getMesh(); +} + + +//----------------------------------------------------------------------------- +// getMesh( LLPolyMeshSharedData *shared_data ) +//----------------------------------------------------------------------------- +LLPolyMesh* LLAvatarAppearance::getMesh( LLPolyMeshSharedData *shared_data ) +{ + for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) + { + LLPolyMesh* mesh = i->second; + if (mesh->getSharedData() == shared_data) + { + return mesh; + } + } + return NULL; +} + +// static +void LLAvatarAppearance::getMeshInfo (mesh_info_t* mesh_info) +{ + if (!mesh_info) return; + + LLAvatarXmlInfo::mesh_info_list_t::iterator iter = sAvatarXmlInfo->mMeshInfoList.begin(); + LLAvatarXmlInfo::mesh_info_list_t::iterator end = sAvatarXmlInfo->mMeshInfoList.end(); + + for (; iter != end; ++iter) + { + LLAvatarXmlInfo::LLAvatarMeshInfo* avatar_info = (*iter); + std::string type = avatar_info->mType; + S32 lod = avatar_info->mLOD; + std::string file = avatar_info->mMeshFileName; + + mesh_info_t::iterator iter_info = mesh_info->find(type); + if(iter_info == mesh_info->end()) + { + lod_mesh_map_t lod_mesh; + lod_mesh.insert(std::pair(lod, file)); + mesh_info->insert(std::pair(type, lod_mesh)); + } + else + { + lod_mesh_map_t& lod_mesh = iter_info->second; + lod_mesh_map_t::iterator iter_lod = lod_mesh.find(lod); + if (iter_lod == lod_mesh.end()) + { + lod_mesh.insert(std::pair(lod, file)); + } + else + { + // Should never happen + llwarns << "Duplicate mesh LOD " << type << " " << lod << " " << file << llendl; + } + } + } + return; +} + +// virtual +BOOL LLAvatarAppearance::isValid() const +{ + // This should only be called on ourself. + if (!isSelf()) + { + llerrs << "Called LLAvatarAppearance::isValid() on when isSelf() == false" << llendl; + } + return TRUE; +} + + +// adds a morph mask to the appropriate baked texture structure +void LLAvatarAppearance::addMaskedMorph(EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer) +{ + if (index < BAKED_NUM_INDICES) + { + LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer); + mBakedTextureDatas[index].mMaskedMorphs.push_front(morph); + } +} + + +//static +BOOL LLAvatarAppearance::teToColorParams( ETextureIndex te, U32 *param_name ) +{ + switch( te ) + { + case TEX_UPPER_SHIRT: + param_name[0] = 803; //"shirt_red"; + param_name[1] = 804; //"shirt_green"; + param_name[2] = 805; //"shirt_blue"; + break; + + case TEX_LOWER_PANTS: + param_name[0] = 806; //"pants_red"; + param_name[1] = 807; //"pants_green"; + param_name[2] = 808; //"pants_blue"; + break; + + case TEX_LOWER_SHOES: + param_name[0] = 812; //"shoes_red"; + param_name[1] = 813; //"shoes_green"; + param_name[2] = 817; //"shoes_blue"; + break; + + case TEX_LOWER_SOCKS: + param_name[0] = 818; //"socks_red"; + param_name[1] = 819; //"socks_green"; + param_name[2] = 820; //"socks_blue"; + break; + + case TEX_UPPER_JACKET: + case TEX_LOWER_JACKET: + param_name[0] = 834; //"jacket_red"; + param_name[1] = 835; //"jacket_green"; + param_name[2] = 836; //"jacket_blue"; + break; + + case TEX_UPPER_GLOVES: + param_name[0] = 827; //"gloves_red"; + param_name[1] = 829; //"gloves_green"; + param_name[2] = 830; //"gloves_blue"; + break; + + case TEX_UPPER_UNDERSHIRT: + param_name[0] = 821; //"undershirt_red"; + param_name[1] = 822; //"undershirt_green"; + param_name[2] = 823; //"undershirt_blue"; + break; + + case TEX_LOWER_UNDERPANTS: + param_name[0] = 824; //"underpants_red"; + param_name[1] = 825; //"underpants_green"; + param_name[2] = 826; //"underpants_blue"; + break; + + case TEX_SKIRT: + param_name[0] = 921; //"skirt_red"; + param_name[1] = 922; //"skirt_green"; + param_name[2] = 923; //"skirt_blue"; + break; + + case TEX_HEAD_TATTOO: + case TEX_LOWER_TATTOO: + case TEX_UPPER_TATTOO: + param_name[0] = 1071; //"tattoo_red"; + param_name[1] = 1072; //"tattoo_green"; + param_name[2] = 1073; //"tattoo_blue"; + break; + + default: + llassert(0); + return FALSE; + } + + return TRUE; +} + +void LLAvatarAppearance::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake ) +{ + U32 param_name[3]; + if( teToColorParams( te, param_name ) ) + { + setVisualParamWeight( param_name[0], new_color.mV[VX], upload_bake ); + setVisualParamWeight( param_name[1], new_color.mV[VY], upload_bake ); + setVisualParamWeight( param_name[2], new_color.mV[VZ], upload_bake ); + } +} + +LLColor4 LLAvatarAppearance::getClothesColor( ETextureIndex te ) +{ + LLColor4 color; + U32 param_name[3]; + if( teToColorParams( te, param_name ) ) + { + color.mV[VX] = getVisualParamWeight( param_name[0] ); + color.mV[VY] = getVisualParamWeight( param_name[1] ); + color.mV[VZ] = getVisualParamWeight( param_name[2] ); + } + return color; +} +// static +LLColor4 LLAvatarAppearance::getDummyColor() +{ + return DUMMY_COLOR; +} + +LLColor4 LLAvatarAppearance::getGlobalColor( const std::string& color_name ) const +{ + if (color_name=="skin_color" && mTexSkinColor) + { + return mTexSkinColor->getColor(); + } + else if(color_name=="hair_color" && mTexHairColor) + { + return mTexHairColor->getColor(); + } + if(color_name=="eye_color" && mTexEyeColor) + { + return mTexEyeColor->getColor(); + } + else + { +// return LLColor4( .5f, .5f, .5f, .5f ); + return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color + } +} + +// Unlike most wearable functions, this works for both self and other. +// virtual +BOOL LLAvatarAppearance::isWearingWearableType(LLWearableType::EType type) const +{ + return mWearableData->getWearableCount(type) > 0; +} + +LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_index) const +{ + /* switch(index) + case TEX_HEAD_BAKED: + case TEX_HEAD_BODYPAINT: + return mHeadLayerSet; */ + return mBakedTextureDatas[baked_index].mTexLayerSet; +} + +//----------------------------------------------------------------------------- +// allocateCollisionVolumes() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num ) +{ + deleteAndClearArray(mCollisionVolumes); + mNumCollisionVolumes = 0; + + mCollisionVolumes = new LLAvatarJointCollisionVolume[num]; + if (!mCollisionVolumes) + { + return FALSE; + } + + mNumCollisionVolumes = num; + return TRUE; +} + +//----------------------------------------------------------------------------- +// LLAvatarBoneInfo::parseXml() +//----------------------------------------------------------------------------- +BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node) +{ + if (node->hasName("bone")) + { + mIsJoint = TRUE; + static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); + if (!node->getFastAttributeString(name_string, mName)) + { + llwarns << "Bone without name" << llendl; + return FALSE; + } + } + else if (node->hasName("collision_volume")) + { + mIsJoint = FALSE; + static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); + if (!node->getFastAttributeString(name_string, mName)) + { + mName = "Collision Volume"; + } + } + else + { + llwarns << "Invalid node " << node->getName() << llendl; + return FALSE; + } + + static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); + if (!node->getFastAttributeVector3(pos_string, mPos)) + { + llwarns << "Bone without position" << llendl; + return FALSE; + } + + static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot"); + if (!node->getFastAttributeVector3(rot_string, mRot)) + { + llwarns << "Bone without rotation" << llendl; + return FALSE; + } + + static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); + if (!node->getFastAttributeVector3(scale_string, mScale)) + { + llwarns << "Bone without scale" << llendl; + return FALSE; + } + + if (mIsJoint) + { + static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); + if (!node->getFastAttributeVector3(pivot_string, mPivot)) + { + llwarns << "Bone without pivot" << llendl; + return FALSE; + } + } + + // parse children + LLXmlTreeNode* child; + for( child = node->getFirstChild(); child; child = node->getNextChild() ) + { + LLAvatarBoneInfo *child_info = new LLAvatarBoneInfo; + if (!child_info->parseXml(child)) + { + delete child_info; + return FALSE; + } + mChildList.push_back(child_info); + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// LLAvatarSkeletonInfo::parseXml() +//----------------------------------------------------------------------------- +BOOL LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) +{ + static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones"); + if (!node->getFastAttributeS32(num_bones_string, mNumBones)) + { + llwarns << "Couldn't find number of bones." << llendl; + return FALSE; + } + + static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes"); + node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes); + + LLXmlTreeNode* child; + for( child = node->getFirstChild(); child; child = node->getNextChild() ) + { + LLAvatarBoneInfo *info = new LLAvatarBoneInfo; + if (!info->parseXml(child)) + { + delete info; + llwarns << "Error parsing bone in skeleton file" << llendl; + return FALSE; + } + mBoneInfoList.push_back(info); + } + return TRUE; +} + + +//----------------------------------------------------------------------------- +// parseXmlSkeletonNode(): parses nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root) +{ + LLXmlTreeNode* node = root->getChildByName( "skeleton" ); + if( !node ) + { + llwarns << "avatar file: missing " << llendl; + return FALSE; + } + + LLXmlTreeNode* child; + + // SKELETON DISTORTIONS + for (child = node->getChildByName( "param" ); + child; + child = node->getNextNamedChild()) + { + if (!child->getChildByName("param_skeleton")) + { + if (child->getChildByName("param_morph")) + { + llwarns << "Can't specify morph param in skeleton definition." << llendl; + } + else + { + llwarns << "Unknown param type." << llendl; + } + continue; + } + + LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo; + if (!info->parseXml(child)) + { + delete info; + return FALSE; + } + + mSkeletalDistortionInfoList.push_back(info); + } + + // ATTACHMENT POINTS + for (child = node->getChildByName( "attachment_point" ); + child; + child = node->getNextNamedChild()) + { + LLAvatarAttachmentInfo* info = new LLAvatarAttachmentInfo(); + + static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); + if (!child->getFastAttributeString(name_string, info->mName)) + { + llwarns << "No name supplied for attachment point." << llendl; + delete info; + continue; + } + + static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint"); + if (!child->getFastAttributeString(joint_string, info->mJointName)) + { + llwarns << "No bone declared in attachment point " << info->mName << llendl; + delete info; + continue; + } + + static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position"); + if (child->getFastAttributeVector3(position_string, info->mPosition)) + { + info->mHasPosition = TRUE; + } + + static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation"); + if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler)) + { + info->mHasRotation = TRUE; + } + static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group"); + if (child->getFastAttributeS32(group_string, info->mGroup)) + { + if (info->mGroup == -1) + info->mGroup = -1111; // -1 = none parsed, < -1 = bad value + } + + static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id"); + if (!child->getFastAttributeS32(id_string, info->mAttachmentID)) + { + llwarns << "No id supplied for attachment point " << info->mName << llendl; + delete info; + continue; + } + + static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice"); + child->getFastAttributeS32(slot_string, info->mPieMenuSlice); + + static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person"); + child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson); + + static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud"); + child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment); + + mAttachmentInfoList.push_back(info); + } + + return TRUE; +} + +//----------------------------------------------------------------------------- +// parseXmlMeshNodes(): parses nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root) +{ + for (LLXmlTreeNode* node = root->getChildByName( "mesh" ); + node; + node = root->getNextNamedChild()) + { + LLAvatarMeshInfo *info = new LLAvatarMeshInfo; + + // attribute: type + static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type"); + if( !node->getFastAttributeString( type_string, info->mType ) ) + { + llwarns << "Avatar file: is missing type attribute. Ignoring element. " << llendl; + delete info; + return FALSE; // Ignore this element + } + + static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod"); + if (!node->getFastAttributeS32( lod_string, info->mLOD )) + { + llwarns << "Avatar file: is missing lod attribute. Ignoring element. " << llendl; + delete info; + return FALSE; // Ignore this element + } + + static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); + if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) ) + { + llwarns << "Avatar file: is missing file_name attribute. Ignoring: " << info->mType << llendl; + delete info; + return FALSE; // Ignore this element + } + + static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference"); + node->getFastAttributeString( reference_string, info->mReferenceMeshName ); + + // attribute: min_pixel_area + static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area"); + static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width"); + if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea )) + { + F32 min_pixel_area = 0.1f; + if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area )) + { + // this is square root of pixel area (sensible to use linear space in defining lods) + min_pixel_area = min_pixel_area * min_pixel_area; + } + info->mMinPixelArea = min_pixel_area; + } + + // Parse visual params for this node only if we haven't already + for (LLXmlTreeNode* child = node->getChildByName( "param" ); + child; + child = node->getNextNamedChild()) + { + if (!child->getChildByName("param_morph")) + { + if (child->getChildByName("param_skeleton")) + { + llwarns << "Can't specify skeleton param in a mesh definition." << llendl; + } + else + { + llwarns << "Unknown param type." << llendl; + } + continue; + } + + LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo(); + if (!morphinfo->parseXml(child)) + { + delete morphinfo; + delete info; + return -1; + } + BOOL shared = FALSE; + static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared"); + child->getFastAttributeBOOL(shared_string, shared); + + info->mPolyMorphTargetInfoList.push_back(LLAvatarMeshInfo::morph_info_pair_t(morphinfo, shared)); + } + + mMeshInfoList.push_back(info); + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// parseXmlColorNodes(): parses nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root) +{ + for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" ); + color_node; + color_node = root->getNextNamedChild()) + { + std::string global_color_name; + static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); + if (color_node->getFastAttributeString( name_string, global_color_name ) ) + { + if( global_color_name == "skin_color" ) + { + if (mTexSkinColorInfo) + { + llwarns << "avatar file: multiple instances of skin_color" << llendl; + return FALSE; + } + mTexSkinColorInfo = new LLTexGlobalColorInfo; + if( !mTexSkinColorInfo->parseXml( color_node ) ) + { + deleteAndClear(mTexSkinColorInfo); + llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl; + return FALSE; + } + } + else if( global_color_name == "hair_color" ) + { + if (mTexHairColorInfo) + { + llwarns << "avatar file: multiple instances of hair_color" << llendl; + return FALSE; + } + mTexHairColorInfo = new LLTexGlobalColorInfo; + if( !mTexHairColorInfo->parseXml( color_node ) ) + { + deleteAndClear(mTexHairColorInfo); + llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl; + return FALSE; + } + } + else if( global_color_name == "eye_color" ) + { + if (mTexEyeColorInfo) + { + llwarns << "avatar file: multiple instances of eye_color" << llendl; + return FALSE; + } + mTexEyeColorInfo = new LLTexGlobalColorInfo; + if( !mTexEyeColorInfo->parseXml( color_node ) ) + { + llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl; + return FALSE; + } + } + } + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// parseXmlLayerNodes(): parses nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root) +{ + for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" ); + layer_node; + layer_node = root->getNextNamedChild()) + { + LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo(); + if( layer_info->parseXml( layer_node ) ) + { + mLayerInfoList.push_back(layer_info); + } + else + { + delete layer_info; + llwarns << "avatar file: layer_set->parseXml() failed" << llendl; + return FALSE; + } + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// parseXmlDriverNodes(): parses nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root) +{ + LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" ); + if( driver ) + { + for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" ); + grand_child; + grand_child = driver->getNextNamedChild()) + { + if( grand_child->getChildByName( "param_driver" ) ) + { + LLDriverParamInfo* driver_info = new LLDriverParamInfo(); + if( driver_info->parseXml( grand_child ) ) + { + mDriverInfoList.push_back(driver_info); + } + else + { + delete driver_info; + llwarns << "avatar file: driver_param->parseXml() failed" << llendl; + return FALSE; + } + } + } + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// parseXmlDriverNodes(): parses nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root) +{ + LLXmlTreeNode* masks = root->getChildByName( "morph_masks" ); + if( !masks ) + { + return FALSE; + } + + for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" ); + grand_child; + grand_child = masks->getNextNamedChild()) + { + LLAvatarMorphInfo* info = new LLAvatarMorphInfo(); + + static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name"); + if (!grand_child->getFastAttributeString(name_string, info->mName)) + { + llwarns << "No name supplied for morph mask." << llendl; + delete info; + continue; + } + + static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region"); + if (!grand_child->getFastAttributeString(region_string, info->mRegion)) + { + llwarns << "No region supplied for morph mask." << llendl; + delete info; + continue; + } + + static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer"); + if (!grand_child->getFastAttributeString(layer_string, info->mLayer)) + { + llwarns << "No layer supplied for morph mask." << llendl; + delete info; + continue; + } + + // optional parameter. don't throw a warning if not present. + static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert"); + grand_child->getFastAttributeBOOL(invert_string, info->mInvert); + + mMorphMaskInfoList.push_back(info); + } + + return TRUE; +} + +//virtual +LLAvatarAppearance::LLMaskedMorph::LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer) : + mMorphTarget(morph_target), + mInvert(invert), + mLayer(layer) +{ + LLPolyMorphTarget *target = dynamic_cast(morph_target); + if (target) + { + target->addPendingMorphMask(); + } +} + + + diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h new file mode 100644 index 000000000..21a813cc8 --- /dev/null +++ b/indra/llappearance/llavatarappearance.h @@ -0,0 +1,452 @@ +/** + * @file llavatarappearance.h + * @brief Declaration of LLAvatarAppearance class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_AVATAR_APPEARANCE_H +#define LL_AVATAR_APPEARANCE_H + +#include "llcharacter.h" +#include "llavatarappearancedefines.h" +#include "llavatarjointmesh.h" +#include "lldriverparam.h" +#include "lltexlayer.h" +#include "llviewervisualparam.h" +#include "llxmltree.h" + +class LLTexLayerSet; +class LLTexGlobalColor; +class LLTexGlobalColorInfo; +class LLWearableData; +class LLAvatarBoneInfo; +class LLAvatarSkeletonInfo; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLAvatarAppearance +// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLAvatarAppearance : public LLCharacter +{ + LOG_CLASS(LLAvatarAppearance); + +protected: + struct LLAvatarXmlInfo; + +/******************************************************************************** + ** ** + ** INITIALIZATION + **/ +private: + // Hide default constructor. + LLAvatarAppearance() {} + +public: + LLAvatarAppearance(LLWearableData* wearable_data); + virtual ~LLAvatarAppearance(); + + static void initClass(); // initializes static members + 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(); + BOOL loadMeshNodes(); + BOOL loadLayersets(); + + +/** Initialization + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** INHERITED + **/ + + //-------------------------------------------------------------------- + // LLCharacter interface and related + //-------------------------------------------------------------------- +public: + /*virtual*/ LLJoint* getCharacterJoint(U32 num); + + /*virtual*/ const char* getAnimationPrefix() { return "avatar"; } + /*virtual*/ LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset); + /*virtual*/ LLJoint* findCollisionVolume(U32 volume_id); + /*virtual*/ S32 getCollisionVolumeID(std::string &name); + /*virtual*/ LLPolyMesh* getHeadMesh(); + /*virtual*/ LLPolyMesh* getUpperBodyMesh(); + LLPolyMesh* getMesh( LLPolyMeshSharedData *shared_data ); + + typedef std::map lod_mesh_map_t; + typedef std::map mesh_info_t; + static void getMeshInfo(mesh_info_t* mesh_info); + +/** Inherited + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** STATE + **/ +public: + virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent + virtual BOOL isValid() const; + virtual BOOL isUsingServerBakes() const = 0; + virtual BOOL isUsingLocalAppearance() const = 0; + virtual BOOL isEditingAppearance() const = 0; + + bool isBuilt() const { return mIsBuilt; } + + virtual std::string getFullname() const = 0; +/** State + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** SKELETON + **/ + +protected: + virtual LLAvatarJoint* createAvatarJoint() = 0; + virtual LLAvatarJoint* createAvatarJoint(S32 joint_num) = 0; + virtual LLAvatarJointMesh* createAvatarJointMesh() = 0; +public: + F32 getPelvisToFoot() const { return mPelvisToFoot; } + /*virtual*/ LLJoint* getRootJoint() { return mRoot; } + + LLVector3 mHeadOffset; // current head position + LLAvatarJoint *mRoot; + + typedef std::map joint_map_t; + joint_map_t mJointMap; + + void computeBodySize(); + + +protected: + static BOOL parseSkeletonFile(const std::string& filename); + virtual void buildCharacter(); + virtual BOOL loadAvatar(); + virtual void bodySizeChanged() = 0; + + 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 avatar_joint_list_t; + avatar_joint_list_t mSkeleton; + + //-------------------------------------------------------------------- + // Pelvis height adjustment members. + //-------------------------------------------------------------------- +public: + LLVector3 mBodySize; +protected: + F32 mPelvisToFoot; + + //-------------------------------------------------------------------- + // Cached pointers to well known joints + //-------------------------------------------------------------------- +public: + LLJoint* mPelvisp; + LLJoint* mTorsop; + LLJoint* mChestp; + LLJoint* mNeckp; + LLJoint* mHeadp; + LLJoint* mSkullp; + LLJoint* mEyeLeftp; + LLJoint* mEyeRightp; + LLJoint* mHipLeftp; + LLJoint* mHipRightp; + LLJoint* mKneeLeftp; + LLJoint* mKneeRightp; + LLJoint* mAnkleLeftp; + LLJoint* mAnkleRightp; + LLJoint* mFootLeftp; + LLJoint* mFootRightp; + LLJoint* mWristLeftp; + LLJoint* mWristRightp; + + //-------------------------------------------------------------------- + // XML parse tree + //-------------------------------------------------------------------- +protected: + static LLXmlTree sXMLTree; // avatar config file + static LLXmlTree sSkeletonXMLTree; // avatar skeleton file + + static LLAvatarSkeletonInfo* sAvatarSkeletonInfo; + static LLAvatarXmlInfo* sAvatarXmlInfo; + + +/** Skeleton + ** ** + *******************************************************************************/ + + +/******************************************************************************** + ** ** + ** RENDERING + **/ +public: + BOOL mIsDummy; // for special views + + //-------------------------------------------------------------------- + // Morph masks + //-------------------------------------------------------------------- +public: + void addMaskedMorph(LLAvatarAppearanceDefines::EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer); + virtual void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES) = 0; + +/** Rendering + ** ** + *******************************************************************************/ + + //-------------------------------------------------------------------- + // Composites + //-------------------------------------------------------------------- +public: + virtual void invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result) = 0; + +/******************************************************************************** + ** ** + ** MESHES + **/ + +public: + virtual void updateMeshTextures() = 0; + virtual void dirtyMesh() = 0; // Dirty the avatar mesh +protected: + virtual void dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority + +protected: + typedef std::multimap polymesh_map_t; + polymesh_map_t mPolyMeshes; + avatar_joint_list_t mMeshLOD; + +/** Meshes + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** APPEARANCE + **/ + + //-------------------------------------------------------------------- + // Clothing colors (convenience functions to access visual parameters) + //-------------------------------------------------------------------- +public: + void setClothesColor(LLAvatarAppearanceDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake); + LLColor4 getClothesColor(LLAvatarAppearanceDefines::ETextureIndex te); + static BOOL teToColorParams(LLAvatarAppearanceDefines::ETextureIndex te, U32 *param_name); + + //-------------------------------------------------------------------- + // Global colors + //-------------------------------------------------------------------- +public: + LLColor4 getGlobalColor(const std::string& color_name ) const; + virtual void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake) = 0; +protected: + LLTexGlobalColor* mTexSkinColor; + LLTexGlobalColor* mTexHairColor; + LLTexGlobalColor* mTexEyeColor; + + //-------------------------------------------------------------------- + // Visibility + //-------------------------------------------------------------------- +public: + static LLColor4 getDummyColor(); +/** Appearance + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** WEARABLES + **/ + +public: + LLWearableData* getWearableData() { return mWearableData; } + const LLWearableData* getWearableData() const { return mWearableData; } + virtual BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index = 0 ) const = 0; + virtual BOOL isWearingWearableType(LLWearableType::EType type ) const; + +private: + LLWearableData* mWearableData; + +/******************************************************************************** + ** ** + ** BAKED TEXTURES + **/ +public: + LLTexLayerSet* getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const; + +protected: + virtual LLTexLayerSet* createTexLayerSet() = 0; + +protected: + class LLMaskedMorph; + typedef std::deque morph_list_t; + struct BakedTextureData + { + LLUUID mLastTextureID; + LLTexLayerSet* mTexLayerSet; // Only exists for self + bool mIsLoaded; + bool mIsUsed; + LLAvatarAppearanceDefines::ETextureIndex mTextureIndex; + U32 mMaskTexName; + // Stores pointers to the joint meshes that this baked texture deals with + avatar_joint_mesh_list_t mJointMeshes; + morph_list_t mMaskedMorphs; + }; + typedef std::vector bakedtexturedata_vec_t; + bakedtexturedata_vec_t mBakedTextureDatas; + +/******************************************************************************** + ** ** + ** PHYSICS + **/ + + //-------------------------------------------------------------------- + // Collision volumes + //-------------------------------------------------------------------- +public: + S32 mNumCollisionVolumes; + LLAvatarJointCollisionVolume* mCollisionVolumes; +protected: + BOOL allocateCollisionVolumes(U32 num); + +/** Physics + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** SUPPORT CLASSES + **/ + + struct LLAvatarXmlInfo + { + LLAvatarXmlInfo(); + ~LLAvatarXmlInfo(); + + BOOL parseXmlSkeletonNode(LLXmlTreeNode* root); + BOOL parseXmlMeshNodes(LLXmlTreeNode* root); + BOOL parseXmlColorNodes(LLXmlTreeNode* root); + BOOL parseXmlLayerNodes(LLXmlTreeNode* root); + BOOL parseXmlDriverNodes(LLXmlTreeNode* root); + BOOL parseXmlMorphNodes(LLXmlTreeNode* root); + + struct LLAvatarMeshInfo + { + typedef std::pair morph_info_pair_t; // LLPolyMorphTargetInfo stored here + typedef std::vector morph_info_list_t; + + LLAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {} + ~LLAvatarMeshInfo() + { + morph_info_list_t::iterator iter; + for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++) + { + delete iter->first; + } + mPolyMorphTargetInfoList.clear(); + } + + std::string mType; + S32 mLOD; + std::string mMeshFileName; + std::string mReferenceMeshName; + F32 mMinPixelArea; + morph_info_list_t mPolyMorphTargetInfoList; + }; + typedef std::vector mesh_info_list_t; + mesh_info_list_t mMeshInfoList; + + typedef std::vector skeletal_distortion_info_list_t; // LLPolySkeletalDistortionInfo stored here + skeletal_distortion_info_list_t mSkeletalDistortionInfoList; + + struct LLAvatarAttachmentInfo + { + LLAvatarAttachmentInfo() + : mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE), + mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {} + std::string mName; + std::string mJointName; + LLVector3 mPosition; + LLVector3 mRotationEuler; + S32 mGroup; + S32 mAttachmentID; + S32 mPieMenuSlice; + BOOL mVisibleFirstPerson; + BOOL mIsHUDAttachment; + BOOL mHasPosition; + BOOL mHasRotation; + }; + typedef std::vector attachment_info_list_t; + attachment_info_list_t mAttachmentInfoList; + + LLTexGlobalColorInfo *mTexSkinColorInfo; + LLTexGlobalColorInfo *mTexHairColorInfo; + LLTexGlobalColorInfo *mTexEyeColorInfo; + + typedef std::vector layer_info_list_t; + layer_info_list_t mLayerInfoList; + + typedef std::vector driver_info_list_t; + driver_info_list_t mDriverInfoList; + + struct LLAvatarMorphInfo + { + LLAvatarMorphInfo() + : mInvert(FALSE) {} + std::string mName; + std::string mRegion; + std::string mLayer; + BOOL mInvert; + }; + + typedef std::vector morph_info_list_t; + morph_info_list_t mMorphMaskInfoList; + }; + + + class LLMaskedMorph + { + public: + LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer); + + LLVisualParam *mMorphTarget; + BOOL mInvert; + std::string mLayer; + }; +/** Support Classes + ** ** + *******************************************************************************/ +}; + +#endif // LL_AVATAR_APPEARANCE_H diff --git a/indra/newview/llvoavatardefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp similarity index 70% rename from indra/newview/llvoavatardefines.cpp rename to indra/llappearance/llavatarappearancedefines.cpp index c0ec8fc61..f1c78946a 100644 --- a/indra/newview/llvoavatardefines.cpp +++ b/indra/llappearance/llavatarappearancedefines.cpp @@ -1,51 +1,43 @@ /** - * @file llvoavatar.cpp - * @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject + * @file llavatarappearancedefines.cpp + * @brief Implementation of LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 "llvoavatardefines.h" -#include "llviewercontrol.h" // gSavedSettings +#include "linden_common.h" +#include "llavatarappearancedefines.h" -const S32 LLVOAvatarDefines::SCRATCH_TEX_WIDTH = 512; -const S32 LLVOAvatarDefines::SCRATCH_TEX_HEIGHT = 512; -const S32 LLVOAvatarDefines::IMPOSTOR_PERIOD = 2; +const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 512; +const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 512; +const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2; -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines; /********************************************************************************* * Edit this function to add/remove/change textures and mesh definitions for avatars. - * If these are changed, they MUST be changed in floater_avatar_textures.xml as well! */ -LLVOAvatarDictionary::Textures::Textures() +LLAvatarAppearanceDictionary::Textures::Textures() { addEntry(TEX_HEAD_BODYPAINT, new TextureEntry("head_bodypaint", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_SKIN)); addEntry(TEX_UPPER_SHIRT, new TextureEntry("upper_shirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShirtUUID", LLWearableType::WT_SHIRT)); @@ -73,15 +65,15 @@ LLVOAvatarDictionary::Textures::Textures() addEntry(TEX_UPPER_TATTOO, new TextureEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO)); addEntry(TEX_LOWER_TATTOO, new TextureEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO)); - addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD)); - addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER)); - addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER)); - addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES)); - addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR)); - addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT)); + addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD, "head")); + addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER, "upper")); + addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER, "lower")); + addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES, "eyes")); + addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR, "hair")); + addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT, "skirt")); } -LLVOAvatarDictionary::BakedTextures::BakedTextures() +LLAvatarAppearanceDictionary::BakedTextures::BakedTextures() { // Baked textures addEntry(BAKED_HEAD, new BakedEntry(TEX_HEAD_BAKED, @@ -117,36 +109,36 @@ LLVOAvatarDictionary::BakedTextures::BakedTextures() 2, LLWearableType::WT_HAIR, LLWearableType::WT_ALPHA)); } -LLVOAvatarDictionary::Meshes::Meshes() +LLAvatarAppearanceDictionary::MeshEntries::MeshEntries() { - // Meshes - addEntry(MESH_ID_HAIR, new MeshEntry(BAKED_HAIR, "hairMesh", 6, LLViewerJoint::PN_4)); - addEntry(MESH_ID_HEAD, new MeshEntry(BAKED_HEAD, "headMesh", 5, LLViewerJoint::PN_5)); - addEntry(MESH_ID_EYELASH, new MeshEntry(BAKED_HEAD, "eyelashMesh", 1, LLViewerJoint::PN_0)); // no baked mesh associated currently - addEntry(MESH_ID_UPPER_BODY, new MeshEntry(BAKED_UPPER, "upperBodyMesh", 5, LLViewerJoint::PN_1)); - addEntry(MESH_ID_LOWER_BODY, new MeshEntry(BAKED_LOWER, "lowerBodyMesh", 5, LLViewerJoint::PN_2)); - addEntry(MESH_ID_EYEBALL_LEFT, new MeshEntry(BAKED_EYES, "eyeBallLeftMesh", 2, LLViewerJoint::PN_3)); - addEntry(MESH_ID_EYEBALL_RIGHT, new MeshEntry(BAKED_EYES, "eyeBallRightMesh", 2, LLViewerJoint::PN_3)); - addEntry(MESH_ID_SKIRT, new MeshEntry(BAKED_SKIRT, "skirtMesh", 5, LLViewerJoint::PN_5)); + // MeshEntries + addEntry(MESH_ID_HAIR, new MeshEntry(BAKED_HAIR, "hairMesh", 6, PN_4)); + addEntry(MESH_ID_HEAD, new MeshEntry(BAKED_HEAD, "headMesh", 5, PN_5)); + addEntry(MESH_ID_EYELASH, new MeshEntry(BAKED_HEAD, "eyelashMesh", 1, PN_0)); // no baked mesh associated currently + addEntry(MESH_ID_UPPER_BODY, new MeshEntry(BAKED_UPPER, "upperBodyMesh", 5, PN_1)); + addEntry(MESH_ID_LOWER_BODY, new MeshEntry(BAKED_LOWER, "lowerBodyMesh", 5, PN_2)); + addEntry(MESH_ID_EYEBALL_LEFT, new MeshEntry(BAKED_EYES, "eyeBallLeftMesh", 2, PN_3)); + addEntry(MESH_ID_EYEBALL_RIGHT, new MeshEntry(BAKED_EYES, "eyeBallRightMesh", 2, PN_3)); + addEntry(MESH_ID_SKIRT, new MeshEntry(BAKED_SKIRT, "skirtMesh", 5, PN_5)); } /* * *********************************************************************************/ -LLVOAvatarDictionary::LLVOAvatarDictionary() +LLAvatarAppearanceDictionary::LLAvatarAppearanceDictionary() { createAssociations(); } //virtual -LLVOAvatarDictionary::~LLVOAvatarDictionary() +LLAvatarAppearanceDictionary::~LLAvatarAppearanceDictionary() { } // Baked textures are composites of textures; for each such composited texture, // map it to the baked texture. -void LLVOAvatarDictionary::createAssociations() +void LLAvatarAppearanceDictionary::createAssociations() { for (BakedTextures::const_iterator iter = mBakedTextures.begin(); iter != mBakedTextures.end(); iter++) { @@ -167,11 +159,11 @@ void LLVOAvatarDictionary::createAssociations() } -LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name, - bool is_local_texture, - EBakedTextureIndex baked_texture_index, - const std::string &default_image_name, - LLWearableType::EType wearable_type) : +LLAvatarAppearanceDictionary::TextureEntry::TextureEntry(const std::string &name, + bool is_local_texture, + EBakedTextureIndex baked_texture_index, + const std::string &default_image_name, + LLWearableType::EType wearable_type) : LLDictionaryEntry(name), mIsLocalTexture(is_local_texture), mIsBakedTexture(!is_local_texture), @@ -182,17 +174,17 @@ LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name, { } -LLVOAvatarDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index, +LLAvatarAppearanceDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index, const std::string &name, U8 level, - LLViewerJoint::PickName pick) : + LLJointPickName pick) : LLDictionaryEntry(name), mBakedID(baked_index), mLOD(level), mPickName(pick) { } -LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index, +LLAvatarAppearanceDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index, const std::string &name, const std::string &hash_name, U32 num_local_textures, @@ -223,18 +215,18 @@ LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index, } // static -ETextureIndex LLVOAvatarDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index) +ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index) { - return LLVOAvatarDictionary::getInstance()->getBakedTexture(index)->mTextureIndex; + return LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(index)->mTextureIndex; } -//static -EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name) +// static +EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::string name) { U8 index = 0; while (index < BAKED_NUM_INDICES) { - const BakedEntry *be = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index); + const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index); if (be && be->mName.compare(name) == 0) { // baked texture found @@ -246,23 +238,31 @@ EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name) return BAKED_NUM_INDICES; } -//static -const LLUUID LLVOAvatarDictionary::getDefaultTextureImageID(ETextureIndex index) +// static +EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::string name) { - const TextureEntry *texture_dict = getInstance()->getTexture(index); - const std::string &default_image_name = texture_dict->mDefaultImageName; - if (default_image_name == "") + U8 index = 0; + while (index < BAKED_NUM_INDICES) { - return IMG_DEFAULT_AVATAR; - } - else - { - return LLUUID(gSavedSettings.getString(default_image_name)); + const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index); + if (be) + { + const TextureEntry *te = LLAvatarAppearanceDictionary::getInstance()->getTexture(be->mTextureIndex); + if (te && te->mDefaultImageName.compare(name) == 0) + { + // baked texture found + return (EBakedTextureIndex) index; + } + } + index++; } + // baked texture could not be found + return BAKED_NUM_INDICES; } // static -LLWearableType::EType LLVOAvatarDictionary::getTEWearableType(ETextureIndex index ) +LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index ) { return getInstance()->getTexture(index)->mWearableType; } + diff --git a/indra/newview/llvoavatardefines.h b/indra/llappearance/llavatarappearancedefines.h similarity index 65% rename from indra/newview/llvoavatardefines.h rename to indra/llappearance/llavatarappearancedefines.h index bf157732d..496f85c10 100644 --- a/indra/newview/llvoavatardefines.h +++ b/indra/llappearance/llavatarappearancedefines.h @@ -1,45 +1,40 @@ /** - * @file llvoavatar.h - * @brief Declaration of LLVOAvatar class which is a derivation fo + * @file llavatarappearancedefines.h + * @brief Various LLAvatarAppearance related definitions * LLViewerObject * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 LLVOAVATAR_DEFINES_H -#define LLVOAVATAR_DEFINES_H +#ifndef LL_AVATARAPPEARANCE_DEFINES_H +#define LL_AVATARAPPEARANCE_DEFINES_H #include -#include "llwearable.h" -#include "llviewerjoint.h" +#include "lljointpickname.h" #include "lldictionary.h" +#include "llwearabletype.h" +#include "lluuid.h" -namespace LLVOAvatarDefines +namespace LLAvatarAppearanceDefines { extern const S32 SCRATCH_TEX_WIDTH; @@ -47,10 +42,11 @@ extern const S32 SCRATCH_TEX_HEIGHT; extern const S32 IMPOSTOR_PERIOD; //-------------------------------------------------------------------- -// texture entry assignment +// Enums //-------------------------------------------------------------------- enum ETextureIndex { + TEX_INVALID = -1, TEX_HEAD_BODYPAINT = 0, TEX_UPPER_SHIRT, TEX_LOWER_PANTS, @@ -59,9 +55,9 @@ enum ETextureIndex TEX_UPPER_BODYPAINT, TEX_LOWER_BODYPAINT, TEX_LOWER_SHOES, - TEX_HEAD_BAKED, // Pre-composited - TEX_UPPER_BAKED, // Pre-composited - TEX_LOWER_BAKED, // Pre-composited + TEX_HEAD_BAKED, // Pre-composited + TEX_UPPER_BAKED, // Pre-composited + TEX_LOWER_BAKED, // Pre-composited TEX_EYES_BAKED, // Pre-composited TEX_LOWER_SOCKS, TEX_UPPER_JACKET, @@ -70,7 +66,7 @@ enum ETextureIndex TEX_UPPER_UNDERSHIRT, TEX_LOWER_UNDERPANTS, TEX_SKIRT, - TEX_SKIRT_BAKED, // Pre-composited + TEX_SKIRT_BAKED, // Pre-composited TEX_HAIR_BAKED, // Pre-composited TEX_LOWER_ALPHA, TEX_UPPER_ALPHA, @@ -81,7 +77,7 @@ enum ETextureIndex TEX_UPPER_TATTOO, TEX_LOWER_TATTOO, TEX_NUM_INDICES -}; +}; enum EBakedTextureIndex { @@ -117,21 +113,21 @@ typedef std::vector mesh_vec_t; typedef std::vector wearables_vec_t; //------------------------------------------------------------------------ -// LLVOAvatarDictionary +// LLAvatarAppearanceDictionary // // Holds dictionary static entries for textures, baked textures, meshes, etc.; i.e. // information that is common to all avatars. // // This holds const data - it is initialized once and the contents never change after that. //------------------------------------------------------------------------ -class LLVOAvatarDictionary : public LLSingleton +class LLAvatarAppearanceDictionary : public LLSingleton { //-------------------------------------------------------------------- // Constructors and Destructors //-------------------------------------------------------------------- public: - LLVOAvatarDictionary(); - virtual ~LLVOAvatarDictionary(); + LLAvatarAppearanceDictionary(); + virtual ~LLAvatarAppearanceDictionary(); private: void createAssociations(); @@ -141,19 +137,19 @@ private: public: struct TextureEntry : public LLDictionaryEntry { - TextureEntry(const std::string &name, - bool is_local_texture, - EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES, - const std::string &default_image_name = "", + TextureEntry(const std::string &name, // this must match the xml name used by LLTexLayerInfo::parseXml + bool is_local_texture, + EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES, + const std::string& default_image_name = "", LLWearableType::EType wearable_type = LLWearableType::WT_INVALID); - const std::string mDefaultImageName; + const std::string mDefaultImageName; const LLWearableType::EType mWearableType; // It's either a local texture xor baked - BOOL mIsLocalTexture; - BOOL mIsBakedTexture; + BOOL mIsLocalTexture; + BOOL mIsBakedTexture; // If it's a local texture, it may be used by a baked texture - BOOL mIsUsedByBakedTexture; - EBakedTextureIndex mBakedTextureIndex; + BOOL mIsUsedByBakedTexture; + EBakedTextureIndex mBakedTextureIndex; }; struct Textures : public LLDictionary @@ -170,22 +166,22 @@ public: struct MeshEntry : public LLDictionaryEntry { MeshEntry(EBakedTextureIndex baked_index, - const std::string &name, - U8 level, - LLViewerJoint::PickName pick); + const std::string &name, // names of mesh types as they are used in avatar_lad.xml + U8 level, + LLJointPickName pick); // Levels of Detail for each mesh. Must match levels of detail present in avatar_lad.xml // Otherwise meshes will be unable to be found, or levels of detail will be ignored - const U8 mLOD; - const EBakedTextureIndex mBakedID; - const LLViewerJoint::PickName mPickName; + const U8 mLOD; + const EBakedTextureIndex mBakedID; + const LLJointPickName mPickName; }; - struct Meshes : public LLDictionary + struct MeshEntries : public LLDictionary { - Meshes(); - } mMeshes; - const MeshEntry* getMesh(EMeshIndex index) const { return mMeshes.lookup(index); } - const Meshes& getMeshes() const { return mMeshes; } + MeshEntries(); + } mMeshEntries; + const MeshEntry* getMeshEntry(EMeshIndex index) const { return mMeshEntries.lookup(index); } + const MeshEntries& getMeshEntries() const { return mMeshEntries; } //-------------------------------------------------------------------- // Baked Textures @@ -204,7 +200,7 @@ public: const LLUUID mWearablesHashID; wearables_vec_t mWearables; }; - + struct BakedTextures: public LLDictionary { BakedTextures(); @@ -221,14 +217,13 @@ public: // find a baked texture index based on its name static EBakedTextureIndex findBakedByRegionName(std::string name); - - static const LLUUID getDefaultTextureImageID(ETextureIndex index); + static EBakedTextureIndex findBakedByImageName(std::string name); // Given a texture entry, determine which wearable type owns it. static LLWearableType::EType getTEWearableType(ETextureIndex index); -}; // End LLVOAvatarDictionary +}; // End LLAvatarAppearanceDictionary -} // End namespace LLVOAvatarDefines +} // End namespace LLAvatarAppearanceDefines -#endif +#endif //LL_AVATARAPPEARANCE_DEFINES_H diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp new file mode 100644 index 000000000..6ab341af6 --- /dev/null +++ b/indra/llappearance/llavatarjoint.cpp @@ -0,0 +1,326 @@ +/** + * @file llavatarjoint.cpp + * @brief Implementation of LLAvatarJoint class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "llavatarjoint.h" + +#include "llgl.h" +#include "llrender.h" +#include "llmath.h" +#include "llglheaders.h" +#include "llavatarappearance.h" + +const F32 DEFAULT_AVATAR_JOINT_LOD = 0.0f; + +//----------------------------------------------------------------------------- +// Static Data +//----------------------------------------------------------------------------- +BOOL LLAvatarJoint::sDisableLOD = FALSE; + +//----------------------------------------------------------------------------- +// LLAvatarJoint() +// Class Constructors +//----------------------------------------------------------------------------- +LLAvatarJoint::LLAvatarJoint() : + LLJoint() +{ + init(); +} + +LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) : + LLJoint(name, parent) +{ + init(); +} + +LLAvatarJoint::LLAvatarJoint(S32 joint_num) : + LLJoint(joint_num) +{ + init(); +} + + +void LLAvatarJoint::init() +{ + mValid = FALSE; + mComponents = SC_JOINT | SC_BONE | SC_AXES; + mMinPixelArea = DEFAULT_AVATAR_JOINT_LOD; + mPickName = PN_DEFAULT; + mVisible = TRUE; + mMeshID = 0; + mIsTransparent = FALSE; +} + + +//----------------------------------------------------------------------------- +// ~LLAvatarJoint() +// Class Destructor +//----------------------------------------------------------------------------- +LLAvatarJoint::~LLAvatarJoint() +{ +} + + +//-------------------------------------------------------------------- +// setValid() +//-------------------------------------------------------------------- +void LLAvatarJoint::setValid( BOOL valid, BOOL recursive ) +{ + //---------------------------------------------------------------- + // set visibility for this joint + //---------------------------------------------------------------- + mValid = valid; + + //---------------------------------------------------------------- + // set visibility for children + //---------------------------------------------------------------- + if (recursive) + { + for (child_list_t::iterator iter = mChildren.begin(); + iter != mChildren.end(); ++iter) + { + LLAvatarJoint* joint = (LLAvatarJoint*)(*iter); + joint->setValid(valid, TRUE); + } + } + +} + +//-------------------------------------------------------------------- +// setSkeletonComponents() +//-------------------------------------------------------------------- +void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive ) +{ + mComponents = comp; + if (recursive) + { + for (child_list_t::iterator iter = mChildren.begin(); + iter != mChildren.end(); ++iter) + { + LLAvatarJoint* joint = dynamic_cast(*iter); + joint->setSkeletonComponents(comp, recursive); + } + } +} + +void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive) +{ + mVisible = visible; + + if (recursive) + { + for (child_list_t::iterator iter = mChildren.begin(); + iter != mChildren.end(); ++iter) + { + LLAvatarJoint* joint = (LLAvatarJoint*)(*iter); + joint->setVisible(visible, recursive); + } + } +} + +void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area) +{ + for (child_list_t::iterator iter = mChildren.begin(); + iter != mChildren.end(); ++iter) + { + LLAvatarJoint* joint = dynamic_cast(*iter); + joint->updateFaceSizes(num_vertices, num_indices, pixel_area); + } +} + +void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update) +{ + for (child_list_t::iterator iter = mChildren.begin(); + iter != mChildren.end(); ++iter) + { + LLAvatarJoint* joint = dynamic_cast(*iter); + joint->updateFaceData(face, pixel_area, damp_wind, terse_update); + } +} + +void LLAvatarJoint::updateJointGeometry() +{ + for (child_list_t::iterator iter = mChildren.begin(); + iter != mChildren.end(); ++iter) + { + LLAvatarJoint* joint = dynamic_cast(*iter); + joint->updateJointGeometry(); + } +} + + +BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate) +{ + BOOL lod_changed = FALSE; + BOOL found_lod = FALSE; + + for (child_list_t::iterator iter = mChildren.begin(); + iter != mChildren.end(); ++iter) + { + LLAvatarJoint* joint = dynamic_cast(*iter); + F32 jointLOD = joint->getLOD(); + + if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD) + { + // we've already found a joint to enable, so enable the rest as alternatives + lod_changed |= joint->updateLOD(pixel_area, TRUE); + } + else + { + if (pixel_area >= jointLOD || sDisableLOD) + { + lod_changed |= joint->updateLOD(pixel_area, TRUE); + found_lod = TRUE; + } + else + { + lod_changed |= joint->updateLOD(pixel_area, FALSE); + } + } + } + return lod_changed; +} + +void LLAvatarJoint::dump() +{ + for (child_list_t::iterator iter = mChildren.begin(); + iter != mChildren.end(); ++iter) + { + LLAvatarJoint* joint = dynamic_cast(*iter); + joint->dump(); + } +} + + +void LLAvatarJoint::setMeshesToChildren() +{ + removeAllChildren(); + for (avatar_joint_mesh_list_t::iterator iter = mMeshParts.begin(); + iter != mMeshParts.end(); iter++) + { + addChild((*iter)); + } +} +//----------------------------------------------------------------------------- +// LLAvatarJointCollisionVolume() +//----------------------------------------------------------------------------- + +LLAvatarJointCollisionVolume::LLAvatarJointCollisionVolume() +{ + mUpdateXform = FALSE; +} + +/*virtual*/ +U32 LLAvatarJointCollisionVolume::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy ) +{ + llerrs << "Cannot call render() on LLAvatarJointCollisionVolume" << llendl; + return 0; +} + +LLVector3 LLAvatarJointCollisionVolume::getVolumePos(LLVector3 &offset) +{ + mUpdateXform = TRUE; + + LLVector3 result = offset; + result.scaleVec(getScale()); + result.rotVec(getWorldRotation()); + result += getWorldPosition(); + + return result; +} + +void LLAvatarJointCollisionVolume::renderCollision() +{ + updateWorldMatrix(); + + gGL.pushMatrix(); + gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] ); + + gGL.diffuseColor3f( 0.f, 0.f, 1.f ); + + gGL.begin(LLRender::LINES); + + LLVector3 v[] = + { + LLVector3(1,0,0), + LLVector3(-1,0,0), + LLVector3(0,1,0), + LLVector3(0,-1,0), + + LLVector3(0,0,-1), + LLVector3(0,0,1), + }; + + //sides + gGL.vertex3fv(v[0].mV); + gGL.vertex3fv(v[2].mV); + + gGL.vertex3fv(v[0].mV); + gGL.vertex3fv(v[3].mV); + + gGL.vertex3fv(v[1].mV); + gGL.vertex3fv(v[2].mV); + + gGL.vertex3fv(v[1].mV); + gGL.vertex3fv(v[3].mV); + + + //top + gGL.vertex3fv(v[0].mV); + gGL.vertex3fv(v[4].mV); + + gGL.vertex3fv(v[1].mV); + gGL.vertex3fv(v[4].mV); + + gGL.vertex3fv(v[2].mV); + gGL.vertex3fv(v[4].mV); + + gGL.vertex3fv(v[3].mV); + gGL.vertex3fv(v[4].mV); + + + //bottom + gGL.vertex3fv(v[0].mV); + gGL.vertex3fv(v[5].mV); + + gGL.vertex3fv(v[1].mV); + gGL.vertex3fv(v[5].mV); + + gGL.vertex3fv(v[2].mV); + gGL.vertex3fv(v[5].mV); + + gGL.vertex3fv(v[3].mV); + gGL.vertex3fv(v[5].mV); + + gGL.end(); + + gGL.popMatrix(); +} + + +// End diff --git a/indra/llappearance/llavatarjoint.h b/indra/llappearance/llavatarjoint.h new file mode 100644 index 000000000..fec91503c --- /dev/null +++ b/indra/llappearance/llavatarjoint.h @@ -0,0 +1,140 @@ +/** + * @file llavatarjoint.h + * @brief Implementation of LLAvatarJoint class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLAVATARJOINT_H +#define LL_LLAVATARJOINT_H + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "lljoint.h" +#include "lljointpickname.h" + +class LLFace; +class LLAvatarJointMesh; + +extern const F32 DEFAULT_AVATAR_JOINT_LOD; + +//----------------------------------------------------------------------------- +// class LLViewerJoint +//----------------------------------------------------------------------------- +class LLAvatarJoint : + public LLJoint +{ +public: + LLAvatarJoint(); + LLAvatarJoint(S32 joint_num); + // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform* + LLAvatarJoint(const std::string &name, LLJoint *parent = NULL); + virtual ~LLAvatarJoint(); + + // Gets the validity of this joint + BOOL getValid() { return mValid; } + + // Sets the validity of this joint + virtual void setValid( BOOL valid, BOOL recursive=FALSE ); + + // Returns true if this object is transparent. + // This is used to determine in which order to draw objects. + virtual BOOL isTransparent() { return mIsTransparent; } + + // Returns true if this object should inherit scale modifiers from its immediate parent + virtual BOOL inheritScale() { return FALSE; } + + enum Components + { + SC_BONE = 1, + SC_JOINT = 2, + SC_AXES = 4 + }; + + // Selects which skeleton components to draw + void setSkeletonComponents( U32 comp, BOOL recursive = TRUE ); + + // Returns which skeleton components are enables for drawing + U32 getSkeletonComponents() { return mComponents; } + + // Sets the level of detail for this node as a minimum + // pixel area threshold. If the current pixel area for this + // object is less than the specified threshold, the node is + // not traversed. In addition, if a value is specified (not + // default of 0.0), and the pixel area is larger than the + // specified minimum, the node is rendered, but no other siblings + // of this node under the same parent will be. + F32 getLOD() { return mMinPixelArea; } + void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; } + + void setPickName(LLJointPickName name) { mPickName = name; } + LLJointPickName getPickName() { return mPickName; } + + void setVisible( BOOL visible, BOOL recursive ); + + // Takes meshes in mMeshParts and sets each one as a child joint + void setMeshesToChildren(); + + // LLViewerJoint interface + virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) = 0; + virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area); + virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false); + virtual BOOL updateLOD(F32 pixel_area, BOOL activate); + virtual void updateJointGeometry(); + virtual void dump(); + + +public: + static BOOL sDisableLOD; + avatar_joint_mesh_list_t mMeshParts; //LLViewerJointMesh* + void setMeshID( S32 id ) {mMeshID = id;} + +protected: + void init(); + + BOOL mValid; + BOOL mIsTransparent; + U32 mComponents; + F32 mMinPixelArea; + LLJointPickName mPickName; + BOOL mVisible; + S32 mMeshID; +}; + +class LLAvatarJointCollisionVolume : public LLAvatarJoint +{ +public: + LLAvatarJointCollisionVolume(); + virtual ~LLAvatarJointCollisionVolume() {}; + + /*virtual*/ BOOL inheritScale() { return TRUE; } + /*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ); + + void renderCollision(); + + LLVector3 getVolumePos(LLVector3 &offset); +}; + +#endif // LL_LLAVATARJOINT_H + + diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp new file mode 100644 index 000000000..4a5cff1dc --- /dev/null +++ b/indra/llappearance/llavatarjointmesh.cpp @@ -0,0 +1,375 @@ +/** + * @file LLAvatarJointMesh.cpp + * @brief Implementation of LLAvatarJointMesh class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "linden_common.h" +#include "imageids.h" +#include "llfasttimer.h" +#include "llrender.h" + +#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" +#include "m4math.h" +#include "llmatrix4a.h" + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// LLAvatarJointMesh::LLSkinJoint +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// LLSkinJoint +//----------------------------------------------------------------------------- +LLSkinJoint::LLSkinJoint() +{ + mJoint = NULL; +} + +//----------------------------------------------------------------------------- +// ~LLSkinJoint +//----------------------------------------------------------------------------- +LLSkinJoint::~LLSkinJoint() +{ + mJoint = NULL; +} + + +//----------------------------------------------------------------------------- +// LLSkinJoint::setupSkinJoint() +//----------------------------------------------------------------------------- +BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint) +{ + // find the named joint + mJoint = joint; + if ( !mJoint ) + { + llinfos << "Can't find joint" << llendl; + } + + // compute the inverse root skin matrix + mRootToJointSkinOffset.clearVec(); + + LLVector3 rootSkinOffset; + while (joint) + { + rootSkinOffset += joint->getSkinOffset(); + joint = (LLAvatarJoint*)joint->getParent(); + } + + mRootToJointSkinOffset = -rootSkinOffset; + mRootToParentJointSkinOffset = mRootToJointSkinOffset; + mRootToParentJointSkinOffset += mJoint->getSkinOffset(); + + return TRUE; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// LLAvatarJointMesh +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +BOOL LLAvatarJointMesh::sPipelineRender = FALSE; +EAvatarRenderPass LLAvatarJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; +U32 LLAvatarJointMesh::sClothingMaskImageName = 0; +LLColor4 LLAvatarJointMesh::sClothingInnerColor; + +//----------------------------------------------------------------------------- +// LLAvatarJointMesh() +//----------------------------------------------------------------------------- +LLAvatarJointMesh::LLAvatarJointMesh() + : + mTexture( NULL ), + mLayerSet( NULL ), + mTestImageName( 0 ), + mFaceIndexCount(0) +{ + + mColor[0] = 1.0f; + mColor[1] = 1.0f; + mColor[2] = 1.0f; + mColor[3] = 1.0f; + mShiny = 0.0f; + mCullBackFaces = TRUE; + + mMesh = NULL; + + mNumSkinJoints = 0; + mSkinJoints = NULL; + + mFace = NULL; + + mMeshID = 0; + mUpdateXform = FALSE; + + mValid = FALSE; + + mIsTransparent = FALSE; +} + + +//----------------------------------------------------------------------------- +// ~LLAvatarJointMesh() +// Class Destructor +//----------------------------------------------------------------------------- +LLAvatarJointMesh::~LLAvatarJointMesh() +{ + mMesh = NULL; + mTexture = NULL; + freeSkinData(); +} + + +//----------------------------------------------------------------------------- +// LLAvatarJointMesh::allocateSkinData() +//----------------------------------------------------------------------------- +BOOL LLAvatarJointMesh::allocateSkinData( U32 numSkinJoints ) +{ + mSkinJoints = new LLSkinJoint[ numSkinJoints ]; + mNumSkinJoints = numSkinJoints; + return TRUE; +} + +//----------------------------------------------------------------------------- +// LLAvatarJointMesh::freeSkinData() +//----------------------------------------------------------------------------- +void LLAvatarJointMesh::freeSkinData() +{ + mNumSkinJoints = 0; + delete [] mSkinJoints; + mSkinJoints = NULL; +} + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::getColor() +//-------------------------------------------------------------------- +void LLAvatarJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha ) +{ + *red = mColor[0]; + *green = mColor[1]; + *blue = mColor[2]; + *alpha = mColor[3]; +} + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::setColor() +//-------------------------------------------------------------------- +void LLAvatarJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha ) +{ + mColor[0] = red; + mColor[1] = green; + mColor[2] = blue; + mColor[3] = alpha; +} + +void LLAvatarJointMesh::setColor( const LLColor4& color ) +{ + mColor = color; +} + + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::getTexture() +//-------------------------------------------------------------------- +//LLViewerTexture *LLAvatarJointMesh::getTexture() +//{ +// return mTexture; +//} + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::setTexture() +//-------------------------------------------------------------------- +void LLAvatarJointMesh::setTexture( LLGLTexture *texture ) +{ + mTexture = texture; + + // texture and dynamic_texture are mutually exclusive + if( texture ) + { + mLayerSet = NULL; + //texture->bindTexture(0); + //texture->setClamp(TRUE, TRUE); + } +} + + +BOOL LLAvatarJointMesh::hasGLTexture() const +{ + return mTexture.notNull() && mTexture->hasGLTexture(); +} + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::setLayerSet() +// Sets the shape texture (takes precedence over normal texture) +//-------------------------------------------------------------------- +void LLAvatarJointMesh::setLayerSet( LLTexLayerSet* layer_set ) +{ + mLayerSet = layer_set; + + // texture and dynamic_texture are mutually exclusive + if( layer_set ) + { + mTexture = NULL; + } +} + +BOOL LLAvatarJointMesh::hasComposite() const +{ + return (mLayerSet && mLayerSet->hasComposite()); +} + + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::getMesh() +//-------------------------------------------------------------------- +LLPolyMesh *LLAvatarJointMesh::getMesh() +{ + return mMesh; +} + +//----------------------------------------------------------------------------- +// LLAvatarJointMesh::setMesh() +//----------------------------------------------------------------------------- +void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh ) +{ + // set the mesh pointer + mMesh = mesh; + + // release any existing skin joints + freeSkinData(); + + if ( mMesh == NULL ) + { + return; + } + + // acquire the transform from the mesh object + setPosition( mMesh->getPosition() ); + setRotation( mMesh->getRotation() ); + setScale( mMesh->getScale() ); + + // create skin joints if necessary + if ( mMesh->hasWeights() && !mMesh->isLOD()) + { + U32 numJointNames = mMesh->getNumJointNames(); + + allocateSkinData( numJointNames ); + std::string *jointNames = mMesh->getJointNames(); + + U32 jn; + for (jn = 0; jn < numJointNames; jn++) + { + //llinfos << "Setting up joint " << jointNames[jn] << llendl; + LLAvatarJoint* joint = (LLAvatarJoint*)(getRoot()->findJoint(jointNames[jn]) ); + mSkinJoints[jn].setupSkinJoint( joint ); + } + } + + // setup joint array + if (!mMesh->isLOD()) + { + setupJoint((LLAvatarJoint*)getRoot()); + } + +// llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl; +} + +//----------------------------------------------------------------------------- +// setupJoint() +//----------------------------------------------------------------------------- +void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint) +{ +// llinfos << "Mesh: " << getName() << llendl; + +// S32 joint_count = 0; + U32 sj; + for (sj=0; sjmJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == ¤t_joint->getParent()->getWorldMatrix()) + { + // ...then just add ourselves + LLAvatarJoint* jointp = js.mJoint; + mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js)); +// llinfos << "joint " << joint_count << js.mJoint->getName() << llendl; +// joint_count++; + } + // otherwise add our parent and ourselves + else + { + mMesh->mJointRenderData.put(new LLJointRenderData(¤t_joint->getParent()->getWorldMatrix(), NULL)); +// llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl; +// joint_count++; + mMesh->mJointRenderData.put(new LLJointRenderData(¤t_joint->getWorldMatrix(), &js)); +// llinfos << "joint " << joint_count << current_joint->getName() << llendl; +// joint_count++; + } + } + + // depth-first traversal + for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin(); + iter != current_joint->mChildren.end(); ++iter) + { + LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter); + setupJoint(child_joint); + } +} + + +// End diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h new file mode 100644 index 000000000..17b7b9842 --- /dev/null +++ b/indra/llappearance/llavatarjointmesh.h @@ -0,0 +1,142 @@ +/** + * @file llavatarjointmesh.h + * @brief Declaration of LLAvatarJointMesh class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLAVATARJOINTMESH_H +#define LL_LLAVATARJOINTMESH_H + +#include "llavatarjoint.h" +#include "llgltexture.h" +#include "llpolymesh.h" +#include "v4color.h" + +class LLDrawable; +class LLFace; +class LLCharacter; +class LLTexLayerSet; + +typedef enum e_avatar_render_pass +{ + AVATAR_RENDER_PASS_SINGLE, + AVATAR_RENDER_PASS_CLOTHING_INNER, + AVATAR_RENDER_PASS_CLOTHING_OUTER +} EAvatarRenderPass; + +class LLSkinJoint +{ +public: + LLSkinJoint(); + ~LLSkinJoint(); + BOOL setupSkinJoint( LLAvatarJoint *joint); + + LLAvatarJoint *mJoint; + LLVector3 mRootToJointSkinOffset; + LLVector3 mRootToParentJointSkinOffset; +}; + +//----------------------------------------------------------------------------- +// class LLViewerJointMesh +//----------------------------------------------------------------------------- +class LLAvatarJointMesh : public virtual LLAvatarJoint +{ +protected: + LLColor4 mColor; // color value +// LLColor4 mSpecular; // specular color (always white for now) + F32 mShiny; // shiny value + LLPointer mTexture; // ptr to a global texture + LLTexLayerSet* mLayerSet; // ptr to a layer set owned by the avatar + U32 mTestImageName; // handle to a temporary texture for previewing uploads + LLPolyMesh* mMesh; // ptr to a global polymesh + BOOL mCullBackFaces; // true by default + LLFace* mFace; // ptr to a face w/ AGP copy of mesh + + U32 mFaceIndexCount; + + U32 mNumSkinJoints; + LLSkinJoint* mSkinJoints; + S32 mMeshID; + +public: + static BOOL sPipelineRender; + //RN: this is here for testing purposes + static U32 sClothingMaskImageName; + static EAvatarRenderPass sRenderPass; + static LLColor4 sClothingInnerColor; + +public: + // Constructor + LLAvatarJointMesh(); + + // Destructor + virtual ~LLAvatarJointMesh(); + + // Gets the shape color + void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha ); + + // Sets the shape color + void setColor( F32 red, F32 green, F32 blue, F32 alpha ); + void setColor( const LLColor4& color ); + + // Sets the shininess + void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; }; + + // Sets the shape texture + void setTexture( LLGLTexture *texture ); + + BOOL hasGLTexture() const; + + void setTestTexture( U32 name ) { mTestImageName = name; } + + // Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture) + void setLayerSet( LLTexLayerSet* layer_set ); + + BOOL hasComposite() const; + + // Gets the poly mesh + LLPolyMesh *getMesh(); + + // Sets the poly mesh + void setMesh( LLPolyMesh *mesh ); + + // Sets up joint matrix data for rendering + void setupJoint(LLAvatarJoint* current_joint); + + // Sets ID for picking + void setMeshID( S32 id ) {mMeshID = id;} + + // Gets ID for picking + S32 getMeshID() { return mMeshID; } + + void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; } + +private: + // Allocate skin data + BOOL allocateSkinData( U32 numSkinJoints ); + + // Free skin data + void freeSkinData(); +}; + +#endif // LL_LLAVATARJOINTMESH_H diff --git a/indra/newview/lldriverparam.cpp b/indra/llappearance/lldriverparam.cpp similarity index 88% rename from indra/newview/lldriverparam.cpp rename to indra/llappearance/lldriverparam.cpp index a1cba861c..8a3181702 100644 --- a/indra/newview/lldriverparam.cpp +++ b/indra/llappearance/lldriverparam.cpp @@ -24,22 +24,20 @@ * $/LicenseInfo$ */ -#include "llviewerprecompiledheaders.h" +#include "linden_common.h" #include "lldriverparam.h" -#include "llfasttimer.h" -#include "llvoavatar.h" -#include "llvoavatarself.h" -#include "llagent.h" +#include "llavatarappearance.h" #include "llwearable.h" -#include "llagentwearables.h" +#include "llwearabledata.h" //----------------------------------------------------------------------------- // LLDriverParamInfo //----------------------------------------------------------------------------- -LLDriverParamInfo::LLDriverParamInfo() +LLDriverParamInfo::LLDriverParamInfo() : + mDriverParam(NULL) { } @@ -112,12 +110,14 @@ void LLDriverParamInfo::toStream(std::ostream &out) out << std::endl; - if(isAgentAvatarValid()) + if(mDriverParam && mDriverParam->getAvatarAppearance()->isSelf() && + mDriverParam->getAvatarAppearance()->isValid()) { for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++) { LLDrivenEntryInfo driven = *iter; - LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID); + LLViewerVisualParam *param = + (LLViewerVisualParam*)mDriverParam->getAvatarAppearance()->getVisualParam(driven.mDrivenID); if (param) { param->getInfo()->toStream(out); @@ -139,7 +139,9 @@ void LLDriverParamInfo::toStream(std::ostream &out) } else { - llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp.get() << " for driver parameter " << getID() << llendl; + llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " + << mDriverParam->getAvatarAppearance() + << " for driver parameter " << getID() << llendl; } out << std::endl; } @@ -150,19 +152,16 @@ void LLDriverParamInfo::toStream(std::ostream &out) // LLDriverParam //----------------------------------------------------------------------------- -LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) : +LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */) : mCurrentDistortionParam( NULL ), - mAvatarp(avatarp), - mWearablep(NULL) -{ - mDefaultVec.clear(); -} - -LLDriverParam::LLDriverParam(LLWearable *wearablep) : - mCurrentDistortionParam( NULL ), - mAvatarp(NULL), - mWearablep(wearablep) + mAvatarAppearance(appearance), + mWearablep(wearable) { + llassert(mAvatarAppearance); + if (mWearablep) + { + llassert(mAvatarAppearance->isSelf()); + } mDefaultVec.clear(); } @@ -177,49 +176,22 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info) return FALSE; mInfo = info; mID = info->mID; + info->mDriverParam = this; setWeight(getDefaultWeight(), FALSE ); return TRUE; } -void LLDriverParam::setWearable(LLWearable *wearablep) -{ - if (wearablep) - { - mWearablep = wearablep; - mAvatarp = NULL; - } -} - -void LLDriverParam::setAvatar(LLVOAvatar *avatarp) -{ - if (avatarp) - { - mWearablep = NULL; - mAvatarp = avatarp; - } -} - /*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const { - LLDriverParam *new_param; - if (wearable) - { - new_param = new LLDriverParam(wearable); - } - else - { - if (mWearablep) - { - new_param = new LLDriverParam(mWearablep); - } - else - { - new_param = new LLDriverParam(mAvatarp); - } - } + llassert(wearable); + LLDriverParam *new_param = new LLDriverParam(mAvatarAppearance, wearable); + // FIXME DRANO this clobbers mWearablep, which means any code + // currently using mWearablep is wrong, or at least untested. *new_param = *this; + //new_param->mWearablep = wearable; +// new_param->mDriven.clear(); // clear driven list to avoid overwriting avatar driven params from wearables. return new_param; } @@ -456,6 +428,20 @@ const LLVector4a* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly return v; }; +S32 LLDriverParam::getDrivenParamsCount() const +{ + return mDriven.size(); +} + +const LLViewerVisualParam* LLDriverParam::getDrivenParam(S32 index) const +{ + if (0 > index || index >= (S32)mDriven.size()) + { + return NULL; + } + return mDriven[index].mParam; +} + //----------------------------------------------------------------------------- // setAnimationTarget() //----------------------------------------------------------------------------- @@ -511,6 +497,7 @@ BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross if (!found) { LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id); + if (param) param->setParamLocation(this->getParamLocation()); bool push = param && (!only_cross_params || param->getCrossWearable()); if (push) { @@ -555,7 +542,7 @@ void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type) // Thus this wearable needs to get updates from the driver wearable. // The call to setVisualParamWeight seems redundant, but is necessary // as the number of driven wearables has changed since the last update. -Nyx - LLWearable *wearable = gAgentWearables.getTopWearable(driver_type); + LLWearable *wearable = mAvatarAppearance->getWearableData()->getTopWearable(driver_type); if (wearable) { wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false); @@ -623,13 +610,22 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake) { - if(isAgentAvatarValid() && - mWearablep && - driven->mParam->getCrossWearable() && - mWearablep->isOnTop()) + bool use_self = false; + if(mWearablep && + mAvatarAppearance->isValid() && + driven->mParam->getCrossWearable()) + { + LLWearable* wearable = dynamic_cast (mWearablep); + if (mAvatarAppearance->getWearableData()->isOnTop(wearable)) + { + use_self = true; + } + } + + if (use_self) { // call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values - gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake ); + mAvatarAppearance->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake ); } else { diff --git a/indra/newview/lldriverparam.h b/indra/llappearance/lldriverparam.h similarity index 84% rename from indra/newview/lldriverparam.h rename to indra/llappearance/lldriverparam.h index 7a4d711d4..1a24cefa1 100644 --- a/indra/newview/lldriverparam.h +++ b/indra/llappearance/lldriverparam.h @@ -30,8 +30,8 @@ #include "llviewervisualparam.h" #include "llwearabletype.h" -class LLPhysicsMotion; -class LLVOAvatar; +class LLAvatarAppearance; +class LLDriverParam; class LLWearable; //----------------------------------------------------------------------------- @@ -71,25 +71,39 @@ public: protected: typedef std::deque entry_info_list_t; entry_info_list_t mDrivenInfoList; + LLDriverParam* mDriverParam; // backpointer }; //----------------------------------------------------------------------------- class LLDriverParam : public LLViewerVisualParam { - friend class LLPhysicsMotion; // physics motion needs to access driven params directly. + friend class LLPhysicsMotion; +private: + // Hide the default constructor. Force construction with LLAvatarAppearance. + LLDriverParam() {} public: - LLDriverParam(LLVOAvatar *avatarp); - LLDriverParam(LLWearable *wearablep); + LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable = NULL); ~LLDriverParam(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + // Special: These functions are overridden by child classes LLDriverParamInfo* getInfo() const { return (LLDriverParamInfo*)mInfo; } // This sets mInfo and calls initialization functions BOOL setInfo(LLDriverParamInfo *info); - void setWearable(LLWearable *wearablep); - void setAvatar(LLVOAvatar *avatarp); + LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; } + const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; } + void updateCrossDrivenParams(LLWearableType::EType driven_type); /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const; @@ -111,6 +125,9 @@ public: /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); + S32 getDrivenParamsCount() const; + const LLViewerVisualParam* getDrivenParam(S32 index) const; + protected: F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight); void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake); @@ -121,7 +138,7 @@ protected: entry_list_t mDriven; LLViewerVisualParam* mCurrentDistortionParam; // Backlink only; don't make this an LLPointer. - LLVOAvatar* mAvatarp; + LLAvatarAppearance* mAvatarAppearance; LLWearable* mWearablep; }; diff --git a/indra/llappearance/lljointpickname.h b/indra/llappearance/lljointpickname.h new file mode 100644 index 000000000..1d41a761f --- /dev/null +++ b/indra/llappearance/lljointpickname.h @@ -0,0 +1,49 @@ +/** + * @file lljointpickname.h + * @brief Defines OpenGL seleciton stack names + * + * $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_LLJOINTPICKNAME_H +#define LL_LLJOINTPICKNAME_H + +class LLAvatarJointMesh; + +// Sets the OpenGL selection stack name that is pushed and popped +// with this joint state. The default value indicates that no name +// should be pushed/popped. +enum LLJointPickName +{ + PN_DEFAULT = -1, + PN_0 = 0, + PN_1 = 1, + PN_2 = 2, + PN_3 = 3, + PN_4 = 4, + PN_5 = 5 +}; + +typedef std::vector avatar_joint_mesh_list_t; + +#endif // LL_LLJOINTPICKNAME_H diff --git a/indra/newview/lllocaltextureobject.cpp b/indra/llappearance/lllocaltextureobject.cpp similarity index 92% rename from indra/newview/lllocaltextureobject.cpp rename to indra/llappearance/lllocaltextureobject.cpp index 07ec0fab9..7e36a0679 100644 --- a/indra/newview/lllocaltextureobject.cpp +++ b/indra/llappearance/lllocaltextureobject.cpp @@ -23,13 +23,14 @@ * $/LicenseInfo$ */ -#include "llviewerprecompiledheaders.h" +#include "linden_common.h" #include "lllocaltextureobject.h" +#include "llimage.h" +#include "llrender.h" #include "lltexlayer.h" -#include "llviewertexture.h" -#include "lltextureentry.h" +#include "llgltexture.h" #include "lluuid.h" #include "llwearable.h" @@ -41,7 +42,7 @@ LLLocalTextureObject::LLLocalTextureObject() : mImage = NULL; } -LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id) : +LLLocalTextureObject::LLLocalTextureObject(LLGLTexture* image, const LLUUID& id) : mIsBakedReady(FALSE), mDiscard(MAX_DISCARD_LEVEL+1) { @@ -77,7 +78,7 @@ LLLocalTextureObject::~LLLocalTextureObject() { } -LLViewerFetchedTexture* LLLocalTextureObject::getImage() const +LLGLTexture* LLLocalTextureObject::getImage() const { return mImage; } @@ -126,7 +127,7 @@ BOOL LLLocalTextureObject::getBakedReady() const return mIsBakedReady; } -void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image) +void LLLocalTextureObject::setImage(LLGLTexture* new_image) { mImage = new_image; } diff --git a/indra/newview/lllocaltextureobject.h b/indra/llappearance/lllocaltextureobject.h similarity index 89% rename from indra/newview/lllocaltextureobject.h rename to indra/llappearance/lllocaltextureobject.h index b9bfc5472..9b9f41fd1 100644 --- a/indra/newview/lllocaltextureobject.h +++ b/indra/llappearance/lllocaltextureobject.h @@ -29,11 +29,10 @@ #include -#include "llviewertexture.h" +#include "llpointer.h" +#include "llgltexture.h" -class LLUUID; class LLTexLayer; -class LLTextureEntry; class LLTexLayerTemplate; class LLWearable; @@ -44,11 +43,11 @@ class LLLocalTextureObject { public: LLLocalTextureObject(); - LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id); + LLLocalTextureObject(LLGLTexture* image, const LLUUID& id); LLLocalTextureObject(const LLLocalTextureObject& lto); ~LLLocalTextureObject(); - LLViewerFetchedTexture* getImage() const; + LLGLTexture* getImage() const; LLTexLayer* getTexLayer(U32 index) const; LLTexLayer* getTexLayer(const std::string &name); U32 getNumTexLayers() const; @@ -56,7 +55,7 @@ public: S32 getDiscard() const; BOOL getBakedReady() const; - void setImage(LLViewerFetchedTexture* new_image); + void setImage(LLGLTexture* new_image); BOOL setTexLayer(LLTexLayer *new_tex_layer, U32 index); BOOL addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable); BOOL addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable); @@ -70,7 +69,7 @@ protected: private: - LLPointer mImage; + LLPointer mImage; // NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer // using shared pointers here only for smart assignment & cleanup // do NOT create new shared pointers to these objects, or keep pointers to them around diff --git a/indra/newview/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp similarity index 86% rename from indra/newview/llpolymesh.cpp rename to indra/llappearance/llpolymesh.cpp index 1265ed7c7..7ddfc874e 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/llappearance/llpolymesh.cpp @@ -27,25 +27,24 @@ //----------------------------------------------------------------------------- // Header Files //----------------------------------------------------------------------------- -#include "llviewerprecompiledheaders.h" - +#include "linden_common.h" +#include "llpolymesh.h" #include "llfasttimer.h" #include "llmemory.h" -#include "llviewercontrol.h" +//#include "llviewercontrol.h" #include "llxmltree.h" -#include "llvoavatar.h" -#include "llwearable.h" +#include "llavatarappearance.h" +//#include "llwearable.h" #include "lldir.h" #include "llvolume.h" #include "llendianswizzle.h" -#include "llpolymesh.h" #define HEADER_ASCII "Linden Mesh 1.0" #define HEADER_BINARY "Linden Binary Mesh 1.0" -extern LLControlGroup gSavedSettings; // read only +//extern LLControlGroup gSavedSettings; // read only LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data, const std::string &name); @@ -125,28 +124,28 @@ void LLPolyMeshSharedData::setupLOD(LLPolyMeshSharedData* reference_data) //----------------------------------------------------------------------------- void LLPolyMeshSharedData::freeMeshData() { - if (!mReferenceData) - { - mNumVertices = 0; + if (!mReferenceData) + { + mNumVertices = 0; - delete [] mBaseCoords; - mBaseCoords = NULL; + ll_aligned_free_16(mBaseCoords); + mBaseCoords = NULL; - delete [] mBaseNormals; - mBaseNormals = NULL; + ll_aligned_free_16(mBaseNormals); + mBaseNormals = NULL; - delete [] mBaseBinormals; - mBaseBinormals = NULL; + ll_aligned_free_16(mBaseBinormals); + mBaseBinormals = NULL; - delete [] mTexCoords; - mTexCoords = NULL; + ll_aligned_free_16(mTexCoords); + mTexCoords = NULL; - delete [] mDetailTexCoords; - mDetailTexCoords = NULL; + ll_aligned_free_16(mDetailTexCoords); + mDetailTexCoords = NULL; - delete [] mWeights; - mWeights = NULL; - } + ll_aligned_free_16(mWeights); + mWeights = NULL; + } mNumFaces = 0; delete [] mFaces; @@ -228,14 +227,14 @@ U32 LLPolyMeshSharedData::getNumKB() //----------------------------------------------------------------------------- BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices ) { - U32 i; - mBaseCoords = new LLVector4a[ numVertices ]; - mBaseNormals = new LLVector4a[ numVertices ]; - mBaseBinormals = new LLVector4a[ numVertices ]; - mTexCoords = new LLVector2[ numVertices ]; - mDetailTexCoords = new LLVector2[ numVertices ]; - mWeights = new F32[ numVertices ]; - for (i = 0; i < numVertices; i++) + U32 i; + mBaseCoords = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); + mBaseNormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); + mBaseBinormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); + mTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); + mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); + mWeights = (F32*) ll_aligned_malloc_16(numVertices*sizeof(F32)); + for (i = 0; i < numVertices; i++) { mBaseCoords[i].clear(); mBaseNormals[i].clear(); @@ -1492,7 +1491,7 @@ BOOL LLPolyMesh::setSharedFromCurrent() std::vector< LLCharacter* >::iterator avatar_it; for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it) { - LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it; + LLAvatarAppearance* avatarp = (LLAvatarAppearance*)*avatar_it; LLPolyMesh* mesh = avatarp->getMesh(mSharedData); if (mesh) { @@ -1770,250 +1769,4 @@ F32* LLPolyMesh::getWritableWeights() const return mSharedData->mWeights; } -//----------------------------------------------------------------------------- -// LLPolySkeletalDistortionInfo() -//----------------------------------------------------------------------------- -LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo() -{ -} - -BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node) -{ - llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) ); - - if (!LLViewerVisualParamInfo::parseXml(node)) - return FALSE; - - LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton"); - - if (NULL == skeletalParam) - { - llwarns << "Failed to getChildByName(\"param_skeleton\")" - << llendl; - return FALSE; - } - - for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() ) - { - if (bone->hasName("bone")) - { - std::string name; - LLVector3 scale; - LLVector3 pos; - BOOL haspos = FALSE; - - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - if (!bone->getFastAttributeString(name_string, name)) - { - llwarns << "No bone name specified for skeletal param." << llendl; - continue; - } - - static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); - if (!bone->getFastAttributeVector3(scale_string, scale)) - { - llwarns << "No scale specified for bone " << name << "." << llendl; - continue; - } - - // optional offset deformation (translation) - static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset"); - if (bone->getFastAttributeVector3(offset_string, pos)) - { - haspos = TRUE; - } - mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos)); - } - else - { - llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl; - continue; - } - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// LLPolySkeletalDistortion() -//----------------------------------------------------------------------------- -LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp) -{ - mAvatar = avatarp; - mDefaultVec.splat(0.001f); -} - -//----------------------------------------------------------------------------- -// ~LLPolySkeletalDistortion() -//----------------------------------------------------------------------------- -LLPolySkeletalDistortion::~LLPolySkeletalDistortion() -{ -} - -BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) -{ - llassert(mInfo == NULL); - if (info->mID < 0) - return FALSE; - mInfo = info; - mID = info->mID; - setWeight(getDefaultWeight(), FALSE ); - - 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) - { - llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl; - continue; - } - - if (mJointScales.find(joint) != mJointScales.end()) - { - llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl; - } - - // 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) - { - LLViewerJoint* child_joint = (LLViewerJoint*)(*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()) - { - llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl; - } - mJointOffsets[joint] = bone_info->mPositionDeformation; - } - } - return TRUE; -} - -/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const -{ - LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar); - *new_param = *this; - return new_param; -} - -//----------------------------------------------------------------------------- -// apply() -//----------------------------------------------------------------------------- -static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion"); - -void LLPolySkeletalDistortion::apply( ESex avatar_sex ) -{ - LLFastTimer t(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); - 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; -} - - -LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data, - const std::string &name) -{ - LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); - cloned_morph_data->mName = name; - for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) - { - cloned_morph_data->mCoords[v] = src_data->mCoords[v]; - cloned_morph_data->mNormals[v] = src_data->mNormals[v]; - cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]; - } - return cloned_morph_data; -} - -LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data, - const LLVector3 &direction, - const std::string &name) -{ - LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); - cloned_morph_data->mName = name; - LLVector4a dir; - dir.load3(direction.mV); - - for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) - { - cloned_morph_data->mCoords[v] = dir; - cloned_morph_data->mNormals[v].clear(); - cloned_morph_data->mBinormals[v].clear(); - } - return cloned_morph_data; -} - -LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data, - F32 scale, - const std::string &name) -{ - LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); - cloned_morph_data->mName = name; - - LLVector4a sc; - sc.splat(scale); - - LLVector4a nsc; - nsc.set(scale, -scale, scale, scale); - - for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) - { - if (cloned_morph_data->mCoords[v][1] < 0) - { - cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc); - cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc); - cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc); - } - else - { - cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc); - cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc); - cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc); - } - } - return cloned_morph_data; -} - // End diff --git a/indra/newview/llpolymesh.h b/indra/llappearance/llpolymesh.h similarity index 77% rename from indra/newview/llpolymesh.h rename to indra/llappearance/llpolymesh.h index d09909309..87f421f33 100644 --- a/indra/newview/llpolymesh.h +++ b/indra/llappearance/llpolymesh.h @@ -24,8 +24,8 @@ * $/LicenseInfo$ */ -#ifndef LL_LLPOLYMESH_H -#define LL_LLPOLYMESH_H +#ifndef LL_LLPOLYMESHINTERFACE_H +#define LL_LLPOLYMESHINTERFACE_H #include #include @@ -39,7 +39,7 @@ //#include "lldarray.h" class LLSkinJoint; -class LLVOAvatar; +class LLAvatarAppearance; class LLWearable; //#define USE_STRIPS // Use tri-strips for rendering. @@ -340,8 +340,8 @@ public: BOOL isLOD() { return mSharedData && mSharedData->isLOD(); } - void setAvatar(LLVOAvatar* avatarp) { mAvatarp = avatarp; } - LLVOAvatar* getAvatar() { return mAvatarp; } + void setAvatar(LLAvatarAppearance* avatarp) { mAvatarp = avatarp; } + LLAvatarAppearance* getAvatar() { return mAvatarp; } LLDynamicArray mJointRenderData; @@ -384,77 +384,8 @@ protected: static LLPolyMeshSharedDataTable sGlobalSharedMeshList; // Backlink only; don't make this an LLPointer. - LLVOAvatar* mAvatarp; + LLAvatarAppearance* mAvatarp; }; -//----------------------------------------------------------------------------- -// LLPolySkeletalDeformationInfo -// Shared information for LLPolySkeletalDeformations -//----------------------------------------------------------------------------- -struct LLPolySkeletalBoneInfo -{ - LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos) - : mBoneName(name), - mScaleDeformation(scale), - mPositionDeformation(pos), - mHasPositionDeformation(haspos) {} - std::string mBoneName; - LLVector3 mScaleDeformation; - LLVector3 mPositionDeformation; - BOOL mHasPositionDeformation; -}; - -class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo -{ - friend class LLPolySkeletalDistortion; -public: - LLPolySkeletalDistortionInfo(); - /*virtual*/ ~LLPolySkeletalDistortionInfo() {}; - - /*virtual*/ BOOL parseXml(LLXmlTreeNode* node); - -protected: - typedef std::vector bone_info_list_t; - bone_info_list_t mBoneInfoList; -}; - -//----------------------------------------------------------------------------- -// LLPolySkeletalDeformation -// A set of joint scale data for deforming the avatar mesh -//----------------------------------------------------------------------------- -class LLPolySkeletalDistortion : public LLViewerVisualParam -{ -public: - LLPolySkeletalDistortion(LLVOAvatar *avatarp); - ~LLPolySkeletalDistortion(); - - // Special: These functions are overridden by child classes - LLPolySkeletalDistortionInfo* getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; } - // This sets mInfo and calls initialization functions - BOOL setInfo(LLPolySkeletalDistortionInfo *info); - - /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const; - - // LLVisualParam Virtual functions - ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); - /*virtual*/ void apply( ESex sex ); - - // LLViewerVisualParam Virtual functions - /*virtual*/ F32 getTotalDistortion() { return 0.1f; } - /*virtual*/ const LLVector4a& getAvgDistortion() { return mDefaultVec; } - /*virtual*/ F32 getMaxDistortion() { return 0.1f; } - /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);} - /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;}; - /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;}; - -protected: - typedef std::map joint_vec_map_t; - joint_vec_map_t mJointScales; - joint_vec_map_t mJointOffsets; - LLVector4a mDefaultVec; - // Backlink only; don't make this an LLPointer. - LLVOAvatar *mAvatar; -}; - -#endif // LL_LLPOLYMESH_H +#endif // LL_LLPOLYMESHINTERFACE_H diff --git a/indra/newview/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp similarity index 94% rename from indra/newview/llpolymorph.cpp rename to indra/llappearance/llpolymorph.cpp index cfbe6907c..d5db0a5d3 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -27,13 +27,15 @@ //----------------------------------------------------------------------------- // Header Files //----------------------------------------------------------------------------- -#include "llviewerprecompiledheaders.h" #include "llpolymorph.h" -#include "llvoavatar.h" -#include "llwearable.h" +#include "llavatarappearance.h" +#include "llavatarjoint.h" +//#include "llwearable.h" #include "llxmltree.h" #include "llendianswizzle.h" +#include "llpolymesh.h" +#include "v2math.h" //#include "../tools/imdebug/imdebug.h" @@ -74,9 +76,9 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : { const S32 numVertices = mNumIndices; - mCoords = new LLVector4a[numVertices]; - mNormals = new LLVector4a[numVertices]; - mBinormals = new LLVector4a[numVertices]; + mCoords = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); + mNormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); + mBinormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); mTexCoords = new LLVector2[numVertices]; mVertexIndices = new U32[numVertices]; @@ -90,17 +92,12 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : } } - //----------------------------------------------------------------------------- // ~LLPolyMorphData() //----------------------------------------------------------------------------- LLPolyMorphData::~LLPolyMorphData() { - delete [] mVertexIndices; - delete [] mCoords; - delete [] mNormals; - delete [] mBinormals; - delete [] mTexCoords; + freeData(); } //----------------------------------------------------------------------------- @@ -119,12 +116,17 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) return FALSE; } + //------------------------------------------------------------------------- + // free any existing data + //------------------------------------------------------------------------- + freeData(); + //------------------------------------------------------------------------- // allocate vertices //------------------------------------------------------------------------- - mCoords = new LLVector4a[numVertices]; - mNormals = new LLVector4a[numVertices]; - mBinormals = new LLVector4a[numVertices]; + mCoords = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); + mNormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); + mBinormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); mTexCoords = new LLVector2[numVertices]; // Actually, we are allocating more space than we need for the skiplist mVertexIndices = new U32[numVertices]; @@ -207,6 +209,42 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) return TRUE; } +//----------------------------------------------------------------------------- +// freeData() +//----------------------------------------------------------------------------- +void LLPolyMorphData::freeData() +{ + if (mCoords != NULL) + { + ll_aligned_free_16(mCoords); + mCoords = NULL; + } + + if (mNormals != NULL) + { + ll_aligned_free_16(mNormals); + mNormals = NULL; + } + + if (mBinormals != NULL) + { + ll_aligned_free_16(mBinormals); + mBinormals = NULL; + } + + if (mTexCoords != NULL) + { + delete [] mTexCoords; + mTexCoords = NULL; + } + + if (mVertexIndices != NULL) + { + delete [] mVertexIndices; + mVertexIndices = NULL; + } +} + //----------------------------------------------------------------------------- // LLPolyMesh::saveLLM() //----------------------------------------------------------------------------- @@ -354,9 +392,9 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) if (num_significant == 0) nindices = 1; - LLVector4a* new_coords = new LLVector4a[nindices]; - LLVector4a* new_normals = new LLVector4a[nindices]; - LLVector4a* new_binormals = new LLVector4a[nindices]; + LLVector4a* new_coords = static_cast(ll_aligned_malloc_16(nindices * sizeof(LLVector4a))); + LLVector4a* new_normals = static_cast(ll_aligned_malloc_16(nindices * sizeof(LLVector4a))); + LLVector4a* new_binormals = static_cast(ll_aligned_malloc_16(nindices * sizeof(LLVector4a))); LLVector2* new_tex_coords = new LLVector2[nindices]; U32* new_vertex_indices = new U32[nindices]; @@ -426,7 +464,7 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) std::vector< LLCharacter* >::iterator avatar_it; for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it) { - LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it; + LLAvatarAppearance* avatarp = (LLAvatarAppearance*)*avatar_it; LLPolyMorphTarget* param = (LLPolyMorphTarget*) avatarp->getVisualParam(mName.c_str()); if (!param) @@ -490,11 +528,7 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) //------------------------------------------------------------------------- // reallocate vertices //------------------------------------------------------------------------- - delete [] mVertexIndices; - delete [] mCoords; - delete [] mNormals; - delete [] mBinormals; - delete [] mTexCoords; + freeData(); mVertexIndices = new_vertex_indices; mCoords = new_coords; @@ -601,7 +635,7 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info) mID = info->mID; setWeight(getDefaultWeight(), FALSE ); - LLVOAvatar* avatarp = mMesh->getAvatar(); + LLAvatarAppearance* avatarp = mMesh->getAvatar(); LLPolyMorphTargetInfo::volume_info_list_t::iterator iter; for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++) { diff --git a/indra/newview/llpolymorph.h b/indra/llappearance/llpolymorph.h similarity index 78% rename from indra/newview/llpolymorph.h rename to indra/llappearance/llpolymorph.h index dac698437..f7782ffb3 100644 --- a/indra/newview/llpolymorph.h +++ b/indra/llappearance/llpolymorph.h @@ -2,31 +2,25 @@ * @file llpolymorph.h * @brief Implementation of LLPolyMesh class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,10 +32,10 @@ #include "llviewervisualparam.h" +class LLAvatarJointCollisionVolume; class LLPolyMeshSharedData; -class LLVOAvatar; class LLVector2; -class LLViewerJointCollisionVolume; +class LLAvatarJointCollisionVolume; class LLWearable; //----------------------------------------------------------------------------- @@ -54,6 +48,16 @@ public: ~LLPolyMorphData(); LLPolyMorphData(const LLPolyMorphData &rhs); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + BOOL loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh); const std::string& getName() { return mName; } @@ -77,6 +81,9 @@ public: F32 mMaxDistortion; // maximum single vertex distortion in a given morph LLVector4a mAvgDistortion; // average vertex distortion, to infer directionality of the morph LLPolyMeshSharedData* mMesh; + +private: + void freeData(); }; //----------------------------------------------------------------------------- @@ -114,10 +121,10 @@ struct LLPolyVolumeMorphInfo struct LLPolyVolumeMorph { - LLPolyVolumeMorph(LLViewerJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos) + LLPolyVolumeMorph(LLAvatarJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos) : mVolume(volume), mScale(scale), mPos(pos) {}; - LLViewerJointCollisionVolume* mVolume; + LLAvatarJointCollisionVolume* mVolume; LLVector3 mScale; LLVector3 mPos; }; diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp new file mode 100644 index 000000000..5f6d30e7d --- /dev/null +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -0,0 +1,293 @@ +/** + * @file llpolyskeletaldistortion.cpp + * @brief Implementation of LLPolySkeletalDistortion classes + * + * $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$ + */ + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "llpreprocessor.h" +#include "llerrorlegacy.h" +//#include "llcommon.h" +//#include "llmemory.h" +#include "llavatarappearance.h" +#include "llavatarjoint.h" +#include "llpolymorph.h" +//#include "llviewercontrol.h" +//#include "llxmltree.h" +//#include "llvoavatar.h" +#include "llwearable.h" +//#include "lldir.h" +//#include "llvolume.h" +//#include "llendianswizzle.h" + +#include "llpolyskeletaldistortion.h" + +//----------------------------------------------------------------------------- +// LLPolySkeletalDistortionInfo() +//----------------------------------------------------------------------------- +LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo() +{ +} + +BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node) +{ + llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) ); + + if (!LLViewerVisualParamInfo::parseXml(node)) + return FALSE; + + LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton"); + + if (NULL == skeletalParam) + { + llwarns << "Failed to getChildByName(\"param_skeleton\")" + << llendl; + return FALSE; + } + + for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() ) + { + if (bone->hasName("bone")) + { + std::string name; + LLVector3 scale; + LLVector3 pos; + BOOL haspos = FALSE; + + static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); + if (!bone->getFastAttributeString(name_string, name)) + { + llwarns << "No bone name specified for skeletal param." << llendl; + continue; + } + + static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); + if (!bone->getFastAttributeVector3(scale_string, scale)) + { + llwarns << "No scale specified for bone " << name << "." << llendl; + continue; + } + + // optional offset deformation (translation) + static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset"); + if (bone->getFastAttributeVector3(offset_string, pos)) + { + haspos = TRUE; + } + mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos)); + } + else + { + llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl; + continue; + } + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// LLPolySkeletalDistortion() +//----------------------------------------------------------------------------- +LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLAvatarAppearance *avatarp) +{ + mAvatar = avatarp; + mDefaultVec.splat(0.001f); +} + +//----------------------------------------------------------------------------- +// ~LLPolySkeletalDistortion() +//----------------------------------------------------------------------------- +LLPolySkeletalDistortion::~LLPolySkeletalDistortion() +{ +} + +BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) +{ + llassert(mInfo == NULL); + if (info->mID < 0) + return FALSE; + mInfo = info; + mID = info->mID; + setWeight(getDefaultWeight(), FALSE ); + + 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) + { + llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl; + continue; + } + + if (mJointScales.find(joint) != mJointScales.end()) + { + llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl; + } + + // 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; + } + } + + if (bone_info->mHasPositionDeformation) + { + if (mJointOffsets.find(joint) != mJointOffsets.end()) + { + llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl; + } + mJointOffsets[joint] = bone_info->mPositionDeformation; + } + } + return TRUE; +} + +/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const +{ + LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar); + *new_param = *this; + return new_param; +} + +//----------------------------------------------------------------------------- +// apply() +//----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion"); + +void LLPolySkeletalDistortion::apply( ESex avatar_sex ) +{ + LLFastTimer t(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); + 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; +} + + +LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data, + const std::string &name) +{ + LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); + cloned_morph_data->mName = name; + for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) + { + cloned_morph_data->mCoords[v] = src_data->mCoords[v]; + cloned_morph_data->mNormals[v] = src_data->mNormals[v]; + cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]; + } + return cloned_morph_data; +} + +LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data, + const LLVector3 &direction, + const std::string &name) +{ + LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); + cloned_morph_data->mName = name; + LLVector4a dir; + dir.load3(direction.mV); + + for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) + { + cloned_morph_data->mCoords[v] = dir; + cloned_morph_data->mNormals[v].clear(); + cloned_morph_data->mBinormals[v].clear(); + } + return cloned_morph_data; +} + +LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data, + F32 scale, + const std::string &name) +{ + LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); + cloned_morph_data->mName = name; + + LLVector4a sc; + sc.splat(scale); + + LLVector4a nsc; + nsc.set(scale, -scale, scale, scale); + + for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) + { + if (cloned_morph_data->mCoords[v][1] < 0) + { + cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc); + cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc); + cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc); + } + else + { + cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc); + cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc); + cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc); + } + } + return cloned_morph_data; +} + +// End diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h new file mode 100644 index 000000000..b9c3c3628 --- /dev/null +++ b/indra/llappearance/llpolyskeletaldistortion.h @@ -0,0 +1,130 @@ +/** + * @file llpolyskeletaldistortion.h + * @brief Implementation of LLPolyMesh class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPOLYSKELETALDISTORTION_H +#define LL_LLPOLYSKELETALDISTORTION_H + +#include "llcommon.h" + +#include +#include +#include "llstl.h" + +#include "v3math.h" +#include "v2math.h" +#include "llquaternion.h" +//#include "llpolymorph.h" +#include "lljoint.h" +#include "llviewervisualparam.h" +//#include "lldarray.h" + +//class LLSkinJoint; +class LLAvatarAppearance; + +//#define USE_STRIPS // Use tri-strips for rendering. + +//----------------------------------------------------------------------------- +// LLPolySkeletalDeformationInfo +// Shared information for LLPolySkeletalDeformations +//----------------------------------------------------------------------------- +struct LLPolySkeletalBoneInfo +{ + LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos) + : mBoneName(name), + mScaleDeformation(scale), + mPositionDeformation(pos), + mHasPositionDeformation(haspos) {} + std::string mBoneName; + LLVector3 mScaleDeformation; + LLVector3 mPositionDeformation; + BOOL mHasPositionDeformation; +}; + +class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo +{ + friend class LLPolySkeletalDistortion; +public: + + LLPolySkeletalDistortionInfo(); + /*virtual*/ ~LLPolySkeletalDistortionInfo() {}; + + /*virtual*/ BOOL parseXml(LLXmlTreeNode* node); + +protected: + typedef std::vector bone_info_list_t; + bone_info_list_t mBoneInfoList; +}; + +//----------------------------------------------------------------------------- +// LLPolySkeletalDeformation +// A set of joint scale data for deforming the avatar mesh +//----------------------------------------------------------------------------- +class LLPolySkeletalDistortion : public LLViewerVisualParam +{ +public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + + LLPolySkeletalDistortion(LLAvatarAppearance *avatarp); + ~LLPolySkeletalDistortion(); + + // Special: These functions are overridden by child classes + LLPolySkeletalDistortionInfo* getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; } + // This sets mInfo and calls initialization functions + BOOL setInfo(LLPolySkeletalDistortionInfo *info); + + /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const; + + // LLVisualParam Virtual functions + ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); + /*virtual*/ void apply( ESex sex ); + + // LLViewerVisualParam Virtual functions + /*virtual*/ F32 getTotalDistortion() { return 0.1f; } + /*virtual*/ const LLVector4a& getAvgDistortion() { return mDefaultVec; } + /*virtual*/ F32 getMaxDistortion() { return 0.1f; } + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);} + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;}; + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;}; + +protected: + typedef std::map joint_vec_map_t; + joint_vec_map_t mJointScales; + joint_vec_map_t mJointOffsets; + LLVector4a mDefaultVec; + // Backlink only; don't make this an LLPointer. + LLAvatarAppearance *mAvatar; +}; + +#endif // LL_LLPOLYSKELETALDISTORTION_H + diff --git a/indra/newview/lltexglobalcolor.cpp b/indra/llappearance/lltexglobalcolor.cpp similarity index 92% rename from indra/newview/lltexglobalcolor.cpp rename to indra/llappearance/lltexglobalcolor.cpp index ebe5ccd6c..f38b98210 100644 --- a/indra/newview/lltexglobalcolor.cpp +++ b/indra/llappearance/lltexglobalcolor.cpp @@ -24,20 +24,20 @@ * $/LicenseInfo$ */ -#include "llviewerprecompiledheaders.h" -#include "llagent.h" +#include "linden_common.h" +#include "llavatarappearance.h" #include "lltexlayer.h" -#include "llvoavatar.h" -#include "llwearable.h" #include "lltexglobalcolor.h" +class LLWearable; + //----------------------------------------------------------------------------- // LLTexGlobalColor //----------------------------------------------------------------------------- -LLTexGlobalColor::LLTexGlobalColor(LLVOAvatar* avatar) +LLTexGlobalColor::LLTexGlobalColor(LLAvatarAppearance* appearance) : - mAvatar(avatar), + mAvatarAppearance(appearance), mInfo(NULL) { } @@ -91,7 +91,7 @@ const std::string& LLTexGlobalColor::getName() const // LLTexParamGlobalColor //----------------------------------------------------------------------------- LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) : - LLTexLayerParamColor(tex_global_color->getAvatar()), + LLTexLayerParamColor(tex_global_color->getAvatarAppearance()), mTexGlobalColor(tex_global_color) { } @@ -105,7 +105,7 @@ LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) void LLTexParamGlobalColor::onGlobalColorChanged(bool upload_bake) { - mAvatar->onGlobalColorChanged(mTexGlobalColor, upload_bake); + mAvatarAppearance->onGlobalColorChanged(mTexGlobalColor, upload_bake); } //----------------------------------------------------------------------------- diff --git a/indra/newview/lltexglobalcolor.h b/indra/llappearance/lltexglobalcolor.h similarity index 84% rename from indra/newview/lltexglobalcolor.h rename to indra/llappearance/lltexglobalcolor.h index ae0479844..286747987 100644 --- a/indra/newview/lltexglobalcolor.h +++ b/indra/llappearance/lltexglobalcolor.h @@ -1,6 +1,6 @@ /** * @file lltexglobalcolor.h - * @brief This is global texture color info used by llvoavatar. + * @brief This is global texture color info used by llavatarappearance. * * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code @@ -30,31 +30,31 @@ #include "lltexlayer.h" #include "lltexlayerparams.h" -class LLVOAvatar; +class LLAvatarAppearance; class LLWearable; class LLTexGlobalColorInfo; class LLTexGlobalColor { public: - LLTexGlobalColor( LLVOAvatar* avatar ); + LLTexGlobalColor( LLAvatarAppearance* appearance ); ~LLTexGlobalColor(); LLTexGlobalColorInfo* getInfo() const { return mInfo; } // This sets mInfo and calls initialization functions BOOL setInfo(LLTexGlobalColorInfo *info); - LLVOAvatar* getAvatar() const { return mAvatar; } + LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; } LLColor4 getColor() const; const std::string& getName() const; private: param_color_list_t mParamGlobalColorList; - LLVOAvatar* mAvatar; // just backlink, don't LLPointer + LLAvatarAppearance* mAvatarAppearance; // just backlink, don't LLPointer LLTexGlobalColorInfo *mInfo; }; -// Used by llvoavatar to determine skin/eye/hair color. +// Used by llavatarappearance to determine skin/eye/hair color. class LLTexGlobalColorInfo { friend class LLTexGlobalColor; diff --git a/indra/newview/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp similarity index 64% rename from indra/newview/lltexlayer.cpp rename to indra/llappearance/lltexlayer.cpp index 2b6195521..d1edd4f09 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -24,36 +24,29 @@ * $/LicenseInfo$ */ -#include "llviewerprecompiledheaders.h" +#include "linden_common.h" #include "lltexlayer.h" -#include "llagent.h" +#include "llavatarappearance.h" +#include "llcrc.h" +#include "imageids.h" #include "llimagej2c.h" #include "llimagetga.h" -#include "llnotificationsutil.h" +#include "lldir.h" #include "llvfile.h" #include "llvfs.h" -#include "llviewerstats.h" -#include "llviewerregion.h" -#include "llvoavatar.h" -#include "llvoavatarself.h" -#include "pipeline.h" -#include "llassetuploadresponders.h" #include "lltexlayerparams.h" -#include "llui.h" -#include "llagentwearables.h" +#include "lltexturemanagerbridge.h" +#include "llrender2dutils.h" #include "llwearable.h" -#include "llviewercontrol.h" -#include "llviewershadermgr.h" +#include "llwearabledata.h" +#include "llvertexbuffer.h" #include "llviewervisualparam.h" //#include "../tools/imdebug/imdebug.h" -using namespace LLVOAvatarDefines; - -static const S32 BAKE_UPLOAD_ATTEMPTS = 7; -static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt +using namespace LLAvatarAppearanceDefines; // runway consolidate extern std::string self_av_string(); @@ -68,7 +61,7 @@ public: ~LLTexLayerInfo(); BOOL parseXml(LLXmlTreeNode* node); - BOOL createVisualParams(LLVOAvatar *avatar); + BOOL createVisualParams(LLAvatarAppearance *appearance); BOOL isUserSettable() { return mLocalTexture != -1; } S32 getLocalTexture() const { return mLocalTexture; } BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; } @@ -95,127 +88,18 @@ private: param_alpha_info_list_t mParamAlphaInfoList; }; -//----------------------------------------------------------------------------- -// LLBakedUploadData() -//----------------------------------------------------------------------------- -LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar, - LLTexLayerSet* layerset, - const LLUUID& id, - bool highest_res) : - mAvatar(avatar), - mTexLayerSet(layerset), - mID(id), - mStartTime(LLFrameTimer::getTotalTime()), // Record starting time - mIsHighestRes(highest_res) -{ -} - //----------------------------------------------------------------------------- // LLTexLayerSetBuffer -// The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one. +// The composite image that a LLViewerTexLayerSet writes to. Each LLViewerTexLayerSet has one. //----------------------------------------------------------------------------- -// static -S32 LLTexLayerSetBuffer::sGLByteCount = 0; - -LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner, - S32 width, S32 height) : - // ORDER_LAST => must render these after the hints are created. - LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), - mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates - mNeedsUpload(FALSE), - mNumLowresUploads(0), - mUploadFailCount(0), - mNeedsUpdate(TRUE), - mNumLowresUpdates(0), +LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner) : mTexLayerSet(owner) { - LLTexLayerSetBuffer::sGLByteCount += getSize(); - mNeedsUploadTimer.start(); - mNeedsUpdateTimer.start(); } LLTexLayerSetBuffer::~LLTexLayerSetBuffer() { - LLTexLayerSetBuffer::sGLByteCount -= getSize(); - destroyGLTexture(); - for( S32 order = 0; order < ORDER_COUNT; order++ ) - { - LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. - } -} - -//virtual -S8 LLTexLayerSetBuffer::getType() const -{ - return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ; -} - -//virtual -void LLTexLayerSetBuffer::restoreGLTexture() -{ - LLViewerDynamicTexture::restoreGLTexture() ; -} - -//virtual -void LLTexLayerSetBuffer::destroyGLTexture() -{ - LLViewerDynamicTexture::destroyGLTexture() ; -} - -// static -void LLTexLayerSetBuffer::dumpTotalByteCount() -{ - llinfos << "Composite System GL Buffers: " << (LLTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl; -} - -void LLTexLayerSetBuffer::requestUpdate() -{ - restartUpdateTimer(); - mNeedsUpdate = TRUE; - mNumLowresUpdates = 0; - // If we're in the middle of uploading a baked texture, we don't care about it any more. - // When it's downloaded, ignore it. - mUploadID.setNull(); -} - -void LLTexLayerSetBuffer::requestUpload() -{ - conditionalRestartUploadTimer(); - mNeedsUpload = TRUE; - mNumLowresUploads = 0; - mUploadPending = TRUE; -} - -void LLTexLayerSetBuffer::conditionalRestartUploadTimer() -{ - // If we requested a new upload but haven't even uploaded - // a low res version of our last upload request, then - // keep the timer ticking instead of resetting it. - if (mNeedsUpload && (mNumLowresUploads == 0)) - { - mNeedsUploadTimer.unpause(); - } - else - { - mNeedsUploadTimer.unpause(); //Isn't always unpaused before this, although it should be.. - mNeedsUploadTimer.reset(); - mNeedsUploadTimer.start(); - } -} - -void LLTexLayerSetBuffer::restartUpdateTimer() -{ - mNeedsUpdateTimer.reset(); - mNeedsUpdateTimer.start(); -} - -void LLTexLayerSetBuffer::cancelUpload() -{ - mNeedsUpload = FALSE; - mUploadPending = FALSE; - mNeedsUploadTimer.pause(); - mUploadRetryTimer.reset(); } void LLTexLayerSetBuffer::pushProjection() const @@ -223,7 +107,7 @@ void LLTexLayerSetBuffer::pushProjection() const gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); gGL.loadIdentity(); - gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); + gGL.ortho(0.0f, getCompositeWidth(), 0.0f, getCompositeHeight(), -1.0f, 1.0f); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); @@ -239,64 +123,24 @@ void LLTexLayerSetBuffer::popProjection() const gGL.popMatrix(); } -BOOL LLTexLayerSetBuffer::needsRender() -{ - llassert(mTexLayerSet->getAvatar() == gAgentAvatarp); - if (!isAgentAvatarValid()) return FALSE; - - const BOOL upload_now = mNeedsUpload && isReadyToUpload(); - const BOOL update_now = mNeedsUpdate && isReadyToUpdate(); - - // Don't render if we don't want to (or aren't ready to) upload or update. - if (!(update_now || upload_now)) - { - return FALSE; - } - - // Don't render if we're animating our appearance. - if (gAgentAvatarp->getIsAppearanceAnimating()) - { - return FALSE; - } - - // Don't render if we are trying to create a shirt texture but aren't wearing a skirt. - if (gAgentAvatarp->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED && - !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT)) - { - cancelUpload(); - return FALSE; - } - - // Render if we have at least minimal level of detail for each local texture. - return mTexLayerSet->isLocalTextureDataAvailable(); -} - -void LLTexLayerSetBuffer::preRender(BOOL clear_depth) +// virtual +void LLTexLayerSetBuffer::preRenderTexLayerSet() { // Set up an ortho projection pushProjection(); - - // keep depth buffer, we don't need to clear it - LLViewerDynamicTexture::preRender(FALSE); } -void LLTexLayerSetBuffer::postRender(BOOL success) +// virtual +void LLTexLayerSetBuffer::postRenderTexLayerSet(BOOL success) { popProjection(); - - LLViewerDynamicTexture::postRender(success); } -BOOL LLTexLayerSetBuffer::render() +BOOL LLTexLayerSetBuffer::renderTexLayerSet() { // Default color mask for tex layer render gGL.setColorMask(true, true); - // do we need to upload, and do we have sufficient data to create an uploadable composite? - // TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero? - const BOOL upload_now = mNeedsUpload && isReadyToUpload(); - const BOOL update_now = mNeedsUpdate && isReadyToUpdate(); - BOOL success = TRUE; bool use_shaders = LLGLSLShader::sNoFixedFunction; @@ -311,37 +155,11 @@ BOOL LLTexLayerSetBuffer::render() // Composite the color data LLGLSUIDefault gls_ui; - success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight ); + success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(), + getCompositeWidth(), getCompositeHeight() ); gGL.flush(); - if(upload_now) - { - if (!success) - { - llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegionName() << llendl; - mUploadPending = FALSE; - } - else - { - if (mTexLayerSet->isVisible()) - { - mTexLayerSet->getAvatar()->debugBakedTextureUpload(mTexLayerSet->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish. - doUpload(); - } - else - { - mUploadPending = FALSE; - mNeedsUpload = FALSE; - mNeedsUploadTimer.pause(); - mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getBakedTexIndex(),IMG_INVISIBLE); - } - } - } - - if (update_now) - { - doUpdate(); - } + midRenderTexLayerSet(success); if (use_shaders) { @@ -354,369 +172,11 @@ BOOL LLTexLayerSetBuffer::render() gGL.setColorMask(true, true); gGL.setSceneBlendType(LLRender::BT_ALPHA); - // we have valid texture data now - mGLTexturep->setGLTextureCreated(true); - return success; } -BOOL LLTexLayerSetBuffer::isInitialized(void) const -{ - return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated(); -} - -BOOL LLTexLayerSetBuffer::uploadPending() const -{ - return mUploadPending; -} - -BOOL LLTexLayerSetBuffer::uploadNeeded() const -{ - return mNeedsUpload; -} - -BOOL LLTexLayerSetBuffer::uploadInProgress() const -{ - return !mUploadID.isNull(); -} - -BOOL LLTexLayerSetBuffer::isReadyToUpload() const -{ - if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries. - if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) return FALSE; // Don't upload if avatar is using composites. - - BOOL ready = FALSE; - if (mTexLayerSet->isLocalTextureDataFinal()) - { - // If we requested an upload and have the final LOD ready, upload (or wait a while if this is a retry) - if (mUploadFailCount == 0) - { - ready = TRUE; - } - else - { - ready = mUploadRetryTimer.getElapsedTimeF32() >= BAKE_UPLOAD_RETRY_DELAY * (1 << (mUploadFailCount - 1)); - } - } - else - { - // Upload if we've hit a timeout. Upload is a pretty expensive process so we need to make sure - // we aren't doing uploads too frequently. - const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout"); - if (texture_timeout != 0) - { - // The timeout period increases exponentially between every lowres upload in order to prevent - // spamming the server with frequent uploads. - const U32 texture_timeout_threshold = texture_timeout*(1 << mNumLowresUploads); - - // If we hit our timeout and have textures available at even lower resolution, then upload. - const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold; - const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable(); - ready = has_lower_lod && is_upload_textures_timeout; - } - } - - return ready; -} - -BOOL LLTexLayerSetBuffer::isReadyToUpdate() const -{ - // If we requested an update and have the final LOD ready, then update. - if (mTexLayerSet->isLocalTextureDataFinal()) return TRUE; - - // If we haven't done an update yet, then just do one now regardless of state of textures. - if (mNumLowresUpdates == 0) return TRUE; - - // Update if we've hit a timeout. Unlike for uploads, we can make this timeout fairly small - // since render unnecessarily doesn't cost much. - const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout"); - if (texture_timeout != 0) - { - // If we hit our timeout and have textures available at even lower resolution, then update. - const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout; - const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable(); - if (has_lower_lod && is_update_textures_timeout) return TRUE; - } - - return FALSE; -} - -BOOL LLTexLayerSetBuffer::requestUpdateImmediate() -{ - mNeedsUpdate = TRUE; - BOOL result = FALSE; - - if (needsRender()) - { - preRender(FALSE); - result = render(); - postRender(result); - } - - return result; -} - -// Create the baked texture, send it out to the server, then wait for it to come -// back so we can switch to using it. -void LLTexLayerSetBuffer::doUpload() -{ - llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl; - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES); - - // Don't need caches since we're baked now. (note: we won't *really* be baked - // until this image is sent to the server and the Avatar Appearance message is received.) - mTexLayerSet->deleteCaches(); - - // Get the COLOR information from our texture - U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ]; - glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data ); - stop_glerror(); - - // Get the MASK information from our texture - LLGLSUIDefault gls_ui; - LLPointer baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 ); - U8* baked_mask_data = baked_mask_image->getData(); - mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight); - - - // Create the baked image from our color and mask information - const S32 baked_image_components = 5; // red green blue [bump] clothing - LLPointer baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components ); - U8* baked_image_data = baked_image->getData(); - S32 i = 0; - for (S32 u=0; u < mFullWidth; u++) - { - for (S32 v=0; v < mFullHeight; v++) - { - baked_image_data[5*i + 0] = baked_color_data[4*i + 0]; - baked_image_data[5*i + 1] = baked_color_data[4*i + 1]; - baked_image_data[5*i + 2] = baked_color_data[4*i + 2]; - baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes. - baked_image_data[5*i + 4] = baked_mask_data[i]; - i++; - } - } - - LLPointer compressedImage = new LLImageJ2C; - //compressedImage->setRate(0.f); - const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask) - if (compressedImage->encode(baked_image, comment_text)) - { - LLTransactionID tid; - tid.generate(); - const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); - if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(), - gVFS, asset_id, LLAssetType::AT_TEXTURE)) - { - // Read back the file and validate. - BOOL valid = FALSE; - LLPointer integrity_test = new LLImageJ2C; - S32 file_size = 0; - U8* data = LLVFile::readFile(gVFS, LLImageBase::getPrivatePool(), asset_id, LLAssetType::AT_TEXTURE, &file_size); - if (data) - { - valid = integrity_test->validate(data, file_size); // integrity_test will delete 'data' - } - else - { - integrity_test->setLastError("Unable to read entire file"); - } - - if (valid) - { - const bool highest_lod = mTexLayerSet->isLocalTextureDataFinal(); - // Baked_upload_data is owned by the responder and deleted after the request completes. - LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, - this->mTexLayerSet, - asset_id, - highest_lod); - // upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit. - mUploadID = asset_id; - - // Upload the image - const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture"); - if(!url.empty() - && !LLPipeline::sForceOldBakedUpload // toggle debug setting UploadBakedTexOld to change between the new caps method and old method - && (mUploadFailCount < (BAKE_UPLOAD_ATTEMPTS - 1))) // Try last ditch attempt via asset store if cap upload is failing. - { - LLSD body = LLSD::emptyMap(); - // The responder will call LLTexLayerSetBuffer::onTextureUploadComplete() - LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data)); - llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl; - } - else - { - gAssetStorage->storeAssetData(tid, - LLAssetType::AT_TEXTURE, - LLTexLayerSetBuffer::onTextureUploadComplete, - baked_upload_data, - TRUE, // temp_file - TRUE, // is_priority - TRUE); // store_local - llinfos << "Baked texture upload via Asset Store." << llendl; - } - - if (highest_lod) - { - // Sending the final LOD for the baked texture. All done, pause - // the upload timer so we know how long it took. - mNeedsUpload = FALSE; - mNeedsUploadTimer.pause(); - } - else - { - // Sending a lower level LOD for the baked texture. Restart the upload timer. - mNumLowresUploads++; - mNeedsUploadTimer.unpause(); - mNeedsUploadTimer.reset(); - } - - // Print out notification that we uploaded this texture. - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { - const std::string lod_str = highest_lod ? "HighRes" : "LowRes"; - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32()); - args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32()); - args["BODYREGION"] = mTexLayerSet->getBodyRegionName(); - args["RESOLUTION"] = lod_str; - LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args); - LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL; - } - } - else - { - // The read back and validate operation failed. Remove the uploaded file. - mUploadPending = FALSE; - LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE); - file.remove(); - llinfos << "Unable to create baked upload file (reason: corrupted)." << llendl; - } - } - } - else - { - // The VFS write file operation failed. - mUploadPending = FALSE; - llinfos << "Unable to create baked upload file (reason: failed to write file)" << llendl; - } - - delete [] baked_color_data; -} - -// Mostly bookkeeping; don't need to actually "do" anything since -// render() will actually do the update. -void LLTexLayerSetBuffer::doUpdate() -{ - const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal(); - if (highest_lod) - { - mNeedsUpdate = FALSE; - } - else - { - mNumLowresUpdates++; - } - - restartUpdateTimer(); - - // need to swtich to using this layerset if this is the first update - // after getting the lowest LOD - mTexLayerSet->getAvatar()->updateMeshTextures(); - - // Print out notification that we uploaded this texture. - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { - const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal(); - const std::string lod_str = highest_lod ? "HighRes" : "LowRes"; - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32()); - args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32()); - args["BODYREGION"] = mTexLayerSet->getBodyRegionName(); - args["RESOLUTION"] = lod_str; - LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args); - LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL; - } -} - -// static -void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, - void* userdata, - S32 result, - LLExtStat ext_status) // StoreAssetData callback (not fixed) -{ - LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata; - - if (isAgentAvatarValid() && - !gAgentAvatarp->isDead() && - (baked_upload_data->mAvatar == gAgentAvatarp) && // Sanity check: only the user's avatar should be uploading textures. - (baked_upload_data->mTexLayerSet->hasComposite())) - { - LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getComposite(); - S32 failures = layerset_buffer->mUploadFailCount; - layerset_buffer->mUploadFailCount = 0; - - if (layerset_buffer->mUploadID.isNull()) - { - // The upload got canceled, we should be in the - // process of baking a new texture so request an - // upload with the new data - - // BAP: does this really belong in this callback, as - // opposed to where the cancellation takes place? - // suspect this does nothing. - layerset_buffer->requestUpload(); - } - else if (baked_upload_data->mID == layerset_buffer->mUploadID) - { - // This is the upload we're currently waiting for. - layerset_buffer->mUploadID.setNull(); - const std::string name(baked_upload_data->mTexLayerSet->getBodyRegionName()); - const std::string resolution = baked_upload_data->mIsHighestRes ? " full res " : " low res "; - if (result >= 0) - { - layerset_buffer->mUploadPending = FALSE; // Allows sending of AgentSetAppearance later - LLVOAvatarDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->mTexLayerSet); - // Update baked texture info with the new UUID - U64 now = LLFrameTimer::getTotalTime(); // Record starting time - llinfos << "Baked" << resolution << "texture upload for " << name << " took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl; - gAgentAvatarp->setNewBakedTexture(baked_te, uuid); - } - else - { - ++failures; - S32 max_attempts = baked_upload_data->mIsHighestRes ? BAKE_UPLOAD_ATTEMPTS : 1; // only retry final bakes - llwarns << "Baked" << resolution << "texture upload for " << name << " failed (attempt " << failures << "/" << max_attempts << ")" << llendl; - if (failures < max_attempts) - { - layerset_buffer->mUploadFailCount = failures; - layerset_buffer->mUploadRetryTimer.start(); - layerset_buffer->requestUpload(); - } - } - } - else - { - llinfos << "Received baked texture out of date, ignored." << llendl; - } - - gAgentAvatarp->dirtyMesh(); - } - else - { - // Baked texture failed to upload (in which case since we - // didn't set the new baked texture, it means that they'll try - // and rebake it at some point in the future (after login?)), - // or this response to upload is out of date, in which case a - // current response should be on the way or already processed. - llwarns << "Baked upload failed" << llendl; - } - - delete baked_upload_data; -} - //----------------------------------------------------------------------------- -// LLTexLayerSet +// LLTexLayerSetInfo // An ordered set of texture layers that get composited into a single texture. //----------------------------------------------------------------------------- @@ -786,7 +246,7 @@ BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node) } // creates visual params without generating layersets or layers -void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar) +void LLTexLayerSetInfo::createVisualParams(LLAvatarAppearance *appearance) { //layer_info_list_t mLayerInfoList; for (layer_info_list_t::iterator layer_iter = mLayerInfoList.begin(); @@ -794,7 +254,7 @@ void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar) layer_iter++) { LLTexLayerInfo *layer_info = *layer_iter; - layer_info->createVisualParams(avatar); + layer_info->createVisualParams(appearance); } } @@ -805,16 +265,15 @@ void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar) BOOL LLTexLayerSet::sHasCaches = FALSE; -LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) : - mComposite( NULL ), - mAvatar( avatar ), - mUpdatesEnabled( FALSE ), +LLTexLayerSet::LLTexLayerSet(LLAvatarAppearance* const appearance) : + mAvatarAppearance( appearance ), mIsVisible( TRUE ), - mBakedTexIndex(LLVOAvatarDefines::BAKED_HEAD), + mBakedTexIndex(LLAvatarAppearanceDefines::BAKED_HEAD), mInfo( NULL ) { } +// virtual LLTexLayerSet::~LLTexLayerSet() { deleteCaches(); @@ -840,13 +299,13 @@ BOOL LLTexLayerSet::setInfo(const LLTexLayerSetInfo *info) LLTexLayerInterface *layer = NULL; if ( (*iter)->isUserSettable() ) { - layer = new LLTexLayerTemplate( this ); + layer = new LLTexLayerTemplate( this, getAvatarAppearance() ); } else { layer = new LLTexLayer(this); } - // this is the first time this layer (of either type) is being created - make sure you add the parameters to the avatar + // this is the first time this layer (of either type) is being created - make sure you add the parameters to the avatar appearance if (!layer->setInfo(*iter, NULL)) { mInfo = NULL; @@ -906,21 +365,6 @@ void LLTexLayerSet::deleteCaches() } } -// Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on. -BOOL LLTexLayerSet::isLocalTextureDataAvailable() const -{ - if (!mAvatar->isSelf()) return FALSE; - return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataAvailable(this); -} - - -// Returns TRUE if all of the data for the textures that this layerset depends on have arrived. -BOOL LLTexLayerSet::isLocalTextureDataFinal() const -{ - if (!mAvatar->isSelf()) return FALSE; - return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataFinal(this); -} - BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) { @@ -1021,43 +465,31 @@ const std::string LLTexLayerSet::getBodyRegionName() const return mInfo->mBodyRegion; } -void LLTexLayerSet::requestUpdate() + +// virtual +void LLTexLayerSet::asLLSD(LLSD& sd) const { - if( mUpdatesEnabled ) + sd["visible"] = LLSD::Boolean(isVisible()); + LLSD layer_list_sd; + layer_list_t::const_iterator layer_iter = mLayerList.begin(); + layer_list_t::const_iterator layer_end = mLayerList.end(); + for(; layer_iter != layer_end; ++layer_iter); { - createComposite(); - mComposite->requestUpdate(); + LLSD layer_sd; + //LLTexLayerInterface* layer = (*layer_iter); + //if (layer) + //{ + // layer->asLLSD(layer_sd); + //} + layer_list_sd.append(layer_sd); } + LLSD mask_list_sd; + LLSD info_sd; + sd["layers"] = layer_list_sd; + sd["masks"] = mask_list_sd; + sd["info"] = info_sd; } -void LLTexLayerSet::requestUpload() -{ - createComposite(); - mComposite->requestUpload(); -} - -void LLTexLayerSet::cancelUpload() -{ - if(mComposite) - { - mComposite->cancelUpload(); - } -} - -void LLTexLayerSet::createComposite() -{ - if(!mComposite) - { - S32 width = mInfo->mWidth; - S32 height = mInfo->mHeight; - // Composite other avatars at reduced resolution - if( !mAvatar->isSelf() ) - { - llerrs << "composites should not be created for non-self avatars!" << llendl; - } - mComposite = new LLTexLayerSetBuffer( this, width, height ); - } -} void LLTexLayerSet::destroyComposite() { @@ -1067,18 +499,6 @@ void LLTexLayerSet::destroyComposite() } } -void LLTexLayerSet::setUpdatesEnabled( BOOL b ) -{ - mUpdatesEnabled = b; -} - - -void LLTexLayerSet::updateComposite() -{ - createComposite(); - mComposite->requestUpdateImmediate(); -} - LLTexLayerSetBuffer* LLTexLayerSet::getComposite() { if (!mComposite) @@ -1093,22 +513,26 @@ const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const return mComposite; } -void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 width, S32 height) +static LLFastTimer::DeclareTimer FTM_GATHER_MORPH_MASK_ALPHA("gatherMorphMaskAlpha"); +void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height) { + LLFastTimer t(FTM_GATHER_MORPH_MASK_ALPHA); memset(data, 255, width * height); for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { LLTexLayerInterface* layer = *iter; - layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height); + layer->gatherAlphaMasks(data, origin_x, origin_y, width, height); } // Set alpha back to that of our alpha masks. - renderAlphaMaskTextures(mComposite->getOriginX(), mComposite->getOriginY(), width, height, true); + renderAlphaMaskTextures(origin_x, origin_y, width, height, true); } +static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK_TEXTURES("renderAlphaMaskTextures"); void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear) { + LLFastTimer t(FTM_RENDER_ALPHA_MASK_TEXTURES); const LLTexLayerSetInfo *info = getInfo(); bool use_shaders = LLGLSLShader::sNoFixedFunction; @@ -1121,7 +545,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, { gGL.flush(); { - LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE); + LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE); if( tex ) { LLGLSUIDefault gls_ui; @@ -1178,7 +602,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components) { - mAvatar->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex); + mAvatarAppearance->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex); } BOOL LLTexLayerSet::isMorphValid() const @@ -1293,11 +717,11 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) /* if ("upper_shirt" == local_texture_name) mLocalTexture = TEX_UPPER_SHIRT; */ mLocalTexture = TEX_NUM_INDICES; - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); iter++) { - const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; if (local_texture_name == texture_dict->mName) { mLocalTexture = iter->first; @@ -1364,7 +788,7 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) return TRUE; } -BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar) +BOOL LLTexLayerInfo::createVisualParams(LLAvatarAppearance *appearance) { BOOL success = TRUE; for (param_color_info_list_t::iterator color_info_iter = mParamColorInfoList.begin(); @@ -1372,7 +796,7 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar) color_info_iter++) { LLTexLayerParamColorInfo * color_info = *color_info_iter; - LLTexLayerParamColor* param_color = new LLTexLayerParamColor(avatar); + LLTexLayerParamColor* param_color = new LLTexLayerParamColor(appearance); if (!param_color->setInfo(color_info, TRUE)) { llwarns << "NULL TexLayer Color Param could not be added to visual param list. Deleting." << llendl; @@ -1386,7 +810,7 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar) alpha_info_iter++) { LLTexLayerParamAlphaInfo * alpha_info = *alpha_info_iter; - LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha(avatar); + LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha(appearance); if (!param_alpha->setInfo(alpha_info, TRUE)) { llwarns << "NULL TexLayer Alpha Param could not be added to visual param list. Deleting." << llendl; @@ -1494,6 +918,21 @@ const std::string& LLTexLayerInterface::getName() const return mInfo->mName; } +ETextureIndex LLTexLayerInterface::getLocalTextureIndex() const +{ + return (ETextureIndex) mInfo->mLocalTexture; +} + +LLWearableType::EType LLTexLayerInterface::getWearableType() const +{ + ETextureIndex te = getLocalTextureIndex(); + if (TEX_INVALID == te) + { + return LLWearableType::WT_INVALID; + } + return LLAvatarAppearanceDictionary::getTEWearableType(te); +} + LLTexLayerInterface::ERenderPass LLTexLayerInterface::getRenderPass() const { return mInfo->mRenderPass; @@ -1582,6 +1021,12 @@ LLTexLayer::~LLTexLayer() } +void LLTexLayer::asLLSD(LLSD& sd) const +{ + // *TODO: Finish + sd["id"] = getUUID(); +} + //----------------------------------------------------------------------------- // setInfo //----------------------------------------------------------------------------- @@ -1633,17 +1078,21 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t ¶m_list, LL BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) { LLGLEnable color_mat(GL_COLOR_MATERIAL); - gPipeline.disableLights(); + // *TODO: Is this correct? + //gPipeline.disableLights(); + stop_glerror(); + glDisable(GL_LIGHTING); + stop_glerror(); bool use_shaders = LLGLSLShader::sNoFixedFunction; LLColor4 net_color; BOOL color_specified = findNetColor(&net_color); - if (mTexLayerSet->getAvatar()->mIsDummy) + if (mTexLayerSet->getAvatarAppearance()->mIsDummy) { color_specified = true; - net_color = LLVOAvatar::getDummyColor(); + net_color = LLAvatarAppearance::getDummyColor(); } BOOL success = TRUE; @@ -1700,7 +1149,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly ) { { - LLViewerTexture* tex = NULL; + LLGLTexture* tex = NULL; if (mLocalTextureObject && mLocalTextureObject->getImage()) { tex = mLocalTextureObject->getImage(); @@ -1713,15 +1162,18 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) { llinfos << "lto not defined or image not defined: " << getInfo()->getLocalTexture() << " lto: " << mLocalTextureObject << llendl; } -// if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) ) +// if( mTexLayerSet->getAvatarAppearance()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) ) { if( tex ) { bool no_alpha_test = getInfo()->mWriteAllChannels; LLGLDisable alpha_test(no_alpha_test ? GL_ALPHA_TEST : 0); - if (use_shaders && no_alpha_test) + if (no_alpha_test) { - gAlphaMaskProgram.setMinimumAlpha(0.f); + if (use_shaders) + { + gAlphaMaskProgram.setMinimumAlpha(0.f); + } } LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); @@ -1733,11 +1185,13 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) gGL.getTexUnit(0)->setTextureAddressMode(old_mode); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - if (use_shaders && no_alpha_test) + if (no_alpha_test) { - gAlphaMaskProgram.setMinimumAlpha(0.004f); + if (use_shaders) + { + gAlphaMaskProgram.setMinimumAlpha(0.004f); + } } - } } // else @@ -1750,7 +1204,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) if( !getInfo()->mStaticImageFileName.empty() ) { { - LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); if( tex ) { gGL.getTexUnit(0)->bind(tex, TRUE); @@ -1772,8 +1226,9 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) LLGLDisable no_alpha(GL_ALPHA_TEST); if (use_shaders) { - gAlphaMaskProgram.setMinimumAlpha(0.f); + gAlphaMaskProgram.setMinimumAlpha(0.000f); } + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4fv( net_color.mV ); gl_rect_2d_simple( width, height ); @@ -1830,7 +1285,7 @@ BOOL LLTexLayer::findNetColor(LLColor4* net_color) const { if( !getGlobalColor().empty() ) { - net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getInfo()->mGlobalColor ) ); + net_color->setVec( mTexLayerSet->getAvatarAppearance()->getGlobalColor( getInfo()->mGlobalColor ) ); } else if (getInfo()->mFixedColor.mV[VW]) { @@ -1847,7 +1302,7 @@ BOOL LLTexLayer::findNetColor(LLColor4* net_color) const if( !getGlobalColor().empty() ) { - net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getGlobalColor() ) ); + net_color->setVec( mTexLayerSet->getAvatarAppearance()->getGlobalColor( getGlobalColor() ) ); return TRUE; } @@ -1872,7 +1327,7 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) if( !getInfo()->mStaticImageFileName.empty() ) { - LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); + LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); if( tex ) { LLGLSNoAlphaTest gls_no_alpha_test; @@ -1897,7 +1352,7 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) { if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES) { - LLViewerTexture* tex = mLocalTextureObject->getImage(); + LLGLTexture* tex = mLocalTextureObject->getImage(); if (tex) { LLGLSNoAlphaTest gls_no_alpha_test; @@ -1925,8 +1380,10 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) addAlphaMask(data, originX, originY, width, height); } +static LLFastTimer::DeclareTimer FTM_RENDER_MORPH_MASKS("renderMorphMasks"); BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color) { + LLFastTimer t(FTM_RENDER_MORPH_MASKS); BOOL success = TRUE; llassert( !mParamAlphaList.empty() ); @@ -1971,7 +1428,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC // Accumulate the alpha component of the texture if( getInfo()->mLocalTexture != -1 ) { - LLViewerTexture* tex = mLocalTextureObject->getImage(); + LLGLTexture* tex = mLocalTextureObject->getImage(); if( tex && (tex->getComponents() == 4) ) { LLGLSNoAlphaTest gls_no_alpha_test; @@ -1989,7 +1446,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC if( !getInfo()->mStaticImageFileName.empty() ) { - LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); if( tex ) { if( (tex->getComponents() == 4) || @@ -2040,7 +1497,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC if (!alpha_data) { // clear out a slot if we have filled our cache - S32 max_cache_entries = getTexLayerSet()->getAvatar()->isSelf() ? 4 : 1; + S32 max_cache_entries = getTexLayerSet()->getAvatarAppearance()->isSelf() ? 4 : 1; while ((S32)mAlphaCache.size() >= max_cache_entries) { alpha_cache_t::iterator iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry @@ -2053,7 +1510,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); } - getTexLayerSet()->getAvatar()->dirtyMesh(); + getTexLayerSet()->getAvatarAppearance()->dirtyMesh(); mMorphMasksValid = TRUE; getTexLayerSet()->applyMorphMask(alpha_data, width, height, 1); @@ -2062,8 +1519,10 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC return success; } +static LLFastTimer::DeclareTimer FTM_ADD_ALPHA_MASK("addAlphaMask"); void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height) { + LLFastTimer t(FTM_ADD_ALPHA_MASK); S32 size = width * height; const U8* alphaData = getAlphaData(); if (!alphaData && hasAlphaParams()) @@ -2106,7 +1565,7 @@ LLUUID LLTexLayer::getUUID() const LLUUID uuid; if( getInfo()->mLocalTexture != -1 ) { - LLViewerTexture* tex = mLocalTextureObject->getImage(); + LLGLTexture* tex = mLocalTextureObject->getImage(); if (tex) { uuid = mLocalTextureObject->getID(); @@ -2114,7 +1573,7 @@ LLUUID LLTexLayer::getUUID() const } if( !getInfo()->mStaticImageFileName.empty() ) { - LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); if( tex ) { uuid = tex->getID(); @@ -2137,13 +1596,15 @@ LLUUID LLTexLayer::getUUID() const // * a texture entry index (TE) // * (optional) one or more alpha parameters (weighted alpha textures) //----------------------------------------------------------------------------- -LLTexLayerTemplate::LLTexLayerTemplate(LLTexLayerSet* layer_set) : - LLTexLayerInterface(layer_set) +LLTexLayerTemplate::LLTexLayerTemplate(LLTexLayerSet* layer_set, LLAvatarAppearance* const appearance) : + LLTexLayerInterface(layer_set), + mAvatarAppearance( appearance ) { } LLTexLayerTemplate::LLTexLayerTemplate(const LLTexLayerTemplate &layer) : - LLTexLayerInterface(layer) + LLTexLayerInterface(layer), + mAvatarAppearance(layer.getAvatarAppearance()) { } @@ -2164,18 +1625,17 @@ U32 LLTexLayerTemplate::updateWearableCache() const { mWearableCache.clear(); - S32 te = mInfo->mLocalTexture; - if (te == -1) + LLWearableType::EType wearable_type = getWearableType(); + if (LLWearableType::WT_INVALID == wearable_type) { //this isn't a cloneable layer return 0; } - LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te); - U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); + U32 num_wearables = getAvatarAppearance()->getWearableData()->getWearableCount(wearable_type); U32 added = 0; for (U32 i = 0; i < num_wearables; i++) { - LLWearable* wearable = gAgentWearables.getWearable(wearable_type, i); + LLWearable* wearable = getAvatarAppearance()->getWearableData()->getWearable(wearable_type, i); if (!wearable) { continue; @@ -2230,7 +1690,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const } if (layer) { - wearable->writeToAvatar(); + wearable->writeToAvatar(mAvatarAppearance); layer->setLTO(lto); success &= layer->render(x,y,width,height); } @@ -2337,7 +1797,7 @@ LLTexLayerInterface* LLTexLayerSet::findLayerByName(const std::string& name) return NULL; } -void LLTexLayerSet::cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable *wearable) +void LLTexLayerSet::cloneTemplates(LLLocalTextureObject *lto, LLAvatarAppearanceDefines::ETextureIndex tex_index, LLWearable *wearable) { // initialize all texlayers with this texture type for this LTO for( LLTexLayerSet::layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) @@ -2404,8 +1864,10 @@ void LLTexLayerStaticImageList::deleteCachedImages() // Returns an LLImageTGA that contains the encoded data from a tga file named file_name. // Caches the result to speed identical subsequent requests. +static LLFastTimer::DeclareTimer FTM_LOAD_STATIC_TGA("getImageTGA"); LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name) { + LLFastTimer t(FTM_LOAD_STATIC_TGA); const char *namekey = mImageNames.addString(file_name); image_tga_map_t::const_iterator iter = mStaticImageListTGA.find(namekey); if( iter != mStaticImageListTGA.end() ) @@ -2432,9 +1894,11 @@ LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name) // Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name. // Caches the result to speed identical subsequent requests. -LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask) +static LLFastTimer::DeclareTimer FTM_LOAD_STATIC_TEXTURE("getTexture"); +LLGLTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask) { - LLPointer tex; + LLFastTimer t(FTM_LOAD_STATIC_TEXTURE); + LLPointer tex; const char *namekey = mImageNames.addString(file_name); texture_map_t::const_iterator iter = mStaticImageList.find(namekey); @@ -2444,7 +1908,8 @@ LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_n } else { - tex = LLViewerTextureManager::getLocalTexture( FALSE ); + llassert(gTextureManagerBridgep); + tex = gTextureManagerBridgep->getLocalTexture( FALSE ); LLPointer image_raw = new LLImageRaw; if( loadImageRaw( file_name, image_raw ) ) { @@ -2454,7 +1919,7 @@ LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_n // that once an image is a mask it's always a mask. tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); } - tex->createGLTexture(0, image_raw, 0, TRUE, LLViewerTexture::LOCAL); + tex->createGLTexture(0, image_raw, 0, TRUE, LLGLTexture::LOCAL); gGL.getTexUnit(0)->bind(tex); tex->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -2473,8 +1938,10 @@ LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_n // Reads a .tga file, decodes it, and puts the decoded data in image_raw. // Returns TRUE if successful. +static LLFastTimer::DeclareTimer FTM_LOAD_IMAGE_RAW("loadImageRaw"); BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLImageRaw* image_raw) { + LLFastTimer t(FTM_LOAD_IMAGE_RAW); BOOL success = FALSE; std::string path; path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name); @@ -2488,23 +1955,3 @@ BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLIma return success; } -const std::string LLTexLayerSetBuffer::dumpTextureInfo() const -{ - if (!isAgentAvatarValid()) return ""; - - const BOOL is_high_res = !mNeedsUpload; - const U32 num_low_res = mNumLowresUploads; - const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32(); - const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(mTexLayerSet); - - std::string status = "CREATING "; - if (!uploadNeeded()) status = "DONE "; - if (uploadInProgress()) status = "UPLOADING"; - - std::string text = llformat("[%s] [HiRes:%d LoRes:%d] [Elapsed:%d] %s", - status.c_str(), - is_high_res, num_low_res, - upload_time, - local_texture_info.c_str()); - return text; -} diff --git a/indra/newview/lltexlayer.h b/indra/llappearance/lltexlayer.h similarity index 66% rename from indra/newview/lltexlayer.h rename to indra/llappearance/lltexlayer.h index 4f43547da..f267753f2 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/llappearance/lltexlayer.h @@ -28,14 +28,15 @@ #define LL_LLTEXLAYER_H #include -#include "lldynamictexture.h" -#include "llvoavatardefines.h" +#include "llglslshader.h" +#include "llgltexture.h" +#include "llavatarappearancedefines.h" #include "lltexlayerparams.h" -class LLVOAvatar; -class LLVOAvatarSelf; +class LLAvatarAppearance; class LLImageTGA; class LLImageRaw; +class LLLocalTextureObject; class LLXmlTreeNode; class LLTexLayerSet; class LLTexLayerSetInfo; @@ -50,7 +51,7 @@ class LLViewerVisualParam; // Interface class to generalize functionality shared by LLTexLayer // and LLTexLayerTemplate. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLTexLayerInterface +class LLTexLayerInterface { public: enum ERenderPass @@ -71,6 +72,8 @@ public: const LLTexLayerInfo* getInfo() const { return mInfo; } virtual BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // sets mInfo, calls initialization functions + LLWearableType::EType getWearableType() const; + LLAvatarAppearanceDefines::ETextureIndex getLocalTextureIndex() const; const std::string& getName() const; const LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; } @@ -88,6 +91,8 @@ public: ERenderPass getRenderPass() const; BOOL isVisibilityMask() const; + virtual void asLLSD(LLSD& sd) const {} + protected: const std::string& getGlobalColor() const; LLViewerVisualParam* getVisualParamPtr(S32 index) const; @@ -113,7 +118,7 @@ protected: class LLTexLayerTemplate : public LLTexLayerInterface { public: - LLTexLayerTemplate(LLTexLayerSet* const layer_set); + LLTexLayerTemplate(LLTexLayerSet* const layer_set, LLAvatarAppearance* const appearance); LLTexLayerTemplate(const LLTexLayerTemplate &layer); /*virtual*/ ~LLTexLayerTemplate(); /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height); @@ -126,7 +131,9 @@ public: protected: U32 updateWearableCache() const; LLTexLayer* getLayer(U32 i) const; + LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; } private: + LLAvatarAppearance* const mAvatarAppearance; // note: backlink only; don't make this an LLPointer. typedef std::vector wearable_cache_t; mutable wearable_cache_t mWearableCache; // mutable b/c most get- require updating this cache }; @@ -160,10 +167,11 @@ public: void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; } LLLocalTextureObject* getLTO() { return mLocalTextureObject; } + /*virtual*/ void asLLSD(LLSD& sd) const; + static void calculateTexLayerColor(const param_color_list_t ¶m_list, LLColor4 &net_color); protected: LLUUID getUUID() const; -private: typedef std::map alpha_cache_t; alpha_cache_t mAlphaCache; LLLocalTextureObject* mLocalTextureObject; @@ -179,8 +187,14 @@ class LLTexLayerSet { friend class LLTexLayerSetBuffer; public: - LLTexLayerSet(LLVOAvatarSelf* const avatar); - ~LLTexLayerSet(); + LLTexLayerSet(LLAvatarAppearance* const appearance); + virtual ~LLTexLayerSet(); + + LLTexLayerSetBuffer* getComposite(); + const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist. + virtual void createComposite() = 0; + void destroyComposite(); + void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height); const LLTexLayerSetInfo* getInfo() const { return mInfo; } BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions @@ -189,45 +203,34 @@ public: void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false); BOOL isBodyRegion(const std::string& region) const; - LLTexLayerSetBuffer* getComposite(); - const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist. - void requestUpdate(); - void requestUpload(); - void cancelUpload(); - void updateComposite(); - BOOL isLocalTextureDataAvailable() const; - BOOL isLocalTextureDataFinal() const; - void createComposite(); - void destroyComposite(); - void setUpdatesEnabled(BOOL b); - BOOL getUpdatesEnabled() const { return mUpdatesEnabled; } - void deleteCaches(); - void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height); void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); BOOL isMorphValid() const; + virtual void requestUpdate() = 0; void invalidateMorphMasks(); + void deleteCaches(); LLTexLayerInterface* findLayerByName(const std::string& name); - void cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable); + void cloneTemplates(LLLocalTextureObject *lto, LLAvatarAppearanceDefines::ETextureIndex tex_index, LLWearable* wearable); - LLVOAvatarSelf* getAvatar() const { return mAvatar; } + LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; } const std::string getBodyRegionName() const; BOOL hasComposite() const { return (mComposite.notNull()); } - LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } - void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } + LLAvatarAppearanceDefines::EBakedTextureIndex getBakedTexIndex() const { return mBakedTexIndex; } + void setBakedTexIndex(LLAvatarAppearanceDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } BOOL isVisible() const { return mIsVisible; } static BOOL sHasCaches; -private: + virtual void asLLSD(LLSD& sd) const; + +protected: typedef std::vector layer_list_t; layer_list_t mLayerList; layer_list_t mMaskLayerList; LLPointer mComposite; - LLVOAvatarSelf* const mAvatar; // note: backlink only; don't make this an LLPointer. - BOOL mUpdatesEnabled; + LLAvatarAppearance* const mAvatarAppearance; // note: backlink only; don't make this an LLPointer. BOOL mIsVisible; - LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex; + LLAvatarAppearanceDefines::EBakedTextureIndex mBakedTexIndex; const LLTexLayerSetInfo* mInfo; }; @@ -243,8 +246,10 @@ public: LLTexLayerSetInfo(); ~LLTexLayerSetInfo(); BOOL parseXml(LLXmlTreeNode* node); - void createVisualParams(LLVOAvatar *avatar); -private: + void createVisualParams(LLAvatarAppearance *appearance); + S32 getWidth() const { return mWidth; } + S32 getHeight() const { return mHeight; } +protected: std::string mBodyRegion; S32 mWidth; S32 mHeight; @@ -259,78 +264,27 @@ private: // // The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLTexLayerSetBuffer : public LLViewerDynamicTexture +class LLTexLayerSetBuffer : public virtual LLRefCount { LOG_CLASS(LLTexLayerSetBuffer); public: - LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height); + LLTexLayerSetBuffer(LLTexLayerSet* const owner); virtual ~LLTexLayerSetBuffer(); -public: - /*virtual*/ S8 getType() const; - BOOL isInitialized(void) const; - static void dumpTotalByteCount(); - const std::string dumpTextureInfo() const; - virtual void restoreGLTexture(); - virtual void destroyGLTexture(); protected: void pushProjection() const; void popProjection() const; -private: - LLTexLayerSet* const mTexLayerSet; - static S32 sGLByteCount; + virtual void preRenderTexLayerSet(); + virtual void midRenderTexLayerSet(BOOL success) {} + virtual void postRenderTexLayerSet(BOOL success); + virtual S32 getCompositeOriginX() const = 0; + virtual S32 getCompositeOriginY() const = 0; + virtual S32 getCompositeWidth() const = 0; + virtual S32 getCompositeHeight() const = 0; + BOOL renderTexLayerSet(); - //-------------------------------------------------------------------- - // Render - //-------------------------------------------------------------------- -public: - /*virtual*/ BOOL needsRender(); -protected: - BOOL render(S32 x, S32 y, S32 width, S32 height); - virtual void preRender(BOOL clear_depth); - virtual void postRender(BOOL success); - virtual BOOL render(); - - //-------------------------------------------------------------------- - // Uploads - //-------------------------------------------------------------------- -public: - void requestUpload(); - void cancelUpload(); - BOOL uploadNeeded() const; // We need to upload a new texture - BOOL uploadInProgress() const; // We have started uploading a new texture and are awaiting the result - BOOL uploadPending() const; // We are expecting a new texture to be uploaded at some point - static void onTextureUploadComplete(const LLUUID& uuid, - void* userdata, - S32 result, LLExtStat ext_status); -protected: - BOOL isReadyToUpload() const; - void doUpload(); // Does a read back and upload. - void conditionalRestartUploadTimer(); -private: - BOOL mNeedsUpload; // Whether we need to send our baked textures to the server - U32 mNumLowresUploads; // Number of times we've sent a lowres version of our baked textures to the server - BOOL mUploadPending; // Whether we have received back the new baked textures - LLUUID mUploadID; // The current upload process (null if none). - LLFrameTimer mNeedsUploadTimer; // Tracks time since upload was requested and performed. - S32 mUploadFailCount; // Number of consecutive upload failures - LLFrameTimer mUploadRetryTimer; // Tracks time since last upload failure. - - //-------------------------------------------------------------------- - // Updates - //-------------------------------------------------------------------- -public: - void requestUpdate(); - BOOL requestUpdateImmediate(); -protected: - BOOL isReadyToUpdate() const; - void doUpdate(); - void restartUpdateTimer(); -private: - BOOL mNeedsUpdate; // Whether we need to locally update our baked textures - U32 mNumLowresUpdates; // Number of times we've locally updated with lowres version of our baked textures - LLFrameTimer mNeedsUpdateTimer; // Tracks time since update was requested and performed. + LLTexLayerSet* const mTexLayerSet; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -342,7 +296,7 @@ class LLTexLayerStaticImageList : public LLSingleton public: LLTexLayerStaticImageList(); ~LLTexLayerStaticImageList(); - LLViewerTexture* getTexture(const std::string& file_name, BOOL is_mask); + LLGLTexture* getTexture(const std::string& file_name, BOOL is_mask); LLImageTGA* getImageTGA(const std::string& file_name); void deleteCachedImages(); void dumpByteCount() const; @@ -350,7 +304,7 @@ protected: BOOL loadImageRaw(const std::string& file_name, LLImageRaw* image_raw); private: LLStringTable mImageNames; - typedef std::map > texture_map_t; + typedef std::map > texture_map_t; texture_map_t mStaticImageList; typedef std::map > image_tga_map_t; image_tga_map_t mStaticImageListTGA; @@ -358,23 +312,4 @@ private: S32 mTGABytes; }; -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// LLBakedUploadData -// -// Used by LLTexLayerSetBuffer for a callback. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -struct LLBakedUploadData -{ - LLBakedUploadData(const LLVOAvatarSelf* avatar, - LLTexLayerSet* layerset, - const LLUUID& id, - bool highest_res); - ~LLBakedUploadData() {} - const LLUUID mID; - const LLVOAvatarSelf* mAvatar; // note: backlink only; don't LLPointer - LLTexLayerSet* mTexLayerSet; - const U64 mStartTime; // for measuring baked texture upload time - const bool mIsHighestRes; // whether this is a "final" bake, or intermediate low res -}; - #endif // LL_LLTEXLAYER_H diff --git a/indra/newview/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp similarity index 85% rename from indra/newview/lltexlayerparams.cpp rename to indra/llappearance/lltexlayerparams.cpp index 8972827ef..0cdeb48ce 100644 --- a/indra/newview/lltexlayerparams.cpp +++ b/indra/llappearance/lltexlayerparams.cpp @@ -24,27 +24,28 @@ * $/LicenseInfo$ */ -#include "llviewerprecompiledheaders.h" +#include "linden_common.h" #include "lltexlayerparams.h" -#include "llagentcamera.h" +#include "llavatarappearance.h" #include "llimagetga.h" +#include "llquantize.h" #include "lltexlayer.h" -#include "llvoavatarself.h" +#include "lltexturemanagerbridge.h" +#include "llrender2dutils.h" #include "llwearable.h" -#include "llui.h" //----------------------------------------------------------------------------- // LLTexLayerParam //----------------------------------------------------------------------------- LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) : mTexLayer(layer), - mAvatar(NULL) + mAvatarAppearance(NULL) { if (mTexLayer != NULL) { - mAvatar = mTexLayer->getTexLayerSet()->getAvatar(); + mAvatarAppearance = mTexLayer->getTexLayerSet()->getAvatarAppearance(); } else { @@ -52,20 +53,21 @@ LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) : } } -LLTexLayerParam::LLTexLayerParam(LLVOAvatar *avatar) : - mTexLayer(NULL) +LLTexLayerParam::LLTexLayerParam(LLAvatarAppearance *appearance) : + mTexLayer(NULL), + mAvatarAppearance(appearance) { - mAvatar = avatar; } -BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar ) -{ +BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance) +{ LLViewerVisualParam::setInfo(info); - if (add_to_avatar) + if (add_to_appearance) { - mAvatar->addVisualParam( this); + mAvatarAppearance->addVisualParam( this); + this->setParamLocation(mAvatarAppearance->isSelf() ? LOC_AV_SELF : LOC_AV_OTHER); } return TRUE; @@ -96,7 +98,7 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes) iter != sInstances.end(); iter++) { LLTexLayerParamAlpha* instance = *iter; - LLViewerTexture* tex = instance->mCachedProcessedTexture; + LLGLTexture* tex = instance->mCachedProcessedTexture; if (tex) { S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents(); @@ -120,8 +122,8 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) : sInstances.push_front(this); } -LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLVOAvatar* avatar) : - LLTexLayerParam(avatar), +LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance) : + LLTexLayerParam(appearance), mCachedProcessedTexture(NULL), mNeedsCreateTexture(FALSE), mStaticImageInvalid(FALSE), @@ -173,13 +175,14 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake) { mCurWeight = new_weight; - if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param. + if ((mAvatarAppearance->getSex() & getSex()) && + (mAvatarAppearance->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param. { - if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) + if (mAvatarAppearance->isValid() && mAvatarAppearance->isEditingAppearance()) { upload_bake = FALSE; } - mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake); + mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake); mTexLayer->invalidateMorphMasks(); } } @@ -218,11 +221,11 @@ BOOL LLTexLayerParamAlpha::getSkip() const return TRUE; } - const LLVOAvatar *avatar = mTexLayer->getTexLayerSet()->getAvatar(); + const LLAvatarAppearance *appearance = mTexLayer->getTexLayerSet()->getAvatarAppearance(); if (((LLTexLayerParamAlphaInfo *)getInfo())->mSkipIfZeroWeight) { - F32 effective_weight = (avatar->getSex() & getSex()) ? mCurWeight : getDefaultWeight(); + F32 effective_weight = (appearance->getSex() & getSex()) ? mCurWeight : getDefaultWeight(); if (is_approx_zero(effective_weight)) { return TRUE; @@ -230,7 +233,7 @@ BOOL LLTexLayerParamAlpha::getSkip() const } LLWearableType::EType type = (LLWearableType::EType)getWearableType(); - if ((type != LLWearableType::WT_INVALID) && !avatar->isWearingWearableType(type)) + if ((type != LLWearableType::WT_INVALID) && !appearance->isWearingWearableType(type)) { return TRUE; } @@ -239,8 +242,10 @@ BOOL LLTexLayerParamAlpha::getSkip() const } +static LLFastTimer::DeclareTimer FTM_TEX_LAYER_PARAM_ALPHA("alpha render"); BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) { + LLFastTimer t(FTM_TEX_LAYER_PARAM_ALPHA); BOOL success = TRUE; if (!mTexLayer) @@ -248,7 +253,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) return success; } - F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatar()->getSex() & getSex()) ? mCurWeight : getDefaultWeight(); + F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatarAppearance()->getSex() & getSex()) ? mCurWeight : getDefaultWeight(); BOOL weight_changed = effective_weight != mCachedEffectiveWeight; if (getSkip()) { @@ -290,12 +295,12 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) (mCachedProcessedTexture->getHeight() != image_tga_height) || (weight_changed)) { -// llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl; mCachedEffectiveWeight = effective_weight; if (!mCachedProcessedTexture) { - mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture(image_tga_width, image_tga_height, 1, FALSE); + llassert(gTextureManagerBridgep); + mCachedProcessedTexture = gTextureManagerBridgep->getLocalTexture(image_tga_width, image_tga_height, 1, FALSE); // We now have something in one of our caches LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE; @@ -308,6 +313,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) mStaticImageRaw = new LLImageRaw; mStaticImageTGA->decodeAndProcess(mStaticImageRaw, info->mDomain, effective_weight); mNeedsCreateTexture = TRUE; + lldebugs << "Built Cached Alpha: " << info->mStaticImageFileName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << "Domain: " << info->mDomain << " Weight: " << effective_weight << llendl; } if (mCachedProcessedTexture) @@ -332,7 +338,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) // Don't keep the cache for other people's avatars // (It's not really a "cache" in that case, but the logic is the same) - if (!mAvatar->isSelf()) + if (!mAvatarAppearance->isSelf()) { mCachedProcessedTexture = NULL; } @@ -402,8 +408,8 @@ LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) : { } -LLTexLayerParamColor::LLTexLayerParamColor(LLVOAvatar *avatar) : - LLTexLayerParam(avatar), +LLTexLayerParamColor::LLTexLayerParamColor(LLAvatarAppearance *appearance) : + LLTexLayerParam(appearance), mAvgDistortionVec(1.f, 1.f, 1.f) { } @@ -425,7 +431,7 @@ LLColor4 LLTexLayerParamColor::getNetColor() const llassert(info->mNumColors >= 1); - F32 effective_weight = (mAvatar && (mAvatar->getSex() & getSex())) ? mCurWeight : getDefaultWeight(); + F32 effective_weight = (mAvatarAppearance && (mAvatarAppearance->getSex() & getSex())) ? mCurWeight : getDefaultWeight(); S32 index_last = info->mNumColors - 1; F32 scaled_weight = effective_weight * index_last; @@ -470,12 +476,12 @@ void LLTexLayerParamColor::setWeight(F32 weight, BOOL upload_bake) return; } - if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param. + if ((mAvatarAppearance->getSex() & getSex()) && (mAvatarAppearance->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param. { onGlobalColorChanged(upload_bake); if (mTexLayer) { - mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake); + mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake); } } diff --git a/indra/newview/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h similarity index 91% rename from indra/newview/lltexlayerparams.h rename to indra/llappearance/lltexlayerparams.h index 2c0da60b4..ca1497ebf 100644 --- a/indra/newview/lltexlayerparams.h +++ b/indra/llappearance/lltexlayerparams.h @@ -27,14 +27,16 @@ #ifndef LL_LLTEXLAYERPARAMS_H #define LL_LLTEXLAYERPARAMS_H +#include "llpointer.h" +#include "v4color.h" #include "llviewervisualparam.h" +class LLAvatarAppearance; class LLImageRaw; class LLImageTGA; class LLTexLayer; class LLTexLayerInterface; -class LLViewerTexture; -class LLVOAvatar; +class LLGLTexture; class LLWearable; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -45,13 +47,13 @@ class LLTexLayerParam : public LLViewerVisualParam { public: LLTexLayerParam(LLTexLayerInterface *layer); - LLTexLayerParam(LLVOAvatar *avatar); - /*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar ); + LLTexLayerParam(LLAvatarAppearance *appearance); + /*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance); /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0; protected: LLTexLayerInterface* mTexLayer; - LLVOAvatar* mAvatar; + LLAvatarAppearance* mAvatarAppearance; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -62,11 +64,21 @@ class LLTexLayerParamAlpha : public LLTexLayerParam { public: LLTexLayerParamAlpha( LLTexLayerInterface* layer ); - LLTexLayerParamAlpha( LLVOAvatar* avatar ); + LLTexLayerParamAlpha( LLAvatarAppearance* appearance ); /*virtual*/ ~LLTexLayerParamAlpha(); /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const; + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); /*virtual*/ void apply( ESex avatar_sex ) {} @@ -89,7 +101,7 @@ public: BOOL getMultiplyBlend() const; private: - LLPointer mCachedProcessedTexture; + LLPointer mCachedProcessedTexture; LLPointer mStaticImageTGA; LLPointer mStaticImageRaw; BOOL mNeedsCreateTexture; @@ -140,9 +152,19 @@ public: }; LLTexLayerParamColor( LLTexLayerInterface* layer ); - LLTexLayerParamColor( LLVOAvatar* avatar ); + LLTexLayerParamColor( LLAvatarAppearance* appearance ); /* virtual */ ~LLTexLayerParamColor(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const; // LLVisualParam Virtual functions diff --git a/indra/llappearance/lltexturemanagerbridge.cpp b/indra/llappearance/lltexturemanagerbridge.cpp new file mode 100644 index 000000000..939f6d620 --- /dev/null +++ b/indra/llappearance/lltexturemanagerbridge.cpp @@ -0,0 +1,33 @@ + /** + * @file lltexturemanagerbridge.cpp + * @brief Defined a null texture manager bridge. Applications must provide their own bridge implementaton. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "lltexturemanagerbridge.h" + +// Define a null texture manager bridge. Applications must provide their own bridge implementaton. +LLTextureManagerBridge* gTextureManagerBridgep = NULL; + + diff --git a/indra/llappearance/lltexturemanagerbridge.h b/indra/llappearance/lltexturemanagerbridge.h new file mode 100644 index 000000000..355bcf02b --- /dev/null +++ b/indra/llappearance/lltexturemanagerbridge.h @@ -0,0 +1,47 @@ +/** + * @file lltexturemanagerbridge.h + * @brief Bridge to an application-specific texture manager. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_TEXTUREMANAGERBRIDGE_H +#define LL_TEXTUREMANAGERBRIDGE_H + +#include "llavatarappearancedefines.h" +#include "llpointer.h" +#include "llgltexture.h" + +// Abstract bridge interface +class LLTextureManagerBridge +{ +public: + virtual ~LLTextureManagerBridge(){}; + virtual LLPointer getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) = 0; + virtual LLPointer getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) = 0; + virtual LLGLTexture* getFetchedTexture(const LLUUID &image_id) = 0; +}; + +extern LLTextureManagerBridge* gTextureManagerBridgep; + +#endif // LL_TEXTUREMANAGERBRIDGE_H + diff --git a/indra/newview/llviewervisualparam.cpp b/indra/llappearance/llviewervisualparam.cpp similarity index 78% rename from indra/newview/llviewervisualparam.cpp rename to indra/llappearance/llviewervisualparam.cpp index 422e530dc..dd5331207 100644 --- a/indra/newview/llviewervisualparam.cpp +++ b/indra/llappearance/llviewervisualparam.cpp @@ -2,42 +2,35 @@ * @file llviewervisualparam.cpp * @brief Implementation of LLViewerVisualParam class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ //----------------------------------------------------------------------------- // Header Files //----------------------------------------------------------------------------- -#include "llviewerprecompiledheaders.h" +#include "linden_common.h" #include "llviewervisualparam.h" #include "llxmltree.h" -#include "llui.h" #include "llwearable.h" //----------------------------------------------------------------------------- diff --git a/indra/newview/llviewervisualparam.h b/indra/llappearance/llviewervisualparam.h similarity index 100% rename from indra/newview/llviewervisualparam.h rename to indra/llappearance/llviewervisualparam.h diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp new file mode 100644 index 000000000..bacd4e5fb --- /dev/null +++ b/indra/llappearance/llwearable.cpp @@ -0,0 +1,820 @@ +/** + * @file llwearable.cpp + * @brief LLWearable 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 "linden_common.h" + +#include "llavatarappearance.h" +#include "lllocaltextureobject.h" +#include "lltexlayer.h" +#include "lltexturemanagerbridge.h" +#include "llvisualparam.h" +#include "llavatarappearancedefines.h" +#include "llwearable.h" + +using namespace LLAvatarAppearanceDefines; + +// static +S32 LLWearable::sCurrentDefinitionVersion = 1; + +// Private local functions +static std::string terse_F32_to_string(F32 f); + +LLWearable::LLWearable() : + mDefinitionVersion(0), + mType(LLWearableType::WT_INVALID) +{ +} + +// virtual +LLWearable::~LLWearable() +{ +} + +const std::string& LLWearable::getTypeLabel() const +{ + return LLWearableType::getTypeLabel(mType); +} + +const std::string& LLWearable::getTypeName() const +{ + return LLWearableType::getTypeName(mType); +} + +LLAssetType::EType LLWearable::getAssetType() const +{ + return LLWearableType::getAssetType(mType); +} + +// reX: new function +BOOL LLWearable::FileExportParams( FILE* file ) const +{ + // wearable type + S32 type = (S32)mType; + fprintf( file, "type %d\n", type ); + + // parameters + S32 num_parameters = mVisualParamIndexMap.size(); + fprintf( file, "parameters %d\n", num_parameters ); + + for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); + iter != mVisualParamIndexMap.end(); ++iter) + { + S32 param_id = iter->first; + F32 param_weight = iter->second->getWeight(); + fprintf( file, "%d %s\n", param_id, terse_F32_to_string(param_weight).c_str() ); + } + + return TRUE; +} + +// reX: new function +BOOL LLWearable::FileExportTextures( FILE* file ) const +{ + // wearable type + S32 type = (S32)mType; + fprintf( file, "type %d\n", type ); + + // texture entries + S32 num_textures = mTEMap.size(); + fprintf( file, "textures %d\n", num_textures ); + + for (te_map_t::const_iterator iter = mTEMap.begin(); + iter != mTEMap.end(); ++iter) + { + S32 te = iter->first; + fprintf( file, "%d %s\n", te, iter->second->getID().asString().c_str() ); + } + + return TRUE; +} + +BOOL LLWearable::exportFile(LLFILE* fp) const +{ + llofstream ofs(fp); + return exportStream(ofs); +} + +// virtual +BOOL LLWearable::exportStream( std::ostream& output_stream ) const +{ + if (!output_stream.good()) return FALSE; + + // header and version + output_stream << "LLWearable version " << mDefinitionVersion << "\n"; + // name + output_stream << mName << "\n"; + // description + output_stream << mDescription << "\n"; + + // permissions + if( !mPermissions.exportStream( output_stream ) ) + { + return FALSE; + } + + // sale info + if( !mSaleInfo.exportStream( output_stream ) ) + { + return FALSE; + } + + // wearable type + output_stream << "type " << (S32) getType() << "\n"; + + // parameters + output_stream << "parameters " << mVisualParamIndexMap.size() << "\n"; + + for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); + iter != mVisualParamIndexMap.end(); + ++iter) + { + S32 param_id = iter->first; + const LLVisualParam* param = iter->second; + F32 param_weight = param->getWeight(); + output_stream << param_id << " " << terse_F32_to_string( param_weight ) << "\n"; + } + + // texture entries + output_stream << "textures " << mTEMap.size() << "\n"; + + for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter) + { + S32 te = iter->first; + const LLUUID& image_id = iter->second->getID(); + output_stream << te << " " << image_id << "\n"; + } + return TRUE; +} + +void LLWearable::createVisualParams(LLAvatarAppearance *avatarp) +{ + for (LLViewerVisualParam* param = (LLViewerVisualParam*) avatarp->getFirstVisualParam(); + param; + param = (LLViewerVisualParam*) avatarp->getNextVisualParam()) + { + if (param->getWearableType() == mType) + { + LLVisualParam *clone_param = param->cloneParam(this); + clone_param->setParamLocation(LOC_UNKNOWN); + clone_param->setParamLocation(LOC_WEARABLE); + addVisualParam(clone_param); + } + } + + // resync driver parameters to point to the newly cloned driven parameters + for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin(); + param_iter != mVisualParamIndexMap.end(); + ++param_iter) + { + LLVisualParam* param = param_iter->second; + LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam; + // need this line to disambiguate between versions of LLCharacter::getVisualParam() + LLVisualParam*(LLAvatarAppearance::*param_function)(S32)const = &LLAvatarAppearance::getVisualParam; + param->resetDrivenParams(); + if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false)) + { + if( !param->linkDrivenParams(boost::bind(param_function,avatarp,_1 ), true)) + { + llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl; + continue; + } + } + } +} + +void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp) +{ + LLTexLayerSet *layer_set = NULL; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te); + if (texture_dict->mIsUsedByBakedTexture) + { + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + + layer_set = avatarp->getAvatarLayerSet(baked_index); + } + + if (layer_set) + { + layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this); + } + else + { + llerrs << "could not find layerset for LTO in wearable!" << llendl; + } +} + +LLWearable::EImportResult LLWearable::importFile(LLFILE* fp, LLAvatarAppearance* avatarp ) +{ + llifstream ifs(fp); + return importStream(ifs, avatarp); +} + +// virtual +LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp ) +{ + // *NOTE: changing the type or size of this buffer will require + // changes in the fscanf() code below. + // We are using a local max buffer size here to avoid issues + // if MAX_STRING size changes. + const U32 PARSE_BUFFER_SIZE = 2048; + char buffer[2048]; /* Flawfinder: ignore */ + char uuid_buffer[37]; /* Flawfinder: ignore */ + + // This data is being generated on the viewer. + // Impose some sane limits on parameter and texture counts. + const S32 MAX_WEARABLE_ASSET_TEXTURES = 100; + const S32 MAX_WEARABLE_ASSET_PARAMETERS = 1000; + + if(!avatarp) + { + return LLWearable::FAILURE; + } + + // read header and version + if (!input_stream.good()) + { + llwarns << "Failed to read wearable asset input stream." << llendl; + return LLWearable::FAILURE; + } + input_stream.getline(buffer, PARSE_BUFFER_SIZE); + if ( 1 != sscanf( /* Flawfinder: ignore */ + buffer, + "LLWearable version %d\n", + &mDefinitionVersion ) ) + { + return LLWearable::BAD_HEADER; + } + + // Hack to allow wearables with definition version 24 to still load. + // This should only affect lindens and NDA'd testers who have saved wearables in 2.0 + // the extra check for version == 24 can be removed before release, once internal testers + // have loaded these wearables again. See hack pt 2 at bottom of function to ensure that + // these wearables get re-saved with version definition 22. + if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 ) + { + llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl; + return LLWearable::FAILURE; + } + + // name + if (!input_stream.good()) + { + llwarns << "Bad Wearable asset: early end of input stream " + << "while reading name" << llendl; + return LLWearable::FAILURE; + } + input_stream.getline(buffer, PARSE_BUFFER_SIZE); + mName = buffer; + + // description + if (!input_stream.good()) + { + llwarns << "Bad Wearable asset: early end of input stream " + << "while reading description" << llendl; + return LLWearable::FAILURE; + } + input_stream.getline(buffer, PARSE_BUFFER_SIZE); + mDescription = buffer; + + // permissions + if (!input_stream.good()) + { + llwarns << "Bad Wearable asset: early end of input stream " + << "while reading permissions" << llendl; + return LLWearable::FAILURE; + } + input_stream.getline(buffer, PARSE_BUFFER_SIZE); + S32 perm_version = -1; + if ( 1 != sscanf( buffer, " permissions %d\n", &perm_version ) || + perm_version != 0 ) + { + llwarns << "Bad Wearable asset: missing valid permissions" << llendl; + return LLWearable::FAILURE; + } + if( !mPermissions.importStream( input_stream ) ) + { + return LLWearable::FAILURE; + } + + // sale info + if (!input_stream.good()) + { + llwarns << "Bad Wearable asset: early end of input stream " + << "while reading sale info" << llendl; + return LLWearable::FAILURE; + } + input_stream.getline(buffer, PARSE_BUFFER_SIZE); + S32 sale_info_version = -1; + if ( 1 != sscanf( buffer, " sale_info %d\n", &sale_info_version ) || + sale_info_version != 0 ) + { + llwarns << "Bad Wearable asset: missing valid sale_info" << llendl; + return LLWearable::FAILURE; + } + // Sale info used to contain next owner perm. It is now in the + // permissions. Thus, we read that out, and fix legacy + // objects. It's possible this op would fail, but it should pick + // up the vast majority of the tasks. + BOOL has_perm_mask = FALSE; + U32 perm_mask = 0; + if( !mSaleInfo.importStream(input_stream, has_perm_mask, perm_mask) ) + { + return LLWearable::FAILURE; + } + if(has_perm_mask) + { + // fair use fix. + if(!(perm_mask & PERM_COPY)) + { + perm_mask |= PERM_TRANSFER; + } + mPermissions.setMaskNext(perm_mask); + } + + // wearable type + if (!input_stream.good()) + { + llwarns << "Bad Wearable asset: early end of input stream " + << "while reading type" << llendl; + return LLWearable::FAILURE; + } + input_stream.getline(buffer, PARSE_BUFFER_SIZE); + S32 type = -1; + if ( 1 != sscanf( buffer, "type %d\n", &type ) ) + { + llwarns << "Bad Wearable asset: bad type" << llendl; + return LLWearable::FAILURE; + } + if( 0 <= type && type < LLWearableType::WT_COUNT ) + { + setType((LLWearableType::EType)type, avatarp); + } + else + { + mType = LLWearableType::WT_COUNT; + llwarns << "Bad Wearable asset: bad type #" << type << llendl; + return LLWearable::FAILURE; + } + + // parameters header + if (!input_stream.good()) + { + llwarns << "Bad Wearable asset: early end of input stream " + << "while reading parameters header" << llendl; + return LLWearable::FAILURE; + } + input_stream.getline(buffer, PARSE_BUFFER_SIZE); + S32 num_parameters = -1; + if ( 1 != sscanf( buffer, "parameters %d\n", &num_parameters ) ) + { + llwarns << "Bad Wearable asset: missing parameters block" << llendl; + return LLWearable::FAILURE; + } + if ( num_parameters > MAX_WEARABLE_ASSET_PARAMETERS ) + { + llwarns << "Bad Wearable asset: too many parameters, " + << num_parameters << llendl; + return LLWearable::FAILURE; + } + if( num_parameters != mVisualParamIndexMap.size() ) + { + llwarns << "Wearable parameter mismatch. Reading in " + << num_parameters << " from file, but created " + << mVisualParamIndexMap.size() + << " from avatar parameters. type: " + << getType() << llendl; + } + + // parameters + S32 i; + for( i = 0; i < num_parameters; i++ ) + { + if (!input_stream.good()) + { + llwarns << "Bad Wearable asset: early end of input stream " + << "while reading parameter #" << i << llendl; + return LLWearable::FAILURE; + } + input_stream.getline(buffer, PARSE_BUFFER_SIZE); + S32 param_id = 0; + F32 param_weight = 0.f; + if ( 2 != sscanf( buffer, "%d %f\n", ¶m_id, ¶m_weight ) ) + { + llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl; + return LLWearable::FAILURE; + } + mSavedVisualParamMap[param_id] = param_weight; + } + + // textures header + if (!input_stream.good()) + { + llwarns << "Bad Wearable asset: early end of input stream " + << "while reading textures header" << i << llendl; + return LLWearable::FAILURE; + } + input_stream.getline(buffer, PARSE_BUFFER_SIZE); + S32 num_textures = -1; + if ( 1 != sscanf( buffer, "textures %d\n", &num_textures) ) + { + llwarns << "Bad Wearable asset: missing textures block" << llendl; + return LLWearable::FAILURE; + } + if ( num_textures > MAX_WEARABLE_ASSET_TEXTURES ) + { + llwarns << "Bad Wearable asset: too many textures, " + << num_textures << llendl; + return LLWearable::FAILURE; + } + + // textures + for( i = 0; i < num_textures; i++ ) + { + if (!input_stream.good()) + { + llwarns << "Bad Wearable asset: early end of input stream " + << "while reading textures #" << i << llendl; + return LLWearable::FAILURE; + } + input_stream.getline(buffer, PARSE_BUFFER_SIZE); + S32 te = 0; + if ( 2 != sscanf( /* Flawfinder: ignore */ + buffer, + "%d %36s\n", + &te, uuid_buffer) ) + { + llwarns << "Bad Wearable asset: bad texture, #" << i << llendl; + return LLWearable::FAILURE; + } + + if( !LLUUID::validate( uuid_buffer ) ) + { + llwarns << "Bad Wearable asset: bad texture uuid: " + << uuid_buffer << llendl; + return LLWearable::FAILURE; + } + LLUUID id = LLUUID(uuid_buffer); + LLGLTexture* image = gTextureManagerBridgep->getFetchedTexture( id ); + if( mTEMap.find(te) != mTEMap.end() ) + { + delete mTEMap[te]; + } + if( mSavedTEMap.find(te) != mSavedTEMap.end() ) + { + delete mSavedTEMap[te]; + } + + LLUUID textureid(uuid_buffer); + mTEMap[te] = new LLLocalTextureObject(image, textureid); + mSavedTEMap[te] = new LLLocalTextureObject(image, textureid); + createLayers(te, avatarp); + } + + // copy all saved param values to working params + revertValues(); + + return LLWearable::SUCCESS; +} + +void LLWearable::setType(LLWearableType::EType type, LLAvatarAppearance *avatarp) +{ + mType = type; + createVisualParams(avatarp); +} + + +LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) +{ + te_map_t::iterator iter = mTEMap.find(index); + if( iter != mTEMap.end() ) + { + LLLocalTextureObject* lto = iter->second; + return lto; + } + return NULL; +} + +const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const +{ + te_map_t::const_iterator iter = mTEMap.find(index); + if( iter != mTEMap.end() ) + { + const LLLocalTextureObject* lto = iter->second; + return lto; + } + return NULL; +} + +std::vector LLWearable::getLocalTextureListSeq() +{ + std::vector result; + + for(te_map_t::const_iterator iter = mTEMap.begin(); + iter != mTEMap.end(); iter++) + { + LLLocalTextureObject* lto = iter->second; + result.push_back(lto); + } + + return result; +} + +void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject <o) +{ + if( mTEMap.find(index) != mTEMap.end() ) + { + mTEMap.erase(index); + } + mTEMap[index] = new LLLocalTextureObject(lto); +} + +void LLWearable::revertValues() +{ + // FIXME DRANO - this triggers changes to driven params on avatar, potentially clobbering baked appearance. + + //update saved settings so wearable is no longer dirty + // non-driver params first + for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) + { + S32 id = iter->first; + F32 value = iter->second; + LLVisualParam *param = getVisualParam(id); + if(param && !dynamic_cast(param) ) + { + setVisualParamWeight(id, value, TRUE); + } + } + + //then driver params + for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) + { + S32 id = iter->first; + F32 value = iter->second; + LLVisualParam *param = getVisualParam(id); + if(param && dynamic_cast(param) ) + { + setVisualParamWeight(id, value, TRUE); + } + } + + // make sure that saved values are sane + for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) + { + S32 id = iter->first; + LLVisualParam *param = getVisualParam(id); + if( param ) + { + mSavedVisualParamMap[id] = param->getWeight(); + } + } + + syncImages(mSavedTEMap, mTEMap); +} + +void LLWearable::saveValues() +{ + //update saved settings so wearable is no longer dirty + mSavedVisualParamMap.clear(); + for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter) + { + S32 id = iter->first; + LLVisualParam *wearable_param = iter->second; + F32 value = wearable_param->getWeight(); + mSavedVisualParamMap[id] = value; + } + + // Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed) + syncImages(mTEMap, mSavedTEMap); +} + +void LLWearable::syncImages(te_map_t &src, te_map_t &dst) +{ + // Deep copy of src (copies only those tes that are current, filling in defaults where needed) + for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) + { + if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType) + { + te_map_t::const_iterator iter = src.find(te); + LLUUID image_id; + LLGLTexture *image = NULL; + LLLocalTextureObject *lto = NULL; + if(iter != src.end()) + { + // there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map. + lto = iter->second; + image = lto->getImage(); + image_id = lto->getID(); + } + else + { + // there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map. + image_id = getDefaultTextureImageID((ETextureIndex) te); + image = gTextureManagerBridgep->getFetchedTexture( image_id ); + } + + if( dst.find(te) != dst.end() ) + { + // there's already an entry in the destination map for the texture. Just update its values. + dst[te]->setImage(image); + dst[te]->setID(image_id); + } + else + { + // no entry found in the destination map, we need to create a new Local Texture Object + dst[te] = new LLLocalTextureObject(image, image_id); + } + + if( lto ) + { + // If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map. + dst[te]->setBakedReady(lto->getBakedReady()); + dst[te]->setDiscard(lto->getDiscard()); + } + } + } +} + +void LLWearable::destroyTextures() +{ + for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter ) + { + LLLocalTextureObject *lto = iter->second; + delete lto; + } + mTEMap.clear(); + for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter ) + { + LLLocalTextureObject *lto = iter->second; + delete lto; + } + mSavedTEMap.clear(); +} + +void LLWearable::addVisualParam(LLVisualParam *param) +{ + if( mVisualParamIndexMap[param->getID()] ) + { + delete mVisualParamIndexMap[param->getID()]; + } + param->setIsDummy(FALSE); + param->setParamLocation(LOC_WEARABLE); + mVisualParamIndexMap[param->getID()] = param; + mSavedVisualParamMap[param->getID()] = param->getDefaultWeight(); +} + + +void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake) +{ + if( is_in_map(mVisualParamIndexMap, param_index ) ) + { + LLVisualParam *wearable_param = mVisualParamIndexMap[param_index]; + wearable_param->setWeight(value, upload_bake); + } + else + { + llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl; + } +} + +F32 LLWearable::getVisualParamWeight(S32 param_index) const +{ + if( is_in_map(mVisualParamIndexMap, param_index ) ) + { + const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second; + return wearable_param->getWeight(); + } + else + { + llwarns << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl; + } + return (F32)-1.0; +} + +LLVisualParam* LLWearable::getVisualParam(S32 index) const +{ + visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index); + return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second; +} + + +void LLWearable::getVisualParams(visual_param_vec_t &list) +{ + visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin(); + visual_param_index_map_t::iterator end = mVisualParamIndexMap.end(); + + // add all visual params to the passed-in vector + for( ; iter != end; ++iter ) + { + list.push_back(iter->second); + } +} + +void LLWearable::animateParams(F32 delta, BOOL upload_bake) +{ + for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin(); + iter != mVisualParamIndexMap.end(); + ++iter) + { + LLVisualParam *param = (LLVisualParam*) iter->second; + param->animate(delta, upload_bake); + } +} + +LLColor4 LLWearable::getClothesColor(S32 te) const +{ + LLColor4 color; + U32 param_name[3]; + if( LLAvatarAppearance::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) ) + { + for( U8 index = 0; index < 3; index++ ) + { + color.mV[index] = getVisualParamWeight(param_name[index]); + } + } + return color; +} + +void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake ) +{ + U32 param_name[3]; + if( LLAvatarAppearance::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) ) + { + for( U8 index = 0; index < 3; index++ ) + { + setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake); + } + } +} + +void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp) +{ + if (!avatarp) return; + + // Pull params + for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() ) + { + // cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the + // avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way. + if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) ) + { + S32 param_id = param->getID(); + F32 weight = getVisualParamWeight(param_id); + + avatarp->setVisualParamWeight( param_id, weight, FALSE ); + } + } +} + + +std::string terse_F32_to_string(F32 f) +{ + std::string r = llformat("%.2f", f); + S32 len = r.length(); + + // "1.20" -> "1.2" + // "24.00" -> "24." + while (len > 0 && ('0' == r[len - 1])) + { + r.erase(len-1, 1); + len--; + } + if ('.' == r[len - 1]) + { + // "24." -> "24" + r.erase(len-1, 1); + } + else if (('-' == r[0]) && ('0' == r[1])) + { + // "-0.59" -> "-.59" + r.erase(1, 1); + } + else if ('0' == r[0]) + { + // "0.59" -> ".59" + r.erase(0, 1); + } + return r; +} \ No newline at end of file diff --git a/indra/newview/llwearable.h b/indra/llappearance/llwearable.h similarity index 68% rename from indra/newview/llwearable.h rename to indra/llappearance/llwearable.h index af9119d6d..8faf383aa 100644 --- a/indra/newview/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -27,48 +27,35 @@ #ifndef LL_LLWEARABLE_H #define LL_LLWEARABLE_H -#include "lluuid.h" -#include "llstring.h" +#include "llavatarappearancedefines.h" +#include "llextendedstatus.h" #include "llpermissions.h" #include "llsaleinfo.h" -#include "llassetstorage.h" #include "llwearabletype.h" -#include "llfile.h" #include "lllocaltextureobject.h" -class LLViewerInventoryItem; +class LLMD5; class LLVisualParam; class LLTexGlobalColorInfo; class LLTexGlobalColor; +class LLAvatarAppearance; +// Abstract class. class LLWearable { - friend class LLWearableList; - //-------------------------------------------------------------------- // Constructors and destructors //-------------------------------------------------------------------- -private: - // Private constructors used by LLWearableList - LLWearable(const LLTransactionID& transactionID); - LLWearable(const LLAssetID& assetID); public: + LLWearable(); virtual ~LLWearable(); //-------------------------------------------------------------------- // Accessors //-------------------------------------------------------------------- public: - const LLUUID& getItemID() const; - const LLAssetID& getAssetID() const { return mAssetID; } - const LLTransactionID& getTransactionID() const { return mTransactionID; } - - BOOL FileExportParams(FILE* file); - BOOL FileExportTextures(FILE* file); - - LLWearableType::EType getType() const { return mType; } - void setType( LLWearableType::EType type ); + void setType(LLWearableType::EType type, LLAvatarAppearance *avatarp); const std::string& getName() const { return mName; } void setName( const std::string& name ) { mName = name; } const std::string& getDescription() const { return mDescription; } @@ -82,39 +69,36 @@ public: LLAssetType::EType getAssetType() const; S32 getDefinitionVersion() const { return mDefinitionVersion; } void setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; } + static S32 getCurrentDefinitionVersion() { return LLWearable::sCurrentDefinitionVersion; } public: typedef std::vector visual_param_vec_t; - BOOL isDirty() const; - BOOL isOldVersion() const; - - void writeToAvatar(); - void removeFromAvatar( BOOL upload_bake ) { LLWearable::removeFromAvatar( mType, upload_bake ); } - static void removeFromAvatar( LLWearableType::EType type, BOOL upload_bake ); + virtual void writeToAvatar(LLAvatarAppearance* avatarp); + BOOL FileExportParams(FILE* file) const; + BOOL FileExportTextures(FILE* file) const; + + enum EImportResult + { + FAILURE = 0, + SUCCESS, + BAD_HEADER + }; BOOL exportFile(LLFILE* file) const; - BOOL importFile(LLFILE* file); - - void setParamsToDefaults(); - void setTexturesToDefaults(); - - void saveNewAsset() const; - static void onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status ); - - void copyDataFrom(const LLWearable* src); + EImportResult importFile(LLFILE* file, LLAvatarAppearance* avatarp ); + virtual BOOL exportStream( std::ostream& output_stream ) const; + virtual EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp ); static void setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; } - - friend std::ostream& operator<<(std::ostream &s, const LLWearable &w); - void setItemID(const LLUUID& item_id); + virtual const LLUUID getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const = 0; LLLocalTextureObject* getLocalTextureObject(S32 index); const LLLocalTextureObject* getLocalTextureObject(S32 index) const; + std::vector getLocalTextureListSeq(); void setLocalTextureObject(S32 index, LLLocalTextureObject <o); void addVisualParam(LLVisualParam *param); - void setVisualParams(); void setVisualParamWeight(S32 index, F32 value, BOOL upload_bake); F32 getVisualParamWeight(S32 index) const; LLVisualParam* getVisualParam(S32 index) const; @@ -124,27 +108,21 @@ public: LLColor4 getClothesColor(S32 te) const; void setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake ); - void revertValues(); - void saveValues(); - void pullCrossWearableValues(); + virtual void revertValues(); + virtual void saveValues(); - BOOL isOnTop() const; + // Something happened that requires the wearable to be updated (e.g. worn/unworn). + virtual void setUpdated() const = 0; - // Something happened that requires the wearable's label to be updated (e.g. worn/unworn). - void setLabelUpdated() const; + // Update the baked texture hash. + virtual void addToBakedTextureHash(LLMD5& hash) const = 0; - // the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem, - // not the wearable asset itself. - void refreshName(); - -private: +protected: typedef std::map te_map_t; - typedef std::map visual_param_index_map_t; - - void createLayers(S32 te); - void createVisualParams(); void syncImages(te_map_t &src, te_map_t &dst); - void destroyTextures(); + void destroyTextures(); + void createVisualParams(LLAvatarAppearance *avatarp); + void createLayers(S32 te, LLAvatarAppearance *avatarp); static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml. S32 mDefinitionVersion; // Depends on the state of the avatar_lad.xml when this asset was created. @@ -152,18 +130,16 @@ private: std::string mDescription; LLPermissions mPermissions; LLSaleInfo mSaleInfo; - LLAssetID mAssetID; - LLTransactionID mTransactionID; LLWearableType::EType mType; typedef std::map param_map_t; param_map_t mSavedVisualParamMap; // last saved version of visual params + typedef std::map visual_param_index_map_t; visual_param_index_map_t mVisualParamIndexMap; te_map_t mTEMap; // maps TE to LocalTextureObject te_map_t mSavedTEMap; // last saved version of TEMap - LLUUID mItemID; // ID of the inventory item in the agent's inventory }; #endif // LL_LLWEARABLE_H diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp new file mode 100644 index 000000000..f3ddfcb2f --- /dev/null +++ b/indra/llappearance/llwearabledata.cpp @@ -0,0 +1,363 @@ +/** + * @file llwearabledata.cpp + * @brief LLWearableData class implementation + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llwearabledata.h" + +#include "llavatarappearance.h" +#include "llavatarappearancedefines.h" +#include "lldriverparam.h" +#include "llmd5.h" + +LLWearableData::LLWearableData() : + mAvatarAppearance(NULL) +{ +} + +// virtual +LLWearableData::~LLWearableData() +{ +} + +using namespace LLAvatarAppearanceDefines; + +LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) +{ + //llassert_always(index == 0); + wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); + if (wearable_iter == mWearableDatas.end()) + { + return NULL; + } + wearableentry_vec_t& wearable_vec = wearable_iter->second; + if (index>=wearable_vec.size()) + { + return NULL; + } + else + { + return wearable_vec[index]; + } +} + +void LLWearableData::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable) +{ + //llassert_always(index == 0); + LLWearable *old_wearable = getWearable(type,index); + if (!old_wearable) + { + pushWearable(type,wearable); + return; + } + + wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); + if (wearable_iter == mWearableDatas.end()) + { + llwarns << "invalid type, type " << type << " index " << index << llendl; + return; + } + wearableentry_vec_t& wearable_vec = wearable_iter->second; + if (index>=wearable_vec.size()) + { + llwarns << "invalid index, type " << type << " index " << index << llendl; + } + else + { + wearable_vec[index] = wearable; + old_wearable->setUpdated(); + const BOOL removed = FALSE; + wearableUpdated(wearable, removed); + } +} + +U32 LLWearableData::pushWearable(const LLWearableType::EType type, + LLWearable *wearable) +{ + if (wearable == NULL) + { + // no null wearables please! + llwarns << "Null wearable sent for type " << type << llendl; + return MAX_CLOTHING_PER_TYPE; + } +// if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) +// { +// mWearableDatas[type].push_back(wearable); +// wearableUpdated(wearable); +// checkWearableAgainstInventory(wearable); +// return mWearableDatas[type].size()-1; +// } +// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g + if ( (type < LLWearableType::WT_COUNT) && (mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) ) + { + // Don't add the same wearable twice + U32 idxWearable = getWearableIndex(wearable); + //RLV_ASSERT(MAX_CLOTHING_PER_TYPE == idxWearable); // pushWearable() on an already added wearable is a bug *somewhere* + if (MAX_CLOTHING_PER_TYPE == idxWearable) + { + mWearableDatas[type].push_back(wearable); + idxWearable = mWearableDatas[type].size() - 1; + } + const BOOL removed = FALSE; + wearableUpdated(wearable, removed); + return idxWearable; +// [/RLVa:KB] + } + return MAX_CLOTHING_PER_TYPE; +} + +// virtual +void LLWearableData::wearableUpdated(LLWearable *wearable, BOOL removed) +{ + wearable->setUpdated(); + // FIXME DRANO avoid updating params via wearables when rendering server-baked appearance. +#if 0 + if (mAvatarAppearance->isUsingServerBakes() && !mAvatarAppearance->isUsingLocalAppearance()) + { + return; + } +#endif + if (!removed) + { + pullCrossWearableValues(wearable->getType()); + } +} + +void LLWearableData::popWearable(LLWearable *wearable) +{ + if (wearable == NULL) + { + // nothing to do here. move along. + return; + } + + U32 index = getWearableIndex(wearable); + const LLWearableType::EType type = wearable->getType(); + + if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type)) + { + popWearable(type, index); + } +} + +void LLWearableData::popWearable(const LLWearableType::EType type, U32 index) +{ + //llassert_always(index == 0); + LLWearable *wearable = getWearable(type, index); + if (wearable) + { + mWearableDatas[type].erase(mWearableDatas[type].begin() + index); + const BOOL removed = TRUE; + wearableUpdated(wearable, removed); + } +} + +bool LLWearableData::swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b) +{ + wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); + if (wearable_iter == mWearableDatas.end()) + { + return false; + } + + wearableentry_vec_t& wearable_vec = wearable_iter->second; + if (0 > index_a || index_a >= wearable_vec.size()) return false; + if (0 > index_b || index_b >= wearable_vec.size()) return false; + + LLWearable* wearable = wearable_vec[index_a]; + wearable_vec[index_a] = wearable_vec[index_b]; + wearable_vec[index_b] = wearable; + return true; +} + +void LLWearableData::pullCrossWearableValues(const LLWearableType::EType type) +{ + llassert(mAvatarAppearance); + // scan through all of the avatar's visual parameters + for (LLViewerVisualParam* param = (LLViewerVisualParam*) mAvatarAppearance->getFirstVisualParam(); + param; + param = (LLViewerVisualParam*) mAvatarAppearance->getNextVisualParam()) + { + if( param ) + { + LLDriverParam *driver_param = dynamic_cast(param); + if(driver_param) + { + // parameter is a driver parameter, have it update its cross-driven params + driver_param->updateCrossDrivenParams(type); + } + } + } +} + + +U32 LLWearableData::getWearableIndex(const LLWearable *wearable) const +{ + if (wearable == NULL) + { + return MAX_CLOTHING_PER_TYPE; + } + + const LLWearableType::EType type = wearable->getType(); + wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); + if (wearable_iter == mWearableDatas.end()) + { + llwarns << "tried to get wearable index with an invalid type!" << llendl; + return MAX_CLOTHING_PER_TYPE; + } + const wearableentry_vec_t& wearable_vec = wearable_iter->second; + for(U32 index = 0; index < wearable_vec.size(); index++) + { + if (wearable_vec[index] == wearable) + { + return index; + } + } + + return MAX_CLOTHING_PER_TYPE; +} + +BOOL LLWearableData::isOnTop(LLWearable* wearable) const +{ + if (!wearable) return FALSE; + const LLWearableType::EType type = wearable->getType(); + return ( getTopWearable(type) == wearable ); +} + +const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) const +{ + //llassert_always(index == 0); + wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); + if (wearable_iter == mWearableDatas.end()) + { + return NULL; + } + const wearableentry_vec_t& wearable_vec = wearable_iter->second; + if (index>=wearable_vec.size()) + { + return NULL; + } + else + { + return wearable_vec[index]; + } +} + +LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) +{ + U32 count = getWearableCount(type); + if ( count == 0) + { + return NULL; + } + + return getWearable(type, count-1); +} + +const LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) const +{ + U32 count = getWearableCount(type); + if ( count == 0) + { + return NULL; + } + + return getWearable(type, count-1); +} + +LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) +{ + if (getWearableCount(type) == 0) + { + return NULL; + } + + return getWearable(type, 0); +} + +const LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) const +{ + if (getWearableCount(type) == 0) + { + return NULL; + } + + return getWearable(type, 0); +} + +U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const +{ + wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); + if (wearable_iter == mWearableDatas.end()) + { + return 0; + } + const wearableentry_vec_t& wearable_vec = wearable_iter->second; + return wearable_vec.size(); +} + +U32 LLWearableData::getWearableCount(const U32 tex_index) const +{ + const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index); + return getWearableCount(wearable_type); +} + +LLUUID LLWearableData::computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index, + BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache +{ + LLUUID hash_id; + bool hash_computed = false; + LLMD5 hash; + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index); + + for (U8 i=0; i < baked_dict->mWearables.size(); i++) + { + const LLWearableType::EType baked_type = baked_dict->mWearables[i]; + const U32 num_wearables = getWearableCount(baked_type); + for (U32 index = 0; index < num_wearables; ++index) + { + const LLWearable* wearable = getWearable(baked_type,index); + if (wearable) + { + wearable->addToBakedTextureHash(hash); + hash_computed = true; + } + } + } + if (hash_computed) + { + hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES); + + if (!generate_valid_hash) + { + invalidateBakedTextureHash(hash); + } + hash.finalize(); + hash.raw_digest(hash_id.mData); + } + + return hash_id; +} \ No newline at end of file diff --git a/indra/llappearance/llwearabledata.h b/indra/llappearance/llwearabledata.h new file mode 100644 index 000000000..c3f80a72d --- /dev/null +++ b/indra/llappearance/llwearabledata.h @@ -0,0 +1,106 @@ +/** + * @file llwearabledata.h + * @brief LLWearableData class header file + * + * $LicenseInfo:firstyear=20012license=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_WEARABLEDATA_H +#define LL_WEARABLEDATA_H + +#include "llavatarappearancedefines.h" +#include "llwearable.h" +#include "llerror.h" + +class LLAvatarAppearance; + +class LLWearableData +{ + // *TODO: Figure out why this is causing compile error. + //LOG_CLASS(LLWearableData); + + //-------------------------------------------------------------------- + // Constructors / destructors / Initializers + //-------------------------------------------------------------------- +public: + LLWearableData(); + virtual ~LLWearableData(); + + void setAvatarAppearance(LLAvatarAppearance* appearance) { mAvatarAppearance = appearance; } + +protected: + //-------------------------------------------------------------------- + // Accessors + //-------------------------------------------------------------------- +public: + LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/); + const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const; + LLWearable* getTopWearable(const LLWearableType::EType type); + const LLWearable* getTopWearable(const LLWearableType::EType type) const; + LLWearable* getBottomWearable(const LLWearableType::EType type); + const LLWearable* getBottomWearable(const LLWearableType::EType type) const; + U32 getWearableCount(const LLWearableType::EType type) const; + U32 getWearableCount(const U32 tex_index) const; + U32 getWearableIndex(const LLWearable *wearable) const; + + BOOL isOnTop(LLWearable* wearable) const; + + static const U32 MAX_CLOTHING_PER_TYPE = 5; + + //-------------------------------------------------------------------- + // Setters + //-------------------------------------------------------------------- +protected: + // Low-level data structure setter - public access is via setWearableItem, etc. + void setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable); + U32 pushWearable(const LLWearableType::EType type, LLWearable *wearable); + virtual void wearableUpdated(LLWearable *wearable, BOOL removed) = 0; + void popWearable(LLWearable *wearable); + void popWearable(const LLWearableType::EType type, U32 index); + bool swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b); + +private: + void pullCrossWearableValues(const LLWearableType::EType type); + + //-------------------------------------------------------------------- + // Server Communication + //-------------------------------------------------------------------- +public: + LLUUID computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index, + BOOL generate_valid_hash = TRUE); +protected: + virtual void invalidateBakedTextureHash(LLMD5& hash) const = 0; + + //-------------------------------------------------------------------- + // Member variables + //-------------------------------------------------------------------- +protected: + LLAvatarAppearance* mAvatarAppearance; + typedef std::vector wearableentry_vec_t; // all wearables of a certain type (EG all shirts) + typedef std::map wearableentry_map_t; // wearable "categories" arranged by wearable type + wearableentry_map_t mWearableDatas; + +}; + + + +#endif // LL_WEARABLEDATA_H \ No newline at end of file diff --git a/indra/newview/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp similarity index 83% rename from indra/newview/llwearabletype.cpp rename to indra/llappearance/llwearabletype.cpp index 66ac79a12..bccc4ed18 100644 --- a/indra/newview/llwearabletype.cpp +++ b/indra/llappearance/llwearabletype.cpp @@ -24,24 +24,36 @@ * $/LicenseInfo$ */ -#include "llviewerprecompiledheaders.h" +#include "linden_common.h" #include "llwearabletype.h" -#include "llinventoryfunctions.h" -#include "lltrans.h" +#include "llinventorytype.h" + +static LLTranslationBridge* sTrans = NULL; + +// static +void LLWearableType::initClass(LLTranslationBridge* trans) +{ + sTrans = trans; +} + +void LLWearableType::cleanupClass() +{ + delete sTrans; +} struct WearableEntry : public LLDictionaryEntry { WearableEntry(const std::string &name, const std::string& default_new_name, LLAssetType::EType assetType, - LLInventoryIcon::EIconName iconName, + LLInventoryType::EIconName iconName, BOOL disable_camera_switch = FALSE, BOOL allow_multiwear = TRUE) : LLDictionaryEntry(name), mAssetType(assetType), mDefaultNewName(default_new_name), //*TODO:Translate - mLabel(/*LLTrans::getString*/(name)), + mLabel(/*sTrans->getString*/(name)), mIconName(iconName), mDisableCameraSwitch(disable_camera_switch), mAllowMultiwear(allow_multiwear) @@ -51,7 +63,7 @@ struct WearableEntry : public LLDictionaryEntry const LLAssetType::EType mAssetType; const std::string mLabel; const std::string mDefaultNewName; //keep mLabel for backward compatibility - LLInventoryIcon::EIconName mIconName; + LLInventoryType::EIconName mIconName; BOOL mDisableCameraSwitch; BOOL mAllowMultiwear; }; @@ -71,26 +83,26 @@ protected: LLWearableDictionary::LLWearableDictionary() { - addEntry(LLWearableType::WT_SHAPE, new WearableEntry("shape", "New Shape", LLAssetType::AT_BODYPART, LLInventoryIcon::ICONNAME_BODYPART_SHAPE, FALSE, FALSE)); - addEntry(LLWearableType::WT_SKIN, new WearableEntry("skin", "New Skin", LLAssetType::AT_BODYPART, LLInventoryIcon::ICONNAME_BODYPART_SKIN, FALSE, FALSE)); - addEntry(LLWearableType::WT_HAIR, new WearableEntry("hair", "New Hair", LLAssetType::AT_BODYPART, LLInventoryIcon::ICONNAME_BODYPART_HAIR, FALSE, FALSE)); - addEntry(LLWearableType::WT_EYES, new WearableEntry("eyes", "New Eyes", LLAssetType::AT_BODYPART, LLInventoryIcon::ICONNAME_BODYPART_EYES, FALSE, FALSE)); - addEntry(LLWearableType::WT_SHIRT, new WearableEntry("shirt", "New Shirt", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE)); - addEntry(LLWearableType::WT_PANTS, new WearableEntry("pants", "New Pants", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_PANTS, FALSE, TRUE)); - addEntry(LLWearableType::WT_SHOES, new WearableEntry("shoes", "New Shoes", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_SHOES, FALSE, TRUE)); - addEntry(LLWearableType::WT_SOCKS, new WearableEntry("socks", "New Socks", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE)); - addEntry(LLWearableType::WT_JACKET, new WearableEntry("jacket", "New Jacket", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_JACKET, FALSE, TRUE)); - addEntry(LLWearableType::WT_GLOVES, new WearableEntry("gloves", "New Gloves", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE)); - addEntry(LLWearableType::WT_UNDERSHIRT, new WearableEntry("undershirt", "New Undershirt", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE)); - addEntry(LLWearableType::WT_UNDERPANTS, new WearableEntry("underpants", "New Underpants", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE)); - addEntry(LLWearableType::WT_SKIRT, new WearableEntry("skirt", "New Skirt", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE)); - addEntry(LLWearableType::WT_ALPHA, new WearableEntry("alpha", "New Alpha", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE)); - addEntry(LLWearableType::WT_TATTOO, new WearableEntry("tattoo", "New Tattoo", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE)); + addEntry(LLWearableType::WT_SHAPE, new WearableEntry("shape", "New Shape", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_SHAPE, FALSE, FALSE)); + addEntry(LLWearableType::WT_SKIN, new WearableEntry("skin", "New Skin", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_SKIN, FALSE, FALSE)); + addEntry(LLWearableType::WT_HAIR, new WearableEntry("hair", "New Hair", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_HAIR, FALSE, FALSE)); + addEntry(LLWearableType::WT_EYES, new WearableEntry("eyes", "New Eyes", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_EYES, FALSE, FALSE)); + addEntry(LLWearableType::WT_SHIRT, new WearableEntry("shirt", "New Shirt", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE)); + addEntry(LLWearableType::WT_PANTS, new WearableEntry("pants", "New Pants", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PANTS, FALSE, TRUE)); + addEntry(LLWearableType::WT_SHOES, new WearableEntry("shoes", "New Shoes", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_SHOES, FALSE, TRUE)); + addEntry(LLWearableType::WT_SOCKS, new WearableEntry("socks", "New Socks", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE)); + addEntry(LLWearableType::WT_JACKET, new WearableEntry("jacket", "New Jacket", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_JACKET, FALSE, TRUE)); + addEntry(LLWearableType::WT_GLOVES, new WearableEntry("gloves", "New Gloves", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE)); + addEntry(LLWearableType::WT_UNDERSHIRT, new WearableEntry("undershirt", "New Undershirt", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE)); + addEntry(LLWearableType::WT_UNDERPANTS, new WearableEntry("underpants", "New Underpants", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE)); + addEntry(LLWearableType::WT_SKIRT, new WearableEntry("skirt", "New Skirt", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE)); + addEntry(LLWearableType::WT_ALPHA, new WearableEntry("alpha", "New Alpha", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE)); + addEntry(LLWearableType::WT_TATTOO, new WearableEntry("tattoo", "New Tattoo", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE)); - addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE)); + addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE)); - addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE)); - addEntry(LLWearableType::WT_NONE, new WearableEntry("none", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE)); + addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE)); + addEntry(LLWearableType::WT_NONE, new WearableEntry("none", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE)); } // static @@ -138,7 +150,7 @@ LLAssetType::EType LLWearableType::getAssetType(LLWearableType::EType type) } // static -LLInventoryIcon::EIconName LLWearableType::getIconName(LLWearableType::EType type) +LLInventoryType::EIconName LLWearableType::getIconName(LLWearableType::EType type) { const LLWearableDictionary *dict = LLWearableDictionary::getInstance(); const WearableEntry *entry = dict->lookup(type); diff --git a/indra/newview/llwearabletype.h b/indra/llappearance/llwearabletype.h similarity index 84% rename from indra/newview/llwearabletype.h rename to indra/llappearance/llwearabletype.h index d633b4807..8d34f0025 100644 --- a/indra/newview/llwearabletype.h +++ b/indra/llappearance/llwearabletype.h @@ -29,9 +29,17 @@ #include "llassettype.h" #include "lldictionary.h" -#include "llinventoryicon.h" +#include "llinventorytype.h" #include "llsingleton.h" +class LLTranslationBridge +{ +public: + virtual ~LLTranslationBridge(){}; + virtual std::string getString(const std::string &xml_desc) = 0; +}; + + class LLWearableType { public: @@ -59,12 +67,15 @@ public: WT_NONE = -1, }; + static void initClass(LLTranslationBridge* trans); // initializes static members + static void cleanupClass(); // initializes static members + static const std::string& getTypeName(EType type); static const std::string& getTypeDefaultNewName(EType type); static const std::string& getTypeLabel(EType type); static LLAssetType::EType getAssetType(EType type); static EType typeNameToType(const std::string& type_name); - static LLInventoryIcon::EIconName getIconName(EType type); + static LLInventoryType::EIconName getIconName(EType type); static BOOL getDisableCameraSwitch(EType type); static BOOL getAllowMultiwear(EType type); diff --git a/indra/llaudio/llaudiodecodemgr.h b/indra/llaudio/llaudiodecodemgr.h index 040506c55..e42fe8a40 100644 --- a/indra/llaudio/llaudiodecodemgr.h +++ b/indra/llaudio/llaudiodecodemgr.h @@ -1,31 +1,25 @@ /** * @file llaudiodecodemgr.h * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index 7c3f3e315..98587674c 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -3,31 +3,25 @@ * @brief implementation of LLAudioEngine class abstracting the Open * AL audio support * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index 77c7fd6d7..cf44afee7 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -2,31 +2,25 @@ * @file audioengine.h * @brief Definition of LLAudioEngine base class abstracting the audio support * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp index cdd27ec3e..168bb5f60 100644 --- a/indra/llaudio/llaudioengine_fmod.cpp +++ b/indra/llaudio/llaudioengine_fmod.cpp @@ -2,31 +2,25 @@ * @file audioengine_fmod.cpp * @brief Implementation of LLAudioEngine class abstracting the audio support as a FMOD 3D implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/llaudioengine_fmod.h b/indra/llaudio/llaudioengine_fmod.h index 384a20264..4582a5d57 100644 --- a/indra/llaudio/llaudioengine_fmod.h +++ b/indra/llaudio/llaudioengine_fmod.h @@ -3,31 +3,25 @@ * @brief Definition of LLAudioEngine class abstracting the audio * support as a FMOD 3D implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -65,7 +59,7 @@ public: #else typedef S16 MIXBUFFERFORMAT; #endif - + protected: /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to. /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel. diff --git a/indra/llaudio/lllistener.cpp b/indra/llaudio/lllistener.cpp index 846c6bccb..df2366c8c 100644 --- a/indra/llaudio/lllistener.cpp +++ b/indra/llaudio/lllistener.cpp @@ -2,31 +2,25 @@ * @file listener.cpp * @brief Implementation of LISTENER class abstracting the audio support * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/lllistener.h b/indra/llaudio/lllistener.h index e94fbe853..41836bf03 100644 --- a/indra/llaudio/lllistener.h +++ b/indra/llaudio/lllistener.h @@ -2,31 +2,25 @@ * @file listener.h * @brief Description of LISTENER base class abstracting the audio support. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/lllistener_ds3d.h b/indra/llaudio/lllistener_ds3d.h index 1ff9c170c..9150ccd5b 100644 --- a/indra/llaudio/lllistener_ds3d.h +++ b/indra/llaudio/lllistener_ds3d.h @@ -3,31 +3,25 @@ * @brief Description of LISTENER class abstracting the audio support * as a DirectSound 3D implementation (windows only) * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/lllistener_fmod.cpp b/indra/llaudio/lllistener_fmod.cpp index 57ad461b0..0138f4345 100644 --- a/indra/llaudio/lllistener_fmod.cpp +++ b/indra/llaudio/lllistener_fmod.cpp @@ -3,31 +3,25 @@ * @brief implementation of LISTENER class abstracting the audio * support as a FMOD 3D implementation (windows only) * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/lllistener_fmod.h b/indra/llaudio/lllistener_fmod.h index 5a48ec8b6..818da05d5 100644 --- a/indra/llaudio/lllistener_fmod.h +++ b/indra/llaudio/lllistener_fmod.h @@ -3,31 +3,25 @@ * @brief Description of LISTENER class abstracting the audio support * as an FMOD 3D implementation (windows and Linux) * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/lllistener_openal.cpp b/indra/llaudio/lllistener_openal.cpp index a96ebd5db..b3d4b02f0 100644 --- a/indra/llaudio/lllistener_openal.cpp +++ b/indra/llaudio/lllistener_openal.cpp @@ -3,31 +3,25 @@ * @brief implementation of audio engine using OpenAL * support as a OpenAL 3D implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/lllistener_openal.h b/indra/llaudio/lllistener_openal.h index 0dfeea5c9..cb163b11a 100644 --- a/indra/llaudio/lllistener_openal.h +++ b/indra/llaudio/lllistener_openal.h @@ -3,31 +3,25 @@ * @brief Description of LISTENER class abstracting the audio support * as an OpenAL implementation * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/llstreamingaudio.h b/indra/llaudio/llstreamingaudio.h index 3fb9ad4e3..6262ce41c 100644 --- a/indra/llaudio/llstreamingaudio.h +++ b/indra/llaudio/llstreamingaudio.h @@ -3,31 +3,25 @@ * @author Tofu Linden * @brief Definition of LLStreamingAudioInterface base class abstracting the streaming audio interface * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/llstreamingaudio_fmod.cpp b/indra/llaudio/llstreamingaudio_fmod.cpp index 08cc74bf2..4036b8df6 100644 --- a/indra/llaudio/llstreamingaudio_fmod.cpp +++ b/indra/llaudio/llstreamingaudio_fmod.cpp @@ -2,31 +2,25 @@ * @file streamingaudio_fmod.cpp * @brief LLStreamingAudio_FMOD implementation * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -206,6 +200,7 @@ void LLStreamingAudio_FMOD::update() // buffering break; } + } void LLStreamingAudio_FMOD::stop() diff --git a/indra/llaudio/llstreamingaudio_fmod.h b/indra/llaudio/llstreamingaudio_fmod.h index 0478a79ac..4bb65c54d 100644 --- a/indra/llaudio/llstreamingaudio_fmod.h +++ b/indra/llaudio/llstreamingaudio_fmod.h @@ -3,31 +3,25 @@ * @author Tofu Linden * @brief Definition of LLStreamingAudio_FMOD implementation * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp index d06654ace..dd301585d 100644 --- a/indra/llaudio/llvorbisencode.cpp +++ b/indra/llaudio/llvorbisencode.cpp @@ -2,31 +2,25 @@ * @file vorbisencode.cpp * @brief Vorbis encoding routine routine for Indra. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llaudio/llvorbisencode.h b/indra/llaudio/llvorbisencode.h index 0828073d7..ad60e1130 100644 --- a/indra/llaudio/llvorbisencode.h +++ b/indra/llaudio/llvorbisencode.h @@ -2,31 +2,25 @@ * @file vorbisencode.h * @brief Vorbis encoding routine routine for Indra. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/llanimationstates.cpp b/indra/llcharacter/llanimationstates.cpp index 43f3e60b0..155226cf1 100644 --- a/indra/llcharacter/llanimationstates.cpp +++ b/indra/llcharacter/llanimationstates.cpp @@ -2,31 +2,25 @@ * @file llanimationstates.cpp * @brief Implementation of animation state related functions. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,57 +33,57 @@ #include "llanimationstates.h" #include "llstring.h" -LLUUID const ANIM_AGENT_AFRAID ("6b61c8e8-4747-0d75-12d7-e49ff207a4ca"); -LLUUID const ANIM_AGENT_AIM_BAZOOKA_R ("b5b4a67d-0aee-30d2-72cd-77b333e932ef"); -LLUUID const ANIM_AGENT_AIM_BOW_L ("46bb4359-de38-4ed8-6a22-f1f52fe8f506"); -LLUUID const ANIM_AGENT_AIM_HANDGUN_R ("3147d815-6338-b932-f011-16b56d9ac18b"); -LLUUID const ANIM_AGENT_AIM_RIFLE_R ("ea633413-8006-180a-c3ba-96dd1d756720"); -LLUUID const ANIM_AGENT_ANGRY ("5747a48e-073e-c331-f6f3-7c2149613d3e"); -LLUUID const ANIM_AGENT_AWAY ("fd037134-85d4-f241-72c6-4f42164fedee"); -LLUUID const ANIM_AGENT_BACKFLIP ("c4ca6188-9127-4f31-0158-23c4e2f93304"); -LLUUID const ANIM_AGENT_BELLY_LAUGH ("18b3a4b5-b463-bd48-e4b6-71eaac76c515"); -LLUUID const ANIM_AGENT_BLOW_KISS ("db84829b-462c-ee83-1e27-9bbee66bd624"); -LLUUID const ANIM_AGENT_BORED ("b906c4ba-703b-1940-32a3-0c7f7d791510"); -LLUUID const ANIM_AGENT_BOW ("82e99230-c906-1403-4d9c-3889dd98daba"); -LLUUID const ANIM_AGENT_BRUSH ("349a3801-54f9-bf2c-3bd0-1ac89772af01"); -LLUUID const ANIM_AGENT_BUSY ("efcf670c-2d18-8128-973a-034ebc806b67"); -LLUUID const ANIM_AGENT_CLAP ("9b0c1c4e-8ac7-7969-1494-28c874c4f668"); -LLUUID const ANIM_AGENT_COURTBOW ("9ba1c942-08be-e43a-fb29-16ad440efc50"); -LLUUID const ANIM_AGENT_CROUCH ("201f3fdf-cb1f-dbec-201f-7333e328ae7c"); -LLUUID const ANIM_AGENT_CROUCHWALK ("47f5f6fb-22e5-ae44-f871-73aaaf4a6022"); -LLUUID const ANIM_AGENT_CRY ("92624d3e-1068-f1aa-a5ec-8244585193ed"); -LLUUID const ANIM_AGENT_CUSTOMIZE ("038fcec9-5ebd-8a8e-0e2e-6e71a0a1ac53"); -LLUUID const ANIM_AGENT_CUSTOMIZE_DONE ("6883a61a-b27b-5914-a61e-dda118a9ee2c"); -LLUUID const ANIM_AGENT_DANCE1 ("b68a3d7c-de9e-fc87-eec8-543d787e5b0d"); -LLUUID const ANIM_AGENT_DANCE2 ("928cae18-e31d-76fd-9cc9-2f55160ff818"); -LLUUID const ANIM_AGENT_DANCE3 ("30047778-10ea-1af7-6881-4db7a3a5a114"); -LLUUID const ANIM_AGENT_DANCE4 ("951469f4-c7b2-c818-9dee-ad7eea8c30b7"); -LLUUID const ANIM_AGENT_DANCE5 ("4bd69a1d-1114-a0b4-625f-84e0a5237155"); -LLUUID const ANIM_AGENT_DANCE6 ("cd28b69b-9c95-bb78-3f94-8d605ff1bb12"); -LLUUID const ANIM_AGENT_DANCE7 ("a54d8ee2-28bb-80a9-7f0c-7afbbe24a5d6"); -LLUUID const ANIM_AGENT_DANCE8 ("b0dc417c-1f11-af36-2e80-7e7489fa7cdc"); -LLUUID const ANIM_AGENT_DEAD ("57abaae6-1d17-7b1b-5f98-6d11a6411276"); -LLUUID const ANIM_AGENT_DRINK ("0f86e355-dd31-a61c-fdb0-3a96b9aad05f"); -LLUUID const ANIM_AGENT_EMBARRASSED ("514af488-9051-044a-b3fc-d4dbf76377c6"); -LLUUID const ANIM_AGENT_EXPRESS_AFRAID ("aa2df84d-cf8f-7218-527b-424a52de766e"); -LLUUID const ANIM_AGENT_EXPRESS_ANGER ("1a03b575-9634-b62a-5767-3a679e81f4de"); -LLUUID const ANIM_AGENT_EXPRESS_BORED ("214aa6c1-ba6a-4578-f27c-ce7688f61d0d"); -LLUUID const ANIM_AGENT_EXPRESS_CRY ("d535471b-85bf-3b4d-a542-93bea4f59d33"); -LLUUID const ANIM_AGENT_EXPRESS_DISDAIN ("d4416ff1-09d3-300f-4183-1b68a19b9fc1"); -LLUUID const ANIM_AGENT_EXPRESS_EMBARRASSED ("0b8c8211-d78c-33e8-fa28-c51a9594e424"); -LLUUID const ANIM_AGENT_EXPRESS_FROWN ("fee3df48-fa3d-1015-1e26-a205810e3001"); -LLUUID const ANIM_AGENT_EXPRESS_KISS ("1e8d90cc-a84e-e135-884c-7c82c8b03a14"); -LLUUID const ANIM_AGENT_EXPRESS_LAUGH ("62570842-0950-96f8-341c-809e65110823"); -LLUUID const ANIM_AGENT_EXPRESS_OPEN_MOUTH ("d63bc1f9-fc81-9625-a0c6-007176d82eb7"); -LLUUID const ANIM_AGENT_EXPRESS_REPULSED ("f76cda94-41d4-a229-2872-e0296e58afe1"); -LLUUID const ANIM_AGENT_EXPRESS_SAD ("eb6ebfb2-a4b3-a19c-d388-4dd5c03823f7"); -LLUUID const ANIM_AGENT_EXPRESS_SHRUG ("a351b1bc-cc94-aac2-7bea-a7e6ebad15ef"); -LLUUID const ANIM_AGENT_EXPRESS_SMILE ("b7c7c833-e3d3-c4e3-9fc0-131237446312"); -LLUUID const ANIM_AGENT_EXPRESS_SURPRISE ("728646d9-cc79-08b2-32d6-937f0a835c24"); -LLUUID const ANIM_AGENT_EXPRESS_TONGUE_OUT ("835965c6-7f2f-bda2-5deb-2478737f91bf"); -LLUUID const ANIM_AGENT_EXPRESS_TOOTHSMILE ("b92ec1a5-e7ce-a76b-2b05-bcdb9311417e"); -LLUUID const ANIM_AGENT_EXPRESS_WINK ("da020525-4d94-59d6-23d7-81fdebf33148"); -LLUUID const ANIM_AGENT_EXPRESS_WORRY ("9c05e5c7-6f07-6ca4-ed5a-b230390c3950"); +LLUUID const ANIM_AGENT_AFRAID ("6b61c8e8-4747-0d75-12d7-e49ff207a4ca"); +LLUUID const ANIM_AGENT_AIM_BAZOOKA_R ("b5b4a67d-0aee-30d2-72cd-77b333e932ef"); +LLUUID const ANIM_AGENT_AIM_BOW_L ("46bb4359-de38-4ed8-6a22-f1f52fe8f506"); +LLUUID const ANIM_AGENT_AIM_HANDGUN_R ("3147d815-6338-b932-f011-16b56d9ac18b"); +LLUUID const ANIM_AGENT_AIM_RIFLE_R ("ea633413-8006-180a-c3ba-96dd1d756720"); +LLUUID const ANIM_AGENT_ANGRY ("5747a48e-073e-c331-f6f3-7c2149613d3e"); +LLUUID const ANIM_AGENT_AWAY ("fd037134-85d4-f241-72c6-4f42164fedee"); +LLUUID const ANIM_AGENT_BACKFLIP ("c4ca6188-9127-4f31-0158-23c4e2f93304"); +LLUUID const ANIM_AGENT_BELLY_LAUGH ("18b3a4b5-b463-bd48-e4b6-71eaac76c515"); +LLUUID const ANIM_AGENT_BLOW_KISS ("db84829b-462c-ee83-1e27-9bbee66bd624"); +LLUUID const ANIM_AGENT_BORED ("b906c4ba-703b-1940-32a3-0c7f7d791510"); +LLUUID const ANIM_AGENT_BOW ("82e99230-c906-1403-4d9c-3889dd98daba"); +LLUUID const ANIM_AGENT_BRUSH ("349a3801-54f9-bf2c-3bd0-1ac89772af01"); +LLUUID const ANIM_AGENT_BUSY ("efcf670c-2d18-8128-973a-034ebc806b67"); +LLUUID const ANIM_AGENT_CLAP ("9b0c1c4e-8ac7-7969-1494-28c874c4f668"); +LLUUID const ANIM_AGENT_COURTBOW ("9ba1c942-08be-e43a-fb29-16ad440efc50"); +LLUUID const ANIM_AGENT_CROUCH ("201f3fdf-cb1f-dbec-201f-7333e328ae7c"); +LLUUID const ANIM_AGENT_CROUCHWALK ("47f5f6fb-22e5-ae44-f871-73aaaf4a6022"); +LLUUID const ANIM_AGENT_CRY ("92624d3e-1068-f1aa-a5ec-8244585193ed"); +LLUUID const ANIM_AGENT_CUSTOMIZE ("038fcec9-5ebd-8a8e-0e2e-6e71a0a1ac53"); +LLUUID const ANIM_AGENT_CUSTOMIZE_DONE ("6883a61a-b27b-5914-a61e-dda118a9ee2c"); +LLUUID const ANIM_AGENT_DANCE1 ("b68a3d7c-de9e-fc87-eec8-543d787e5b0d"); +LLUUID const ANIM_AGENT_DANCE2 ("928cae18-e31d-76fd-9cc9-2f55160ff818"); +LLUUID const ANIM_AGENT_DANCE3 ("30047778-10ea-1af7-6881-4db7a3a5a114"); +LLUUID const ANIM_AGENT_DANCE4 ("951469f4-c7b2-c818-9dee-ad7eea8c30b7"); +LLUUID const ANIM_AGENT_DANCE5 ("4bd69a1d-1114-a0b4-625f-84e0a5237155"); +LLUUID const ANIM_AGENT_DANCE6 ("cd28b69b-9c95-bb78-3f94-8d605ff1bb12"); +LLUUID const ANIM_AGENT_DANCE7 ("a54d8ee2-28bb-80a9-7f0c-7afbbe24a5d6"); +LLUUID const ANIM_AGENT_DANCE8 ("b0dc417c-1f11-af36-2e80-7e7489fa7cdc"); +LLUUID const ANIM_AGENT_DEAD ("57abaae6-1d17-7b1b-5f98-6d11a6411276"); +LLUUID const ANIM_AGENT_DRINK ("0f86e355-dd31-a61c-fdb0-3a96b9aad05f"); +LLUUID const ANIM_AGENT_EMBARRASSED ("514af488-9051-044a-b3fc-d4dbf76377c6"); +LLUUID const ANIM_AGENT_EXPRESS_AFRAID ("aa2df84d-cf8f-7218-527b-424a52de766e"); +LLUUID const ANIM_AGENT_EXPRESS_ANGER ("1a03b575-9634-b62a-5767-3a679e81f4de"); +LLUUID const ANIM_AGENT_EXPRESS_BORED ("214aa6c1-ba6a-4578-f27c-ce7688f61d0d"); +LLUUID const ANIM_AGENT_EXPRESS_CRY ("d535471b-85bf-3b4d-a542-93bea4f59d33"); +LLUUID const ANIM_AGENT_EXPRESS_DISDAIN ("d4416ff1-09d3-300f-4183-1b68a19b9fc1"); +LLUUID const ANIM_AGENT_EXPRESS_EMBARRASSED ("0b8c8211-d78c-33e8-fa28-c51a9594e424"); +LLUUID const ANIM_AGENT_EXPRESS_FROWN ("fee3df48-fa3d-1015-1e26-a205810e3001"); +LLUUID const ANIM_AGENT_EXPRESS_KISS ("1e8d90cc-a84e-e135-884c-7c82c8b03a14"); +LLUUID const ANIM_AGENT_EXPRESS_LAUGH ("62570842-0950-96f8-341c-809e65110823"); +LLUUID const ANIM_AGENT_EXPRESS_OPEN_MOUTH ("d63bc1f9-fc81-9625-a0c6-007176d82eb7"); +LLUUID const ANIM_AGENT_EXPRESS_REPULSED ("f76cda94-41d4-a229-2872-e0296e58afe1"); +LLUUID const ANIM_AGENT_EXPRESS_SAD ("eb6ebfb2-a4b3-a19c-d388-4dd5c03823f7"); +LLUUID const ANIM_AGENT_EXPRESS_SHRUG ("a351b1bc-cc94-aac2-7bea-a7e6ebad15ef"); +LLUUID const ANIM_AGENT_EXPRESS_SMILE ("b7c7c833-e3d3-c4e3-9fc0-131237446312"); +LLUUID const ANIM_AGENT_EXPRESS_SURPRISE ("728646d9-cc79-08b2-32d6-937f0a835c24"); +LLUUID const ANIM_AGENT_EXPRESS_TONGUE_OUT ("835965c6-7f2f-bda2-5deb-2478737f91bf"); +LLUUID const ANIM_AGENT_EXPRESS_TOOTHSMILE ("b92ec1a5-e7ce-a76b-2b05-bcdb9311417e"); +LLUUID const ANIM_AGENT_EXPRESS_WINK ("da020525-4d94-59d6-23d7-81fdebf33148"); +LLUUID const ANIM_AGENT_EXPRESS_WORRY ("9c05e5c7-6f07-6ca4-ed5a-b230390c3950"); LLUUID const ANIM_AGENT_FALLDOWN ("666307d9-a860-572d-6fd4-c3ab8865c094"); LLUUID const ANIM_AGENT_FEMALE_RUN_NEW ("85995026-eade-5d78-d364-94a64512cb66"); LLUUID const ANIM_AGENT_FEMALE_WALK ("f5fc7433-043d-e819-8298-f519a119b688"); @@ -97,33 +91,33 @@ LLUUID const ANIM_AGENT_FEMALE_WALK_NEW ("d60c41d2-7c24-7074-d3fa-6101cea2 LLUUID const ANIM_AGENT_FINGER_WAG ("c1bc7f36-3ba0-d844-f93c-93be945d644f"); LLUUID const ANIM_AGENT_FIST_PUMP ("7db00ccd-f380-f3ee-439d-61968ec69c8a"); LLUUID const ANIM_AGENT_FLY ("aec4610c-757f-bc4e-c092-c6e9caf18daf"); -LLUUID const ANIM_AGENT_FLYSLOW ("2b5a38b2-5e00-3a97-a495-4c826bc443e6"); -LLUUID const ANIM_AGENT_HELLO ("9b29cd61-c45b-5689-ded2-91756b8d76a9"); -LLUUID const ANIM_AGENT_HOLD_BAZOOKA_R ("ef62d355-c815-4816-2474-b1acc21094a6"); -LLUUID const ANIM_AGENT_HOLD_BOW_L ("8b102617-bcba-037b-86c1-b76219f90c88"); -LLUUID const ANIM_AGENT_HOLD_HANDGUN_R ("efdc1727-8b8a-c800-4077-975fc27ee2f2"); -LLUUID const ANIM_AGENT_HOLD_RIFLE_R ("3d94bad0-c55b-7dcc-8763-033c59405d33"); -LLUUID const ANIM_AGENT_HOLD_THROW_R ("7570c7b5-1f22-56dd-56ef-a9168241bbb6"); -LLUUID const ANIM_AGENT_HOVER ("4ae8016b-31b9-03bb-c401-b1ea941db41d"); -LLUUID const ANIM_AGENT_HOVER_DOWN ("20f063ea-8306-2562-0b07-5c853b37b31e"); -LLUUID const ANIM_AGENT_HOVER_UP ("62c5de58-cb33-5743-3d07-9e4cd4352864"); -LLUUID const ANIM_AGENT_IMPATIENT ("5ea3991f-c293-392e-6860-91dfa01278a3"); -LLUUID const ANIM_AGENT_JUMP ("2305bd75-1ca9-b03b-1faa-b176b8a8c49e"); -LLUUID const ANIM_AGENT_JUMP_FOR_JOY ("709ea28e-1573-c023-8bf8-520c8bc637fa"); -LLUUID const ANIM_AGENT_KISS_MY_BUTT ("19999406-3a3a-d58c-a2ac-d72e555dcf51"); -LLUUID const ANIM_AGENT_LAND ("7a17b059-12b2-41b1-570a-186368b6aa6f"); -LLUUID const ANIM_AGENT_LAUGH_SHORT ("ca5b3f14-3194-7a2b-c894-aa699b718d1f"); -LLUUID const ANIM_AGENT_MEDIUM_LAND ("f4f00d6e-b9fe-9292-f4cb-0ae06ea58d57"); -LLUUID const ANIM_AGENT_MOTORCYCLE_SIT ("08464f78-3a8e-2944-cba5-0c94aff3af29"); -LLUUID const ANIM_AGENT_MUSCLE_BEACH ("315c3a41-a5f3-0ba4-27da-f893f769e69b"); -LLUUID const ANIM_AGENT_NO ("5a977ed9-7f72-44e9-4c4c-6e913df8ae74"); -LLUUID const ANIM_AGENT_NO_UNHAPPY ("d83fa0e5-97ed-7eb2-e798-7bd006215cb4"); -LLUUID const ANIM_AGENT_NYAH_NYAH ("f061723d-0a18-754f-66ee-29a44795a32f"); -LLUUID const ANIM_AGENT_ONETWO_PUNCH ("eefc79be-daae-a239-8c04-890f5d23654a"); -LLUUID const ANIM_AGENT_PEACE ("b312b10e-65ab-a0a4-8b3c-1326ea8e3ed9"); -LLUUID const ANIM_AGENT_POINT_ME ("17c024cc-eef2-f6a0-3527-9869876d7752"); -LLUUID const ANIM_AGENT_POINT_YOU ("ec952cca-61ef-aa3b-2789-4d1344f016de"); -LLUUID const ANIM_AGENT_PRE_JUMP ("7a4e87fe-de39-6fcb-6223-024b00893244"); +LLUUID const ANIM_AGENT_FLYSLOW ("2b5a38b2-5e00-3a97-a495-4c826bc443e6"); +LLUUID const ANIM_AGENT_HELLO ("9b29cd61-c45b-5689-ded2-91756b8d76a9"); +LLUUID const ANIM_AGENT_HOLD_BAZOOKA_R ("ef62d355-c815-4816-2474-b1acc21094a6"); +LLUUID const ANIM_AGENT_HOLD_BOW_L ("8b102617-bcba-037b-86c1-b76219f90c88"); +LLUUID const ANIM_AGENT_HOLD_HANDGUN_R ("efdc1727-8b8a-c800-4077-975fc27ee2f2"); +LLUUID const ANIM_AGENT_HOLD_RIFLE_R ("3d94bad0-c55b-7dcc-8763-033c59405d33"); +LLUUID const ANIM_AGENT_HOLD_THROW_R ("7570c7b5-1f22-56dd-56ef-a9168241bbb6"); +LLUUID const ANIM_AGENT_HOVER ("4ae8016b-31b9-03bb-c401-b1ea941db41d"); +LLUUID const ANIM_AGENT_HOVER_DOWN ("20f063ea-8306-2562-0b07-5c853b37b31e"); +LLUUID const ANIM_AGENT_HOVER_UP ("62c5de58-cb33-5743-3d07-9e4cd4352864"); +LLUUID const ANIM_AGENT_IMPATIENT ("5ea3991f-c293-392e-6860-91dfa01278a3"); +LLUUID const ANIM_AGENT_JUMP ("2305bd75-1ca9-b03b-1faa-b176b8a8c49e"); +LLUUID const ANIM_AGENT_JUMP_FOR_JOY ("709ea28e-1573-c023-8bf8-520c8bc637fa"); +LLUUID const ANIM_AGENT_KISS_MY_BUTT ("19999406-3a3a-d58c-a2ac-d72e555dcf51"); +LLUUID const ANIM_AGENT_LAND ("7a17b059-12b2-41b1-570a-186368b6aa6f"); +LLUUID const ANIM_AGENT_LAUGH_SHORT ("ca5b3f14-3194-7a2b-c894-aa699b718d1f"); +LLUUID const ANIM_AGENT_MEDIUM_LAND ("f4f00d6e-b9fe-9292-f4cb-0ae06ea58d57"); +LLUUID const ANIM_AGENT_MOTORCYCLE_SIT ("08464f78-3a8e-2944-cba5-0c94aff3af29"); +LLUUID const ANIM_AGENT_MUSCLE_BEACH ("315c3a41-a5f3-0ba4-27da-f893f769e69b"); +LLUUID const ANIM_AGENT_NO ("5a977ed9-7f72-44e9-4c4c-6e913df8ae74"); +LLUUID const ANIM_AGENT_NO_UNHAPPY ("d83fa0e5-97ed-7eb2-e798-7bd006215cb4"); +LLUUID const ANIM_AGENT_NYAH_NYAH ("f061723d-0a18-754f-66ee-29a44795a32f"); +LLUUID const ANIM_AGENT_ONETWO_PUNCH ("eefc79be-daae-a239-8c04-890f5d23654a"); +LLUUID const ANIM_AGENT_PEACE ("b312b10e-65ab-a0a4-8b3c-1326ea8e3ed9"); +LLUUID const ANIM_AGENT_POINT_ME ("17c024cc-eef2-f6a0-3527-9869876d7752"); +LLUUID const ANIM_AGENT_POINT_YOU ("ec952cca-61ef-aa3b-2789-4d1344f016de"); +LLUUID const ANIM_AGENT_PRE_JUMP ("7a4e87fe-de39-6fcb-6223-024b00893244"); LLUUID const ANIM_AGENT_PUNCH_LEFT ("f3300ad9-3462-1d07-2044-0fef80062da0"); LLUUID const ANIM_AGENT_PUNCH_RIGHT ("c8e42d32-7310-6906-c903-cab5d4a34656"); LLUUID const ANIM_AGENT_REPULSED ("36f81a92-f076-5893-dc4b-7c3795e487cf"); @@ -140,44 +134,44 @@ LLUUID const ANIM_AGENT_SHOOT_BOW_L ("e04d450d-fdb5-0432-fd68-818aaf59 LLUUID const ANIM_AGENT_SHOUT ("6bd01860-4ebd-127a-bb3d-d1427e8e0c42"); LLUUID const ANIM_AGENT_SHRUG ("70ea714f-3a97-d742-1b01-590a8fcd1db5"); LLUUID const ANIM_AGENT_SIT ("1a5fe8ac-a804-8a5d-7cbd-56bd83184568"); -LLUUID const ANIM_AGENT_SIT_FEMALE ("b1709c8d-ecd3-54a1-4f28-d55ac0840782"); -LLUUID const ANIM_AGENT_SIT_GENERIC ("245f3c54-f1c0-bf2e-811f-46d8eeb386e7"); -LLUUID const ANIM_AGENT_SIT_GROUND ("1c7600d6-661f-b87b-efe2-d7421eb93c86"); +LLUUID const ANIM_AGENT_SIT_FEMALE ("b1709c8d-ecd3-54a1-4f28-d55ac0840782"); +LLUUID const ANIM_AGENT_SIT_GENERIC ("245f3c54-f1c0-bf2e-811f-46d8eeb386e7"); +LLUUID const ANIM_AGENT_SIT_GROUND ("1c7600d6-661f-b87b-efe2-d7421eb93c86"); LLUUID const ANIM_AGENT_SIT_GROUND_CONSTRAINED("1a2bd58e-87ff-0df8-0b4c-53e047b0bb6e"); -LLUUID const ANIM_AGENT_SIT_TO_STAND ("a8dee56f-2eae-9e7a-05a2-6fb92b97e21e"); -LLUUID const ANIM_AGENT_SLEEP ("f2bed5f9-9d44-39af-b0cd-257b2a17fe40"); -LLUUID const ANIM_AGENT_SMOKE_IDLE ("d2f2ee58-8ad1-06c9-d8d3-3827ba31567a"); -LLUUID const ANIM_AGENT_SMOKE_INHALE ("6802d553-49da-0778-9f85-1599a2266526"); -LLUUID const ANIM_AGENT_SMOKE_THROW_DOWN ("0a9fb970-8b44-9114-d3a9-bf69cfe804d6"); -LLUUID const ANIM_AGENT_SNAPSHOT ("eae8905b-271a-99e2-4c0e-31106afd100c"); -LLUUID const ANIM_AGENT_STAND ("2408fe9e-df1d-1d7d-f4ff-1384fa7b350f"); -LLUUID const ANIM_AGENT_STANDUP ("3da1d753-028a-5446-24f3-9c9b856d9422"); -LLUUID const ANIM_AGENT_STAND_1 ("15468e00-3400-bb66-cecc-646d7c14458e"); -LLUUID const ANIM_AGENT_STAND_2 ("370f3a20-6ca6-9971-848c-9a01bc42ae3c"); -LLUUID const ANIM_AGENT_STAND_3 ("42b46214-4b44-79ae-deb8-0df61424ff4b"); -LLUUID const ANIM_AGENT_STAND_4 ("f22fed8b-a5ed-2c93-64d5-bdd8b93c889f"); -LLUUID const ANIM_AGENT_STRETCH ("80700431-74ec-a008-14f8-77575e73693f"); -LLUUID const ANIM_AGENT_STRIDE ("1cb562b0-ba21-2202-efb3-30f82cdf9595"); -LLUUID const ANIM_AGENT_SURF ("41426836-7437-7e89-025d-0aa4d10f1d69"); -LLUUID const ANIM_AGENT_SURPRISE ("313b9881-4302-73c0-c7d0-0e7a36b6c224"); -LLUUID const ANIM_AGENT_SWORD_STRIKE ("85428680-6bf9-3e64-b489-6f81087c24bd"); -LLUUID const ANIM_AGENT_TALK ("5c682a95-6da4-a463-0bf6-0f5b7be129d1"); -LLUUID const ANIM_AGENT_TANTRUM ("11000694-3f41-adc2-606b-eee1d66f3724"); -LLUUID const ANIM_AGENT_THROW_R ("aa134404-7dac-7aca-2cba-435f9db875ca"); -LLUUID const ANIM_AGENT_TRYON_SHIRT ("83ff59fe-2346-f236-9009-4e3608af64c1"); -LLUUID const ANIM_AGENT_TURNLEFT ("56e0ba0d-4a9f-7f27-6117-32f2ebbf6135"); -LLUUID const ANIM_AGENT_TURNRIGHT ("2d6daa51-3192-6794-8e2e-a15f8338ec30"); +LLUUID const ANIM_AGENT_SIT_TO_STAND ("a8dee56f-2eae-9e7a-05a2-6fb92b97e21e"); +LLUUID const ANIM_AGENT_SLEEP ("f2bed5f9-9d44-39af-b0cd-257b2a17fe40"); +LLUUID const ANIM_AGENT_SMOKE_IDLE ("d2f2ee58-8ad1-06c9-d8d3-3827ba31567a"); +LLUUID const ANIM_AGENT_SMOKE_INHALE ("6802d553-49da-0778-9f85-1599a2266526"); +LLUUID const ANIM_AGENT_SMOKE_THROW_DOWN ("0a9fb970-8b44-9114-d3a9-bf69cfe804d6"); +LLUUID const ANIM_AGENT_SNAPSHOT ("eae8905b-271a-99e2-4c0e-31106afd100c"); +LLUUID const ANIM_AGENT_STAND ("2408fe9e-df1d-1d7d-f4ff-1384fa7b350f"); +LLUUID const ANIM_AGENT_STANDUP ("3da1d753-028a-5446-24f3-9c9b856d9422"); +LLUUID const ANIM_AGENT_STAND_1 ("15468e00-3400-bb66-cecc-646d7c14458e"); +LLUUID const ANIM_AGENT_STAND_2 ("370f3a20-6ca6-9971-848c-9a01bc42ae3c"); +LLUUID const ANIM_AGENT_STAND_3 ("42b46214-4b44-79ae-deb8-0df61424ff4b"); +LLUUID const ANIM_AGENT_STAND_4 ("f22fed8b-a5ed-2c93-64d5-bdd8b93c889f"); +LLUUID const ANIM_AGENT_STRETCH ("80700431-74ec-a008-14f8-77575e73693f"); +LLUUID const ANIM_AGENT_STRIDE ("1cb562b0-ba21-2202-efb3-30f82cdf9595"); +LLUUID const ANIM_AGENT_SURF ("41426836-7437-7e89-025d-0aa4d10f1d69"); +LLUUID const ANIM_AGENT_SURPRISE ("313b9881-4302-73c0-c7d0-0e7a36b6c224"); +LLUUID const ANIM_AGENT_SWORD_STRIKE ("85428680-6bf9-3e64-b489-6f81087c24bd"); +LLUUID const ANIM_AGENT_TALK ("5c682a95-6da4-a463-0bf6-0f5b7be129d1"); +LLUUID const ANIM_AGENT_TANTRUM ("11000694-3f41-adc2-606b-eee1d66f3724"); +LLUUID const ANIM_AGENT_THROW_R ("aa134404-7dac-7aca-2cba-435f9db875ca"); +LLUUID const ANIM_AGENT_TRYON_SHIRT ("83ff59fe-2346-f236-9009-4e3608af64c1"); +LLUUID const ANIM_AGENT_TURNLEFT ("56e0ba0d-4a9f-7f27-6117-32f2ebbf6135"); +LLUUID const ANIM_AGENT_TURNRIGHT ("2d6daa51-3192-6794-8e2e-a15f8338ec30"); LLUUID const ANIM_AGENT_TYPE ("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9"); LLUUID const ANIM_AGENT_WALK ("6ed24bd8-91aa-4b12-ccc7-c97c857ab4e0"); LLUUID const ANIM_AGENT_WALK_NEW ("33339176-7ddc-9397-94a4-bf3403cbc8f5"); LLUUID const ANIM_AGENT_WHISPER ("7693f268-06c7-ea71-fa21-2b30d6533f8f"); LLUUID const ANIM_AGENT_WHISTLE ("b1ed7982-c68e-a982-7561-52a88a5298c0"); -LLUUID const ANIM_AGENT_WINK ("869ecdad-a44b-671e-3266-56aef2e3ac2e"); -LLUUID const ANIM_AGENT_WINK_HOLLYWOOD ("c0c4030f-c02b-49de-24ba-2331f43fe41c"); -LLUUID const ANIM_AGENT_WORRY ("9f496bd2-589a-709f-16cc-69bf7df1d36c"); -LLUUID const ANIM_AGENT_YES ("15dd911d-be82-2856-26db-27659b142875"); -LLUUID const ANIM_AGENT_YES_HAPPY ("b8c8b2a3-9008-1771-3bfc-90924955ab2d"); -LLUUID const ANIM_AGENT_YOGA_FLOAT ("42ecd00b-9947-a97c-400a-bbc9174c7aeb"); +LLUUID const ANIM_AGENT_WINK ("869ecdad-a44b-671e-3266-56aef2e3ac2e"); +LLUUID const ANIM_AGENT_WINK_HOLLYWOOD ("c0c4030f-c02b-49de-24ba-2331f43fe41c"); +LLUUID const ANIM_AGENT_WORRY ("9f496bd2-589a-709f-16cc-69bf7df1d36c"); +LLUUID const ANIM_AGENT_YES ("15dd911d-be82-2856-26db-27659b142875"); +LLUUID const ANIM_AGENT_YES_HAPPY ("b8c8b2a3-9008-1771-3bfc-90924955ab2d"); +LLUUID const ANIM_AGENT_YOGA_FLOAT ("42ecd00b-9947-a97c-400a-bbc9174c7aeb"); LLUUID AGENT_WALK_ANIMS[] = {ANIM_AGENT_WALK, ANIM_AGENT_RUN, ANIM_AGENT_CROUCHWALK, ANIM_AGENT_TURNLEFT, ANIM_AGENT_TURNRIGHT}; S32 NUM_AGENT_WALK_ANIMS = LL_ARRAY_SIZE(AGENT_WALK_ANIMS); @@ -498,6 +492,5 @@ const LLAnimStateEntry gUserAnimStates[] = { const S32 gUserAnimStatesCount = LL_ARRAY_SIZE(gUserAnimStates); - // End diff --git a/indra/llcharacter/llanimationstates.h b/indra/llcharacter/llanimationstates.h index 77556013d..aa6579ac8 100644 --- a/indra/llcharacter/llanimationstates.h +++ b/indra/llcharacter/llanimationstates.h @@ -2,31 +2,25 @@ * @file llanimationstates.h * @brief Implementation of animation state support. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -262,7 +256,6 @@ extern const LLAnimStateEntry gUserAnimStates[]; extern const S32 gUserAnimStatesCount; extern LLAnimationLibrary gAnimLibrary; - #endif // LL_LLANIMATIONSTATES_H diff --git a/indra/llcharacter/llbvhconsts.h b/indra/llcharacter/llbvhconsts.h index d5876aa07..b77732de1 100644 --- a/indra/llcharacter/llbvhconsts.h +++ b/indra/llcharacter/llbvhconsts.h @@ -33,7 +33,7 @@ #ifndef LL_LLBVHCONSTS_H #define LL_LLBVHCONSTS_H -const F32 MAX_ANIM_DURATION = 30.f; +const F32 MAX_ANIM_DURATION = 60.f; typedef enum e_constraint_type { diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 9ef121624..2249d1622 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -2,31 +2,25 @@ * @file llbvhloader.cpp * @brief Translates a BVH files to LindenLabAnimation format. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 23d1fbeb3..8ffebfd21 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -2,31 +2,25 @@ * @file llcharacter.cpp * @brief Implementation of LLCharacter class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -292,7 +286,7 @@ void LLCharacter::removeAnimationData(std::string name) //----------------------------------------------------------------------------- // setVisualParamWeight() //----------------------------------------------------------------------------- -BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL upload_bake) +BOOL LLCharacter::setVisualParamWeight(const LLVisualParam* which_param, F32 weight, BOOL upload_bake) { S32 index = which_param->getID(); visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 5fad36b1c..0d66b1d52 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -2,31 +2,25 @@ * @file llcharacter.h * @brief Implementation of LLCharacter class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -99,13 +93,6 @@ public: // get the height & normal of the ground under a point virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm) = 0; - // allocate an array of joints for the character skeleton - // this must be overloaded to support joint subclasses, - // and is called implicitly from buildSkeleton(). - // Note this must handle reallocation as it will be called - // each time buildSkeleton() is called. - virtual BOOL allocateCharacterJoints( U32 num ) = 0; - // skeleton joint accessor to support joint subclasses virtual LLJoint *getCharacterJoint( U32 i ) = 0; @@ -203,7 +190,7 @@ public: void addVisualParam(LLVisualParam *param); void addSharedVisualParam(LLVisualParam *param); - virtual BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE ); + virtual BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE ); virtual BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE ); virtual BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE ); diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index b591380c6..cb283c9ec 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -2,31 +2,25 @@ * @file lleditingmotion.cpp * @brief Implementation of LLEditingMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -187,7 +181,7 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) } focus_pt += mCharacter->getCharacterPosition(); - + // propagate joint positions to kinematic chain mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp index b1af1c4ec..d992b349e 100644 --- a/indra/llcharacter/llhandmotion.cpp +++ b/indra/llcharacter/llhandmotion.cpp @@ -2,31 +2,25 @@ * @file llhandmotion.cpp * @brief Implementation of LLHandMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 091cfa859..f2900d4a5 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -2,31 +2,25 @@ * @file lljoint.cpp * @brief Implementation of LLJoint class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,7 +40,9 @@ S32 LLJoint::sNumTouches = 0; // LLJoint() // Class Constructor //----------------------------------------------------------------------------- -LLJoint::LLJoint() + + +void LLJoint::init() { mName = "unnamed"; mParent = NULL; @@ -54,7 +50,20 @@ LLJoint::LLJoint() mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f)); mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY; mUpdateXform = TRUE; - mJointNum = -1; +} + +LLJoint::LLJoint() : + mJointNum(-1) +{ + init(); + touch(); + mResetAfterRestoreOldXform = false; +} + +LLJoint::LLJoint(S32 joint_num) : + mJointNum(joint_num) +{ + init(); touch(); mResetAfterRestoreOldXform = false; } @@ -64,15 +73,12 @@ LLJoint::LLJoint() // LLJoint() // Class Constructor //----------------------------------------------------------------------------- -LLJoint::LLJoint(const std::string &name, LLJoint *parent) +LLJoint::LLJoint(const std::string &name, LLJoint *parent) : + mJointNum(0) { - mName = "unnamed"; - mParent = NULL; - mXform.setScaleChildOffset(TRUE); - mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f)); - mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY; + init(); mUpdateXform = FALSE; - mJointNum = 0; + // *TODO: mResetAfterRestoreOldXform is not initialized!!! setName(name); if (parent) @@ -240,6 +246,7 @@ void LLJoint::setPosition( const LLVector3& pos ) } } + //-------------------------------------------------------------------- // setPosition() //-------------------------------------------------------------------- diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index e2d6672b5..fe14c1e44 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -2,31 +2,25 @@ * @file lljoint.h * @brief Implementation of LLJoint class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -93,6 +87,7 @@ protected: public: U32 mDirtyFlags; BOOL mUpdateXform; + BOOL mResetAfterRestoreOldXform; // describes the skin binding pose @@ -110,10 +105,15 @@ public: public: LLJoint(); + LLJoint(S32 joint_num); + // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform* LLJoint( const std::string &name, LLJoint *parent=NULL ); - virtual ~LLJoint(); +private: + void init(); + +public: // set name and parent void setup( const std::string &name, LLJoint *parent=NULL ); @@ -140,7 +140,9 @@ public: // get/set local position const LLVector3& getPosition(); void setPosition( const LLVector3& pos ); - + + void setDefaultPosition( const LLVector3& pos ); + // get/set world position LLVector3 getWorldPosition(); LLVector3 getLastWorldPosition(); @@ -181,8 +183,7 @@ public: virtual BOOL isAnimatable() const { return TRUE; } S32 getJointNum() const { return mJointNum; } - void setJointNum(S32 joint_num) { mJointNum = joint_num; } - + void restoreOldXform( void ); void restoreToDefaultXform( void ); void setDefaultFromCurrentXform( void ); diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 6f769ab7e..df10f984a 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -2,31 +2,25 @@ * @file llkeyframemotion.cpp * @brief Implementation of LLKeyframeMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -961,6 +955,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 { return; } + LLVector3 root_pos = root_joint->getWorldPosition(); // LLQuaternion root_rot = root_joint->getParent()->getWorldRotation(); @@ -1456,7 +1451,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) LLPointer joint_state = new LLJointState; mJointStates.push_back(joint_state); - joint_state->setJoint( joint ); + joint_state->setJoint( joint ); // note: can accept NULL joint_state->setUsage( 0 ); //--------------------------------------------------------------------- @@ -1841,7 +1836,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) mJointMotionList->mConstraints.push_front(constraintp); - constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; + constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume); // get joint to which this collision volume is attached diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp index c93cf2107..4df1ef46b 100644 --- a/indra/llcharacter/llkeyframemotionparam.cpp +++ b/indra/llcharacter/llkeyframemotionparam.cpp @@ -2,31 +2,25 @@ * @file llkeyframemotionparam.cpp * @brief Implementation of LLKeyframeMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp index 9983be4f5..251ff3ed5 100644 --- a/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/indra/llcharacter/llkeyframewalkmotion.cpp @@ -2,31 +2,25 @@ * @file llkeyframewalkmotion.cpp * @brief Implementation of LLKeyframeWalkMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -153,7 +147,6 @@ LLWalkAdjustMotion::LLWalkAdjustMotion(const LLUUID &id) : mAnkleOffset(0.f) { mName = "walk_adjust"; - mPelvisState = new LLJointState; } diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp index e7e6575de..d8290681a 100644 --- a/indra/llcharacter/llmultigesture.cpp +++ b/indra/llcharacter/llmultigesture.cpp @@ -50,8 +50,7 @@ LLMultiGesture::LLMultiGesture() mSteps(), mPlaying(FALSE), mCurrentStep(0), - mDoneCallback(NULL), - mCallbackData(NULL) + mDoneCallback(NULL) { reset(); } diff --git a/indra/llcharacter/llmultigesture.h b/indra/llcharacter/llmultigesture.h index 0c027b31b..4c5a29cf0 100644 --- a/indra/llcharacter/llmultigesture.h +++ b/indra/llcharacter/llmultigesture.h @@ -2,31 +2,25 @@ * @file llmultigesture.h * @brief Gestures that are asset-based and can have multiple steps. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -100,8 +94,7 @@ public: // Timer for waiting LLFrameTimer mWaitTimer; - void (*mDoneCallback)(LLMultiGesture* gesture, void* data); - void* mCallbackData; + boost::function mDoneCallback; // Animations that we requested to start std::set mRequestedAnimIDs; diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp index 7f08f3e58..c63f8c21b 100644 --- a/indra/llcharacter/llpose.cpp +++ b/indra/llcharacter/llpose.cpp @@ -2,31 +2,25 @@ * @file llpose.cpp * @brief Implementation of LLPose class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/llstatemachine.cpp b/indra/llcharacter/llstatemachine.cpp index b77a999fa..dcc4ff5f0 100644 --- a/indra/llcharacter/llstatemachine.cpp +++ b/indra/llcharacter/llstatemachine.cpp @@ -2,31 +2,25 @@ * @file llstatemachine.cpp * @brief LLStateMachine implementation file. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp index 809b312ab..f7cb0f76b 100644 --- a/indra/llcharacter/llvisualparam.cpp +++ b/indra/llcharacter/llvisualparam.cpp @@ -168,7 +168,8 @@ LLVisualParam::LLVisualParam() mIsAnimating( FALSE ), mID( -1 ), mInfo( 0 ), - mIsDummy(FALSE) + mIsDummy(FALSE), + mParamLocation(LOC_UNKNOWN) { } @@ -250,6 +251,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL upload_bake) if (mIsDummy) { setWeight(target_value, upload_bake); + mTargetWeight = mCurWeight; return; } @@ -319,3 +321,32 @@ void LLVisualParam::resetDrivenParams() // nothing to do for non-driver parameters return; } + +const std::string param_location_name(const EParamLocation& loc) +{ + switch (loc) + { + case LOC_UNKNOWN: return "unknown"; + case LOC_AV_SELF: return "self"; + case LOC_AV_OTHER: return "other"; + case LOC_WEARABLE: return "wearable"; + default: return "error"; + } +} + +void LLVisualParam::setParamLocation(EParamLocation loc) +{ + if (mParamLocation == LOC_UNKNOWN || loc == LOC_UNKNOWN) + { + mParamLocation = loc; + } + else if (mParamLocation == loc) + { + // no action + } + else + { + lldebugs << "param location is already " << mParamLocation << ", not slamming to " << loc << llendl; + } +} + diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h index 694e27f37..a5864c15c 100644 --- a/indra/llcharacter/llvisualparam.h +++ b/indra/llcharacter/llvisualparam.h @@ -50,6 +50,16 @@ enum EVisualParamGroup NUM_VISUAL_PARAM_GROUPS }; +enum EParamLocation +{ + LOC_UNKNOWN, + LOC_AV_SELF, + LOC_AV_OTHER, + LOC_WEARABLE +}; + +const std::string param_location_name(const EParamLocation& loc); + const S32 MAX_TRANSMITTED_VISUAL_PARAMS = 255; //----------------------------------------------------------------------------- @@ -149,6 +159,9 @@ public: void setIsDummy(BOOL is_dummy) { mIsDummy = is_dummy; } + void setParamLocation(EParamLocation loc); + EParamLocation getParamLocation() const { return mParamLocation; } + protected: F32 mCurWeight; // current weight F32 mLastWeight; // last weight @@ -160,6 +173,7 @@ protected: S32 mID; // id for storing weight/morphtarget compares compactly LLVisualParamInfo *mInfo; + EParamLocation mParamLocation; // where does this visual param live? }; #endif // LL_LLVisualParam_H diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 5d86a6415..43e4f030a 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -105,6 +105,7 @@ set(llcommon_HEADER_FILES CMakeLists.txt aiframetimer.h + airecursive.h aithreadid.h aithreadsafe.h bitpack.h @@ -170,6 +171,7 @@ set(llcommon_HEADER_FILES llfoldertype.h llformat.h llframetimer.h + llhandle.h llhash.h llheartbeat.h llhttpstatuscodes.h diff --git a/indra/llcommon/airecursive.h b/indra/llcommon/airecursive.h new file mode 100644 index 000000000..0b22535a8 --- /dev/null +++ b/indra/llcommon/airecursive.h @@ -0,0 +1,58 @@ +/** + * @file airecursive.h + * @brief Declaration of AIRecursive. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 05/01/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AI_RECURSIVE +#define AI_RECURSIVE + +// Exception safe class to detect recursive calls. +// +// A unique, static bool must be passed (thread local if the function is +// called by more than one thread). +// +// Example usage: +// +// void f() +// { +// static bool recursive; +// if (recursive) return; +// AIRecursive dummy(flag); +// ... +// } + +class AIRecursive { + private: + bool& mFlag; + + public: + AIRecursive(bool& flag) : mFlag(flag) { mFlag = true; } + ~AIRecursive() { mFlag = false; } +}; + +#endif // AI_RECURSIVE diff --git a/indra/llcommon/aithreadsafe.h b/indra/llcommon/aithreadsafe.h index a9f56afff..eff95d83f 100644 --- a/indra/llcommon/aithreadsafe.h +++ b/indra/llcommon/aithreadsafe.h @@ -111,10 +111,10 @@ template struct AIAccess; template struct AISTAccessConst; template struct AISTAccess; +// This helper class is needed because offsetof is only allowed on POD types. template -class AIThreadSafeBits +struct AIThreadSafeBitsPOD { -private: // AIThreadSafe is a wrapper around an instance of T. // Because T might not have a default constructor, it is constructed // 'in place', with placement new, in the memory reserved here. @@ -122,7 +122,11 @@ private: // Make sure that the memory that T will be placed in is properly // aligned by using an array of long's. long mMemory[(sizeof(T) + sizeof(long) - 1) / sizeof(long)]; +}; +template +class AIThreadSafeBits : private AIThreadSafeBitsPOD +{ public: // The wrapped objects are constructed in-place with placement new *outside* // of this object (by AITHREADSAFE macro(s) or derived classes). @@ -130,20 +134,20 @@ public: ~AIThreadSafeBits() { ptr()->~T(); } // Only for use by AITHREADSAFE, see below. - void* memory() const { return const_cast(&mMemory[0]); } + void* memory() const { return const_cast(&AIThreadSafeBitsPOD::mMemory[0]); } // Cast a T* back to AIThreadSafeBits. This is the inverse of memory(). template static AIThreadSafeBits* wrapper_cast(T2* ptr) - { return reinterpret_cast*>(reinterpret_cast(ptr) - offsetof(AIThreadSafeBits, mMemory[0])); } + { return static_cast*>(reinterpret_cast*>(reinterpret_cast(ptr) - offsetof(AIThreadSafeBitsPOD, mMemory[0]))); } template static AIThreadSafeBits const* wrapper_cast(T2 const* ptr) - { return reinterpret_cast const*>(reinterpret_cast(ptr) - offsetof(AIThreadSafeBits, mMemory[0])); } + { return static_cast const*>(reinterpret_cast const*>(reinterpret_cast(ptr) - offsetof(AIThreadSafeBitsPOD, mMemory[0]))); } protected: // Accessors. - T const* ptr() const { return reinterpret_cast(mMemory); } - T* ptr() { return reinterpret_cast(mMemory); } + T const* ptr() const { return reinterpret_cast(AIThreadSafeBitsPOD::mMemory); } + T* ptr() { return reinterpret_cast(AIThreadSafeBitsPOD::mMemory); } }; /** diff --git a/indra/llcommon/imageids.cpp b/indra/llcommon/imageids.cpp index 6b4fcd3d7..fe1146522 100644 --- a/indra/llcommon/imageids.cpp +++ b/indra/llcommon/imageids.cpp @@ -1,33 +1,26 @@ -/** +/** * @file imageids.cpp * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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 "linden_common.h" diff --git a/indra/llcommon/imageids.h b/indra/llcommon/imageids.h index dc726dcf5..e0c2683fd 100644 --- a/indra/llcommon/imageids.h +++ b/indra/llcommon/imageids.h @@ -2,31 +2,25 @@ * @file imageids.h * @brief Temporary holder for image IDs * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 3668be93f..05e59d51f 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -2,31 +2,25 @@ * @file indra_constants.h * @brief some useful short term constants for Indra * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llallocator.cpp b/indra/llcommon/llallocator.cpp index 6f6abefc6..87654b5b9 100644 --- a/indra/llcommon/llallocator.cpp +++ b/indra/llcommon/llallocator.cpp @@ -27,7 +27,7 @@ #include "linden_common.h" #include "llallocator.h" -#if LL_USE_TCMALLOC +#if (LL_USE_TCMALLOC && LL_USE_HEAP_PROFILER) #include "google/heap-profiler.h" #include "google/commandlineflags_public.h" diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 316b07e83..a11effc15 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -2,31 +2,25 @@ * @file llapp.cpp * @brief Implementation of the LLApp class. * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 788177dd9..d56e20800 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -2,31 +2,25 @@ * @file llapp.h * @brief Declaration of the LLApp class. * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 997da6a79..4b86fecdf 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -4,31 +4,25 @@ * @date 2004-11-28 * @brief Helper functions for using the apache portable runtime library. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 61f3f97c0..97aa96e0b 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -4,31 +4,25 @@ * @date 2004-11-28 * @brief Helper functions for using the apache portable runtime library. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index e0c24fc97..5b22d5bab 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -2,31 +2,25 @@ * @file llassettype.cpp * @brief Implementatino of LLAssetType functionality. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index c253754ab..e6fee54ca 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -2,31 +2,25 @@ * @file llassettype.h * @brief Declaration of LLAssetType. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -42,121 +36,113 @@ class LL_COMMON_API LLAssetType public: enum EType { - // Used for painting the faces of geometry. - // Stored in typical j2c stream format AT_TEXTURE = 0, + // Used for painting the faces of geometry. + // Stored in typical j2c stream format. - // Used to fill the aural spectrum. AT_SOUND = 1, + // Used to fill the aural spectrum. - // Links instant message access to the user on the card. eg, a - // card for yourself, a card for linden support, a card for - // the guy you were talking to in the coliseum. AT_CALLINGCARD = 2, + // Links instant message access to the user on the card. + // : E.G. A card for yourself, for linden support, for + // : the guy you were talking to in the coliseum. - // Links to places in the world with location and a screen - // shot or image saved. eg, home, linden headquarters, the - // coliseum, or destinations where we want to increase - // traffic. AT_LANDMARK = 3, + // Links to places in the world with location and a screen shot or image saved. + // : E.G. Home, linden headquarters, the coliseum, destinations where + // : we want to increase traffic. - // Valid scripts that can be attached to an object. eg. open a - // door, jump into the air. AT_SCRIPT = 4, + // Valid scripts that can be attached to an object. + // : E.G. Open a door, jump into the air. - // A collection of textures and parameters that can be worn - // by an avatar. AT_CLOTHING = 5, + // A collection of textures and parameters that can be worn by an avatar. - // Any combination of textures, sounds, and scripts that are - // associated with a fixed piece of geometry. eg, a hot tub, a - // house with working door. AT_OBJECT = 6, + // Any combination of textures, sounds, and scripts that are + // associated with a fixed piece of geometry. + // : E.G. A hot tub, a house with working door. - // Just text AT_NOTECARD = 7, + // Just text. - // A category holds a collection of inventory items. It's - // treated as an item in the inventory, and therefore needs a - // type. AT_CATEGORY = 8, + // Holds a collection of inventory items. + // It's treated as an item in the inventory and therefore needs a type. - // A root category is a user's root inventory category. We - // decided to expose it visually, so it seems logical to fold - // it into the asset types. - //AT_ROOT_CATEGORY = 9, - - // The LSL is the brand spanking new scripting language. We've - // split it into a text and bytecode representation. AT_LSL_TEXT = 10, AT_LSL_BYTECODE = 11, + // The LSL is the scripting language. + // We've split it into a text and bytecode representation. - // uncompressed TGA texture AT_TEXTURE_TGA = 12, + // Uncompressed TGA texture. - // A collection of textures and parameters that can be worn - // by an avatar. AT_BODYPART = 13, - - // This asset type is meant to only be used as a marker for a - // category preferred type. Using this, we can throw things in - // the trash before completely deleting. + // A collection of textures and parameters that can be worn by an avatar. + //AT_TRASH = 14, - - // This is a marker for a folder meant for snapshots. No - // actual assets will be snapshots, though if there were, you - // could interpret them as textures. + // This asset type is meant to only be used as a marker for a + // category preferred type. Using this, we can throw things in + // the trash before completely deleting. + //AT_SNAPSHOT_CATEGORY = 15, + // This is a marker for a folder meant for snapshots. No + // actual assets will be snapshots, though if there were, you + // could interpret them as textures. - // This is used to stuff lost&found items into //AT_LOST_AND_FOUND = 16, + // This is used to stuff lost&found items into // uncompressed sound AT_SOUND_WAV = 17, + // Uncompressed sound. - // uncompressed image, non-square, and not appropriate for use - // as a texture. AT_IMAGE_TGA = 18, + // Uncompressed image, non-square. + // Not appropriate for use as a texture. - // compressed image, non-square, and not appropriate for use - // as a texture. AT_IMAGE_JPEG = 19, + // Compressed image, non-square. + // Not appropriate for use as a texture. - // animation AT_ANIMATION = 20, + // Animation. - // gesture, sequence of animations, sounds, chat, wait steps AT_GESTURE = 21, + // Gesture, sequence of animations, sounds, chat, wait steps. - // simstate file AT_SIMSTATE = 22, + // Simstate file. - //AT_FAVORITE = 23, - - // Inventory symbolic link AT_LINK = 24, + // Inventory symbolic link - // Inventory folder link AT_LINK_FOLDER = 25, + // Inventory folder link AT_CURRENT_OUTFIT = 46, AT_OUTFIT = 47, AT_MY_OUTFITS = 48, - + AT_MESH = 49, - // Mesh data in our proprietary SLM format - + // Mesh data in our proprietary SLM format + AT_COUNT = 50, - // +*********************************************+ - // | TO ADD AN ELEMENT TO THIS ENUM: | - // +*********************************************+ - // | 1. INSERT BEFORE AT_COUNT | - // | 2. INCREMENT AT_COUNT BY 1 | - // | 3. ADD TO LLAssetType::mAssetTypeNames | - // | 4. ADD TO LLAssetType::mAssetTypeHumanNames | - // +*********************************************+ + + // +*********************************************************+ + // | TO ADD AN ELEMENT TO THIS ENUM: | + // +*********************************************************+ + // | 1. INSERT BEFORE AT_COUNT | + // | 2. INCREMENT AT_COUNT BY 1 | + // | 3. ADD TO LLAssetType.cpp | + // | 4. ADD TO LLViewerAssetType.cpp | + // | 5. ADD TO DEFAULT_ASSET_FOR_INV in LLInventoryType.cpp | + // +*********************************************************+ AT_NONE = -1 }; @@ -171,8 +157,6 @@ public: static EType lookupHumanReadable(const std::string& readable_name); static const char* lookupHumanReadable(EType asset_type); - //NOTE: LLAssetType::lookupDragAndDropType & LLAssetType::generateDescriptionFor moved to newview/llviewerassettype.h - static EType getType(const std::string& desc_name); static const std::string& getDesc(EType asset_type); diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h index f7456eda0..13b99550b 100644 --- a/indra/llcommon/llchat.h +++ b/indra/llcommon/llchat.h @@ -3,31 +3,25 @@ * @author James Cook * @brief Chat constants and data structures. * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 33b30ac72..62f419116 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -1,31 +1,25 @@ /** * @file llcommon.cpp * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llcommon.h b/indra/llcommon/llcommon.h index 300ebe2b2..9c5f1b65a 100644 --- a/indra/llcommon/llcommon.h +++ b/indra/llcommon/llcommon.h @@ -1,31 +1,25 @@ /** * @file llcommon.h * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llcursortypes.cpp b/indra/llcommon/llcursortypes.cpp index 916ac8a91..2db209a02 100644 --- a/indra/llcommon/llcursortypes.cpp +++ b/indra/llcommon/llcursortypes.cpp @@ -2,31 +2,25 @@ * @file llcursortypes.cpp * @brief Cursor types and lookup of types from a string * - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/lldarray.h b/indra/llcommon/lldarray.h index 5433e8d72..293695411 100644 --- a/indra/llcommon/lldarray.h +++ b/indra/llcommon/lldarray.h @@ -2,31 +2,25 @@ * @file lldarray.h * @brief Wrapped std::vector for backward compatibility. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -56,6 +50,7 @@ public: }; LLDynamicArray(S32 size=0) : std::vector(size) { if (size < BlockSize) std::vector::reserve(BlockSize); } + LLDynamicArray(const std::vector& copy) : std::vector(copy) {} void reset() { std::vector::clear(); } diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 7b362b230..8b40edb40 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -3,31 +3,25 @@ * @date December 2006 * @brief error message system * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index c4865e947..f367d5e65 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -3,31 +3,25 @@ * @date December 2006 * @brief error message system * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,7 +35,7 @@ #include "stdtypes.h" -/* Error Logging Facility +/** Error Logging Facility Information for most users: @@ -54,7 +48,7 @@ using one of four "streams": LL_DEBUGS("StringTag") - debug messages that are normally suppressed - LL_INFOS("StringTag") - informational messages that are normally shown + LL_INFOS("StringTag") - informational messages that are normal shown LL_WARNS("StringTag") - warning messages that signal a problem LL_ERRS("StringTag") - error messages that are major, unrecoverable failures @@ -106,7 +100,6 @@ even release. Which means you can use them to help debug even when deployed to a real grid. */ - namespace LLError { enum ELevel diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index c6eb39cae..58a7c9f21 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -1,33 +1,27 @@ -/** +/** * @file llerrorcontrol.h * @date December 2006 * @brief error message system control * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,7 +38,7 @@ class LLSD; This is the part of the LLError namespace that manages the messages produced by the logging. The logging support is defined in llerror.h. Most files do not need to include this. - + These implementations are in llerror.cpp. */ @@ -105,30 +99,31 @@ namespace LLError // (by, for example, setting a class level to LEVEL_NONE), will keep // the that message from causing the fatal funciton to be invoked. - LL_COMMON_API FatalFunction getFatalFunction(); - // Retrieve the previously-set FatalFunction + LL_COMMON_API FatalFunction getFatalFunction(); + // Retrieve the previously-set FatalFunction - /// temporarily override the FatalFunction for the duration of a - /// particular scope, e.g. for unit tests - class LL_COMMON_API OverrideFatalFunction - { - public: - OverrideFatalFunction(const FatalFunction& func): - mPrev(getFatalFunction()) - { - setFatalFunction(func); - } - ~OverrideFatalFunction() - { - setFatalFunction(mPrev); - } + /// temporarily override the FatalFunction for the duration of a + /// particular scope, e.g. for unit tests + class LL_COMMON_API OverrideFatalFunction + { + public: + OverrideFatalFunction(const FatalFunction& func): + mPrev(getFatalFunction()) + { + setFatalFunction(func); + } + ~OverrideFatalFunction() + { + setFatalFunction(mPrev); + } + + private: + FatalFunction mPrev; + }; - private: - FatalFunction mPrev; - }; typedef std::string (*TimeFunction)(); LL_COMMON_API std::string utcTime(); - + LL_COMMON_API void setTimeFunction(TimeFunction); // The function is use to return the current time, formatted for // display by those error recorders that want the time included. @@ -140,19 +135,27 @@ namespace LLError // An object that handles the actual output or error messages. public: virtual ~Recorder(); - + virtual void recordMessage(LLError::ELevel, const std::string& message) = 0; // use the level for better display, not for filtering - + virtual bool wantsTime(); // default returns false // override and return true if the recorder wants the time string // included in the text of the message }; - + + /** + * @NOTE: addRecorder() conveys ownership to the underlying Settings + * object -- when destroyed, it will @em delete the passed Recorder*! + */ LL_COMMON_API void addRecorder(Recorder*); + /** + * @NOTE: removeRecorder() reclaims ownership of the Recorder*: its + * lifespan becomes the caller's problem. + */ LL_COMMON_API void removeRecorder(Recorder*); // each error message is passed to each recorder via recordMessage() - + LL_COMMON_API void logToFile(const std::string& filename); LL_COMMON_API void logToFixedBuffer(LLLineBuffer*); // Utilities to add recorders for logging to a file or a fixed buffer diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h index 278f781ae..146aa9206 100644 --- a/indra/llcommon/llerrorlegacy.h +++ b/indra/llcommon/llerrorlegacy.h @@ -3,31 +3,25 @@ * @date January 2007 * @brief old things from the older error system * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -124,6 +118,25 @@ const int LL_ERR_PRICE_MISMATCH = -23018; #define llverify(func) do {if (func) {}} while(0) #endif +// This can be used for function parameters that are only used by llassert. +// The ellipsis is needed in case the parameter contains comma's (ie, as part of the type, +// or trailing comma). The first version can be used as first (or only) parameter of a function, +// or as parameter in the middle when adding a trailing comma, while the second version can be +// used as last parameter. +// +// Example usage: +// +// void foo(ASSERT_ONLY(int x)); +// void foo(x, ASSERT_ONLY(int y,) int z); +// void foo(x/*,*/ ASSERT_ONLY_COMMA(int y)); // The optional /*,*/ makes it just a bit better readable. +#ifdef SHOW_ASSERT +#define ASSERT_ONLY(...) __VA_ARGS__ +#define ASSERT_ONLY_COMMA(...) , __VA_ARGS__ +#else +#define ASSERT_ONLY(...) +#define ASSERT_ONLY_COMMA(...) +#endif + // handy compile-time assert - enforce those template parameters! #define cassert(expn) typedef char __C_ASSERT__[(expn)?1:-1] /* Flawfinder: ignore */ //XXX: used in two places in llcommon/llskipmap.h diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp index da6f35089..e03faf0d1 100644 --- a/indra/llcommon/llerrorthread.cpp +++ b/indra/llcommon/llerrorthread.cpp @@ -1,31 +1,25 @@ /** * @file llerrorthread.cpp * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index 9bc61ccb5..480e94e43 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -444,13 +444,13 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL { // The new node isn't last. Place it between the previous node and // the successor. - newNode = (myprev + mydmi->second)/2.0; + 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.0; + newNode = std::ceil(myprev) + 1.f; } // Now that newNode has a value that places it appropriately in mSignal, // connect it. diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 0d8dce1eb..e0e9d3a27 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -1,75 +1,203 @@ -/** +/** * @file llfile.cpp * @author Michael Schlachter * @date 2006-03-23 * @brief Implementation of cross-platform POSIX file buffer and c++ * stream classes. * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ #if LL_WINDOWS #include +#include // Windows errno #else -#include +#include #endif #include "linden_common.h" #include "llfile.h" #include "llstring.h" #include "llerror.h" +#include "stringize.h" using namespace std; +static std::string empty; + +// Many of the methods below use OS-level functions that mess with errno. Wrap +// variants of strerror() to report errors. + +#if LL_WINDOWS +// On Windows, use strerror_s(). +std::string strerr(int errn) +{ + char buffer[256]; + strerror_s(buffer, errn); // infers sizeof(buffer) -- love it! + return buffer; +} + +typedef std::basic_ios > _Myios; + +#else +// On Posix we want to call strerror_r(), but alarmingly, there are two +// different variants. The one that returns int always populates the passed +// buffer (except in case of error), whereas the other one always returns a +// valid char* but might or might not populate the passed buffer. How do we +// know which one we're getting? Define adapters for each and let the compiler +// select the applicable adapter. + +// strerror_r() returns char* +std::string message_from(int /*orig_errno*/, const char* /*buffer*/, size_t /*bufflen*/, + const char* strerror_ret) +{ + return strerror_ret; +} + +// strerror_r() returns int +std::string message_from(int orig_errno, const char* buffer, size_t bufflen, + int strerror_ret) +{ + if (strerror_ret == 0) + { + return buffer; + } + // Here strerror_r() has set errno. Since strerror_r() has already failed, + // seems like a poor bet to call it again to diagnose its own error... + int stre_errno = errno; + if (stre_errno == ERANGE) + { + return STRINGIZE("strerror_r() can't explain errno " << orig_errno + << " (" << bufflen << "-byte buffer too small)"); + } + if (stre_errno == EINVAL) + { + return STRINGIZE("unknown errno " << orig_errno); + } + // Here we don't even understand the errno from strerror_r()! + return STRINGIZE("strerror_r() can't explain errno " << orig_errno + << " (error " << stre_errno << ')'); +} + +std::string strerr(int errn) +{ + char buffer[256]; + // Select message_from() function matching the strerror_r() we have on hand. + return message_from(errn, buffer, sizeof(buffer), + strerror_r(errn, buffer, sizeof(buffer))); +} +#endif // ! LL_WINDOWS + +// On either system, shorthand call just infers global 'errno'. +std::string strerr() +{ + return strerr(errno); +} + +int warnif(const std::string& desc, const std::string& filename, int rc, int accept=0) +{ + if (rc < 0) + { + // Capture errno before we start emitting output + int errn = errno; + // For certain operations, a particular errno value might be + // acceptable -- e.g. stat() could permit ENOENT, mkdir() could permit + // EEXIST. Don't warn if caller explicitly says this errno is okay. + if (errn != accept) + { + LL_WARNS("LLFile") << "Couldn't " << desc << " '" << filename + << "' (errno " << errn << "): " << strerr(errn) << LL_ENDL; + } +#if 0 && LL_WINDOWS // turn on to debug file-locking problems + // If the problem is "Permission denied," maybe it's because another + // process has the file open. Try to find out. + if (errn == EACCES) // *not* EPERM + { + // Only do any of this stuff (before LL_ENDL) if it will be logged. + LL_DEBUGS("LLFile") << empty; + const char* TEMP = getenv("TEMP"); + if (! TEMP) + { + LL_CONT << "No $TEMP, not running 'handle'"; + } + else + { + std::string tf(TEMP); + tf += "\\handle.tmp"; + // http://technet.microsoft.com/en-us/sysinternals/bb896655 + std::string cmd(STRINGIZE("handle \"" << filename + // "openfiles /query /v | fgrep -i \"" << filename + << "\" > \"" << tf << '"')); + LL_CONT << cmd; + if (system(cmd.c_str()) != 0) + { + LL_CONT << "\nDownload 'handle.exe' from http://technet.microsoft.com/en-us/sysinternals/bb896655"; + } + else + { + std::ifstream inf(tf); + std::string line; + while (std::getline(inf, line)) + { + LL_CONT << '\n' << line; + } + } + LLFile::remove(tf); + } + LL_CONT << LL_ENDL; + } +#endif // LL_WINDOWS hack to identify processes holding file open + } + return rc; +} + // static int LLFile::mkdir(const std::string& dirname, int perms) { -#if LL_WINDOWS +#if LL_WINDOWS // permissions are ignored on Windows std::string utf8dirname = dirname; llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname); - return _wmkdir(utf16dirname.c_str()); + int rc = _wmkdir(utf16dirname.c_str()); #else - return ::mkdir(dirname.c_str(), (mode_t)perms); + int rc = ::mkdir(dirname.c_str(), (mode_t)perms); #endif + // We often use mkdir() to ensure the existence of a directory that might + // already exist. Don't spam the log if it does. + return warnif("mkdir", dirname, rc, EEXIST); } // static int LLFile::rmdir(const std::string& dirname) { -#if LL_WINDOWS +#if LL_WINDOWS // permissions are ignored on Windows std::string utf8dirname = dirname; llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname); - return _wrmdir(utf16dirname.c_str()); + int rc = _wrmdir(utf16dirname.c_str()); #else - return ::rmdir(dirname.c_str()); + int rc = ::rmdir(dirname.c_str()); #endif + return warnif("rmdir", dirname, rc); } // static @@ -116,10 +244,11 @@ int LLFile::remove(const std::string& filename) #if LL_WINDOWS std::string utf8filename = filename; llutf16string utf16filename = utf8str_to_utf16str(utf8filename); - return _wremove(utf16filename.c_str()); + int rc = _wremove(utf16filename.c_str()); #else - return ::remove(filename.c_str()); + int rc = ::remove(filename.c_str()); #endif + return warnif("remove", filename, rc); } int LLFile::rename(const std::string& filename, const std::string& newname) @@ -129,10 +258,11 @@ int LLFile::rename(const std::string& filename, const std::string& newname) std::string utf8newname = newname; llutf16string utf16filename = utf8str_to_utf16str(utf8filename); llutf16string utf16newname = utf8str_to_utf16str(utf8newname); - return _wrename(utf16filename.c_str(),utf16newname.c_str()); + int rc = _wrename(utf16filename.c_str(),utf16newname.c_str()); #else - return ::rename(filename.c_str(),newname.c_str()); + int rc = ::rename(filename.c_str(),newname.c_str()); #endif + return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc); } int LLFile::stat(const std::string& filename, llstat* filestatus) @@ -140,23 +270,26 @@ int LLFile::stat(const std::string& filename, llstat* filestatus) #if LL_WINDOWS std::string utf8filename = filename; llutf16string utf16filename = utf8str_to_utf16str(utf8filename); - return _wstat(utf16filename.c_str(),filestatus); + int rc = _wstat(utf16filename.c_str(),filestatus); #else - return ::stat(filename.c_str(),filestatus); + int rc = ::stat(filename.c_str(),filestatus); #endif + // We use stat() to determine existence (see isfile(), isdir()). + // Don't spam the log if the subject pathname doesn't exist. + return warnif("stat", filename, rc, ENOENT); } bool LLFile::isdir(const std::string& filename) { llstat st; - + return stat(filename, &st) == 0 && S_ISDIR(st.st_mode); } bool LLFile::isfile(const std::string& filename) { llstat st; - + return stat(filename, &st) == 0 && S_ISREG(st.st_mode); } @@ -193,9 +326,10 @@ const char *LLFile::tmpdir() /***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/ -#if USE_LLFILESTREAMS +#if LL_WINDOWS -LLFILE * LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,int) // protection currently unused +LLFILE * LLFile::_Fiopen(const std::string& filename, + std::ios::openmode mode) { // open a file static const char *mods[] = { // fopen mode strings corresponding to valid[i] @@ -254,118 +388,682 @@ LLFILE * LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,in return (0); } +#endif /* LL_WINDOWS */ + +/************** llstdio file buffer ********************************/ + + +//llstdio_filebuf* llstdio_filebuf::open(const char *_Filename, +// ios_base::openmode _Mode) +//{ +//#if LL_WINDOWS +// _Filet *_File; +// if (is_open() || (_File = LLFILE::_Fiopen(_Filename, _Mode)) == 0) +// return (0); // open failed +// +// _Init(_File, _Openfl); +// _Initcvt(&_USE(_Mysb::getloc(), _Cvt)); +// return (this); // open succeeded +//#else +// std::filebuf* _file = std::filebuf::open(_Filename, _Mode); +// if (NULL == _file) return NULL; +// return this; +//#endif +//} + + +// *TODO: Seek the underlying c stream for better cross-platform compatibility? +#if !LL_WINDOWS +llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __c) +{ + int_type __ret = traits_type::eof(); + const bool __testeof = traits_type::eq_int_type(__c, __ret); + const bool __testout = _M_mode & ios_base::out; + if (__testout && !_M_reading) + { + if (this->pbase() < this->pptr()) + { + // If appropriate, append the overflow char. + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + + // Convert pending sequence to external representation, + // and output. + if (_convert_to_external(this->pbase(), + this->pptr() - this->pbase())) + { + _M_set_buffer(0); + __ret = traits_type::not_eof(__c); + } + } + else if (_M_buf_size > 1) + { + // Overflow in 'uncommitted' mode: set _M_writing, set + // the buffer to the initial 'write' mode, and put __c + // into the buffer. + _M_set_buffer(0); + _M_writing = true; + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + __ret = traits_type::not_eof(__c); + } + else + { + // Unbuffered. + char_type __conv = traits_type::to_char_type(__c); + if (__testeof || _convert_to_external(&__conv, 1)) + { + _M_writing = true; + __ret = traits_type::not_eof(__c); + } + } + } + return __ret; +} + +bool llstdio_filebuf::_convert_to_external(char_type* __ibuf, + std::streamsize __ilen) +{ + // Sizes of external and pending output. + streamsize __elen; + streamsize __plen; + if (__check_facet(_M_codecvt).always_noconv()) + { + //__elen = _M_file.xsputn(reinterpret_cast(__ibuf), __ilen); + __elen = fwrite(reinterpret_cast(__ibuf), 1, + __ilen, _M_file.file()); + __plen = __ilen; + } + else + { + // Worst-case number of external bytes needed. + // XXX Not done encoding() == -1. + streamsize __blen = __ilen * _M_codecvt->max_length(); + char* __buf = static_cast(__builtin_alloca(__blen)); + + char* __bend; + const char_type* __iend; + codecvt_base::result __r; + __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen, + __iend, __buf, __buf + __blen, __bend); + + if (__r == codecvt_base::ok || __r == codecvt_base::partial) + __blen = __bend - __buf; + else if (__r == codecvt_base::noconv) + { + // Same as the always_noconv case above. + __buf = reinterpret_cast(__ibuf); + __blen = __ilen; + } + else + __throw_ios_failure(__N("llstdio_filebuf::_convert_to_external " + "conversion error")); + + //__elen = _M_file.xsputn(__buf, __blen); + __elen = fwrite(__buf, 1, __blen, _M_file.file()); + __plen = __blen; + + // Try once more for partial conversions. + if (__r == codecvt_base::partial && __elen == __plen) + { + const char_type* __iresume = __iend; + streamsize __rlen = this->pptr() - __iend; + __r = _M_codecvt->out(_M_state_cur, __iresume, + __iresume + __rlen, __iend, __buf, + __buf + __blen, __bend); + if (__r != codecvt_base::error) + { + __rlen = __bend - __buf; + //__elen = _M_file.xsputn(__buf, __rlen); + __elen = fwrite(__buf, 1, __rlen, _M_file.file()); + __plen = __rlen; + } + else + { + __throw_ios_failure(__N("llstdio_filebuf::_convert_to_external " + "conversion error")); + } + } + } + return __elen == __plen; +} + +llstdio_filebuf::int_type llstdio_filebuf::underflow() +{ + int_type __ret = traits_type::eof(); + const bool __testin = _M_mode & ios_base::in; + if (__testin) + { + if (_M_writing) + { + if (overflow() == traits_type::eof()) + return __ret; + //_M_set_buffer(-1); + //_M_writing = false; + } + // Check for pback madness, and if so switch back to the + // normal buffers and jet outta here before expensive + // fileops happen... + _M_destroy_pback(); + + if (this->gptr() < this->egptr()) + return traits_type::to_int_type(*this->gptr()); + + // Get and convert input sequence. + const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; + + // Will be set to true if ::fread() returns 0 indicating EOF. + bool __got_eof = false; + // Number of internal characters produced. + streamsize __ilen = 0; + codecvt_base::result __r = codecvt_base::ok; + if (__check_facet(_M_codecvt).always_noconv()) + { + //__ilen = _M_file.xsgetn(reinterpret_cast(this->eback()), + // __buflen); + __ilen = fread(reinterpret_cast(this->eback()), 1, + __buflen, _M_file.file()); + if (__ilen == 0) + __got_eof = true; + } + else + { + // Worst-case number of external bytes. + // XXX Not done encoding() == -1. + const int __enc = _M_codecvt->encoding(); + streamsize __blen; // Minimum buffer size. + streamsize __rlen; // Number of chars to read. + if (__enc > 0) + __blen = __rlen = __buflen * __enc; + else + { + __blen = __buflen + _M_codecvt->max_length() - 1; + __rlen = __buflen; + } + const streamsize __remainder = _M_ext_end - _M_ext_next; + __rlen = __rlen > __remainder ? __rlen - __remainder : 0; + + // An imbue in 'read' mode implies first converting the external + // chars already present. + if (_M_reading && this->egptr() == this->eback() && __remainder) + __rlen = 0; + + // Allocate buffer if necessary and move unconverted + // bytes to front. + if (_M_ext_buf_size < __blen) + { + char* __buf = new char[__blen]; + if (__remainder) + __builtin_memcpy(__buf, _M_ext_next, __remainder); + + delete [] _M_ext_buf; + _M_ext_buf = __buf; + _M_ext_buf_size = __blen; + } + else if (__remainder) + __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder); + + _M_ext_next = _M_ext_buf; + _M_ext_end = _M_ext_buf + __remainder; + _M_state_last = _M_state_cur; + + do + { + if (__rlen > 0) + { + // Sanity check! + // This may fail if the return value of + // codecvt::max_length() is bogus. + if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size) + { + __throw_ios_failure(__N("llstdio_filebuf::underflow " + "codecvt::max_length() " + "is not valid")); + } + //streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen); + streamsize __elen = fread(_M_ext_end, 1, + __rlen, _M_file.file()); + if (__elen == 0) + __got_eof = true; + else if (__elen == -1) + break; + //_M_ext_end += __elen; + } + + char_type* __iend = this->eback(); + if (_M_ext_next < _M_ext_end) + { + __r = _M_codecvt->in(_M_state_cur, _M_ext_next, + _M_ext_end, _M_ext_next, + this->eback(), + this->eback() + __buflen, __iend); + } + if (__r == codecvt_base::noconv) + { + size_t __avail = _M_ext_end - _M_ext_buf; + __ilen = std::min(__avail, __buflen); + traits_type::copy(this->eback(), + reinterpret_cast + (_M_ext_buf), __ilen); + _M_ext_next = _M_ext_buf + __ilen; + } + else + __ilen = __iend - this->eback(); + + // _M_codecvt->in may return error while __ilen > 0: this is + // ok, and actually occurs in case of mixed encodings (e.g., + // XML files). + if (__r == codecvt_base::error) + break; + + __rlen = 1; + } while (__ilen == 0 && !__got_eof); + } + + if (__ilen > 0) + { + _M_set_buffer(__ilen); + _M_reading = true; + __ret = traits_type::to_int_type(*this->gptr()); + } + else if (__got_eof) + { + // If the actual end of file is reached, set 'uncommitted' + // mode, thus allowing an immediate write without an + // intervening seek. + _M_set_buffer(-1); + _M_reading = false; + // However, reaching it while looping on partial means that + // the file has got an incomplete character. + if (__r == codecvt_base::partial) + __throw_ios_failure(__N("llstdio_filebuf::underflow " + "incomplete character in file")); + } + else if (__r == codecvt_base::error) + __throw_ios_failure(__N("llstdio_filebuf::underflow " + "invalid byte sequence in file")); + else + __throw_ios_failure(__N("llstdio_filebuf::underflow " + "error reading the file")); + } + return __ret; +} + +std::streamsize llstdio_filebuf::xsgetn(char_type* __s, std::streamsize __n) +{ + // Clear out pback buffer before going on to the real deal... + streamsize __ret = 0; + if (_M_pback_init) + { + if (__n > 0 && this->gptr() == this->eback()) + { + *__s++ = *this->gptr(); + this->gbump(1); + __ret = 1; + --__n; + } + _M_destroy_pback(); + } + + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n > __buflen we read directly instead of using the + // buffer repeatedly. + const bool __testin = _M_mode & ios_base::in; + const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; + + if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() + && __testin && !_M_writing) + { + // First, copy the chars already present in the buffer. + const streamsize __avail = this->egptr() - this->gptr(); + if (__avail != 0) + { + if (__avail == 1) + *__s = *this->gptr(); + else + traits_type::copy(__s, this->gptr(), __avail); + __s += __avail; + this->gbump(__avail); + __ret += __avail; + __n -= __avail; + } + + // Need to loop in case of short reads (relatively common + // with pipes). + streamsize __len; + for (;;) + { + //__len = _M_file.xsgetn(reinterpret_cast(__s), __n); + __len = fread(reinterpret_cast(__s), 1, + __n, _M_file.file()); + if (__len == -1) + __throw_ios_failure(__N("llstdio_filebuf::xsgetn " + "error reading the file")); + if (__len == 0) + break; + + __n -= __len; + __ret += __len; + if (__n == 0) + break; + + __s += __len; + } + + if (__n == 0) + { + _M_set_buffer(0); + _M_reading = true; + } + else if (__len == 0) + { + // If end of file is reached, set 'uncommitted' + // mode, thus allowing an immediate write without + // an intervening seek. + _M_set_buffer(-1); + _M_reading = false; + } + } + else + __ret += __streambuf_type::xsgetn(__s, __n); + + return __ret; +} + +std::streamsize llstdio_filebuf::xsputn(char_type const* __s, std::streamsize __n) +{ + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n is sufficiently large we write directly instead of + // using the buffer. + streamsize __ret = 0; + const bool __testout = _M_mode & ios_base::out; + if (__check_facet(_M_codecvt).always_noconv() + && __testout && !_M_reading) + { + // Measurement would reveal the best choice. + const streamsize __chunk = 1ul << 10; + streamsize __bufavail = this->epptr() - this->pptr(); + + // Don't mistake 'uncommitted' mode buffered with unbuffered. + if (!_M_writing && _M_buf_size > 1) + __bufavail = _M_buf_size - 1; + + const streamsize __limit = std::min(__chunk, __bufavail); + if (__n >= __limit) + { + const streamsize __buffill = this->pptr() - this->pbase(); + const char* __buf = reinterpret_cast(this->pbase()); + //__ret = _M_file.xsputn_2(__buf, __buffill, + // reinterpret_cast(__s), __n); + if (__buffill) + { + __ret = fwrite(__buf, 1, __buffill, _M_file.file()); + } + if (__ret == __buffill) + { + __ret += fwrite(reinterpret_cast(__s), 1, + __n, _M_file.file()); + } + if (__ret == __buffill + __n) + { + _M_set_buffer(0); + _M_writing = true; + } + if (__ret > __buffill) + __ret -= __buffill; + else + __ret = 0; + } + else + __ret = __streambuf_type::xsputn(__s, __n); + } + else + __ret = __streambuf_type::xsputn(__s, __n); + return __ret; +} + +int llstdio_filebuf::sync() +{ + return (_M_file.sync() == 0 ? 0 : -1); +} +#endif + /************** input file stream ********************************/ -void llifstream::close() -{ // close the C stream - if (_Filebuffer && _Filebuffer->close() == 0) - { - _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/ - } -} -void llifstream::open(const std::string& _Filename, /* Flawfinder: ignore */ - ios_base::openmode _Mode, - int _Prot) -{ // open a C stream with specified mode - - LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::in, _Prot); - if(filep == NULL) - { - _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/ - return; - } - llassert(_Filebuffer == NULL); - _Filebuffer = new _Myfb(filep); - _ShouldClose = true; - _Myios::init(_Filebuffer); +llifstream::llifstream() : _M_filebuf(), +#if LL_WINDOWS + std::istream(&_M_filebuf) {} +#else + std::istream() +{ + this->init(&_M_filebuf); } +#endif + +// explicit +llifstream::llifstream(const std::string& _Filename, + ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS + std::istream(&_M_filebuf) +{ + if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0) + { + _Myios::setstate(ios_base::failbit); + } +} +#else + std::istream() +{ + this->init(&_M_filebuf); + this->open(_Filename.c_str(), _Mode | ios_base::in); +} +#endif + +// explicit +llifstream::llifstream(const char* _Filename, + ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS + std::istream(&_M_filebuf) +{ + if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0) + { + _Myios::setstate(ios_base::failbit); + } +} +#else + std::istream() +{ + this->init(&_M_filebuf); + this->open(_Filename, _Mode | ios_base::in); +} +#endif + + +// explicit +llifstream::llifstream(_Filet *_File, + ios_base::openmode _Mode, size_t _Size) : + _M_filebuf(_File, _Mode, _Size), +#if LL_WINDOWS + std::istream(&_M_filebuf) {} +#else + std::istream() +{ + this->init(&_M_filebuf); +} +#endif + +#if !LL_WINDOWS +// explicit +llifstream::llifstream(int __fd, + ios_base::openmode _Mode, size_t _Size) : + _M_filebuf(__fd, _Mode, _Size), + std::istream() +{ + this->init(&_M_filebuf); +} +#endif bool llifstream::is_open() const { // test if C stream has been opened - if(_Filebuffer) - return (_Filebuffer->is_open()); - return false; + return _M_filebuf.is_open(); } -llifstream::~llifstream() -{ - if (_ShouldClose) + +void llifstream::open(const char* _Filename, ios_base::openmode _Mode) +{ // open a C stream with specified mode + if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0) +#if LL_WINDOWS { - close(); + _Myios::setstate(ios_base::failbit); } - delete _Filebuffer; + else + { + _Myios::clear(); + } +#else + { + this->setstate(ios_base::failbit); + } + else + { + this->clear(); + } +#endif } -llifstream::llifstream(const std::string& _Filename, - ios_base::openmode _Mode, - int _Prot) - : std::basic_istream< char , std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) - -{ // construct with named file and specified mode - open(_Filename, _Mode | ios_base::in, _Prot); /* Flawfinder: ignore */ +void llifstream::close() +{ // close the C stream + if (_M_filebuf.close() == 0) + { +#if LL_WINDOWS + _Myios::setstate(ios_base::failbit); +#else + this->setstate(ios_base::failbit); +#endif + } } /************** output file stream ********************************/ + +llofstream::llofstream() : _M_filebuf(), +#if LL_WINDOWS + std::ostream(&_M_filebuf) {} +#else + std::ostream() +{ + this->init(&_M_filebuf); +} +#endif + +// explicit +llofstream::llofstream(const std::string& _Filename, + ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS + std::ostream(&_M_filebuf) +{ + if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0) + { + _Myios::setstate(ios_base::failbit); + } +} +#else + std::ostream() +{ + this->init(&_M_filebuf); + this->open(_Filename.c_str(), _Mode | ios_base::out); +} +#endif + +// explicit +llofstream::llofstream(const char* _Filename, + ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS + std::ostream(&_M_filebuf) +{ + if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0) + { + _Myios::setstate(ios_base::failbit); + } +} +#else + std::ostream() +{ + this->init(&_M_filebuf); + this->open(_Filename, _Mode | ios_base::out); +} +#endif + +// explicit +llofstream::llofstream(_Filet *_File, + ios_base::openmode _Mode, size_t _Size) : + _M_filebuf(_File, _Mode, _Size), +#if LL_WINDOWS + std::ostream(&_M_filebuf) {} +#else + std::ostream() +{ + this->init(&_M_filebuf); +} +#endif + +#if !LL_WINDOWS +// explicit +llofstream::llofstream(int __fd, + ios_base::openmode _Mode, size_t _Size) : + _M_filebuf(__fd, _Mode, _Size), + std::ostream() +{ + this->init(&_M_filebuf); +} +#endif + bool llofstream::is_open() const { // test if C stream has been opened - if(_Filebuffer) - return (_Filebuffer->is_open()); - return false; + return _M_filebuf.is_open(); } -void llofstream::open(const std::string& _Filename, /* Flawfinder: ignore */ - ios_base::openmode _Mode, - int _Prot) +void llofstream::open(const char* _Filename, ios_base::openmode _Mode) { // open a C stream with specified mode - - LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::out, _Prot); - if(filep == NULL) + if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0) +#if LL_WINDOWS { - _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/ - return; + _Myios::setstate(ios_base::failbit); } - llassert(_Filebuffer==NULL); - _Filebuffer = new _Myfb(filep); - _ShouldClose = true; - _Myios::init(_Filebuffer); + else + { + _Myios::clear(); + } +#else + { + this->setstate(ios_base::failbit); + } + else + { + this->clear(); + } +#endif } void llofstream::close() { // close the C stream - if(is_open()) + if (_M_filebuf.close() == 0) { - if (_Filebuffer->close() == 0) - { - _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/ - } - delete _Filebuffer; - _Filebuffer = NULL; - _ShouldClose = false; +#if LL_WINDOWS + _Myios::setstate(ios_base::failbit); +#else + this->setstate(ios_base::failbit); +#endif } } -llofstream::llofstream(const std::string& _Filename, - std::ios_base::openmode _Mode, - int _Prot) - : std::basic_ostream >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) -{ // construct with named file and specified mode - open(_Filename, _Mode , _Prot); /* Flawfinder: ignore */ -} - -llofstream::~llofstream() -{ - // destroy the object - if (_ShouldClose) - { - close(); - } - delete _Filebuffer; -} - -#endif // #if USE_LLFILESTREAMS - /************** helper functions ********************************/ std::streamsize llifstream_size(llifstream& ifstr) diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 0c16e55de..6d2bb8f13 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -5,31 +5,25 @@ * @brief Declaration of cross-platform POSIX file buffer and c++ * stream classes. * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,16 +35,9 @@ * Attempts to mostly mirror the POSIX style IO functions. */ -typedef FILE LLFILE; +typedef FILE LLFILE; #include - -#ifdef LL_WINDOWS -#define USE_LLFILESTREAMS 1 -#else -#define USE_LLFILESTREAMS 0 -#endif - #include #if LL_WINDOWS @@ -58,6 +45,8 @@ typedef FILE LLFILE; typedef struct _stat llstat; #else typedef struct stat llstat; +#include +#include #endif #ifndef S_ISREG @@ -89,145 +78,345 @@ public: static int stat(const std::string& filename,llstat* file_status); static bool isdir(const std::string& filename); static bool isfile(const std::string& filename); - static LLFILE * _Fiopen(const std::string& filename, std::ios::openmode mode,int); // protection currently unused + static LLFILE * _Fiopen(const std::string& filename, + std::ios::openmode mode); static const char * tmpdir(); }; +/** + * @brief Provides a layer of compatibility for C/POSIX. + * + * This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and + * VC's basic_filebuf implementation. + * This file buffer provides extensions for working with standard C FILE*'s + * and POSIX file descriptors for platforms that support this. +*/ +namespace +{ +#if LL_WINDOWS +typedef std::filebuf _Myfb; +#else +typedef __gnu_cxx::stdio_filebuf< char > _Myfb; +typedef std::__c_file _Filet; +#endif /* LL_WINDOWS */ +} -#if USE_LLFILESTREAMS +class LL_COMMON_API llstdio_filebuf : public _Myfb +{ +public: + /** + * deferred initialization / destruction + */ + llstdio_filebuf() : _Myfb() {} + virtual ~llstdio_filebuf() {} -class LL_COMMON_API llifstream : public std::basic_istream < char , std::char_traits < char > > + /** + * @param f An open @c FILE*. + * @param mode Same meaning as in a standard filebuf. + * @param size Optimal or preferred size of internal buffer, in chars. + * Defaults to system's @c BUFSIZ. + * + * This constructor associates a file stream buffer with an open + * C @c FILE*. The @c FILE* will not be automatically closed when the + * stdio_filebuf is closed/destroyed. + */ + llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode, + //size_t __size = static_cast(BUFSIZ)) : + size_t __size = static_cast(1)) : +#if LL_WINDOWS + _Myfb(__f) {} +#else + _Myfb(__f, __mode, __size) {} +#endif + + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * @return @c this on success, NULL on failure + * + * If a file is already open, this function immediately fails. + * Otherwise it tries to open the file named @a s using the flags + * given in @a mode. + */ + //llstdio_filebuf* open(const char *_Filename, + // std::ios_base::openmode _Mode); + + /** + * @param fd An open file descriptor. + * @param mode Same meaning as in a standard filebuf. + * @param size Optimal or preferred size of internal buffer, in chars. + * + * This constructor associates a file stream buffer with an open + * POSIX file descriptor. The file descriptor will be automatically + * closed when the stdio_filebuf is closed/destroyed. + */ +#if !LL_WINDOWS + llstdio_filebuf(int __fd, std::ios_base::openmode __mode, + //size_t __size = static_cast(BUFSIZ)) : + size_t __size = static_cast(1)) : + _Myfb(__fd, __mode, __size) {} +#endif + +// *TODO: Seek the underlying c stream for better cross-platform compatibility? +#if !LL_WINDOWS +protected: + /** underflow() and uflow() functions are called to get the next + * character from the real input source when the buffer is empty. + * Buffered input uses underflow() + */ + /*virtual*/ int_type underflow(); + + /* Convert internal byte sequence to external, char-based + * sequence via codecvt. + */ + bool _convert_to_external(char_type*, std::streamsize); + + /** The overflow() function is called to transfer characters to the + * real output destination when the buffer is full. A call to + * overflow(c) outputs the contents of the buffer plus the + * character c. + * Consume some sequence of the characters in the pending sequence. + */ + /*virtual*/ int_type overflow(int_type __c = traits_type::eof()); + + /** sync() flushes the underlying @c FILE* stream. + */ + /*virtual*/ int sync(); + + std::streamsize xsgetn(char_type*, std::streamsize); + std::streamsize xsputn(char_type const*, std::streamsize); +#endif +}; + + +/** + * @brief Controlling input for files. + * + * This class supports reading from named files, using the inherited + * functions from std::basic_istream. To control the associated + * sequence, an instance of std::basic_filebuf (or a platform-specific derivative) + * which allows construction using a pre-exisintg file stream buffer. + * We refer to this std::basic_filebuf (or derivative) as @c sb. +*/ +class LL_COMMON_API llifstream : public std::istream { // input stream associated with a C stream public: - typedef std::basic_ifstream > _Myt; - typedef std::basic_filebuf > _Myfb; - typedef std::basic_ios > _Myios; - - llifstream() - : std::basic_istream >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) - { // construct unopened - } + // Constructors: + /** + * @brief Default constructor. + * + * Initializes @c sb using its default constructor, and passes + * @c &sb to the base class initializer. Does not open any files + * (you haven't given it a filename to open). + */ + llifstream(); + /** + * @brief Create an input file stream. + * @param Filename String specifying the filename. + * @param Mode Open file in specified mode (see std::ios_base). + * + * @c ios_base::in is automatically included in @a mode. + */ explicit llifstream(const std::string& _Filename, - ios_base::openmode _Mode = ios_base::in, - int _Prot = (int)ios_base::_Openprot); + ios_base::openmode _Mode = ios_base::in); + explicit llifstream(const char* _Filename, + ios_base::openmode _Mode = ios_base::in); - explicit llifstream(_Filet *_File) - : std::basic_istream >(NULL,true), - _Filebuffer(new _Myfb(_File)), - _ShouldClose(false) - { // construct with specified C stream - } - virtual ~llifstream(); - - _Myfb *rdbuf() const - { // return pointer to file buffer - return _Filebuffer; - } - bool is_open() const; - void open(const std::string& _Filename, /* Flawfinder: ignore */ - ios_base::openmode _Mode = ios_base::in, - int _Prot = (int)ios_base::_Openprot); - void close(); - -private: - _Myfb* _Filebuffer; // the file buffer - bool _ShouldClose; -}; - - -class LL_COMMON_API llofstream : public std::basic_ostream< char , std::char_traits < char > > -{ -public: - typedef std::basic_ostream< char , std::char_traits < char > > _Myt; - typedef std::basic_filebuf< char , std::char_traits < char > > _Myfb; - typedef std::basic_ios > _Myios; - - llofstream() - : std::basic_ostream >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) - { // construct unopened - } - - explicit llofstream(const std::string& _Filename, - std::ios_base::openmode _Mode = ios_base::out, - int _Prot = (int)std::ios_base::_Openprot); - - - explicit llofstream(_Filet *_File) - : std::basic_ostream >(NULL,true), - _Filebuffer(new _Myfb(_File)),//_File) - _ShouldClose(false) - { // construct with specified C stream - } - - virtual ~llofstream(); - - _Myfb *rdbuf() const - { // return pointer to file buffer - return _Filebuffer; - } - - bool is_open() const; - - void open(const std::string& _Filename,ios_base::openmode _Mode = ios_base::out,int _Prot = (int)ios_base::_Openprot); /* Flawfinder: ignore */ - - void close(); - -private: - _Myfb *_Filebuffer; // the file buffer - bool _ShouldClose; -}; - - - -#else -//Use standard file streams on non windows platforms -//#define llifstream std::ifstream -//#define llofstream std::ofstream - -class LL_COMMON_API llifstream : public std::ifstream -{ -public: - llifstream() : std::ifstream() - { - } - - explicit llifstream(const std::string& _Filename, std::_Ios_Openmode _Mode = in) - : std::ifstream(_Filename.c_str(), _Mode) - { - } - void open(const std::string& _Filename, std::_Ios_Openmode _Mode = in) /* Flawfinder: ignore */ - { - std::ifstream::open(_Filename.c_str(), _Mode); - } -}; - - -class LL_COMMON_API llofstream : public std::ofstream -{ -public: - llofstream() : std::ofstream() - { - } - - explicit llofstream(const std::string& _Filename, std::_Ios_Openmode _Mode = out) - : std::ofstream(_Filename.c_str(), _Mode) - { - } - - void open(const std::string& _Filename, std::_Ios_Openmode _Mode = out) /* Flawfinder: ignore */ - { - std::ofstream::open(_Filename.c_str(), _Mode); - } - -}; + /** + * @brief Create a stream using an open c file stream. + * @param File An open @c FILE*. + @param Mode Same meaning as in a standard filebuf. + @param Size Optimal or preferred size of internal buffer, in chars. + Defaults to system's @c BUFSIZ. + */ + explicit llifstream(_Filet *_File, + ios_base::openmode _Mode = ios_base::in, + //size_t _Size = static_cast(BUFSIZ)); + size_t _Size = static_cast(1)); + /** + * @brief Create a stream using an open file descriptor. + * @param fd An open file descriptor. + @param Mode Same meaning as in a standard filebuf. + @param Size Optimal or preferred size of internal buffer, in chars. + Defaults to system's @c BUFSIZ. + */ +#if !LL_WINDOWS + explicit llifstream(int __fd, + ios_base::openmode _Mode = ios_base::in, + //size_t _Size = static_cast(BUFSIZ)); + size_t _Size = static_cast(1)); #endif + /** + * @brief The destructor does nothing. + * + * The file is closed by the filebuf object, not the formatting + * stream. + */ + virtual ~llifstream() {} + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_filebuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + llstdio_filebuf* rdbuf() const + { return const_cast(&_M_filebuf); } + + /** + * @brief Wrapper to test for an open file. + * @return @c rdbuf()->is_open() + */ + bool is_open() const; + + /** + * @brief Opens an external file. + * @param Filename The name of the file. + * @param Node The open mode flags. + * + * Calls @c llstdio_filebuf::open(s,mode|in). If that function + * fails, @c failbit is set in the stream's error state. + */ + void open(const std::string& _Filename, + ios_base::openmode _Mode = ios_base::in) + { open(_Filename.c_str(), _Mode); } + void open(const char* _Filename, + ios_base::openmode _Mode = ios_base::in); + + /** + * @brief Close the file. + * + * Calls @c llstdio_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ + void close(); + +private: + llstdio_filebuf _M_filebuf; +}; + + /** - * @brief filesize helpers. + * @brief Controlling output for files. + * + * This class supports writing to named files, using the inherited + * functions from std::basic_ostream. To control the associated + * sequence, an instance of std::basic_filebuf (or a platform-specific derivative) + * which allows construction using a pre-exisintg file stream buffer. + * We refer to this std::basic_filebuf (or derivative) as @c sb. +*/ +class LL_COMMON_API llofstream : public std::ostream +{ +public: + // Constructors: + /** + * @brief Default constructor. + * + * Initializes @c sb using its default constructor, and passes + * @c &sb to the base class initializer. Does not open any files + * (you haven't given it a filename to open). + */ + llofstream(); + + /** + * @brief Create an output file stream. + * @param Filename String specifying the filename. + * @param Mode Open file in specified mode (see std::ios_base). + * + * @c ios_base::out|ios_base::trunc is automatically included in + * @a mode. + */ + explicit llofstream(const std::string& _Filename, + ios_base::openmode _Mode = ios_base::out|ios_base::trunc); + explicit llofstream(const char* _Filename, + ios_base::openmode _Mode = ios_base::out|ios_base::trunc); + + /** + * @brief Create a stream using an open c file stream. + * @param File An open @c FILE*. + @param Mode Same meaning as in a standard filebuf. + @param Size Optimal or preferred size of internal buffer, in chars. + Defaults to system's @c BUFSIZ. + */ + explicit llofstream(_Filet *_File, + ios_base::openmode _Mode = ios_base::out, + //size_t _Size = static_cast(BUFSIZ)); + size_t _Size = static_cast(1)); + + /** + * @brief Create a stream using an open file descriptor. + * @param fd An open file descriptor. + @param Mode Same meaning as in a standard filebuf. + @param Size Optimal or preferred size of internal buffer, in chars. + Defaults to system's @c BUFSIZ. + */ +#if !LL_WINDOWS + explicit llofstream(int __fd, + ios_base::openmode _Mode = ios_base::out, + //size_t _Size = static_cast(BUFSIZ)); + size_t _Size = static_cast(1)); +#endif + + /** + * @brief The destructor does nothing. + * + * The file is closed by the filebuf object, not the formatting + * stream. + */ + virtual ~llofstream() {} + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_filebuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + llstdio_filebuf* rdbuf() const + { return const_cast(&_M_filebuf); } + + /** + * @brief Wrapper to test for an open file. + * @return @c rdbuf()->is_open() + */ + bool is_open() const; + + /** + * @brief Opens an external file. + * @param Filename The name of the file. + * @param Node The open mode flags. + * + * Calls @c llstdio_filebuf::open(s,mode|out). If that function + * fails, @c failbit is set in the stream's error state. + */ + void open(const std::string& _Filename, + ios_base::openmode _Mode = ios_base::out|ios_base::trunc) + { open(_Filename.c_str(), _Mode); } + void open(const char* _Filename, + ios_base::openmode _Mode = ios_base::out|ios_base::trunc); + + /** + * @brief Close the file. + * + * Calls @c llstdio_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ + void close(); + +private: + llstdio_filebuf _M_filebuf; +}; + + +/** + * @breif filesize helpers. * * The file size helpers are not considered particularly efficient, * and should only be used for config files and the like -- not in a diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp index 08be3e259..4b5cdbe28 100644 --- a/indra/llcommon/llfixedbuffer.cpp +++ b/indra/llcommon/llfixedbuffer.cpp @@ -1,31 +1,25 @@ /** * @file llfixedbuffer.cpp * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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" diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index 4ffb22515..c214f03a4 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -1,32 +1,25 @@ /** * @file llframetimer.cpp * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * Copyright (c) 2011, Aleric Inglewood. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h index 2bb1943c8..b09937895 100644 --- a/indra/llcommon/llframetimer.h +++ b/indra/llcommon/llframetimer.h @@ -3,32 +3,25 @@ * @brief A lightweight timer that measures seconds and is only * updated once per frame. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * Copyright (c) 2011, Aleric Inglewood. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,7 +31,7 @@ /** * *NOTE: Because of limitations on linux which we do not really have * time to explore, the total time is derived from the frame time - * and is resynchronized on every frame. + * and is recsynchronized on every frame. */ #include "lltimer.h" diff --git a/indra/llcommon/llhandle.h b/indra/llcommon/llhandle.h new file mode 100644 index 000000000..6af5e198d --- /dev/null +++ b/indra/llcommon/llhandle.h @@ -0,0 +1,217 @@ +/** +* @file llhandle.h +* @brief "Handle" to an object (usually a floater) whose lifetime you don't +* control. +* +* $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 LLHANDLE_H +#define LLHANDLE_H + +#include "llpointer.h" +#include +#include + +/** + * Helper object for LLHandle. Don't instantiate these directly, used + * exclusively by LLHandle. + */ +class LLTombStone : public LLRefCount +{ +public: + LLTombStone(void* target = NULL) : mTarget(target) {} + + void setTarget(void* target) { mTarget = target; } + void* getTarget() const { return mTarget; } +private: + mutable void* mTarget; +}; + +/** + * LLHandles are used to refer to objects whose lifetime you do not control or influence. + * Calling get() on a handle will return a pointer to the referenced object or NULL, + * if the object no longer exists. Note that during the lifetime of the returned pointer, + * you are assuming that the object will not be deleted by any action you perform, + * or any other thread, as normal when using pointers, so avoid using that pointer outside of + * the local code block. + * + * https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 + * + * The implementation is like some "weak pointer" implementations. When we + * can't control the lifespan of the referenced object of interest, we can + * still instantiate a proxy object whose lifespan we DO control, and store in + * the proxy object a dumb pointer to the actual target. Then we just have to + * ensure that on destruction of the target object, the proxy's dumb pointer + * is set NULL. + * + * LLTombStone is our proxy object. LLHandle contains an LLPointer to the + * LLTombStone, so every copy of an LLHandle increments the LLTombStone's ref + * count as usual. + * + * One copy of the LLHandle, specifically the LLRootHandle, must be stored in + * the referenced object. Destroying the LLRootHandle is what NULLs the + * proxy's target pointer. + * + * Minor optimization: we want LLHandle's mTombStone to always be a valid + * LLPointer, saving some conditionals in dereferencing. That's the + * getDefaultTombStone() mechanism. The default LLTombStone object's target + * pointer is always NULL, so it's semantically identical to allowing + * mTombStone to be invalid. + */ +template +class LLHandle +{ + template friend class LLHandle; + template friend class LLHandleProvider; +public: + LLHandle() : mTombStone(getDefaultTombStone()) {} + + template + LLHandle(const LLHandle& other, typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) + : mTombStone(other.mTombStone) + {} + + bool isDead() const + { + return mTombStone->getTarget() == NULL; + } + + void markDead() + { + mTombStone = getDefaultTombStone(); + } + + T* get() const + { + return reinterpret_cast(mTombStone->getTarget()); + } + + friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone == rhs.mTombStone; + } + friend bool operator!= (const LLHandle& lhs, const LLHandle& rhs) + { + return !(lhs == rhs); + } + friend bool operator< (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone < rhs.mTombStone; + } + friend bool operator> (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone > rhs.mTombStone; + } + +protected: + LLPointer mTombStone; + +private: + typedef T* pointer_t; + static LLPointer& getDefaultTombStone() + { + static LLPointer sDefaultTombStone = new LLTombStone; + return sDefaultTombStone; + } +}; + +/** + * LLRootHandle isa LLHandle which must be stored in the referenced object. + * You can either store it directly and explicitly bind(this), or derive from + * LLHandleProvider (q.v.) which automates that for you. The essential point + * is that destroying the LLRootHandle (as a consequence of destroying the + * referenced object) calls unbind(), setting the LLTombStone's target pointer + * NULL. + */ +template +class LLRootHandle : public LLHandle +{ +public: + typedef LLRootHandle self_t; + typedef LLHandle base_t; + + LLRootHandle(T* object) { bind(object); } + LLRootHandle() {}; + ~LLRootHandle() { unbind(); } + + // this is redundant, since an LLRootHandle *is* an LLHandle + //LLHandle getHandle() { return LLHandle(*this); } + + void bind(T* object) + { + // unbind existing tombstone + if (LLHandle::mTombStone.notNull()) + { + if (LLHandle::mTombStone->getTarget() == (void*)object) return; + LLHandle::mTombStone->setTarget(NULL); + } + // tombstone reference counted, so no paired delete + LLHandle::mTombStone = new LLTombStone((void*)object); + } + + void unbind() + { + LLHandle::mTombStone->setTarget(NULL); + } + + //don't allow copying of root handles, since there should only be one +private: + LLRootHandle(const LLRootHandle& other) {}; +}; + +/** + * Use this as a mixin for simple classes that need handles and when you don't + * want handles at multiple points of the inheritance hierarchy + */ +template +class LLHandleProvider +{ +public: + LLHandle getHandle() const + { + // perform lazy binding to avoid small tombstone allocations for handle + // providers whose handles are never referenced + mHandle.bind(static_cast(const_cast* >(this))); + return mHandle; + } + +protected: + typedef LLHandle handle_type_t; + LLHandleProvider() + { + // provided here to enforce T deriving from LLHandleProvider + } + + template + LLHandle getDerivedHandle(typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) const + { + LLHandle downcast_handle; + downcast_handle.mTombStone = getHandle().mTombStone; + return downcast_handle; + } + + +private: + mutable LLRootHandle mHandle; +}; + +#endif diff --git a/indra/llcommon/llhash.h b/indra/llcommon/llhash.h index c0a8bff66..1000d2306 100644 --- a/indra/llcommon/llhash.h +++ b/indra/llcommon/llhash.h @@ -2,31 +2,25 @@ * @file llhash.h * @brief Wrapper for a hash function. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,15 +33,15 @@ #include #include #elif LL_DARWIN || LL_LINUX -#if GCC_VERSION >= 40300 || LL_ICC// gcc 4.3 or icc 11 and up -# include -#elif GCC_VERSION >= 30400 // gcc 3.4 and up -# include -#elif __GNUC__ >= 3 -# include -#else -# include -#endif +# if GCC_VERSION >= 40300 || LL_ICC// gcc 4.3 or icc 11 and up +# include +# elif GCC_VERSION >= 30400 // gcc 3.4 and up +# include +# elif __GNUC__ >= 3 +# include +# else +# include +# endif #elif LL_SOLARIS #include #else diff --git a/indra/llcommon/llheartbeat.cpp b/indra/llcommon/llheartbeat.cpp index 83cf3e50c..0ae1d73cb 100644 --- a/indra/llcommon/llheartbeat.cpp +++ b/indra/llcommon/llheartbeat.cpp @@ -2,31 +2,25 @@ * @file llheartbeat.cpp * @brief Class encapsulating logic for telling a watchdog that we live. * - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 0bf4c1bd5..403df0899 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -3,33 +3,26 @@ * @brief LLInstanceTracker is a mixin class that automatically tracks object * instances with or without an associated key * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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_LLINSTANCETRACKER_H @@ -45,10 +38,16 @@ #include #include +/** + * Base class manages "class-static" data that must actually have singleton + * semantics: one instance per process, rather than one instance per module as + * sometimes happens with data simply declared static. + */ class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable { - protected: - static void * & getInstances(std::type_info const & info); +protected: + /// Get a process-unique void* pointer slot for the specified type_info + static void * & getInstances(std::type_info const & info); /// Find or create a STATICDATA instance for the specified TRACKED class. /// STATICDATA must be default-constructible. @@ -168,8 +167,9 @@ public: static T* getInstance(const KEY& k) { - typename InstanceMap::const_iterator found = getMap_().find(k); - return (found == getMap_().end()) ? NULL : found->second; + const InstanceMap& map(getMap_()); + typename InstanceMap::const_iterator found = map.find(k); + return (found == map.end()) ? NULL : found->second; } static instance_iter beginInstances() @@ -240,8 +240,20 @@ class LLInstanceTracker : public LLInstanceTrackerBase public: - /// for completeness of analogy with the generic implementation - static T* getInstance(T* k) { return k; } + /** + * Does a particular instance still exist? Of course, if you already have + * a T* in hand, you need not call getInstance() to @em locate the + * instance -- unlike the case where getInstance() accepts some kind of + * key. Nonetheless this method is still useful to @em validate a + * particular T*, since each instance's destructor removes itself from the + * underlying set. + */ + static T* getInstance(T* k) + { + const InstanceSet& set(getSet_()); + typename InstanceSet::const_iterator found = set.find(k); + return (found == set.end())? NULL : *found; + } static S32 instanceCount() { return getSet_().size(); } class instance_iter : public boost::iterator_facade diff --git a/indra/llcommon/lllivefile.h b/indra/llcommon/lllivefile.h index 7480a8a8a..030b96dcc 100644 --- a/indra/llcommon/lllivefile.h +++ b/indra/llcommon/lllivefile.h @@ -2,31 +2,25 @@ * @file lllivefile.h * @brief Automatically reloads a file whenever it changes or is removed. * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/lllslconstants.h b/indra/llcommon/lllslconstants.h index 42aaad985..9452d7031 100644 --- a/indra/llcommon/lllslconstants.h +++ b/indra/llcommon/lllslconstants.h @@ -3,31 +3,25 @@ * @author James Cook * @brief Constants used in lsl. * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index 1257af0e3..1409c55d1 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -1,31 +1,25 @@ /** * @file llmd5.cpp * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -171,11 +165,6 @@ void LLMD5::update(FILE* file){ } - - - - - // MD5 update for istreams. // Like update for files; see above. @@ -186,7 +175,7 @@ void LLMD5::update(std::istream& stream){ while (stream.good()){ stream.read( (char*)buffer, BLOCK_LEN); /* Flawfinder: ignore */ // note that return value of read is unusable. - len=stream.gcount(); + len=(int)stream.gcount(); update(buffer, len); } @@ -320,6 +309,7 @@ void LLMD5::hex_digest(char *s) const + std::ostream& operator<<(std::ostream &stream, LLMD5 context) { char s[33]; /* Flawfinder: ignore */ @@ -544,3 +534,5 @@ void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){ output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); } + + diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 446946ac4..05809d20b 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -2,31 +2,25 @@ * @file llmemory.cpp * @brief Very special memory allocation/deallocation stuff here * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -67,6 +61,18 @@ BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE; LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker; #endif +void ll_assert_aligned_func(uintptr_t ptr,U32 alignment) +{ +#ifdef SHOW_ASSERT + // Redundant, place to set breakpoints. + if (ptr%alignment!=0) + { + llwarns << "alignment check failed" << llendl; + } + llassert(ptr%alignment==0); +#endif +} + //static void LLMemory::initClass() { @@ -246,21 +252,6 @@ U32 LLMemory::getAllocatedMemKB() return sAllocatedMemInKB ; } -void* ll_allocate (size_t size) -{ - if (size == 0) - { - llwarns << "Null allocation" << llendl; - } - void *p = malloc(size); - if (p == NULL) - { - LLMemory::freeReserve(); - llerrs << "Out of memory Error" << llendl; - } - return p; -} - //---------------------------------------------------------------------------- #if defined(LL_WINDOWS) @@ -382,6 +373,7 @@ U32 LLMemory::getWorkingSetSize() { return 0 ; } + #elif LL_SOLARIS #include #include @@ -425,7 +417,7 @@ U64 LLMemory::getCurrentRSS() U32 LLMemory::getWorkingSetSize() { - return 0 ; + return 0; } #endif @@ -1358,7 +1350,7 @@ char* LLPrivateMemoryPool::allocate(U32 size) //if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it if(size >= CHUNK_SIZE) { - return (char*)malloc(size) ; + return (char*)ll_aligned_malloc_16(size) ; } char* p = NULL ; @@ -1415,7 +1407,7 @@ char* LLPrivateMemoryPool::allocate(U32 size) to_log = false ; } - return (char*)malloc(size) ; + return (char*)ll_aligned_malloc_16(size) ; } return p ; @@ -1434,7 +1426,7 @@ void LLPrivateMemoryPool::freeMem(void* addr) if(!chunk) { - free(addr) ; //release from heap + ll_aligned_free_16(addr) ; //release from heap } else { @@ -1558,7 +1550,7 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde mReservedPoolSize += preferred_size + overhead ; - char* buffer = (char*)malloc(preferred_size + overhead) ; + char* buffer = (char*)ll_aligned_malloc_16(preferred_size + overhead) ; if(!buffer) { return NULL ; @@ -1626,7 +1618,7 @@ void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk) mReservedPoolSize -= chunk->getBufferSize() ; //release memory - free(chunk->getBuffer()) ; + ll_aligned_free_16(chunk->getBuffer()) ; } U16 LLPrivateMemoryPool::findHashKey(const char* addr) @@ -1970,7 +1962,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size, if(!poolp) { - p = (char*)malloc(size) ; + p = (char*)ll_aligned_malloc_16(size) ; } else { @@ -1999,7 +1991,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size) } else { - return (char*)malloc(size) ; + return (char*)ll_aligned_malloc_16(size) ; } } #endif @@ -2024,7 +2016,7 @@ void LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr { if(!sPrivatePoolEnabled) { - free(addr) ; //private pool is disabled. + ll_aligned_free_16(addr) ; //private pool is disabled. } else if(!sInstance) //the private memory manager is destroyed, try the dangling list { diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 19cc720b0..255358260 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -1,32 +1,26 @@ -/** +/** * @file llmemory.h * @brief Memory allocation/deallocation header-stuff goes here. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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 LLMEMORY_H @@ -39,9 +33,14 @@ #include // uintptr_t #endif -#include "llerror.h" #include "llmemtype.h" -#if LL_DEBUG + +#if LL_WINDOWS && LL_DEBUG +#define LL_CHECK_MEMORY llassert(_CrtCheckMemory()); +#else +#define LL_CHECK_MEMORY +#endif + inline void* ll_aligned_malloc( size_t size, int align ) { void* mem = malloc( size + (align - 1) + sizeof(void*) ); @@ -57,10 +56,11 @@ inline void ll_aligned_free( void* ptr ) free( ((void**)ptr)[-1] ); } +#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) - return _mm_malloc(size, 16); + return _aligned_malloc(size, 16); #elif defined(LL_DARWIN) return malloc(size); // default osx malloc is 16 byte aligned. #else @@ -75,7 +75,7 @@ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed wi inline void ll_aligned_free_16(void *p) { #if defined(LL_WINDOWS) - _mm_free(p); + _aligned_free(p); #elif defined(LL_DARWIN) return free(p); #else @@ -83,10 +83,39 @@ inline void ll_aligned_free_16(void *p) #endif } +inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // returned hunk MUST be freed with ll_aligned_free_16(). +{ +#if defined(LL_WINDOWS) + return _aligned_realloc(ptr, size, 16); +#elif defined(LL_DARWIN) + return realloc(ptr,size); // default osx malloc is 16 byte aligned. +#else + //FIXME: memcpy is SLOW + void* ret = ll_aligned_malloc_16(size); + if (ptr) + { + if (ret) + { + // Only copy the size of the smallest memory block to avoid memory corruption. + memcpy(ret, ptr, llmin(old_size, size)); + } + ll_aligned_free_16(ptr); + } + return ret; +#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) - return _mm_malloc(size, 32); + return _aligned_malloc(size, 32); #elif defined(LL_DARWIN) return ll_aligned_malloc( size, 32 ); #else @@ -101,22 +130,13 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi inline void ll_aligned_free_32(void *p) { #if defined(LL_WINDOWS) - _mm_free(p); + _aligned_free(p); #elif defined(LL_DARWIN) ll_aligned_free( p ); #else free(p); // posix_memalign() is compatible with heap deallocator #endif } -#else // LL_DEBUG -// ll_aligned_foo are noops now that we use tcmalloc everywhere (tcmalloc aligns automatically at appropriate intervals) -#define ll_aligned_malloc( size, align ) malloc(size) -#define ll_aligned_free( ptr ) free(ptr) -#define ll_aligned_malloc_16 malloc -#define ll_aligned_free_16 free -#define ll_aligned_malloc_32 malloc -#define ll_aligned_free_32 free -#endif // LL_DEBUG #ifndef __DEBUG_PRIVATE_MEM__ #define __DEBUG_PRIVATE_MEM__ 0 @@ -521,6 +541,14 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr) #endif #endif +LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); + +#ifdef SHOW_ASSERT +#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast(ptr),((U32)alignment)) +#else +#define ll_assert_aligned(ptr,alignment) +#endif + //EVENTUALLY REMOVE THESE: #include "llpointer.h" #include "llsingleton.h" diff --git a/indra/llcommon/llmemtype.h b/indra/llcommon/llmemtype.h index 413540d7c..b51d7e0f6 100644 --- a/indra/llcommon/llmemtype.h +++ b/indra/llcommon/llmemtype.h @@ -2,31 +2,25 @@ * @file llmemtype.h * @brief Runtime memory usage debugging utilities. * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/lloptioninterface.h b/indra/llcommon/lloptioninterface.h index dd5829d79..53294e69a 100644 --- a/indra/llcommon/lloptioninterface.h +++ b/indra/llcommon/lloptioninterface.h @@ -2,31 +2,25 @@ * @file lloptioninterface.h * @brief * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index a1f598d4a..e903cf607 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -3,31 +3,25 @@ * @brief This file should be included in all Linden Lab files and * should only contain special preprocessor directives * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 9532410b7..7e0e74d50 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -2,31 +2,25 @@ * @file llprocessor.cpp * @brief Code to figure out the processor. Originally by Benjamin Jurke. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 27e3dca7c..e9c0a2493 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -1,31 +1,25 @@ /** * @file llqueuedthread.cpp * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -140,8 +134,8 @@ S32 LLQueuedThread::updateQueue(F32 max_time_ms) pending = getPending(); if(pending > 0) { - unpause(); - } + unpause(); + } } else { diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index 9e2e7d969..dda7bf69c 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -2,31 +2,25 @@ * @file llqueuedthread.h * @brief * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,7 +38,7 @@ #include "llsimplehash.h" //============================================================================ -// Note: ~LLQueuedThread is O(N) N=# of queued requests, assumed to be small +// Note: ~LLQueuedThread is O(N) N=# of queued threads, assumed to be small // It is assumed that LLQueuedThreads are rarely created/destroyed. class LL_COMMON_API LLQueuedThread : public LLThread @@ -154,6 +148,7 @@ protected: } }; + //------------------------------------------------------------------------ public: diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 7086e4248..61c4ca08d 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -2,31 +2,25 @@ * @file llsd.cpp * @brief LLSD flexible data system * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -162,7 +156,7 @@ namespace virtual LLSD::Type type() const { return T; } - using LLSD::Impl::assign; + using LLSD::Impl::assign; // Unhiding base class virtuals... virtual void assign(LLSD::Impl*& var, DataRef value) { if (shared()) { @@ -496,12 +490,13 @@ namespace void ImplArray::insert(LLSD::Integer i, const LLSD& v) { - if (i < 0) { + if (i < 0) + { return; } DataVector::size_type index = i; - if (index >= mData.size()) + if (index >= mData.size()) // tbd - sanity check limit for index ? { mData.resize(index + 1); } diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index 5cfca77f8..6e242a163 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -2,31 +2,25 @@ * @file llsd.h * @brief LLSD flexible data system. * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,10 +40,10 @@ /** LLSD provides a flexible data system similar to the data facilities of dynamic languages like Perl and Python. It is created to support exchange - of structured data between loosly coupled systems. (Here, "loosly coupled" + of structured data between loosely coupled systems. (Here, "loosely coupled" means not compiled together into the same module.) - Data in such exchanges must be highly tollerant of changes on either side + Data in such exchanges must be highly tolerant of changes on either side such as: - recompilation - implementation in a different langauge @@ -57,19 +51,19 @@ - execution of older versions (with fewer parameters) To this aim, the C++ API of LLSD strives to be very easy to use, and to - default to "the right thing" whereever possible. It is extremely tollerant + default to "the right thing" wherever possible. It is extremely tolerant of errors and unexpected situations. - The fundimental class is LLSD. LLSD is a value holding object. It holds + The fundamental class is LLSD. LLSD is a value holding object. It holds one value that is either undefined, one of the scalar types, or a map or an array. LLSD objects have value semantics (copying them copies the value, - though it can be considered efficient, due to shareing.), and mutable. + though it can be considered efficient, due to sharing), and mutable. Undefined is the singular value given to LLSD objects that are not initialized with any data. It is also used as the return value for - operations that return an LLSD, + operations that return an LLSD. - The sclar data types are: + The scalar data types are: - Boolean - true or false - Integer - a 32 bit signed integer - Real - a 64 IEEE 754 floating point value @@ -86,9 +80,73 @@ An array is a sequence of zero or more LLSD values. + Thread Safety + + In general, these LLSD classes offer *less* safety than STL container + classes. Implementations prior to this one were unsafe even when + completely unrelated LLSD trees were in two threads due to reference + sharing of special 'undefined' values that participated in the reference + counting mechanism. + + The dereference-before-refcount and aggressive tree sharing also make + it impractical to share an LLSD across threads. A strategy of passing + ownership or a copy to another thread is still difficult due to a lack + of a cloning interface but it can be done with some care. + + One way of transferring ownership is as follows: + + void method(const LLSD input) { + ... + LLSD * xfer_tree = new LLSD(); + { + // Top-level values + (* xfer_tree)['label'] = "Some text"; + (* xfer_tree)['mode'] = APP_MODE_CONSTANT; + + // There will be a second-level + LLSD subtree(LLSD::emptyMap()); + (* xfer_tree)['subtree'] = subtree; + + // Do *not* copy from LLSD objects via LLSD + // intermediaries. Only use plain-old-data + // types as intermediaries to prevent reference + // sharing. + subtree['value1'] = input['value1'].asInteger(); + subtree['value2'] = input['value2'].asString(); + + // Close scope and drop 'subtree's reference. + // Only xfer_tree has a reference to the second + // level data. + } + ... + // Transfer the LLSD pointer to another thread. Ownership + // transfers, this thread no longer has a reference to any + // part of the xfer_tree and there's nothing to free or + // release here. Receiving thread does need to delete the + // pointer when it is done with the LLSD. Transfer + // mechanism must perform correct data ordering operations + // as dictated by architecture. + other_thread.sendMessageAndPointer("Take This", xfer_tree); + xfer_tree = NULL; + + + Avoid this pattern which provides half of a race condition: + + void method(const LLSD input) { + ... + LLSD xfer_tree(LLSD::emptyMap()); + xfer_tree['label'] = "Some text"; + xfer_tree['mode'] = APP_MODE_CONSTANT; + ... + other_thread.sendMessageAndPointer("Take This", xfer_tree); + + @nosubgrouping */ +// Normally undefined, used for diagnostics +//#define LLSD_DEBUG_INFO 1 + class LL_COMMON_API LLSD { public: @@ -211,7 +269,7 @@ public: //@} /** @name Character Pointer Helpers - These are helper routines to make working with char* the same as easy as + These are helper routines to make working with char* as easy as working with strings. */ //@{ @@ -275,7 +333,7 @@ public: /** @name Type Testing */ //@{ enum Type { - TypeUndefined, + TypeUndefined = 0, TypeBoolean, TypeInteger, TypeReal, @@ -285,7 +343,10 @@ public: TypeURI, TypeBinary, TypeMap, - TypeArray + TypeArray, + TypeLLSDTypeEnd, + TypeLLSDTypeBegin = TypeUndefined, + TypeLLSDNumTypes = (TypeLLSDTypeEnd - TypeLLSDTypeBegin) }; Type type() const; @@ -311,7 +372,7 @@ public: If you get a linker error about these being missing, you have made mistake in your code. DO NOT IMPLEMENT THESE FUNCTIONS as a fix. - All of thse problems stem from trying to support char* in LLSD or in + All of these problems stem from trying to support char* in LLSD or in std::string. There are too many automatic casts that will lead to using an arbitrary pointer or scalar type to std::string. */ @@ -320,7 +381,7 @@ public: void assign(const void*); ///< assign from arbitrary pointers LLSD& operator=(const void*); ///< assign from arbitrary pointers - bool has(Integer) const; ///< has only works for Maps + bool has(Integer) const; ///< has() only works for Maps //@} /** @name Implementation */ @@ -395,8 +456,8 @@ struct llsd_select_string : public std::unary_function LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLSD& llsd); /** QUESTIONS & TO DOS - - Would Binary be more convenient as usigned char* buffer semantics? - - Should Binary be convertable to/from String, and if so how? + - Would Binary be more convenient as unsigned char* buffer semantics? + - Should Binary be convertible to/from String, and if so how? - as UTF8 encoded strings (making not like UUID<->String) - as Base64 or Base96 encoded (making like UUID<->String) - Conversions to std::string and LLUUID do not result in easy assignment diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 61dc62388..ad4fce6f3 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -4,31 +4,25 @@ * @date 2006-03-05 * @brief Implementation of LLSD parsers and formatters * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,6 +33,7 @@ #include #include "apr_base64.h" + #ifdef LL_STANDALONE # include #else @@ -63,6 +58,7 @@ const std::string LLSD_XML_HEADER("LLSD/XML"); //used to deflate a gzipped asset (currently used for navmeshes) #define windowBits 15 #define ENABLE_ZLIB_GZIP 32 + /** * LLSDSerialize */ @@ -118,7 +114,7 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes) if (!strncasecmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER))) /* Flawfinder: ignore */ { legacy_no_header = true; - inbuf = str.gcount(); + inbuf = (int)str.gcount(); } else { @@ -351,7 +347,7 @@ std::istream& LLSDParser::get( char delim) const { istr.get(s, n, delim); - if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); + if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); return istr; } @@ -361,7 +357,7 @@ std::istream& LLSDParser::get( char delim) const { istr.get(sb, delim); - if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); + if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); return istr; } @@ -385,7 +381,7 @@ std::istream& LLSDParser::read( std::streamsize n) const { istr.read(s, n); - if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); + if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); return istr; } @@ -797,7 +793,7 @@ bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const if(len) { value.resize(len); - account(fullread(istr, (char *)&value[0], len)); + account((int)fullread(istr, (char *)&value[0], len)); } c = get(istr); // strip off the trailing double-quote data = value; @@ -1077,7 +1073,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const if(size > 0) { value.resize(size); - account(fullread(istr, (char*)&value[0], size)); + account((int)fullread(istr, (char*)&value[0], size)); } data = value; } @@ -1208,7 +1204,7 @@ bool LLSDBinaryParser::parseString( if(size) { buf.resize(size); - account(fullread(istr, &buf[0], size)); + account((int)fullread(istr, &buf[0], size)); value.assign(buf.begin(), buf.end()); } return true; @@ -1455,12 +1451,12 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option } case LLSD::TypeUUID: - { + { ostr.put('u'); - LLUUID value = data.asUUID(); - ostr.write((const char*)(&value.mData), UUID_BYTES); + LLUUID temp = data.asUUID(); + ostr.write((const char*)(&(temp.mData)), UUID_BYTES); break; - } + } case LLSD::TypeString: ostr.put('s'); @@ -1653,7 +1649,7 @@ int deserialize_string_raw( const S32 BUF_LEN = 20; char buf[BUF_LEN]; /* Flawfinder: ignore */ istr.get(buf, BUF_LEN - 1, ')'); - count += istr.gcount(); + count += (int)istr.gcount(); int c = istr.get(); c = istr.get(); count += 2; @@ -1668,7 +1664,7 @@ int deserialize_string_raw( if(len) { buf.resize(len); - count += fullread(istr, (char *)&buf[0], len); + count += (int)fullread(istr, (char *)&buf[0], len); value.assign(buf.begin(), buf.end()); } c = istr.get(); @@ -2000,6 +1996,7 @@ std::ostream& operator<<(std::ostream& s, const LLSD& llsd) return s; } + //dirty little zippers -- yell at davep if these are horrid //return a string containing gzipped bytes of binary serialized LLSD @@ -2106,7 +2103,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size) strm.next_in = in; S32 ret = inflateInit(&strm); - + do { strm.avail_out = CHUNK; @@ -2169,7 +2166,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size) llwarns << "Failed to unzip LLSD block" << llendl; free(result); return false; - } + } } free(result); @@ -2252,3 +2249,4 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 return result; } + diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index 9bc17e0aa..f0b4716ce 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -2,31 +2,25 @@ * @file llsdserialize_xml.cpp * @brief XML parsers and formatters for LLSD * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -383,10 +377,13 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data) { break; } - count = get_till_eol(input, (char *)buffer, BUFFER_SIZE); - if (!count) { - break; + + count = get_till_eol(input, (char *)buffer, BUFFER_SIZE); + if (!count) + { + break; + } } status = XML_ParseBuffer(mParser, count, false); @@ -471,7 +468,7 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data) } } - status = XML_ParseBuffer(mParser, num_read, false); + status = XML_ParseBuffer(mParser, (int)num_read, false); if (status == XML_STATUS_ERROR) { break; diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index f57cab3e0..532d3f934 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -4,31 +4,25 @@ * @date 2006-05-24 * @brief Utility classes, functions, etc, for using structured data. * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -314,7 +308,7 @@ class LLSDParam \ { \ public: \ LLSDParam(const LLSD& value): \ - _value(value.AS()) \ + _value((T)value.AS()) \ {} \ \ operator T() const { return _value; } \ diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp index 40ae67c51..b82d52797 100644 --- a/indra/llcommon/llstat.cpp +++ b/indra/llcommon/llstat.cpp @@ -1,31 +1,25 @@ /** * @file llstat.cpp * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,7 +40,6 @@ S32 LLPerfBlock::sStatsFlags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS; // Control what is being recorded LLPerfBlock::stat_map_t LLPerfBlock::sStatMap; // Map full path string to LLStatTime objects, tracks all active objects std::string LLPerfBlock::sCurrentStatPath = ""; // Something like "/total_time/physics/physics step" -LLStat::stat_map_t LLStat::sStatList; //------------------------------------------------------------------------ // Live config file to trigger stats logging @@ -599,7 +592,7 @@ void LLStatTime::stop() { if ( LLStatAccum::SCALE_PER_FRAME == scale ) { - return mTotalTimeInFrame; + return (F32)mTotalTimeInFrame; } else { @@ -777,13 +770,19 @@ void LLStat::init() if (!mName.empty()) { - stat_map_t::iterator iter = sStatList.find(mName); - if (iter != sStatList.end()) + stat_map_t::iterator iter = getStatList().find(mName); + if (iter != getStatList().end()) llwarns << "LLStat with duplicate name: " << mName << llendl; - sStatList.insert(std::make_pair(mName, this)); + getStatList().insert(std::make_pair(mName, this)); } } +LLStat::stat_map_t& LLStat::getStatList() +{ + static LLStat::stat_map_t stat_list; + return stat_list; +} + LLStat::LLStat(const U32 num_bins, const BOOL use_frame_timer) : mUseFrameTimer(use_frame_timer), mNumBins(num_bins) @@ -809,10 +808,10 @@ LLStat::~LLStat() if (!mName.empty()) { // handle multiple entries with the same name - stat_map_t::iterator iter = sStatList.find(mName); - while (iter != sStatList.end() && iter->second != this) + stat_map_t::iterator iter = getStatList().find(mName); + while (iter != getStatList().end() && iter->second != this) ++iter; - sStatList.erase(iter); + getStatList().erase(iter); } } diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h index bd73c9a6b..1a8404cc0 100644 --- a/indra/llcommon/llstat.h +++ b/indra/llcommon/llstat.h @@ -2,31 +2,25 @@ * @file llstat.h * @brief Runtime statistics accumulation. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -269,9 +263,9 @@ class LL_COMMON_API LLStat { private: typedef std::multimap stat_map_t; - static stat_map_t sStatList; void init(); + static stat_map_t& getStatList(); public: LLStat(U32 num_bins = 32, BOOL use_frame_timer = FALSE); @@ -348,8 +342,8 @@ public: static LLStat* getStat(const std::string& name) { // return the first stat that matches 'name' - stat_map_t::iterator iter = sStatList.find(name); - if (iter != sStatList.end()) + stat_map_t::iterator iter = getStatList().find(name); + if (iter != getStatList().end()) return iter->second; else return NULL; diff --git a/indra/llcommon/llstatenums.h b/indra/llcommon/llstatenums.h index f8bf07f19..608ac5473 100644 --- a/indra/llcommon/llstatenums.h +++ b/indra/llcommon/llstatenums.h @@ -1,31 +1,25 @@ /** * @file llstatenums.h * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,41 +28,41 @@ enum { - LL_SIM_STAT_TIME_DILATION, // 0 - LL_SIM_STAT_FPS, - LL_SIM_STAT_PHYSFPS, - LL_SIM_STAT_AGENTUPS, - LL_SIM_STAT_FRAMEMS, - LL_SIM_STAT_NETMS, // 5 - LL_SIM_STAT_SIMOTHERMS, - LL_SIM_STAT_SIMPHYSICSMS, - LL_SIM_STAT_AGENTMS, - LL_SIM_STAT_IMAGESMS, - LL_SIM_STAT_SCRIPTMS, // 10 - LL_SIM_STAT_NUMTASKS, - LL_SIM_STAT_NUMTASKSACTIVE, - LL_SIM_STAT_NUMAGENTMAIN, - LL_SIM_STAT_NUMAGENTCHILD, - LL_SIM_STAT_NUMSCRIPTSACTIVE, // 15 - LL_SIM_STAT_LSLIPS, - LL_SIM_STAT_INPPS, - LL_SIM_STAT_OUTPPS, - LL_SIM_STAT_PENDING_DOWNLOADS, - LL_SIM_STAT_PENDING_UPLOADS, // 20 - LL_SIM_STAT_VIRTUAL_SIZE_KB, - LL_SIM_STAT_RESIDENT_SIZE_KB, - LL_SIM_STAT_PENDING_LOCAL_UPLOADS, - LL_SIM_STAT_TOTAL_UNACKED_BYTES, - LL_SIM_STAT_PHYSICS_PINNED_TASKS, // 25 - LL_SIM_STAT_PHYSICS_LOD_TASKS, - LL_SIM_STAT_SIMPHYSICSSTEPMS, - LL_SIM_STAT_SIMPHYSICSSHAPEMS, - LL_SIM_STAT_SIMPHYSICSOTHERMS, - LL_SIM_STAT_SIMPHYSICSMEMORY, // 30 - LL_SIM_STAT_SCRIPT_EPS, - LL_SIM_STAT_SIMSPARETIME, - LL_SIM_STAT_SIMSLEEPTIME, - LL_SIM_STAT_IOPUMPTIME, + LL_SIM_STAT_TIME_DILATION = 0, + LL_SIM_STAT_FPS = 1, + LL_SIM_STAT_PHYSFPS = 2, + LL_SIM_STAT_AGENTUPS = 3, + LL_SIM_STAT_FRAMEMS = 4, + LL_SIM_STAT_NETMS = 5, + LL_SIM_STAT_SIMOTHERMS = 6, + LL_SIM_STAT_SIMPHYSICSMS = 7, + LL_SIM_STAT_AGENTMS = 8, + LL_SIM_STAT_IMAGESMS = 9, + LL_SIM_STAT_SCRIPTMS = 10, + LL_SIM_STAT_NUMTASKS = 11, + LL_SIM_STAT_NUMTASKSACTIVE = 12, + LL_SIM_STAT_NUMAGENTMAIN = 13, + LL_SIM_STAT_NUMAGENTCHILD = 14, + LL_SIM_STAT_NUMSCRIPTSACTIVE = 15, + LL_SIM_STAT_LSLIPS = 16, + LL_SIM_STAT_INPPS = 17, + LL_SIM_STAT_OUTPPS = 18, + LL_SIM_STAT_PENDING_DOWNLOADS = 19, + LL_SIM_STAT_PENDING_UPLOADS = 20, + LL_SIM_STAT_VIRTUAL_SIZE_KB = 21, + LL_SIM_STAT_RESIDENT_SIZE_KB = 22, + LL_SIM_STAT_PENDING_LOCAL_UPLOADS = 23, + LL_SIM_STAT_TOTAL_UNACKED_BYTES = 24, + LL_SIM_STAT_PHYSICS_PINNED_TASKS = 25, + LL_SIM_STAT_PHYSICS_LOD_TASKS = 26, + LL_SIM_STAT_SIMPHYSICSSTEPMS = 27, + LL_SIM_STAT_SIMPHYSICSSHAPEMS = 28, + LL_SIM_STAT_SIMPHYSICSOTHERMS = 29, + LL_SIM_STAT_SIMPHYSICSMEMORY = 30, + LL_SIM_STAT_SCRIPT_EPS = 31, + LL_SIM_STAT_SIMSPARETIME = 32, + LL_SIM_STAT_SIMSLEEPTIME = 33, + LL_SIM_STAT_IOPUMPTIME = 34, }; #endif diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 15a4b3d77..8953a1089 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -2,31 +2,25 @@ * @file llstring.cpp * @brief String utility functions and the std::string class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -53,7 +47,8 @@ std::string ll_safe_string(const char* in) std::string ll_safe_string(const char* in, S32 maxlen) { - if(in && maxlen > 0) return std::string(in, maxlen); + if(in && maxlen > 0 ) return std::string(in, maxlen); + return std::string(); } diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 992008ae8..35d20d2ee 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -2,31 +2,25 @@ * @file llstring.h * @brief String utility functions and std::string class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -189,6 +183,9 @@ public: static bool isPunct(char a) { return ispunct((unsigned char)a) != 0; } static bool isPunct(llwchar a) { return iswpunct(a) != 0; } + static bool isAlpha(char a) { return isalpha((unsigned char)a) != 0; } + static bool isAlpha(llwchar a) { return iswalpha(a) != 0; } + static bool isAlnum(char a) { return isalnum((unsigned char)a) != 0; } static bool isAlnum(llwchar a) { return iswalnum(a) != 0; } @@ -463,7 +460,7 @@ public: * This function works on bytes rather than glyphs, so this will * incorrectly truncate non-single byte strings. * Use utf8str_truncate() for utf8 strings - * @return a copy of in string minus the trailing count characters. + * @return a copy of in string minus the trailing count bytes. */ inline std::string chop_tail_copy( const std::string& in, @@ -495,7 +492,7 @@ LL_COMMON_API bool iswindividual(llwchar elem); */ // Make the incoming string a utf8 string. Replaces any unknown glyph -// with the UNKOWN_CHARACTER. Once any unknown glph is found, the rest +// with the UNKNOWN_CHARACTER. Once any unknown glyph is found, the rest // of the data may not be recovered. LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw); @@ -528,10 +525,10 @@ LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str); // Length of this UTF32 string in bytes when transformed to UTF8 -LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr); +LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr); // Length in bytes of this wide char in a UTF8 string -LL_COMMON_API S32 wchar_utf8_length(const llwchar wc); +LL_COMMON_API S32 wchar_utf8_length(const llwchar wc); LL_COMMON_API std::string utf8str_tolower(const std::string& utf8str); @@ -577,7 +574,7 @@ LL_COMMON_API std::string utf8str_substChar( LL_COMMON_API std::string utf8str_makeASCII(const std::string& utf8str); // Hack - used for evil notecards. -LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str); +LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str); LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); @@ -608,7 +605,7 @@ LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); // Deal with the differeneces on Windows namespace snprintf_hack { - LL_COMMON_API int snprintf(char *str, size_t size, const char *format, ...); + LL_COMMON_API int snprintf(char *str, size_t size, const char *format, ...); } using snprintf_hack::snprintf; @@ -696,7 +693,7 @@ namespace LLStringFn //////////////////////////////////////////////////////////// // NOTE: LLStringUtil::format, getTokens, and support functions moved to llstring.cpp. // There is no LLWStringUtil::format implementation currently. -// Calling thse for anything other than LLStringUtil will produce link errors. +// Calling these for anything other than LLStringUtil will produce link errors. //////////////////////////////////////////////////////////// diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index db6e02ca2..4056b3253 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -1,32 +1,26 @@ /** * @file llsys.cpp - * @brief Impelementation of the basic system query functions. + * @brief Implementation of the basic system query functions. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 10f963d50..41a4f2500 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -2,31 +2,25 @@ * @file llsys.h * @brief System information debugging classes. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index ac97d37de..7970dd1d2 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -1,31 +1,25 @@ /** * @file llthread.cpp * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 549a090ec..3c54c8221 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -2,31 +2,25 @@ * @file llthread.h * @brief Base classes for thread, mutex and condition handling. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 007ee2816..fa81302cb 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -2,31 +2,25 @@ * @file lltimer.cpp * @brief Cross-platform objects for doing timing * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -262,11 +256,6 @@ U64 totalTime() // No wrapping, we're all okay. gTotalTimeClockCount += current_clock_count - gLastTotalTimeClockCount; } - else if((gLastTotalTimeClockCount - current_clock_count)<0xFFFF) - { - //clock is glitching and walking backwards - ignore it - gTotalTimeClockCount = gLastTotalTimeClockCount; - } else { // We've wrapped. Compensate correctly diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h index 2316944f4..167784f3c 100644 --- a/indra/llcommon/lltimer.h +++ b/indra/llcommon/lltimer.h @@ -2,31 +2,25 @@ * @file lltimer.h * @brief Cross-platform objects for doing timing * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index 673afd460..33a5dd2a0 100644 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -4,31 +4,25 @@ * @date 2006-02-08 * @brief Implementation of the LLURI class. * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,6 +37,8 @@ // system includes #include +#include +#include void encode_character(std::ostream& ostr, std::string::value_type val) { @@ -324,7 +320,7 @@ LLURI LLURI::buildHTTP(const std::string& prefix, const LLSD& path) { LLURI result; - + // TODO: deal with '/' '?' '#' in host_port if (prefix.find("://") != prefix.npos) { @@ -349,15 +345,41 @@ LLURI LLURI::buildHTTP(const std::string& prefix, result.mEscapedPath += "/" + escapePathComponent(it->asString()); } } - else if(path.isString()) + else if (path.isString()) { - result.mEscapedPath += "/" + escapePathComponent(path.asString()); + std::string pathstr(path); + // Trailing slash is significant in HTTP land. If caller specified, + // make a point of preserving. + std::string last_slash; + std::string::size_type len(pathstr.length()); + if (len && pathstr[len-1] == '/') + { + last_slash = "/"; + } + + // Escape every individual path component, recombining with slashes. + for (boost::split_iterator + ti(pathstr, boost::first_finder("/")), tend; + ti != tend; ++ti) + { + // Eliminate a leading slash or duplicate slashes anywhere. (Extra + // slashes show up here as empty components.) This test also + // eliminates a trailing slash, hence last_slash above. + if (! ti->empty()) + { + result.mEscapedPath + += "/" + escapePathComponent(std::string(ti->begin(), ti->end())); + } + } + + // Reinstate trailing slash, if any. + result.mEscapedPath += last_slash; } else if(path.isUndefined()) { // do nothing } - else + else { llwarns << "Valid path arguments to buildHTTP are array, string, or undef, you passed type" << path.type() << llendl; diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index 38084811b..1cbd888e5 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -1,31 +1,25 @@ /** * @file lluuid.cpp * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index 3a0d66e4a..726be4a82 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -1,31 +1,25 @@ /** * @file lluuid.h * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcommon/llversionviewer.h.in b/indra/llcommon/llversionviewer.h.in index 40933fcd4..030623505 100644 --- a/indra/llcommon/llversionviewer.h.in +++ b/indra/llcommon/llversionviewer.h.in @@ -35,7 +35,7 @@ const S32 LL_VERSION_MAJOR = 1; const S32 LL_VERSION_MINOR = 7; -const S32 LL_VERSION_PATCH = 2; +const S32 LL_VERSION_PATCH = 3; const S32 LL_VERSION_BUILD = ${vBUILD}; const char * const LL_CHANNEL = "${VIEWER_CHANNEL}"; diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index a5e0844c6..8106113df 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -1,31 +1,25 @@ /** * @file llworkerthread.cpp * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -345,7 +339,7 @@ bool LLWorkerClass::checkWork(bool aborting) } else { - llassert_always(workreq); + llassert_always(workreq); } return true ; } diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index 543fa1e56..2a96118c1 100644 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -1,31 +1,25 @@ /** * @file llworkerthread.h * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -81,7 +75,7 @@ public: }; protected: - void clearDeleteList(); + void clearDeleteList() ; private: typedef std::list delete_list_t; diff --git a/indra/llcommon/roles_constants.h b/indra/llcommon/roles_constants.h index a79d3e3bd..aa7ea3e5f 100644 --- a/indra/llcommon/roles_constants.h +++ b/indra/llcommon/roles_constants.h @@ -2,31 +2,25 @@ * @file roles_constants.h * @brief General Roles Constants * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -58,7 +52,6 @@ enum LLRoleChangeType // // KNOWN HOLES: use these for any single bit powers you need -// bit 0x1 << 41 // bit 0x1 << 46 // bit 0x1 << 49 and above @@ -111,6 +104,7 @@ const U64 GP_LAND_ALLOW_LANDMARK = 0x1 << 26; // Bypass Landmark Restriction const U64 GP_LAND_ALLOW_SET_HOME = 0x1 << 28; // Bypass Set Home Point Restriction const U64 GP_LAND_ALLOW_HOLD_EVENT = 0x1LL << 41; // Allowed to hold events on group-owned land + // Parcel Access const U64 GP_LAND_MANAGE_ALLOWED = 0x1 << 29; // Manage Allowed List const U64 GP_LAND_MANAGE_BANNED = 0x1 << 30; // Manage Banned List @@ -142,7 +136,9 @@ const U64 GP_NOTICES_SEND = 0x1LL << 42; // Send Notices const U64 GP_NOTICES_RECEIVE = 0x1LL << 43; // Receive Notices and View Notice History // Proposals +// TODO: _DEPRECATED suffix as part of vote removal - DEV-24856: const U64 GP_PROPOSAL_START = 0x1LL << 44; // Start Proposal +// TODO: _DEPRECATED suffix as part of vote removal - DEV-24856: const U64 GP_PROPOSAL_VOTE = 0x1LL << 45; // Vote on Proposal // Group chat moderation related @@ -155,18 +151,17 @@ const U64 GP_DEFAULT_MEMBER = GP_ACCOUNTING_ACCOUNTABLE | GP_NOTICES_RECEIVE | GP_PROPOSAL_START | GP_PROPOSAL_VOTE - | GP_SESSION_JOIN + | GP_SESSION_JOIN | GP_SESSION_VOICE ; -const U64 GP_DEFAULT_OFFICER = GP_ACCOUNTING_ACCOUNTABLE +const U64 GP_DEFAULT_OFFICER = GP_DEFAULT_MEMBER // Superset of GP_DEFAULT_MEMBER | GP_GROUP_CHANGE_IDENTITY | GP_LAND_ADMIN | GP_LAND_ALLOW_EDIT_LAND | GP_LAND_ALLOW_FLY | GP_LAND_ALLOW_CREATE | GP_LAND_ALLOW_LANDMARK - | GP_LAND_ALLOW_SET_HOME | GP_LAND_CHANGE_IDENTITY | GP_LAND_CHANGE_MEDIA | GP_LAND_DEED @@ -188,17 +183,12 @@ const U64 GP_DEFAULT_OFFICER = GP_ACCOUNTING_ACCOUNTABLE | GP_MEMBER_INVITE | GP_MEMBER_OPTIONS | GP_MEMBER_VISIBLE_IN_DIR - | GP_NOTICES_RECEIVE | GP_NOTICES_SEND | GP_OBJECT_DEED | GP_OBJECT_MANIPULATE | GP_OBJECT_SET_SALE - | GP_PROPOSAL_START - | GP_PROPOSAL_VOTE | GP_ROLE_ASSIGN_MEMBER_LIMITED | GP_ROLE_PROPERTIES | GP_SESSION_MODERATOR - | GP_SESSION_JOIN - | GP_SESSION_VOICE ; #endif diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h index ef0582f95..16a4ee854 100644 --- a/indra/llcommon/stdenums.h +++ b/indra/llcommon/stdenums.h @@ -2,31 +2,25 @@ * @file stdenums.h * @brief Enumerations for indra. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -55,7 +49,7 @@ enum EDragAndDropType DAD_ANIMATION = 12, DAD_GESTURE = 13, DAD_LINK = 14, - DAD_MESH = 15, + DAD_MESH = 15, DAD_COUNT = 16, // number of types in this enum }; diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 2537a4b87..7880271c3 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -60,22 +60,23 @@ extern AIHTTPTimeoutPolicy crashLoggerResponder_timeout; class LLCrashLoggerResponder : public LLHTTPClient::ResponderWithResult { public: - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return crashLoggerResponder_timeout; } - LLCrashLoggerResponder() { } - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { gBreak = true; } - virtual void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { gBreak = true; gSent = true; } + + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return crashLoggerResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLCrashLoggerResponder"; } }; bool LLCrashLoggerText::mainLoop() diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 66217f902..aa0086a53 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -2,31 +2,25 @@ * @file llimage.cpp * @brief Base class for images. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -180,11 +174,21 @@ U8* LLImageBase::allocateData(S32 size) llerrs << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,(S32)mComponents) << llendl; } } - else if (size <= 0 || (size > 4096*4096*16 && !mAllowOverSize)) - { - llerrs << "LLImageBase::allocateData: bad size: " << size << llendl; - } + //make this function thread-safe. + static const U32 MAX_BUFFER_SIZE = 4096 * 4096 * 16 ; //256 MB + if (size < 1 || size > MAX_BUFFER_SIZE) + { + //llinfos << "width: " << mWidth << " height: " << mHeight << " components: " << mComponents << llendl ; + if(mAllowOverSize) + { + //llinfos << "Oversize: " << size << llendl ; + } + else + { + llerrs << "LLImageBase::allocateData: bad size: " << size << llendl; + } + } if (!mData || size != mDataSize) { deleteData(); // virtual @@ -192,7 +196,7 @@ U8* LLImageBase::allocateData(S32 size) mData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size); if (!mData) { - llwarns << "allocate image data: " << size << llendl; + llwarns << "Failed to allocate image data size [" << size << "]" << llendl; size = 0 ; mWidth = mHeight = 0 ; mBadBufferAllocation = true ; @@ -206,6 +210,19 @@ U8* LLImageBase::allocateData(S32 size) // virtual U8* LLImageBase::reallocateData(S32 size) { + if (size == -1) + { + size = mWidth * mHeight * mComponents; + if (size <= 0) + { + llerrs << llformat("LLImageBase::reallocateData called with bad dimensions: %dx%dx%d", mWidth, mHeight, (S32)mComponents) << llendl; + } + } + else if (size <= 0 || (size > 4096 * 4096 * 16 && !mAllowOverSize)) + { + llerrs << "LLImageBase::reallocateData: bad size: " << size << llendl; + } + if(mData && (mDataSize == size)) return mData; @@ -300,6 +317,32 @@ LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components) ++sRawImageCount; } +LLImageRaw::LLImageRaw(LLImageRaw const* src, U16 width, U16 height, U16 crop_offset, bool crop_vertically) : mCacheEntries(0) +{ + mMemType = LLMemType::MTYPE_IMAGERAW; + llassert_always(src); + S8 const components = src->getComponents(); + U8 const* const data = src->getData(); + if (allocateDataSize(width, height, components)) + { + if (crop_vertically) + { + llassert_always(width == src->getWidth()); + memcpy(getData(), data + width * crop_offset * components, width * height * components); + } + else + { + llassert_always(height == src->getHeight()); + U16 const src_width = src->getWidth(); + for (U16 row = 0; row < height; ++row) + { + memcpy(getData() + width * row * components, data + (src_width * row + crop_offset) * components, width * components); + } + } + } + ++sRawImageCount; +} + /*LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only) : LLImageBase(), mCacheEntries(0) { @@ -459,22 +502,24 @@ void LLImageRaw::verticalFlip() { LLMemType mt1(mMemType); S32 row_bytes = getWidth() * getComponents(); - U8* line_buffer = new (std::nothrow) U8[row_bytes]; - if (!line_buffer ) + llassert(row_bytes > 0); + try { - llerrs << "Out of memory in LLImageRaw::verticalFlip()" << llendl; - return; - } + std::vector line_buffer(row_bytes); S32 mid_row = getHeight() / 2; for( S32 row = 0; row < mid_row; row++ ) { U8* row_a_data = getData() + row * row_bytes; U8* row_b_data = getData() + (getHeight() - 1 - row) * row_bytes; - memcpy( line_buffer, row_a_data, row_bytes ); /* Flawfinder: ignore */ - memcpy( row_a_data, row_b_data, row_bytes ); /* Flawfinder: ignore */ - memcpy( row_b_data, line_buffer, row_bytes ); /* Flawfinder: ignore */ + memcpy( &line_buffer[0], row_a_data, row_bytes ); + memcpy( row_a_data, row_b_data, row_bytes ); + memcpy( row_b_data, &line_buffer[0], row_bytes ); + } + } + catch(std::bad_alloc) + { + llerrs << "Out of memory in LLImageRaw::verticalFlip()" << llendl; } - delete[] line_buffer; } @@ -516,7 +561,7 @@ void LLImageRaw::contractToPowerOfTwo(S32 max_dim, BOOL scale_image) scale( new_width, new_height, scale_image ); } -void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim) +void LLImageRaw::biasedScaleToPowerOfTwo(S32 target_width, S32 target_height, S32 max_dim) { // Strong bias towards rounding down (to save bandwidth) // No bias would mean THRESHOLD == 1.5f; @@ -525,22 +570,22 @@ void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim) // Find new sizes S32 larger_w = max_dim; // 2^n >= mWidth S32 smaller_w = max_dim; // 2^(n-1) <= mWidth - while( (smaller_w > getWidth()) && (smaller_w > MIN_IMAGE_SIZE) ) + while( (smaller_w > target_width) && (smaller_w > MIN_IMAGE_SIZE) ) { larger_w = smaller_w; smaller_w >>= 1; } - S32 new_width = ( (F32)getWidth() / smaller_w > THRESHOLD ) ? larger_w : smaller_w; + S32 new_width = ( (F32)target_width / smaller_w > THRESHOLD ) ? larger_w : smaller_w; S32 larger_h = max_dim; // 2^m >= mHeight S32 smaller_h = max_dim; // 2^(m-1) <= mHeight - while( (smaller_h > getHeight()) && (smaller_h > MIN_IMAGE_SIZE) ) + while( (smaller_h > target_height) && (smaller_h > MIN_IMAGE_SIZE) ) { larger_h = smaller_h; smaller_h >>= 1; } - S32 new_height = ( (F32)getHeight() / smaller_h > THRESHOLD ) ? larger_h : smaller_h; + S32 new_height = ( (F32)target_height / smaller_h > THRESHOLD ) ? larger_h : smaller_h; scale( new_width, new_height ); @@ -602,27 +647,28 @@ void LLImageRaw::compositeScaled4onto3(LLImageRaw* src) llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) ); - // Vertical: scale but no composite S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents(); - U8* temp_buffer = new (std::nothrow) U8[ temp_data_size ]; - if (!temp_buffer ) + llassert_always(temp_data_size > 0); + try { - llerrs << "Out of memory in LLImageRaw::compositeScaled4onto3()" << llendl; - return; - } + std::vector temp_buffer(temp_data_size); + + // Vertical: scale but no composite for( S32 col = 0; col < src->getWidth(); col++ ) { - copyLineScaled( src->getData() + (src->getComponents() * col), temp_buffer + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() ); + copyLineScaled( src->getData() + (src->getComponents() * col), &temp_buffer[0] + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() ); } // Horizontal: scale and composite for( S32 row = 0; row < dst->getHeight(); row++ ) { - compositeRowScaled4onto3( temp_buffer + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() ); + compositeRowScaled4onto3( &temp_buffer[0] + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() ); + } + } + catch(std::bad_alloc) + { + llerrs << "Out of memory in LLImageRaw::compositeScaled4onto3()" << llendl; } - - // Clean up - delete[] temp_buffer; } @@ -858,28 +904,29 @@ void LLImageRaw::copyScaled( LLImageRaw* src ) return; } - // Vertical S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents(); llassert_always(temp_data_size > 0); - U8* temp_buffer = new (std::nothrow) U8[ temp_data_size ]; - if (!temp_buffer ) + try { - llerrs << "Out of memory in LLImageRaw::copyScaled()" << llendl; - return; - } + std::vector temp_buffer(temp_data_size); + + // Vertical for( S32 col = 0; col < src->getWidth(); col++ ) { - copyLineScaled( src->getData() + (getComponents() * col), temp_buffer + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() ); + copyLineScaled( src->getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() ); } // Horizontal for( S32 row = 0; row < dst->getHeight(); row++ ) { - copyLineScaled( temp_buffer + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 ); + copyLineScaled( &temp_buffer[0] + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 ); } - - // Clean up - delete[] temp_buffer; + } + catch(std::bad_alloc) + { + llerrs << "Out of memory in LLImageRaw::copyScaled()" << llendl; + } + } #if 0 @@ -943,76 +990,66 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data ) return TRUE; // Nothing to do. } - // Reallocate the data buffer. + U8* old_buffer = NULL; + U8* new_buffer; + S32 const old_width_bytes = old_width * getComponents(); + S32 const new_width_bytes = new_width * getComponents(); + S32 const min_height = llmin(old_height, new_height); + S32 const min_width_bytes = llmin(old_width_bytes, new_width_bytes); if (scale_image_data) { - // Vertical - S32 temp_data_size = old_width * new_height * getComponents(); - llassert_always(temp_data_size > 0); - U8* temp_buffer = new (std::nothrow) U8[ temp_data_size ]; - if (!temp_buffer ) + if (new_height != old_height) { - llerrs << "Out of memory in LLImageRaw::scale()" << llendl; - return FALSE; + // Resize vertically. + old_buffer = LLImageBase::release(); + new_buffer = allocateDataSize(old_width, new_height, getComponents()); + for (S32 col = 0; col < old_width; ++col) + { + copyLineScaled(old_buffer + getComponents() * col, new_buffer + getComponents() * col, old_height, new_height, old_width, old_width); + } + LLImageBase::deleteData(old_buffer); } - for( S32 col = 0; col < old_width; col++ ) + if (new_width != old_width) { - copyLineScaled( getData() + (getComponents() * col), temp_buffer + (getComponents() * col), old_height, new_height, old_width, old_width ); + // Resize horizontally. + old_buffer = LLImageBase::release(); + new_buffer = allocateDataSize(new_width, new_height, getComponents()); + for (S32 row = 0; row < new_height; ++row) + { + copyLineScaled(old_buffer + old_width_bytes * row, new_buffer + new_width_bytes * row, old_width, new_width, 1, 1); + } + LLImageBase::deleteData(old_buffer); } - - deleteData(); - - U8* new_buffer = allocateDataSize(new_width, new_height, getComponents()); - - // Horizontal - for( S32 row = 0; row < new_height; row++ ) - { - copyLineScaled( temp_buffer + (getComponents() * old_width * row), new_buffer + (getComponents() * new_width * row), old_width, new_width, 1, 1 ); - } - - // Clean up - delete[] temp_buffer; } else { - // copy out existing image data - S32 temp_data_size = old_width * old_height * getComponents(); - U8* temp_buffer = new (std::nothrow) U8[ temp_data_size ]; - if (!temp_buffer) + if (new_width == old_width) { - llwarns << "Out of memory in LLImageRaw::scale: old (w, h, c) = (" << old_width << ", " << old_height << ", " << (S32)getComponents() << - ") ; new (w, h, c) = (" << new_width << ", " << new_height << ", " << (S32)getComponents() << ")" << llendl; - - return FALSE ; + setSize(new_width, new_height, getComponents()); + new_buffer = reallocateData(); } - memcpy(temp_buffer, getData(), temp_data_size); /* Flawfinder: ignore */ - - // 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++ ) + else { - if (row < old_height) + old_buffer = LLImageBase::release(); + new_buffer = allocateDataSize(new_width, new_height, getComponents()); + for (S32 row = 0; row < min_height; ++row) { - memcpy(new_buffer + (new_width * row * getComponents()), temp_buffer + (old_width * row * getComponents()), getComponents() * llmin(old_width, new_width)); /* Flawfinder: ignore */ - if (old_width < new_width) + memcpy(new_buffer + row * new_width_bytes, old_buffer + row * old_width_bytes, min_width_bytes); + if (new_width_bytes > old_width_bytes) { - // pad out rest of row with black - memset(new_buffer + (getComponents() * ((new_width * row) + old_width)), 0, getComponents() * (new_width - old_width)); + // Pad out rest of row with black. + memset(new_buffer + new_width_bytes * row + old_width_bytes, 0, new_width_bytes - old_width_bytes); } } - else - { - // pad remaining rows with black - memset(new_buffer + (new_width * row * getComponents()), 0, new_width * getComponents()); - } + LLImageBase::deleteData(old_buffer); + } + if (new_height > old_height) + { + // Pad remaining rows with black. + memset(new_buffer + new_width_bytes * min_height, 0, new_width_bytes * (new_height - old_height)); } - - // Clean up - delete[] temp_buffer; } - return TRUE ; } @@ -1330,7 +1367,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip llassert(image.notNull()); U8 *buffer = image->allocateData(length); - ifs.read ((char*)buffer, length); /* Flawfinder: ignore */ + ifs.read ((char*)buffer, length); ifs.close(); BOOL success; @@ -1578,6 +1615,7 @@ void LLImageFormatted::setData(U8 *data, S32 size) { deleteData(); setDataAndSize(data, size); // Access private LLImageBase members + sGlobalFormattedMemory += getDataSize(); } } @@ -1603,7 +1641,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size) //---------------------------------------------------------------------------- -BOOL LLImageFormatted::load(const std::string &filename) +BOOL LLImageFormatted::load(const std::string &filename, int load_size) { resetLastError(); @@ -1621,14 +1659,19 @@ BOOL LLImageFormatted::load(const std::string &filename) return FALSE; } + // Constrain the load size to acceptable values + if ((load_size == 0) || (load_size > file_size)) + { + load_size = file_size; + } BOOL res; - U8 *data = allocateData(file_size); - apr_size_t bytes_read = file_size; + 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 - if (s != APR_SUCCESS || (S32) bytes_read != file_size) + if (s != APR_SUCCESS || (S32) bytes_read != load_size) { deleteData(); - setLastError("Unable to read entire file",filename); + setLastError("Unable to read file",filename); res = FALSE; } else @@ -1690,6 +1733,12 @@ static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2); } +void LLImageBase::setDataAndSize(U8 *data, S32 size) +{ + ll_assert_aligned(data, 16); + mData = data; mDataSize = size; +} + //static void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 height, S32 nchannels) { diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 3782ff1cf..a9b7485da 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -114,6 +114,8 @@ public: virtual void deleteData(); virtual U8* allocateData(S32 size = -1); virtual U8* reallocateData(S32 size = -1); + static void deleteData(U8* data) { FREE_MEM(sPrivatePoolp, data); } + U8* release() { U8* data = mData; mData = NULL; mDataSize = 0; return data; } // Same as deleteData(), but returns old data. Call deleteData(old_data) to free it. virtual void dump(); virtual void sanityCheck(); @@ -134,7 +136,7 @@ public: protected: // special accessor to allow direct setting of mData and mDataSize by LLImageFormatted - void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; } + void setDataAndSize(U8 *data, S32 size); public: static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels); @@ -175,12 +177,13 @@ public: LLImageRaw(); LLImageRaw(U16 width, U16 height, S8 components); LLImageRaw(U8 *data, U16 width, U16 height, S8 components); + LLImageRaw(LLImageRaw const* src, U16 width, U16 height, U16 crop_offset, bool crop_vertically); // Construct using createFromFile (used by tools) //LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false); /*virtual*/ void deleteData(); /*virtual*/ U8* allocateData(S32 size = -1); - /*virtual*/ U8* reallocateData(S32 size); + /*virtual*/ U8* reallocateData(S32 size = -1); BOOL resize(U16 width, U16 height, S8 components); @@ -194,7 +197,8 @@ public: 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); + void biasedScaleToPowerOfTwo(S32 target_width, S32 target_height, S32 max_dim = MAX_IMAGE_SIZE); + void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE) { biasedScaleToPowerOfTwo(getWidth(), getHeight(), max_dim); } BOOL scale( S32 new_width, S32 new_height, BOOL scale_image = TRUE ); //BOOL scaleDownWithoutBlending( S32 new_width, S32 new_height) ; @@ -287,7 +291,7 @@ public: // LLImageBase /*virtual*/ void deleteData(); /*virtual*/ U8* allocateData(S32 size = -1); - /*virtual*/ U8* reallocateData(S32 size); + /*virtual*/ U8* reallocateData(S32 size = -1); /*virtual*/ void dump(); /*virtual*/ void sanityCheck(); @@ -296,16 +300,16 @@ public: // subclasses must return a prefered file extension (lowercase without a leading dot) virtual std::string getExtension() = 0; // calcHeaderSize() returns the maximum size of header; - // 0 indicates we don't know have a header and have to lead the entire file + // 0 indicates we don't have a header and have to read the entire file virtual S32 calcHeaderSize() { return 0; }; // calcDataSize() returns how many bytes to read to load discard_level (including header) virtual S32 calcDataSize(S32 discard_level); // calcDiscardLevelBytes() returns the smallest valid discard level based on the number of input bytes virtual S32 calcDiscardLevelBytes(S32 bytes); - // getRawDiscardLevel()by default returns mDiscardLevel, but may be overridden (LLImageJ2C) + // getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C) virtual S8 getRawDiscardLevel() { return mDiscardLevel; } - BOOL load(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 diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index b39ae0c04..987c95f3f 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -1,31 +1,25 @@ /** * @file llimagej2c.cpp * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #if LL_LINUX && defined(LL_STANDALONE) diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index 56782fbf0..6d6e097e4 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -2,31 +2,25 @@ * @file llimagej2c.h * @brief Image implmenation for jpeg2000. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 57388541a..161b25f5e 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -2,31 +2,25 @@ * @file llimageworker.cpp * @brief Base class for images. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index 7af311d36..6d9ae3fe9 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -2,31 +2,25 @@ * @file llimageworker.h * @brief Object for managing images and their textures. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h index 276709d1a..5f3ad0d5a 100644 --- a/indra/llimage/llpngwrapper.h +++ b/indra/llimage/llpngwrapper.h @@ -1,31 +1,25 @@ /* * @file llpngwrapper.h * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index bf7acc6d1..7de5ba69d 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llimagej2coj.cpp * @brief This is an implementation of JPEG2000 encode/decode using OpenJPEG. * @@ -35,9 +35,7 @@ const char* fallbackEngineInfoLLImageJ2CImpl() { - static std::string version_string = - std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ") - + opj_version(); + static std::string version_string = std::string("OpenJPEG: ") + opj_version(); return version_string.c_str(); } @@ -186,7 +184,15 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod { opj_image_destroy(image); } - +#if 0 + std::stringstream filename; + filename << "err" << (int)base.getRawDiscardLevel() << "_" << rand() << ".jp2"; + FILE* file = fopen(filename.str().c_str(), "wb"); + if (file) { + fwrite(base.getData(), base.getDataSize(), 1, file); + fclose(file); + } +#endif base.decodeFailed(); return TRUE; // done } diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 1f1f4ce38..31cca09fd 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -2,31 +2,25 @@ * @file llinventory.cpp * @brief Implementation of the inventory system. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -845,7 +839,7 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream) } else if(0 == strcmp("permissions", keyword)) { - success = mPermissions.importLegacyStream(input_stream); + success = mPermissions.importStream(input_stream); } else if(0 == strcmp("sale_info", keyword)) { @@ -855,7 +849,7 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream) // should pick up the vast majority of the tasks. BOOL has_perm_mask = FALSE; U32 perm_mask = 0; - success = mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask); + success = mSaleInfo.importStream(input_stream, has_perm_mask, perm_mask); if(has_perm_mask) { if(perm_mask == PERM_NONE) @@ -971,7 +965,7 @@ BOOL LLInventoryItem::exportLegacyStream(std::ostream& output_stream, BOOL inclu output_stream << "\t\titem_id\t" << uuid_str << "\n"; mParentUUID.toString(uuid_str); output_stream << "\t\tparent_id\t" << uuid_str << "\n"; - mPermissions.exportLegacyStream(output_stream); + mPermissions.exportStream(output_stream); // Check for permissions to see the asset id, and if so write it // out as an asset id. Otherwise, apply our cheesy encryption. @@ -1005,7 +999,7 @@ BOOL LLInventoryItem::exportLegacyStream(std::ostream& output_stream, BOOL inclu std::string buffer; buffer = llformat( "\t\tflags\t%08x\n", mFlags); output_stream << buffer; - mSaleInfo.exportLegacyStream(output_stream); + mSaleInfo.exportStream(output_stream); output_stream << "\t\tname\t" << mName.c_str() << "|\n"; output_stream << "\t\tdesc\t" << mDescription.c_str() << "|\n"; output_stream << "\t\tcreation_date\t" << mCreationDate << "\n"; @@ -1123,7 +1117,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd) { if (sd[w].isString()) { - mType = LLAssetType::lookup(sd[w].asString()); + mType = LLAssetType::lookup(sd[w].asString().c_str()); } else if (sd[w].isInteger()) { diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index 14c04a0d1..bf701d39a 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -2,31 +2,25 @@ * @file llinventory.h * @brief LLInventoryItem and LLInventoryCategory class declaration. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -200,9 +194,9 @@ public: // Assumes you have already called nextBlock(). virtual void packMessage(LLMessageSystem* msg) const; - // unpack returns TRUE if the inventory item came through the - // network ok. It uses a simple crc check which is defeatable, but - // we want to detect network mangling somehow. + // Returns TRUE if the inventory item came through the network correctly. + // Uses a simple crc check which is defeatable, but we want to detect + // network mangling somehow. virtual BOOL unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0); //-------------------------------------------------------------------- @@ -241,9 +235,8 @@ protected: //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInventoryCategory // -// An instance of this class represents a category of inventory -// items. Users come with a set of default categories, and can create -// new ones as needed. +// A category/folder of inventory items. Users come with a set of default +// categories, and can create new ones as needed. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLInventoryCategory : public LLInventoryObject { diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index a174f08c1..1f30c771b 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -2,31 +2,25 @@ * @file llinventorytype.cpp * @brief Inventory item type, more specific than an asset type. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -98,30 +92,31 @@ LLInventoryDictionary::LLInventoryDictionary() static const LLInventoryType::EType DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = { - LLInventoryType::IT_TEXTURE, // AT_TEXTURE - LLInventoryType::IT_SOUND, // AT_SOUND - LLInventoryType::IT_CALLINGCARD, // AT_CALLINGCARD - LLInventoryType::IT_LANDMARK, // AT_LANDMARK - LLInventoryType::IT_LSL, // AT_SCRIPT - LLInventoryType::IT_WEARABLE, // AT_CLOTHING - LLInventoryType::IT_OBJECT, // AT_OBJECT - LLInventoryType::IT_NOTECARD, // AT_NOTECARD - LLInventoryType::IT_CATEGORY, // AT_CATEGORY - LLInventoryType::IT_ROOT_CATEGORY, // AT_ROOT_CATEGORY - LLInventoryType::IT_LSL, // AT_LSL_TEXT - LLInventoryType::IT_LSL, // AT_LSL_BYTECODE - LLInventoryType::IT_TEXTURE, // AT_TEXTURE_TGA - LLInventoryType::IT_WEARABLE, // AT_BODYPART - LLInventoryType::IT_CATEGORY, // AT_TRASH - LLInventoryType::IT_CATEGORY, // AT_SNAPSHOT_CATEGORY - LLInventoryType::IT_CATEGORY, // AT_LOST_AND_FOUND - LLInventoryType::IT_SOUND, // AT_SOUND_WAV - LLInventoryType::IT_NONE, // AT_IMAGE_TGA - LLInventoryType::IT_NONE, // AT_IMAGE_JPEG - LLInventoryType::IT_ANIMATION, // AT_ANIMATION - LLInventoryType::IT_GESTURE, // AT_GESTURE - LLInventoryType::IT_NONE, // AT_SIMSTATE - LLInventoryType::IT_NONE, // AT_FAVORITE + LLInventoryType::IT_TEXTURE, // 0 AT_TEXTURE + LLInventoryType::IT_SOUND, // 1 AT_SOUND + LLInventoryType::IT_CALLINGCARD, // 2 AT_CALLINGCARD + LLInventoryType::IT_LANDMARK, // 3 AT_LANDMARK + LLInventoryType::IT_LSL, // 4 AT_SCRIPT + LLInventoryType::IT_WEARABLE, // 5 AT_CLOTHING + LLInventoryType::IT_OBJECT, // 6 AT_OBJECT + LLInventoryType::IT_NOTECARD, // 7 AT_NOTECARD + LLInventoryType::IT_CATEGORY, // 8 AT_CATEGORY + LLInventoryType::IT_ROOT_CATEGORY, // 9 AT_ROOT_CATEGORY + LLInventoryType::IT_LSL, // 10 AT_LSL_TEXT + LLInventoryType::IT_LSL, // 11 AT_LSL_BYTECODE + LLInventoryType::IT_TEXTURE, // 12 AT_TEXTURE_TGA + LLInventoryType::IT_WEARABLE, // 13 AT_BODYPART + LLInventoryType::IT_CATEGORY, // 14 AT_TRASH + LLInventoryType::IT_CATEGORY, // 15 AT_SNAPSHOT_CATEGORY + LLInventoryType::IT_CATEGORY, // 16 AT_LOST_AND_FOUND + LLInventoryType::IT_SOUND, // 17 AT_SOUND_WAV + LLInventoryType::IT_NONE, // 18 AT_IMAGE_TGA + LLInventoryType::IT_NONE, // 19 AT_IMAGE_JPEG + LLInventoryType::IT_ANIMATION, // 20 AT_ANIMATION + LLInventoryType::IT_GESTURE, // 21 AT_GESTURE + LLInventoryType::IT_NONE, // 22 AT_SIMSTATE + + LLInventoryType::IT_NONE, // 23 AT_LINK LLInventoryType::IT_NONE, // 24 AT_LINK_FOLDER LLInventoryType::IT_NONE, // 25 AT_NONE @@ -148,7 +143,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = LLInventoryType::IT_NONE, // 46 AT_NONE LLInventoryType::IT_NONE, // 47 AT_NONE LLInventoryType::IT_NONE, // 48 AT_NONE - LLInventoryType::IT_MESH // 49 AT_MESH + LLInventoryType::IT_MESH, // 49 AT_MESH }; // static diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h index f833ec692..36f3ce264 100644 --- a/indra/llinventory/llinventorytype.h +++ b/indra/llinventory/llinventorytype.h @@ -2,31 +2,25 @@ * @file llinventorytype.h * @brief Inventory item type, more specific than an asset type. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -67,13 +61,59 @@ public: IT_WEARABLE = 18, IT_ANIMATION = 19, IT_GESTURE = 20, - IT_MESH = 22, IT_COUNT = 23, IT_NONE = -1 }; + enum EIconName + { + ICONNAME_TEXTURE, + ICONNAME_SOUND, + ICONNAME_CALLINGCARD_ONLINE, + ICONNAME_CALLINGCARD_OFFLINE, + ICONNAME_LANDMARK, + ICONNAME_LANDMARK_VISITED, + ICONNAME_SCRIPT, + ICONNAME_CLOTHING, + ICONNAME_OBJECT, + ICONNAME_OBJECT_MULTI, + ICONNAME_NOTECARD, + ICONNAME_BODYPART, + ICONNAME_SNAPSHOT, + + ICONNAME_BODYPART_SHAPE, + ICONNAME_BODYPART_SKIN, + ICONNAME_BODYPART_HAIR, + ICONNAME_BODYPART_EYES, + ICONNAME_CLOTHING_SHIRT, + ICONNAME_CLOTHING_PANTS, + ICONNAME_CLOTHING_SHOES, + ICONNAME_CLOTHING_SOCKS, + ICONNAME_CLOTHING_JACKET, + ICONNAME_CLOTHING_GLOVES, + ICONNAME_CLOTHING_UNDERSHIRT, + ICONNAME_CLOTHING_UNDERPANTS, + ICONNAME_CLOTHING_SKIRT, + ICONNAME_CLOTHING_ALPHA, + ICONNAME_CLOTHING_TATTOO, + + ICONNAME_ANIMATION, + ICONNAME_GESTURE, + + ICONNAME_CLOTHING_PHYSICS, + + ICONNAME_LINKITEM, + ICONNAME_LINKFOLDER, + ICONNAME_MESH, + + ICONNAME_INVALID, + ICONNAME_COUNT, + ICONNAME_NONE = -1 + }; + + // machine transation between type and strings static EType lookup(const std::string& name); static const std::string &lookup(EType type); @@ -92,7 +132,7 @@ private: ~LLInventoryType( void ); }; -// helper function which returns true if inventory type and asset type +// helper function that returns true if inventory type and asset type // are potentially compatible. For example, an attachment must be an // object, but a wearable can be a bodypart or clothing asset. bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type, diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index e92ae5dc0..8512a248b 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -2,31 +2,25 @@ * @file llparcel.cpp * @brief A land parcel. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -718,6 +712,7 @@ void LLParcel::unpackMessage(LLMessageSystem* msg) msg->getS32("MediaData", "MediaWidth", mMediaWidth); msg->getS32("MediaData", "MediaHeight", mMediaHeight); msg->getU8 ( "MediaData", "MediaLoop", mMediaLoop ); + // the ObscureMedia and ObscureMusic flags previously set here are no longer used } else { diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index 9683252dc..34354e3e8 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -3,31 +3,25 @@ * @author Phoenix * @brief Permissions for objects and inventory. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -578,143 +572,17 @@ void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 b BOOL LLPermissions::importFile(LLFILE* fp) { - init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null); - const S32 BUFSIZE = 16384; - - // *NOTE: Changing the buffer size will require changing the scanf - // calls below. - char buffer[BUFSIZE]; /* Flawfinder: ignore */ - char keyword[256]; /* Flawfinder: ignore */ - char valuestr[256]; /* Flawfinder: ignore */ - char uuid_str[256]; /* Flawfinder: ignore */ - U32 mask; - - keyword[0] = '\0'; - valuestr[0] = '\0'; - - while (!feof(fp)) - { - if (fgets(buffer, BUFSIZE, fp) == NULL) - { - buffer[0] = '\0'; - } - - sscanf( /* Flawfinder: ignore */ - buffer, - " %255s %255s", - keyword, valuestr); - if (!strcmp("{", keyword)) - { - continue; - } - if (!strcmp("}",keyword)) - { - break; - } - else if (!strcmp("creator_mask", keyword)) - { - // legacy support for "creator" masks - sscanf(valuestr, "%x", &mask); - mMaskBase = mask; - fixFairUse(); - } - else if (!strcmp("base_mask", keyword)) - { - sscanf(valuestr, "%x", &mask); - mMaskBase = mask; - //fixFairUse(); - } - else if (!strcmp("owner_mask", keyword)) - { - sscanf(valuestr, "%x", &mask); - mMaskOwner = mask; - } - else if (!strcmp("group_mask", keyword)) - { - sscanf(valuestr, "%x", &mask); - mMaskGroup = mask; - } - else if (!strcmp("everyone_mask", keyword)) - { - sscanf(valuestr, "%x", &mask); - mMaskEveryone = mask; - } - else if (!strcmp("next_owner_mask", keyword)) - { - sscanf(valuestr, "%x", &mask); - mMaskNextOwner = mask; - } - else if (!strcmp("creator_id", keyword)) - { - sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ - mCreator.set(uuid_str); - } - else if (!strcmp("owner_id", keyword)) - { - sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ - mOwner.set(uuid_str); - } - else if (!strcmp("last_owner_id", keyword)) - { - sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ - mLastOwner.set(uuid_str); - } - else if (!strcmp("group_id", keyword)) - { - sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ - mGroup.set(uuid_str); - } - else if (!strcmp("group_owned", keyword)) - { - sscanf(valuestr, "%d", &mask); - if(mask) mIsGroupOwned = true; - else mIsGroupOwned = false; - } - else - { - llinfos << "unknown keyword " << keyword << " in permissions import" << llendl; - } - } - fix(); - return TRUE; + llifstream ifs(fp); + return importStream(ifs); } - BOOL LLPermissions::exportFile(LLFILE* fp) const { - std::string uuid_str; - - fprintf(fp, "\tpermissions 0\n"); - fprintf(fp, "\t{\n"); - - fprintf(fp, "\t\tbase_mask\t%08x\n", mMaskBase); - fprintf(fp, "\t\towner_mask\t%08x\n", mMaskOwner); - fprintf(fp, "\t\tgroup_mask\t%08x\n", mMaskGroup); - fprintf(fp, "\t\teveryone_mask\t%08x\n", mMaskEveryone); - fprintf(fp, "\t\tnext_owner_mask\t%08x\n", mMaskNextOwner); - - mCreator.toString(uuid_str); - fprintf(fp, "\t\tcreator_id\t%s\n", uuid_str.c_str()); - - mOwner.toString(uuid_str); - fprintf(fp, "\t\towner_id\t%s\n", uuid_str.c_str()); - - mLastOwner.toString(uuid_str); - fprintf(fp, "\t\tlast_owner_id\t%s\n", uuid_str.c_str()); - - mGroup.toString(uuid_str); - fprintf(fp, "\t\tgroup_id\t%s\n", uuid_str.c_str()); - - if(mIsGroupOwned) - { - fprintf(fp, "\t\tgroup_owned\t1\n"); - } - fprintf(fp,"\t}\n"); - return TRUE; + llofstream ofs(fp); + return exportStream(ofs); } - -BOOL LLPermissions::importLegacyStream(std::istream& input_stream) +BOOL LLPermissions::importStream(std::istream& input_stream) { init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null); const S32 BUFSIZE = 16384; @@ -733,6 +601,18 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream) while (input_stream.good()) { input_stream.getline(buffer, BUFSIZE); + if (input_stream.eof()) + { + llwarns << "Bad permissions: early end of input stream" + << llendl; + return FALSE; + } + if (input_stream.fail()) + { + llwarns << "Bad permissions: failed to read from input stream" + << llendl; + return FALSE; + } sscanf( /* Flawfinder: ignore */ buffer, " %255s %255s", @@ -806,7 +686,8 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream) } else { - llinfos << "unknown keyword " << keyword << " in permissions import" << llendl; + llwarns << "unknown keyword " << keyword + << " in permissions import" << llendl; } } fix(); @@ -814,36 +695,26 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream) } -BOOL LLPermissions::exportLegacyStream(std::ostream& output_stream) const +BOOL LLPermissions::exportStream(std::ostream& output_stream) const { - std::string uuid_str; - + if (!output_stream.good()) return FALSE; output_stream << "\tpermissions 0\n"; output_stream << "\t{\n"; - std::string buffer; - buffer = llformat( "\t\tbase_mask\t%08x\n", mMaskBase); - output_stream << buffer; - buffer = llformat( "\t\towner_mask\t%08x\n", mMaskOwner); - output_stream << buffer; - buffer = llformat( "\t\tgroup_mask\t%08x\n", mMaskGroup); - output_stream << buffer; - buffer = llformat( "\t\teveryone_mask\t%08x\n", mMaskEveryone); - output_stream << buffer; - buffer = llformat( "\t\tnext_owner_mask\t%08x\n", mMaskNextOwner); - output_stream << buffer; + char prev_fill = output_stream.fill('0'); + output_stream << std::hex; + output_stream << "\t\tbase_mask\t" << std::setw(8) << mMaskBase << "\n"; + output_stream << "\t\towner_mask\t" << std::setw(8) << mMaskOwner << "\n"; + output_stream << "\t\tgroup_mask\t" << std::setw(8) << mMaskGroup << "\n"; + output_stream << "\t\teveryone_mask\t" << std::setw(8) << mMaskEveryone << "\n"; + output_stream << "\t\tnext_owner_mask\t" << std::setw(8) << mMaskNextOwner << "\n"; + output_stream << std::dec; + output_stream.fill(prev_fill); - mCreator.toString(uuid_str); - output_stream << "\t\tcreator_id\t" << uuid_str << "\n"; - - mOwner.toString(uuid_str); - output_stream << "\t\towner_id\t" << uuid_str << "\n"; - - mLastOwner.toString(uuid_str); - output_stream << "\t\tlast_owner_id\t" << uuid_str << "\n"; - - mGroup.toString(uuid_str); - output_stream << "\t\tgroup_id\t" << uuid_str << "\n"; + output_stream << "\t\tcreator_id\t" << mCreator << "\n"; + output_stream << "\t\towner_id\t" << mOwner << "\n"; + output_stream << "\t\tlast_owner_id\t" << mLastOwner << "\n"; + output_stream << "\t\tgroup_id\t" << mGroup << "\n"; if(mIsGroupOwned) { diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index fa20d5c21..7d3a68d35 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -2,31 +2,25 @@ * @file llpermissions.h * @brief Permissions structures for objects. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -322,8 +316,8 @@ public: BOOL importFile(LLFILE* fp); BOOL exportFile(LLFILE* fp) const; - BOOL importLegacyStream(std::istream& input_stream); - BOOL exportLegacyStream(std::ostream& output_stream) const; + BOOL importStream(std::istream& input_stream); + BOOL exportStream(std::ostream& output_stream) const; bool operator==(const LLPermissions &rhs) const; bool operator!=(const LLPermissions &rhs) const; diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp index 88e7da7ac..b39f02f6a 100644 --- a/indra/llinventory/llsaleinfo.cpp +++ b/indra/llinventory/llsaleinfo.cpp @@ -87,15 +87,13 @@ U32 LLSaleInfo::getCRC32() const BOOL LLSaleInfo::exportFile(LLFILE* fp) const { - fprintf(fp, "\tsale_info\t0\n\t{\n"); - fprintf(fp, "\t\tsale_type\t%s\n", lookup(mSaleType)); - fprintf(fp, "\t\tsale_price\t%d\n", mSalePrice); - fprintf(fp,"\t}\n"); - return TRUE; + llofstream ofs(fp); + return exportStream(ofs); } -BOOL LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const +BOOL LLSaleInfo::exportStream(std::ostream& output_stream) const { + if (!output_stream.good()) return FALSE; output_stream << "\tsale_info\t0\n\t{\n"; output_stream << "\t\tsale_type\t" << lookup(mSaleType) << "\n"; output_stream << "\t\tsale_price\t" << mSalePrice << "\n"; @@ -140,80 +138,39 @@ bool LLSaleInfo::fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask) BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask) { - has_perm_mask = FALSE; - - // *NOTE: Changing the buffer size will require changing the scanf - // calls below. - char buffer[MAX_STRING]; /* Flawfinder: ignore */ - char keyword[MAX_STRING]; /* Flawfinder: ignore */ - char valuestr[MAX_STRING]; /* Flawfinder: ignore */ - BOOL success = TRUE; - - keyword[0] = '\0'; - valuestr[0] = '\0'; - while(success && (!feof(fp))) - { - if (fgets(buffer, MAX_STRING, fp) == NULL) - { - buffer[0] = '\0'; - } - - sscanf( /* Flawfinder: ignore */ - buffer, - " %254s %254s", - keyword, valuestr); - if(!keyword[0]) - { - continue; - } - if(0 == strcmp("{",keyword)) - { - continue; - } - if(0 == strcmp("}", keyword)) - { - break; - } - else if(0 == strcmp("sale_type", keyword)) - { - mSaleType = lookup(valuestr); - } - else if(0 == strcmp("sale_price", keyword)) - { - sscanf(valuestr, "%d", &mSalePrice); - mSalePrice = llclamp(mSalePrice, 0, S32_MAX); - } - else if (!strcmp("perm_mask", keyword)) - { - //llinfos << "found deprecated keyword perm_mask" << llendl; - has_perm_mask = TRUE; - sscanf(valuestr, "%x", &perm_mask); - } - else - { - llwarns << "unknown keyword '" << keyword - << "' in sale info import" << llendl; - } - } - return success; + llifstream ifs(fp); + return importStream(ifs, has_perm_mask, perm_mask); } -BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask) +BOOL LLSaleInfo::importStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask) { has_perm_mask = FALSE; + const S32 BUFSIZE = 16384; + // *NOTE: Changing the buffer size will require changing the scanf // calls below. - char buffer[MAX_STRING]; /* Flawfinder: ignore */ - char keyword[MAX_STRING]; /* Flawfinder: ignore */ - char valuestr[MAX_STRING]; /* Flawfinder: ignore */ - BOOL success = TRUE; + char buffer[BUFSIZE]; /* Flawfinder: ignore */ + char keyword[255]; /* Flawfinder: ignore */ + char valuestr[255]; /* Flawfinder: ignore */ keyword[0] = '\0'; valuestr[0] = '\0'; - while(success && input_stream.good()) + while(input_stream.good()) { input_stream.getline(buffer, MAX_STRING); + if (input_stream.eof()) + { + llwarns << "Bad sale info: early end of input stream" + << llendl; + return FALSE; + } + if (input_stream.fail()) + { + llwarns << "Bad sale info: failed to read from input stream" + << llendl; + return FALSE; + } sscanf( /* Flawfinder: ignore */ buffer, " %254s %254s", @@ -251,7 +208,7 @@ BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_m << "' in sale info import" << llendl; } } - return success; + return TRUE; } void LLSaleInfo::setSalePrice(S32 price) diff --git a/indra/llinventory/llsaleinfo.h b/indra/llinventory/llsaleinfo.h index 3461a128b..026e042bc 100644 --- a/indra/llinventory/llsaleinfo.h +++ b/indra/llinventory/llsaleinfo.h @@ -95,11 +95,11 @@ public: BOOL exportFile(LLFILE* fp) const; BOOL importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask); - BOOL exportLegacyStream(std::ostream& output_stream) const; + BOOL exportStream(std::ostream& output_stream) const; LLSD asLLSD() const; operator LLSD() const { return asLLSD(); } bool fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask); - BOOL importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask); + BOOL importStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask); LLSD packMessage() const; void unpackMessage(LLSD sales); diff --git a/indra/llinventory/lltransactionflags.cpp b/indra/llinventory/lltransactionflags.cpp index fda8cad90..084107c83 100644 --- a/indra/llinventory/lltransactionflags.cpp +++ b/indra/llinventory/lltransactionflags.cpp @@ -3,31 +3,25 @@ * @brief Some exported symbols and functions for dealing with * transaction flags. * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index 0459f797c..97e56b2a2 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -66,7 +66,7 @@ static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD; // roll(), pitch(), yaw() // etc... - +LL_ALIGN_PREFIX(16) class LLCamera : public LLCoordFrame { @@ -114,7 +114,7 @@ public: }; private: - LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP + LL_ALIGN_16(LLPlane mAgentPlanes[7]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP U8 mPlaneMask[8]; // 8 for alignment F32 mView; // angle between top and bottom frustum planes in radians. @@ -122,13 +122,13 @@ private: S32 mViewHeightInPixels; // for ViewHeightInPixels() only F32 mNearPlane; F32 mFarPlane; - LLPlane mLocalPlanes[4]; + LL_ALIGN_16(LLPlane mLocalPlanes[4]); F32 mFixedDistance; // Always return this distance, unless < 0 LLVector3 mFrustCenter; // center of frustum and radius squared for ultra-quick exclusion test F32 mFrustRadiusSquared; - LLPlane mWorldPlanes[PLANE_NUM]; - LLPlane mHorizPlanes[HORIZ_PLANE_NUM]; + LL_ALIGN_16(LLPlane mWorldPlanes[PLANE_NUM]); + LL_ALIGN_16(LLPlane mHorizPlanes[HORIZ_PLANE_NUM]); U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in @@ -214,7 +214,7 @@ protected: void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom); void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2); void calculateWorldFrustumPlanes(); -}; +} LL_ALIGN_POSTFIX(16); #endif diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index bb6c6deff..6d3f06710 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -2,31 +2,25 @@ * @file llmath.h * @brief Useful math constants and macros. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -522,6 +516,7 @@ inline void ll_remove_outliers(std::vector& data, F32 k) return; } + VEC_TYPE min = (VEC_TYPE) ((F32) Q1-k * (F32) (Q3-Q1)); VEC_TYPE max = (VEC_TYPE) ((F32) Q3+k * (F32) (Q3-Q1)); @@ -550,4 +545,5 @@ inline void ll_remove_outliers(std::vector& data, F32 k) // Include simd math header #include "llsimdmath.h" + #endif diff --git a/indra/llmath/llmatrix3a.h b/indra/llmath/llmatrix3a.h index adb7e3389..9916cfd2d 100644 --- a/indra/llmath/llmatrix3a.h +++ b/indra/llmath/llmatrix3a.h @@ -111,7 +111,7 @@ public: protected: - LLVector4a mColumns[3]; + LL_ALIGN_16(LLVector4a mColumns[3]); }; diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 0c61fc96f..94e5e54af 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -34,7 +34,7 @@ class LLMatrix4a { public: - LLVector4a mMatrix[4]; + LL_ALIGN_16(LLVector4a mMatrix[4]); inline void clear() { diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index b642c6317..d22f2d70d 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -2,31 +2,25 @@ * @file lloctree.h * @brief Octree declaration. * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,6 +31,7 @@ #include "v3math.h" #include "llvector4a.h" #include +#include #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG #define OCT_ERRS LL_ERRS("OctreeErrors") @@ -46,6 +41,7 @@ #endif extern U32 gOctreeMaxCapacity; +extern U32 gOctreeReserveCapacity; #if LL_DEBUG #define LL_OCTREE_PARANOIA_CHECK 0 #else @@ -56,6 +52,106 @@ extern U32 gOctreeMaxCapacity; template class LLOctreeNode; +#include "lltimer.h" + +//#define LL_OCTREE_STATS +#define LL_OCTREE_POOLS +#ifdef LL_OCTREE_STATS +class OctreeStats : public LLSingleton +{ +public: + OctreeStats() : + mPeriodNodesCreated(0), + mPeriodNodesDestroyed(0), + mPeriodAllocs(0), + mPeriodFrees(0), + mPeriodLargestSize(0), + mTotalNodes(0), + mTotalAllocs(0), + mTotalFrees(0), + mLargestSize(0), + mTotalSize(0) + { + mTotalTimer.reset(); + mPeriodTimer.reset(); + } + void addNode() + { + ++mTotalNodes; + ++mPeriodNodesCreated; + } + void removeNode() + { + --mTotalNodes; + ++mPeriodNodesDestroyed; + } + void realloc(U32 old_count, U32 new_count) + { + if(new_count >= old_count) + mTotalSize+=new_count-old_count; + else + mTotalSize-=old_count-new_count; + if(mLargestSize < new_count) + mLargestSize = new_count; + if(mPeriodLargestSize < new_count) + mPeriodLargestSize = new_count; + ++mTotalAllocs; + ++mPeriodAllocs; + } + void free(U32 count) + { + mTotalSize-=count; + ++mTotalFrees; + ++mPeriodFrees; + } + void dump() + { + llinfos << llformat("Lifetime: Allocs:(+%u|-%u) Allocs/s: (+%lf|-%lf) Nodes: %u AccumSize: %llubytes Avg: %lf LargestSize: %u", + mTotalAllocs, + mTotalFrees, + F64(mTotalAllocs)/mTotalTimer.getElapsedTimeF64(), + F64(mTotalFrees)/mTotalTimer.getElapsedTimeF64(), + mTotalNodes, + mTotalSize*sizeof(LLPointer), + F64(mTotalSize)/F64(mTotalNodes), + mLargestSize + ) << llendl; + llinfos << llformat("Timeslice: Allocs:(+%u|-%u) Allocs/s: (+%lf|-%lf) Nodes:(+%u|-%u) LargestSize: %u", + mPeriodAllocs, + mPeriodFrees, + F64(mPeriodAllocs)/mPeriodTimer.getElapsedTimeF64(), + F64(mPeriodFrees)/mPeriodTimer.getElapsedTimeF64(), + mPeriodNodesCreated, + mPeriodNodesDestroyed, + mPeriodLargestSize + ) << llendl; + + mPeriodNodesCreated=0; + mPeriodNodesDestroyed=0; + mPeriodAllocs=0; + mPeriodFrees=0; + mPeriodLargestSize=0; + mPeriodTimer.reset(); + } +private: + //Accumulate per timer update + U32 mPeriodNodesCreated; + U32 mPeriodNodesDestroyed; + U32 mPeriodAllocs; + U32 mPeriodFrees; + U32 mPeriodLargestSize; + LLTimer mPeriodTimer; + + //Accumulate through entire app lifetime: + U32 mTotalNodes; + U32 mTotalAllocs; + U32 mTotalFrees; + U32 mLargestSize; + U64 mTotalSize; + LLTimer mTotalTimer; +}; +#endif //LL_OCTREE_STATS + template class LLOctreeListener: public LLTreeListener { @@ -129,25 +225,52 @@ public: typedef LLOctreeTraveler oct_traveler; typedef LLTreeTraveler tree_traveler; - typedef LLPointer* element_list; - typedef LLPointer* element_iter; - typedef const LLPointer* const_element_iter; + typedef std::vector > element_list; + typedef typename element_list::iterator element_iter; + typedef typename element_list::const_iterator const_element_iter; typedef typename std::vector*>::iterator tree_listener_iter; typedef LLOctreeNode** child_list; typedef LLOctreeNode** child_iter; + typedef LLTreeNode BaseType; typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; - /*void* operator new(size_t size) +#ifdef LL_OCTREE_POOLS + struct octree_pool_alloc + { + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + static char * malloc(const std::size_t bytes) + { return (char *)ll_aligned_malloc_16(bytes); } + static void free(char * const block) + { ll_aligned_free_16(block); } + }; + static boost::pool& getPool(const std::size_t& size) + { + static boost::pool sPool((std::size_t)LL_NEXT_ALIGNED_ADDRESS((char*)size),1200); + llassert_always((std::size_t)LL_NEXT_ALIGNED_ADDRESS((char*)size) == sPool.get_requested_size()); + return sPool; + } + void* operator new(size_t size) + { + return getPool(size).malloc(); + } + void operator delete(void* ptr) + { + getPool(sizeof(LLOctreeNode)).free(ptr); + } +#else + void* operator new(size_t size) { return ll_aligned_malloc_16(size); } - void operator delete(void* ptr) { ll_aligned_free_16(ptr); - }*/ + } +#endif LLOctreeNode( const LLVector4a& center, const LLVector4a& size, @@ -156,8 +279,16 @@ public: : mParent((oct_node*)parent), mOctant(octant) { - mData = NULL; - mDataEnd = NULL; +#ifdef LL_OCTREE_STATS + OctreeStats::getInstance()->addNode(); +#endif + if(gOctreeReserveCapacity) + mData.reserve(gOctreeReserveCapacity); +#ifdef LL_OCTREE_STATS + OctreeStats::getInstance()->realloc(0,mData.capacity()); +#endif + //mData = NULL; + //mDataEnd = NULL; mCenter = center; mSize = size; @@ -168,24 +299,31 @@ public: mOctant = ((oct_node*) mParent)->getOctant(mCenter); } - mElementCount = 0; + //mElementCount = 0; clearChildren(); } virtual ~LLOctreeNode() - { + { +#ifdef LL_OCTREE_STATS + OctreeStats::getInstance()->removeNode(); +#endif BaseType::destroyListeners(); - for (U32 i = 0; i < mElementCount; ++i) + //for (U32 i = 0; i < mElementCount; ++i) + for (U32 i = 0; i < mData.size(); ++i) { mData[i]->setBinIndex(-1); mData[i] = NULL; } - free(mData); - mData = NULL; - mDataEnd = NULL; +#ifdef LL_OCTREE_STATS + OctreeStats::getInstance()->free(mData.capacity()); +#endif + //free(mData); + //mData = NULL; + //mDataEnd = NULL; for (U32 i = 0; i < getChildCount(); i++) { @@ -285,14 +423,14 @@ public: void accept(oct_traveler* visitor) { visitor->visit(this); } virtual bool isLeaf() const { return mChildCount == 0; } - U32 getElementCount() const { return mElementCount; } - bool isEmpty() const { return mElementCount == 0; } + U32 getElementCount() const { return mData.size(); } + bool isEmpty() const { return mData.size() == 0; } //element_list& getData() { return mData; } //const element_list& getData() const { return mData; } - element_iter getDataBegin() { return mData; } - element_iter getDataEnd() { return mDataEnd; } - const_element_iter getDataBegin() const { return mData; } - const_element_iter getDataEnd() const { return mDataEnd; } + element_iter getDataBegin() { return mData.begin(); } + element_iter getDataEnd() { return mData.end(); } + const_element_iter getDataBegin() const { return mData.begin(); } + const_element_iter getDataEnd() const { return mData.end(); } U32 getChildCount() const { return mChildCount; } oct_node* getChild(U32 index) { return mChild[index]; } @@ -372,7 +510,10 @@ public: if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) || (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here - mElementCount++; + /*mElementCount++; +#ifdef LL_OCTREE_STATS + OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount); +#endif mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); //avoid unref on uninitialized memory @@ -380,7 +521,18 @@ public: mData[mElementCount-1] = data; mDataEnd = mData + mElementCount; - data->setBinIndex(mElementCount-1); + data->setBinIndex(mElementCount-1);*/ + +#ifdef LL_OCTREE_STATS + U32 old_cap = mData.capacity(); +#endif + data->setBinIndex(mData.size()); + mData.push_back(data); +#ifdef LL_OCTREE_STATS + if(old_cap != mData.capacity()) + OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); +#endif + BaseType::insert(data); return true; } @@ -415,7 +567,10 @@ public: if( lt == 0x7 ) { - mElementCount++; + /*mElementCount++; +#ifdef LL_OCTREE_STATS + OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount); +#endif mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); //avoid unref on uninitialized memory @@ -423,7 +578,17 @@ public: mData[mElementCount-1] = data; mDataEnd = mData + mElementCount; - data->setBinIndex(mElementCount-1); + data->setBinIndex(mElementCount-1);*/ +#ifdef LL_OCTREE_STATS + U32 old_cap = mData.capacity(); +#endif + data->setBinIndex(mData.size()); + mData.push_back(data); +#ifdef LL_OCTREE_STATS + if(old_cap != mData.capacity()) + OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); +#endif + BaseType::insert(data); return true; } @@ -476,10 +641,10 @@ public: void _remove(T* data, S32 i) { //precondition -- mElementCount > 0, idx is in range [0, mElementCount) OctreeGuard::checkGuarded(this); - mElementCount--; + //mElementCount--; data->setBinIndex(-1); - - if (mElementCount > 0) + +/* if (mElementCount > 0) { if (mElementCount != i) { @@ -488,15 +653,51 @@ public: } mData[mElementCount] = NULL; //needed for unref +#ifdef LL_OCTREE_STATS + OctreeStats::getInstance()->realloc(mElementCount+1,mElementCount); +#endif mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); mDataEnd = mData+mElementCount; } else { mData[0] = NULL; //needed for unref +#ifdef LL_OCTREE_STATS + OctreeStats::getInstance()->free(1); +#endif free(mData); mData = NULL; mDataEnd = NULL; + }*/ + + if(mData.size()) + { + if((mData.size()-1)!=i) + { + mData[i] = mData[mData.size()-1]; + mData[i]->setBinIndex(i); + } +#ifdef LL_OCTREE_STATS + U32 old_cap = mData.capacity(); +#endif + mData.pop_back(); + if( mData.size() == gOctreeReserveCapacity || + (mData.size() > gOctreeReserveCapacity && mData.capacity() > gOctreeReserveCapacity + mData.size() - 1 - (mData.size() - gOctreeReserveCapacity - 1) % 4)) + { + //Shrink to lowest possible (reserve)+4*i size.. Say reserve is 5, here are [size,capacity] pairs. [10,13],[9,9],[8,9],[7,9],[6,9],[5,5],[4,5],[3,5],[2,5],[1,5],[0,5] + //For Windows: We always assume vs2010 or later, which support this c++11 feature with no configuration needed. + //For GCC: __cplusplus >= 201103L indicates C++11 support. __GXX_EXPERIMENTAL_CXX0X being set indicates experimental c++0x support. C++11 support replaces C++0x support. + // std::vector::shrink_to_fit was added to GCCs C++0x implementation in version 4.5.0. +#if defined(LL_WINDOWS) || __cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X) && __GNUC_MINOR__ >= 5) + mData.shrink_to_fit(); +#else + std::vector >(mData.begin(), mData.end()).swap(mData); //Need to confirm this works on OSX.. +#endif + } +#ifdef LL_OCTREE_STATS + if(old_cap != mData.capacity()) + OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); +#endif } this->notifyRemoval(data); @@ -508,7 +709,8 @@ public: OctreeGuard::checkGuarded(this); S32 i = data->getBinIndex(); - if (i >= 0 && i < (S32)mElementCount) + //if (i >= 0 && i < mElementCount) + if (i >= 0 && i < (S32)mData.size()) { if (mData[i] == data) { //found it @@ -552,7 +754,8 @@ public: void removeByAddress(T* data) { OctreeGuard::checkGuarded(this); - for (U32 i = 0; i < mElementCount; ++i) + //for (U32 i = 0; i < mElementCount; ++i) + for (U32 i = 0; i < mData.size(); ++i) { if (mData[i] == data) { //we have data @@ -660,8 +863,6 @@ public: listener->handleChildRemoval(this, getChild(index)); } - - if (destroy) { mChild[index]->destroy(); @@ -733,8 +934,8 @@ protected: U32 mChildCount; element_list mData; - element_iter mDataEnd; - U32 mElementCount; + //element_iter mDataEnd; + //U32 mElementCount; }; diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h index a18f63a0d..44c8327f5 100644 --- a/indra/llmath/llplane.h +++ b/indra/llmath/llplane.h @@ -42,6 +42,8 @@ // The plane normal = [A, B, C] // The closest approach = D / sqrt(A*A + B*B + C*C) + +LL_ALIGN_PREFIX(16) class LLPlane { public: @@ -100,7 +102,7 @@ public: private: LLVector4a mV; -}; +} LL_ALIGN_POSTFIX(16); diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h index d7595dcee..f3b55d83a 100644 --- a/indra/llmath/llrect.h +++ b/indra/llmath/llrect.h @@ -2,31 +2,25 @@ * @file llrect.h * @brief A rectangle in GL coordinates, with bottom,left = 0,0 * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -124,8 +118,8 @@ public: if (end_y < mBottom) clip_y = end_y - mBottom; // clip_? and delta_? should have same sign, since starting point is in rect // so ratios will be positive - F32 ratio_x = ((F32)clip_x / (F32)delta_x); - F32 ratio_y = ((F32)clip_y / (F32)delta_y); + F32 ratio_x = delta_x ? ((F32)clip_x / (F32)delta_x) : 0.f; + F32 ratio_y = delta_y ? ((F32)clip_y / (F32)delta_y) : 0.f; if (ratio_x > ratio_y) { // clip along x direction diff --git a/indra/llmath/llsimdmath.h b/indra/llmath/llsimdmath.h index c7cdf7b32..01458521e 100644 --- a/indra/llmath/llsimdmath.h +++ b/indra/llmath/llsimdmath.h @@ -67,11 +67,10 @@ template T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) #define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16) - - #include #include +#include "llmemory.h" #include "llsimdtypes.h" #include "llsimdtypes.inl" diff --git a/indra/llmath/llsimdtypes.inl b/indra/llmath/llsimdtypes.inl index 712239e42..e905c8495 100644 --- a/indra/llmath/llsimdtypes.inl +++ b/indra/llmath/llsimdtypes.inl @@ -62,6 +62,7 @@ inline LLSimdScalar operator/(const LLSimdScalar& a, const LLSimdScalar& b) inline LLSimdScalar operator-(const LLSimdScalar& a) { static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 }; + ll_assert_aligned(signMask,16); return _mm_xor_ps(*reinterpret_cast(signMask), a); } @@ -146,6 +147,7 @@ inline LLSimdScalar& LLSimdScalar::operator/=(const LLSimdScalar& rhs) inline LLSimdScalar LLSimdScalar::getAbs() const { static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; + ll_assert_aligned(F_ABS_MASK_4A,16); return _mm_and_ps( mQ, *reinterpret_cast(F_ABS_MASK_4A)); } diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp index b66b7a707..6edeb0fef 100644 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -24,6 +24,7 @@ * $/LicenseInfo$ */ +#include "llmemory.h" #include "llmath.h" #include "llquantize.h" @@ -44,7 +45,10 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast ( F assert(dst != NULL); assert(bytes > 0); assert((bytes % sizeof(F32))== 0); - + ll_assert_aligned(src,16); + ll_assert_aligned(dst,16); + assert(bytes%16==0); + F32* end = dst + (bytes / sizeof(F32) ); if (bytes > 64) @@ -189,6 +193,8 @@ void LLVector4a::quantize16( const LLVector4a& low, const LLVector4a& high ) LLVector4a oneOverDelta; { static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f }; + ll_assert_aligned(F_TWO_4A,16); + LLVector4a two; two.load4a( F_TWO_4A ); // Here we use _mm_rcp_ps plus one round of newton-raphson diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 596082509..9de0e6677 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -32,6 +32,7 @@ class LLRotation; #include #include "llpreprocessor.h" +#include "llmemory.h" /////////////////////////////////// // FIRST TIME USERS PLEASE READ @@ -46,6 +47,7 @@ class LLRotation; // LLVector3/LLVector4. ///////////////////////////////// +LL_ALIGN_PREFIX(16) class LLVector4a { public: @@ -90,6 +92,7 @@ public: LLVector4a() { //DO NOT INITIALIZE -- The overhead is completely unnecessary + ll_assert_aligned(this,16); } LLVector4a(F32 x, F32 y, F32 z, F32 w = 0.f) @@ -313,7 +316,7 @@ public: private: LLQuad mQ; -}; +} LL_ALIGN_POSTFIX(16); inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p) { diff --git a/indra/llmath/llvector4logical.h b/indra/llmath/llvector4logical.h index dd66b09d4..c5698f7ce 100644 --- a/indra/llmath/llvector4logical.h +++ b/indra/llmath/llvector4logical.h @@ -27,6 +27,7 @@ #ifndef LL_VECTOR4LOGICAL_H #define LL_VECTOR4LOGICAL_H +#include "llmemory.h" //////////////////////////// // LLVector4Logical @@ -77,6 +78,7 @@ public: inline LLVector4Logical& invert() { static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + ll_assert_aligned(allOnes,16); mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) ); return *this; } diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 54a88a570..24bd48bed 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -29,6 +29,10 @@ #include "llmath.h" #include +#if !LL_WINDOWS +#include +#endif +#include #include "llerror.h" #include "llmemtype.h" @@ -91,17 +95,6 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1; extern BOOL gDebugGL; -void assert_aligned(void* ptr, uintptr_t alignment) -{ -#if 0 - uintptr_t t = (uintptr_t) ptr; - if (t%alignment != 0) - { - llerrs << "Alignment check failed." << llendl; - } -#endif -} - BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) { LLVector3 test = (pt2-pt1)%(pt3-pt2); @@ -2703,7 +2696,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) return true; } - + BOOL LLVolume::isMeshAssetLoaded() { return mIsMeshAssetLoaded; @@ -3062,15 +3055,29 @@ S32 sculpt_sides(F32 detail) // determine the number of vertices in both s and t direction for this sculpt -void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32& s, S32& t) +bool sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32& s, S32& t) { + //Singu Note: minimum number of vertices depend on stitching type. + S32 min_s = 1; + S32 min_t = 1; + + if ((type == LL_SCULPT_TYPE_SPHERE) || + (type == LL_SCULPT_TYPE_TORUS) || + (type == LL_SCULPT_TYPE_CYLINDER)) + min_s = 4; + + if (type == LL_SCULPT_TYPE_TORUS) + min_t = 4; + // this code has the following properties: // 1) the aspect ratio of the mesh is as close as possible to the ratio of the map // while still using all available verts // 2) the mesh cannot have more verts than is allowed by LOD // 3) the mesh cannot have more verts than is allowed by the map - - S32 max_vertices_lod = (S32)pow((double)sculpt_sides(detail), 2.0); + + //Singu Note: Replaced float math mangling to get an integer square with just one multiplication. + S32 const sculptsides = sculpt_sides(detail); + S32 max_vertices_lod = sculptsides * sculptsides; S32 max_vertices_map = width * height / 4; S32 vertices; @@ -3089,11 +3096,22 @@ void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32 s = (S32)(F32) sqrt(((F32)vertices / ratio)); - s = llmax(s, 4); // no degenerate sizes, please + s = llmax(s, min_s); // no degenerate sizes, please t = vertices / s; - t = llmax(t, 4); // no degenerate sizes, please + t = llmax(t, min_t); // no degenerate sizes, please s = vertices / t; + + // Singu Note: return false if we failed to get enough vertices for this stitching + // type (due to not enough data, ie while the sculpt is still loading). + bool enough_data = s >= min_s; + if (!enough_data) + { + // Uses standard lod stepping for the sphere that will be shown. + s = t = sculptsides; + } + + return enough_data; } // sculpt replaces generate() for sculpted surfaces @@ -3120,7 +3138,14 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, sculpt_detail = 4.0; } - sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, sculpt_detail, requested_sizeS, requested_sizeT); + //Singu Note: this function returns false when sculpt_width and sculpt_height are too small. + // In that case requested_sizeS and requested_sizeT are set to the same values as should have happened + // when either of sculpt_width or sculpt_height had been zero. + if (!sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, sculpt_detail, requested_sizeS, requested_sizeT)) + { + sculpt_level = -1; + data_is_empty = TRUE; + } mPathp->generate(mParams.getPathParams(), sculpt_detail, 0, TRUE, requested_sizeS); mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), sculpt_detail, 0, TRUE, requested_sizeT); @@ -6963,14 +6988,14 @@ void LLVolumeFace::resizeVertices(S32 num_verts) if (num_verts) { mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - assert_aligned(mPositions, 16); + ll_assert_aligned(mPositions, 16); mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - assert_aligned(mNormals, 16); + ll_assert_aligned(mNormals, 16); //pad texture coordinate block end to allow for QWORD reads S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; mTexCoords = (LLVector2*) ll_aligned_malloc_16(size); - assert_aligned(mTexCoords, 16); + ll_assert_aligned(mTexCoords, 16); } else { @@ -6991,17 +7016,21 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con { S32 new_verts = mNumVertices+1; S32 new_size = new_verts*16; -// S32 old_size = mNumVertices*16; + S32 old_size = mNumVertices*16; //positions - mPositions = (LLVector4a*) realloc(mPositions, new_size); + mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_size, old_size); + ll_assert_aligned(mPositions,16); //normals - mNormals = (LLVector4a*) realloc(mNormals, new_size); - + mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_size, old_size); + ll_assert_aligned(mNormals,16); + //tex coords new_size = ((new_verts*8)+0xF) & ~0xF; - mTexCoords = (LLVector2*) realloc(mTexCoords, new_size); + old_size = ((mNumVertices*8)+0xF) & ~0xF; + mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, new_size, old_size); + ll_assert_aligned(mTexCoords,16); //just clear binormals @@ -7054,7 +7083,8 @@ void LLVolumeFace::pushIndex(const U16& idx) S32 old_size = ((mNumIndices*2)+0xF) & ~0xF; if (new_size != old_size) { - mIndices = (U16*) realloc(mIndices, new_size); + mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size); + ll_assert_aligned(mIndices,16); } mIndices[mNumIndices++] = idx; @@ -7095,12 +7125,12 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat } //allocate new buffer space - mPositions = (LLVector4a*) realloc(mPositions, new_count*sizeof(LLVector4a)); - assert_aligned(mPositions, 16); - mNormals = (LLVector4a*) realloc(mNormals, new_count*sizeof(LLVector4a)); - assert_aligned(mNormals, 16); - mTexCoords = (LLVector2*) realloc(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF); - assert_aligned(mTexCoords, 16); + mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a)); + ll_assert_aligned(mPositions, 16); + mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a)); + ll_assert_aligned(mNormals, 16); + mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF, (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF); + ll_assert_aligned(mTexCoords, 16); mNumVertices = new_count; @@ -7146,7 +7176,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat new_count = mNumIndices + face.mNumIndices; //allocate new index buffer - mIndices = (U16*) realloc(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF); + mIndices = (U16*) ll_aligned_realloc_16(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF, (mNumIndices*sizeof(U16)+0xF) & ~0xF); //get destination address into new index buffer U16* dst_idx = mIndices+mNumIndices; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 9999c236d..16b640fe7 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -2,31 +2,25 @@ * @file llvolume.h * @brief LLVolume base class. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index f140d7910..42180197f 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -1,31 +1,25 @@ /** * @file llvolumemgr.cpp * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index c25e37f1a..03f10814e 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -37,6 +37,15 @@ class LLVolumeTriangle : public LLRefCount { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } LLVolumeTriangle() { mBinIndex = -1; @@ -58,7 +67,7 @@ public: } - LLVector4a mPositionGroup; + LL_ALIGN_16(LLVector4a mPositionGroup); const LLVector4a* mV[3]; U16 mIndex[3]; @@ -78,6 +87,16 @@ class LLVolumeOctreeListener : public LLOctreeListener { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVolumeOctreeListener(LLOctreeNode* node); ~LLVolumeOctreeListener(); @@ -104,8 +123,8 @@ public: public: - LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector4a mExtents[2]; // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children }; class LLOctreeTriangleRayIntersect : public LLOctreeTraveler diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h index 211b0b91a..5cd6e4dfe 100644 --- a/indra/llmath/v3dmath.h +++ b/indra/llmath/v3dmath.h @@ -2,31 +2,25 @@ * @file v3dmath.h * @brief High precision 3 dimensional vector. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index b87db741b..0e5b196ee 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -2,31 +2,25 @@ * @file v3math.h * @brief LLVector3 class header file. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmath/v4color.cpp b/indra/llmath/v4color.cpp index 660f59fbe..9131befd8 100644 --- a/indra/llmath/v4color.cpp +++ b/indra/llmath/v4color.cpp @@ -2,31 +2,25 @@ * @file v4color.cpp * @brief LLColor4 class implementation. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index 3a4f8475c..3f9e1efd8 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -2,31 +2,25 @@ * @file v4color.h * @brief LLColor4 class header file. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmath/v4coloru.h b/indra/llmath/v4coloru.h index 1324b49df..fa1295441 100644 --- a/indra/llmath/v4coloru.h +++ b/indra/llmath/v4coloru.h @@ -2,31 +2,25 @@ * @file v4coloru.h * @brief The LLColor4U class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h index bae69eb59..299202d71 100644 --- a/indra/llmath/xform.h +++ b/indra/llmath/xform.h @@ -1,31 +1,25 @@ /** * @file xform.h * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 8bbb150c4..f3e68b53b 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -27,6 +27,7 @@ set(llmessage_SOURCE_FILES aicurlperhost.cpp aicurlthread.cpp aihttpheaders.cpp + aihttptimeout.cpp aihttptimeoutpolicy.cpp debug_libcurl.cpp llhttpclient.cpp @@ -114,6 +115,7 @@ set(llmessage_HEADER_FILES aicurlperhost.h aicurlthread.h aihttpheaders.h + aihttptimeout.h aihttptimeoutpolicy.h debug_libcurl.h llares.h diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp index 11668f5fc..2bb76b5ab 100644 --- a/indra/llmessage/aicurl.cpp +++ b/indra/llmessage/aicurl.cpp @@ -308,9 +308,10 @@ LLAtomicU32 Stats::llsd_body_count; LLAtomicU32 Stats::llsd_body_parse_error; LLAtomicU32 Stats::raw_body_count; +// Called from BufferedCurlEasyRequest::setStatusAndReason. +// The only allowed values for 'status' are S <= status < S+20, where S={100,200,300,400,500}. U32 Stats::status2index(U32 status) { - llassert_always(status >= 100 && status < 600 && (status % 100) < 20); // Max value 519. return (status - 100) / 100 * 20 + status % 100; // Returns 0..99 (for status 100..519). } @@ -492,12 +493,10 @@ void Stats::print(void) // Even more strict, BufferedCurlEasyRequest may not be created directly either, only as // base class of ThreadSafeBufferedCurlEasyRequest. llassert(BufferedCurlEasyRequest_count == ThreadSafeBufferedCurlEasyRequest_count); - // Each AICurlEasyRequestStateMachine is responsible for exactly one easy handle. - llassert(easy_handles >= AICurlEasyRequest_count); // Each AICurlEasyRequestStateMachine has one AICurlEasyRequest member. llassert(AICurlEasyRequest_count >= AICurlEasyRequestStateMachine_count); // AIFIXME: is this really always the case? And why? - llassert(easy_handles <= ResponderBase_count); + llassert(easy_handles <= S32(ResponderBase_count)); } } // namespace AICurlInterface @@ -547,6 +546,9 @@ void CurlEasyHandle::handle_easy_error(CURLcode code) // Throws AICurlNoEasyHandle. CurlEasyHandle::CurlEasyHandle(void) : mActiveMultiHandle(NULL), mErrorBuffer(NULL), mQueuedForRemoval(false) +#ifdef DEBUG_CURLIO + , mDebug(false) +#endif #ifdef SHOW_ASSERT , mRemovedPerCommand(true) #endif @@ -590,6 +592,12 @@ CurlEasyHandle::~CurlEasyHandle() llassert(!mActiveMultiHandle); curl_easy_cleanup(mEasyHandle); Stats::easy_cleanup_calls++; +#ifdef DEBUG_CURLIO + if (mDebug) + { + debug_curl_remove_easy(mEasyHandle); + } +#endif } //static @@ -762,17 +770,17 @@ void CurlEasyRequest::setoptString(CURLoption option, std::string const& value) setopt(option, value.c_str()); } -void CurlEasyRequest::setPost(AIPostFieldPtr const& postdata, U32 size) +void CurlEasyRequest::setPost(AIPostFieldPtr const& postdata, U32 size, bool keepalive) { llassert_always(postdata->data()); DoutCurl("POST size is " << size << " bytes: \"" << libcwd::buf2str(postdata->data(), size) << "\"."); setPostField(postdata); // Make sure the data stays around until we don't need it anymore. - setPost_raw(size, postdata->data()); + setPost_raw(size, postdata->data(), keepalive); } -void CurlEasyRequest::setPost_raw(U32 size, char const* data) +void CurlEasyRequest::setPost_raw(U32 size, char const* data, bool keepalive) { if (!data) { @@ -782,7 +790,7 @@ void CurlEasyRequest::setPost_raw(U32 size, char const* data) // The server never replies with 100-continue, so suppress the "Expect: 100-continue" header that libcurl adds by default. addHeader("Expect:"); - if (size > 0) + if (size > 0 && keepalive) { addHeader("Connection: keep-alive"); addHeader("Keep-alive: 300"); @@ -1007,6 +1015,8 @@ CURLcode CurlEasyRequest::curlCtxCallback(CURL* curl, void* sslctx, void* parm) options |= SSL_OP_NO_TLSv1_1; } #else + // This is expected when you compile against the headers of a version < 1.0.1 and then link at runtime with version >= 1.0.1. + // Don't do that. llassert_always(!need_renegotiation_hack); #endif SSL_CTX_set_options(ctx, options); @@ -1227,6 +1237,20 @@ void CurlEasyRequest::removed_from_multi_handle(AICurlEasyRequest_wat& curl_easy mHandleEventsTarget->removed_from_multi_handle(curl_easy_request_w); } +void CurlEasyRequest::bad_file_descriptor(AICurlEasyRequest_wat& curl_easy_request_w) +{ + if (mHandleEventsTarget) + mHandleEventsTarget->bad_file_descriptor(curl_easy_request_w); +} + +#ifdef SHOW_ASSERT +void CurlEasyRequest::queued_for_removal(AICurlEasyRequest_wat& curl_easy_request_w) +{ + if (mHandleEventsTarget) + mHandleEventsTarget->queued_for_removal(curl_easy_request_w); +} +#endif + PerHostRequestQueuePtr CurlEasyRequest::getPerHostPtr(void) { if (!mPerHostPtr) @@ -1252,7 +1276,7 @@ static int const HTTP_REDIRECTS_DEFAULT = 10; LLChannelDescriptors const BufferedCurlEasyRequest::sChannels; -BufferedCurlEasyRequest::BufferedCurlEasyRequest() : mRequestTransferedBytes(0), mResponseTransferedBytes(0), mBufferEventsTarget(NULL) +BufferedCurlEasyRequest::BufferedCurlEasyRequest() : mRequestTransferedBytes(0), mResponseTransferedBytes(0), mBufferEventsTarget(NULL), mStatus(HTTP_INTERNAL_ERROR) { AICurlInterface::Stats::BufferedCurlEasyRequest_count++; } @@ -1290,7 +1314,17 @@ void BufferedCurlEasyRequest::timed_out(void) mResponder->finished(CURLE_OK, HTTP_INTERNAL_ERROR, "Request timeout, aborted.", sChannels, mOutput); if (mResponder->needsHeaders()) { - send_buffer_events_to(NULL); // Revoke buffer events: we sent them to the responder. + send_buffer_events_to(NULL); // Revoke buffer events: we send them to the responder. + } + mResponder = NULL; +} + +void BufferedCurlEasyRequest::bad_socket(void) +{ + mResponder->finished(CURLE_OK, HTTP_INTERNAL_ERROR, "File descriptor went bad! Aborted.", sChannels, mOutput); + if (mResponder->needsHeaders()) + { + send_buffer_events_to(NULL); // Revoke buffer events: we send them to the responder. } mResponder = NULL; } @@ -1302,8 +1336,13 @@ void BufferedCurlEasyRequest::resetState(void) // Call base class implementation. CurlEasyRequest::resetState(); + // Reset local variables. mOutput.reset(); mInput.reset(); + mRequestTransferedBytes = 0; + mResponseTransferedBytes = 0; + mBufferEventsTarget = NULL; + mStatus = HTTP_INTERNAL_ERROR; } void BufferedCurlEasyRequest::print_diagnostics(CURLcode code) @@ -1349,11 +1388,22 @@ void BufferedCurlEasyRequest::prepRequest(AICurlEasyRequest_wat& curl_easy_reque curl_easy_request_w->setReadCallback(&curlReadCallback, lockobj); curl_easy_request_w->setHeaderCallback(&curlHeaderCallback, lockobj); + bool allow_cookies = headers.hasHeader("Cookie"); // Allow up to ten redirects. if (responder->followRedir()) { curl_easy_request_w->setopt(CURLOPT_FOLLOWLOCATION, 1); curl_easy_request_w->setopt(CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT); + // This is needed (at least) for authentication after temporary redirection + // to id.secondlife.com for marketplace.secondlife.com. + allow_cookies = true; + } + if (allow_cookies) + { + // Given an empty or non-existing file or by passing the empty string (""), + // this option will enable cookies for this curl handle, making it understand + // and parse received cookies and then use matching cookies in future requests. + curl_easy_request_w->setopt(CURLOPT_COOKIEFILE, ""); } // Keep responder alive. @@ -1399,3 +1449,18 @@ CurlMultiHandle::~CurlMultiHandle() } } // namespace AICurlPrivate + +#if LL_LINUX +extern "C" { + +// Keep linker happy. +const SSL_METHOD *SSLv2_client_method(void) +{ + // Never used. + llassert_always(false); + return NULL; +} + +} +#endif + diff --git a/indra/llmessage/aicurl.h b/indra/llmessage/aicurl.h index b7599c817..16d1b14fd 100644 --- a/indra/llmessage/aicurl.h +++ b/indra/llmessage/aicurl.h @@ -208,6 +208,10 @@ struct AICurlEasyHandleEvents { virtual void added_to_multi_handle(AICurlEasyRequest_wat& curl_easy_request_w) = 0; virtual void finished(AICurlEasyRequest_wat& curl_easy_request_w) = 0; virtual void removed_from_multi_handle(AICurlEasyRequest_wat& curl_easy_request_w) = 0; + virtual void bad_file_descriptor(AICurlEasyRequest_wat& curl_easy_request_w) = 0; +#ifdef SHOW_ASSERT + virtual void queued_for_removal(AICurlEasyRequest_wat& curl_easy_request_w) = 0; +#endif // Avoid compiler warning. virtual ~AICurlEasyHandleEvents() { } }; @@ -271,6 +275,11 @@ class AICurlEasyRequest { // Queue a command to remove this request from the multi session (or cancel a queued command to add it). void removeRequest(void); +#ifdef DEBUG_CURLIO + // Turn on/off debug output. + void debug(bool debug) { AICurlEasyRequest_wat(*mBufferedCurlEasyRequest)->debug(debug); } +#endif + private: // The actual pointer to the ThreadSafeBufferedCurlEasyRequest instance. AICurlPrivate::BufferedCurlEasyRequestPtr mBufferedCurlEasyRequest; diff --git a/indra/llmessage/aicurleasyrequeststatemachine.cpp b/indra/llmessage/aicurleasyrequeststatemachine.cpp index d7babe6f3..b9f486d67 100644 --- a/indra/llmessage/aicurleasyrequeststatemachine.cpp +++ b/indra/llmessage/aicurleasyrequeststatemachine.cpp @@ -40,7 +40,8 @@ enum curleasyrequeststatemachine_state_type { AICurlEasyRequestStateMachine_timedOut, // This must be smaller than the rest, so they always overrule. AICurlEasyRequestStateMachine_finished, AICurlEasyRequestStateMachine_removed, // The removed states must be largest two, so they are never ignored. - AICurlEasyRequestStateMachine_removed_after_finished + AICurlEasyRequestStateMachine_removed_after_finished, + AICurlEasyRequestStateMachine_bad_file_descriptor }; char const* AICurlEasyRequestStateMachine::state_str_impl(state_type run_state) const @@ -54,6 +55,7 @@ char const* AICurlEasyRequestStateMachine::state_str_impl(state_type run_state) AI_CASE_RETURN(AICurlEasyRequestStateMachine_finished); AI_CASE_RETURN(AICurlEasyRequestStateMachine_removed); AI_CASE_RETURN(AICurlEasyRequestStateMachine_removed_after_finished); + AI_CASE_RETURN(AICurlEasyRequestStateMachine_bad_file_descriptor); } return "UNKNOWN STATE"; } @@ -94,6 +96,24 @@ void AICurlEasyRequestStateMachine::removed_from_multi_handle(AICurlEasyRequest_ set_state(mFinished ? AICurlEasyRequestStateMachine_removed_after_finished : AICurlEasyRequestStateMachine_removed); } +// CURL-THREAD +void AICurlEasyRequestStateMachine::bad_file_descriptor(AICurlEasyRequest_wat&) +{ + if (!mFinished) + { + mFinished = true; + set_state(AICurlEasyRequestStateMachine_bad_file_descriptor); + } +} + +#ifdef SHOW_ASSERT +// CURL-THREAD +void AICurlEasyRequestStateMachine::queued_for_removal(AICurlEasyRequest_wat&) +{ + llassert(mFinished || mTimedOut); // See AICurlEasyRequestStateMachine::removed_from_multi_handle +} +#endif + void AICurlEasyRequestStateMachine::multiplex_impl(void) { mSetStateLock.lock(); @@ -207,6 +227,11 @@ void AICurlEasyRequestStateMachine::multiplex_impl(void) break; } + case AICurlEasyRequestStateMachine_bad_file_descriptor: + { + AICurlEasyRequest_wat(*mCurlEasyRequest)->bad_socket(); + abort(); + } } } diff --git a/indra/llmessage/aicurleasyrequeststatemachine.h b/indra/llmessage/aicurleasyrequeststatemachine.h index 8ece6fc26..8a6441874 100644 --- a/indra/llmessage/aicurleasyrequeststatemachine.h +++ b/indra/llmessage/aicurleasyrequeststatemachine.h @@ -81,6 +81,14 @@ class AICurlEasyRequestStateMachine : public AIStateMachine, public AICurlEasyHa // Called after this curl easy handle was removed from a multi handle. /*virtual*/ void removed_from_multi_handle(AICurlEasyRequest_wat&); + // Called when the curl thread detected that the socket of this handle has become unusable. + /*virtual*/ void bad_file_descriptor(AICurlEasyRequest_wat&); + +#ifdef SHOW_ASSERT + // Called when a command was added to remove this easy handle. + /*virtual*/ void queued_for_removal(AICurlEasyRequest_wat&); +#endif + protected: // AIStateMachine implementations. diff --git a/indra/llmessage/aicurlperhost.cpp b/indra/llmessage/aicurlperhost.cpp index 7f7490865..b444ba6df 100644 --- a/indra/llmessage/aicurlperhost.cpp +++ b/indra/llmessage/aicurlperhost.cpp @@ -92,13 +92,13 @@ void PerHostRequestQueue::release(PerHostRequestQueuePtr& instance) bool PerHostRequestQueue::throttled() const { - llassert(mAdded <= curl_concurrent_connections_per_host); - return mAdded == curl_concurrent_connections_per_host; + llassert(mAdded <= int(curl_concurrent_connections_per_host)); + return mAdded == int(curl_concurrent_connections_per_host); } void PerHostRequestQueue::added_to_multi_handle(void) { - llassert(mAdded < curl_concurrent_connections_per_host); + llassert(mAdded < int(curl_concurrent_connections_per_host)); ++mAdded; } diff --git a/indra/llmessage/aicurlprivate.h b/indra/llmessage/aicurlprivate.h index ee28ae849..bb39bdddb 100644 --- a/indra/llmessage/aicurlprivate.h +++ b/indra/llmessage/aicurlprivate.h @@ -35,82 +35,15 @@ #include "llatomic.h" #include "llrefcount.h" #include "aicurlperhost.h" +#include "aihttptimeout.h" class AIHTTPHeaders; -class AIHTTPTimeoutPolicy; -class AICurlEasyRequest; class AICurlEasyRequestStateMachine; namespace AICurlPrivate { -class CurlEasyRequest; -class ThreadSafeBufferedCurlEasyRequest; - namespace curlthread { - class MultiHandle; - -// A class that keeps track of timeout administration per connection. -class HTTPTimeout : public LLRefCount { - private: - AIHTTPTimeoutPolicy const* mPolicy; // A pointer to the used timeout policy. - std::vector mBuckets; // An array with the number of bytes transfered in each second. - U16 mBucket; // The bucket corresponding to mLastSecond. - bool mNothingReceivedYet; // Set when created, reset when the HTML reply header from the server is received. - bool mLowSpeedOn; // Set while uploading or downloading data. - bool mUploadFinished; // Used to keep track of whether upload_finished was called yet. - S32 mLastSecond; // The time at which lowspeed() was last called, in seconds since mLowSpeedClock. - U32 mTotalBytes; // The sum of all bytes in mBuckets. - U64 mLowSpeedClock; // Clock count at which low speed detection (re)started. - U64 mStalled; // The clock count at which this transaction is considered to be stalling if nothing is transfered anymore. - public: - static F64 const sClockWidth; // Time between two clock ticks in seconds. - static U64 sClockCount; // Clock count used as 'now' during one loop of the main loop. -#if defined(CWDEBUG) || defined(DEBUG_CURLIO) - ThreadSafeBufferedCurlEasyRequest* mLockObj; -#endif - - public: - HTTPTimeout(AIHTTPTimeoutPolicy const* policy, ThreadSafeBufferedCurlEasyRequest* lock_obj) : - mPolicy(policy), mNothingReceivedYet(true), mLowSpeedOn(false), mUploadFinished(false), mStalled((U64)-1) -#if defined(CWDEBUG) || defined(DEBUG_CURLIO) - , mLockObj(lock_obj) -#endif - { } - - // Called after sending all headers, when body data is written the first time. - void connected(void); - - // Called when everything we had to send to the server has been sent. - void upload_finished(void); - - // Called when data is sent. Returns true if transfer timed out. - bool data_sent(size_t n); - - // Called when data is received. Returns true if transfer timed out. - bool data_received(size_t n); - - // Called immediately before done() after curl finished, with code. - void done(AICurlEasyRequest_wat const& curlEasyRequest_w, CURLcode code); - - // Accessor. - bool has_stalled(void) const { return mStalled < sClockCount; } - - // Called from BufferedCurlEasyRequest::processOutput if a timeout occurred. - void print_diagnostics(CurlEasyRequest const* curl_easy_request, char const* eff_url); - -#if defined(CWDEBUG) || defined(DEBUG_CURLIO) - void* get_lockobj(void) const { return mLockObj; } -#endif - - private: - // (Re)start low speed transer rate detection. - void reset_lowspeed(void); - - // Common low speed detection, Called from data_sent or data_received. - bool lowspeed(size_t bytes); -}; - } // namespace curlthread void handle_multi_error(CURLMcode code); @@ -201,12 +134,19 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven // In case it's added after being removed. void add_queued(void) { mQueuedForRemoval = false; } +#ifdef DEBUG_CURLIO + void debug(bool debug) { if (mDebug) debug_curl_remove_easy(mEasyHandle); if (debug) debug_curl_add_easy(mEasyHandle); mDebug = debug; } +#endif + private: CURL* mEasyHandle; CURLM* mActiveMultiHandle; mutable char* mErrorBuffer; AIPostFieldPtr mPostField; // This keeps the POSTFIELD data alive for as long as the easy handle exists. bool mQueuedForRemoval; // Set if the easy handle is (probably) added to the multi handle, but is queued for removal. +#ifdef DEBUG_CURLIO + bool mDebug; +#endif #ifdef SHOW_ASSERT public: bool mRemovedPerCommand; // Set if mActiveMultiHandle was reset as per command from the main thread. @@ -270,11 +210,11 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven // and the CurlEasyRequest destructed. class CurlEasyRequest : public CurlEasyHandle { private: - void setPost_raw(U32 size, char const* data); + void setPost_raw(U32 size, char const* data, bool keepalive); public: - void setPost(U32 size) { setPost_raw(size, NULL); } - void setPost(AIPostFieldPtr const& postdata, U32 size); - void setPost(char const* data, U32 size) { setPost(new AIPostField(data), size); } + void setPost(U32 size, bool keepalive = true) { setPost_raw(size, NULL, keepalive); } + void setPost(AIPostFieldPtr const& postdata, U32 size, bool keepalive = true); + void setPost(char const* data, U32 size, bool keepalive = true) { setPost(new AIPostField(data), size, keepalive); } void setoptString(CURLoption option, std::string const& value); void addHeader(char const* str); void addHeaders(AIHTTPHeaders const& headers); @@ -413,6 +353,11 @@ class CurlEasyRequest : public CurlEasyHandle { /*virtual*/ void added_to_multi_handle(AICurlEasyRequest_wat& curl_easy_request_w); /*virtual*/ void finished(AICurlEasyRequest_wat& curl_easy_request_w); /*virtual*/ void removed_from_multi_handle(AICurlEasyRequest_wat& curl_easy_request_w); + public: + /*virtual*/ void bad_file_descriptor(AICurlEasyRequest_wat& curl_easy_request_w); +#ifdef SHOW_ASSERT + /*virtual*/ void queued_for_removal(AICurlEasyRequest_wat& curl_easy_request_w); +#endif }; // This class adds input/output buffers to the request and hooks up the libcurl callbacks to use those buffers. @@ -431,6 +376,9 @@ class BufferedCurlEasyRequest : public CurlEasyRequest { // Called if libcurl doesn't deliver within AIHTTPTimeoutPolicy::mMaximumTotalDelay seconds. void timed_out(void); + // Called if the underlaying socket went bad (ie, when accidently closed by a buggy library). + void bad_socket(void); + // Called after removed_from_multi_handle was called. void processOutput(void); @@ -483,6 +431,9 @@ class BufferedCurlEasyRequest : public CurlEasyRequest { // Return pointer to the ThreadSafe (wrapped) version of this object. ThreadSafeBufferedCurlEasyRequest* get_lockobj(void); ThreadSafeBufferedCurlEasyRequest const* get_lockobj(void) const; + // Return true when an error code was received that can occur before the upload finished. + // So far the only such error I've seen is HTTP_BAD_REQUEST. + bool upload_error_status(void) const { return mStatus == HTTP_BAD_REQUEST /*&& mStatus != HTTP_INTERNAL_ERROR*/; } // Return true when prepRequest was already called and the object has not been // invalidated as a result of calling timed_out(). diff --git a/indra/llmessage/aicurlthread.cpp b/indra/llmessage/aicurlthread.cpp index ae686c087..efb5ca46b 100644 --- a/indra/llmessage/aicurlthread.cpp +++ b/indra/llmessage/aicurlthread.cpp @@ -31,6 +31,7 @@ #include "linden_common.h" #include "aicurlthread.h" #include "aihttptimeoutpolicy.h" +#include "aihttptimeout.h" #include "aicurlperhost.h" #include "lltimer.h" // ms_sleep, get_clock_count #include "llhttpstatuscodes.h" @@ -286,14 +287,35 @@ enum refresh_t { empty_and_complete = complete|empty }; +// A class with info for each socket that is in use by curl. +class CurlSocketInfo +{ + public: + CurlSocketInfo(MultiHandle& multi_handle, ASSERT_ONLY(CURL* easy,) curl_socket_t s, int action, ThreadSafeBufferedCurlEasyRequest* lockobj); + ~CurlSocketInfo(); + + void set_action(int action); + void mark_dead(void) { set_action(CURL_POLL_NONE); mDead = true; } + curl_socket_t getSocketFd(void) const { return mSocketFd; } + AICurlEasyRequest& getEasyRequest(void) { return mEasyRequest; } + + private: + MultiHandle& mMultiHandle; + curl_socket_t mSocketFd; + int mAction; + bool mDead; + AICurlEasyRequest mEasyRequest; + LLPointer mTimeout; +}; + class PollSet { public: PollSet(void); // Add/remove a filedescriptor to/from mFileDescriptors. - void add(curl_socket_t s); - void remove(curl_socket_t s); + void add(CurlSocketInfo* sp); + void remove(CurlSocketInfo* sp); // Copy mFileDescriptors to an internal fd_set that is returned by access(). // Returns if all fds could be copied (complete) and/or if the resulting fd_set is empty. @@ -307,8 +329,8 @@ class PollSet curl_socket_t get_max_fd(void) const { return mMaxFdSet; } #endif - // Return true if a filedescriptor is set in mFileDescriptors (used for debugging). - bool contains(curl_socket_t s) const; + // Return a pointer to the corresponding CurlSocketInfo if a filedescriptor is set in mFileDescriptors, or NULL if s is not set. + CurlSocketInfo* contains(curl_socket_t s) const; // Return true if a filedescriptor is set in mFdSet. bool is_set(curl_socket_t s) const; @@ -323,7 +345,7 @@ class PollSet void next(void); // Advance to next filedescriptor. private: - curl_socket_t* mFileDescriptors; + CurlSocketInfo** mFileDescriptors; int mNrFds; // The number of filedescriptors in the array. int mNext; // The index of the first file descriptor to start copying, the next call to refresh(). @@ -359,7 +381,7 @@ class PollSet static size_t const MAXSIZE = llmax(1024, FD_SETSIZE); // Create an empty PollSet. -PollSet::PollSet(void) : mFileDescriptors(new curl_socket_t [MAXSIZE]), +PollSet::PollSet(void) : mFileDescriptors(new CurlSocketInfo* [MAXSIZE]), mNrFds(0), mNext(0) #if !WINDOWS_CODE , mMaxFd(-1), mMaxFdSet(-1) @@ -369,17 +391,17 @@ PollSet::PollSet(void) : mFileDescriptors(new curl_socket_t [MAXSIZE]), } // Add filedescriptor s to the PollSet. -void PollSet::add(curl_socket_t s) +void PollSet::add(CurlSocketInfo* sp) { llassert_always(mNrFds < (int)MAXSIZE); - mFileDescriptors[mNrFds++] = s; + mFileDescriptors[mNrFds++] = sp; #if !WINDOWS_CODE - mMaxFd = llmax(mMaxFd, s); + mMaxFd = llmax(mMaxFd, sp->getSocketFd()); #endif } // Remove filedescriptor s from the PollSet. -void PollSet::remove(curl_socket_t s) +void PollSet::remove(CurlSocketInfo* sp) { // The number of open filedescriptors is relatively small, // and on top of that we rather do something CPU intensive @@ -391,15 +413,15 @@ void PollSet::remove(curl_socket_t s) // back, keeping it compact and keeping the filedescriptors // in the same order (which is supposedly their priority). // - // The general case is where mFileDescriptors contains s at an index + // The general case is where mFileDescriptors contains sp at an index // between 0 and mNrFds: // mNrFds = 6 // v // index: 0 1 2 3 4 5 // a b c s d e - // This function should never be called unless s is actually in mFileDescriptors, - // as a result of a previous call to PollSet::add(). + // This function should never be called unless sp is actually in mFileDescriptors, + // as a result of a previous call to PollSet::add(sp). llassert(mNrFds > 0); // Correct mNrFds for when the descriptor is removed. @@ -409,17 +431,18 @@ void PollSet::remove(curl_socket_t s) // v // index: 0 1 2 3 4 5 // a b c s d e - curl_socket_t cur = mFileDescriptors[i]; // cur = 'e' + curl_socket_t const s = sp->getSocketFd(); + CurlSocketInfo* cur = mFileDescriptors[i]; // cur = 'e' #if !WINDOWS_CODE curl_socket_t max = -1; #endif - while (cur != s) + while (cur != sp) { llassert(i > 0); - curl_socket_t next = mFileDescriptors[--i]; // next = 'd' + CurlSocketInfo* next = mFileDescriptors[--i]; // next = 'd' mFileDescriptors[i] = cur; // Overwrite 'd' with 'e'. #if !WINDOWS_CODE - max = llmax(max, cur); // max is the maximum value in 'i' or higher. + max = llmax(max, cur->getSocketFd()); // max is the maximum value in 'i' or higher. #endif cur = next; // cur = 'd' // i NrFds = 5 @@ -427,21 +450,21 @@ void PollSet::remove(curl_socket_t s) // index: 0 1 2 3 4 // a b c s e // cur = 'd' // - // Next loop iteration: next = 's', overwrite 's' with 'd', cur = 's'; loop terminates. + // Next loop iteration: next = 'sp', overwrite 'sp' with 'd', cur = 'sp'; loop terminates. // i NrFds = 5 // v v // index: 0 1 2 3 4 - // a b c d e // cur = 's' + // a b c d e // cur = 'sp' } - llassert(cur == s); + llassert(cur == sp); // At this point i was decremented once more and points to the element before the old s. // i NrFds = 5 // v v // index: 0 1 2 3 4 // a b c d e // max = llmax('d', 'e') - // If mNext pointed to an element before s, it should be left alone. Otherwise, if mNext pointed - // to s it must now point to 'd', or if it pointed beyond 's' it must be decremented by 1. + // If mNext pointed to an element before sp, it should be left alone. Otherwise, if mNext pointed + // to sp it must now point to 'd', or if it pointed beyond 'sp' it must be decremented by 1. if (mNext > i) // i is where s was. --mNext; @@ -451,8 +474,8 @@ void PollSet::remove(curl_socket_t s) { while (i > 0) { - curl_socket_t next = mFileDescriptors[--i]; - max = llmax(max, next); + CurlSocketInfo* next = mFileDescriptors[--i]; + max = llmax(max, next->getSocketFd()); } mMaxFd = max; llassert(mMaxFd < s); @@ -487,12 +510,12 @@ void PollSet::remove(curl_socket_t s) #endif } -bool PollSet::contains(curl_socket_t fd) const +CurlSocketInfo* PollSet::contains(curl_socket_t fd) const { for (int i = 0; i < mNrFds; ++i) - if (mFileDescriptors[i] == fd) - return true; - return false; + if (mFileDescriptors[i]->getSocketFd() == fd) + return mFileDescriptors[i]; + return NULL; } inline bool PollSet::is_set(curl_socket_t fd) const @@ -536,7 +559,7 @@ refresh_t PollSet::refresh(void) // Calculate mMaxFdSet. // Run over FD_SETSIZE - 1 elements, starting at mNext, wrapping to 0 when we reach the end. int max = -1, i = mNext, count = 0; - while (++count < FD_SETSIZE) { max = llmax(max, mFileDescriptors[i]); if (++i == mNrFds) i = 0; } + while (++count < FD_SETSIZE) { max = llmax(max, mFileDescriptors[i]->getSocketFd()); if (++i == mNrFds) i = 0; } mMaxFdSet = max; #endif } @@ -556,16 +579,16 @@ refresh_t PollSet::refresh(void) mNext = i; return not_complete_not_empty; } - FD_SET(mFileDescriptors[i], &mFdSet); + FD_SET(mFileDescriptors[i]->getSocketFd(), &mFdSet); #if !WINDOWS_CODE - mCopiedFileDescriptors.push_back(mFileDescriptors[i]); + mCopiedFileDescriptors.push_back(mFileDescriptors[i]->getSocketFd()); #endif if (++i == mNrFds) { // If we reached the end and start at the beginning, then we copied everything. if (mNext == 0) break; - // When can only come here if mNrFds >= FD_SETSIZE, hence we can just + // We can only come here if mNrFds >= FD_SETSIZE, hence we can just // wrap around and terminate on count reaching FD_SETSIZE. i = 0; } @@ -646,12 +669,10 @@ class MergeIterator private: PollSet* mReadPollSet; PollSet* mWritePollSet; - int readIndx; - int writeIndx; }; MergeIterator::MergeIterator(PollSet* readPollSet, PollSet* writePollSet) : - mReadPollSet(readPollSet), mWritePollSet(writePollSet), readIndx(0), writeIndx(0) + mReadPollSet(readPollSet), mWritePollSet(writePollSet) { mReadPollSet->reset(); mWritePollSet->reset(); @@ -743,26 +764,8 @@ std::ostream& operator<<(std::ostream& os, DebugFdSet const& s) } #endif -// A class with info for each socket that is in use by curl. -class CurlSocketInfo -{ - public: - CurlSocketInfo(MultiHandle& multi_handle, CURL* easy, curl_socket_t s, int action, ThreadSafeBufferedCurlEasyRequest* lockobj); - ~CurlSocketInfo(); - - void set_action(int action); - - private: - MultiHandle& mMultiHandle; - CURL const* mEasy; - curl_socket_t mSocketFd; - int mAction; - AICurlEasyRequest mEasyRequest; - LLPointer mTimeout; -}; - -CurlSocketInfo::CurlSocketInfo(MultiHandle& multi_handle, CURL* easy, curl_socket_t s, int action, ThreadSafeBufferedCurlEasyRequest* lockobj) : - mMultiHandle(multi_handle), mEasy(easy), mSocketFd(s), mAction(CURL_POLL_NONE), mEasyRequest(lockobj) +CurlSocketInfo::CurlSocketInfo(MultiHandle& multi_handle, ASSERT_ONLY(CURL* easy,) curl_socket_t s, int action, ThreadSafeBufferedCurlEasyRequest* lockobj) : + mMultiHandle(multi_handle), mSocketFd(s), mAction(CURL_POLL_NONE), mDead(false), mEasyRequest(lockobj) { llassert(*AICurlEasyRequest_wat(*mEasyRequest) == easy); mMultiHandle.assign(s, this); @@ -785,23 +788,28 @@ CurlSocketInfo::~CurlSocketInfo() void CurlSocketInfo::set_action(int action) { + if (mDead) + { + return; + } + Dout(dc::curl, "CurlSocketInfo::set_action(" << action_str(mAction) << " --> " << action_str(action) << ") [" << (void*)mEasyRequest.get_ptr().get() << "]"); int toggle_action = mAction ^ action; mAction = action; if ((toggle_action & CURL_POLL_IN)) { if ((action & CURL_POLL_IN)) - mMultiHandle.mReadPollSet->add(mSocketFd); + mMultiHandle.mReadPollSet->add(this); else - mMultiHandle.mReadPollSet->remove(mSocketFd); + mMultiHandle.mReadPollSet->remove(this); } if ((toggle_action & CURL_POLL_OUT)) { if ((action & CURL_POLL_OUT)) - mMultiHandle.mWritePollSet->add(mSocketFd); + mMultiHandle.mWritePollSet->add(this); else { - mMultiHandle.mWritePollSet->remove(mSocketFd); + mMultiHandle.mWritePollSet->remove(this); // The following is a bit of a hack, needed because of the lack of proper timeout callbacks in libcurl. // The removal of CURL_POLL_OUT could be part of the SSL handshake, therefore check if we're already connected: @@ -838,6 +846,9 @@ class AICurlThread : public LLThread // MAIN-THREAD void stop_thread(void) { mRunning = false; wakeup_thread(); } + // MAIN-THREAD + apr_status_t join_thread(void); + protected: virtual void run(void); void wakeup(AICurlMultiHandle_wat const& multi_handle_w); @@ -1110,6 +1121,17 @@ void AICurlThread::wakeup_thread(void) #endif } +apr_status_t AICurlThread::join_thread(void) +{ + apr_status_t retval = APR_SUCCESS; + if (sInstance) + { + apr_thread_join(&retval, sInstance->mAPRThreadp); + delete sInstance; + } + return retval; +} + void AICurlThread::wakeup(AICurlMultiHandle_wat const& multi_handle_w) { DoutEntering(dc::curl, "AICurlThread::wakeup"); @@ -1255,6 +1277,26 @@ void AICurlThread::process_commands(AICurlMultiHandle_wat const& multi_handle_w) } } +// Return true if fd is a 'bad' socket. +static bool is_bad(curl_socket_t fd, bool for_writing) +{ + fd_set tmp; + FD_ZERO(&tmp); + FD_SET(fd, &tmp); + fd_set* readfds = for_writing ? NULL : &tmp; + fd_set* writefds = for_writing ? &tmp : NULL; +#if !WINDOWS_CODE + int nfds = fd + 1; +#else + int nfds = 64; +#endif + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 10; + int ret = select(nfds, readfds, writefds, NULL, &timeout); + return ret == -1; +} + // The main loop of the curl thread. void AICurlThread::run(void) { @@ -1266,28 +1308,7 @@ void AICurlThread::run(void) { // If mRunning is true then we can only get here if mWakeUpFd != CURL_SOCKET_BAD. llassert(mWakeUpFd != CURL_SOCKET_BAD); - // Copy the next batch of file descriptors from the PollSets mFiledescriptors into their mFdSet. - multi_handle_w->mReadPollSet->refresh(); - refresh_t wres = multi_handle_w->mWritePollSet->refresh(); - // Add wake up fd if any, and pass NULL to select() if a set is empty. - fd_set* read_fd_set = multi_handle_w->mReadPollSet->access(); - FD_SET(mWakeUpFd, read_fd_set); - fd_set* write_fd_set = ((wres & empty)) ? NULL : multi_handle_w->mWritePollSet->access(); - // Calculate nfds (ignored on windows). -#if !WINDOWS_CODE - curl_socket_t const max_rfd = llmax(multi_handle_w->mReadPollSet->get_max_fd(), mWakeUpFd); - curl_socket_t const max_wfd = multi_handle_w->mWritePollSet->get_max_fd(); - int nfds = llmax(max_rfd, max_wfd) + 1; - llassert(0 <= nfds && nfds <= FD_SETSIZE); - llassert((max_rfd == -1) == (read_fd_set == NULL) && - (max_wfd == -1) == (write_fd_set == NULL)); // Needed on Windows. - llassert((max_rfd == -1 || multi_handle_w->mReadPollSet->is_set(max_rfd)) && - (max_wfd == -1 || multi_handle_w->mWritePollSet->is_set(max_wfd))); -#else - int nfds = 64; -#endif - int ready = 0; - // Process every command in command_queue before entering select(). + // Process every command in command_queue before filling the fd_set passed to select(). for(;;) { mWakeUpMutex.lock(); @@ -1305,9 +1326,32 @@ void AICurlThread::run(void) mWakeUpMutex.unlock(); break; } + // If we get here then mWakeUpFlag has been false since we grabbed the lock. // We're now entering select(), during which the main thread will write to the pipe/socket // to wake us up, because it can't get the lock. + + // Copy the next batch of file descriptors from the PollSets mFileDescriptors into their mFdSet. + multi_handle_w->mReadPollSet->refresh(); + refresh_t wres = multi_handle_w->mWritePollSet->refresh(); + // Add wake up fd if any, and pass NULL to select() if a set is empty. + fd_set* read_fd_set = multi_handle_w->mReadPollSet->access(); + FD_SET(mWakeUpFd, read_fd_set); + fd_set* write_fd_set = ((wres & empty)) ? NULL : multi_handle_w->mWritePollSet->access(); + // Calculate nfds (ignored on windows). +#if !WINDOWS_CODE + curl_socket_t const max_rfd = llmax(multi_handle_w->mReadPollSet->get_max_fd(), mWakeUpFd); + curl_socket_t const max_wfd = multi_handle_w->mWritePollSet->get_max_fd(); + int nfds = llmax(max_rfd, max_wfd) + 1; + llassert(1 <= nfds && nfds <= FD_SETSIZE); + llassert((max_rfd == -1) == (read_fd_set == NULL) && + (max_wfd == -1) == (write_fd_set == NULL)); // Needed on Windows. + llassert((max_rfd == -1 || multi_handle_w->mReadPollSet->is_set(max_rfd)) && + (max_wfd == -1 || multi_handle_w->mWritePollSet->is_set(max_wfd))); +#else + int nfds = 64; +#endif + int ready = 0; struct timeval timeout; long timeout_ms = multi_handle_w->getTimeout(); // If no timeout is set, sleep 1 second. @@ -1383,6 +1427,51 @@ void AICurlThread::run(void) if (ready == -1) { llwarns << "select() failed: " << errno << ", " << strerror(errno) << llendl; + if (errno == EBADF) + { + // Somewhere (fmodex?) one of our file descriptors was closed. Try to recover by finding out which. + llassert_always(!is_bad(mWakeUpFd, false)); // We can't recover from this. + PollSet* found = NULL; + // Run over all read file descriptors. + multi_handle_w->mReadPollSet->refresh(); + multi_handle_w->mReadPollSet->reset(); + curl_socket_t fd; + while ((fd = multi_handle_w->mReadPollSet->get()) != CURL_SOCKET_BAD) + { + if (is_bad(fd, false)) + { + found = multi_handle_w->mReadPollSet; + break; + } + multi_handle_w->mReadPollSet->next(); + } + if (!found) + { + // Try all write file descriptors. + refresh_t wres = multi_handle_w->mWritePollSet->refresh(); + if (!(wres & empty)) + { + multi_handle_w->mWritePollSet->reset(); + while ((fd = multi_handle_w->mWritePollSet->get()) != CURL_SOCKET_BAD) + { + if (is_bad(fd, true)) + { + found = multi_handle_w->mWritePollSet; + break; + } + multi_handle_w->mWritePollSet->next(); + } + } + } + llassert_always(found); // It makes no sense to continue if we can't recover. + // Find the corresponding CurlSocketInfo + CurlSocketInfo* sp = found->contains(fd); + llassert_always(sp); // fd was just *read* from this sp. + sp->mark_dead(); // Make sure it's never used again. + AICurlEasyRequest_wat curl_easy_request_w(*sp->getEasyRequest()); + curl_easy_request_w->pause(CURLPAUSE_ALL); // Keep libcurl at bay. + curl_easy_request_w->bad_file_descriptor(curl_easy_request_w); // Make the main thread cleanly terminate this transaction. + } continue; } // Clock count used for timeouts. @@ -1489,7 +1578,7 @@ int MultiHandle::socket_callback(CURL* easy, curl_socket_t s, int action, void* ThreadSafeBufferedCurlEasyRequest* ptr; CURLcode rese = curl_easy_getinfo(easy, CURLINFO_PRIVATE, &ptr); llassert_always(rese == CURLE_OK); - sock_info = new CurlSocketInfo(self, easy, s, action, ptr); + sock_info = new CurlSocketInfo(self, ASSERT_ONLY(easy,) s, action, ptr); } else { @@ -1613,7 +1702,9 @@ CURLMcode MultiHandle::remove_easy_request(addedEasyRequests_type::iterator cons ThreadSafeBufferedCurlEasyRequest* lockobj = iter->get_ptr().get(); #endif mAddedEasyRequests.erase(iter); +#if CWDEBUG Dout(dc::curl, "MultiHandle::remove_easy_request: Removed AICurlEasyRequest " << (void*)lockobj << "; now processing " << mAddedEasyRequests.size() << " easy handles."); +#endif // Attempt to add a queued request, if any. PerHostRequestQueue_wat(*per_host)->add_queued_to(this); @@ -1719,385 +1810,6 @@ void MultiHandle::finish_easy_request(AICurlEasyRequest const& easy_request, CUR curl_easy_request_w->done(curl_easy_request_w, result); } -//----------------------------------------------------------------------------- -// HTTPTimeout - -//static -F64 const HTTPTimeout::sClockWidth = 1.0 / calc_clock_frequency(); // Time between two clock ticks, in seconds. -U64 HTTPTimeout::sClockCount; // Clock count, set once per select() exit. - -// CURL-THREAD -// This is called when body data was sent to the server socket. -// <-----mLowSpeedOn------> -// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done -// ^ ^ ^ ^ ^ ^ -// | | | | | | -bool HTTPTimeout::data_sent(size_t n) -{ - // Generate events. - if (!mLowSpeedOn) - { - // If we can send data (for the first time) then that's our only way to know we connected. - reset_lowspeed(); - } - // Detect low speed. - return lowspeed(n); -} - -// CURL-THREAD -// This is called when the 'low speed' timer should be started. -// <-----mLowSpeedOn------> <-------mLowSpeedOn--------> -// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done -// ^ ^ -// | | -void HTTPTimeout::reset_lowspeed(void) -{ - mLowSpeedClock = sClockCount; - mLowSpeedOn = true; - mLastSecond = -1; // This causes lowspeed to initialize the rest. - mStalled = (U64)-1; // Stop reply delay timer. - DoutCurl("reset_lowspeed: mLowSpeedClock = " << mLowSpeedClock << "; mStalled = -1"); -} - -// CURL-THREAD -// This is called when everything we had to send to the server has been sent. -// <-----mLowSpeedOn------> -// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done -// ^ -// | -void HTTPTimeout::upload_finished(void) -{ - llassert(!mUploadFinished); // If we get here twice, then the 'upload finished' detection failed. - mUploadFinished = true; - // We finished uploading (if there was a body to upload at all), so not more transfer rate timeouts. - mLowSpeedOn = false; - // Timeout if the server doesn't reply quick enough. - mStalled = sClockCount + mPolicy->getReplyDelay() / sClockWidth; - DoutCurl("upload_finished: mStalled set to sClockCount (" << sClockCount << ") + " << (mStalled - sClockCount) << " (" << mPolicy->getReplyDelay() << " seconds)"); -} - -// CURL-THREAD -// This is called when data was received from the server. -// -// <--------------------------------mNothingReceivedYet------------------------------><-------mLowSpeedOn--------> -// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done -// ^ ^ ^ ^ ^ ^ ^ ^ -// | | | | | | | | -bool HTTPTimeout::data_received(size_t n) -{ - // The HTTP header of the reply is the first thing we receive. - if (mNothingReceivedYet && n > 0) - { - if (!mUploadFinished) - { - // mUploadFinished not being set this point should only happen for GET requests (in fact, then it is normal), - // because in that case it is impossible to detect the difference between connecting and waiting for a reply without - // using CURLOPT_DEBUGFUNCTION. Note that mDebugIsHeadOrGetMethod is only valid when the debug channel 'curlio' is on, - // because it is set in the debug callback function. - Debug(llassert(AICurlEasyRequest_wat(*mLockObj)->mDebugIsHeadOrGetMethod || !dc::curlio.is_on())); - // 'Upload finished' detection failed, generate it now. - upload_finished(); - } - // Turn this flag off again now that we received data, so that if 'upload_finished()' is called again - // for a future upload on the same descriptor, then that won't trigger an assert. - // Note that because we also set mNothingReceivedYet here, we won't enter this code block anymore, - // so it's safe to do this. - mUploadFinished = false; - // Mark that something was received. - mNothingReceivedYet = false; - // We received something; switch to getLowSpeedLimit()/getLowSpeedTime(). - reset_lowspeed(); - } - return mLowSpeedOn ? lowspeed(n) : false; -} - -// CURL_THREAD -// bytes is the number of bytes we just sent or received (including headers). -// Returns true if the transfer should be aborted. -// -// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done -// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ -// | | | | | | | | | | | | | | -bool HTTPTimeout::lowspeed(size_t bytes) -{ - DoutCurlEntering("HTTPTimeout::lowspeed(" << bytes << ")"); - - // The algorithm to determine if we timed out if different from how libcurls CURLOPT_LOW_SPEED_TIME works. - // - // libcurl determines the transfer rate since the last call to an equivalent 'lowspeed' function, and then - // triggers a timeout if CURLOPT_LOW_SPEED_TIME long such a transfer value is less than CURLOPT_LOW_SPEED_LIMIT. - // That doesn't work right because once there IS data it can happen that this function is called a few - // times (with less than a milisecond in between) causing seemingly VERY high "transfer rate" spikes. - // The only correct way to determine the transfer rate is to actually average over CURLOPT_LOW_SPEED_TIME - // seconds. - // - // We do this as follows: we create low_speed_time (in seconds) buckets and fill them with the number - // of bytes received during that second. We also keep track of the sum of all bytes received between 'now' - // and 'now - llmax(starttime, low_speed_time)'. Then if that period reaches at least low_speed_time - // seconds, and the transfer rate (sum / low_speed_time) is less than low_speed_limit, we abort. - - // When are we? - S32 second = (sClockCount - mLowSpeedClock) * sClockWidth; - llassert(sClockWidth > 0.0); - // This REALLY should never happen, but due to another bug it did happened - // and caused something so evil and hard to find that... NEVER AGAIN! - llassert(second >= 0); - - // If this is the same second as last time, just add the number of bytes to the current bucket. - if (second == mLastSecond) - { - mTotalBytes += bytes; - mBuckets[mBucket] += bytes; - return false; - } - - // We arrived at a new second. - // The below is at most executed once per second, even though for - // every currently connected transfer, CPU is not a big issue. - - // Determine the number of buckets needed and increase the number of buckets if needed. - U16 const low_speed_time = mPolicy->getLowSpeedTime(); - if (low_speed_time > mBuckets.size()) - { - mBuckets.resize(low_speed_time, 0); - } - - S32 s = mLastSecond; - mLastSecond = second; - - // If this is the first time this function is called, we need to do some initialization. - if (s == -1) - { - mBucket = 0; // It doesn't really matter where we start. - mTotalBytes = bytes; - mBuckets[mBucket] = bytes; - return false; - } - - // Update all administration. - U16 bucket = mBucket; - while(1) // Run over all the seconds that were skipped. - { - if (++bucket == low_speed_time) - bucket = 0; - if (++s == second) - break; - mTotalBytes -= mBuckets[bucket]; - mBuckets[bucket] = 0; - } - mBucket = bucket; - mTotalBytes -= mBuckets[mBucket]; - mTotalBytes += bytes; - mBuckets[mBucket] = bytes; - - // Check if we timed out. - U32 const low_speed_limit = mPolicy->getLowSpeedLimit(); - U32 mintotalbytes = low_speed_limit * low_speed_time; - DoutCurl("Transfered " << mTotalBytes << " bytes in " << llmin(second, (S32)low_speed_time) << " seconds after " << second << " second" << ((second == 1) ? "" : "s") << "."); - if (second >= low_speed_time) - { - DoutCurl("Average transfer rate is " << (mTotalBytes / low_speed_time) << " bytes/s (low speed limit is " << low_speed_limit << " bytes/s)"); - if (mTotalBytes < mintotalbytes) - { - // The average transfer rate over the passed low_speed_time seconds is too low. Abort the transfer. - llwarns << -#ifdef CWDEBUG - (void*)get_lockobj() << ": " -#endif - "aborting slow connection (average transfer rate below " << low_speed_limit << - " for more than " << low_speed_time << " second" << ((low_speed_time == 1) ? "" : "s") << ")." << llendl; - return true; - } - } - - // Calculate how long the data transfer may stall until we should timeout. - llassert_always(mintotalbytes > 0); - S32 max_stall_time = 0; - U32 dropped_bytes = 0; - while(1) - { - if (++bucket == low_speed_time) // The next second the next bucket will be emptied. - bucket = 0; - ++max_stall_time; - dropped_bytes += mBuckets[bucket]; - // Note how, when max_stall_time == low_speed_time, dropped_bytes has - // to be equal to mTotalBytes, the sum of all vector elements. - llassert_always(max_stall_time < low_speed_time || dropped_bytes == mTotalBytes); - // And thus the following will certainly abort. - if (second + max_stall_time >= low_speed_time && mTotalBytes - dropped_bytes < mintotalbytes) - break; - } - // If this function isn't called again within max_stall_time seconds, we stalled. - mStalled = sClockCount + max_stall_time / sClockWidth; - DoutCurl("mStalled set to sClockCount (" << sClockCount << ") + " << (mStalled - sClockCount) << " (" << max_stall_time << " seconds)"); - - return false; -} - -// CURL-THREAD -// This is called immediately before done() after curl finished, with code. -// <-------mLowSpeedOn--------> -// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done -// ^ -// | -void HTTPTimeout::done(AICurlEasyRequest_wat const& curlEasyRequest_w, CURLcode code) -{ - if (code == CURLE_OPERATION_TIMEDOUT || code == CURLE_COULDNT_RESOLVE_HOST) - { - bool dns_problem = false; - if (code == CURLE_COULDNT_RESOLVE_HOST) - { - // Note that CURLINFO_OS_ERRNO returns 0; we don't know any more than this. - llwarns << "Failed to resolve hostname " << curlEasyRequest_w->getLowercaseHostname() << llendl; - dns_problem = true; - } - else if (mNothingReceivedYet) - { - // Only consider this to possibly be related to a DNS lookup if we didn't - // resolved the host yet, which can be detected by asking for - // CURLINFO_NAMELOOKUP_TIME which is set when libcurl initiates the - // actual connect and thus knows the IP# (possibly from it's DNS cache). - double namelookup_time; - curlEasyRequest_w->getinfo(CURLINFO_NAMELOOKUP_TIME, &namelookup_time); - dns_problem = (namelookup_time == 0); - } - if (dns_problem) - { - // Inform policy object that there might be problems with resolving this host. - // This will increase the connect timeout the next time we try to connect to this host. - AIHTTPTimeoutPolicy::connect_timed_out(curlEasyRequest_w->getLowercaseHostname()); - // AIFIXME: use return value to change priority - } - } - // Make sure no timeout will happen anymore. - mLowSpeedOn = false; - mStalled = (U64)-1; - DoutCurl("done: mStalled set to -1"); -} - -// Libcurl uses GetTickCount on windows, with a resolution of 10 to 16 ms. -// As a result, we can not assume that namelookup_time == 0 has a special meaning. -#define LOWRESTIMER LL_WINDOWS - -void HTTPTimeout::print_diagnostics(CurlEasyRequest const* curl_easy_request, char const* eff_url) -{ - llwarns << "Request to \"" << curl_easy_request->getLowercaseHostname() << "\" timed out for " << curl_easy_request->getTimeoutPolicy()->name() << llendl; - llinfos << "Effective URL: \"" << eff_url << "\"." << llendl; - double namelookup_time, connect_time, appconnect_time, pretransfer_time, starttransfer_time; - curl_easy_request->getinfo(CURLINFO_NAMELOOKUP_TIME, &namelookup_time); - curl_easy_request->getinfo(CURLINFO_CONNECT_TIME, &connect_time); - curl_easy_request->getinfo(CURLINFO_APPCONNECT_TIME, &appconnect_time); - curl_easy_request->getinfo(CURLINFO_PRETRANSFER_TIME, &pretransfer_time); - curl_easy_request->getinfo(CURLINFO_STARTTRANSFER_TIME, &starttransfer_time); - if (namelookup_time == 0 -#if LOWRESTIMER - && connect_time == 0 -#endif - ) - { -#if LOWRESTIMER - llinfos << "Hostname seems to have been still in the DNS cache." << llendl; -#else - llwarns << "Huh? Curl returned CURLE_OPERATION_TIMEDOUT, but DNS lookup did not occur according to timings. Expected CURLE_COULDNT_RESOLVE_PROXY or CURLE_COULDNT_RESOLVE_HOST!" << llendl; - llassert(connect_time == 0); - llassert(appconnect_time == 0); - llassert(pretransfer_time == 0); - llassert(starttransfer_time == 0); - // Fatal error for diagnostics. - return; -#endif - } - // If namelookup_time is less than 500 microseconds, then it's very likely just a DNS cache lookup. - else if (namelookup_time < 500e-6) - { -#if LOWRESTIMER - llinfos << "Hostname was most likely still in DNS cache (or lookup occured in under ~10ms)." << llendl; -#else - llinfos << "Hostname was still in DNS cache." << llendl; -#endif - } - else - { - llinfos << "DNS lookup of " << curl_easy_request->getLowercaseHostname() << " took " << namelookup_time << " seconds." << llendl; - } - if (connect_time == 0 -#if LOWRESTIMER - && namelookup_time > 0 // connect_time, when set, is namelookup_time + something. -#endif - ) - { - llwarns << "Huh? Curl returned CURLE_OPERATION_TIMEDOUT, but connection did not occur according to timings. Expected CURLE_COULDNT_CONNECT!" << llendl; - llassert(appconnect_time == 0); - llassert(pretransfer_time == 0); - llassert(starttransfer_time == 0); - // Fatal error for diagnostics. - return; - } - // If connect_time is almost equal to namelookup_time, then it was just set because it was already connected. - if (connect_time - namelookup_time <= 1e-5) - { -#if LOWRESTIMER // Assuming 10ms resolution. - llinfos << "The socket was most likely already connected (or you connected to a proxy with a connect time of under ~10 ms)." << llendl; -#else - llinfos << "The socket was already connected (to remote or proxy)." << llendl; -#endif - // I'm assuming that the SSL/TLS handshake can be measured with a low res timer. - if (appconnect_time == 0) - { - llwarns << "The SSL/TLS handshake never occurred according to the timings!" << llendl; - return; - } - // If appconnect_time is almost equal to connect_time, then it was just set because this is a connection re-use. - if (appconnect_time - connect_time <= 1e-5) - { - llinfos << "Connection with HTTP server was already established; this was a re-used connection." << llendl; - } - else - { - llinfos << "SSL/TLS handshake with HTTP server took " << (appconnect_time - connect_time) << " seconds." << llendl; - } - } - else - { - llinfos << "Socket connected to remote host (or proxy) in " << (connect_time - namelookup_time) << " seconds." << llendl; - if (appconnect_time == 0) - { - llwarns << "The SSL/TLS handshake never occurred according to the timings!" << llendl; - return; - } - llinfos << "SSL/TLS handshake with HTTP server took " << (appconnect_time - connect_time) << " seconds." << llendl; - } - if (pretransfer_time == 0) - { - llwarns << "The transfer never happened because there was too much in the pipeline (apparently)." << llendl; - return; - } - else if (pretransfer_time - appconnect_time >= 1e-5) - { - llinfos << "Apparently there was a delay, due to waits in line for the pipeline, of " << (pretransfer_time - appconnect_time) << " seconds before the transfer began." << llendl; - } - if (starttransfer_time == 0) - { - llwarns << "No data was ever received from the server according to the timings." << llendl; - } - else - { - llinfos << "The time it took to send the request to the server plus the time it took before the server started to reply was " << (starttransfer_time - pretransfer_time) << " seconds." << llendl; - } - if (mNothingReceivedYet) - { - llinfos << "No data at all was actually received from the server." << llendl; - } - if (mUploadFinished) - { - llinfos << "The request upload finished successfully." << llendl; - } - if (mLastSecond > 0 && mLowSpeedOn) - { - llinfos << "The " << (mNothingReceivedYet ? "upload" : "download") << " did last " << mLastSecond << " second" << ((mLastSecond == 1) ? "" : "s") << ", before it timed out." << llendl; - } -} - } // namespace curlthread } // namespace AICurlPrivate @@ -2146,12 +1858,22 @@ void stopCurlThread(void) if (AICurlThread::sInstance) { AICurlThread::sInstance->stop_thread(); - int count = 101; + int count = 401; while(--count && !AICurlThread::sInstance->isStopped()) { ms_sleep(10); } - Dout(dc::curl, "Curl thread" << (curlThreadIsRunning() ? " not" : "") << " stopped after " << ((100 - count) * 10) << "ms."); + if (AICurlThread::sInstance->isStopped()) + { + // isStopped() returns true somewhere at the end of run(), + // but that doesn't mean the thread really stopped: it still + // needs to destroy it's static variables. + // If we don't join here, then there is a chance that the + // curl thread will crash when using globals that we (the + // main thread) will have destroyed before it REALLY finished. + AICurlThread::sInstance->join_thread(); // Wait till it is REALLY done. + } + llinfos << "Curl thread" << (curlThreadIsRunning() ? " not" : "") << " stopped after " << ((400 - count) * 10) << "ms." << llendl; } } @@ -2169,7 +1891,17 @@ void BufferedCurlEasyRequest::setStatusAndReason(U32 status, std::string const& { mStatus = status; mReason = reason; - AICurlInterface::Stats::status_count[AICurlInterface::Stats::status2index(mStatus)]++; + if (status >= 100 && status < 600 && (status % 100) < 20) + { + // Only count statistic for sane values. + AICurlInterface::Stats::status_count[AICurlInterface::Stats::status2index(mStatus)]++; + } + + // Sanity check. If the server replies with a redirect status then we better have that option turned on! + if ((status >= 300 && status < 400) && mResponder && !mResponder->redirect_status_ok()) + { + llerrs << "Received " << status << " (" << reason << ") for responder \"" << mTimeoutPolicy->name() << "\" which has no followRedir()!" << llendl; + } } void BufferedCurlEasyRequest::processOutput(void) @@ -2180,7 +1912,7 @@ void BufferedCurlEasyRequest::processOutput(void) CURLcode code; AITransferInfo info; getResult(&code, &info); - if (code == CURLE_OK) + if (code == CURLE_OK && mStatus != HTTP_INTERNAL_ERROR) { getinfo(CURLINFO_RESPONSE_CODE, &responseCode); // If getResult code is CURLE_OK then we should have decoded the first header line ourselves. @@ -2193,7 +1925,7 @@ void BufferedCurlEasyRequest::processOutput(void) else { responseCode = HTTP_INTERNAL_ERROR; - responseReason = curl_easy_strerror(code); + responseReason = (code == CURLE_OK) ? mReason : std::string(curl_easy_strerror(code)); setopt(CURLOPT_FRESH_CONNECT, TRUE); } @@ -2289,23 +2021,18 @@ size_t BufferedCurlEasyRequest::curlHeaderCallback(char* data, size_t size, size char const* const header_line = static_cast(data); size_t const header_len = size * nmemb; - if (self_w->httptimeout()->data_received(header_len)) // Update timeout administration. - { - // Transfer timed out. Return 0 which will abort with error CURLE_WRITE_ERROR. - return 0; - } if (!header_len) { return header_len; } std::string header(header_line, header_len); + bool done = false; if (!LLStringUtil::_isASCII(header)) { - return header_len; + done = true; } - // Per HTTP spec the first header line must be the status line. - if (header.substr(0, 5) == "HTTP/") + else if (header.substr(0, 5) == "HTTP/") { std::string::iterator const begin = header.begin(); std::string::iterator const end = header.end(); @@ -2314,23 +2041,41 @@ size_t BufferedCurlEasyRequest::curlHeaderCallback(char* data, size_t size, size std::string::iterator pos2 = std::find(pos1, end, ' '); if (pos2 != end) ++pos2; std::string::iterator pos3 = std::find(pos2, end, '\r'); - U32 status; + U32 status = 0; std::string reason; if (pos3 != end && std::isdigit(*pos1)) { status = atoi(&header_line[pos1 - begin]); reason.assign(pos2, pos3); } - else + if (!(status >= 100 && status < 600 && (status % 100) < 20)) // Sanity check on the decoded status. { + if (status == 0) + { + reason = "Header parse error."; + llwarns << "Received broken header line from server: \"" << header << "\"" << llendl; + } + else + { + reason = "Unexpected HTTP status."; + llwarns << "Received unexpected status value from server (" << status << "): \"" << header << "\"" << llendl; + } + // Either way, this status value is not understood (or taken into account). + // Set it to internal error so that the rest of code treats it as an error. status = HTTP_INTERNAL_ERROR; - reason = "Header parse error."; - llwarns << "Received broken header line from server: \"" << header << "\"" << llendl; - } - { - self_w->received_HTTP_header(); - self_w->setStatusAndReason(status, reason); } + self_w->received_HTTP_header(); + self_w->setStatusAndReason(status, reason); + done = true; + } + // Update timeout administration. This must be done after the status is already known. + if (self_w->httptimeout()->data_received(header_len/*,*/ ASSERT_ONLY_COMMA(self_w->upload_error_status()))) + { + // Transfer timed out. Return 0 which will abort with error CURLE_WRITE_ERROR. + return 0; + } + if (done) + { return header_len; } @@ -2359,14 +2104,25 @@ size_t BufferedCurlEasyRequest::curlHeaderCallback(char* data, size_t size, size } #if defined(CWDEBUG) || defined(DEBUG_CURLIO) -int debug_callback(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr) +int debug_callback(CURL* handle, curl_infotype infotype, char* buf, size_t size, void* user_ptr) { + BufferedCurlEasyRequest* request = (BufferedCurlEasyRequest*)user_ptr; + if (infotype == CURLINFO_HEADER_OUT && size >= 5 && (strncmp(buf, "GET ", 4) == 0 || strncmp(buf, "HEAD ", 5) == 0)) + { + request->mDebugIsHeadOrGetMethod = true; + } + +#ifdef DEBUG_CURLIO + if (!debug_curl_print_debug(handle)) + { + return 0; + } +#endif + #ifdef CWDEBUG using namespace ::libcwd; - - BufferedCurlEasyRequest* request = (BufferedCurlEasyRequest*)user_ptr; std::ostringstream marker; - marker << (void*)request->get_lockobj(); + marker << (void*)request->get_lockobj() << ' '; libcw_do.push_marker(); libcw_do.marker().assign(marker.str().data(), marker.str().size()); if (!debug::channels::dc::curlio.is_on()) @@ -2390,8 +2146,6 @@ int debug_callback(CURL*, curl_infotype infotype, char* buf, size_t size, void* break; case CURLINFO_HEADER_OUT: LibcwDoutStream << "H< "; - if (size >= 5 && (strncmp(buf, "GET ", 4) == 0 || strncmp(buf, "HEAD ", 5) == 0)) - request->mDebugIsHeadOrGetMethod = true; break; case CURLINFO_DATA_IN: LibcwDoutStream << "D> "; @@ -2565,6 +2319,14 @@ void AICurlEasyRequest::removeRequest(void) } } } + { + AICurlEasyRequest_wat curl_easy_request_w(*get()); + // As soon as the lock on the command queue is released, it could be picked up by + // the curl thread and executed. At that point it (already) demands that the easy + // request either timed out or is finished. So, to avoid race conditions that already + // has to be true right now. The call to queued_for_removal() checks this. + curl_easy_request_w->queued_for_removal(curl_easy_request_w); + } #endif // Add a command to remove this request from the multi session to the command queue. command_queue_w->push_back(Command(*this, cmd_remove)); diff --git a/indra/llmessage/aihttpheaders.cpp b/indra/llmessage/aihttpheaders.cpp index 0c6009cad..dc9c7b5bf 100644 --- a/indra/llmessage/aihttpheaders.cpp +++ b/indra/llmessage/aihttpheaders.cpp @@ -107,6 +107,20 @@ void AIHTTPReceivedHeaders::addHeader(std::string const& key, std::string const& { mContainer = new Container; } + else if (equal(key, "set-cookie")) + { + // If a cookie with this name already exists, replace it. + std::string const name = value.substr(0, value.find('=')); + container_t::iterator const end = mContainer->mKeyValuePairs.end(); + for (container_t::iterator header = mContainer->mKeyValuePairs.begin(); header != end; ++header) + { + if (equal(header->first, "set-cookie") && header->second.substr(0, header->second.find('=')) == name) + { + header->second = value; + return; + } + } + } mContainer->mKeyValuePairs.insert(container_t::value_type(key, value)); } @@ -151,3 +165,20 @@ std::ostream& operator<<(std::ostream& os, AIHTTPReceivedHeaders const& headers) return os; } +//static +bool AIHTTPReceivedHeaders::equal(std::string const& key1, std::string const& key2) +{ + if (key1.length() != key2.length()) + { + return false; + } + for (std::string::const_iterator i1 = key1.begin(), i2 = key2.begin(); i1 != key1.end(); ++i1, ++i2) + { + if (((*i1 ^ *i2) & 0xdf) != 0) + { + return false; + } + } + return true; +} + diff --git a/indra/llmessage/aihttpheaders.h b/indra/llmessage/aihttpheaders.h index da40ed7f9..637390660 100644 --- a/indra/llmessage/aihttpheaders.h +++ b/indra/llmessage/aihttpheaders.h @@ -132,6 +132,9 @@ class AIHTTPReceivedHeaders { // Add a header. void addHeader(std::string const& key, std::string const& value); + // Swap headers with another container. + void swap(AIHTTPReceivedHeaders& headers) { LLPointer::swap(mContainer, headers.mContainer); } + // Return true if there are no headers associated with this object. bool empty(void) const { return !mContainer || mContainer->mKeyValuePairs.empty(); } @@ -147,6 +150,9 @@ class AIHTTPReceivedHeaders { // For debug purposes. friend std::ostream& operator<<(std::ostream& os, AIHTTPReceivedHeaders const& headers); + // Returns true if the two keys compare equal (ie, "Set-Cookie" == "set-cookie"). + static bool equal(std::string const& key1, std::string const& key2); + private: struct Container : public LLThreadSafeRefCount { container_t mKeyValuePairs; diff --git a/indra/llmessage/aihttptimeout.cpp b/indra/llmessage/aihttptimeout.cpp new file mode 100644 index 000000000..61ed5ca86 --- /dev/null +++ b/indra/llmessage/aihttptimeout.cpp @@ -0,0 +1,495 @@ +/** + * @file aihttptimeout.cpp + * @brief Implementation of HTTPTimeout + * + * Copyright (c) 2012, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 28/04/2012 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef HTTPTIMEOUT_TESTSUITE + +#include "linden_common.h" +#include "aihttptimeoutpolicy.h" +#include "lltimer.h" // calc_clock_frequency() +#include "aicurl.h" // DoutCurl + +#undef AICurlPrivate + +#else + +#include "../llcommon/stdtypes.h" +#include +#include + +#define llassert assert +#define llassert_always assert +#define DoutCurl(...) do { std::cout << __VA_ARGS__ ; } while(0) +#define Debug(...) do { } while(0) +#define llmin std::min +#define llwarns std::cout +#define llendl std::endl +int const CURLE_OPERATION_TIMEDOUT = 1; +int const CURLE_COULDNT_RESOLVE_HOST = 2; +int const CURLINFO_NAMELOOKUP_TIME = 3; + +F64 calc_clock_frequency(void) { return 1000000.0; } + +template +struct AIAccess { + T* mP; + AIAccess(T* p) : mP(p) { } + T* operator->() const { return mP; } +}; + +struct AIHTTPTimeoutPolicy { + U16 getReplyDelay(void) const { return 60; } + U16 getLowSpeedTime(void) const { return 30; } + U32 getLowSpeedLimit(void) const { return 56000; } + static bool connect_timed_out(std::string const&) { return false; } +}; + +namespace AICurlPrivate { + +class BufferedCurlEasyRequest { +public: + char const* getLowercaseHostname(void) const { return "hostname.com"; } + void getinfo(const int&, double* p) { *p = 0.1; } +}; + +} + +#endif // HTTPTIMEOUT_TESTSUITE + +#include "aihttptimeout.h" + +namespace AICurlPrivate { +namespace curlthread { + +//----------------------------------------------------------------------------- +// HTTPTimeout + +//static +F64 const HTTPTimeout::sClockWidth = 1.0 / calc_clock_frequency(); // Time between two clock ticks, in seconds. +U64 HTTPTimeout::sClockCount; // Clock count, set once per select() exit. + +// CURL-THREAD +// This is called when body data was sent to the server socket. +// <-----mLowSpeedOn------> +// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done +// ^ ^ ^ ^ ^ ^ +// | | | | | | +bool HTTPTimeout::data_sent(size_t n) +{ + // Generate events. + if (!mLowSpeedOn) + { + // If we can send data (for the first time) then that's our only way to know we connected. + reset_lowspeed(); + } + // Detect low speed. + return lowspeed(n); +} + +// CURL-THREAD +// This is called when the 'low speed' timer should be started. +// <-----mLowSpeedOn------> <-------mLowSpeedOn--------> +// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done +// ^ ^ +// | | +void HTTPTimeout::reset_lowspeed(void) +{ + mLowSpeedClock = sClockCount; + mLowSpeedOn = true; + mLastSecond = -1; // This causes lowspeed to initialize the rest. + mStalled = (U64)-1; // Stop reply delay timer. + DoutCurl("reset_lowspeed: mLowSpeedClock = " << mLowSpeedClock << "; mStalled = -1"); +} + +// CURL-THREAD +// This is called when everything we had to send to the server has been sent. +// <-----mLowSpeedOn------> +// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done +// ^ +// | +void HTTPTimeout::upload_finished(void) +{ + llassert(!mUploadFinished); // If we get here twice, then the 'upload finished' detection failed. + mUploadFinished = true; + // We finished uploading (if there was a body to upload at all), so not more transfer rate timeouts. + mLowSpeedOn = false; + // Timeout if the server doesn't reply quick enough. + mStalled = sClockCount + mPolicy->getReplyDelay() / sClockWidth; + DoutCurl("upload_finished: mStalled set to sClockCount (" << sClockCount << ") + " << (mStalled - sClockCount) << " (" << mPolicy->getReplyDelay() << " seconds)"); +} + +// CURL-THREAD +// This is called when data was received from the server. +// +// <--------------------------------mNothingReceivedYet------------------------------><-------mLowSpeedOn--------> +// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done +// ^ ^ ^ ^ ^ ^ ^ ^ +// | | | | | | | | +bool HTTPTimeout::data_received(size_t n/*,*/ +#ifdef CWDEBUG + ASSERT_ONLY_COMMA(bool upload_error_status) +#else + ASSERT_ONLY_COMMA(bool) +#endif + ) +{ + // The HTTP header of the reply is the first thing we receive. + if (mNothingReceivedYet && n > 0) + { + if (!mUploadFinished) + { + // mUploadFinished not being set this point should only happen for GET requests (in fact, then it is normal), + // because in that case it is impossible to detect the difference between connecting and waiting for a reply without + // using CURLOPT_DEBUGFUNCTION. Note that mDebugIsHeadOrGetMethod is only valid when the debug channel 'curlio' is on, + // because it is set in the debug callback function. + // This is also normal if we received a HTTP header with an error status, since that can interrupt our upload. + Debug(llassert(upload_error_status || AICurlEasyRequest_wat(*mLockObj)->mDebugIsHeadOrGetMethod || !dc::curlio.is_on())); + // 'Upload finished' detection failed, generate it now. + upload_finished(); + } + // Turn this flag off again now that we received data, so that if 'upload_finished()' is called again + // for a future upload on the same descriptor, then that won't trigger an assert. + // Note that because we also set mNothingReceivedYet here, we won't enter this code block anymore, + // so it's safe to do this. + mUploadFinished = false; + // Mark that something was received. + mNothingReceivedYet = false; + // We received something; switch to getLowSpeedLimit()/getLowSpeedTime(). + reset_lowspeed(); + } + return mLowSpeedOn ? lowspeed(n) : false; +} + +// CURL_THREAD +// bytes is the number of bytes we just sent or received (including headers). +// Returns true if the transfer should be aborted. +// +// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done +// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +// | | | | | | | | | | | | | | +bool HTTPTimeout::lowspeed(size_t bytes) +{ + //DoutCurlEntering("HTTPTimeout::lowspeed(" << bytes << ")"); commented out... too spammy for normal use. + + // The algorithm to determine if we timed out if different from how libcurls CURLOPT_LOW_SPEED_TIME works. + // + // libcurl determines the transfer rate since the last call to an equivalent 'lowspeed' function, and then + // triggers a timeout if CURLOPT_LOW_SPEED_TIME long such a transfer value is less than CURLOPT_LOW_SPEED_LIMIT. + // That doesn't work right because once there IS data it can happen that this function is called a few + // times (with less than a milisecond in between) causing seemingly VERY high "transfer rate" spikes. + // The only correct way to determine the transfer rate is to actually average over CURLOPT_LOW_SPEED_TIME + // seconds. + // + // We do this as follows: we create low_speed_time (in seconds) buckets and fill them with the number + // of bytes received during that second. We also keep track of the sum of all bytes received between 'now' + // and 'now - llmax(starttime, low_speed_time)'. Then if that period reaches at least low_speed_time + // seconds, and the transfer rate (sum / low_speed_time) is less than low_speed_limit, we abort. + + // When are we? + S32 second = (sClockCount - mLowSpeedClock) * sClockWidth; + llassert(sClockWidth > 0.0); + // This REALLY should never happen, but due to another bug it did happened + // and caused something so evil and hard to find that... NEVER AGAIN! + llassert(second >= 0); + + // If this is the same second as last time, just add the number of bytes to the current bucket. + if (second == mLastSecond) + { + mTotalBytes += bytes; + mBuckets[mBucket] += bytes; + return false; + } + + // We arrived at a new second. + // The below is at most executed once per second, even though for + // every currently connected transfer, CPU is not a big issue. + + // Determine the number of buckets needed and increase the number of buckets if needed. + U16 const low_speed_time = mPolicy->getLowSpeedTime(); + if (low_speed_time > mBuckets.size()) + { + mBuckets.resize(low_speed_time, 0); + } + + S32 s = mLastSecond; + mLastSecond = second; + + // If this is the first time this function is called, we need to do some initialization. + if (s == -1) + { + mBucket = 0; // It doesn't really matter where we start. + mTotalBytes = bytes; + mBuckets[mBucket] = bytes; + return false; + } + + // Update all administration. + U16 bucket = mBucket; + while(1) // Run over all the seconds that were skipped. + { + if (++bucket == low_speed_time) + bucket = 0; + if (++s == second) + break; + mTotalBytes -= mBuckets[bucket]; + mBuckets[bucket] = 0; + } + mBucket = bucket; + mTotalBytes -= mBuckets[mBucket]; + mTotalBytes += bytes; + mBuckets[mBucket] = bytes; + + // Check if we timed out. + U32 const low_speed_limit = mPolicy->getLowSpeedLimit(); + U32 mintotalbytes = low_speed_limit * low_speed_time; + DoutCurl("Transfered " << mTotalBytes << " bytes in " << llmin(second, (S32)low_speed_time) << " seconds after " << second << " second" << ((second == 1) ? "" : "s") << "."); + if (second >= low_speed_time) + { + DoutCurl("Average transfer rate is " << (mTotalBytes / low_speed_time) << " bytes/s (low speed limit is " << low_speed_limit << " bytes/s)"); + if (mTotalBytes < mintotalbytes) + { + // The average transfer rate over the passed low_speed_time seconds is too low. Abort the transfer. + llwarns << +#ifdef CWDEBUG + (void*)get_lockobj() << ": " +#endif + "aborting slow connection (average transfer rate below " << low_speed_limit << + " for more than " << low_speed_time << " second" << ((low_speed_time == 1) ? "" : "s") << ")." << llendl; + return true; + } + } + + // Calculate how long the data transfer may stall until we should timeout. + llassert_always(mintotalbytes > 0); + S32 max_stall_time = 0; + U32 dropped_bytes = 0; + while(1) + { + if (++bucket == low_speed_time) // The next second the next bucket will be emptied. + bucket = 0; + ++max_stall_time; + dropped_bytes += mBuckets[bucket]; + // Note how, when max_stall_time == low_speed_time, dropped_bytes has + // to be equal to mTotalBytes, the sum of all vector elements. + llassert(max_stall_time < low_speed_time || dropped_bytes == mTotalBytes); + // AIFIXME: This is a bug and should really be fixed instead of just be a warning. + if (!(max_stall_time < low_speed_time || dropped_bytes == mTotalBytes)) + { + llwarns << "ASSERT max_stall_time < low_speed_time || dropped_bytes == mTotalBytes failed... aborting. " + "max_stall_time = " << max_stall_time << "; low_speed_time = " << low_speed_time << + "; dropped_bytes = " << dropped_bytes << "; mTotalBytes = " << mTotalBytes << llendl; + break; + } + // And thus the following will certainly abort. + if (second + max_stall_time >= low_speed_time && mTotalBytes - dropped_bytes < mintotalbytes) + break; + } + // If this function isn't called again within max_stall_time seconds, we stalled. + mStalled = sClockCount + max_stall_time / sClockWidth; + DoutCurl("mStalled set to sClockCount (" << sClockCount << ") + " << (mStalled - sClockCount) << " (" << max_stall_time << " seconds)"); + + return false; +} + +// CURL-THREAD +// This is called immediately before done() after curl finished, with code. +// <-------mLowSpeedOn--------> +// queued--><--DNS lookup + connect + send headers-->[<--send body (if any)-->]<--replydelay--><--receive headers + body--><--done +// ^ +// | +void HTTPTimeout::done(AICurlEasyRequest_wat const& curlEasyRequest_w, CURLcode code) +{ + if (code == CURLE_OPERATION_TIMEDOUT || code == CURLE_COULDNT_RESOLVE_HOST) + { + bool dns_problem = false; + if (code == CURLE_COULDNT_RESOLVE_HOST) + { + // Note that CURLINFO_OS_ERRNO returns 0; we don't know any more than this. + llwarns << "Failed to resolve hostname " << curlEasyRequest_w->getLowercaseHostname() << llendl; + dns_problem = true; + } + else if (mNothingReceivedYet) + { + // Only consider this to possibly be related to a DNS lookup if we didn't + // resolved the host yet, which can be detected by asking for + // CURLINFO_NAMELOOKUP_TIME which is set when libcurl initiates the + // actual connect and thus knows the IP# (possibly from it's DNS cache). + double namelookup_time; + curlEasyRequest_w->getinfo(CURLINFO_NAMELOOKUP_TIME, &namelookup_time); + dns_problem = (namelookup_time == 0); + } + if (dns_problem) + { + // Inform policy object that there might be problems with resolving this host. + // This will increase the connect timeout the next time we try to connect to this host. + AIHTTPTimeoutPolicy::connect_timed_out(curlEasyRequest_w->getLowercaseHostname()); + // AIFIXME: use return value to change priority + } + } + // Make sure no timeout will happen anymore. + mLowSpeedOn = false; + mStalled = (U64)-1; + DoutCurl("done: mStalled set to -1"); +} + +// Libcurl uses GetTickCount on windows, with a resolution of 10 to 16 ms. +// As a result, we can not assume that namelookup_time == 0 has a special meaning. +#define LOWRESTIMER LL_WINDOWS + +void HTTPTimeout::print_diagnostics(CurlEasyRequest const* curl_easy_request, char const* eff_url) +{ +#ifndef HTTPTIMEOUT_TESTSUITE + llwarns << "Request to \"" << curl_easy_request->getLowercaseHostname() << "\" timed out for " << curl_easy_request->getTimeoutPolicy()->name() << llendl; + llinfos << "Effective URL: \"" << eff_url << "\"." << llendl; + double namelookup_time, connect_time, appconnect_time, pretransfer_time, starttransfer_time; + curl_easy_request->getinfo(CURLINFO_NAMELOOKUP_TIME, &namelookup_time); + curl_easy_request->getinfo(CURLINFO_CONNECT_TIME, &connect_time); + curl_easy_request->getinfo(CURLINFO_APPCONNECT_TIME, &appconnect_time); + curl_easy_request->getinfo(CURLINFO_PRETRANSFER_TIME, &pretransfer_time); + curl_easy_request->getinfo(CURLINFO_STARTTRANSFER_TIME, &starttransfer_time); + if (namelookup_time == 0 +#if LOWRESTIMER + && connect_time == 0 +#endif + ) + { +#if LOWRESTIMER + llinfos << "Hostname seems to have been still in the DNS cache." << llendl; +#else + llwarns << "Curl returned CURLE_OPERATION_TIMEDOUT and DNS lookup did not occur according to timings. Apparently the resolve attempt timed out (bad network?)" << llendl; + llassert(connect_time == 0); + llassert(appconnect_time == 0); + llassert(pretransfer_time == 0); + llassert(starttransfer_time == 0); + return; +#endif + } + // If namelookup_time is less than 500 microseconds, then it's very likely just a DNS cache lookup. + else if (namelookup_time < 500e-6) + { +#if LOWRESTIMER + llinfos << "Hostname was most likely still in DNS cache (or lookup occured in under ~10ms)." << llendl; +#else + llinfos << "Hostname was still in DNS cache." << llendl; +#endif + } + else + { + llinfos << "DNS lookup of " << curl_easy_request->getLowercaseHostname() << " took " << namelookup_time << " seconds." << llendl; + } + if (connect_time == 0 +#if LOWRESTIMER + && namelookup_time > 0 // connect_time, when set, is namelookup_time + something. +#endif + ) + { + llwarns << "Curl returned CURLE_OPERATION_TIMEDOUT and connection did not occur according to timings: apparently the connect attempt timed out (bad network?)" << llendl; + llassert(appconnect_time == 0); + llassert(pretransfer_time == 0); + llassert(starttransfer_time == 0); + return; + } + // If connect_time is almost equal to namelookup_time, then it was just set because it was already connected. + if (connect_time - namelookup_time <= 1e-5) + { +#if LOWRESTIMER // Assuming 10ms resolution. + llinfos << "The socket was most likely already connected (or you connected to a proxy with a connect time of under ~10 ms)." << llendl; +#else + llinfos << "The socket was already connected (to remote or proxy)." << llendl; +#endif + // I'm assuming that the SSL/TLS handshake can be measured with a low res timer. + if (appconnect_time == 0) + { + llwarns << "The SSL/TLS handshake never occurred according to the timings!" << llendl; + return; + } + // If appconnect_time is almost equal to connect_time, then it was just set because this is a connection re-use. + if (appconnect_time - connect_time <= 1e-5) + { + llinfos << "Connection with HTTP server was already established; this was a re-used connection." << llendl; + } + else + { + llinfos << "SSL/TLS handshake with HTTP server took " << (appconnect_time - connect_time) << " seconds." << llendl; + } + } + else + { + llinfos << "Socket connected to remote host (or proxy) in " << (connect_time - namelookup_time) << " seconds." << llendl; + if (appconnect_time == 0) + { + llwarns << "The SSL/TLS handshake never occurred according to the timings!" << llendl; + return; + } + llinfos << "SSL/TLS handshake with HTTP server took " << (appconnect_time - connect_time) << " seconds." << llendl; + } + if (pretransfer_time == 0) + { + llwarns << "The transfer never happened because there was too much in the pipeline (apparently)." << llendl; + return; + } + else if (pretransfer_time - appconnect_time >= 1e-5) + { + llinfos << "Apparently there was a delay, due to waits in line for the pipeline, of " << (pretransfer_time - appconnect_time) << " seconds before the transfer began." << llendl; + } + if (starttransfer_time == 0) + { + llwarns << "No data was ever received from the server according to the timings." << llendl; + } + else + { + llinfos << "The time it took to send the request to the server plus the time it took before the server started to reply was " << (starttransfer_time - pretransfer_time) << " seconds." << llendl; + } + if (mNothingReceivedYet) + { + llinfos << "No data at all was actually received from the server." << llendl; + } + if (mUploadFinished) + { + llinfos << "The request upload finished successfully." << llendl; + } + if (mLastSecond > 0 && mLowSpeedOn) + { + llinfos << "The " << (mNothingReceivedYet ? "upload" : "download") << " did last " << mLastSecond << " second" << ((mLastSecond == 1) ? "" : "s") << ", before it timed out." << llendl; + } +#endif // HTTPTIMEOUT_TESTSUITE +} + +} // namespace curlthread +} // namespace AICurlPrivate + +#ifdef HTTPTIMEOUT_TESTSUITE +int main() +{ + using namespace AICurlPrivate::curlthread; + AIHTTPTimeoutPolicy policy; + HTTPTimeout test(&policy, NULL); +} +#endif // HTTPTIMEOUT_TESTSUITE + diff --git a/indra/llmessage/aihttptimeout.h b/indra/llmessage/aihttptimeout.h new file mode 100644 index 000000000..6bb89ee20 --- /dev/null +++ b/indra/llmessage/aihttptimeout.h @@ -0,0 +1,136 @@ +/** + * @file aihttptimeout.h + * @brief HTTP timeout control class. + * + * Copyright (c) 2012, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 28/04/2012 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AIHTTPTIMEOUT_H +#define AIHTTPTIMEOUT_H + +#include + +#ifndef HTTPTIMEOUT_TESTSUITE + +#include "llrefcount.h" +#include "aithreadsafe.h" // AIAccess + +#include // Needed for files that include this header (also for aicurlprivate.h). +#ifdef DEBUG_CURLIO +#include "debug_libcurl.h" +#endif + +#else + +#include + +class LLRefCount { }; +template struct AIAccess; +typedef int CURLcode; + +#define ASSERT_ONLY_COMMA(...) , __VA_ARGS__ + +#endif + +class AIHTTPTimeoutPolicy; + +// Forward declaration (see aicurlprivate.h). +namespace AICurlPrivate { + class BufferedCurlEasyRequest; +} // namespace AICurlPrivate + +typedef AIAccess AICurlEasyRequest_wat; + +namespace AICurlPrivate { + +class CurlEasyRequest; +class ThreadSafeBufferedCurlEasyRequest; + +namespace curlthread { + +// A class that keeps track of timeout administration per connection. +class HTTPTimeout : public LLRefCount { + private: + AIHTTPTimeoutPolicy const* mPolicy; // A pointer to the used timeout policy. + std::vector mBuckets; // An array with the number of bytes transfered in each second. + U16 mBucket; // The bucket corresponding to mLastSecond. + bool mNothingReceivedYet; // Set when created, reset when the HTML reply header from the server is received. + bool mLowSpeedOn; // Set while uploading or downloading data. + bool mUploadFinished; // Used to keep track of whether upload_finished was called yet. + S32 mLastSecond; // The time at which lowspeed() was last called, in seconds since mLowSpeedClock. + U32 mTotalBytes; // The sum of all bytes in mBuckets. + U64 mLowSpeedClock; // Clock count at which low speed detection (re)started. + U64 mStalled; // The clock count at which this transaction is considered to be stalling if nothing is transfered anymore. + public: + static F64 const sClockWidth; // Time between two clock ticks in seconds. + static U64 sClockCount; // Clock count used as 'now' during one loop of the main loop. +#if defined(CWDEBUG) || defined(DEBUG_CURLIO) + ThreadSafeBufferedCurlEasyRequest* mLockObj; +#endif + + public: + HTTPTimeout(AIHTTPTimeoutPolicy const* policy, ThreadSafeBufferedCurlEasyRequest* lock_obj) : + mPolicy(policy), mNothingReceivedYet(true), mLowSpeedOn(false), mUploadFinished(false), mStalled((U64)-1) +#if defined(CWDEBUG) || defined(DEBUG_CURLIO) + , mLockObj(lock_obj) +#endif + { } + + // Called when everything we had to send to the server has been sent. + void upload_finished(void); + + // Called when data is sent. Returns true if transfer timed out. + bool data_sent(size_t n); + + // Called when data is received. Returns true if transfer timed out. + bool data_received(size_t n/*,*/ ASSERT_ONLY_COMMA(bool upload_error_status = false)); + + // Called immediately before done() after curl finished, with code. + void done(AICurlEasyRequest_wat const& curlEasyRequest_w, CURLcode code); + + // Accessor. + bool has_stalled(void) const { return mStalled < sClockCount; } + + // Called from BufferedCurlEasyRequest::processOutput if a timeout occurred. + void print_diagnostics(CurlEasyRequest const* curl_easy_request, char const* eff_url); + +#if defined(CWDEBUG) || defined(DEBUG_CURLIO) + void* get_lockobj(void) const { return mLockObj; } +#endif + + private: + // (Re)start low speed transer rate detection. + void reset_lowspeed(void); + + // Common low speed detection, Called from data_sent or data_received. + bool lowspeed(size_t bytes); +}; + +} // namespace curlthread +} // namespace AICurlPrivate + +#endif + diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index 4acd41267..a45b990e9 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -646,6 +646,12 @@ AIHTTPTimeoutPolicyBase transfer_18s(AIHTTPTimeoutPolicyBase::getDebugSettingsCu transactionOp18s ); +// This used to be '30 seconds'. +Transaction transactionOp30s(30); +AIHTTPTimeoutPolicyBase transfer_30s(AIHTTPTimeoutPolicyBase::getDebugSettingsCurlTimeout(), + transactionOp30s + ); + // This used to be '300 seconds'. We derive this from the hardcoded result so users can't mess with it. Transaction transactionOp300s(300); AIHTTPTimeoutPolicyBase transfer_300s(HTTPTimeoutPolicy_default, @@ -820,6 +826,7 @@ P(accountingCostResponder); P(agentStateResponder); P(assetUploadResponder); P(asyncConsoleResponder); +P(avatarPickerResponder); P(authHandler); P(avatarNameResponder); P2(baseCapabilitiesComplete, transfer_18s); @@ -838,6 +845,7 @@ P(estateChangeInfoResponder); P(eventPollResponder); P(fetchInventoryResponder); P(fnPtrResponder); +P2(groupMemberDataResponder, transfer_300s); P2(groupProposalBallotResponder, transfer_300s); P(homeLocationResponder); P(HTTPGetResponder); @@ -850,6 +858,7 @@ P(lcl_responder); P(MPImportGetResponder); P(MPImportPostResponder); P(mapLayerResponder); +P2(maturityPreferences, transfer_30s); P(mediaTypeResponder); P(meshDecompositionResponder); P(meshHeaderResponder); @@ -871,6 +880,7 @@ P(placeAvatarTeleportResponder); P(productInfoRequestResponder); P(regionResponder); P(remoteParcelRequestResponder); +P(requestAgentUpdateAppearance); P(responderIgnore); P(sessionInviteResponder); P(setDisplayNameResponder); @@ -889,6 +899,7 @@ P(viewerStatsResponder); P(viewerVoiceAccountProvisionResponder); P(voiceCallCapResponder); P(voiceClientCapResponder); +P(webProfileResponders); P(wholeModelFeeResponder); P(wholeModelUploadResponder); P2(XMLRPCResponder, connect_40s); diff --git a/indra/llmessage/debug_libcurl.cpp b/indra/llmessage/debug_libcurl.cpp index 512bc696c..0a302e601 100644 --- a/indra/llmessage/debug_libcurl.cpp +++ b/indra/llmessage/debug_libcurl.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "llpreprocessor.h" #include #define COMPILING_DEBUG_LIBCURL_CC @@ -528,19 +529,66 @@ std::ostream& operator<<(std::ostream& os, EvBitmask const& bitmask) return os; } +// Set this to limit the curl debug output to specific easy handles. +bool gDebugCurlTerse = false; + +namespace { + +std::vector handles; + +inline bool print_debug(CURL* handle) +{ + if (!gDebugCurlTerse) + return true; + return std::find(handles.begin(), handles.end(), handle) != handles.end(); +} + +} // namespace + +void debug_curl_add_easy(CURL* handle) +{ + std::vector::iterator iter = std::find(handles.begin(), handles.end(), handle); + if (iter == handles.end()) + { + handles.push_back(handle); + Dout(dc::warning, "debug_curl_add_easy(" << (void*)handle << "): added"); + } + llassert(print_debug(handle)); +} + +void debug_curl_remove_easy(CURL* handle) +{ + std::vector::iterator iter = std::find(handles.begin(), handles.end(), handle); + if (iter != handles.end()) + { + handles.erase(iter); + Dout(dc::warning, "debug_curl_remove_easy(" << (void*)handle << "): removed"); + } + llassert(!print_debug(handle)); +} + +bool debug_curl_print_debug(CURL* handle) +{ + return print_debug(handle); +} + extern "C" { void debug_curl_easy_cleanup(CURL* handle) { curl_easy_cleanup(handle); - Dout(dc::curl, "curl_easy_cleanup(" << (AICURL*)handle << ")"); + if (print_debug(handle)) + { + Dout(dc::curltr, "curl_easy_cleanup(" << (AICURL*)handle << ")"); + } } CURL* debug_curl_easy_duphandle(CURL* handle) { CURL* ret; ret = curl_easy_duphandle(handle); - Dout(dc::curl, "curl_easy_duphandle(" << (AICURL*)handle << ") = " << (AICURL*)ret); + if (!print_debug(handle)) return ret; + Dout(dc::curltr, "curl_easy_duphandle(" << (AICURL*)handle << ") = " << (AICURL*)ret); return ret; } @@ -548,11 +596,12 @@ char* debug_curl_easy_escape(CURL* curl, char* url, int length) { char* ret; ret = curl_easy_escape(curl, url, length); - Dout(dc::curl, "curl_easy_escape(" << (AICURL*)curl << ", \"" << url << "\", " << length << ") = \"" << ret << '"'); + if (!print_debug(curl)) return ret; + Dout(dc::curltr, "curl_easy_escape(" << (AICURL*)curl << ", \"" << url << "\", " << length << ") = \"" << ret << '"'); return ret; } -CURLcode debug_curl_easy_getinfo(CURL* curl, CURLINFO info, ...) +CURLcode debug_curl_easy_getinfo(CURL* handle, CURLINFO info, ...) { CURLcode ret; va_list ap; @@ -566,26 +615,27 @@ CURLcode debug_curl_easy_getinfo(CURL* curl, CURLINFO info, ...) va_start(ap, info); param.some_ptr = va_arg(ap, void*); va_end(ap); - ret = curl_easy_getinfo(curl, info, param.some_ptr); + ret = curl_easy_getinfo(handle, info, param.some_ptr); + if (!print_debug(handle)) return ret; if (info == CURLINFO_PRIVATE) { - Dout(dc::curl, "curl_easy_getinfo(" << (AICURL*)curl << ", " << info << ", 0x" << std::hex << (size_t)param.some_ptr << std::dec << ") = " << ret); + Dout(dc::curltr, "curl_easy_getinfo(" << (AICURL*)handle << ", " << info << ", 0x" << std::hex << (size_t)param.some_ptr << std::dec << ") = " << ret); } else { switch((info & CURLINFO_TYPEMASK)) { case CURLINFO_STRING: - Dout(dc::curl, "curl_easy_getinfo(" << (AICURL*)curl << ", " << info << ", (char**){ \"" << (ret == CURLE_OK ? *param.char_ptr : " ") << "\" }) = " << ret); + Dout(dc::curltr, "curl_easy_getinfo(" << (AICURL*)handle << ", " << info << ", (char**){ \"" << (ret == CURLE_OK ? *param.char_ptr : " ") << "\" }) = " << ret); break; case CURLINFO_LONG: - Dout(dc::curl, "curl_easy_getinfo(" << (AICURL*)curl << ", " << info << ", (long*){ " << (ret == CURLE_OK ? *param.long_ptr : 0L) << "L }) = " << ret); + Dout(dc::curltr, "curl_easy_getinfo(" << (AICURL*)handle << ", " << info << ", (long*){ " << (ret == CURLE_OK ? *param.long_ptr : 0L) << "L }) = " << ret); break; case CURLINFO_DOUBLE: - Dout(dc::curl, "curl_easy_getinfo(" << (AICURL*)curl << ", " << info << ", (double*){" << (ret == CURLE_OK ? *param.double_ptr : 0.) << "}) = " << ret); + Dout(dc::curltr, "curl_easy_getinfo(" << (AICURL*)handle << ", " << info << ", (double*){" << (ret == CURLE_OK ? *param.double_ptr : 0.) << "}) = " << ret); break; case CURLINFO_SLIST: - Dout(dc::curl, "curl_easy_getinfo(" << (AICURL*)curl << ", " << info << ", (curl_slist**){ " << (ret == CURLE_OK ? **param.curl_slist_ptr : unchanged_slist) << " }) = " << ret); + Dout(dc::curltr, "curl_easy_getinfo(" << (AICURL*)handle << ", " << info << ", (curl_slist**){ " << (ret == CURLE_OK ? **param.curl_slist_ptr : unchanged_slist) << " }) = " << ret); break; } } @@ -596,7 +646,8 @@ CURL* debug_curl_easy_init(void) { CURL* ret; ret = curl_easy_init(); - Dout(dc::curl, "curl_easy_init() = " << (AICURL*)ret); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_easy_init() = " << (AICURL*)ret); return ret; } @@ -604,7 +655,8 @@ CURLcode debug_curl_easy_pause(CURL* handle, int bitmask) { CURLcode ret; ret = curl_easy_pause(handle, bitmask); - Dout(dc::curl, "curl_easy_pause(" << (AICURL*)handle << ", 0x" << std::hex << bitmask << std::dec << ") = " << ret); + if (!print_debug(handle)) return ret; + Dout(dc::curltr, "curl_easy_pause(" << (AICURL*)handle << ", 0x" << std::hex << bitmask << std::dec << ") = " << ret); return ret; } @@ -612,19 +664,21 @@ CURLcode debug_curl_easy_perform(CURL* handle) { CURLcode ret; ret = curl_easy_perform(handle); - Dout(dc::curl, "curl_easy_perform(" << (AICURL*)handle << ") = " << ret); + if (!print_debug(handle)) return ret; + Dout(dc::curltr, "curl_easy_perform(" << (AICURL*)handle << ") = " << ret); return ret; } void debug_curl_easy_reset(CURL* handle) { curl_easy_reset(handle); - Dout(dc::curl, "curl_easy_reset(" << (AICURL*)handle << ")"); + if (!print_debug(handle)) return; + Dout(dc::curltr, "curl_easy_reset(" << (AICURL*)handle << ")"); } CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...) { - CURLcode ret; + CURLcode ret = CURLE_OBSOLETE50; // Suppress compiler warning. va_list ap; union param_type { long along; @@ -656,7 +710,10 @@ CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...) case CURLOPTTYPE_LONG: { ret = curl_easy_setopt(handle, option, param.along); - Dout(dc::curl, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", " << param.along << "L) = " << ret); + if (print_debug(handle)) + { + Dout(dc::curltr, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", " << param.along << "L) = " << ret); + } if (option == CURLOPT_POSTFIELDSIZE) { postfieldsize = param.along; @@ -666,7 +723,8 @@ CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...) case CURLOPTTYPE_OBJECTPOINT: { ret = curl_easy_setopt(handle, option, param.ptr); - LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcwd::libcw_do, dc::curl) + if (!print_debug(handle)) break; + LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcwd::libcw_do, dc::curltr) LibcwDoutStream << "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", "; // For a subset of all options that take a char*, print the string passed. if (option == CURLOPT_PROXY || // Set HTTP proxy to use. The parameter should be a char* to a zero terminated string holding the host name or dotted IP address. @@ -717,11 +775,11 @@ CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...) if (option == CURLOPT_HTTPHEADER && param.ptr) { debug::Indent indent(2); - Dout(dc::curl, "HTTP Headers:"); + Dout(dc::curltr, "HTTP Headers:"); struct curl_slist* list = (struct curl_slist*)param.ptr; while (list) { - Dout(dc::curl, '"' << list->data << '"'); + Dout(dc::curltr, '"' << list->data << '"'); list = list->next; } } @@ -729,12 +787,18 @@ CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...) } case CURLOPTTYPE_FUNCTIONPOINT: ret = curl_easy_setopt(handle, option, param.ptr); - Dout(dc::curl, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", (function*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret); + if (print_debug(handle)) + { + Dout(dc::curltr, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", (function*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret); + } break; case CURLOPTTYPE_OFF_T: { ret = curl_easy_setopt(handle, option, param.offset); - Dout(dc::curl, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", (curl_off_t)" << param.offset << ") = " << ret); + if (print_debug(handle)) + { + Dout(dc::curltr, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", (curl_off_t)" << param.offset << ") = " << ret); + } if (option == CURLOPT_POSTFIELDSIZE_LARGE) { postfieldsize = (long)param.offset; @@ -751,7 +815,8 @@ char const* debug_curl_easy_strerror(CURLcode errornum) { char const* ret; ret = curl_easy_strerror(errornum); - Dout(dc::curl, "curl_easy_strerror(" << errornum << ") = \"" << ret << '"'); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_easy_strerror(" << errornum << ") = \"" << ret << '"'); return ret; } @@ -759,35 +824,38 @@ char* debug_curl_easy_unescape(CURL* curl, char* url, int inlength, int* outleng { char* ret; ret = curl_easy_unescape(curl, url, inlength, outlength); - Dout(dc::curl, "curl_easy_unescape(" << (AICURL*)curl << ", \"" << url << "\", " << inlength << ", " << ((ret && outlength) ? *outlength : 1) << ") = \"" << ret << '"'); + if (!print_debug(curl)) return ret; + Dout(dc::curltr, "curl_easy_unescape(" << (AICURL*)curl << ", \"" << url << "\", " << inlength << ", " << ((ret && outlength) ? *outlength : 1) << ") = \"" << ret << '"'); return ret; } void debug_curl_free(char* ptr) { curl_free(ptr); - Dout(dc::curl, "curl_free(0x" << std::hex << (size_t)ptr << std::dec << ")"); + if (gDebugCurlTerse) return; + Dout(dc::curltr, "curl_free(0x" << std::hex << (size_t)ptr << std::dec << ")"); } time_t debug_curl_getdate(char const* datestring, time_t* now) { time_t ret; ret = curl_getdate(datestring, now); - Dout(dc::curl, "curl_getdate(\"" << datestring << "\", " << (now == NULL ? "NULL" : "") << ") = " << ret); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_getdate(\"" << datestring << "\", " << (now == NULL ? "NULL" : "") << ") = " << ret); return ret; } void debug_curl_global_cleanup(void) { curl_global_cleanup(); - Dout(dc::curl, "curl_global_cleanup()"); + Dout(dc::curltr, "curl_global_cleanup()"); } CURLcode debug_curl_global_init(long flags) { CURLcode ret; ret = curl_global_init(flags); - Dout(dc::curl, "curl_global_init(0x" << std::hex << flags << std::dec << ") = " << ret); + Dout(dc::curltr, "curl_global_init(0x" << std::hex << flags << std::dec << ") = " << ret); return ret; } @@ -795,7 +863,8 @@ CURLMcode debug_curl_multi_add_handle(CURLM* multi_handle, CURL* easy_handle) { CURLMcode ret; ret = curl_multi_add_handle(multi_handle, easy_handle); - Dout(dc::curl, "curl_multi_add_handle(" << (AICURLM*)multi_handle << ", " << (AICURL*)easy_handle << ") = " << ret); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_multi_add_handle(" << (AICURLM*)multi_handle << ", " << (AICURL*)easy_handle << ") = " << ret); return ret; } @@ -803,7 +872,8 @@ CURLMcode debug_curl_multi_assign(CURLM* multi_handle, curl_socket_t sockfd, voi { CURLMcode ret; ret = curl_multi_assign(multi_handle, sockfd, sockptr); - Dout(dc::curl, "curl_multi_assign(" << (AICURLM*)multi_handle << ", " << Socket(sockfd) << ", " << sockptr << ") = " << ret); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_multi_assign(" << (AICURLM*)multi_handle << ", " << Socket(sockfd) << ", " << sockptr << ") = " << ret); return ret; } @@ -811,7 +881,8 @@ CURLMcode debug_curl_multi_cleanup(CURLM* multi_handle) { CURLMcode ret; ret = curl_multi_cleanup(multi_handle); - Dout(dc::curl, "curl_multi_cleanup(" << (AICURLM*)multi_handle << ") = " << ret); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_multi_cleanup(" << (AICURLM*)multi_handle << ") = " << ret); return ret; } @@ -819,7 +890,8 @@ CURLMsg* debug_curl_multi_info_read(CURLM* multi_handle, int* msgs_in_queue) { CURLMsg* ret; ret = curl_multi_info_read(multi_handle, msgs_in_queue); - Dout(dc::curl, "curl_multi_info_read(" << (AICURLM*)multi_handle << ", {" << *msgs_in_queue << "}) = " << ret); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_multi_info_read(" << (AICURLM*)multi_handle << ", {" << *msgs_in_queue << "}) = " << ret); return ret; } @@ -827,7 +899,8 @@ CURLM* debug_curl_multi_init(void) { CURLM* ret; ret = curl_multi_init(); - Dout(dc::curl, "curl_multi_init() = " << (AICURLM*)ret); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_multi_init() = " << (AICURLM*)ret); return ret; } @@ -835,13 +908,14 @@ CURLMcode debug_curl_multi_remove_handle(CURLM* multi_handle, CURL* easy_handle) { CURLMcode ret; ret = curl_multi_remove_handle(multi_handle, easy_handle); - Dout(dc::curl, "curl_multi_remove_handle(" << (AICURLM*)multi_handle << ", " << (AICURL*)easy_handle << ") = " << ret); + if (!print_debug(easy_handle)) return ret; + Dout(dc::curltr, "curl_multi_remove_handle(" << (AICURLM*)multi_handle << ", " << (AICURL*)easy_handle << ") = " << ret); return ret; } CURLMcode debug_curl_multi_setopt(CURLM* multi_handle, CURLMoption option, ...) { - CURLMcode ret; + CURLMcode ret = CURLM_UNKNOWN_OPTION; // Suppress compiler warning. va_list ap; union param_type { long along; @@ -871,19 +945,23 @@ CURLMcode debug_curl_multi_setopt(CURLM* multi_handle, CURLMoption option, ...) { case CURLOPTTYPE_LONG: ret = curl_multi_setopt(multi_handle, option, param.along); - Dout(dc::curl, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", " << param.along << "L) = " << ret); + if (gDebugCurlTerse) break; + Dout(dc::curltr, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", " << param.along << "L) = " << ret); break; case CURLOPTTYPE_OBJECTPOINT: ret = curl_multi_setopt(multi_handle, option, param.ptr); - Dout(dc::curl, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", (object*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret); + if (gDebugCurlTerse) break; + Dout(dc::curltr, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", (object*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret); break; case CURLOPTTYPE_FUNCTIONPOINT: ret = curl_multi_setopt(multi_handle, option, param.ptr); - Dout(dc::curl, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", (function*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret); + if (gDebugCurlTerse) break; + Dout(dc::curltr, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", (function*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret); break; case CURLOPTTYPE_OFF_T: ret = curl_multi_setopt(multi_handle, option, param.offset); - Dout(dc::curl, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", (curl_off_t)" << param.offset << ") = " << ret); + if (gDebugCurlTerse) break; + Dout(dc::curltr, "curl_easy_setopt(" << (AICURLM*)multi_handle << ", " << option << ", (curl_off_t)" << param.offset << ") = " << ret); break; default: // Stop compiler complaining about no default. break; @@ -895,7 +973,8 @@ CURLMcode debug_curl_multi_socket_action(CURLM* multi_handle, curl_socket_t sock { CURLMcode ret; ret = curl_multi_socket_action(multi_handle, sockfd, ev_bitmask, running_handles); - Dout(dc::curl, "curl_multi_socket_action(" << (AICURLM*)multi_handle << ", " << Socket(sockfd) << + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_multi_socket_action(" << (AICURLM*)multi_handle << ", " << Socket(sockfd) << ", " << EvBitmask(ev_bitmask) << ", {" << (ret == CURLM_OK ? *running_handles : 0) << "}) = " << ret); return ret; } @@ -904,7 +983,8 @@ char const* debug_curl_multi_strerror(CURLMcode errornum) { char const* ret; ret = curl_multi_strerror(errornum); - Dout(dc::curl, "curl_multi_strerror(" << errornum << ") = \"" << ret << '"'); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_multi_strerror(" << errornum << ") = \"" << ret << '"'); return ret; } @@ -912,21 +992,24 @@ struct curl_slist* debug_curl_slist_append(struct curl_slist* list, char const* { struct curl_slist* ret; ret = curl_slist_append(list, string); - Dout(dc::curl, "curl_slist_append((curl_slist)@0x" << std::hex << (size_t)list << std::dec << ", \"" << string << "\") = " << *ret); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_slist_append((curl_slist)@0x" << std::hex << (size_t)list << std::dec << ", \"" << string << "\") = " << *ret); return ret; } void debug_curl_slist_free_all(struct curl_slist* list) { curl_slist_free_all(list); - Dout(dc::curl, "curl_slist_free_all((curl_slist)@0x" << std::hex << (size_t)list << std::dec << ")"); + if (gDebugCurlTerse) return; + Dout(dc::curltr, "curl_slist_free_all((curl_slist)@0x" << std::hex << (size_t)list << std::dec << ")"); } char* debug_curl_unescape(char const* url, int length) { char* ret; ret = curl_unescape(url, length); - Dout(dc::curl, "curl_unescape(\"" << url << "\", " << length << ") = \"" << ret << '"'); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_unescape(\"" << url << "\", " << length << ") = \"" << ret << '"'); return ret; } @@ -934,7 +1017,8 @@ char* debug_curl_version(void) { char* ret; ret = curl_version(); - Dout(dc::curl, "curl_version() = \"" << ret << '"'); + if (gDebugCurlTerse) return ret; + Dout(dc::curltr, "curl_version() = \"" << ret << '"'); return ret; } diff --git a/indra/llmessage/debug_libcurl.h b/indra/llmessage/debug_libcurl.h index 27becb1c6..49105aa1d 100644 --- a/indra/llmessage/debug_libcurl.h +++ b/indra/llmessage/debug_libcurl.h @@ -86,4 +86,9 @@ extern char* debug_curl_version(void); #endif // !COMPILING_DEBUG_LIBCURL_CC +extern bool gDebugCurlTerse; // With this set, +void debug_curl_add_easy(CURL* handle); // only output debug output for easy handles added with this function. +void debug_curl_remove_easy(CURL* handle); +bool debug_curl_print_debug(CURL* handle); + #endif // DEBUG_LIBCURL diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index ae04a8105..36d691a5d 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -24,12 +24,12 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - #include "linden_common.h" #include "llavatarnamecache.h" #include "llcachename.h" // we wrap this system +#include "llcontrol.h" // For LLCachedControl #include "llframetimer.h" #include "llhttpclient.h" #include "llsd.h" @@ -93,6 +93,9 @@ namespace LLAvatarNameCache /// Time when unrefreshed cached names were checked last static F64 sLastExpireCheck; + /// Time-to-live for a temp cache entry. + const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0; + //----------------------------------------------------------------------- // Internal methods //----------------------------------------------------------------------- @@ -185,8 +188,6 @@ private: virtual bool needsHeaders(void) const { return true; } public: - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return avatarNameResponder_timeout; } - LLAvatarNameResponder(const std::vector& agent_ids) : mAgentIDs(agent_ids) { } @@ -268,6 +269,9 @@ public: LLAvatarNameCache::handleAgentError(agent_id); } } + + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return avatarNameResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLAvatarNameResponder"; } }; // Provide some fallback for agents that return errors @@ -291,13 +295,14 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) // Clear this agent from the pending list LLAvatarNameCache::sPendingQueue.erase(agent_id); - const LLAvatarName& av_name = existing->second; + LLAvatarName& av_name = existing->second; LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << "user '" << av_name.mUsername << "' " << "display '" << av_name.mDisplayName << "' " << "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds" << LL_ENDL; + av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest. } } @@ -342,19 +347,23 @@ void LLAvatarNameCache::requestNamesViaCapability() // http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0 // // Apache can handle URLs of 4096 chars, but let's be conservative - const U32 NAME_URL_MAX = 4096; - const U32 NAME_URL_SEND_THRESHOLD = 3000; + static const U32 NAME_URL_MAX = 4096; + static const U32 NAME_URL_SEND_THRESHOLD = 3500; + std::string url; url.reserve(NAME_URL_MAX); std::vector agent_ids; agent_ids.reserve(128); + U32 id_total = sAskQueue.size(); U32 ids = 0; - ask_queue_t::const_iterator it = sAskQueue.begin(); - for ( ; it != sAskQueue.end(); ++it) + ask_queue_t::const_iterator it; + while(!sAskQueue.empty()) { + it = sAskQueue.begin(); const LLUUID& agent_id = *it; + sAskQueue.erase(it); if (url.empty()) { @@ -377,27 +386,17 @@ void LLAvatarNameCache::requestNamesViaCapability() if (url.size() > NAME_URL_SEND_THRESHOLD) { - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability first " - << ids << " ids" - << LL_ENDL; - LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids)); - url.clear(); - agent_ids.clear(); + break; } } if (!url.empty()) { - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability all " - << ids << " ids" + LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested " + << ids << "/" << id_total << "ids " << LL_ENDL; LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids)); - url.clear(); - agent_ids.clear(); } - - // We've moved all asks to the pending request queue - sAskQueue.clear(); } void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id, @@ -414,20 +413,25 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id, << LL_ENDL; buildLegacyName(full_name, &av_name); - // Don't add to cache, the data already exists in the legacy name system - // cache and we don't want or need duplicate storage, because keeping the - // two copies in sync is complex. - processName(agent_id, av_name, false); + // Add to cache, because if we don't we'll keep rerequesting the + // same record forever. buildLegacyName should always guarantee + // that these records expire reasonably soon + // (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due + // to something temporary we will eventually request and get the right data. + processName(agent_id, av_name, true); } void LLAvatarNameCache::requestNamesViaLegacy() { + static const S32 MAX_REQUESTS = 100; F64 now = LLFrameTimer::getTotalSeconds(); std::string full_name; - ask_queue_t::const_iterator it = sAskQueue.begin(); - for (; it != sAskQueue.end(); ++it) + ask_queue_t::const_iterator it; + for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests) { + it = sAskQueue.begin(); const LLUUID& agent_id = *it; + sAskQueue.erase(it); // Mark as pending first, just in case the callback is immediately // invoked below. This should never happen in practice. @@ -439,10 +443,6 @@ void LLAvatarNameCache::requestNamesViaLegacy() boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3)); } - - // We've either answered immediately or moved all asks to the - // pending queue - sAskQueue.clear(); } void LLAvatarNameCache::initClass(bool running) @@ -519,11 +519,11 @@ void LLAvatarNameCache::idle() // *TODO: Possibly re-enabled this based on People API load measurements // 100 ms is the threshold for "user speed" operations, so we can // stall for about that long to batch up requests. - //const F32 SECS_BETWEEN_REQUESTS = 0.1f; - //if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS)) - //{ - // return; - //} + const F32 SECS_BETWEEN_REQUESTS = 0.1f; + if (!sRequestTimer.hasExpired()) + { + return; + } if (!sAskQueue.empty()) { @@ -538,6 +538,12 @@ void LLAvatarNameCache::idle() } } + if (sAskQueue.empty()) + { + // cleared the list, reset the request timer. + sRequestTimer.reset(SECS_BETWEEN_REQUESTS); + } + // erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME eraseUnrefreshed(); } @@ -595,7 +601,7 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name, av_name->mDisplayName = full_name; av_name->mIsDisplayNameDefault = true; av_name->mIsTemporaryName = true; - av_name->mExpires = F64_MAX; // not used because these are not cached + av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName " << full_name << LL_ENDL; @@ -619,7 +625,6 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) // ...only do immediate lookups when cache is running if (useDisplayNames()) { - // ...use display names cache std::map::iterator it = sCache.find(agent_id); if (it != sCache.end()) @@ -664,6 +669,29 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) return false; } +// Return true when name has been set to Phoenix Name System Name, if not return false. +bool LLAvatarNameCache::getPNSName(const LLUUID& agent_id, std::string& name) +{ + LLAvatarName avatar_name; + if (get(agent_id, &avatar_name)) + getPNSName(avatar_name, name); + else return false; + return true; +} + +// get() with callback compatible version of getPNSName +void LLAvatarNameCache::getPNSName(const LLAvatarName& avatar_name, std::string& name) +{ + static LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); + switch (phoenix_name_system) + { + case 0 : name = avatar_name.getLegacyName(); break; + case 1 : name = avatar_name.getCompleteName(); break; + case 2 : name = avatar_name.mDisplayName; break; + default : name = avatar_name.getLegacyName(); break; + } +} + void LLAvatarNameCache::fireSignal(const LLUUID& agent_id, const callback_slot_t& slot, const LLAvatarName& av_name) @@ -673,8 +701,10 @@ void LLAvatarNameCache::fireSignal(const LLUUID& agent_id, signal(agent_id, av_name); } -void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) +LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) { + callback_connection_t connection; + if (sRunning) { // ...only do immediate lookups when cache is running @@ -690,7 +720,7 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) { // ...name already exists in cache, fire callback now fireSignal(agent_id, slot, av_name); - return; + return connection; } } } @@ -703,7 +733,7 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) LLAvatarName av_name; buildLegacyName(full_name, &av_name); fireSignal(agent_id, slot, av_name); - return; + return connection; } } } @@ -720,15 +750,17 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) { // ...new callback for this id callback_signal_t* signal = new callback_signal_t(); - signal->connect(slot); + connection = signal->connect(slot); sSignalMap[agent_id] = signal; } else { // ...existing callback, bind additional slot callback_signal_t* signal = sig_it->second; - signal->connect(slot); + connection = signal->connect(slot); } + + return connection; } // [RLVa:KB] - Checked: 2010-12-08 (RLVa-1.4.0a) | Added: RLVa-1.2.2c @@ -774,12 +806,6 @@ void LLAvatarNameCache::erase(const LLUUID& agent_id) sCache.erase(agent_id); } -void LLAvatarNameCache::fetch(const LLUUID& agent_id) -{ - // re-request, even if request is already pending - sAskQueue.insert(agent_id); -} - void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name) { // *TODO: update timestamp if zero? @@ -788,26 +814,35 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na F64 LLAvatarNameCache::nameExpirationFromHeaders(AIHTTPReceivedHeaders const& headers) { - F64 expires; - expirationFromCacheControl(headers, &expires); - return expires; + F64 expires = 0.0; + if (expirationFromCacheControl(headers, &expires)) + { + return expires; + } + else + { + // With no expiration info, default to an hour + const F64 DEFAULT_EXPIRES = 60.0 * 60.0; + F64 now = LLFrameTimer::getTotalSeconds(); + return now + DEFAULT_EXPIRES; + } } bool LLAvatarNameCache::expirationFromCacheControl(AIHTTPReceivedHeaders const& headers, F64* expires) { bool fromCacheControl = false; - S32 max_age = 3600; // With no expiration info, default to an hour. F64 now = LLFrameTimer::getTotalSeconds(); // Allow the header to override the default std::string cache_control; if (headers.getFirstValue("cache-control", cache_control)) { + S32 max_age = 0; if (max_age_from_cache_control(cache_control, &max_age)) { + *expires = now + (F64)max_age; fromCacheControl = true; } } - *expires = now + (F64)max_age; LL_DEBUGS("AvNameCache") << ( fromCacheControl ? "expires based on cache control " : "default expiration " ) << "in " << *expires - now << " seconds" diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 75f613e74..99e3fba57 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -65,16 +65,23 @@ namespace LLAvatarNameCache // If name is in cache, returns true and fills in provided LLAvatarName // otherwise returns false bool get(const LLUUID& agent_id, LLAvatarName *av_name); + // If get() succeeds, returns true and fills in name string + // via void function below, otherwise returns false + bool getPNSName(const LLUUID& agent_id, std::string& name); + // Perform a filling of name string according to Phoenix Name System, + // when we have an LLAvatarName already. + void getPNSName(const LLAvatarName& avatar_name, std::string& name); // Callback types for get() below typedef boost::signals2::signal< void (const LLUUID& agent_id, const LLAvatarName& av_name)> callback_signal_t; typedef callback_signal_t::slot_type callback_slot_t; + typedef boost::signals2::connection callback_connection_t; // Fetches name information and calls callback. // If name information is in cache, callback will be called immediately. - void get(const LLUUID& agent_id, callback_slot_t slot); + callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot); // Allow display names to be explicitly disabled for testing. void setUseDisplayNames(bool use); @@ -90,10 +97,6 @@ namespace LLAvatarNameCache /// Provide some fallback for agents that return errors void handleAgentError(const LLUUID& agent_id); - // Force a re-fetch of the most recent data, but keep the current - // data in cache - void fetch(const LLUUID& agent_id); - void insert(const LLUUID& agent_id, const LLAvatarName& av_name); // Compute name expiration time from HTTP Cache-Control header, diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index b7871556e..4acac78f3 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -200,7 +200,9 @@ static void request( LLURLRequest::ERequestAction method, Injector* body_injector, LLHTTPClient::ResponderPtr responder, - AIHTTPHeaders& headers, + AIHTTPHeaders& headers/*,*/ + DEBUG_CURLIO_PARAM(EDebugCurl debug), + EKeepAlive keepalive = keep_alive, bool is_auth = false, bool no_compression = false) { @@ -213,7 +215,10 @@ static void request( LLURLRequest* req; try { - req = new LLURLRequest(method, url, body_injector, responder, headers, is_auth, no_compression); + req = new LLURLRequest(method, url, body_injector, responder, headers, keepalive, is_auth, no_compression); +#ifdef DEBUG_CURLIO + req->mCurlEasyRequest.debug(debug); +#endif } catch(AICurlNoEasyHandle& error) { @@ -225,36 +230,36 @@ static void request( req->run(); } -void LLHTTPClient::getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { if(offset > 0 || bytes > 0) { headers.addHeader("Range", llformat("bytes=%d-%d", offset, offset + bytes - 1)); } - request(url, LLURLRequest::HTTP_GET, NULL, responder, headers); + request(url, LLURLRequest::HTTP_GET, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } -void LLHTTPClient::head(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers) +void LLHTTPClient::head(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - request(url, LLURLRequest::HTTP_HEAD, NULL, responder, headers); + request(url, LLURLRequest::HTTP_HEAD, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } -void LLHTTPClient::get(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::get(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - request(url, LLURLRequest::HTTP_GET, NULL, responder, headers); + request(url, LLURLRequest::HTTP_GET, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } -void LLHTTPClient::getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers) +void LLHTTPClient::getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - request(url, LLURLRequest::HTTP_HEAD, NULL, responder, headers); + request(url, LLURLRequest::HTTP_HEAD, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } -void LLHTTPClient::get(std::string const& url, LLSD const& query, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::get(std::string const& url, LLSD const& query, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { LLURI uri; uri = LLURI::buildHTTP(url, LLSD::emptyArray(), query); - get(uri.asString(), responder, headers); + get(uri.asString(), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } //============================================================================= @@ -362,6 +367,24 @@ void LLHTTPClient::ResponderBase::decode_raw_body(U32 status, std::string const& } } +std::string const& LLHTTPClient::ResponderBase::get_cookie(std::string const& key) +{ + AIHTTPReceivedHeaders::range_type cookies; + if (mReceivedHeaders.getValues("set-cookie", cookies)) + { + for (AIHTTPReceivedHeaders::iterator_type cookie = cookies.first; cookie != cookies.second; ++cookie) + { + if (key == cookie->second.substr(0, cookie->second.find('='))) + { + return cookie->second; + } + } + } + // Not found. + static std::string empty_dummy; + return empty_dummy; +} + // Called with HTML body. // virtual void LLHTTPClient::ResponderWithCompleted::completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) @@ -512,16 +535,19 @@ protected: class BlockingLLSDPostResponder : public BlockingLLSDResponder { public: /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return blockingLLSDPost_timeout; } + /*virtual*/ char const* getName(void) const { return "BlockingLLSDPostResponder"; } }; class BlockingLLSDGetResponder : public BlockingLLSDResponder { public: /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return blockingLLSDGet_timeout; } + /*virtual*/ char const* getName(void) const { return "BlockingLLSDGetResponder"; } }; class BlockingRawGetResponder : public BlockingRawResponder { public: /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return blockingRawGet_timeout; } + /*virtual*/ char const* getName(void) const { return "BlockingRawGetResponder"; } }; // End (blocking) responders. @@ -554,7 +580,8 @@ enum EBlockingRequestAction { static LLSD blocking_request( std::string const& url, EBlockingRequestAction method, - LLSD const& body) // Only used for HTTP_LLSD_POST + LLSD const& body/*,*/ // Only used for HTTP_LLSD_POST + DEBUG_CURLIO_PARAM(EDebugCurl debug)) { lldebugs << "blockingRequest of " << url << llendl; @@ -563,17 +590,17 @@ static LLSD blocking_request( if (method == HTTP_LLSD_POST) { responder = new BlockingLLSDPostResponder; - LLHTTPClient::post(url, body, responder, headers); + LLHTTPClient::post(url, body, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } else if (method == HTTP_LLSD_GET) { responder = new BlockingLLSDGetResponder; - LLHTTPClient::get(url, responder, headers); + LLHTTPClient::get(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } else // method == HTTP_RAW_GET { responder = new BlockingRawGetResponder; - LLHTTPClient::get(url, responder, headers); + LLHTTPClient::get(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } responder->wait(); @@ -635,39 +662,39 @@ static LLSD blocking_request( return response; } -LLSD LLHTTPClient::blockingPost(const std::string& url, const LLSD& body) +LLSD LLHTTPClient::blockingPost(const std::string& url, const LLSD& body/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - return blocking_request(url, HTTP_LLSD_POST, body); + return blocking_request(url, HTTP_LLSD_POST, body/*,*/ DEBUG_CURLIO_PARAM(debug)); } -LLSD LLHTTPClient::blockingGet(const std::string& url) +LLSD LLHTTPClient::blockingGet(const std::string& url/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - return blocking_request(url, HTTP_LLSD_GET, LLSD()); + return blocking_request(url, HTTP_LLSD_GET, LLSD()/*,*/ DEBUG_CURLIO_PARAM(debug)); } -U32 LLHTTPClient::blockingGetRaw(const std::string& url, std::string& body) +U32 LLHTTPClient::blockingGetRaw(const std::string& url, std::string& body/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - LLSD result = blocking_request(url, HTTP_RAW_GET, LLSD()); + LLSD result = blocking_request(url, HTTP_RAW_GET, LLSD()/*,*/ DEBUG_CURLIO_PARAM(debug)); body = result["body"].asString(); return result["status"].asInteger(); } -void LLHTTPClient::put(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::put(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - request(url, LLURLRequest::HTTP_PUT, new LLSDInjector(body), responder, headers); + request(url, LLURLRequest::HTTP_PUT, new LLSDInjector(body), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } -void LLHTTPClient::post(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::post(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) { - request(url, LLURLRequest::HTTP_POST, new LLSDInjector(body), responder, headers); + request(url, LLURLRequest::HTTP_POST, new LLSDInjector(body), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } -void LLHTTPClient::postXMLRPC(std::string const& url, XMLRPC_REQUEST xmlrpc_request, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::postXMLRPC(std::string const& url, XMLRPC_REQUEST xmlrpc_request, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) { - request(url, LLURLRequest::HTTP_POST, new XMLRPCInjector(xmlrpc_request), responder, headers, true, false); // Does use compression. + request(url, LLURLRequest::HTTP_POST, new XMLRPCInjector(xmlrpc_request), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, true, false); // Does use compression. } -void LLHTTPClient::postXMLRPC(std::string const& url, char const* method, XMLRPC_VALUE value, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::postXMLRPC(std::string const& url, char const* method, XMLRPC_VALUE value, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) { XMLRPC_REQUEST xmlrpc_request = XMLRPC_RequestNew(); XMLRPC_RequestSetMethodName(xmlrpc_request, method); @@ -675,33 +702,33 @@ void LLHTTPClient::postXMLRPC(std::string const& url, char const* method, XMLRPC XMLRPC_RequestSetData(xmlrpc_request, value); // XMLRPCInjector takes ownership of xmlrpc_request and will free it when done. // LLURLRequest takes ownership of the XMLRPCInjector object and will free it when done. - request(url, LLURLRequest::HTTP_POST, new XMLRPCInjector(xmlrpc_request), responder, headers, true, true); // Does not use compression. + request(url, LLURLRequest::HTTP_POST, new XMLRPCInjector(xmlrpc_request), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, true, true); // Does not use compression. } -void LLHTTPClient::postRaw(std::string const& url, char const* data, S32 size, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::postRaw(std::string const& url, char const* data, S32 size, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) { - request(url, LLURLRequest::HTTP_POST, new RawInjector(data, size), responder, headers); + request(url, LLURLRequest::HTTP_POST, new RawInjector(data, size), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } -void LLHTTPClient::postFile(std::string const& url, std::string const& filename, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::postFile(std::string const& url, std::string const& filename, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) { - request(url, LLURLRequest::HTTP_POST, new FileInjector(filename), responder, headers); + request(url, LLURLRequest::HTTP_POST, new FileInjector(filename), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } -void LLHTTPClient::postFile(std::string const& url, LLUUID const& uuid, LLAssetType::EType asset_type, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::postFile(std::string const& url, LLUUID const& uuid, LLAssetType::EType asset_type, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) { - request(url, LLURLRequest::HTTP_POST, new VFileInjector(uuid, asset_type), responder, headers); + request(url, LLURLRequest::HTTP_POST, new VFileInjector(uuid, asset_type), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } // static -void LLHTTPClient::del(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::del(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - request(url, LLURLRequest::HTTP_DELETE, NULL, responder, headers); + request(url, LLURLRequest::HTTP_DELETE, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } // static -void LLHTTPClient::move(std::string const& url, std::string const& destination, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::move(std::string const& url, std::string const& destination, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { headers.addHeader("Destination", destination); - request(url, LLURLRequest::HTTP_MOVE, NULL, responder, headers); + request(url, LLURLRequest::HTTP_MOVE, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index 3e491de82..055802a60 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -66,6 +66,21 @@ struct AIBufferedCurlEasyRequestEvents { virtual void completed_headers(U32 status, std::string const& reason, AITransferInfo* info) = 0; // Transaction completed. }; +enum EKeepAlive { + no_keep_alive = 0, + keep_alive +}; + +#ifdef DEBUG_CURLIO +enum EDebugCurl { + debug_off = 0, + debug_on +}; +#define DEBUG_CURLIO_PARAM(p) ,p +#else +#define DEBUG_CURLIO_PARAM(p) +#endif + class LLHTTPClient { public: @@ -140,7 +155,18 @@ public: { // It's possible that this page was moved (302), so we already saw headers // from the 302 page and are starting over on the new page now. - mReceivedHeaders.clear(); + // Erase all headers EXCEPT the cookies. + AIHTTPReceivedHeaders set_cookie_headers; + AIHTTPReceivedHeaders::range_type cookies; + if (mReceivedHeaders.getValues("set-cookie", cookies)) + { + for (AIHTTPReceivedHeaders::iterator_type cookie = cookies.first; cookie != cookies.second; ++cookie) + { + set_cookie_headers.addHeader(cookie->first, cookie->second); + } + } + // Replace headers with just the cookie headers. + mReceivedHeaders.swap(set_cookie_headers); } // Called for all remaining headers. @@ -155,17 +181,26 @@ public: completedHeaders(status, reason, mReceivedHeaders); } + // Extract cookie 'key' from mReceivedHeaders and return the string 'key=value', or an empty string if key does not exists. + std::string const& get_cookie(std::string const& key); + public: // Derived classes that implement completed_headers()/completedHeaders() should return true here. virtual bool needsHeaders(void) const { return false; } // A derived class should return true if curl should follow redirections. // The default is not to follow redirections. - virtual bool followRedir(void) { return false; } + virtual bool followRedir(void) const { return false; } + + // If this function returns false then we generate an error when a redirect status (300..399) is received. + virtual bool redirect_status_ok(void) const { return followRedir(); } // Timeout policy to use. virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const = 0; + // The name of the derived responder object. For debugging purposes. + virtual char const* getName(void) const = 0; + protected: // Derived classes can override this to get the HTML headers that were received, when the message is completed. // Only actually called for classes that implement a needsHeaders() that returns true. @@ -188,6 +223,7 @@ public: class ResponderHeadersOnly : public ResponderBase { private: /*virtual*/ bool needsHeaders(void) const { return true; } + /*virtual*/ bool followRedir(void) const { return true; } protected: // ResponderBase event @@ -347,6 +383,7 @@ public: */ class ResponderIgnore : public ResponderIgnoreBody { /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return responderIgnore_timeout;} + /*virtual*/ char const* getName(void) const { return "ResponderIgnore"; } }; // A Responder is passed around as ResponderPtr, which causes it to automatically @@ -357,59 +394,59 @@ public: /** @name non-blocking API */ //@{ - static void head(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers); - static void head(std::string const& url, ResponderHeadersOnly* responder) - { AIHTTPHeaders headers; head(url, responder, headers); } + static void head(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); + static void head(std::string const& url, ResponderHeadersOnly* responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) + { AIHTTPHeaders headers; head(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } - static void getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder, AIHTTPHeaders& headers); - static void getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder) - { AIHTTPHeaders headers; getByteRange(url, offset, bytes, responder, headers); } + static void getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); + static void getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) + { AIHTTPHeaders headers; getByteRange(url, offset, bytes, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } - static void get(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers); - static void get(std::string const& url, ResponderPtr responder) - { AIHTTPHeaders headers; get(url, responder, headers); } + static void get(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); + static void get(std::string const& url, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) + { AIHTTPHeaders headers; get(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } - static void get(std::string const& url, LLSD const& query, ResponderPtr responder, AIHTTPHeaders& headers); - static void get(std::string const& url, LLSD const& query, ResponderPtr responder) - { AIHTTPHeaders headers; get(url, query, responder, headers); } + static void get(std::string const& url, LLSD const& query, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); + static void get(std::string const& url, LLSD const& query, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) + { AIHTTPHeaders headers; get(url, query, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } - static void put(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers); - static void put(std::string const& url, LLSD const& body, ResponderPtr responder) - { AIHTTPHeaders headers; put(url, body, responder, headers); } + static void put(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); + static void put(std::string const& url, LLSD const& body, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) + { AIHTTPHeaders headers; put(url, body, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } - static void getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers); - static void getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder) - { AIHTTPHeaders headers; getHeaderOnly(url, responder, headers); } + static void getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); + static void getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) + { AIHTTPHeaders headers; getHeaderOnly(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } - static void post(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers); - static void post(std::string const& url, LLSD const& body, ResponderPtr responder) - { AIHTTPHeaders headers; post(url, body, responder, headers); } + static void post(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive); + static void post(std::string const& url, LLSD const& body, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive) + { AIHTTPHeaders headers; post(url, body, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } /** Takes ownership of request and deletes it when sent */ - static void postXMLRPC(std::string const& url, XMLRPC_REQUEST request, ResponderPtr responder, AIHTTPHeaders& headers); - static void postXMLRPC(std::string const& url, XMLRPC_REQUEST request, ResponderPtr responder) - { AIHTTPHeaders headers; postXMLRPC(url, request, responder, headers); } + static void postXMLRPC(std::string const& url, XMLRPC_REQUEST request, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive); + static void postXMLRPC(std::string const& url, XMLRPC_REQUEST request, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive) + { AIHTTPHeaders headers; postXMLRPC(url, request, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } - static void postXMLRPC(std::string const& url, char const* method, XMLRPC_VALUE value, ResponderPtr responder, AIHTTPHeaders& headers); - static void postXMLRPC(std::string const& url, char const* method, XMLRPC_VALUE value, ResponderPtr responder) - { AIHTTPHeaders headers; postXMLRPC(url, method, value, responder, headers); } + static void postXMLRPC(std::string const& url, char const* method, XMLRPC_VALUE value, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive); + static void postXMLRPC(std::string const& url, char const* method, XMLRPC_VALUE value, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive) + { AIHTTPHeaders headers; postXMLRPC(url, method, value, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } /** Takes ownership of data and deletes it when sent */ - static void postRaw(std::string const& url, const char* data, S32 size, ResponderPtr responder, AIHTTPHeaders& headers); - static void postRaw(std::string const& url, const char* data, S32 size, ResponderPtr responder) - { AIHTTPHeaders headers; postRaw(url, data, size, responder, headers); } + static void postRaw(std::string const& url, const char* data, S32 size, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive); + static void postRaw(std::string const& url, const char* data, S32 size, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive) + { AIHTTPHeaders headers; postRaw(url, data, size, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } - static void postFile(std::string const& url, std::string const& filename, ResponderPtr responder, AIHTTPHeaders& headers); - static void postFile(std::string const& url, std::string const& filename, ResponderPtr responder) - { AIHTTPHeaders headers; postFile(url, filename, responder, headers); } + static void postFile(std::string const& url, std::string const& filename, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive); + static void postFile(std::string const& url, std::string const& filename, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive) + { AIHTTPHeaders headers; postFile(url, filename, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } - static void postFile(std::string const& url, const LLUUID& uuid, LLAssetType::EType asset_type, ResponderPtr responder, AIHTTPHeaders& headers); - static void postFile(std::string const& url, const LLUUID& uuid, LLAssetType::EType asset_type, ResponderPtr responder) - { AIHTTPHeaders headers; postFile(url, uuid, asset_type, responder, headers); } + static void postFile(std::string const& url, const LLUUID& uuid, LLAssetType::EType asset_type, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive); + static void postFile(std::string const& url, const LLUUID& uuid, LLAssetType::EType asset_type, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive) + { AIHTTPHeaders headers; postFile(url, uuid, asset_type, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } - static void del(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers); - static void del(std::string const& url, ResponderPtr responder) - { AIHTTPHeaders headers; del(url, responder, headers); } + static void del(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); + static void del(std::string const& url, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) + { AIHTTPHeaders headers; del(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } ///< sends a DELETE method, but we can't call it delete in c++ @@ -422,9 +459,9 @@ public: * @param headers A map of key:value headers to pass to the request * @param timeout The number of seconds to give the server to respond. */ - static void move(std::string const& url, std::string const& destination, ResponderPtr responder, AIHTTPHeaders& headers); - static void move(std::string const& url, std::string const& destination, ResponderPtr responder) - { AIHTTPHeaders headers; move(url, destination, responder, headers); } + static void move(std::string const& url, std::string const& destination, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); + static void move(std::string const& url, std::string const& destination, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) + { AIHTTPHeaders headers; move(url, destination, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } //@} @@ -434,7 +471,7 @@ public: * @param url the complete serialized (and escaped) url to get * @return An LLSD of { 'status':status, 'body':payload } */ - static LLSD blockingGet(std::string const& url); + static LLSD blockingGet(std::string const& url/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); /** * @brief Blocking HTTP GET that returns the raw body. @@ -443,7 +480,7 @@ public: * @param result the target string to write the body to * @return HTTP status */ - static U32 blockingGetRaw(const std::string& url, std::string& result); + static U32 blockingGetRaw(const std::string& url, std::string& result/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); /** * @brief Blocking HTTP POST that returns an LLSD map of status and body. @@ -452,7 +489,7 @@ public: * @param body the LLSD post body * @return An LLSD of { 'status':status (an int), 'body':payload (an LLSD) } */ - static LLSD blockingPost(std::string const& url, LLSD const& body); + static LLSD blockingPost(std::string const& url, LLSD const& body/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); }; #endif // LL_LLHTTPCLIENT_H diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h index 7b796a0fa..1cf940918 100644 --- a/indra/llmessage/llregionflags.h +++ b/indra/llmessage/llregionflags.h @@ -28,95 +28,98 @@ #define LL_LLREGIONFLAGS_H // Can you be hurt here? Should health be on? -const U32 REGION_FLAGS_ALLOW_DAMAGE = (1 << 0); +const U64 REGION_FLAGS_ALLOW_DAMAGE = (1 << 0); // Can you make landmarks here? -const U32 REGION_FLAGS_ALLOW_LANDMARK = (1 << 1); +const U64 REGION_FLAGS_ALLOW_LANDMARK = (1 << 1); // Do we reset the home position when someone teleports away from here? -const U32 REGION_FLAGS_ALLOW_SET_HOME = (1 << 2); +const U64 REGION_FLAGS_ALLOW_SET_HOME = (1 << 2); // Do we reset the home position when someone teleports away from here? -const U32 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3); +const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3); // Does the sun move? -const U32 REGION_FLAGS_SUN_FIXED = (1 << 4); +const U64 REGION_FLAGS_SUN_FIXED = (1 << 4); // Can't change the terrain heightfield, even on owned parcels, // but can plant trees and grass. -const U32 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6); +const U64 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6); // Can't release, sell, or buy land. -const U32 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7); +const U64 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7); // All content wiped once per night -const U32 REGION_FLAGS_SANDBOX = (1 << 8); -const U32 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies -const U32 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13); -const U32 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics -const U32 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15); -const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16); -const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17); -const U32 REGION_FLAGS_BLOCK_DWELL = (1 << 18); +const U64 REGION_FLAGS_SANDBOX = (1 << 8); +const U64 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies +const U64 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13); +const U64 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics +const U64 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15); +const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16); +const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17); +const U64 REGION_FLAGS_BLOCK_DWELL = (1 << 18); // Is flight allowed? -const U32 REGION_FLAGS_BLOCK_FLY = (1 << 19); +const U64 REGION_FLAGS_BLOCK_FLY = (1 << 19); // Is direct teleport (p2p) allowed? -const U32 REGION_FLAGS_ALLOW_DIRECT_TELEPORT = (1 << 20); +const U64 REGION_FLAGS_ALLOW_DIRECT_TELEPORT = (1 << 20); // Is there an administrative override on scripts in the region at the // moment. This is the similar skip scripts, except this flag is // presisted in the database on an estate level. -const U32 REGION_FLAGS_ESTATE_SKIP_SCRIPTS = (1 << 21); +const U64 REGION_FLAGS_ESTATE_SKIP_SCRIPTS = (1 << 21); -const U32 REGION_FLAGS_RESTRICT_PUSHOBJECT = (1 << 22); +const U64 REGION_FLAGS_RESTRICT_PUSHOBJECT = (1 << 22); -const U32 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23); +const U64 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23); -const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26); +const U64 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26); -const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28); +const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28); -const U32 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29); -const U32 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30); +const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29); +const U64 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30); -const U32 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK | +const U64 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK | REGION_FLAGS_ALLOW_SET_HOME | REGION_FLAGS_ALLOW_PARCEL_CHANGES | REGION_FLAGS_ALLOW_VOICE; -const U32 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT; -const U32 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK +const U64 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT; +const U64 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK | REGION_FLAGS_ALLOW_SET_HOME; -const U32 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE +const U64 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE | REGION_FLAGS_SUN_FIXED | REGION_FLAGS_DENY_ANONYMOUS | REGION_FLAGS_DENY_AGEUNVERIFIED; -inline BOOL is_prelude( U32 flags ) +inline BOOL is_prelude( U64 flags ) { // definition of prelude does not depend on fixed-sun return 0 == (flags & REGION_FLAGS_PRELUDE_UNSET) && 0 != (flags & REGION_FLAGS_PRELUDE_SET); } -inline U32 set_prelude_flags(U32 flags) +inline U64 set_prelude_flags(U64 flags) { // also set the sun-fixed flag return ((flags & ~REGION_FLAGS_PRELUDE_UNSET) | (REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED)); } -inline U32 unset_prelude_flags(U32 flags) +inline U64 unset_prelude_flags(U64 flags) { // also unset the fixed-sun flag return ((flags | REGION_FLAGS_PRELUDE_UNSET) & ~(REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED)); } +// Region protocols +const U64 REGION_PROTOCOLS_AGENT_APPEARANCE_SERVICE = (1 << 0); + // estate constants. Need to match first few etries in indra.estate table. const U32 ESTATE_ALL = 0; // will not match in db, reserved key for logic const U32 ESTATE_MAINLAND = 1; diff --git a/indra/llmessage/llsdmessage.h b/indra/llmessage/llsdmessage.h index 72b7dc675..6e7530ddb 100644 --- a/indra/llmessage/llsdmessage.h +++ b/indra/llmessage/llsdmessage.h @@ -136,8 +136,6 @@ private: class EventResponder: public LLHTTPClient::ResponderWithResult { public: - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return *mHTTPTimeoutPolicy; } - /** * LLHTTPClient::ResponderWithResult that dispatches via named LLEventPump instances. * We bind LLEventPumps, even though it's an LLSingleton, for testability. @@ -158,9 +156,12 @@ private: void setTimeoutPolicy(std::string const& name); - virtual void result(const LLSD& data); - virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content); - + /*virtual*/ void result(const LLSD& data); + /*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content); + + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return *mHTTPTimeoutPolicy; } + /*virtual*/ char const* getName(void) const { return "EventResponder"; } + private: LLEventPumps& mPumps; LLReqID mReqID; diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 927b64b7a..429a93627 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -77,19 +77,14 @@ std::string LLURLRequest::actionAsVerb(LLURLRequest::ERequestAction action) // This might throw AICurlNoEasyHandle. LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, std::string const& url, Injector* body, - LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, bool is_auth, bool no_compression) : - mAction(action), mURL(url), mIsAuth(is_auth), mNoCompression(no_compression), + LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, bool keepalive, bool is_auth, bool no_compression) : + mAction(action), mURL(url), mKeepAlive(keepalive), mIsAuth(is_auth), mNoCompression(no_compression), mBody(body), mResponder(responder), mHeaders(headers) { } void LLURLRequest::initialize_impl(void) { - if (mHeaders.hasHeader("Cookie")) - { - allowCookies(); - } - // If the header is "Pragma" with no value, the caller intends to // force libcurl to drop the Pragma header it so gratuitously inserts. // Before inserting the header, force libcurl to not use the proxy. @@ -105,7 +100,7 @@ void LLURLRequest::initialize_impl(void) // but if they did not specify a Content-Type, then ask the injector. mHeaders.addHeader("Content-Type", mBody->contentType(), AIHTTPHeaders::keep_existing_header); } - else + else if (mAction != HTTP_HEAD) { // Check to see if we have already set Accept or not. If no one // set it, set it to application/llsd+xml since that's what we @@ -199,12 +194,6 @@ void LLURLRequest::useProxy(const std::string &proxy) } #endif -void LLURLRequest::allowCookies() -{ - AICurlEasyRequest_wat curlEasyRequest_w(*mCurlEasyRequest); - curlEasyRequest_w->setoptString(CURLOPT_COOKIEFILE, ""); -} - bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w) { bool rv = false; @@ -213,13 +202,11 @@ bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w) { case HTTP_HEAD: curlEasyRequest_w->setopt(CURLOPT_NOBODY, 1); - curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1); rv = true; break; case HTTP_GET: curlEasyRequest_w->setopt(CURLOPT_HTTPGET, 1); - curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1); // Set Accept-Encoding to allow response compression curlEasyRequest_w->setoptString(CURLOPT_ENCODING, mNoCompression ? "identity" : ""); @@ -239,7 +226,7 @@ bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w) case HTTP_POST: { // Set the handle for an http post - curlEasyRequest_w->setPost(mBodySize); + curlEasyRequest_w->setPost(mBodySize, mKeepAlive); // Set Accept-Encoding to allow response compression curlEasyRequest_w->setoptString(CURLOPT_ENCODING, mNoCompression ? "identity" : ""); diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h index 8f019310f..9cdb132bb 100644 --- a/indra/llmessage/llurlrequest.h +++ b/indra/llmessage/llurlrequest.h @@ -77,18 +77,13 @@ class LLURLRequest : public AICurlEasyRequestStateMachine { * @param action One of the ERequestAction enumerations. * @param url The url of the request. It should already be encoded. */ - LLURLRequest(ERequestAction action, std::string const& url, Injector* body, LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, bool is_auth, bool no_compression); + LLURLRequest(ERequestAction action, std::string const& url, Injector* body, LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, bool keepalive, bool is_auth, bool no_compression); protected: // Call abort(), not delete. /*virtual*/ ~LLURLRequest() { } public: - /** - * @brief Turn on cookie handling for this request with CURLOPT_COOKIEFILE. - */ - void allowCookies(void); - /** * @ brief Turn off (or on) the CURLOPT_PROXY header. */ @@ -116,6 +111,7 @@ class LLURLRequest : public AICurlEasyRequestStateMachine { private: ERequestAction mAction; std::string mURL; + bool mKeepAlive; // Set to false only when explicitely requested. bool mIsAuth; // Set for authentication messages (login, buy land, buy currency). bool mNoCompression; // Set to disable using gzip. Injector* mBody; // Non-zero iff the action is HTTP_POST and HTTP_PUT. diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 090ab2a00..b9cddc8e4 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -261,7 +261,7 @@ U32 LLXferManager::numActiveListEntries(LLXfer *list_head) while (list_head) { - if (list_head->mStatus == e_LL_XFER_IN_PROGRESS) + if ((list_head->mStatus == e_LL_XFER_IN_PROGRESS)) { num_entries++; } diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 1d51ff800..3f9c95dc8 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -118,7 +118,7 @@ namespace { } - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { // don't spam when agent communication disconnected already if (status != 410) @@ -131,12 +131,13 @@ namespace if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_TCP_TIMEOUT); } - virtual void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_NOERR); } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fnPtrResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fnPtrResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLFnPtrResponder"; } private: diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 6d1d3498c..e279f781d 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -281,6 +281,8 @@ char const* const _PREHASH_GrabOffset = LLMessageStringTable::getInstance()->get char const* const _PREHASH_SimPort = LLMessageStringTable::getInstance()->getString("SimPort"); char const* const _PREHASH_PricePerMeter = LLMessageStringTable::getInstance()->getString("PricePerMeter"); char const* const _PREHASH_RegionFlags = LLMessageStringTable::getInstance()->getString("RegionFlags"); +char const* const _PREHASH_RegionFlagsExtended = LLMessageStringTable::getInstance()->getString("RegionFlagsExtended"); +char const* const _PREHASH_RegionProtocols = LLMessageStringTable::getInstance()->getString("RegionProtocols"); char const* const _PREHASH_VoteResult = LLMessageStringTable::getInstance()->getString("VoteResult"); char const* const _PREHASH_ParcelDirFeeEstimate = LLMessageStringTable::getInstance()->getString("ParcelDirFeeEstimate"); char const* const _PREHASH_ModifyBlock = LLMessageStringTable::getInstance()->getString("ModifyBlock"); @@ -307,6 +309,8 @@ char const* const _PREHASH_ViewerStartAuction = LLMessageStringTable::getInstanc char const* const _PREHASH_StartAuction = LLMessageStringTable::getInstance()->getString("StartAuction"); char const* const _PREHASH_DuplicateFlags = LLMessageStringTable::getInstance()->getString("DuplicateFlags"); char const* const _PREHASH_RegionInfo2 = LLMessageStringTable::getInstance()->getString("RegionInfo2"); +char const* const _PREHASH_RegionInfo3 = LLMessageStringTable::getInstance()->getString("RegionInfo3"); +char const* const _PREHASH_RegionInfo4 = LLMessageStringTable::getInstance()->getString("RegionInfo4"); char const* const _PREHASH_TextColor = LLMessageStringTable::getInstance()->getString("TextColor"); char const* const _PREHASH_SlaveID = LLMessageStringTable::getInstance()->getString("SlaveID"); char const* const _PREHASH_Charter = LLMessageStringTable::getInstance()->getString("Charter"); @@ -1379,3 +1383,6 @@ char const* const _PREHASH_ProductSKU = LLMessageStringTable::getInstance()->get char const* const _PREHASH_SeeAVs = LLMessageStringTable::getInstance()->getString("SeeAVs"); char const* const _PREHASH_AnyAVSounds = LLMessageStringTable::getInstance()->getString("AnyAVSounds"); char const* const _PREHASH_GroupAVSounds = LLMessageStringTable::getInstance()->getString("GroupAVSounds"); +char const* const _PREHASH_AppearanceData = LLMessageStringTable::getInstance()->getString("AppearanceData"); +char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance()->getString("AppearanceVersion"); +char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index d388d8629..1c1d6e224 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -281,6 +281,8 @@ extern char const* const _PREHASH_GrabOffset; extern char const* const _PREHASH_SimPort; extern char const* const _PREHASH_PricePerMeter; extern char const* const _PREHASH_RegionFlags; +extern char const* const _PREHASH_RegionFlagsExtended; +extern char const* const _PREHASH_RegionProtocols; extern char const* const _PREHASH_VoteResult; extern char const* const _PREHASH_ParcelDirFeeEstimate; extern char const* const _PREHASH_ModifyBlock; @@ -307,6 +309,8 @@ extern char const* const _PREHASH_ViewerStartAuction; extern char const* const _PREHASH_StartAuction; extern char const* const _PREHASH_DuplicateFlags; extern char const* const _PREHASH_RegionInfo2; +extern char const* const _PREHASH_RegionInfo3; +extern char const* const _PREHASH_RegionInfo4; extern char const* const _PREHASH_TextColor; extern char const* const _PREHASH_SlaveID; extern char const* const _PREHASH_Charter; @@ -1379,4 +1383,7 @@ extern char const* const _PREHASH_ProductSKU; extern char const* const _PREHASH_SeeAVs; extern char const* const _PREHASH_AnyAVSounds; extern char const* const _PREHASH_GroupAVSounds; +extern char const* const _PREHASH_AppearanceData; +extern char const* const _PREHASH_AppearanceVersion; +extern char const* const _PREHASH_CofVersion; #endif diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 064b12da1..dc452d1ef 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -3,33 +3,26 @@ * @brief LLPluginClassMedia handles a plugin which knows about the "media" message class. * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 4ad2a3fef..fcaa52874 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -3,33 +3,26 @@ * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class. * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llplugin/llplugininstance.cpp b/indra/llplugin/llplugininstance.cpp index 19d41f201..cb27ea204 100644 --- a/indra/llplugin/llplugininstance.cpp +++ b/indra/llplugin/llplugininstance.cpp @@ -3,33 +3,26 @@ * @brief LLPluginInstance handles loading the dynamic library of a plugin and setting up its entry points for message passing. * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ #if LL_LINUX && defined(LL_STANDALONE) diff --git a/indra/llplugin/llplugininstance.h b/indra/llplugin/llplugininstance.h index c77da97ba..1f4c0a833 100644 --- a/indra/llplugin/llplugininstance.h +++ b/indra/llplugin/llplugininstance.h @@ -2,33 +2,26 @@ * @file llplugininstance.h * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llplugin/llpluginmessage.h b/indra/llplugin/llpluginmessage.h index 7bc4ea12d..5c41f7eef 100644 --- a/indra/llplugin/llpluginmessage.h +++ b/indra/llplugin/llpluginmessage.h @@ -2,33 +2,26 @@ * @file llpluginmessage.h * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llplugin/llpluginmessageclasses.h b/indra/llplugin/llpluginmessageclasses.h index b61720ab4..443f27b00 100644 --- a/indra/llplugin/llpluginmessageclasses.h +++ b/indra/llplugin/llpluginmessageclasses.h @@ -3,33 +3,26 @@ * @brief This file defines the versions of existing message classes for LLPluginMessage. * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp index 8f19145a8..a00cd63e6 100644 --- a/indra/llplugin/llpluginmessagepipe.cpp +++ b/indra/llplugin/llpluginmessagepipe.cpp @@ -3,33 +3,26 @@ * @brief Classes that implement connections from the plugin system to pipes/pumps. * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llplugin/llpluginmessagepipe.h b/indra/llplugin/llpluginmessagepipe.h index 1e71caf42..6b503cc17 100644 --- a/indra/llplugin/llpluginmessagepipe.h +++ b/indra/llplugin/llpluginmessagepipe.h @@ -3,33 +3,26 @@ * @brief Classes that implement connections from the plugin system to pipes/pumps. * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ @@ -48,6 +41,7 @@ class LLPluginMessagePipeOwner public: LLPluginMessagePipeOwner(); virtual ~LLPluginMessagePipeOwner(); + // called with incoming messages virtual void receiveMessageRaw(const std::string &message) = 0; // called when the socket has an error diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp index a85a0343d..08a13c7fd 100644 --- a/indra/llplugin/llpluginprocesschild.cpp +++ b/indra/llplugin/llpluginprocesschild.cpp @@ -3,33 +3,26 @@ * @brief LLPluginProcessChild handles the child side of the external-process plugin API. * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index c3fa0fb53..13c1d3c4e 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -3,33 +3,26 @@ * @brief LLPluginProcessParent handles the parent side of the external-process plugin API. * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index d5a08c435..f3bc60dcf 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -3,33 +3,26 @@ * @brief LLPluginProcessParent handles the parent side of the external-process plugin API. * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llplugin/llpluginsharedmemory.cpp b/indra/llplugin/llpluginsharedmemory.cpp index 56a6fe1c9..d3a340c20 100644 --- a/indra/llplugin/llpluginsharedmemory.cpp +++ b/indra/llplugin/llpluginsharedmemory.cpp @@ -3,33 +3,26 @@ * LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API. * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llplugin/llpluginsharedmemory.h b/indra/llplugin/llpluginsharedmemory.h index a5cb7dcf5..84b7a58c3 100644 --- a/indra/llplugin/llpluginsharedmemory.h +++ b/indra/llplugin/llpluginsharedmemory.h @@ -2,33 +2,26 @@ * @file llpluginsharedmemory.h * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 */ diff --git a/indra/llprimitive/llmaterialtable.cpp b/indra/llprimitive/llmaterialtable.cpp index 280c6d61c..86da1fbf4 100644 --- a/indra/llprimitive/llmaterialtable.cpp +++ b/indra/llprimitive/llmaterialtable.cpp @@ -2,31 +2,25 @@ * @file llmaterialtable.cpp * @brief Table of material names and IDs for viewer * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 7d4b34ead..b3b5145c5 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1027,7 +1027,8 @@ void LLModel::setVolumeFaceData( if (tc.get()) { - LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32)); + U32 tex_size = (num_verts*2*sizeof(F32)+0xF)&~0xF; + LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), tex_size); } else { diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 83ea3e3eb..7e45c0e96 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -2,31 +2,25 @@ * @file llprimitive.cpp * @brief LLPrimitive base class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -1233,94 +1227,77 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const return FALSE; } -S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name) +S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec) { - return(unpackTEMessage(mesgsys,block_name,-1)); -} - -S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num) -{ - // use a negative block_num to indicate a single-block read (a non-variable block) S32 retval = 0; - const U32 MAX_TES = 32; - - // Avoid construction of 32 UUIDs per call. JC - - U8 image_data[MAX_TES*16]; - U8 colors[MAX_TES*4]; - F32 scale_s[MAX_TES]; - F32 scale_t[MAX_TES]; - S16 offset_s[MAX_TES]; - S16 offset_t[MAX_TES]; - S16 image_rot[MAX_TES]; - U8 bump[MAX_TES]; - U8 media_flags[MAX_TES]; - U8 glow[MAX_TES]; - - const U32 MAX_TE_BUFFER = 4096; - U8 packed_buffer[MAX_TE_BUFFER]; - U8 *cur_ptr = packed_buffer; - - U32 size; - U32 face_count = 0; if (block_num < 0) { - size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry); + tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry); } else { - size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry); + tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry); } - if (size == 0) + if (tec.size == 0) { return retval; } if (block_num < 0) { - mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, 0, MAX_TE_BUFFER); + mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, 0, LLTEContents::MAX_TE_BUFFER); } else { - mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, block_num, MAX_TE_BUFFER); + mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER); } - face_count = getNumTEs(); + tec.face_count = getNumTEs(); - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID); + U8 *cur_ptr = tec.packed_buffer; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.colors, 4, tec.face_count, MVT_U8); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_s, 4, tec.face_count, MVT_F32); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_t, 4, tec.face_count, MVT_F32); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_s, 2, tec.face_count, MVT_S16Array); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_t, 2, tec.face_count, MVT_S16Array); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_rot, 2, tec.face_count, MVT_S16Array); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.bump, 1, tec.face_count, MVT_U8); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.media_flags, 1, tec.face_count, MVT_U8); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8); - + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8); + + retval = 1; + return retval; +} + +S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec) +{ + S32 retval = 0; + LLColor4 color; LLColor4U coloru; - for (U32 i = 0; i < face_count; i++) + for (U32 i = 0; i < tec.face_count; i++) { - retval |= setTETexture(i, ((LLUUID*)image_data)[i]); - retval |= setTEScale(i, scale_s[i], scale_t[i]); - retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF); - retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); - retval |= setTEBumpShinyFullbright(i, bump[i]); - retval |= setTEMediaTexGen(i, media_flags[i]); - retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); - coloru = LLColor4U(colors + 4*i); + LLUUID& req_id = ((LLUUID*)tec.image_data)[i]; + retval |= setTETexture(i, req_id); + retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]); + retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF); + retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); + retval |= setTEBumpShinyFullbright(i, tec.bump[i]); + retval |= setTEMediaTexGen(i, tec.media_flags[i]); + retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF); + coloru = LLColor4U(tec.colors + 4*i); // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) // as all zeros. However, the subtraction and addition must be done in unsigned @@ -1337,6 +1314,15 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam return retval; } +S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num) +{ + LLTEContents tec; + S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec); + if (!retval) + return retval; + return applyParsedTEMessage(tec); +} + S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) { // use a negative block_num to indicate a single-block read (a non-variable block) diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 5808ffc3c..75f9f494b 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -2,31 +2,25 @@ * @file llprimitive.h * @brief LLPrimitive base class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -295,6 +289,34 @@ public: }; +// This code is not naming-standards compliant. Leaving it like this for +// now to make the connection to code in +// BOOL packTEMessage(LLDataPacker &dp) const; +// more obvious. This should be refactored to remove the duplication, at which +// point we can fix the names as well. +// - Vir +struct LLTEContents +{ + static const U32 MAX_TES = 32; + + U8 image_data[MAX_TES*16]; + U8 colors[MAX_TES*4]; + F32 scale_s[MAX_TES]; + F32 scale_t[MAX_TES]; + S16 offset_s[MAX_TES]; + S16 offset_t[MAX_TES]; + S16 image_rot[MAX_TES]; + U8 bump[MAX_TES]; + U8 media_flags[MAX_TES]; + U8 glow[MAX_TES]; + + static const U32 MAX_TE_BUFFER = 4096; + U8 packed_buffer[MAX_TE_BUFFER]; + + U32 size; + U32 face_count; +}; + class LLPrimitive : public LLXform { public: @@ -366,9 +388,10 @@ public: S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type); BOOL packTEMessage(LLMessageSystem *mesgsys) const; BOOL packTEMessage(LLDataPacker &dp) const; - S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name); S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks BOOL unpackTEMessage(LLDataPacker &dp); + S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec); + S32 applyParsedTEMessage(LLTEContents& tec); #ifdef CHECK_FOR_FINITE inline void setPosition(const LLVector3& pos); diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 3432f0c98..8b80180d4 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -2,31 +2,25 @@ * @file lltextureentry.cpp * @brief LLTextureEntry base class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index e312e2a91..ba0c92dc7 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -2,31 +2,25 @@ * @file lltextureentry.h * @brief LLTextureEntry base class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llqtwebkit/llstyle.cpp b/indra/llqtwebkit/llstyle.cpp index ecd2b3eb8..8822d481a 100644 --- a/indra/llqtwebkit/llstyle.cpp +++ b/indra/llqtwebkit/llstyle.cpp @@ -71,7 +71,7 @@ void LLStyle::drawControl(ControlElement element, const QStyleOption *option, QP QPlastiqueStyle::drawControl(element, &localOption, painter, widget); return; } - + default: break; } diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 1ec4512f9..22d9d54f1 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -31,11 +31,14 @@ set(llrender_SOURCE_FILES llfontregistry.cpp llgldbg.cpp llglslshader.cpp + llgltexture.cpp llimagegl.cpp llpostprocess.cpp + llrender2dutils.cpp llrendersphere.cpp llshadermgr.cpp lltexture.cpp + lluiimage.cpp llvertexbuffer.cpp ) @@ -52,13 +55,16 @@ set(llrender_HEADER_FILES llglheaders.h llglslshader.h llglstates.h + llgltexture.h llgltypes.h llimagegl.h llpostprocess.h llrender.h + llrender2dutils.h llrendersphere.h llshadermgr.h lltexture.h + lluiimage.h llvertexbuffer.h ) diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 5b327b4ed..1e88768e9 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -2,31 +2,25 @@ * @file llfontgl.cpp * @brief Wrapper around FreeType * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 11ed81c37..abf1009ea 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -3,31 +3,25 @@ * @author Doug Soo * @brief Wrapper around FreeType * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index aaa5b421b..3391862f6 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -3,31 +3,25 @@ * @author Brad Payne * @brief Storage for fonts. * - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h index 4da4ca48b..8b06191c5 100644 --- a/indra/llrender/llfontregistry.h +++ b/indra/llrender/llfontregistry.h @@ -3,31 +3,25 @@ * @author Brad Payne * @brief Storage for fonts. * - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index eba807ece..7dba1e0b4 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -402,7 +402,7 @@ PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL; PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL; PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = NULL; #endif // LL_LINUX_NV_GL_HEADERS -#endif +#endif // (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS LLGLManager gGLManager; @@ -809,8 +809,6 @@ std::string LLGLManager::getGLInfoString() void LLGLManager::printGLInfoString() { - std::string info_str; - LL_INFOS("RenderInit") << "GL_VENDOR: " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL; LL_INFOS("RenderInit") << "GL_RENDERER: " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL; LL_INFOS("RenderInit") << "GL_VERSION: " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL; @@ -935,7 +933,7 @@ void LLGLManager::initExtensions() mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts); mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts); - mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE; + mHasTransformFeedback = mGLVersion >= 4.f || ExtensionExists("GL_EXT_transform_feedback", gGLHExts.mSysExts); #if !LL_DARWIN mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); #endif diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index a63f0aca3..de4a81bb5 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -421,10 +421,13 @@ const U32 FENCE_WAIT_TIME_NANOSECONDS = 1000; //1 ms class LLGLFence { public: + virtual ~LLGLFence() + { + } + virtual void placeFence() = 0; virtual bool isCompleted() = 0; virtual void wait() = 0; - virtual ~LLGLFence() {} }; class LLGLSyncFence : public LLGLFence diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index c5823044d..11074a7fd 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -1,32 +1,26 @@ -/** +/** * @file llglheaders.h * @brief LLGL definitions * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -279,6 +273,9 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT; # undef __APPLE__ #elif LL_LINUX +//---------------------------------------------------------------------------- +// LL_LINUX + //---------------------------------------------------------------------------- // Linux, MESA headers, but not necessarily assuming MESA runtime. // quotes so we get libraries/.../GL/ version diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index ce130cf30..b8827db9e 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -2,31 +2,25 @@ * @file llglslshader.cpp * @brief GLSL helper functions and state. * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -168,7 +162,7 @@ BOOL LLGLSLShader::createShader(vector * attributes, success = FALSE; } } - + // Attach existing objects if (!LLShaderMgr::instance()->attachShaderFeatures(this)) { diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 2f64b0c9f..a5817ce28 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -2,31 +2,25 @@ * @file llglslshader.h * @brief GLSL shader wrappers * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -166,5 +160,8 @@ public: extern LLGLSLShader gUIProgram; //output vec4(color.rgb,color.a*tex0[tc0].a) extern LLGLSLShader gSolidColorProgram; +//Alpha mask shader (declared here so llappearance can access properly) +extern LLGLSLShader gAlphaMaskProgram; + #endif diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp new file mode 100644 index 000000000..c7b223fbf --- /dev/null +++ b/indra/llrender/llgltexture.cpp @@ -0,0 +1,398 @@ +/** + * @file llgltexture.cpp + * @brief Opengl texture implementation + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#include "linden_common.h" +#include "llgltexture.h" + + +// static +S32 LLGLTexture::getTotalNumOfCategories() +{ + return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ; +} + +// static +//index starts from zero. +S32 LLGLTexture::getIndexFromCategory(S32 category) +{ + return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ; +} + +//static +S32 LLGLTexture::getCategoryFromIndex(S32 index) +{ + return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ; +} + +LLGLTexture::LLGLTexture(BOOL usemipmaps) +{ + init(); + mUseMipMaps = usemipmaps; +} + +LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) +{ + init(); + mFullWidth = width ; + mFullHeight = height ; + mUseMipMaps = usemipmaps ; + mComponents = components ; + setTexelsPerImage(); +} + +LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) +{ + init(); + mUseMipMaps = usemipmaps ; + // Create an empty image of the specified size and width + mGLTexturep = new LLImageGL(raw, usemipmaps) ; +} + +LLGLTexture::~LLGLTexture() +{ + cleanup(); +} + +void LLGLTexture::init() +{ + mBoostLevel = LLGLTexture::BOOST_NONE; + + mFullWidth = 0; + mFullHeight = 0; + mTexelsPerImage = 0 ; + mUseMipMaps = FALSE ; + mComponents = 0 ; + + mTextureState = NO_DELETE ; + mDontDiscard = FALSE; + mNeedsGLTexture = FALSE ; +} + +void LLGLTexture::cleanup() +{ + if(mGLTexturep) + { + mGLTexturep->cleanup(); + } +} + +// virtual +void LLGLTexture::dump() +{ + if(mGLTexturep) + { + mGLTexturep->dump(); + } +} + +void LLGLTexture::setBoostLevel(S32 level) +{ + if(mBoostLevel != level) + { + mBoostLevel = level ; + if(mBoostLevel != LLGLTexture::BOOST_NONE) + { + setNoDelete() ; + } + if(gAuditTexture) + { + setCategory(mBoostLevel); + } + } +} + +void LLGLTexture::forceActive() +{ + mTextureState = ACTIVE ; +} + +void LLGLTexture::setActive() +{ + if(mTextureState != NO_DELETE) + { + mTextureState = ACTIVE ; + } +} + +//set the texture to stay in memory +void LLGLTexture::setNoDelete() +{ + mTextureState = NO_DELETE ; +} + +void LLGLTexture::generateGLTexture() +{ + if(mGLTexturep.isNull()) + { + mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ; + } +} + +LLImageGL* LLGLTexture::getGLTexture() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep ; +} + +BOOL LLGLTexture::createGLTexture() +{ + if(mGLTexturep.isNull()) + { + generateGLTexture() ; + } + + return mGLTexturep->createGLTexture() ; +} + +BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category) +{ + llassert(mGLTexturep.notNull()) ; + + BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ; + + if(ret) + { + mFullWidth = mGLTexturep->getCurrentWidth() ; + mFullHeight = mGLTexturep->getCurrentHeight() ; + mComponents = mGLTexturep->getComponents() ; + setTexelsPerImage(); + } + + return ret ; +} + +void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) +{ + llassert(mGLTexturep.notNull()) ; + + mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ; +} +void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode) +{ + llassert(mGLTexturep.notNull()) ; + mGLTexturep->setAddressMode(mode) ; +} +void LLGLTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option) +{ + llassert(mGLTexturep.notNull()) ; + mGLTexturep->setFilteringOption(option) ; +} + +//virtual +S32 LLGLTexture::getWidth(S32 discard_level) const +{ + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getWidth(discard_level) ; +} + +//virtual +S32 LLGLTexture::getHeight(S32 discard_level) const +{ + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getHeight(discard_level) ; +} + +S32 LLGLTexture::getMaxDiscardLevel() const +{ + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getMaxDiscardLevel() ; +} +S32 LLGLTexture::getDiscardLevel() const +{ + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getDiscardLevel() ; +} +S8 LLGLTexture::getComponents() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getComponents() ; +} + +LLGLuint LLGLTexture::getTexName() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getTexName() ; +} + +BOOL LLGLTexture::hasGLTexture() const +{ + if(mGLTexturep.notNull()) + { + return mGLTexturep->getHasGLTexture() ; + } + return FALSE ; +} + +BOOL LLGLTexture::getBoundRecently() const +{ + if(mGLTexturep.notNull()) + { + return mGLTexturep->getBoundRecently() ; + } + return FALSE ; +} + +LLTexUnit::eTextureType LLGLTexture::getTarget(void) const +{ + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getTarget() ; +} + +BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, bool fast_update) +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, fast_update) ; +} + +BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool fast_update) +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height, fast_update) ; +} + +void LLGLTexture::setGLTextureCreated (bool initialized) +{ + llassert(mGLTexturep.notNull()) ; + + mGLTexturep->setGLTextureCreated (initialized) ; +} + +void LLGLTexture::setCategory(S32 category) +{ + llassert(mGLTexturep.notNull()) ; + + mGLTexturep->setCategory(category) ; +} + +LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getAddressMode() ; +} + +S32 LLGLTexture::getTextureMemory() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->mTextureMemory ; +} + +LLGLenum LLGLTexture::getPrimaryFormat() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getPrimaryFormat() ; +} + +BOOL LLGLTexture::getIsAlphaMask() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getIsAlphaMask() ; +} + +BOOL LLGLTexture::getMask(const LLVector2 &tc) +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getMask(tc) ; +} + +F32 LLGLTexture::getTimePassedSinceLastBound() +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getTimePassedSinceLastBound() ; +} +BOOL LLGLTexture::getMissed() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getMissed() ; +} + +BOOL LLGLTexture::isJustBound() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->isJustBound() ; +} + +void LLGLTexture::forceUpdateBindStats(void) const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->forceUpdateBindStats() ; +} + +/*U32 LLGLTexture::getTexelsInAtlas() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getTexelsInAtlas() ; +} + +U32 LLGLTexture::getTexelsInGLTexture() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getTexelsInGLTexture() ; +} + +BOOL LLGLTexture::isGLTextureCreated() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->isGLTextureCreated() ; +} + +S32 LLGLTexture::getDiscardLevelInAtlas() const +{ + llassert(mGLTexturep.notNull()) ; + + return mGLTexturep->getDiscardLevelInAtlas() ; +}*/ + +void LLGLTexture::destroyGLTexture() +{ + if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) + { + mGLTexturep->destroyGLTexture() ; + mTextureState = DELETED ; + } +} + +void LLGLTexture::setTexelsPerImage() +{ + S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT); + S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT); + mTexelsPerImage = (F32)fullwidth * fullheight; +} \ No newline at end of file diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h new file mode 100644 index 000000000..6516dd8bc --- /dev/null +++ b/indra/llrender/llgltexture.h @@ -0,0 +1,196 @@ +/** + * @file llglviewertexture.h + * @brief Object for managing opengl textures + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#ifndef LL_GL_TEXTURE_H +#define LL_GL_TEXTURE_H + +#include "lltexture.h" +#include "llgl.h" + +class LLImageRaw; + +// +//this the parent for the class LLViewerTexture +//through the following virtual functions, the class LLViewerTexture can be reached from /llrender. +// +class LLGLTexture : public LLTexture +{ +public: + enum + { + MAX_IMAGE_SIZE_DEFAULT = 1024, + INVALID_DISCARD_LEVEL = 0x7fff + }; + + enum EBoostLevel + { + BOOST_NONE = 0, + BOOST_AVATAR_BAKED , + BOOST_AVATAR , + BOOST_CLOUDS , + BOOST_SCULPTED , + + BOOST_HIGH = 10, + BOOST_BUMP , + BOOST_TERRAIN , // has to be high priority for minimap / low detail + BOOST_SELECTED , + BOOST_AVATAR_BAKED_SELF , + BOOST_AVATAR_SELF , // needed for baking avatar + BOOST_SUPER_HIGH , //textures higher than this need to be downloaded at the required resolution without delay. + BOOST_HUD , + BOOST_ICON , + BOOST_UI , + BOOST_PREVIEW , + BOOST_MAP , + BOOST_MAP_VISIBLE , + BOOST_MAX_LEVEL, + + //other texture Categories + LOCAL = BOOST_MAX_LEVEL, + AVATAR_SCRATCH_TEX, + DYNAMIC_TEX, + MEDIA, + //ATLAS, + OTHER, + MAX_GL_IMAGE_CATEGORY + }; + + static S32 getTotalNumOfCategories() ; + static S32 getIndexFromCategory(S32 category) ; + static S32 getCategoryFromIndex(S32 index) ; + +protected: + virtual ~LLGLTexture(); + LOG_CLASS(LLGLTexture); + +public: + LLGLTexture(BOOL usemipmaps = TRUE); + LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) ; + LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ; + + virtual void dump(); // debug info to llinfos + + virtual const LLUUID& getID() const = 0; + + void setBoostLevel(S32 level); + S32 getBoostLevel() { return mBoostLevel; } + + S32 getFullWidth() const { return mFullWidth; } + S32 getFullHeight() const { return mFullHeight; } + + void generateGLTexture() ; + void destroyGLTexture() ; + + //--------------------------------------------------------------------------------------------- + //functions to access LLImageGL + //--------------------------------------------------------------------------------------------- + /*virtual*/S32 getWidth(S32 discard_level = -1) const; + /*virtual*/S32 getHeight(S32 discard_level = -1) const; + + BOOL hasGLTexture() const ; + LLGLuint getTexName() const ; + BOOL createGLTexture() ; + BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER); + + void setFilteringOption(LLTexUnit::eTextureFilterOptions option); + void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); + void setAddressMode(LLTexUnit::eTextureAddressMode mode); + BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, bool fast_update = false); + BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool fast_update = false); + void setGLTextureCreated (bool initialized); + void setCategory(S32 category) ; + + LLTexUnit::eTextureAddressMode getAddressMode(void) const ; + S32 getMaxDiscardLevel() const; + S32 getDiscardLevel() const; + S8 getComponents() const; + BOOL getBoundRecently() const; + S32 getTextureMemory() const ; + LLGLenum getPrimaryFormat() const; + BOOL getIsAlphaMask() const ; + LLTexUnit::eTextureType getTarget(void) const ; + BOOL getMask(const LLVector2 &tc); + F32 getTimePassedSinceLastBound(); + BOOL getMissed() const ; + BOOL isJustBound()const ; + void forceUpdateBindStats(void) const; + + /*U32 getTexelsInAtlas() const ; + U32 getTexelsInGLTexture() const ; + BOOL isGLTextureCreated() const ; + S32 getDiscardLevelInAtlas() const ;*/ + //--------------------------------------------------------------------------------------------- + //end of functions to access LLImageGL + //--------------------------------------------------------------------------------------------- + + //----------------- + /*virtual*/ void setActive() ; + void forceActive() ; + void setNoDelete() ; + void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; } + BOOL getDontDiscard() const { return mDontDiscard; } + //----------------- + +private: + void cleanup(); + void init(); + +protected: + void setTexelsPerImage(); + + //note: do not make this function public. + /*virtual*/ LLImageGL* getGLTexture() const ; + +protected: + S32 mBoostLevel; // enum describing priority level + S32 mFullWidth; + S32 mFullHeight; + BOOL mUseMipMaps ; + S8 mComponents; + F32 mTexelsPerImage; // Texels per image. + mutable S8 mNeedsGLTexture; + + //GL texture + LLPointer mGLTexturep ; + S8 mDontDiscard; // Keep full res version of this image (for UI, etc) + +protected: + typedef enum + { + DELETED = 0, //removed from memory + DELETION_CANDIDATE, //ready to be removed from memory + INACTIVE, //not be used for the last certain period (i.e., 30 seconds). + ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). + NO_DELETE = 99 //stay in memory, can not be removed. + } LLGLTextureState; + LLGLTextureState mTextureState ; + + +}; + +#endif // LL_GL_TEXTURE_H + diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 03eddae8d..f45892a5a 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -2,31 +2,25 @@ * @file llimagegl.cpp * @brief Generic GL image handler * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -498,10 +492,11 @@ void LLImageGL::init(BOOL usemipmaps) mWidth = 0; mHeight = 0; mCurrentDiscardLevel = -1; - - mAllowCompression = true; - mTarget = GL_TEXTURE_2D; + + mAllowCompression = true; + + mTarget = GL_TEXTURE_2D; mBindTarget = LLTexUnit::TT_TEXTURE; mHasMipMaps = false; mMipLevels = -1; @@ -521,7 +516,7 @@ void LLImageGL::init(BOOL usemipmaps) mFormatSwapBytes = FALSE; #ifdef DEBUG_MISS - mMissed = FALSE; + mMissed = FALSE; #endif mCategory = -1; @@ -592,11 +587,11 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve width >>= 1; height >>= 1; } + if(discard_level > 0) { mMaxDiscardLevel = llmax(mMaxDiscardLevel, (S8)discard_level); } - } else { @@ -692,14 +687,16 @@ void LLImageGL::setImage(const LLImageRaw* imageraw) setImage(rawdata, FALSE); } +static LLFastTimer::DeclareTimer FTM_SET_IMAGE("setImage"); void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) { + LLFastTimer t(FTM_SET_IMAGE); bool is_compressed = false; if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) { is_compressed = true; } - + if (mUseMipMaps) @@ -739,7 +736,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } if (is_compressed) { -// LLFastTimer t2(FTM_TEMP4); S32 tex_size = dataFormatBytes(mFormatPrimary, w, h); glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in); stop_glerror(); @@ -1048,8 +1044,10 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_ } // static +static LLFastTimer::DeclareTimer FTM_GENERATE_TEXTURES("generate textures"); void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures) { + LLFastTimer t(FTM_GENERATE_TEXTURES); bool empty = true; dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format); @@ -1110,8 +1108,10 @@ void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip } // static +static LLFastTimer::DeclareTimer FTM_SET_MANUAL_IMAGE("setManualImage"); void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression) { + LLFastTimer t(FTM_SET_MANUAL_IMAGE); bool use_scratch = false; U32* scratch = NULL; if (LLRender::sGLCoreProfile) @@ -1215,8 +1215,10 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt //create an empty GL texture: just create a texture name //the texture is assiciate with some image by calling glTexImage outside LLImageGL +static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE1("createGLTexture()"); BOOL LLImageGL::createGLTexture() { + LLFastTimer t(FTM_CREATE_GL_TEXTURE1); if (gGLManager.mIsDisabled) { llwarns << "Trying to create a texture while GL is disabled!" << llendl; @@ -1244,8 +1246,10 @@ BOOL LLImageGL::createGLTexture() return TRUE ; } +static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE2("createGLTexture(raw)"); BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category) { + LLFastTimer t(FTM_CREATE_GL_TEXTURE2); if (gGLManager.mIsDisabled) { llwarns << "Trying to create a texture while GL is disabled!" << llendl; @@ -1261,7 +1265,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S llassert(mCurrentDiscardLevel >= 0); discard_level = mCurrentDiscardLevel; } - + // Actual image width/height = raw image width/height * 2^discard_level S32 raw_w = imageraw->getWidth() ; S32 raw_h = imageraw->getHeight() ; @@ -1275,29 +1279,29 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S { switch (mComponents) { - case 1: + case 1: // Use luminance alpha (for fonts) mFormatInternal = GL_LUMINANCE8; mFormatPrimary = GL_LUMINANCE; mFormatType = GL_UNSIGNED_BYTE; break; - case 2: + case 2: // Use luminance alpha (for fonts) mFormatInternal = GL_LUMINANCE8_ALPHA8; mFormatPrimary = GL_LUMINANCE_ALPHA; mFormatType = GL_UNSIGNED_BYTE; break; - case 3: + case 3: mFormatInternal = GL_RGB8; mFormatPrimary = GL_RGB; mFormatType = GL_UNSIGNED_BYTE; break; - case 4: + case 4: mFormatInternal = GL_RGBA8; mFormatPrimary = GL_RGBA; mFormatType = GL_UNSIGNED_BYTE; break; - default: + default: LL_DEBUGS("Openjpeg") << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL; to_create = false; break; @@ -1314,13 +1318,15 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S return TRUE ; } - setCategory(category) ; + setCategory(category); const U8* rawdata = imageraw->getData(); return createGLTexture(discard_level, rawdata, FALSE, usename); } +static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE3("createGLTexture3(data)"); BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) { + LLFastTimer t(FTM_CREATE_GL_TEXTURE3); llassert(data_in); stop_glerror(); @@ -1329,6 +1335,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ llassert(mCurrentDiscardLevel >= 0); discard_level = mCurrentDiscardLevel; } + discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); if (mTexName != 0 && discard_level == mCurrentDiscardLevel) { @@ -1586,7 +1593,18 @@ void LLImageGL::destroyGLTexture() } } - +//force to invalidate the gl texture, most likely a sculpty texture +void LLImageGL::forceToInvalidateGLTexture() +{ + if (mTexName != 0) + { + destroyGLTexture(); + } + else + { + mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. + } +} //---------------------------------------------------------------------------- @@ -1823,7 +1841,6 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h) llassert(w%2 == 0); llassert(h%2 == 0); const GLubyte* rowstart = ((const GLubyte*) data_in) + mAlphaOffset; - for (U32 y = 0; y < h; y+=2) { const GLubyte* current = rowstart; @@ -1850,6 +1867,7 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h) sample[asum/(16*4)] += 4; } + rowstart += 2 * w * mAlphaStride; } length *= 2; // we sampled everything twice, essentially diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index ef9a2ec09..4ec1905cc 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -119,6 +119,7 @@ public: // Read back a raw image for this discard level, if it exists BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok); void destroyGLTexture(); + void forceToInvalidateGLTexture(); void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); void setComponents(S8 ncomponents) { mComponents = ncomponents; } diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp index c1415e3f6..0ab80bf68 100644 --- a/indra/llrender/llpostprocess.cpp +++ b/indra/llrender/llpostprocess.cpp @@ -49,12 +49,63 @@ extern LLGLSLShader gPostNightVisionProgram; extern LLGLSLShader gPostGaussianBlurProgram; extern LLGLSLShader gPostPosterizeProgram; extern LLGLSLShader gPostMotionBlurProgram; +extern LLGLSLShader gPostVignetteProgram; static const unsigned int NOISE_SIZE = 512; static const char * const XML_FILENAME = "postprocesseffects.xml"; -template<> LLSD LLPostProcessShader::LLShaderSetting::getDefaultValue() +class LLPostProcessShader : public IPostProcessShader, public LLRefCount +{ +public: + LLPostProcessShader(const std::string& enable_name, LLGLSLShader& shader, bool enabled = false) : + mShader(shader), mEnabled(enable_name,enabled) + { + addSetting(mEnabled); + } + /*virtual*/ bool isEnabled() const {return mShader.mProgramObject && mEnabled;} + /*virtual*/ void bindShader() {mShader.bind();} + /*virtual*/ void unbindShader() {mShader.unbind();} + /*virtual*/ LLGLSLShader& getShader() {return mShader;} + + /*virtual*/ LLSD getDefaults(); //See IPostProcessShader::getDefaults + /*virtual*/ void loadSettings(const LLSD& settings); //See IPostProcessShader::loadSettings + /*virtual*/ void addSetting(IShaderSettingBase& setting) { mSettings.push_back(&setting); } +protected: + template + struct LLShaderSetting : public IShaderSettingBase + { + LLShaderSetting(const std::string& name, T def) : + mValue(def), mDefault(def), mSettingName(name) {} + operator T() const { return mValue; } + T get() const { return mValue; } + /*virtual*/ const std::string& getName() const { return mSettingName; } //See LLShaderSettingBase::getName + /*virtual*/ LLSD getDefaultValue() const { return mDefault; } //See LLShaderSettingBase::getDefaultValue + /*virtual*/ void setValue(const LLSD& value) { mValue = value; } //See LLShaderSettingBase::setValue + private: + const std::string mSettingName; //LLSD key names as found in postprocesseffects.xml. eg 'contrast_base' + T mValue; //The member variable mentioned above. + T mDefault; //Set via ctor. Value is inserted into the defaults LLSD list if absent from postprocesseffects.xml + }; +private: + std::vector mSettings; //Contains a list of all the 'settings' this shader uses. Manually add via push_back in ctor. + LLGLSLShader& mShader; + LLShaderSetting mEnabled; +}; + +//helpers +class LLPostProcessSinglePassColorShader : public LLPostProcessShader +{ +public: + LLPostProcessSinglePassColorShader(const std::string& enable_name, LLGLSLShader& shader, bool enabled = false) : + LLPostProcessShader(enable_name, shader, enabled) {} + /*virtual*/ S32 getColorChannel() const {return 0;} + /*virtual*/ S32 getDepthChannel() const {return -1;} + /*virtual*/ bool draw(U32 pass) {return pass == 1;} + /*virtual*/ void postDraw() {} +}; + +template<> LLSD LLPostProcessShader::LLShaderSetting::getDefaultValue() const { return mDefault.getValue(); } @@ -66,223 +117,175 @@ template<> void LLPostProcessShader::LLShaderSetting::setValue(const LLSD LLPostProcessShader::getDefaults() { LLSD defaults; - for(std::vector::iterator it=mSettings.begin();it!=mSettings.end();++it) + for(std::vector::iterator it=mSettings.begin();it!=mSettings.end();++it) { - defaults[(*it)->mSettingName]=(*it)->getDefaultValue(); + defaults[(*it)->getName()]=(*it)->getDefaultValue(); } return defaults; } void LLPostProcessShader::loadSettings(const LLSD& settings) { - for(std::vector::iterator it=mSettings.begin();it!=mSettings.end();++it) + for(std::vector::iterator it=mSettings.begin();it!=mSettings.end();++it) { - LLSD value = settings[(*it)->mSettingName]; + LLSD value = settings[(*it)->getName()]; (*it)->setValue(value); } } -class LLColorFilterShader : public LLPostProcessShader +class LLColorFilterShader : public LLPostProcessSinglePassColorShader { private: - LLShaderSetting mEnabled; LLShaderSetting mGamma, mBrightness, mContrast, mSaturation; LLShaderSetting mContrastBase; public: - LLColorFilterShader() : - mEnabled("enable_color_filter",false), + LLColorFilterShader() : + LLPostProcessSinglePassColorShader("enable_color_filter",gPostColorFilterProgram), mGamma("gamma",1.f), mBrightness("brightness",1.f), mContrast("contrast",1.f), mSaturation("saturation",1.f), mContrastBase("contrast_base",LLVector4(1.f,1.f,1.f,0.5f)) { - mSettings.push_back(&mEnabled); - mSettings.push_back(&mGamma); - mSettings.push_back(&mBrightness); - mSettings.push_back(&mContrast); - mSettings.push_back(&mSaturation); - mSettings.push_back(&mContrastBase); + addSetting(mGamma); + addSetting(mBrightness); + addSetting(mContrast); + addSetting(mSaturation); + addSetting(mContrastBase); } - bool isEnabled() { return mEnabled && gPostColorFilterProgram.mProgramObject; } - S32 getColorChannel() { return 0; } - S32 getDepthChannel() { return -1; } - - QuadType bind() + /*virtual*/ QuadType preDraw() { - if(!isEnabled()) - return QUAD_NONE; + getShader().uniform1f("gamma", mGamma); + getShader().uniform1f("brightness", mBrightness); + getShader().uniform1f("contrast", mContrast); + float baseI = (mContrastBase.get()[VX] + mContrastBase.get()[VY] + mContrastBase.get()[VZ]) / 3.0f; + baseI = mContrastBase.get()[VW] / llmax(baseI,0.001f); + float baseR = mContrastBase.get()[VX] * baseI; + float baseG = mContrastBase.get()[VY] * baseI; + float baseB = mContrastBase.get()[VZ] * baseI; + getShader().uniform3fv("contrastBase", 1, LLVector3(baseR, baseG, baseB).mV); + getShader().uniform1f("saturation", mSaturation); - /// CALCULATING LUMINANCE (Using NTSC lum weights) - /// http://en.wikipedia.org/wiki/Luma_%28video%29 - static const float LUMINANCE_R = 0.299f; - static const float LUMINANCE_G = 0.587f; - static const float LUMINANCE_B = 0.114f; - - gPostColorFilterProgram.bind(); - - gPostColorFilterProgram.uniform1f("gamma", mGamma); - gPostColorFilterProgram.uniform1f("brightness", mBrightness); - gPostColorFilterProgram.uniform1f("contrast", mContrast); - float baseI = (mContrastBase.mValue[VX] + mContrastBase.mValue[VY] + mContrastBase.mValue[VZ]) / 3.0f; - baseI = mContrastBase.mValue[VW] / ((baseI < 0.001f) ? 0.001f : baseI); - float baseR = mContrastBase.mValue[VX] * baseI; - float baseG = mContrastBase.mValue[VY] * baseI; - float baseB = mContrastBase.mValue[VZ] * baseI; - gPostColorFilterProgram.uniform3fv("contrastBase", 1, LLVector3(baseR, baseG, baseB).mV); - gPostColorFilterProgram.uniform1f("saturation", mSaturation); - gPostColorFilterProgram.uniform3fv("lumWeights", 1, LLVector3(LUMINANCE_R, LUMINANCE_G, LUMINANCE_B).mV); return QUAD_NORMAL; } - bool draw(U32 pass) {return pass == 1;} - void unbind() - { - gPostColorFilterProgram.unbind(); - } }; -class LLNightVisionShader : public LLPostProcessShader +class LLNightVisionShader : public LLPostProcessSinglePassColorShader { private: - LLShaderSetting mEnabled; LLShaderSetting mBrightnessMult, mNoiseStrength; public: LLNightVisionShader() : - mEnabled("enable_night_vision",false), + LLPostProcessSinglePassColorShader("enable_night_vision",gPostNightVisionProgram), mBrightnessMult("brightness_multiplier",3.f), mNoiseStrength("noise_strength",.4f) { - mSettings.push_back(&mEnabled); - mSettings.push_back(&mBrightnessMult); - mSettings.push_back(&mNoiseStrength); + addSetting(mBrightnessMult); + addSetting(mNoiseStrength); } - bool isEnabled() { return mEnabled && gPostNightVisionProgram.mProgramObject; } - S32 getColorChannel() { return 0; } - S32 getDepthChannel() { return -1; } - QuadType bind() + /*virtual*/ QuadType preDraw() { - if(!isEnabled()) - return QUAD_NONE; - - gPostNightVisionProgram.bind(); - LLPostProcess::getInstance()->bindNoise(1); - - gPostNightVisionProgram.uniform1f("brightMult", mBrightnessMult); - gPostNightVisionProgram.uniform1f("noiseStrength", mNoiseStrength); - + + getShader().uniform1f("brightMult", mBrightnessMult); + getShader().uniform1f("noiseStrength", mNoiseStrength); + return QUAD_NOISE; - } - bool draw(U32 pass) {return pass == 1;} - void unbind() +}; + +class LLPosterizeShader : public LLPostProcessSinglePassColorShader +{ +private: + LLShaderSetting mNumLayers; +public: + LLPosterizeShader() : LLPostProcessSinglePassColorShader("enable_posterize",gPostPosterizeProgram), + mNumLayers("posterize_layers",2) { - gPostNightVisionProgram.unbind(); + addSetting(mNumLayers); + } + /*virtual*/ QuadType preDraw() + { + getShader().uniform1i("layerCount", mNumLayers); + return QUAD_NORMAL; + } +}; + +class LLVignetteShader : public LLPostProcessSinglePassColorShader +{ +private: + LLShaderSetting mStrength, mRadius, mDarkness, mDesaturation, mChromaticAberration; +public: + LLVignetteShader() : LLPostProcessSinglePassColorShader("enable_vignette",gPostVignetteProgram), + mStrength("vignette_strength",.85f), + mRadius("vignette_radius",.7f), + mDarkness("vignette_darkness",1.f), + mDesaturation("vignette_desaturation",1.5f), + mChromaticAberration("vignette_chromatic_aberration",.05f) + { + addSetting(mStrength); + addSetting(mRadius); + addSetting(mDarkness); + addSetting(mDesaturation); + addSetting(mChromaticAberration); + } + /*virtual*/ QuadType preDraw() + { + LLVector2 screen_rect = LLPostProcess::getInstance()->getDimensions(); + getShader().uniform1f("vignette_strength", mStrength); + getShader().uniform1f("vignette_radius", mRadius); + getShader().uniform1f("vignette_darkness", mDarkness); + getShader().uniform1f("vignette_desaturation", mDesaturation); + getShader().uniform1f("vignette_chromatic_aberration", mChromaticAberration); + getShader().uniform2fv("screen_res", 1, screen_rect.mV); + return QUAD_NORMAL; } }; class LLGaussBlurShader : public LLPostProcessShader { private: - LLShaderSetting mEnabled; LLShaderSetting mNumPasses; GLint mPassLoc; public: - LLGaussBlurShader() : - mEnabled("enable_gauss_blur",false), + LLGaussBlurShader() : LLPostProcessShader("enable_gauss_blur",gPostGaussianBlurProgram), mNumPasses("gauss_blur_passes",2), mPassLoc(0) { - mSettings.push_back(&mEnabled); - mSettings.push_back(&mNumPasses); + addSetting(mNumPasses); } - bool isEnabled() { return mEnabled && mNumPasses && gPostGaussianBlurProgram.mProgramObject; } - S32 getColorChannel() { return 0; } - S32 getDepthChannel() { return -1; } - QuadType bind() + /*virtual*/ bool isEnabled() const { return LLPostProcessShader::isEnabled() && mNumPasses.get(); } + /*virtual*/ S32 getColorChannel() const { return 0; } + /*virtual*/ S32 getDepthChannel() const { return -1; } + /*virtual*/ QuadType preDraw() { - if(!isEnabled()) - return QUAD_NONE; - - gPostGaussianBlurProgram.bind(); - - mPassLoc = gPostGaussianBlurProgram.getUniformLocation("horizontalPass"); - + mPassLoc = getShader().getUniformLocation("horizontalPass"); return QUAD_NORMAL; } - bool draw(U32 pass) + /*virtual*/ bool draw(U32 pass) { if((S32)pass > mNumPasses*2) return false; glUniform1iARB(mPassLoc, (pass-1) % 2); return true; } - void unbind() - { - gPostGaussianBlurProgram.unbind(); - } -}; - -class LLPosterizeShader : public LLPostProcessShader -{ -private: - LLShaderSetting mEnabled; - LLShaderSetting mNumLayers; -public: - LLPosterizeShader() : - mEnabled("enable_posterize",false), - mNumLayers("posterize_layers",2) - { - mSettings.push_back(&mEnabled); - mSettings.push_back(&mNumLayers); - } - bool isEnabled() { return mEnabled && gPostPosterizeProgram.mProgramObject; } - S32 getColorChannel() { return 0; } - S32 getDepthChannel() { return -1; } - QuadType bind() - { - if(!isEnabled()) - return QUAD_NONE; - - gPostPosterizeProgram.bind(); - - gPostPosterizeProgram.uniform1i("layerCount", mNumLayers); - - return QUAD_NORMAL; - } - bool draw(U32 pass) - { - return pass == 1; - } - void unbind() - { - gPostPosterizeProgram.unbind(); - } + /*virtual*/ void postDraw() {} }; class LLMotionShader : public LLPostProcessShader { private: - LLShaderSetting mEnabled; LLShaderSetting mStrength; public: - LLMotionShader() : - mEnabled("enable_motionblur",false), - mStrength("blur_strength",false) + LLMotionShader() : LLPostProcessShader("enable_motionblur",gPostMotionBlurProgram), + mStrength("blur_strength",1) { - mSettings.push_back(&mEnabled); - mSettings.push_back(&mStrength); + addSetting(mStrength); } - bool isEnabled() { return mEnabled && gPostMotionBlurProgram.mProgramObject; } - S32 getColorChannel() { return 0; } - S32 getDepthChannel() { return 1; } - QuadType bind() + /*virtual*/ S32 getColorChannel() const { return 0; } + /*virtual*/ S32 getDepthChannel() const { return 1; } + /*virtual*/ QuadType preDraw() { - if(!isEnabled()) - { - return QUAD_NONE; - } - glh::matrix4f inv_proj(gGLModelView); inv_proj.mult_left(gGLProjection); inv_proj = inv_proj.inverse(); @@ -291,22 +294,18 @@ public: LLVector2 screen_rect = LLPostProcess::getInstance()->getDimensions(); - gPostMotionBlurProgram.bind(); - gPostMotionBlurProgram.uniformMatrix4fv("prev_proj", 1, GL_FALSE, prev_proj.m); - gPostMotionBlurProgram.uniformMatrix4fv("inv_proj", 1, GL_FALSE, inv_proj.m); - gPostMotionBlurProgram.uniform2fv("screen_res", 1, screen_rect.mV); - gPostMotionBlurProgram.uniform1i("blur_strength", mStrength); + getShader().uniformMatrix4fv("prev_proj", 1, GL_FALSE, prev_proj.m); + getShader().uniformMatrix4fv("inv_proj", 1, GL_FALSE, inv_proj.m); + getShader().uniform2fv("screen_res", 1, screen_rect.mV); + getShader().uniform1i("blur_strength", mStrength); return QUAD_NORMAL; } - bool draw(U32 pass) + /*virtual*/ bool draw(U32 pass) { return pass == 1; } - void unbind() - { - gPostMotionBlurProgram.unbind(); - } + /*virtual*/ void postDraw() {} }; LLPostProcess::LLPostProcess(void) : @@ -320,12 +319,12 @@ LLPostProcess::LLPostProcess(void) : mAllEffectInfo(LLSD::emptyMap()) { mShaders.push_back(new LLMotionShader()); + mShaders.push_back(new LLVignetteShader()); mShaders.push_back(new LLColorFilterShader()); mShaders.push_back(new LLNightVisionShader()); mShaders.push_back(new LLGaussBlurShader()); mShaders.push_back(new LLPosterizeShader()); - /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.*/ std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); LL_DEBUGS2("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL; @@ -547,20 +546,19 @@ void LLPostProcess::doEffects(void) void LLPostProcess::applyShaders(void) { - QuadType quad; bool primary_rendertarget = 1; for(std::list >::iterator it=mShaders.begin();it!=mShaders.end();++it) { - if((quad = (*it)->bind()) != QUAD_NONE) + if((*it)->isEnabled()) { S32 color_channel = (*it)->getColorChannel(); S32 depth_channel = (*it)->getDepthChannel(); - if(depth_channel >= 0) gGL.getTexUnit(depth_channel)->bindManual(LLTexUnit::TT_RECT_TEXTURE, mDepthTexture); - U32 pass = 1; + (*it)->bindShader(); + QuadType quad = (*it)->preDraw(); while((*it)->draw(pass++)) { mRenderTarget[!primary_rendertarget].bindTarget(); @@ -573,7 +571,8 @@ void LLPostProcess::applyShaders(void) if(mRenderTarget[0].getFBO()) primary_rendertarget = !primary_rendertarget; } - (*it)->unbind(); + (*it)->postDraw(); + (*it)->unbindShader(); } } //Only need to copy to framebuffer if FBOs are supported, else we've already been drawing to the framebuffer to begin with. diff --git a/indra/llrender/llpostprocess.h b/indra/llrender/llpostprocess.h index 9ecd9e293..6c3da675e 100644 --- a/indra/llrender/llpostprocess.h +++ b/indra/llrender/llpostprocess.h @@ -38,57 +38,48 @@ #include "llrendertarget.h" class LLSD; +class LLGLSLShader; typedef enum _QuadType { - QUAD_NONE, QUAD_NORMAL, QUAD_NOISE } QuadType; //LLPostProcessShader is an attempt to encapsulate the shaders a little better. -class LLPostProcessShader : public LLRefCount //Abstract. PostProcess shaders derive off of this common base. +class IPostProcessShader //Abstract. PostProcess shaders derive off of this common base. { protected: //LLShaderSetting is used to associate key names to member variables to avoid LLSD lookups when drawing. //It also facilitates automating the assigning of defaults to, as well as parsing from, the effects LLSD list. //This replaces the entire old PostProcessTweaks structure. More will be done in the future to move into a more //xml-driven configuration. - struct LLShaderSettingBase + struct IShaderSettingBase { - LLShaderSettingBase(const char* name) : mSettingName(name) {} - const char* mSettingName; //LLSD key names as found in postprocesseffects.xml. eg 'contrast_base' - virtual LLSD getDefaultValue() = 0; //Converts the member variable as an LLSD. Used to set defaults absent in postprocesseffects.xml + virtual ~IShaderSettingBase() {} //virtual dtor. + virtual const std::string& getName() const = 0; //Returns the name of this setting + virtual LLSD getDefaultValue() const = 0; //Converts the member variable as an LLSD. Used to set defaults absent in postprocesseffects.xml virtual void setValue(const LLSD& value) = 0; //Connects the LLSD element to the member variable. Used when loading effects (such as default) }; - template - struct LLShaderSetting : public LLShaderSettingBase - { - LLShaderSetting(const char* setting_name, T def) : LLShaderSettingBase(setting_name), mValue(def), mDefault(def) {} - T mValue; //The member variable mentioned above. - T mDefault; //Set via ctor. Value is inserted into the defaults LLSD list if absent from postprocesseffects.xml - LLSD getDefaultValue() { return mDefault; } //See LLShaderSettingBase::getDefaultValue - void setValue(const LLSD& value) { mValue = value; } //See LLShaderSettingBase::setValue - operator T() { return mValue; } //Typecast operator overload so this object can be handled as if it was whatever T represents. - }; - std::vector mSettings; //Contains a list of all the 'settings' this shader uses. Manually add via push_back in ctor. public: - virtual ~LLPostProcessShader() {}; - virtual bool isEnabled() = 0; //Returning false avoids bind/draw/unbind calls. If no shaders are enabled, framebuffer copying is skipped. - virtual S32 getColorChannel() = 0; //If color buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer. - virtual S32 getDepthChannel() = 0; //If depth buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer. - virtual QuadType bind() = 0; //Bind shader and textures, set up attribs. Returns the 'type' of quad to be drawn. + virtual ~IPostProcessShader() {} //virtual dtor. + virtual bool isEnabled() const = 0; //Returning false avoids bind/draw/unbind calls. If no shaders are enabled, framebuffer copying is skipped. + virtual S32 getColorChannel() const = 0; //If color buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer. + virtual S32 getDepthChannel() const = 0; //If depth buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer. + virtual void bindShader() = 0; + virtual void unbindShader() = 0; + virtual LLGLSLShader& getShader() = 0; + + virtual QuadType preDraw() = 0; //Bind shader and textures, set up attribs. Returns the 'type' of quad to be drawn. virtual bool draw(U32 pass) = 0; //returning false means finished. Used to update per-pass attributes and such. LLPostProcess will call //drawOrthoQuad when this returns true, increment pass, then call this again, and keep repeating this until false is returned. - virtual void unbind() = 0; //Unbind shader and textures. + virtual void postDraw() = 0; //Done drawing.. - LLSD getDefaults(); //Returns a full LLSD kvp list filled with default values. - void loadSettings(const LLSD& settings); //Parses the effects LLSD list and sets the member variables linked to them (via LLShaderSetting::setValue()) + virtual LLSD getDefaults() = 0; //Returns a full LLSD kvp list filled with default values. + virtual void loadSettings(const LLSD& settings) = 0; //Parses the effects LLSD list and sets the member variables linked to them (via LLShaderSetting::setValue()) + virtual void addSetting(IShaderSettingBase& setting) = 0; }; -//LLVector4 does not implicitly convert to and from LLSD, so template specilizations are necessary. -template<> LLSD LLPostProcessShader::LLShaderSetting::getDefaultValue(); -template<> void LLPostProcessShader::LLShaderSetting::setValue(const LLSD& value); - +class LLPostProcessShader; class LLPostProcess : public LLSingleton { private: diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 366f506a7..b35b2dd51 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -229,8 +229,6 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) stop_glerror(); if (mIndex < 0) return false; - gGL.flush(); - LLImageGL* gl_tex = NULL ; if (texture == NULL || !(gl_tex = texture->getGLTexture())) { @@ -258,6 +256,7 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) } if ((mCurrTexture != gl_tex->getTexName()) || forceBind) { + gGL.flush(); activate(); enable(gl_tex->getTarget()); mCurrTexture = gl_tex->getTexName(); @@ -1120,6 +1119,9 @@ void LLRender::refreshState(void) setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal); + //Singu note: Also reset glBlendFunc + blendFunc(mCurrBlendColorSFactor,mCurrBlendColorDFactor,mCurrBlendAlphaSFactor,mCurrBlendAlphaDFactor); + mDirty = false; } @@ -1458,6 +1460,7 @@ U32 LLRender::getMatrixMode() { //always return MM_TEXTURE if current matrix mode points at any texture matrix return MM_TEXTURE; } + return mMatrixMode; } @@ -1510,20 +1513,26 @@ void LLRender::pushUIMatrix() { if (mUIOffset.empty()) { - mUIOffset.push_back(new LLVector4a(0.f)); + mUIOffset.push_back(static_cast(ll_aligned_malloc_16(sizeof(LLVector4a)))); + mUIOffset.back()->splat(0.f); } else { - mUIOffset.push_back(new LLVector4a(*mUIOffset.back())); + const LLVector4a* last_entry = mUIOffset.back(); + mUIOffset.push_back(static_cast(ll_aligned_malloc_16(sizeof(LLVector4a)))); + *mUIOffset.back() = *last_entry; } if (mUIScale.empty()) { - mUIScale.push_back(new LLVector4a(1.f)); + mUIScale.push_back(static_cast(ll_aligned_malloc_16(sizeof(LLVector4a)))); + mUIScale.back()->splat(1.f); } else { - mUIScale.push_back(new LLVector4a(*mUIScale.back())); + const LLVector4a* last_entry = mUIScale.back(); + mUIScale.push_back(static_cast(ll_aligned_malloc_16(sizeof(LLVector4a)))); + *mUIScale.back() = *last_entry; } } @@ -1533,9 +1542,9 @@ void LLRender::popUIMatrix() { llerrs << "UI offset stack blown." << llendl; } - delete mUIOffset.back(); + ll_aligned_free_16(mUIOffset.back()); mUIOffset.pop_back(); - delete mUIScale.back(); + ll_aligned_free_16(mUIScale.back()); mUIScale.pop_back(); } @@ -1580,7 +1589,7 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB if (mCurrColorMask[0] != writeColorR || mCurrColorMask[1] != writeColorG || mCurrColorMask[2] != writeColorB || - mCurrColorMask[3] != writeAlpha) + mCurrColorMask[3] != writeAlpha || mDirty) { mCurrColorMask[0] = writeColorR; mCurrColorMask[1] = writeColorG; @@ -1635,7 +1644,7 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) } if (mCurrAlphaFunc != func || - mCurrAlphaFuncVal != value) + mCurrAlphaFuncVal != value || mDirty) { mCurrAlphaFunc = func; mCurrAlphaFuncVal = value; @@ -1679,7 +1688,7 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor) llassert(sfactor < BF_UNDEF); llassert(dfactor < BF_UNDEF); if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor || - mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor) + mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor || mDirty) { mCurrBlendColorSFactor = sfactor; mCurrBlendAlphaSFactor = sfactor; @@ -1704,7 +1713,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, return; } if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor || - mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor) + mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor || mDirty) { mCurrBlendColorSFactor = color_sfactor; mCurrBlendAlphaSFactor = alpha_sfactor; diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp new file mode 100644 index 000000000..967bd7560 --- /dev/null +++ b/indra/llrender/llrender2dutils.cpp @@ -0,0 +1,1620 @@ +/** + * @file llrender2dutils.cpp + * @brief GL function implementations for immediate-mode gl drawing. + * + * $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 "linden_common.h" + +// Linden library includes +#include "v2math.h" +#include "m3math.h" +#include "v4color.h" +#include "llfontgl.h" +#include "llrender.h" +#include "llrect.h" +#include "llgl.h" +#include "lltexture.h" + +// Project includes +#include "llrender2dutils.h" +#include "lluiimage.h" + + +// +// Globals +// +const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f); +/*static*/ LLVector2 LLRender2D::sGLScaleFactor(1.f, 1.f); +/*static*/ LLImageProviderInterface* LLRender2D::sImageProvider = NULL; + +// +// Functions +// + +BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom) +{ + if (x < left || right < x) return FALSE; + if (y < bottom || top < y) return FALSE; + return TRUE; +} + + +// Puts GL into 2D drawing mode by turning off lighting, setting to an +// orthographic projection, etc. +void gl_state_for_2d(S32 width, S32 height) +{ + stop_glerror(); + F32 window_width = (F32) width;//gViewerWindow->getWindowWidth(); + F32 window_height = (F32) height;//gViewerWindow->getWindowHeight(); + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.loadIdentity(); + gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadIdentity(); + stop_glerror(); +} + + +void gl_draw_x(const LLRect& rect, const LLColor4& color) +{ + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + gGL.color4fv( color.mV ); + + gGL.begin( LLRender::LINES ); + gGL.vertex2i( rect.mLeft, rect.mTop ); + gGL.vertex2i( rect.mRight, rect.mBottom ); + gGL.vertex2i( rect.mLeft, rect.mBottom ); + gGL.vertex2i( rect.mRight, rect.mTop ); + gGL.end(); +} + + +void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled) +{ + gGL.color4fv(color.mV); + gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled); +} + +void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled) +{ + gGL.pushMatrix(); + left += LLFontGL::sCurOrigin.mX; + right += LLFontGL::sCurOrigin.mX; + bottom += LLFontGL::sCurOrigin.mY; + top += LLFontGL::sCurOrigin.mY; + + gGL.loadIdentity(); + gl_rect_2d(llfloor((F32)left * LLRender2D::sGLScaleFactor.mV[VX]) - pixel_offset, + llfloor((F32)top * LLRender2D::sGLScaleFactor.mV[VY]) + pixel_offset, + llfloor((F32)right * LLRender2D::sGLScaleFactor.mV[VX]) + pixel_offset, + llfloor((F32)bottom * LLRender2D::sGLScaleFactor.mV[VY]) - pixel_offset, + filled); + gGL.popMatrix(); +} + + +void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled ) +{ + stop_glerror(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + // Counterclockwise quad will face the viewer + if( filled ) + { + gGL.begin( LLRender::QUADS ); + gGL.vertex2i(left, top); + gGL.vertex2i(left, bottom); + gGL.vertex2i(right, bottom); + gGL.vertex2i(right, top); + gGL.end(); + } + else + { + if( gGLManager.mATIOffsetVerticalLines ) + { + // Work around bug in ATI driver: vertical lines are offset by (-1,-1) + gGL.begin( LLRender::LINES ); + + // Verticals + gGL.vertex2i(left + 1, top + 1); + gGL.vertex2i(left + 1, bottom + 1); + + gGL.vertex2i(right + 1, bottom + 1); + gGL.vertex2i(right + 1, top + 1); + + // Horizontals + gGL.vertex2i(left, bottom); + gGL.vertex2i(right, bottom); + + gGL.vertex2i(left, top); + gGL.vertex2i(right, top); + gGL.end(); + } + else + { + gGL.begin( LLRender::LINE_STRIP ); + gGL.vertex2i(left, top); + gGL.vertex2i(left, bottom); + gGL.vertex2i(right, bottom); + gGL.vertex2i(right, top); + gGL.vertex2i(left, top); + gGL.end(); + } + } + stop_glerror(); +} + +void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled ) +{ + gGL.color4fv( color.mV ); + gl_rect_2d( left, top, right, bottom, filled ); +} + + +void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled ) +{ + gGL.color4fv( color.mV ); + gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled ); +} + +// Given a rectangle on the screen, draws a drop shadow _outside_ +// the right and bottom edges of it. Along the right it has width "lines" +// and along the bottom it has height "lines". +void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines) +{ + stop_glerror(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + // HACK: Overlap with the rectangle by a single pixel. + right--; + bottom++; + lines++; + + LLColor4 end_color = start_color; + end_color.mV[VALPHA] = 0.f; + + gGL.begin(LLRender::QUADS); + + // Right edge, CCW faces screen + gGL.color4fv(start_color.mV); + gGL.vertex2i(right, top-lines); + gGL.vertex2i(right, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(right+lines, bottom); + gGL.vertex2i(right+lines, top-lines); + + // Bottom edge, CCW faces screen + gGL.color4fv(start_color.mV); + gGL.vertex2i(right, bottom); + gGL.vertex2i(left+lines, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(left+lines, bottom-lines); + gGL.vertex2i(right, bottom-lines); + + // bottom left Corner + gGL.color4fv(start_color.mV); + gGL.vertex2i(left+lines, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(left, bottom); + // make the bottom left corner not sharp + gGL.vertex2i(left+1, bottom-lines+1); + gGL.vertex2i(left+lines, bottom-lines); + + // bottom right corner + gGL.color4fv(start_color.mV); + gGL.vertex2i(right, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(right, bottom-lines); + // make the rightmost corner not sharp + gGL.vertex2i(right+lines-1, bottom-lines+1); + gGL.vertex2i(right+lines, bottom); + + // top right corner + gGL.color4fv(start_color.mV); + gGL.vertex2i( right, top-lines ); + gGL.color4fv(end_color.mV); + gGL.vertex2i( right+lines, top-lines ); + // make the corner not sharp + gGL.vertex2i( right+lines-1, top-1 ); + gGL.vertex2i( right, top ); + + gGL.end(); + stop_glerror(); +} + +void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 ) +{ + // Work around bug in ATI driver: vertical lines are offset by (-1,-1) + if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines ) + { + x1++; + x2++; + y1++; + y2++; + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + gGL.begin(LLRender::LINES); + gGL.vertex2i(x1, y1); + gGL.vertex2i(x2, y2); + gGL.end(); +} + +void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color ) +{ + // Work around bug in ATI driver: vertical lines are offset by (-1,-1) + if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines ) + { + x1++; + x2++; + y1++; + y2++; + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + gGL.color4fv( color.mV ); + + gGL.begin(LLRender::LINES); + gGL.vertex2i(x1, y1); + gGL.vertex2i(x2, y2); + gGL.end(); +} + +void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled) +{ + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + gGL.color4fv(color.mV); + + if (filled) + { + gGL.begin(LLRender::TRIANGLES); + } + else + { + gGL.begin(LLRender::LINE_LOOP); + } + gGL.vertex2i(x1, y1); + gGL.vertex2i(x2, y2); + gGL.vertex2i(x3, y3); + gGL.end(); +} + +void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac) +{ + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + length = llmin((S32)(max_frac*(right - left)), length); + length = llmin((S32)(max_frac*(top - bottom)), length); + gGL.begin(LLRender::LINES); + gGL.vertex2i(left, top); + gGL.vertex2i(left + length, top); + + gGL.vertex2i(left, top); + gGL.vertex2i(left, top - length); + + gGL.vertex2i(left, bottom); + gGL.vertex2i(left + length, bottom); + + gGL.vertex2i(left, bottom); + gGL.vertex2i(left, bottom + length); + + gGL.vertex2i(right, top); + gGL.vertex2i(right - length, top); + + gGL.vertex2i(right, top); + gGL.vertex2i(right, top - length); + + gGL.vertex2i(right, bottom); + gGL.vertex2i(right - length, bottom); + + gGL.vertex2i(right, bottom); + gGL.vertex2i(right, bottom + length); + gGL.end(); +} + + +void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect ) +{ + if (NULL == image) + { + llwarns << "image == NULL; aborting function" << llendl; + return; + } + gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect ); +} + +void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) +{ + if (NULL == image) + { + llwarns << "image == NULL; aborting function" << llendl; + return; + } + gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect ); +} + +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect) +{ + if (NULL == image) + { + llwarns << "image == NULL; aborting function" << llendl; + return; + } + + // scale screen size of borders down + F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0); + F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0); + + LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction); + gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect); +} + +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect) +{ + stop_glerror(); + + if (NULL == image) + { + llwarns << "image == NULL; aborting function" << llendl; + return; + } + + // add in offset of current image to current UI translation + const LLVector3 ui_scale = LLVector3(1.f,1.f,1.f);//gGL.getUIScale(); + const LLVector3 ui_translation = LLVector3(x,y,0.f);//(gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale); + + F32 uv_width = uv_outer_rect.getWidth(); + F32 uv_height = uv_outer_rect.getHeight(); + + // shrink scaling region to be proportional to clipped image region + LLRectf uv_center_rect( + uv_outer_rect.mLeft + (center_rect.mLeft * uv_width), + uv_outer_rect.mBottom + (center_rect.mTop * uv_height), + uv_outer_rect.mLeft + (center_rect.mRight * uv_width), + uv_outer_rect.mBottom + (center_rect.mBottom * uv_height)); + + F32 image_width = image->getWidth(0); + F32 image_height = image->getHeight(0); + + S32 image_natural_width = llround(image_width * uv_width); + S32 image_natural_height = llround(image_height * uv_height); + + LLRectf draw_center_rect( uv_center_rect.mLeft * image_width, + uv_center_rect.mTop * image_height, + uv_center_rect.mRight * image_width, + uv_center_rect.mBottom * image_height); + + { // scale fixed region of image to drawn region + draw_center_rect.mRight += width - image_natural_width; + draw_center_rect.mTop += height - image_natural_height; + + F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight); + F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop); + + F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth())); + F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight())); + + F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio); + + draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]); + draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]); + draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]); + draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]); + } + + LLRectf draw_outer_rect(ui_translation.mV[VX], + ui_translation.mV[VY] + height * ui_scale.mV[VY], + ui_translation.mV[VX] + width * ui_scale.mV[VX], + ui_translation.mV[VY]); + + LLGLSUIDefault gls_ui; + + if (solid_color) + { + if (LLGLSLShader::sNoFixedFunction) + { + gSolidColorProgram.bind(); + } + else + { + gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); + gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); + } + } + + gGL.getTexUnit(0)->bind(image, true); + + gGL.color4fv(color.mV); + + const S32 NUM_VERTICES = 9 * 4; // 9 quads + LLVector2 uv[NUM_VERTICES]; + LLVector4a pos[NUM_VERTICES]; + + S32 index = 0; + + gGL.begin(LLRender::QUADS); + { + // draw bottom left + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom); + pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; + + // draw bottom middle + uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; + + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; + + // draw bottom right + uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom); + pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; + + // draw left + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; + + // draw middle + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; + + // draw right + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; + + uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + // draw top left + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop); + pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f); + index++; + + // draw top middle + uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); + index++; + + // draw top right + uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop); + pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f); + index++; + + uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); + index++; + + gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); + } + gGL.end(); + + if (solid_color) + { + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + } + else + { + gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + } + } +} + +void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) +{ + gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect ); +} + +void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) +{ + if (NULL == image) + { + llwarns << "image == NULL; aborting function" << llendl; + return; + } + + LLGLSUIDefault gls_ui; + + + gGL.getTexUnit(0)->bind(image, true); + + gGL.color4fv(color.mV); + + if (degrees == 0.f) + { + const S32 NUM_VERTICES = 4; // 9 quads + LLVector2 uv[NUM_VERTICES]; + LLVector4a pos[NUM_VERTICES]; + + gGL.begin(LLRender::QUADS); + { + LLVector3 ui_scale = LLVector3(1.f,1.f,1.f);//gGL.getUIScale(); + LLVector3 ui_translation = LLVector3(0.f,0.f,0.f); //gGL.getUITranslation(); + ui_translation.mV[VX] += x; + ui_translation.mV[VY] += y; + ui_translation.scaleVec(ui_scale); + S32 index = 0; + S32 scaled_width = llround(width * ui_scale.mV[VX]); + S32 scaled_height = llround(height * ui_scale.mV[VY]); + + uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); + pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f); + index++; + + uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop); + pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f); + index++; + + uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); + pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY], 0.f); + index++; + + uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); + pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f); + index++; + + gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); + } + gGL.end(); + } + else + { + gGL.pushMatrix(); + gGL.translatef((F32)x, (F32)y, 0.f); + + F32 offset_x = F32(width/2); + F32 offset_y = F32(height/2); + + gGL.translatef(offset_x, offset_y, 0.f); + + LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD); + + gGL.getTexUnit(0)->bind(image, true); + + gGL.color4fv(color.mV); + + gGL.begin(LLRender::QUADS); + { + LLVector3 v; + + v = LLVector3(offset_x, offset_y, 0.f) * quat; + gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); + gGL.vertex2f(v.mV[0], v.mV[1] ); + + v = LLVector3(-offset_x, offset_y, 0.f) * quat; + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); + gGL.vertex2f(v.mV[0], v.mV[1] ); + + v = LLVector3(-offset_x, -offset_y, 0.f) * quat; + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); + gGL.vertex2f(v.mV[0], v.mV[1] ); + + v = LLVector3(offset_x, -offset_y, 0.f) * quat; + gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); + gGL.vertex2f(v.mV[0], v.mV[1] ); + } + gGL.end(); + gGL.popMatrix(); + } +} + + +void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase ) +{ + phase = fmod(phase, 1.f); + + S32 shift = S32(phase * 4.f) % 4; + + // Stippled line + LLGLEnable stipple(GL_LINE_STIPPLE); + + gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]); + + gGL.flush(); + glLineWidth(2.5f); + + if (!LLGLSLShader::sNoFixedFunction) + { + glLineStipple(2, 0x3333 << shift); + } + + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv( start.mV ); + gGL.vertex3fv( end.mV ); + } + gGL.end(); + + LLRender2D::setLineWidth(1.f); +} + +void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle) +{ + if (end_angle < start_angle) + { + end_angle += F_TWO_PI; + } + + gGL.pushMatrix(); + { + gGL.translatef(center_x, center_y, 0.f); + + // Inexact, but reasonably fast. + F32 delta = (end_angle - start_angle) / steps; + F32 sin_delta = sin( delta ); + F32 cos_delta = cos( delta ); + F32 x = cosf(start_angle) * radius; + F32 y = sinf(start_angle) * radius; + + if (filled) + { + gGL.begin(LLRender::TRIANGLE_FAN); + gGL.vertex2f(0.f, 0.f); + // make sure circle is complete + steps += 1; + } + else + { + gGL.begin(LLRender::LINE_STRIP); + } + + while( steps-- ) + { + // Successive rotations + gGL.vertex2f( x, y ); + F32 x_new = x * cos_delta - y * sin_delta; + y = x * sin_delta + y * cos_delta; + x = x_new; + } + gGL.end(); + } + gGL.popMatrix(); +} + +void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled) +{ + gGL.pushMatrix(); + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.translatef(center_x, center_y, 0.f); + + // Inexact, but reasonably fast. + F32 delta = F_TWO_PI / steps; + F32 sin_delta = sin( delta ); + F32 cos_delta = cos( delta ); + F32 x = radius; + F32 y = 0.f; + + if (filled) + { + gGL.begin(LLRender::TRIANGLE_FAN); + gGL.vertex2f(0.f, 0.f); + // make sure circle is complete + steps += 1; + } + else + { + gGL.begin(LLRender::LINE_LOOP); + } + + while( steps-- ) + { + // Successive rotations + gGL.vertex2f( x, y ); + F32 x_new = x * cos_delta - y * sin_delta; + y = x * sin_delta + y * cos_delta; + x = x_new; + } + gGL.end(); + } + gGL.popMatrix(); +} + +// Renders a ring with sides (tube shape) +void gl_deep_circle( F32 radius, F32 depth, S32 steps ) +{ + F32 x = radius; + F32 y = 0.f; + F32 angle_delta = F_TWO_PI / (F32)steps; + gGL.begin( LLRender::TRIANGLE_STRIP ); + { + S32 step = steps + 1; // An extra step to close the circle. + while( step-- ) + { + gGL.vertex3f( x, y, depth ); + gGL.vertex3f( x, y, 0.f ); + + F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta); + y = x * sinf(angle_delta) + y * cosf(angle_delta); + x = x_new; + } + } + gGL.end(); +} + +void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center ) +{ + gGL.pushMatrix(); + { + gGL.translatef(0.f, 0.f, -width / 2); + if( render_center ) + { + gGL.color4fv(center_color.mV); + gGL.diffuseColor4fv(center_color.mV); + gl_deep_circle( radius, width, steps ); + } + else + { + gGL.diffuseColor4fv(side_color.mV); + gl_washer_2d(radius, radius - width, steps, side_color, side_color); + gGL.translatef(0.f, 0.f, width); + gl_washer_2d(radius - width, radius, steps, side_color, side_color); + } + } + gGL.popMatrix(); +} + +// Draw gray and white checkerboard with black border +void gl_rect_2d_checkerboard(const LLRect& parent_screen_rect, const LLRect& rect, GLfloat alpha) +{ + //Already reffed in LLImageList via uuid_ui_image_map_t mUIImages. Don't use LLPointer here! + static LLUIImage* checkboard_image = LLRender2D::getUIImage("checkerboard.tga"); + static F32 image_width = checkboard_image->getWidth(); + static F32 image_height = checkboard_image->getHeight(); + + F32 scale_x = rect.getWidth() / image_width; + F32 scale_y = rect.getHeight() / image_height; + F32 offs_x = (parent_screen_rect.mLeft + rect.mLeft) / image_width; + F32 offs_y = (parent_screen_rect.mBottom + rect.mBottom) / image_height; + LLRectf uv_rect(offs_x,offs_y+scale_y,offs_x+scale_x,offs_y); + + LLColor4 color=UI_VERTEX_COLOR; + color.mV[VALPHA] = alpha; + gl_draw_scaled_image(rect.mLeft,rect.mBottom,rect.getWidth(),rect.getHeight(),checkboard_image->getImage(), color, uv_rect); + + gGL.flush(); +} + + +// Draws the area between two concentric circles, like +// a doughnut or washer. +void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color) +{ + const F32 DELTA = F_TWO_PI / steps; + const F32 SIN_DELTA = sin( DELTA ); + const F32 COS_DELTA = cos( DELTA ); + + F32 x1 = outer_radius; + F32 y1 = 0.f; + F32 x2 = inner_radius; + F32 y2 = 0.f; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + gGL.begin( LLRender::TRIANGLE_STRIP ); + { + steps += 1; // An extra step to close the circle. + while( steps-- ) + { + gGL.color4fv(outer_color.mV); + gGL.vertex2f( x1, y1 ); + gGL.color4fv(inner_color.mV); + gGL.vertex2f( x2, y2 ); + + F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; + y1 = x1 * SIN_DELTA + y1 * COS_DELTA; + x1 = x1_new; + + F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; + y2 = x2 * SIN_DELTA + y2 * COS_DELTA; + x2 = x2_new; + } + } + gGL.end(); +} + +// Draws the area between two concentric circles, like +// a doughnut or washer. +void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color) +{ + const F32 DELTA = (end_radians - start_radians) / steps; + const F32 SIN_DELTA = sin( DELTA ); + const F32 COS_DELTA = cos( DELTA ); + + F32 x1 = outer_radius * cos( start_radians ); + F32 y1 = outer_radius * sin( start_radians ); + F32 x2 = inner_radius * cos( start_radians ); + F32 y2 = inner_radius * sin( start_radians ); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.begin( LLRender::TRIANGLE_STRIP ); + { + steps += 1; // An extra step to close the circle. + while( steps-- ) + { + gGL.color4fv(outer_color.mV); + gGL.vertex2f( x1, y1 ); + gGL.color4fv(inner_color.mV); + gGL.vertex2f( x2, y2 ); + + F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; + y1 = x1 * SIN_DELTA + y1 * COS_DELTA; + x1 = x1_new; + + F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; + y2 = x2 * SIN_DELTA + y2 * COS_DELTA; + x2 = x2_new; + } + } + gGL.end(); +} + +// Draws spokes around a circle. +void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color) +{ + const F32 DELTA = F_TWO_PI / count; + const F32 HALF_DELTA = DELTA * 0.5f; + const F32 SIN_DELTA = sin( DELTA ); + const F32 COS_DELTA = cos( DELTA ); + + F32 x1 = outer_radius * cos( HALF_DELTA ); + F32 y1 = outer_radius * sin( HALF_DELTA ); + F32 x2 = inner_radius * cos( HALF_DELTA ); + F32 y2 = inner_radius * sin( HALF_DELTA ); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + gGL.begin( LLRender::LINES ); + { + while( count-- ) + { + gGL.color4fv(outer_color.mV); + gGL.vertex2f( x1, y1 ); + gGL.color4fv(inner_color.mV); + gGL.vertex2f( x2, y2 ); + + F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; + y1 = x1 * SIN_DELTA + y1 * COS_DELTA; + x1 = x1_new; + + F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; + y2 = x2 * SIN_DELTA + y2 * COS_DELTA; + x2 = x2_new; + } + } + gGL.end(); +} + +void gl_rect_2d_simple_tex( S32 width, S32 height ) +{ + gGL.begin( LLRender::QUADS ); + + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(width, height); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(0, height); + + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(0, 0); + + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(width, 0); + + gGL.end(); +} + +void gl_rect_2d_simple( S32 width, S32 height ) +{ + gGL.begin( LLRender::QUADS ); + gGL.vertex2i(width, height); + gGL.vertex2i(0, height); + gGL.vertex2i(0, 0); + gGL.vertex2i(width, 0); + gGL.end(); +} + +void gl_segmented_rect_2d_tex(const S32 left, + const S32 top, + const S32 right, + const S32 bottom, + const S32 texture_width, + const S32 texture_height, + const S32 border_size, + const U32 edges) +{ + S32 width = llabs(right - left); + S32 height = llabs(top - bottom); + + gGL.pushMatrix(); + + gGL.translatef((F32)left, (F32)bottom, 0.f); + LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height); + + if (border_uv_scale.mV[VX] > 0.5f) + { + border_uv_scale *= 0.5f / border_uv_scale.mV[VX]; + } + if (border_uv_scale.mV[VY] > 0.5f) + { + border_uv_scale *= 0.5f / border_uv_scale.mV[VY]; + } + + F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f); + LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; + LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; + LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; + LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; + LLVector2 width_vec((F32)width, 0.f); + LLVector2 height_vec(0.f, (F32)height); + + gGL.begin(LLRender::QUADS); + { + // draw bottom left + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(0.f, 0.f); + + gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv(border_width_left.mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + border_height_bottom).mV); + + gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); + gGL.vertex2fv(border_height_bottom.mV); + + // draw bottom middle + gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv(border_width_left.mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv((width_vec - border_width_right).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + border_height_bottom).mV); + + // draw bottom right + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv((width_vec - border_width_right).mV); + + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2fv(width_vec.mV); + + gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec + border_height_bottom).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); + + // draw left + gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); + gGL.vertex2fv(border_height_bottom.mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + border_height_bottom).mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); + + gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((height_vec - border_height_top).mV); + + // draw middle + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + border_height_bottom).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); + + // draw right + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); + + gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec + border_height_bottom).mV); + + gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + + // draw top left + gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((height_vec - border_height_top).mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((border_width_left + height_vec).mV); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2fv((height_vec).mV); + + // draw top middle + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((border_width_left + height_vec).mV); + + // draw top right + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + + gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); + + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2fv((width_vec + height_vec).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); + } + gGL.end(); + + gGL.popMatrix(); +} + +//FIXME: rewrite to use scissor? +void gl_segmented_rect_2d_fragment_tex(const S32 left, + const S32 top, + const S32 right, + const S32 bottom, + const S32 texture_width, + const S32 texture_height, + const S32 border_size, + const F32 start_fragment, + const F32 end_fragment, + const U32 edges) +{ + S32 width = llabs(right - left); + S32 height = llabs(top - bottom); + + gGL.pushMatrix(); + + gGL.translatef((F32)left, (F32)bottom, 0.f); + LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height); + + if (border_uv_scale.mV[VX] > 0.5f) + { + border_uv_scale *= 0.5f / border_uv_scale.mV[VX]; + } + if (border_uv_scale.mV[VY] > 0.5f) + { + border_uv_scale *= 0.5f / border_uv_scale.mV[VY]; + } + + F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f); + LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; + LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; + LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; + LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; + LLVector2 width_vec((F32)width, 0.f); + LLVector2 height_vec(0.f, (F32)height); + + F32 middle_start = border_scale / (F32)width; + F32 middle_end = 1.f - middle_start; + + F32 u_min; + F32 u_max; + LLVector2 x_min; + LLVector2 x_max; + + gGL.begin(LLRender::QUADS); + { + if (start_fragment < middle_start) + { + u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX]; + u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX]; + x_min = (start_fragment / middle_start) * border_width_left; + x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left; + + // draw bottom left + gGL.texCoord2f(u_min, 0.f); + gGL.vertex2fv(x_min.mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv(x_max.mV); + + gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); + + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); + + // draw left + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); + + gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); + + gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); + + // draw top left + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); + + gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + + gGL.texCoord2f(u_max, 1.f); + gGL.vertex2fv((x_max + height_vec).mV); + + gGL.texCoord2f(u_min, 1.f); + gGL.vertex2fv((x_min + height_vec).mV); + } + + if (end_fragment > middle_start || start_fragment < middle_end) + { + x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec; + x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec; + + // draw bottom middle + gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv(x_min.mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv((x_max).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); + + // draw middle + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); + + // draw top middle + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((x_max + height_vec).mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((x_min + height_vec).mV); + } + + if (end_fragment > middle_end) + { + u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX]; + u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]; + x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right); + x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right); + + // draw bottom right + gGL.texCoord2f(u_min, 0.f); + gGL.vertex2fv((x_min).mV); + + gGL.texCoord2f(u_max, 0.f); + gGL.vertex2fv(x_max.mV); + + gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); + + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); + + // draw right + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); + + gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); + + gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); + + // draw top right + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); + + gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + + gGL.texCoord2f(u_max, 1.f); + gGL.vertex2fv((x_max + height_vec).mV); + + gGL.texCoord2f(u_min, 1.f); + gGL.vertex2fv((x_min + height_vec).mV); + } + } + gGL.end(); + + gGL.popMatrix(); +} + +void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, + const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, + const U32 edges) +{ + LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero; + LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero; + + LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero; + LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero; + + + gGL.begin(LLRender::QUADS); + { + // draw bottom left + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3f(0.f, 0.f, 0.f); + + gGL.texCoord2f(border_scale.mV[VX], 0.f); + gGL.vertex3fv(left_border_width.mV); + + gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + bottom_border_height).mV); + + gGL.texCoord2f(0.f, border_scale.mV[VY]); + gGL.vertex3fv(bottom_border_height.mV); + + // draw bottom middle + gGL.texCoord2f(border_scale.mV[VX], 0.f); + gGL.vertex3fv(left_border_width.mV); + + gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f); + gGL.vertex3fv((width_vec - right_border_width).mV); + + gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); + + gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + bottom_border_height).mV); + + // draw bottom right + gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f); + gGL.vertex3fv((width_vec - right_border_width).mV); + + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3fv(width_vec.mV); + + gGL.texCoord2f(1.f, border_scale.mV[VY]); + gGL.vertex3fv((width_vec + bottom_border_height).mV); + + gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); + + // draw left + gGL.texCoord2f(0.f, border_scale.mV[VY]); + gGL.vertex3fv(bottom_border_height.mV); + + gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + bottom_border_height).mV); + + gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); + + gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]); + gGL.vertex3fv((height_vec - top_border_height).mV); + + // draw middle + gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + bottom_border_height).mV); + + gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); + + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); + + gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); + + // draw right + gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); + + gGL.texCoord2f(1.f, border_scale.mV[VY]); + gGL.vertex3fv((width_vec + bottom_border_height).mV); + + gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec + height_vec - top_border_height).mV); + + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); + + // draw top left + gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]); + gGL.vertex3fv((height_vec - top_border_height).mV); + + gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); + + gGL.texCoord2f(border_scale.mV[VX], 1.f); + gGL.vertex3fv((left_border_width + height_vec).mV); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3fv((height_vec).mV); + + // draw top middle + gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); + + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); + + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f); + gGL.vertex3fv((width_vec - right_border_width + height_vec).mV); + + gGL.texCoord2f(border_scale.mV[VX], 1.f); + gGL.vertex3fv((left_border_width + height_vec).mV); + + // draw top right + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); + + gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec + height_vec - top_border_height).mV); + + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3fv((width_vec + height_vec).mV); + + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f); + gGL.vertex3fv((width_vec - right_border_width + height_vec).mV); + } + gGL.end(); + +} + +void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec) +{ + gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP); +} + +// static +void LLRender2D::initClass(LLImageProviderInterface* image_provider, + const LLVector2* scale_factor) +{ + sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor; + sImageProvider = image_provider; +} + +// static +void LLRender2D::cleanupClass() +{ + if(sImageProvider) + { + sImageProvider->cleanUp(); + } +} + + +//static +void LLRender2D::translate(F32 x, F32 y, F32 z) +{ + gGL.translatef(x,y,z); + LLFontGL::sCurOrigin.mX += (S32) x; + LLFontGL::sCurOrigin.mY += (S32) y; + LLFontGL::sCurDepth += z; +} + +//static +void LLRender2D::pushMatrix() +{ + gGL.pushMatrix(); + LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth)); +} + +//static +void LLRender2D::popMatrix() +{ + gGL.popMatrix(); + LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first; + LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second; + LLFontGL::sOriginStack.pop_back(); +} + +//static +void LLRender2D::loadIdentity() +{ + gGL.loadIdentity(); + LLFontGL::sCurOrigin.mX = 0; + LLFontGL::sCurOrigin.mY = 0; + LLFontGL::sCurDepth = 0.f; +} + +//static +void LLRender2D::setScaleFactor(const LLVector2 &scale_factor) +{ + sGLScaleFactor = scale_factor; +} + +//static +void LLRender2D::setLineWidth(F32 width) +{ + gGL.flush(); + glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f)); +} + +//static +LLPointer LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority) +{ + if (sImageProvider) + { + return sImageProvider->getUIImageByID(image_id, priority); + } + else + { + return NULL; + } +} + +//static +LLPointer LLRender2D::getUIImage(const std::string& name, S32 priority) +{ + if (!name.empty() && sImageProvider) + return sImageProvider->getUIImage(name, priority); + else + return NULL; +} \ No newline at end of file diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h new file mode 100644 index 000000000..0323af6a2 --- /dev/null +++ b/indra/llrender/llrender2dutils.h @@ -0,0 +1,164 @@ +/** + * @file llrender2dutils.h + * @brief GL function declarations for immediate-mode gl drawing. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// All immediate-mode gl drawing should happen here. + + +#ifndef LL_RENDER2DUTILS_H +#define LL_RENDER2DUTILS_H + +#include "llpointer.h" // LLPointer<> +#include "llrect.h" +#include "llglslshader.h" + +class LLColor4; +class LLVector3; +class LLVector2; +class LLUIImage; +class LLUUID; + +extern const LLColor4 UI_VERTEX_COLOR; + +BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom); +void gl_state_for_2d(S32 width, S32 height); + +void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2); +void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color ); +void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled); +void gl_rect_2d_simple( S32 width, S32 height ); + +void gl_draw_x(const LLRect& rect, const LLColor4& color); + +void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE ); +void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE ); +void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE ); +void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE ); +void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE ); +void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE ); +void gl_rect_2d_checkerboard(const LLRect& parent_screen_rect, const LLRect& rect, GLfloat alpha = 1.0f); + +void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines); + +void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled); +void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle); +void gl_deep_circle( F32 radius, F32 depth ); +void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center ); +void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac); +void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); +void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); +void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color); +void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); + +void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); + +void gl_rect_2d_simple_tex( S32 width, S32 height ); + +// segmented rectangles + +/* + TL |______TOP_________| TR + /| |\ + _/_|__________________|_\_ + L| | MIDDLE | |R + _|_|__________________|_|_ + \ | BOTTOM | / + BL\|__________________|/ BR + | | +*/ + +typedef enum e_rounded_edge +{ + ROUNDED_RECT_LEFT = 0x1, + ROUNDED_RECT_TOP = 0x2, + ROUNDED_RECT_RIGHT = 0x4, + ROUNDED_RECT_BOTTOM = 0x8, + ROUNDED_RECT_ALL = 0xf +}ERoundedEdge; + + +void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL); +void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL); +void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL); +void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec); + +inline void gl_rect_2d( const LLRect& rect, BOOL filled ) +{ + gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled ); +} + +inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled) +{ + gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled ); +} + +class LLImageProviderInterface; + +class LLRender2D +{ + LOG_CLASS(LLRender2D); +public: + static void initClass(LLImageProviderInterface* image_provider, + const LLVector2* scale_factor); + static void cleanupClass(); + + static void pushMatrix(); + static void popMatrix(); + static void loadIdentity(); + static void translate(F32 x, F32 y, F32 z = 0.0f); + + static void setLineWidth(F32 width); + static void setScaleFactor(const LLVector2& scale_factor); + + static LLPointer getUIImageByID(const LLUUID& image_id, S32 priority = 0); + static LLPointer getUIImage(const std::string& name, S32 priority = 0); + + static LLVector2 sGLScaleFactor; +private: + static LLImageProviderInterface* sImageProvider; +}; + +class LLImageProviderInterface +{ +protected: + LLImageProviderInterface() {}; + virtual ~LLImageProviderInterface() {}; +public: + virtual LLPointer getUIImage(const std::string& name, S32 priority) = 0; + virtual LLPointer getUIImageByID(const LLUUID& id, S32 priority) = 0; + virtual void cleanUp() = 0; +}; + + +extern LLGLSLShader gSolidColorProgram; +extern LLGLSLShader gUIProgram; + +#endif // LL_RENDER2DUTILS_H + diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index d770e67c9..aa6278417 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -2,31 +2,25 @@ * @file llrendertarget.cpp * @brief LLRenderTarget implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -813,7 +807,6 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); } - check_framebuffer_status(); } stop_glerror(); diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index d9a529ff0..14eea5a4a 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -2,31 +2,25 @@ * @file llrendertarget.h * @brief Off screen render target abstraction. Loose wrapper for GL_EXT_framebuffer_objects. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 234d2e141..65a7fda5e 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -25,6 +25,7 @@ */ #include "linden_common.h" +#include //First, because glh_linear #defines equivalent.. which boost uses internally #include "llshadermgr.h" @@ -53,6 +54,17 @@ LLShaderMgr * LLShaderMgr::sInstance = NULL; LLShaderMgr::LLShaderMgr() { + { + const std::string dumpdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"shader_dump")+gDirUtilp->getDirDelimiter(); + try + { + boost::filesystem::remove_all(dumpdir); + } + catch(const boost::filesystem::filesystem_error& e) + { + llinfos << "boost::filesystem::remove_all(\""+dumpdir+"\") failed: '" + e.code().message() + "'" << llendl; + } + } } @@ -660,6 +672,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade } } + static const LLCachedControl SHPackDeferredNormals("SHPackDeferredNormals",false); + if(SHPackDeferredNormals) + text[count++] = strdup("#define PACK_NORMALS\n"); + //copy preprocessor definitions into buffer for (std::map::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter) { @@ -1116,7 +1132,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("ssao_max_radius"); mReservedUniforms.push_back("ssao_factor"); mReservedUniforms.push_back("ssao_factor_inv"); - mReservedUniforms.push_back("ssao_effect_mat"); + mReservedUniforms.push_back("ssao_effect"); mReservedUniforms.push_back("screen_res"); mReservedUniforms.push_back("near_clip"); mReservedUniforms.push_back("shadow_offset"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index fc9242f7c..7e30e75f0 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -120,7 +120,7 @@ public: DEFERRED_SSAO_MAX_RADIUS, DEFERRED_SSAO_FACTOR, DEFERRED_SSAO_FACTOR_INV, - DEFERRED_SSAO_EFFECT_MAT, + DEFERRED_SSAO_EFFECT, DEFERRED_SCREEN_RES, DEFERRED_NEAR_CLIP, DEFERRED_SHADOW_OFFSET, diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h index 6a08c5b2a..093bac20d 100644 --- a/indra/llrender/lltexture.h +++ b/indra/llrender/lltexture.h @@ -7,33 +7,26 @@ * code, to define an interface for a multiple rendering API abstraction of the UI * rendering, and to abstract out direct rendering calls in a way that is cleaner and easier to maintain. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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_TEXTURE_H @@ -45,10 +38,9 @@ class LLTexUnit ; class LLFontGL ; // -//this is an abstract class as the parent for the class LLViewerTexture -//through the following virtual functions, the class LLViewerTexture can be reached from /llrender. +//this is an abstract class as the parent for the class LLGLTexture // -class LLTexture : public LLRefCount +class LLTexture : public virtual LLRefCount { friend class LLTexUnit ; friend class LLFontGL ; @@ -60,7 +52,7 @@ public: LLTexture(){} // - //interfaces to access LLViewerTexture + //interfaces to access LLGLTexture // virtual S8 getType() const = 0 ; virtual void setKnownDrawSize(S32 width, S32 height) = 0 ; diff --git a/indra/llui/lluiimage.cpp b/indra/llrender/lluiimage.cpp similarity index 99% rename from indra/llui/lluiimage.cpp rename to indra/llrender/lluiimage.cpp index 4855e8127..da122425c 100644 --- a/indra/llui/lluiimage.cpp +++ b/indra/llrender/lluiimage.cpp @@ -31,7 +31,7 @@ // Project includes #include "lluiimage.h" -#include "llui.h" +#include "llrender2dutils.h" LLUIImage::LLUIImage(const std::string& name, LLPointer image) : mName(name), diff --git a/indra/llui/lluiimage.h b/indra/llrender/lluiimage.h similarity index 100% rename from indra/llui/lluiimage.h rename to indra/llrender/lluiimage.h diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index bc4c201d9..d10a9c6bb 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -2083,6 +2083,16 @@ void LLVertexBuffer::flush() } } +// bind for transform feedback (quick 'n dirty) +void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count) +{ +#ifdef GL_TRANSFORM_FEEDBACK_BUFFER + U32 offset = mOffsets[type] + sTypeSize[type]*index; + U32 size= (sTypeSize[type]*count); + glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size); +#endif +} + // Set for rendering void LLVertexBuffer::setBuffer(U32 data_mask) { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 469acfcef..3762d956b 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -202,16 +202,18 @@ protected: void destroyGLIndices(); void updateNumVerts(S32 nverts); void updateNumIndices(S32 nindices); - bool useVBOs() const; void unmapBuffer(); public: + LLVertexBuffer(U32 typemask, S32 usage); // map for data access volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range); volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range); + void bindForFeedback(U32 channel, U32 type, U32 index, U32 count); + // set for rendering virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 void flush(); //flush pending data to GL memory @@ -240,6 +242,7 @@ public: bool getClothWeightStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool useVBOs() const; bool isEmpty() const { return mEmpty; } bool isLocked() const { return mVertexLocked || mIndexLocked; } S32 getNumVerts() const { return mNumVerts; } diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 5049da27a..6aa14e8d6 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -63,7 +63,6 @@ set(llui_SOURCE_FILES llspinctrl.cpp llstyle.cpp lltabcontainer.cpp - lltabcontainervertical.cpp lltextbox.cpp lltexteditor.cpp lltextparser.cpp @@ -72,7 +71,6 @@ set(llui_SOURCE_FILES lluicolor.cpp lluictrl.cpp lluictrlfactory.cpp - lluiimage.cpp lluistring.cpp llundo.cpp llviewborder.cpp @@ -97,7 +95,6 @@ set(llui_HEADER_FILES llfloater.h llfocusmgr.h llfunctorregistry.h - llhandle.h llhtmlhelp.h lliconctrl.h llkeywords.h @@ -129,7 +126,6 @@ set(llui_HEADER_FILES llspinctrl.h llstyle.h lltabcontainer.h - lltabcontainervertical.h lltextbox.h lltexteditor.h lltextparser.h @@ -140,7 +136,6 @@ set(llui_HEADER_FILES lluifwd.h llui.h lluicolor.h - lluiimage.h lluistring.h lluixmltags.h llundo.h diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index b1b8f42e4..6a03f5687 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -603,7 +603,7 @@ void LLComboBox::showList() LLCoordWindow window_size; getWindow()->getSize(&window_size); //HACK: shouldn't have to know about scale here - mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 ); + mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::getScaleFactor().mV[VY]) - 50 ); // Make sure that we can see the whole list LLRect root_view_local; @@ -615,7 +615,7 @@ void LLComboBox::showList() S32 min_width = getRect().getWidth(); S32 max_width = llmax(min_width, MAX_COMBO_WIDTH); // make sure we have up to date content width metrics - mList->calcColumnWidths(); + mList->updateColumnWidths(); S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width); if (mListPosition == BELOW) @@ -707,7 +707,7 @@ void LLComboBox::hideList() mButton->setToggleState(FALSE); mList->setVisible(FALSE); - mList->highlightNthItem(-1); + mList->mouseOverHighlightNthItem(-1); setUseBoundingRect(FALSE); if( gFocusMgr.getTopCtrl() == this ) @@ -731,7 +731,7 @@ void LLComboBox::onButtonDown(void *userdata) if (last_selected_item) { // highlight the original selection before potentially selecting a new item - self->mList->highlightNthItem(self->mList->getItemIndex(last_selected_item)); + self->mList->mouseOverHighlightNthItem(self->mList->getItemIndex(last_selected_item)); } if( self->mPrearrangeCallback ) @@ -839,7 +839,7 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask) if (last_selected_item) { // highlight the original selection before potentially selecting a new item - mList->highlightNthItem(mList->getItemIndex(last_selected_item)); + mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item)); } result = mList->handleKeyHere(key, mask); @@ -873,7 +873,7 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char) if (last_selected_item) { // highlight the original selection before potentially selecting a new item - mList->highlightNthItem(mList->getItemIndex(last_selected_item)); + mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item)); } result = mList->handleUnicodeCharHere(uni_char); if (mList->getLastSelectedItem() != last_selected_item) diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 114cabc0c..1cbb52dab 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -57,6 +57,7 @@ #include "lltabcontainer.h" #include "v2math.h" #include "llfasttimer.h" +#include "airecursive.h" const S32 MINIMIZED_WIDTH = 160; const S32 CLOSE_BOX_FROM_TOP = 1; @@ -148,7 +149,6 @@ LLFloater::LLFloater() : mResizeHandle[i] = NULL; } mDragHandle = NULL; - mHandle.bind(this); mNotificationContext = new LLFloaterNotificationContext(getHandle()); } @@ -222,7 +222,6 @@ void LLFloater::initFloater(const std::string& title, BOOL resizable, S32 min_width, S32 min_height, BOOL drag_on_left, BOOL minimizable, BOOL close_btn) { - mHandle.bind(this); mNotificationContext = new LLFloaterNotificationContext(getHandle()); // Init function can be called more than once, so clear out old data. @@ -422,7 +421,7 @@ void LLFloater::initFloater(const std::string& title, setVisible(FALSE); // add self to handle->floater map - sFloaterMap[mHandle] = this; + sFloaterMap[getHandle()] = this; if (!getParent()) { @@ -483,7 +482,7 @@ LLFloater::~LLFloater() // correct, non-minimized positions. setMinimized( FALSE ); - sFloaterMap.erase(mHandle); + sFloaterMap.erase(getHandle()); delete mDragHandle; for (S32 i = 0; i < 4; i++) @@ -1990,9 +1989,16 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF return new_rect; } - void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) { + // Stop recursive call sequence + // LLFloaterView::bringToFront calls + // LLFloater::setFocus calls + // LLFloater::setFrontmost calls this again. + static bool recursive; + if (recursive) { return; } + AIRecursive enter(recursive); + // *TODO: make this respect floater's mAutoFocus value, instead of // using parameter if (child->getHost()) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index e710fa6dc..1cfb4635a 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -227,7 +227,7 @@ public: void clearSnapTarget() { mSnappedTo.markDead(); } LLHandle getSnapTarget() const { return mSnappedTo; } - LLHandle getHandle() const { return mHandle; } + LLHandle getHandle() const { return getDerivedHandle(); } // Return a closeable floater, if any, given the current focus. static LLFloater* getClosableFloaterFromFocus(); @@ -331,7 +331,6 @@ private: S32 mPreviousMinimizedLeft; LLFloaterNotificationContext* mNotificationContext; - LLRootHandle mHandle; }; ///////////////////////////////////////////////////////////// diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h deleted file mode 100644 index 8c000eee4..000000000 --- a/indra/llui/llhandle.h +++ /dev/null @@ -1,164 +0,0 @@ -/** -* @file llhandle.h -* @brief "Handle" to an object (usually a floater) whose lifetime you don't -* control. -* -* $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 LLHANDLE_H -#define LLHANDLE_H - -#include "llpointer.h" - -template -class LLTombStone : public LLRefCount -{ -public: - LLTombStone(T* target = NULL) : mTarget(target) {} - - void setTarget(T* target) { mTarget = target; } - T* getTarget() const { return mTarget; } -private: - T* mTarget; -}; - -// LLHandles are used to refer to objects whose lifetime you do not control or influence. -// Calling get() on a handle will return a pointer to the referenced object or NULL, -// if the object no longer exists. Note that during the lifetime of the returned pointer, -// you are assuming that the object will not be deleted by any action you perform, -// or any other thread, as normal when using pointers, so avoid using that pointer outside of -// the local code block. -// -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 - -template -class LLHandle -{ -public: - LLHandle() : mTombStone(getDefaultTombStone()) {} - const LLHandle& operator =(const LLHandle& other) - { - mTombStone = other.mTombStone; - return *this; - } - - bool isDead() const - { - return mTombStone->getTarget() == NULL; - } - - void markDead() - { - mTombStone = getDefaultTombStone(); - } - - T* get() const - { - return mTombStone->getTarget(); - } - - friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone == rhs.mTombStone; - } - friend bool operator!= (const LLHandle& lhs, const LLHandle& rhs) - { - return !(lhs == rhs); - } - friend bool operator< (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone < rhs.mTombStone; - } - friend bool operator> (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone > rhs.mTombStone; - } - -protected: - LLPointer > mTombStone; - -private: - static LLPointer >& getDefaultTombStone() - { - static LLPointer > sDefaultTombStone = new LLTombStone; - return sDefaultTombStone; - } -}; - -template -class LLRootHandle : public LLHandle -{ -public: - LLRootHandle(T* object) { bind(object); } - LLRootHandle() {}; - ~LLRootHandle() { unbind(); } - - // this is redundant, since a LLRootHandle *is* an LLHandle - LLHandle getHandle() { return LLHandle(*this); } - - void bind(T* object) - { - // unbind existing tombstone - if (LLHandle::mTombStone.notNull()) - { - if (LLHandle::mTombStone->getTarget() == object) return; - LLHandle::mTombStone->setTarget(NULL); - } - // tombstone reference counted, so no paired delete - LLHandle::mTombStone = new LLTombStone(object); - } - - void unbind() - { - LLHandle::mTombStone->setTarget(NULL); - } - - //don't allow copying of root handles, since there should only be one -private: - LLRootHandle(const LLRootHandle& other) {}; -}; - -// Use this as a mixin for simple classes that need handles and when you don't -// want handles at multiple points of the inheritance hierarchy -template -class LLHandleProvider -{ -protected: - typedef LLHandle handle_type_t; - LLHandleProvider() - { - // provided here to enforce T deriving from LLHandleProvider - } - - LLHandle getHandle() - { - // perform lazy binding to avoid small tombstone allocations for handle - // providers whose handles are never referenced - mHandle.bind(static_cast(this)); - return mHandle; - } - -private: - LLRootHandle mHandle; -}; - -#endif diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 926ae374d..7ba0bf599 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1973,8 +1973,8 @@ void LLLineEditor::draw() LLRect screen_pos = calcScreenRect(); LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - UI_LINEEDITOR_V_PAD ); - ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]); - ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]); + ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]); + ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]); getWindow()->setLanguageTextInput( ime_pos ); } } @@ -2959,7 +2959,7 @@ void LLLineEditor::markAsPreedit(S32 position, S32 length) S32 LLLineEditor::getPreeditFontSize() const { - return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]); + return llround(mGLFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]); } void LLLineEditor::setReplaceNewlinesWithSpaces(BOOL replace) diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp index 684130121..f3a526fae 100644 --- a/indra/llui/lllocalcliprect.cpp +++ b/indra/llui/lllocalcliprect.cpp @@ -88,10 +88,10 @@ void LLScreenClipRect::updateScissorRegion() LLRect rect = sClipRectStack.top(); stop_glerror(); S32 x,y,w,h; - x = llfloor(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]); - y = llfloor(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]); - w = llmax(0, llceil(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX])) + 1; - h = llmax(0, llceil(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY])) + 1; + x = llfloor(rect.mLeft * LLUI::getScaleFactor().mV[VX]); + y = llfloor(rect.mBottom * LLUI::getScaleFactor().mV[VY]); + w = llmax(0, llceil(rect.getWidth() * LLUI::getScaleFactor().mV[VX])) + 1; + h = llmax(0, llceil(rect.getHeight() * LLUI::getScaleFactor().mV[VY])) + 1; glScissor( x,y,w,h ); stop_glerror(); } diff --git a/indra/llui/lllocalcliprect.h b/indra/llui/lllocalcliprect.h index ebd6c1858..eeeaf2adb 100644 --- a/indra/llui/lllocalcliprect.h +++ b/indra/llui/lllocalcliprect.h @@ -26,7 +26,6 @@ #define LLLOCALCLIPRECT_H #include "llgl.h" -#include "lllocalcliprect.h" #include "llrect.h" // can't forward declare, it's templated #include diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 136dcf524..588a36a0f 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -80,7 +80,6 @@ void LLPanel::init() mDefaultBtn = NULL; setIsChrome(FALSE); //is this a decorator to a live window or a form? - mPanelHandle.bind(this); setTabStop(FALSE); mVisibleSignal = NULL; } @@ -766,19 +765,6 @@ void LLPanel::childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl* } } -void LLPanel::childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void *userdata ) -{ - LLUICtrl* child = getChild(id, true); - if (child) - { - child->setDoubleClickCallback(cb); - if (userdata) - { - child->setCallbackUserData(userdata); - } - } -} - void LLPanel::childSetValidate(const std::string& id, BOOL (*cb)(LLUICtrl*, void*)) { LLUICtrl* child = getChild(id, true); @@ -963,7 +949,7 @@ void LLPanel::childSetWrappedText(const std::string& id, const std::string& text } } -void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void* value) +void LLPanel::childSetAction(const std::string& id, boost::function function, void* value) { LLButton* button = getChild(id); if (button) @@ -972,6 +958,15 @@ void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void } } +void LLPanel::childSetAction(const std::string& id, const commit_signal_t::slot_type& function) +{ + LLButton* button = getChild(id); + if (button) + { + button->setClickedCallback(function); + } +} + void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*), void* value) { LLTextBox* textbox = getChild(id); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index ad721cbf5..330378da0 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -57,7 +57,7 @@ const BOOL BORDER_NO = FALSE; * With or without border, * Can contain LLUICtrls. */ -class LLPanel : public LLUICtrl, public boost::signals2::trackable +class LLPanel : public LLUICtrl { public: @@ -136,7 +136,7 @@ public: void setCtrlsEnabled(BOOL b); - LLHandle getHandle() const { return mPanelHandle; } + LLHandle getHandle() const { return getDerivedHandle(); } const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; } @@ -170,7 +170,6 @@ public: BOOL childHasFocus(const std::string& id); void childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void* userdata = NULL ); - void childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void* userdata = NULL ); void childSetValidate(const std::string& id, BOOL (*cb)(LLUICtrl*, void*) ); void childSetUserData(const std::string& id, void* userdata); @@ -211,7 +210,8 @@ public: void childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) ); // LLButton - void childSetAction(const std::string& id, void(*function)(void*), void* value); + void childSetAction(const std::string& id, boost::function function, void* value); + void childSetAction(const std::string& id, const commit_signal_t::slot_type& function); void childSetActionTextbox(const std::string& id, void(*function)(void*), void* value = NULL); void childSetControlName(const std::string& id, const std::string& control_name); @@ -246,7 +246,6 @@ private: LLViewBorder* mBorder; LLButton* mDefaultBtn; std::string mLabel; - LLRootHandle mPanelHandle; typedef std::map ui_string_map_t; ui_string_map_t mUIStrings; diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 5c715d3ff..b193c22b2 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -316,7 +316,8 @@ void LLRadioGroup::setValue( const LLSD& value ) } else { - llwarns << "LLRadioGroup::setValue: value not found: " << value_name << llendl; + llwarns << "LLRadioGroup::setValue: radio_item with name=\"" << value_name << "\" not found, radio_group values are set by radio_item name not value. Falling back on LLUICtrl::setValue." << llendl; + LLUICtrl::setValue(value); } } } diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp index a0a9b36b9..bd99e6c73 100644 --- a/indra/llui/llresizebar.cpp +++ b/indra/llui/llresizebar.cpp @@ -54,6 +54,7 @@ LLResizeBar::LLResizeBar( const std::string& name, LLView* resizing_view, const mAllowDoubleClickSnapping(TRUE), mResizingView(resizing_view) { + setFollowsNone(); // set up some generically good follow code. switch( side ) { @@ -87,6 +88,8 @@ LLResizeBar::LLResizeBar( const std::string& name, LLView* resizing_view, const BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask) { + if (!canResize()) return FALSE; + // Route future Mouse messages here preemptively. (Release on mouse up.) // No handler needed for focus lost since this clas has no state that depends on it. gFocusMgr.setMouseCapture( this ); @@ -240,7 +243,7 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask) handled = TRUE; } - if( handled ) + if( handled && canResize() ) { switch( mSide ) { diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h index b9fc40593..14bdd8d16 100644 --- a/indra/llui/llresizebar.h +++ b/indra/llui/llresizebar.h @@ -52,6 +52,7 @@ public: void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; } void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; } void setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; } + bool canResize() { return getEnabled() && mMaxSize > mMinSize; } private: S32 mDragLastScreenX; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index ea168a35c..38c9b67d7 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -66,8 +66,9 @@ static LLRegisterWidget r("scroll_list"); // local structures & classes. struct SortScrollListItem { - SortScrollListItem(const std::vector >& sort_orders) + SortScrollListItem(const std::vector >& sort_orders,const LLScrollListCtrl::sort_signal_t* sort_signal) : mSortOrders(sort_orders) + , mSortSignal(sort_signal) {} bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2) @@ -80,12 +81,20 @@ struct SortScrollListItem S32 col_idx = it->first; BOOL sort_ascending = it->second; + S32 order = sort_ascending ? 1 : -1; // ascending or descending sort for this column? + const LLScrollListCell *cell1 = i1->getColumn(col_idx); const LLScrollListCell *cell2 = i2->getColumn(col_idx); - S32 order = sort_ascending ? 1 : -1; // ascending or descending sort for this column? if (cell1 && cell2) { - sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString()); + if(mSortSignal) + { + sort_result = order * (*mSortSignal)(col_idx,i1, i2); + } + else + { + sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString()); + } if (sort_result != 0) { break; // we have a sort order! @@ -95,8 +104,10 @@ struct SortScrollListItem return sort_result < 0; } + typedef std::vector > sort_order_t; + const LLScrollListCtrl::sort_signal_t* mSortSignal; const sort_order_t& mSortOrders; }; @@ -109,7 +120,6 @@ LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width) mIcon(icon), // mCallback(NULL), - mUserData(NULL), // mColor(LLColor4::white) { @@ -119,7 +129,6 @@ LLScrollListIcon::LLScrollListIcon(const LLSD& value, S32 width) : LLScrollListCell(width), // mCallback(NULL), - mUserData(NULL), // mColor(LLColor4::white) { @@ -131,6 +140,14 @@ LLScrollListIcon::~LLScrollListIcon() { } +/*virtual*/ +S32 LLScrollListIcon::getHeight() const +{ return mIcon ? mIcon->getHeight() : 0; } + +/*virtual*/ +const LLSD LLScrollListIcon::getValue() const +{ return mIcon.isNull() ? LLStringUtil::null : mIcon->getName(); } + void LLScrollListIcon::setValue(const LLSD& value) { if (value.isUUID()) @@ -174,15 +191,14 @@ S32 LLScrollListIcon::getWidth() const } // -void LLScrollListIcon::setClickCallback(BOOL (*callback)(void*), void* user_data) +void LLScrollListIcon::setClickCallback(boost::function cb) { - mCallback = callback; - mUserData = user_data; + mCallback = cb; } BOOL LLScrollListIcon::handleClick() { - if(mCallback) return mCallback(mUserData); + if(mCallback) return mCallback(); return FALSE; } // @@ -195,46 +211,6 @@ void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_col } } -// -// LLScrollListCheck -// -LLScrollListCheck::LLScrollListCheck(LLCheckBoxCtrl* check_box, S32 width) -{ - mCheckBox = check_box; - LLRect rect(mCheckBox->getRect()); - if (width) - { - - rect.mRight = rect.mLeft + width; - mCheckBox->setRect(rect); - setWidth(width); - } - else - { - setWidth(rect.getWidth()); //check_box->getWidth(); - } -} - -LLScrollListCheck::~LLScrollListCheck() -{ - delete mCheckBox; -} - -void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) const -{ - mCheckBox->draw(); -} - -BOOL LLScrollListCheck::handleClick() -{ - if (mCheckBox->getEnabled()) - { - mCheckBox->toggle(); - } - // don't change selection when clicking on embedded checkbox - return TRUE; -} - // // // LLScrollListLineEditor @@ -288,25 +264,6 @@ BOOL LLScrollListLineEditor::handleUnicodeCharHere(llwchar uni_char ) } // -// -// LLScrollListSeparator -// -LLScrollListSeparator::LLScrollListSeparator(S32 width) : LLScrollListCell(width) -{ -} - -//virtual -S32 LLScrollListSeparator::getHeight() const -{ - return 5; -} - - -void LLScrollListSeparator::draw(const LLColor4& color, const LLColor4& highlight_color) const -{ - // *FIXME: use dynamic item heights and make separators narrow, and inactive - gl_line_2d(5, 8, llmax(5, getWidth() - 5), 8, color); -} // // LLScrollListText @@ -327,6 +284,8 @@ LLScrollListText::LLScrollListText( const std::string& text, const LLFontGL* fon { sCount++; + mTextWidth = getWidth(); + // initialize rounded rect image if (!mRoundedRectImage) { @@ -381,6 +340,11 @@ void LLScrollListText::setText(const LLStringExplicit& text) mText = text; } +void LLScrollListText::setFontStyle(const U8 font_style) +{ + mFontStyle = font_style; +} + //virtual void LLScrollListText::setValue(const LLSD& text) { @@ -452,12 +416,77 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col mFontStyle, LLFontGL::NO_SHADOW, string_chars, - getWidth(), + getTextWidth(), &right_x, FALSE, TRUE); } +// +// LLScrollListCheck +// +LLScrollListCheck::LLScrollListCheck(LLCheckBoxCtrl* check_box, S32 width) +{ + mCheckBox = check_box; + LLRect rect(mCheckBox->getRect()); + if (width) + { + + rect.mRight = rect.mLeft + width; + mCheckBox->setRect(rect); + setWidth(width); + } + else + { + setWidth(rect.getWidth()); //check_box->getWidth(); + } +} + +LLScrollListCheck::~LLScrollListCheck() +{ + delete mCheckBox; + mCheckBox = NULL; +} + +void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) const +{ + mCheckBox->draw(); +} + +BOOL LLScrollListCheck::handleClick() +{ + if (mCheckBox->getEnabled()) + { + mCheckBox->toggle(); + } + // don't change selection when clicking on embedded checkbox + return TRUE; +} + +/*virtual*/ +const LLSD LLScrollListCheck::getValue() const +{ + return mCheckBox->getValue(); +} + +/*virtual*/ +void LLScrollListCheck::setValue(const LLSD& value) +{ + mCheckBox->setValue(value); +} + +/*virtual*/ +void LLScrollListCheck::onCommit() +{ + mCheckBox->onCommit(); +} + +/*virtual*/ +void LLScrollListCheck::setEnabled(BOOL enable) +{ + mCheckBox->setEnabled(enable); +} + LLScrollListDate::LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible) : LLScrollListText(date.asRFC1123(), font, width, font_style, font_alignment, color, use_color, visible), mDate(date) @@ -509,6 +538,21 @@ void LLScrollListItem::setColumn( S32 column, LLScrollListCell *cell ) } } + +S32 LLScrollListItem::getNumColumns() const +{ + return mColumns.size(); +} + +LLScrollListCell* LLScrollListItem::getColumn(const S32 i) const +{ + if (0 <= i && i < (S32)mColumns.size()) + { + return mColumns[i]; + } + return NULL; +} + std::string LLScrollListItem::getContentsCSV() const { std::string ret; @@ -529,12 +573,9 @@ std::string LLScrollListItem::getContentsCSV() const void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) { // draw background rect + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLRect bg_rect = rect; - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4fv(bg_color.mV); - gl_rect_2d( bg_rect ); - } + gl_rect_2d( bg_rect, bg_color ); S32 cur_x = rect.mLeft; S32 num_cols = getNumColumns(); @@ -548,7 +589,7 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLUI::pushMatrix(); { - LLUI::translate((F32) cur_x, (F32) rect.mBottom, 0.0f); + LLUI::translate((F32) cur_x, (F32) rect.mBottom); cell->draw( fg_color, highlight_color ); } @@ -559,74 +600,62 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const } -void LLScrollListItem::setEnabled(BOOL b) +// +// LLScrollListSeparator +// +/* + * Draws a horizontal line. + */ +class LLScrollListSeparator : public LLScrollListCell { - mEnabled = b; -} - -//--------------------------------------------------------------------------- -// LLScrollListItemComment -//--------------------------------------------------------------------------- -LLScrollListItemComment::LLScrollListItemComment(const std::string& comment_string, const LLColor4& color) -: LLScrollListItem(FALSE), - mColor(color) -{ - addColumn( comment_string, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ) ); -} - -void LLScrollListItemComment::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) -{ - LLScrollListCell* cell = getColumn(0); - if (cell) +public: + LLScrollListSeparator(S32 width) : LLScrollListCell(width) {} + virtual ~LLScrollListSeparator() {}; + virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const { - // Two ways a cell could be hidden - if (cell->getWidth() < 0 - || !cell->getVisible()) return; - - LLUI::pushMatrix(); - { - LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f); - - // force first cell to be width of entire item - cell->setWidth(rect.getWidth()); - cell->draw( mColor, highlight_color ); - } - LLUI::popMatrix(); + // *FIXME: use dynamic item heights and make separators narrow, and inactive + gl_line_2d(5, 8, llmax(5, getWidth() - 5), 8, color); } -} + virtual S32 getHeight() const { return 5; }; + virtual BOOL isText() const { return FALSE; } +}; //--------------------------------------------------------------------------- // LLScrollListItemSeparator //--------------------------------------------------------------------------- -LLScrollListItemSeparator::LLScrollListItemSeparator() -: LLScrollListItem(FALSE) -{ - LLScrollListSeparator* cell = new LLScrollListSeparator(0); - setNumColumns(1); - setColumn(0, cell); -} -void LLScrollListItemSeparator::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) +class LLScrollListItemSeparator : public LLScrollListItem { - //TODO* move LLScrollListSeparator::draw into here and get rid of it - LLScrollListCell* cell = getColumn(0); - if (cell) +public: + LLScrollListItemSeparator() : LLScrollListItem(FALSE) { - // Two ways a cell could be hidden - if (cell->getWidth() < 0 - || !cell->getVisible()) return; - - LLUI::pushMatrix(); - { - LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f); - - // force first cell to be width of entire item - cell->setWidth(rect.getWidth()); - cell->draw( fg_color, highlight_color ); - } - LLUI::popMatrix(); + LLScrollListSeparator* cell = new LLScrollListSeparator(0); + setNumColumns(1); + setColumn(0, cell); } -} + + /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) + { + //TODO* move LLScrollListSeparator::draw into here and get rid of it + LLScrollListCell* cell = getColumn(0); + if (cell) + { + // Two ways a cell could be hidden + if (cell->getWidth() < 0 + || !cell->getVisible()) return; + + LLUI::pushMatrix(); + { + LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f); + + // force first cell to be width of entire item + cell->setWidth(rect.getWidth()); + cell->draw( fg_color, highlight_color ); + } + LLUI::popMatrix(); + } + } +}; //--------------------------------------------------------------------------- // LLScrollListCtrl @@ -636,36 +665,24 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, void (*commit_callback)(LLUICtrl* ctrl, void* userdata), void* callback_user_data, BOOL allow_multiple_selection, - BOOL show_border + BOOL show_border, + bool draw_heading ) : LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data), mLineHeight(0), mScrollLines(0), mMouseWheelOpaque(true), mPageLines(0), - mHeadingHeight(20), mMaxSelectable(0), - mAllowMultipleSelection( allow_multiple_selection ), - mAllowKeyboardMovement(TRUE), - mCommitOnKeyboardMovement(TRUE), - mCommitOnSelectionChange(FALSE), - mSelectionChanged(FALSE), - mNeedsScroll(FALSE), - mCanSelect(TRUE), - mDisplayColumnHeaders(FALSE), - mColumnsDirty(FALSE), + mAllowKeyboardMovement(true), + mCommitOnKeyboardMovement(true), + mCommitOnSelectionChange(false), + mSelectionChanged(false), + mNeedsScroll(false), + mCanSelect(true), + mColumnsDirty(false), mMaxItemCount(INT_MAX), mMaxContentWidth(0), - mBackgroundVisible( TRUE ), - mDrawStripes(TRUE), - mBgWriteableColor( LLUI::sColorsGroup->getColor( "ScrollBgWriteableColor" ) ), - mBgReadOnlyColor( LLUI::sColorsGroup->getColor( "ScrollBgReadOnlyColor" ) ), - mBgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedBGColor") ), - mBgStripeColor( LLUI::sColorsGroup->getColor("ScrollBGStripeColor") ), - mFgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedFGColor") ), - mFgUnselectedColor( LLUI::sColorsGroup->getColor("ScrollUnselectedColor") ), - mFgDisabledColor( LLUI::sColorsGroup->getColor("ScrollDisabledColor") ), - mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ), mDefaultListTextColor( LLUI::sColorsGroup->getColor("DefaultListText") ), mBorderThickness( 2 ), mOnDoubleClickCallback( NULL ), @@ -673,14 +690,30 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, mOnSortChangedCallback( NULL ), mHighlightedItem(-1), mBorder(NULL), - mSearchColumn(0), + mSortCallback(NULL), + mCommentTextView(NULL), mNumDynamicWidthColumns(0), mTotalStaticColumnWidth(0), mTotalColumnPadding(0), - mSorted(TRUE), - mDirty(FALSE), + mSorted(true), + mDirty(false), mOriginalSelection(-1), - mDrewSelected(FALSE) + mLastSelected(NULL), + mHeadingHeight(20), + mAllowMultipleSelection( allow_multiple_selection ), + mDisplayColumnHeaders(draw_heading), + mBackgroundVisible(true), + mDrawStripes(true), + mBgWriteableColor( LLUI::sColorsGroup->getColor( "ScrollBgWriteableColor" ) ), + mBgReadOnlyColor( LLUI::sColorsGroup->getColor( "ScrollBgReadOnlyColor" ) ), + mBgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedBGColor") ), + mBgStripeColor( LLUI::sColorsGroup->getColor("ScrollBGStripeColor") ), + mFgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedFGColor") ), + mFgUnselectedColor( LLUI::sColorsGroup->getColor("ScrollUnselectedColor") ), + mFgDisabledColor( LLUI::sColorsGroup->getColor("ScrollDisabledColor") ), + mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ), + mSearchColumn(0), + mColumnPadding(5) { mItemListRect.setOriginAndSize( mBorderThickness, @@ -690,8 +723,6 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, updateLineHeight(); - mPageLines = mLineHeight? (mItemListRect.getHeight()) / mLineHeight : 0; - // Init the scrollbar LLRect scroll_rect; scroll_rect.setOriginAndSize( @@ -703,7 +734,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, LLScrollbar::VERTICAL, getItemCount(), mScrollLines, - mPageLines, + getLinesPerPage(), &LLScrollListCtrl::onScrollChange, this ); mScrollbar->setFollowsRight(); mScrollbar->setFollowsTop(); @@ -721,9 +752,12 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, addChild(mBorder); } - mColumnPadding = 5; - - mLastSelected = NULL; + LLTextBox* textBox = new LLTextBox("comment_text",mItemListRect,std::string()); + textBox->setBorderVisible(false); + textBox->setFollowsAll(); + textBox->setFontShadow(LLFontGL::NO_SHADOW); + textBox->setColor(LLUI::sColorsGroup->getColor("DefaultListText")); + addChild(textBox); } S32 LLScrollListCtrl::getSearchColumn() @@ -750,7 +784,10 @@ S32 LLScrollListCtrl::getSearchColumn() LLScrollListCtrl::~LLScrollListCtrl() { + delete mSortCallback; + std::for_each(mItemList.begin(), mItemList.end(), DeletePointer()); + std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer()); } @@ -786,7 +823,7 @@ void LLScrollListCtrl::clearRows() mScrollLines = 0; mLastSelected = NULL; updateLayout(); - mDirty = FALSE; + mDirty = false; } @@ -831,10 +868,10 @@ std::vector LLScrollListCtrl::getAllSelected() const return ret; } -LLDynamicArray LLScrollListCtrl::getSelectedIDs() +uuid_vec_t LLScrollListCtrl::getSelectedIDs() { LLUUID selected_id; - LLDynamicArray ids; + uuid_vec_t ids; std::vector selected = this->getAllSelected(); for(std::vector::iterator itr = selected.begin(); itr != selected.end(); ++itr) { @@ -843,6 +880,27 @@ LLDynamicArray LLScrollListCtrl::getSelectedIDs() return ids; } +S32 LLScrollListCtrl::getNumSelected() const +{ + if (!getCanSelect()) + { + return 0; + } + + S32 numSelected = 0; + + for(item_list::const_iterator iter = mItemList.begin(); iter != mItemList.end(); ++iter) + { + LLScrollListItem* item = *iter; + if (item->getSelected()) + { + ++numSelected; + } + } + + return numSelected; +} + S32 LLScrollListCtrl::getFirstSelectedIndex() const { if (!getCanSelect()) @@ -852,6 +910,10 @@ S32 LLScrollListCtrl::getFirstSelectedIndex() const S32 CurSelectedIndex = 0; + + // make sure sort is up to date before returning an index + updateSort(); + item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { @@ -887,6 +949,7 @@ LLScrollListItem* LLScrollListCtrl::getLastData() const std::vector LLScrollListCtrl::getAllData() const { std::vector ret; + ret.reserve(mItemList.size()); //Optimization item_list::const_iterator iter; for(iter = mItemList.begin(); iter != mItemList.end(); iter++) { @@ -932,17 +995,26 @@ void LLScrollListCtrl::updateLayout() getRect().getWidth() - 2 * mBorderThickness, getRect().getHeight() - (2 * mBorderThickness ) - heading_size ); + if (mCommentTextView == NULL) + { + mCommentTextView = getChildView("comment_text"); + } + + mCommentTextView->setShape(mItemListRect); + // how many lines of content in a single "page" - mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0; - BOOL scrollbar_visible = getItemCount() > mPageLines; + S32 page_lines = getLinesPerPage(); + + BOOL scrollbar_visible = mLineHeight * getItemCount() > mItemListRect.getHeight(); if (scrollbar_visible) { // provide space on the right for scrollbar mItemListRect.mRight = getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE; } + mScrollbar->setOrigin(getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE, mItemListRect.mBottom); mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0)); - mScrollbar->setPageSize( mPageLines ); + mScrollbar->setPageSize(page_lines); mScrollbar->setDocSize( getItemCount() ); mScrollbar->setVisible(scrollbar_visible); @@ -954,6 +1026,9 @@ void LLScrollListCtrl::updateLayout() void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height) { S32 height = llmin( getRequiredRect().getHeight(), max_height ); + if(mPageLines) + height = llmin( mPageLines * mLineHeight + 2*mBorderThickness + (mDisplayColumnHeaders ? mHeadingHeight : 0), height ); + S32 width = getRect().getWidth(); reshape( width, height ); @@ -981,7 +1056,7 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r { case ADD_TOP: mItemList.push_front(item); - setSorted(FALSE); + setNeedsSort(); break; case ADD_SORTED: @@ -994,22 +1069,22 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r std::stable_sort( mItemList.begin(), mItemList.end(), - SortScrollListItem(single_sort_column)); + SortScrollListItem(single_sort_column,mSortCallback)); // ADD_SORTED just sorts by first column... // this might not match user sort criteria, so flag list as being in unsorted state - setSorted(FALSE); + setNeedsSort(); break; - } + } case ADD_BOTTOM: mItemList.push_back(item); - setSorted(FALSE); + setNeedsSort(); break; default: llassert(0); mItemList.push_back(item); - setSorted(FALSE); + setNeedsSort(); break; } @@ -1023,6 +1098,15 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r addColumn(new_column); } + S32 num_cols = item->getNumColumns(); + S32 i = 0; + for (LLScrollListCell* cell = item->getColumn(i); i < num_cols; cell = item->getColumn(++i)) + { + if (i >= (S32)mColumnsIndexed.size()) break; + + cell->setWidth(mColumnsIndexed[i]->getWidth()); + } + updateLineHeightInsert(item); updateLayout(); @@ -1034,15 +1118,43 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r // NOTE: This is *very* expensive for large lists, especially when we are dirtying the list every frame // while receiving a long list of names. // *TODO: Use bookkeeping to make this an incramental cost with item additions -void LLScrollListCtrl::calcColumnWidths() +S32 LLScrollListCtrl::calcMaxContentWidth() { const S32 HEADING_TEXT_PADDING = 25; const S32 COLUMN_TEXT_PADDING = 10; - mMaxContentWidth = 0; - S32 max_item_width = 0; + ordered_columns_t::iterator column_itor; + for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) + { + LLScrollListColumn* column = *column_itor; + if (!column) continue; + + if (mColumnWidthsDirty) + { + mColumnWidthsDirty = false; + // update max content width for this column, by looking at all items + column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + { + LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); + if (!cellp) continue; + + column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); + } + } + max_item_width += column->mMaxContentWidth; + } + + mMaxContentWidth = max_item_width; + return max_item_width; +} + +bool LLScrollListCtrl::updateColumnWidths() +{ + bool width_changed = false; ordered_columns_t::iterator column_itor; for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) { @@ -1060,23 +1172,14 @@ void LLScrollListCtrl::calcColumnWidths() new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns; } - column->setWidth(new_width); - - // update max content width for this column, by looking at all items - column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + if (column->getWidth() != new_width) { - LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); - if (!cellp) continue; - - column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); + column->setWidth(new_width); + width_changed = true; } - - max_item_width += column->mMaxContentWidth; } - - mMaxContentWidth = max_item_width; + calcMaxContentWidth(); + return width_changed; } const S32 SCROLL_LIST_ROW_PAD = 2; @@ -1112,12 +1215,17 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp) void LLScrollListCtrl::updateColumns() { - calcColumnWidths(); + if (!mColumnsDirty) + return; + + mColumnsDirty = false; + + bool columns_changed_width = updateColumnWidths(); // update column headers std::vector::iterator column_ordered_it; S32 left = mItemListRect.mLeft; - LLColumnHeader* last_header = NULL; + LLScrollColumnHeader* last_header = NULL; for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it) { if ((*column_ordered_it)->getWidth() < 0) @@ -1161,20 +1269,22 @@ void LLScrollListCtrl::updateColumns() } // propagate column widths to individual cells - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + if (columns_changed_width) { - LLScrollListItem *itemp = *iter; - S32 num_cols = itemp->getNumColumns(); - S32 i = 0; - for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { - if (i >= (S32)mColumnsIndexed.size()) break; + LLScrollListItem *itemp = *iter; + S32 num_cols = itemp->getNumColumns(); + S32 i = 0; + for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) + { + if (i >= (S32)mColumnsIndexed.size()) break; - cell->setWidth(mColumnsIndexed[i]->getWidth()); + cell->setWidth(mColumnsIndexed[i]->getWidth()); + } } } - } void LLScrollListCtrl::setDisplayHeading(BOOL display) @@ -1191,6 +1301,12 @@ void LLScrollListCtrl::setHeadingHeight(S32 heading_height) updateLayout(); } +void LLScrollListCtrl::setPageLines(S32 new_page_lines) +{ + mPageLines = new_page_lines; + + updateLayout(); +} BOOL LLScrollListCtrl::selectFirstItem() { @@ -1216,7 +1332,7 @@ BOOL LLScrollListCtrl::selectFirstItem() { deselectItem(itemp); } - first_item = FALSE; + first_item = false; } if (mCommitOnSelectionChange) { @@ -1240,6 +1356,9 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index ) return FALSE; } + // make sure sort is up to date + updateSort(); + S32 listlen = (S32)mItemList.size(); first_index = llclamp(first_index, 0, listlen-1); @@ -1293,6 +1412,7 @@ void LLScrollListCtrl::swapWithNext(S32 index) // At end of list, doesn't do anything return; } + updateSort(); LLScrollListItem *cur_itemp = mItemList[index]; mItemList[index] = mItemList[index + 1]; mItemList[index + 1] = cur_itemp; @@ -1307,6 +1427,7 @@ void LLScrollListCtrl::swapWithPrevious(S32 index) return; } + updateSort(); LLScrollListItem *cur_itemp = mItemList[index]; mItemList[index] = mItemList[index - 1]; mItemList[index - 1] = cur_itemp; @@ -1332,6 +1453,8 @@ void LLScrollListCtrl::deleteSingleItem(S32 target_index) return; } + updateSort(); + LLScrollListItem *itemp; itemp = mItemList[target_index]; if (itemp == mLastSelected) @@ -1388,7 +1511,7 @@ void LLScrollListCtrl::deleteSelectedItems() dirtyColumns(); } -void LLScrollListCtrl::highlightNthItem(S32 target_index) +void LLScrollListCtrl::mouseOverHighlightNthItem(S32 target_index) { if (mHighlightedItem != target_index) { @@ -1396,14 +1519,14 @@ void LLScrollListCtrl::highlightNthItem(S32 target_index) } } -S32 LLScrollListCtrl::selectMultiple( LLDynamicArray ids ) +S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids ) { item_list::iterator iter; S32 count = 0; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem* item = *iter; - LLDynamicArray::iterator iditr; + uuid_vec_t::iterator iditr; for(iditr = ids.begin(); iditr != ids.end(); ++iditr) { if (item->getEnabled() && (item->getUUID() == (*iditr))) @@ -1425,6 +1548,8 @@ S32 LLScrollListCtrl::selectMultiple( LLDynamicArray ids ) S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const { + updateSort(); + S32 index = 0; item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) @@ -1441,6 +1566,8 @@ S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const S32 LLScrollListCtrl::getItemIndex( const LLUUID& target_id ) const { + updateSort(); + S32 index = 0; item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) @@ -1466,6 +1593,8 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection) } else { + updateSort(); + item_list::iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { @@ -1508,6 +1637,8 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection) } else { + updateSort(); + item_list::reverse_iterator iter; for (iter = mItemList.rbegin(); iter != mItemList.rend(); iter++) { @@ -1559,16 +1690,10 @@ void LLScrollListCtrl::deselectAllItems(BOOL no_commit_on_change) /////////////////////////////////////////////////////////////////////////////////////////////////// // Use this to add comment text such as "Searching", which ignores column settings of list -LLScrollListItem* LLScrollListCtrl::addCommentText(const std::string& comment_text, EAddPosition pos) + +void LLScrollListCtrl::setCommentText(const std::string& comment_text) { - LLScrollListItem* item = NULL; - if (getItemCount() < mMaxItemCount) - { - // always draw comment text with "enabled" color - item = new LLScrollListItemComment( comment_text, mFgUnselectedColor ); - addItem( item, pos, FALSE ); - } - return item; + getChild("comment_text")->setWrappedText(comment_text); } LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) @@ -1582,40 +1707,13 @@ LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) // Returns false if item not found. BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sensitive) { - // ensure that no stale items are selected, even if we don't find a match - deselectAllItems(TRUE); - //RN: assume no empty items - if (label.empty()) - { - return FALSE; - } + deselectAllItems(TRUE); // ensure that no stale items are selected, even if we don't find a match + LLScrollListItem* item = getItemByLabel(label, case_sensitive); - std::string target_text = label; - if (!case_sensitive) + bool found = NULL != item; + if(found) { - LLStringUtil::toLower(target_text); - } - - BOOL found = FALSE; - - item_list::iterator iter; - S32 index = 0; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) - { - LLScrollListItem* item = *iter; - // Only select enabled items with matching names - std::string item_text = item->getColumn(0)->getValue().asString(); - if (!case_sensitive) - { - LLStringUtil::toLower(item_text); - } - BOOL select = !found && item->getEnabled() && item_text == target_text; - if (select) - { - selectItem(item); - } - found = found || select; - index++; + selectItem(item); } if (mCommitOnSelectionChange) @@ -1626,6 +1724,36 @@ BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sen return found; } +LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, BOOL case_sensitive, S32 column) +{ + if (label.empty()) //RN: assume no empty items + { + return NULL; + } + + std::string target_text = label; + if (!case_sensitive) + { + LLStringUtil::toLower(target_text); + } + + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + { + LLScrollListItem* item = *iter; + std::string item_text = item->getColumn(column)->getValue().asString(); // Only select enabled items with matching names + if (!case_sensitive) + { + LLStringUtil::toLower(item_text); + } + if(item_text == target_text) + { + return item; + } + } + return NULL; +} + BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_sensitive) { @@ -1822,7 +1950,7 @@ void LLScrollListCtrl::drawItems() S32 y = mItemListRect.mTop - mLineHeight; // allow for partial line at bottom - S32 num_page_lines = mPageLines + 1; + S32 num_page_lines = getLinesPerPage(); LLRect item_rect; @@ -1832,34 +1960,34 @@ void LLScrollListCtrl::drawItems() LLLocalClipRect clip(mItemListRect); S32 cur_y = y; - - mDrewSelected = FALSE; - S32 line = 0; S32 max_columns = 0; LLColor4 highlight_color = LLColor4::white; F32 type_ahead_timeout = LLUI::sConfigGroup->getF32("TypeAheadTimeout"); highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f); - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + S32 first_line = mScrollLines; + S32 last_line = llmin((S32)mItemList.size() - 1, mScrollLines + getLinesPerPage()); + + if ((item_list::size_type)first_line >= mItemList.size()) { - LLScrollListItem* item = *iter; + return; + } + item_list::iterator iter; + for (S32 line = first_line; line <= last_line; line++) + { + LLScrollListItem* item = mItemList[line]; item_rect.setOriginAndSize( x, cur_y, mItemListRect.getWidth(), mLineHeight ); + item->setRect(item_rect); //llinfos << item_rect.getWidth() << llendl; - if (item->getSelected()) - { - mDrewSelected = TRUE; - } - max_columns = llmax(max_columns, item->getNumColumns()); LLColor4 fg_color; @@ -1894,7 +2022,6 @@ void LLScrollListCtrl::drawItems() cur_y -= mLineHeight; } - line++; } } } @@ -1905,15 +2032,12 @@ void LLScrollListCtrl::draw() LLLocalClipRect clip(getLocalRect()); // if user specifies sort, make sure it is maintained - if (needsSorting() && !isSorted()) - { - sortItems(); - } + updateSort(); if (mNeedsScroll) { scrollToShowSelected(); - mNeedsScroll = FALSE; + mNeedsScroll = false; } LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0); // Draw background @@ -1924,17 +2048,15 @@ void LLScrollListCtrl::draw() gl_rect_2d(background); } - if (mColumnsDirty) - { - updateColumns(); - mColumnsDirty = FALSE; - } + updateColumns(); + + getChildView("comment_text")->setVisible(mItemList.empty()); drawItems(); if (mBorder) { - mBorder->setKeyboardFocusHighlight(gFocusMgr.getKeyboardFocus() == this); + mBorder->setKeyboardFocusHighlight(hasFocus()); } LLUICtrl::draw(); @@ -1961,6 +2083,18 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) return handled; } +// *NOTE: Requires a valid row_index and column_index +LLRect LLScrollListCtrl::getCellRect(S32 row_index, S32 column_index) +{ + LLRect cell_rect; + S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft; + S32 rect_bottom = getRowOffsetFromIndex(row_index); + LLScrollListColumn* columnp = getColumn(column_index); + cell_rect.setOriginAndSize(rect_left, rect_bottom, + /*rect_left + */columnp->getWidth(), mLineHeight); + return cell_rect; +} + BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) { S32 column_index = getColumnIndexFromOffset(x); @@ -1988,18 +2122,11 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti if (hit_cell && hit_cell->isText()) { - - S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft; - S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item)); - LLRect cell_rect; - cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight); + S32 row_index = getItemIndex(hit_item); + LLRect cell_rect = getCellRect(row_index, column_index); // Convert rect local to screen coordinates - localPointToScreen( - cell_rect.mLeft, cell_rect.mBottom, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - cell_rect.mRight, cell_rect.mTop, - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); + LLRect sticky_rect; + localRectToScreen(cell_rect, sticky_rect_screen); msg = hit_cell->getValue().asString(); } @@ -2007,7 +2134,7 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti } // otherwise, look for a tooltip associated with this column - LLColumnHeader* headerp = columnp->mHeader; + LLScrollColumnHeader* headerp = columnp->mHeader; if (headerp && !handled) { headerp->handleToolTip(x, y, msg, sticky_rect_screen); @@ -2050,7 +2177,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) { if(mOnMaximumSelectCallback) { - mOnMaximumSelectCallback(mCallbackUserData); + mOnMaximumSelectCallback(); } break; } @@ -2088,7 +2215,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) { if(mOnMaximumSelectCallback) { - mOnMaximumSelectCallback(mCallbackUserData); + mOnMaximumSelectCallback(); } } } @@ -2133,7 +2260,7 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask) setFocus(TRUE); // clear selection changed flag because user is starting a selection operation - mSelectionChanged = FALSE; + mSelectionChanged = false; handleClick(x, y, mask); @@ -2153,15 +2280,15 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask) if(mask == MASK_NONE) { selectItemAt(x, y, mask); - mNeedsScroll = TRUE; + mNeedsScroll = true; } } // always commit when mouse operation is completed inside list if (mItemListRect.pointInRect(x,y)) { - mDirty |= mSelectionChanged; - mSelectionChanged = FALSE; + mDirty = mDirty || mSelectionChanged; + mSelectionChanged = false; onCommit(); } @@ -2179,9 +2306,10 @@ BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) // so the scroll bars will work. if (NULL == LLView::childrenHandleDoubleClick(x, y, mask)) { - if( mCanSelect && mOnDoubleClickCallback ) + // Run the callback only if an item is being double-clicked. + if( mCanSelect && hitItem(x, y) && mOnDoubleClickCallback ) { - mOnDoubleClickCallback( mCallbackUserData ); + mOnDoubleClickCallback(); } } } @@ -2208,7 +2336,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) { selectItemAt(x, y, mask); gFocusMgr.setMouseCapture(this); - mNeedsScroll = TRUE; + mNeedsScroll = true; } // propagate state of cell to rest of selected column @@ -2237,7 +2365,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) // treat this as a normal single item selection selectItemAt(x, y, mask); gFocusMgr.setMouseCapture(this); - mNeedsScroll = TRUE; + mNeedsScroll = true; // do not eat click (allow double click callback) return FALSE; } @@ -2248,6 +2376,8 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y ) // Excludes disabled items. LLScrollListItem* hit_item = NULL; + updateSort(); + LLRect item_rect; item_rect.setLeftTopAndSize( mItemListRect.mLeft, @@ -2256,7 +2386,7 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y ) mLineHeight ); // allow for partial line at bottom - S32 num_page_lines = mPageLines + 1; + S32 num_page_lines = getLinesPerPage(); S32 line = 0; item_list::iterator iter; @@ -2327,8 +2457,7 @@ S32 LLScrollListCtrl::getColumnOffsetFromIndex(S32 index) S32 LLScrollListCtrl::getRowOffsetFromIndex(S32 index) { - S32 row_bottom = ((mItemListRect.mTop - (index - mScrollLines)) * mLineHeight) - - mLineHeight; + S32 row_bottom = (mItemListRect.mTop - ((index - mScrollLines + 1) * mLineHeight) ); return row_bottom; } @@ -2342,7 +2471,7 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) if(mask == MASK_NONE) { selectItemAt(x, y, mask); - mNeedsScroll = TRUE; + mNeedsScroll = true; } } else @@ -2351,11 +2480,11 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) LLScrollListItem* item = hitItem(x, y); if (item) { - highlightNthItem(getItemIndex(item)); + mouseOverHighlightNthItem(getItemIndex(item)); } else { - highlightNthItem(-1); + mouseOverHighlightNthItem(-1); } } @@ -2384,7 +2513,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { // commit implicit in call selectPrevItem(FALSE); - mNeedsScroll = TRUE; + mNeedsScroll = true; handled = TRUE; } break; @@ -2393,7 +2522,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { // commit implicit in call selectNextItem(FALSE); - mNeedsScroll = TRUE; + mNeedsScroll = true; handled = TRUE; } break; @@ -2401,7 +2530,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getFirstSelectedIndex() - (mScrollbar->getPageSize() - 1)); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2414,7 +2543,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getFirstSelectedIndex() + (mScrollbar->getPageSize() - 1)); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2427,7 +2556,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectFirstItem(); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2440,7 +2569,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getItemCount() - 1); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2479,7 +2608,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) } else if (selectItemByPrefix(wstring_to_utf8str(mSearchString), FALSE)) { - mNeedsScroll = TRUE; + mNeedsScroll = true; // update search string only on successful match mSearchTimer.reset(); @@ -2519,7 +2648,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) if (selectItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE)) { // update search string only on successful match - mNeedsScroll = TRUE; + mNeedsScroll = true; mSearchString += uni_char; mSearchTimer.reset(); @@ -2565,7 +2694,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) { selectItem(item); - mNeedsScroll = TRUE; + mNeedsScroll = true; cellp->highlightText(0, 1); mSearchTimer.reset(); @@ -2636,7 +2765,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it } itemp->setSelected(TRUE); mLastSelected = itemp; - mSelectionChanged = TRUE; + mSelectionChanged = true; } } @@ -2657,7 +2786,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp) { cellp->highlightText(0, 0); } - mSelectionChanged = TRUE; + mSelectionChanged = true; } } @@ -2665,7 +2794,7 @@ void LLScrollListCtrl::commitIfChanged() { if (mSelectionChanged) { - mDirty = TRUE; + mDirty = true; mSelectionChanged = FALSE; onCommit(); } @@ -2684,9 +2813,11 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending) LLScrollListColumn* sort_column = getColumn(column_idx); if (!sort_column) return FALSE; - sort_column->mSortAscending = ascending; + sort_column->mSortDirection = ascending ? LLScrollListColumn::ASCENDING : LLScrollListColumn::DESCENDING; sort_column_t new_sort_column(column_idx, ascending); + + setNeedsSort(); if (mSortColumns.empty()) { @@ -2708,6 +2839,19 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending) } } +S32 LLScrollListCtrl::getLinesPerPage() +{ + //if mPageLines is NOT provided display all item + if(mPageLines) + { + return mPageLines; + } + else + { + return mLineHeight ? mItemListRect.getHeight() / mLineHeight : getItemCount(); + } +} + // Called by scrollbar //static void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void* userdata ) @@ -2719,31 +2863,32 @@ void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending) { - std::map::iterator itor = mColumns.find(name); + column_map_t::iterator itor = mColumns.find(name); if (itor != mColumns.end()) { - sortByColumnIndex((*itor).second.mIndex, ascending); + sortByColumnIndex((*itor).second->mIndex, ascending); } } // First column is column 0 void LLScrollListCtrl::sortByColumnIndex(U32 column, BOOL ascending) { - if (setSort(column, ascending)) - { - sortItems(); - } + setSort(column, ascending); + updateSort(); } -void LLScrollListCtrl::sortItems() +void LLScrollListCtrl::updateSort() const { - // do stable sort to preserve any previous sorts - std::stable_sort( - mItemList.begin(), - mItemList.end(), - SortScrollListItem(mSortColumns)); + if (hasSortOrder() && !isSorted()) + { + // do stable sort to preserve any previous sorts + std::stable_sort( + mItemList.begin(), + mItemList.end(), + SortScrollListItem(mSortColumns,mSortCallback)); - setSorted(TRUE); + mSorted = true; + } } // for one-shot sorts, does not save sort column/order @@ -2756,22 +2901,23 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending) std::stable_sort( mItemList.begin(), mItemList.end(), - SortScrollListItem(sort_column)); + SortScrollListItem(sort_column,mSortCallback)); } void LLScrollListCtrl::dirtyColumns() { - mColumnsDirty = TRUE; + mColumnsDirty = true; + mColumnWidthsDirty = true; // need to keep mColumnsIndexed up to date // just in case someone indexes into it immediately mColumnsIndexed.resize(mColumns.size()); - std::map::iterator column_itor; + column_map_t::iterator column_itor; for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) { - LLScrollListColumn *column = &column_itor->second; - mColumnsIndexed[column_itor->second.mIndex] = column; + LLScrollListColumn *column = column_itor->second; + mColumnsIndexed[column_itor->second->mIndex] = column; } } @@ -2799,6 +2945,8 @@ void LLScrollListCtrl::scrollToShowSelected() return; } + updateSort(); + S32 index = getFirstSelectedIndex(); if (index < 0) { @@ -2813,7 +2961,8 @@ void LLScrollListCtrl::scrollToShowSelected() } S32 lowest = mScrollLines; - S32 highest = mScrollLines + mPageLines; + S32 page_lines = getLinesPerPage(); + S32 highest = mScrollLines + page_lines; if (index < lowest) { @@ -2822,7 +2971,7 @@ void LLScrollListCtrl::scrollToShowSelected() } else if (highest <= index) { - setScrollPos(index - mPageLines + 1); + setScrollPos(index - page_lines + 1); } } @@ -2869,9 +3018,9 @@ LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const std::map::const_iterator itor; std::vector sorted_list; sorted_list.resize(mColumns.size()); - for (itor = mColumns.begin(); itor != mColumns.end(); ++itor) + for (column_map_t::const_iterator itor = mColumns.begin(); itor != mColumns.end(); ++itor) { - sorted_list[itor->second.mIndex] = &itor->second; + sorted_list[itor->second->mIndex] = itor->second; } std::vector::iterator itor2; @@ -2993,9 +3142,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac callback, NULL, multi_select, - draw_border); + draw_border, + draw_heading); - scroll_list->setDisplayHeading(draw_heading); if (node->hasAttribute("heading_height")) { S32 heading_height; @@ -3075,16 +3224,20 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { - if (child->hasName("row")) + if (child->hasName("row") || child->hasName("rows")) { LLUUID id; - child->getAttributeUUID("id", id); - LLSD row; - - row["id"] = id; + std::string value; + child->getAttributeString("value",value); + bool id_found = child->getAttributeUUID("id", id); + if(id_found) + row["id"] = id; + else + row["id"] = value; S32 column_idx = 0; + bool explicit_column = false; LLXMLNodePtr row_child; for (row_child = child->getFirstChild(); row_child.notNull(); row_child = row_child->getNextSibling()) { @@ -3106,28 +3259,24 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac row["columns"][column_idx]["font"] = font; row["columns"][column_idx]["font-style"] = font_style; column_idx++; + explicit_column = true; } } - scroll_list->addElement(row); + if(explicit_column) + scroll_list->addElement(row); + else + { + LLSD entry_id; + if(id_found) + entry_id = id; + scroll_list->addSimpleElement(value,ADD_BOTTOM,entry_id); + } } } std::string contents = node->getTextContents(); - if (!contents.empty()) - { - typedef boost::tokenizer > tokenizer; - boost::char_separator sep("\t\n"); - tokenizer tokens(contents, sep); - tokenizer::iterator token_iter = tokens.begin(); + scroll_list->setCommentText(contents); - while(token_iter != tokens.end()) - { - const std::string& line = *token_iter; - scroll_list->addSimpleElement(line); - ++token_iter; - } - } - return scroll_list; } @@ -3217,8 +3366,8 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) if (mColumns.find(name) == mColumns.end()) { // Add column - mColumns[name] = LLScrollListColumn(column, this); - LLScrollListColumn* new_column = &mColumns[name]; + LLScrollListColumn* new_column = new LLScrollListColumn(column, this); + mColumns[name] = new_column; new_column->mParentCtrl = this; new_column->mIndex = mColumns.size()-1; @@ -3239,18 +3388,19 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) new_column->setWidth((mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns); } S32 top = mItemListRect.mTop; + S32 left = mItemListRect.mLeft; + for (column_map_t::iterator itor = mColumns.begin(); + itor != mColumns.end(); + ++itor) { - std::map::iterator itor; - for (itor = mColumns.begin(); itor != mColumns.end(); ++itor) + if (itor->second->mIndex < new_column->mIndex && + itor->second->getWidth() > 0) { - if (itor->second.mIndex < new_column->mIndex && - itor->second.getWidth() > 0) - { - left += itor->second.getWidth() + mColumnPadding; - } + left += itor->second->getWidth() + mColumnPadding; } } + std::string button_name = "btn_" + name; S32 right = left+new_column->getWidth(); if (new_column->mIndex != (S32)mColumns.size()-1) @@ -3258,7 +3408,7 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) right += mColumnPadding; } LLRect temp_rect = LLRect(left,top+mHeadingHeight,right,top); - new_column->mHeader = new LLColumnHeader(button_name, temp_rect, new_column); + new_column->mHeader = new LLScrollColumnHeader(button_name, temp_rect, new_column); if(column["image"].asString() != "") { //new_column->mHeader->setScaleImage(false); @@ -3301,12 +3451,12 @@ void LLScrollListCtrl::onClickColumn(void *userdata) S32 column_index = info->mIndex; LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex]; - bool ascending = column->mSortAscending; + bool ascending = column->mSortDirection == LLScrollListColumn::ASCENDING; if (column->mSortingColumn != column->mName && parent->mColumns.find(column->mSortingColumn) != parent->mColumns.end()) { - LLScrollListColumn& info_redir = parent->mColumns[column->mSortingColumn]; - column_index = info_redir.mIndex; + LLScrollListColumn* info_redir = parent->mColumns[column->mSortingColumn]; + column_index = info_redir->mIndex; } // if this column is the primary sort key, reverse the direction @@ -3320,7 +3470,7 @@ void LLScrollListCtrl::onClickColumn(void *userdata) if (parent->mOnSortChangedCallback) { - parent->mOnSortChangedCallback(parent->getCallbackUserData()); + parent->mOnSortChangedCallback(); } } @@ -3332,23 +3482,29 @@ std::string LLScrollListCtrl::getSortColumnName() else return ""; } -BOOL LLScrollListCtrl::needsSorting() +BOOL LLScrollListCtrl::hasSortOrder() const { return !mSortColumns.empty(); } +void LLScrollListCtrl::clearSortOrder() +{ + mSortColumns.clear(); +} + void LLScrollListCtrl::clearColumns() { - std::map::iterator itor; + column_map_t::iterator itor; for (itor = mColumns.begin(); itor != mColumns.end(); ++itor) { - LLColumnHeader *header = itor->second.mHeader; + LLScrollColumnHeader *header = itor->second->mHeader; if (header) { removeChild(header); delete header; } } + std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer()); mColumns.clear(); mSortColumns.clear(); mTotalStaticColumnWidth = 0; @@ -3357,13 +3513,13 @@ void LLScrollListCtrl::clearColumns() void LLScrollListCtrl::setColumnLabel(const std::string& column, const std::string& label) { - std::map::iterator itor = mColumns.find(column); - if (itor != mColumns.end()) + LLScrollListColumn* columnp = getColumn(column); + if (columnp) { - itor->second.mLabel = label; - if (itor->second.mHeader) + columnp->mLabel = label; + if (columnp->mHeader) { - itor->second.mHeader->setLabel(label); + columnp->mHeader->setLabel(label); } } } @@ -3377,6 +3533,16 @@ LLScrollListColumn* LLScrollListCtrl::getColumn(S32 index) return mColumnsIndexed[index]; } +LLScrollListColumn* LLScrollListCtrl::getColumn(const std::string& name) +{ + column_map_t::iterator column_itor = mColumns.find(name); + if (column_itor != mColumns.end()) + { + return column_itor->second; + } + return NULL; +} + void LLScrollListCtrl::setColumnHeadings(LLSD headings) { mColumns.clear(); @@ -3387,6 +3553,15 @@ void LLScrollListCtrl::setColumnHeadings(LLSD headings) } } +/* "id" + "enabled" + "columns" + "column" + "name" + "label" + "width" + "dynamic_width" +*/ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition pos, void* userdata) { // ID @@ -3423,11 +3598,10 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p column = new_name.str(); } - std::map::iterator column_itor; - column_itor = mColumns.find(column); + column_map_t::iterator column_itor = mColumns.find(column); if (column_itor != mColumns.end()) { - columnp = &column_itor->second; + columnp = column_itor->second; } // create new column on demand @@ -3447,7 +3621,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p new_column["dynamicwidth"] = true; } addColumn(new_column); - columnp = &mColumns[column]; + columnp = mColumns[column]; new_item->setNumColumns(mColumns.size()); } @@ -3561,10 +3735,10 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p // add dummy cells for missing columns for (column_map_t::iterator column_it = mColumns.begin(); column_it != mColumns.end(); ++column_it) { - S32 column_idx = column_it->second.mIndex; + S32 column_idx = column_it->second->mIndex; if (new_item->getColumn(column_idx) == NULL) { - LLScrollListColumn* column_ptr = &column_it->second; + LLScrollListColumn* column_ptr = column_it->second; new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->getWidth(), LLFontGL::NORMAL)); } } @@ -3643,7 +3817,6 @@ BOOL LLScrollListCtrl::operateOnAll(EOperation op) //virtual void LLScrollListCtrl::setFocus(BOOL b) { - mSearchString.clear(); // for tabbing into pristine scroll lists (Finder) if (!getFirstSelected()) { @@ -3677,7 +3850,7 @@ void LLScrollListCtrl::resetDirty() void LLScrollListCtrl::onFocusReceived() { // forget latent selection changes when getting focus - mSelectionChanged = FALSE; + mSelectionChanged = false; LLUICtrl::onFocusReceived(); } @@ -3688,10 +3861,13 @@ void LLScrollListCtrl::onFocusLost() { gFocusMgr.setMouseCapture(NULL); } + + mSearchString.clear(); + LLUICtrl::onFocusLost(); } -LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL* fontp) : +LLScrollColumnHeader::LLScrollColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL* fontp) : LLComboBox(label, rect, label, NULL, NULL), mColumn(column), mOrigLabel(label), @@ -3704,9 +3880,9 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS mButton->setTabStop(FALSE); // require at least two frames between mouse down and mouse up event to capture intentional "hold" not just bad framerate mButton->setHeldDownDelay(LLUI::sConfigGroup->getF32("ColumnHeaderDropDownDelay"), 2); - mButton->setHeldDownCallback(boost::bind(&LLColumnHeader::onHeldDown, this)); - mButton->setClickedCallback(boost::bind(&LLColumnHeader::onClick, this)); - mButton->setMouseDownCallback(boost::bind(&LLColumnHeader::onMouseDown, this)); + mButton->setHeldDownCallback(boost::bind(&LLScrollColumnHeader::onHeldDown, this)); + mButton->setClickedCallback(boost::bind(&LLScrollColumnHeader::onClick, this)); + mButton->setMouseDownCallback(boost::bind(&LLScrollColumnHeader::onMouseDown, this)); mButton->setCallbackUserData(this); mButton->setToolTip(label); @@ -3731,13 +3907,17 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS mImageOverlayColor = LLColor4::white; } -LLColumnHeader::~LLColumnHeader() +LLScrollColumnHeader::~LLScrollColumnHeader() { } -void LLColumnHeader::draw() +void LLScrollColumnHeader::draw() { - BOOL draw_arrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->isSorted() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn; + std::string sort_column = mColumn->mParentCtrl->getSortColumnName(); + BOOL draw_arrow = !mColumn->mLabel.empty() + && mColumn->mParentCtrl->isSorted() + // check for indirect sorting column as well as column's sorting name + && (sort_column == mColumn->mSortingColumn || sort_column == mColumn->mName); BOOL is_ascending = mColumn->mParentCtrl->getSortAscending(); mButton->setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent); @@ -3848,11 +4028,12 @@ void LLColumnHeader::draw() } } -BOOL LLColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) +BOOL LLScrollColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) { if (canResize() && mResizeBar->getRect().pointInRect(x, y)) { // reshape column to max content width + mColumn->mParentCtrl->calcMaxContentWidth(); LLRect column_rect = getRect(); column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth; setShape(column_rect,true); @@ -3864,7 +4045,7 @@ BOOL LLColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } -void LLColumnHeader::setImage(const std::string &image_name) +void LLScrollColumnHeader::setImage(const std::string &image_name) { if (mButton) { @@ -3873,7 +4054,7 @@ void LLColumnHeader::setImage(const std::string &image_name) } } -void LLColumnHeader::setImageOverlay(const std::string &image_name, LLFontGL::HAlign alignment, const LLColor4& color) +void LLScrollColumnHeader::setImageOverlay(const std::string &image_name, LLFontGL::HAlign alignment, const LLColor4& color) { if (image_name.empty()) { @@ -3888,9 +4069,9 @@ void LLColumnHeader::setImageOverlay(const std::string &image_name, LLFontGL::HA } //static -void LLColumnHeader::onClick(void* user_data) +void LLScrollColumnHeader::onClick(void* user_data) { - LLColumnHeader* headerp = (LLColumnHeader*)user_data; + LLScrollColumnHeader* headerp = (LLScrollColumnHeader*)user_data; if (!headerp) return; LLScrollListColumn* column = headerp->mColumn; @@ -3910,20 +4091,20 @@ void LLColumnHeader::onClick(void* user_data) } //static -void LLColumnHeader::onMouseDown(void* user_data) +void LLScrollColumnHeader::onMouseDown(void* user_data) { // for now, do nothing but block the normal showList() behavior return; } //static -void LLColumnHeader::onHeldDown(void* user_data) +void LLScrollColumnHeader::onHeldDown(void* user_data) { - LLColumnHeader* headerp = (LLColumnHeader*)user_data; + LLScrollColumnHeader* headerp = (LLScrollColumnHeader*)user_data; headerp->showList(); } -void LLColumnHeader::showList() +void LLScrollColumnHeader::showList() { if (mShowSortOptions) { @@ -3996,8 +4177,8 @@ void LLColumnHeader::showList() text_width = llmax(text_width, getRect().getWidth() - 30); mList->getColumn(0)->setWidth(text_width); - ((LLScrollListText*)mList->getFirstData()->getColumn(0))->setText(ascending_string); - ((LLScrollListText*)mList->getLastData()->getColumn(0))->setText(descending_string); + mList->getFirstData()->getColumn(0)->setValue(ascending_string); + mList->getLastData()->getColumn(0)->setValue(descending_string); mList->reshape(llmax(text_width + 30, 110, getRect().getWidth()), mList->getRect().getHeight()); @@ -4006,9 +4187,9 @@ void LLColumnHeader::showList() } //static -void LLColumnHeader::onSelectSort(LLUICtrl* ctrl, void* user_data) +void LLScrollColumnHeader::onSelectSort(LLUICtrl* ctrl, void* user_data) { - LLColumnHeader* headerp = (LLColumnHeader*)user_data; + LLScrollColumnHeader* headerp = (LLScrollColumnHeader*)user_data; if (!headerp) return; LLScrollListColumn* column = headerp->mColumn; @@ -4031,7 +4212,7 @@ void LLColumnHeader::onSelectSort(LLUICtrl* ctrl, void* user_data) headerp->setLabel(headerp->mOrigLabel); } -LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding) +LLView* LLScrollColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding) { // this logic assumes dragging on right llassert(snap_edge == SNAP_RIGHT); @@ -4069,7 +4250,7 @@ LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_d return this; } -void LLColumnHeader::handleReshape(const LLRect& new_rect, bool by_user) +void LLScrollColumnHeader::handleReshape(const LLRect& new_rect, bool by_user) { S32 new_width = new_rect.getWidth(); S32 delta_width = new_width - (getRect().getWidth() /*+ mColumn->mParentCtrl->getColumnPadding()*/); @@ -4147,11 +4328,12 @@ void LLColumnHeader::handleReshape(const LLRect& new_rect, bool by_user) // tell scroll list to layout columns again // do immediate update to get proper feedback to resize handle // which needs to know how far the resize actually went + mColumn->mParentCtrl->dirtyColumns(); //Must flag as dirty, else updateColumns will probably be a noop. mColumn->mParentCtrl->updateColumns(); } } -void LLColumnHeader::setHasResizableElement(BOOL resizable) +void LLScrollColumnHeader::setHasResizableElement(BOOL resizable) { // for now, dynamically spaced columns can't be resized // if (mColumn->mDynamicWidth) return; @@ -4163,7 +4345,7 @@ void LLColumnHeader::setHasResizableElement(BOOL resizable) } } -void LLColumnHeader::updateResizeBars() +void LLScrollColumnHeader::updateResizeBars() { S32 num_resizable_columns = 0; S32 col; @@ -4192,7 +4374,7 @@ void LLColumnHeader::updateResizeBars() } } -void LLColumnHeader::enableResizeBar(BOOL enable) +void LLScrollColumnHeader::enableResizeBar(BOOL enable) { // for now, dynamically spaced columns can't be resized //if (!mColumn->mDynamicWidth) @@ -4201,25 +4383,16 @@ void LLColumnHeader::enableResizeBar(BOOL enable) } } -BOOL LLColumnHeader::canResize() +BOOL LLScrollColumnHeader::canResize() { return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth); } -void LLScrollListColumn::setWidth(S32 width) -{ - if (!mDynamicWidth && mRelWidth <= 0.f) - { - mParentCtrl->updateStaticColumnWidth(this, width); - } - mWidth = width; -} - // Default constructor LLScrollListColumn::LLScrollListColumn() : mName(), mSortingColumn(), - mSortAscending(TRUE), + mSortDirection(ASCENDING), mLabel(), mWidth(-1), mRelWidth(-1.0), @@ -4246,10 +4419,13 @@ LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) { mSortingColumn = sd.get("sort").asString(); } - mSortAscending = TRUE; if (sd.has("sort_ascending")) { - mSortAscending = sd.get("sort_ascending").asBoolean(); + mSortDirection = sd.get("sort_ascending").asBoolean() ? ASCENDING : DESCENDING; + } + else + { + mSortDirection = ASCENDING; } mLabel = sd.get("label").asString(); if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0) @@ -4266,7 +4442,6 @@ LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) } else { - setWidth(sd.get("width").asInteger()); } @@ -4280,3 +4455,12 @@ LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) } } + +void LLScrollListColumn::setWidth(S32 width) +{ + if (!mDynamicWidth && mRelWidth <= 0.f) + { + mParentCtrl->updateStaticColumnWidth(this, width); + } + mWidth = width; +} diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 4060c1466..30a8aba11 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -51,6 +51,7 @@ #include "lldate.h" // #include "lllineeditor.h" +#include // /* @@ -69,13 +70,13 @@ public: virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible virtual S32 getWidth() const {return mWidth;} virtual S32 getContentWidth() const { return 0; } - virtual S32 getHeight() const = 0; + virtual S32 getHeight() const { return 0; } virtual const LLSD getValue() const { return LLStringUtil::null; } virtual void setValue(const LLSD& value) { } virtual BOOL getVisible() const { return TRUE; } virtual void setWidth(S32 width) { mWidth = width; } virtual void highlightText(S32 offset, S32 num_chars) {} - virtual BOOL isText() const = 0; + virtual BOOL isText() const { return FALSE; } virtual void setColor(const LLColor4&) {} virtual void onCommit() {}; @@ -86,19 +87,6 @@ private: S32 mWidth; }; -/* - * Draws a horizontal line. - */ -class LLScrollListSeparator : public LLScrollListCell -{ -public: - LLScrollListSeparator(S32 width); - virtual ~LLScrollListSeparator() {}; - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible - virtual S32 getHeight() const; - virtual BOOL isText() const { return FALSE; } -}; - /* * Cell displaying a text label. */ @@ -108,22 +96,27 @@ public: LLScrollListText( const std::string& text, const LLFontGL* font, S32 width = 0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE); /*virtual*/ ~LLScrollListText(); - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; - virtual S32 getContentWidth() const; - virtual S32 getHeight() const; - virtual void setValue(const LLSD& value); - virtual const LLSD getValue() const; - virtual BOOL getVisible() const; - virtual void highlightText(S32 offset, S32 num_chars); + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ S32 getContentWidth() const; + /*virtual*/ S32 getHeight() const; + /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ const LLSD getValue() const; + /*virtual*/ BOOL getVisible() const; + /*virtual*/ void highlightText(S32 offset, S32 num_chars); - virtual void setColor(const LLColor4&); - virtual BOOL isText() const; + /*virtual*/ void setColor(const LLColor4&); + /*virtual*/ BOOL isText() const; + + S32 getTextWidth() const { return mTextWidth;} + void setTextWidth(S32 value) { mTextWidth = value;} + virtual void setWidth(S32 width) { LLScrollListCell::setWidth(width); mTextWidth = width; } void setText(const LLStringExplicit& text); - void setFontStyle(const U8 font_style) { mFontStyle = font_style; } + void setFontStyle(const U8 font_style); private: LLUIString mText; + S32 mTextWidth; const LLFontGL* mFont; LLColor4 mColor; U8 mUseColor; @@ -138,18 +131,6 @@ private: static U32 sCount; }; - -class LLScrollListDate : public LLScrollListText -{ -public: - LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE); - virtual void setValue(const LLSD& value); - virtual const LLSD getValue() const; - -private: - LLDate mDate; -}; - /* * Cell displaying an image. */ @@ -159,24 +140,22 @@ public: LLScrollListIcon( LLUIImagePtr icon, S32 width = 0); LLScrollListIcon(const LLSD& value, S32 width = 0); /*virtual*/ ~LLScrollListIcon(); - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; - virtual S32 getWidth() const; - virtual S32 getHeight() const { return mIcon ? mIcon->getHeight() : 0; } - virtual const LLSD getValue() const { return mIcon.isNull() ? LLStringUtil::null : mIcon->getName(); } - virtual void setColor(const LLColor4&); - virtual BOOL isText()const { return FALSE; } - virtual void setValue(const LLSD& value); + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ S32 getWidth() const; + /*virtual*/ S32 getHeight() const; + /*virtual*/ const LLSD getValue() const; + /*virtual*/ void setColor(const LLColor4&); + /*virtual*/ void setValue(const LLSD& value); // - void setClickCallback(BOOL (*callback)(void*), void* user_data); + void setClickCallback(boost::function cb); virtual BOOL handleClick(); // private: - LLUIImagePtr mIcon; + LLPointer mIcon; LLColor4 mColor; // - BOOL (*mCallback)(void*); - void* mUserData; + boost::function mCallback; // }; @@ -188,22 +167,33 @@ class LLScrollListCheck : public LLScrollListCell public: LLScrollListCheck( LLCheckBoxCtrl* check_box, S32 width = 0); /*virtual*/ ~LLScrollListCheck(); - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; - virtual S32 getHeight() const { return 0; } - virtual const LLSD getValue() const { return mCheckBox->getValue(); } - virtual void setValue(const LLSD& value) { mCheckBox->setValue(value); } - virtual void onCommit() { mCheckBox->onCommit(); } + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ S32 getHeight() const { return 0; } + /*virtual*/ const LLSD getValue() const; + /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ void onCommit(); - virtual BOOL handleClick(); - virtual void setEnabled(BOOL enable) { mCheckBox->setEnabled(enable); } + /*virtual*/ BOOL handleClick(); + /*virtual*/ void setEnabled(BOOL enable); LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } - virtual BOOL isText() const { return FALSE; } private: LLCheckBoxCtrl* mCheckBox; }; + +class LLScrollListDate : public LLScrollListText +{ +public: + LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE); + virtual void setValue(const LLSD& value); + virtual const LLSD getValue() const; + +private: + LLDate mDate; +}; + // class LLScrollListLineEditor : public LLScrollListCell { @@ -228,43 +218,12 @@ private: }; // -/* - * A simple data class describing a column within a scroll list. - */ -class LLScrollListColumn +class LLScrollListColumn; +class LLScrollColumnHeader : public LLComboBox { public: - LLScrollListColumn(); - LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent); - - void setWidth(S32 width); - S32 getWidth() const { return mWidth; } - - // Public data is fine so long as this remains a simple struct-like data class. - // If it ever gets any smarter than that, these should all become private - // with protected or public accessor methods added as needed. -MG - std::string mName; - std::string mSortingColumn; - BOOL mSortAscending; - std::string mLabel; - F32 mRelWidth; - BOOL mDynamicWidth; - S32 mMaxContentWidth; - S32 mIndex; - LLScrollListCtrl* mParentCtrl; - class LLColumnHeader* mHeader; - LLFontGL::HAlign mFontAlignment; - -private: - S32 mWidth; - -}; - -class LLColumnHeader : public LLComboBox -{ -public: - LLColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL *font = NULL); - ~LLColumnHeader(); + LLScrollColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL *font = NULL); + ~LLScrollColumnHeader(); /*virtual*/ void draw(); /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); @@ -301,7 +260,44 @@ private: LLColor4 mImageOverlayColor; }; -class LLScrollListItem +/* + * A simple data class describing a column within a scroll list. + */ +class LLScrollListColumn +{ +public: + typedef enum e_sort_direction + { + DESCENDING, + ASCENDING + } ESortDirection; + LLScrollListColumn(); + LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent); + + void setWidth(S32 width); + S32 getWidth() const { return mWidth; } + + // Public data is fine so long as this remains a simple struct-like data class. + // If it ever gets any smarter than that, these should all become private + // with protected or public accessor methods added as needed. -MG + std::string mName; + std::string mSortingColumn; + ESortDirection mSortDirection; + std::string mLabel; + F32 mRelWidth; + BOOL mDynamicWidth; + S32 mMaxContentWidth; + S32 mIndex; + LLScrollListCtrl* mParentCtrl; + LLScrollColumnHeader* mHeader; + LLFontGL::HAlign mFontAlignment; + +private: + S32 mWidth; + +}; + +class LLScrollListItem : public LLHandleProvider { public: LLScrollListItem( BOOL enabled = TRUE, void* userdata = NULL, const LLUUID& uuid = LLUUID::null ) @@ -314,7 +310,7 @@ public: void setSelected( BOOL b ) { mSelected = b; } BOOL getSelected() const { return mSelected; } - void setEnabled( BOOL b ); + void setEnabled( BOOL b ) { mEnabled = b; } BOOL getEnabled() const { return mEnabled; } void setUserdata( void* userdata ) { mUserdata = userdata; } @@ -323,9 +319,12 @@ public: void setToolTip(const std::string tool_tip) { mToolTip=tool_tip; } std::string getToolTip() { return mToolTip; } - LLUUID getUUID() const { return mItemValue.asUUID(); } + virtual LLUUID getUUID() const { return mItemValue.asUUID(); } LLSD getValue() const { return mItemValue; } + void setRect(LLRect rect) { mRectangle = rect; } + LLRect getRect() const { return mRectangle; } + // If width = 0, just use the width of the text. Otherwise override with // specified width in pixels. void addColumn( const std::string& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, BOOL visible = TRUE) @@ -341,9 +340,9 @@ public: void setColumn( S32 column, LLScrollListCell *cell ); - S32 getNumColumns() const { return mColumns.size(); } + S32 getNumColumns() const; - LLScrollListCell *getColumn(const S32 i) const { if (0 <= i && i < (S32)mColumns.size()) { return mColumns[i]; } return NULL; } + LLScrollListCell *getColumn(const S32 i) const; std::string getContentsCSV() const; @@ -356,42 +355,45 @@ private: LLSD mItemValue; std::string mToolTip; std::vector mColumns; -}; - -/* - * A graphical control representing a scrollable table. - * Cells in the table can be simple text or more complicated things - * such as icons or even interactive elements like check boxes. - */ -class LLScrollListItemComment : public LLScrollListItem -{ -public: - LLScrollListItemComment(const std::string& comment_string, const LLColor4& color); - - /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); -private: - LLColor4 mColor; -}; - -class LLScrollListItemSeparator : public LLScrollListItem -{ -public: - LLScrollListItemSeparator(); - - /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); + LLRect mRectangle; }; class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, public LLCtrlListInterface, public LLCtrlScrollInterface { public: + typedef boost::function callback_t; + + template struct maximum + { + typedef T result_type; + + template + T operator()(InputIterator first, InputIterator last) const + { + // If there are no slots to call, just return the + // default-constructed value + if(first == last ) return T(); + T max_value = *first++; + while (first != last) { + if (max_value < *first) + max_value = *first; + ++first; + } + + return max_value; + } + }; + + + typedef boost::signals2::signal > sort_signal_t; LLScrollListCtrl( const std::string& name, const LLRect& rect, void (*commit_callback)(LLUICtrl*, void*), void* callback_userdata, BOOL allow_multiple_selection, - BOOL draw_border = TRUE); + BOOL draw_border = TRUE, bool draw_heading = false); virtual ~LLScrollListCtrl(); @@ -415,6 +417,7 @@ public: virtual void setColumnLabel(const std::string& column, const std::string& label); virtual LLScrollListColumn* getColumn(S32 index); + virtual LLScrollListColumn* getColumn(const std::string& name); virtual S32 getNumColumns() const { return mColumnsIndexed.size(); } // Adds a single element, from an array of: @@ -465,10 +468,17 @@ public: void deleteSelectedItems(); void deselectAllItems(BOOL no_commit_on_change = FALSE); // by default, go ahead and commit on selection change - void highlightNthItem( S32 index ); - void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; } - void setMaximumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; } - void setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; } + void clearHighlightedItems(); + + virtual void mouseOverHighlightNthItem( S32 index ); + + S32 getHighlightedItemInx() const { return mHighlightedItem; } + + void setDoubleClickCallback( callback_t cb ) { mOnDoubleClickCallback = cb; } + void setMaximumSelectCallback( callback_t cb ) { mOnMaximumSelectCallback = cb; } + void setSortChangedCallback( callback_t cb ) { mOnSortChangedCallback = cb; } + // Convenience function; *TODO: replace with setter above + boost::bind() in calling code + void setDoubleClickCallback( boost::function cb, void* userdata) { mOnDoubleClickCallback = boost::bind(cb, userdata); } void swapWithNext(S32 index); void swapWithPrevious(S32 index); @@ -480,7 +490,7 @@ public: S32 getItemIndex( LLScrollListItem* item ) const; S32 getItemIndex( const LLUUID& item_id ) const; - LLScrollListItem* addCommentText( const std::string& comment_text, EAddPosition pos = ADD_BOTTOM); + void setCommentText( const std::string& comment_text); LLScrollListItem* addSeparator(EAddPosition pos); // "Simple" interface: use this when you're creating a list that contains only unique strings, only @@ -491,6 +501,7 @@ public: BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE ); // FALSE if item not found BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE); BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE); + LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); const std::string getSelectedItemLabel(S32 column = 0) const; LLSD getSelectedValue(); @@ -503,7 +514,8 @@ public: LLScrollListItem* getFirstSelected() const; virtual S32 getFirstSelectedIndex() const; std::vector getAllSelected() const; - LLDynamicArray getSelectedIDs(); + uuid_vec_t getSelectedIDs(); //Helper. Much like getAllSelected, but just provides a LLUUID vec + S32 getNumSelected() const; LLScrollListItem* getLastSelectedItem() const { return mLastSelected; } // iterate over all items @@ -578,17 +590,26 @@ public: LLRect getItemListRect() { return mItemListRect; } + /// Returns rect, in local coords, of a given row/column + LLRect getCellRect(S32 row_index, S32 column_index); + // Used "internally" by the scroll bar. static void onScrollChange( S32 new_pos, LLScrollbar* src, void* userdata ); static void onClickColumn(void *userdata); - void updateColumns(); - void calcColumnWidths(); + virtual void updateColumns(); + S32 calcMaxContentWidth(); + bool updateColumnWidths(); S32 getMaxContentWidth() { return mMaxContentWidth; } void setDisplayHeading(BOOL display); void setHeadingHeight(S32 heading_height); + /** + * Sets max visible lines without scroolbar, if this value equals to 0, + * then display all items. + */ + void setPageLines(S32 page_lines ); void setCollapseEmptyColumns(BOOL collapse); LLScrollListItem* hitItem(S32 x,S32 y); @@ -610,17 +631,37 @@ public: std::string getSortColumnName(); BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } - BOOL needsSorting(); + BOOL hasSortOrder() const; + void clearSortOrder(); - S32 selectMultiple( LLDynamicArray ids ); - void sortItems(); + S32 selectMultiple( uuid_vec_t ids ); + // conceptually const, but mutates mItemList + void updateSort() const; // sorts a list without affecting the permanent sort order (so further list insertions can be unsorted, for example) void sortOnce(S32 column, BOOL ascending); // manually call this whenever editing list items in place to flag need for resorting - void setSorted(BOOL sorted) { mSorted = sorted; } + void setNeedsSort(bool val = true) { mSorted = !val; } + void setNeedsSortColumn(S32 col) + { + if(!isSorted())return; + for(std::vector >::iterator it=mSortColumns.begin();it!=mSortColumns.end();++it) + { + if((*it).first == col) + { + setNeedsSort(); + break; + } + } + } void dirtyColumns(); // some operation has potentially affected column layout or ordering + boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) + { + if (!mSortCallback) mSortCallback = new sort_signal_t(); + return mSortCallback->connect(cb); + } + protected: // "Full" interface: use this when you're creating a list that has one or more of the following: // * contains icons @@ -642,11 +683,13 @@ protected: typedef std::deque item_list; item_list& getItemList() { return mItemList; } + void updateLineHeight(); + private: void selectPrevItem(BOOL extend_selection); void selectNextItem(BOOL extend_selection); void drawItems(); - void updateLineHeight(); + void updateLineHeightInsert(LLScrollListItem* item); void reportInvalidInput(); BOOL isRepeatedChars(const LLWString& string) const; @@ -654,10 +697,7 @@ private: void deselectItem(LLScrollListItem* itemp); void commitIfChanged(); BOOL setSort(S32 column, BOOL ascending); - - - S32 mCurIndex; // For get[First/Next]Data - S32 mCurSelectedIndex; // For get[First/Next]Selected + S32 getLinesPerPage(); S32 mLineHeight; // the max height of a single line S32 mScrollLines; // how many lines we've scrolled down @@ -665,18 +705,19 @@ private: S32 mHeadingHeight; // the height of the column header buttons, if visible U32 mMaxSelectable; LLScrollbar* mScrollbar; - BOOL mAllowMultipleSelection; - BOOL mAllowKeyboardMovement; - BOOL mCommitOnKeyboardMovement; - BOOL mCommitOnSelectionChange; - BOOL mSelectionChanged; - BOOL mNeedsScroll; - BOOL mMouseWheelOpaque; - BOOL mCanSelect; - BOOL mDisplayColumnHeaders; - BOOL mColumnsDirty; + bool mAllowMultipleSelection; + bool mAllowKeyboardMovement; + bool mCommitOnKeyboardMovement; + bool mCommitOnSelectionChange; + bool mSelectionChanged; + bool mNeedsScroll; + bool mMouseWheelOpaque; + bool mCanSelect; + bool mDisplayColumnHeaders; + bool mColumnsDirty; + bool mColumnWidthsDirty; - item_list mItemList; + mutable item_list mItemList; LLScrollListItem *mLastSelected; @@ -700,12 +741,14 @@ private: LLColor4 mDefaultListTextColor; S32 mBorderThickness; - void (*mOnDoubleClickCallback)(void* userdata); - void (*mOnMaximumSelectCallback)(void* userdata ); - void (*mOnSortChangedCallback)(void* userdata); + callback_t mOnDoubleClickCallback; + callback_t mOnMaximumSelectCallback; + callback_t mOnSortChangedCallback; S32 mHighlightedItem; class LLViewBorder* mBorder; + + LLView *mCommentTextView; LLWString mSearchString; LLFrameTimer mSearchTimer; @@ -715,12 +758,12 @@ private: S32 mTotalStaticColumnWidth; S32 mTotalColumnPadding; - BOOL mSorted; + mutable bool mSorted; - typedef std::map column_map_t; + typedef std::map column_map_t; column_map_t mColumns; - BOOL mDirty; + bool mDirty; S32 mOriginalSelection; typedef std::vector ordered_columns_t; @@ -729,8 +772,7 @@ private: typedef std::pair sort_column_t; std::vector mSortColumns; - // HACK: Did we draw one selected item this frame? - BOOL mDrewSelected; + sort_signal_t* mSortCallback; }; // end class LLScrollListCtrl diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 24ccd848f..9a4510690 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -42,7 +42,6 @@ #include "lltextbox.h" #include "llcriticaldamp.h" #include "lluictrlfactory.h" -#include "lltabcontainervertical.h" #include "llrender.h" #include "llmultifloater.h" diff --git a/indra/llui/lltabcontainervertical.h b/indra/llui/lltabcontainervertical.h deleted file mode 100644 index ce42367f8..000000000 --- a/indra/llui/lltabcontainervertical.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file lltabcontainervertical.h - * @brief LLTabContainerVertical base class - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -// deprecated: see LLTabContainer diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 4bc9ee1fc..3be654b4a 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -3244,8 +3244,8 @@ void LLTextEditor::drawCursor() LLRect screen_pos = calcScreenRect(); LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_left), screen_pos.mBottom + llfloor(cursor_top) ); - ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]); - ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]); + ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]); + ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]); getWindow()->setLanguageTextInput( ime_pos ); } } @@ -5224,5 +5224,5 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length) S32 LLTextEditor::getPreeditFontSize() const { - return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]); + return llround(mGLFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]); } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index c5cf582e5..24e57f790 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -2,31 +2,25 @@ * @file llui.cpp * @brief UI implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,10 +33,12 @@ // Linden library includes #include "v2math.h" +#include "m3math.h" #include "v4color.h" #include "llrender.h" #include "llrect.h" #include "lldir.h" +#include "llgl.h" #include "llfontgl.h" // Project includes @@ -55,7 +51,7 @@ // // Globals // -const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f); + // Used to hide the flashing text cursor when window doesn't have focus. BOOL gShowTextEditCursor = TRUE; @@ -67,9 +63,7 @@ std::list gUntranslated; LLControlGroup* LLUI::sConfigGroup = NULL; LLControlGroup* LLUI::sIgnoresGroup = NULL; LLControlGroup* LLUI::sColorsGroup = NULL; -LLImageProviderInterface* LLUI::sImageProvider = NULL; LLUIAudioCallback LLUI::sAudioCallback = NULL; -LLVector2 LLUI::sGLScaleFactor(1.f, 1.f); LLWindow* LLUI::sWindow = NULL; LLHtmlHelp* LLUI::sHtmlHelp = NULL; BOOL LLUI::sShowXUINames = FALSE; @@ -114,1491 +108,6 @@ void make_ui_sound(const char* namep) } } -BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom) -{ - if (x < left || right < x) return FALSE; - if (y < bottom || top < y) return FALSE; - return TRUE; -} - - -// Puts GL into 2D drawing mode by turning off lighting, setting to an -// orthographic projection, etc. -void gl_state_for_2d(S32 width, S32 height) -{ - stop_glerror(); - F32 window_width = (F32) width;//gViewerWindow->getWindowWidth(); - F32 window_height = (F32) height;//gViewerWindow->getWindowHeight(); - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.loadIdentity(); - gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadIdentity(); - stop_glerror(); -} - - -void gl_draw_x(const LLRect& rect, const LLColor4& color) -{ - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.color4fv( color.mV ); - - gGL.begin( LLRender::LINES ); - gGL.vertex2i( rect.mLeft, rect.mTop ); - gGL.vertex2i( rect.mRight, rect.mBottom ); - gGL.vertex2i( rect.mLeft, rect.mBottom ); - gGL.vertex2i( rect.mRight, rect.mTop ); - gGL.end(); -} - - -void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled) -{ - gGL.color4fv(color.mV); - gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled); -} - -void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled) -{ - gGL.pushMatrix(); - left += LLFontGL::sCurOrigin.mX; - right += LLFontGL::sCurOrigin.mX; - bottom += LLFontGL::sCurOrigin.mY; - top += LLFontGL::sCurOrigin.mY; - - gGL.loadIdentity(); - gl_rect_2d(llfloor((F32)left * LLUI::sGLScaleFactor.mV[VX]) - pixel_offset, - llfloor((F32)top * LLUI::sGLScaleFactor.mV[VY]) + pixel_offset, - llfloor((F32)right * LLUI::sGLScaleFactor.mV[VX]) + pixel_offset, - llfloor((F32)bottom * LLUI::sGLScaleFactor.mV[VY]) - pixel_offset, - filled); - gGL.popMatrix(); -} - - -void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled ) -{ - stop_glerror(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // Counterclockwise quad will face the viewer - if( filled ) - { - gGL.begin( LLRender::QUADS ); - gGL.vertex2i(left, top); - gGL.vertex2i(left, bottom); - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, top); - gGL.end(); - } - else - { - if( gGLManager.mATIOffsetVerticalLines ) - { - // Work around bug in ATI driver: vertical lines are offset by (-1,-1) - gGL.begin( LLRender::LINES ); - - // Verticals - gGL.vertex2i(left + 1, top); - gGL.vertex2i(left + 1, bottom); - - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, top); - - // Horizontals - top--; - right--; - gGL.vertex2i(left, bottom); - gGL.vertex2i(right, bottom); - - gGL.vertex2i(left, top); - gGL.vertex2i(right, top); - gGL.end(); - } - else - { - top--; - right--; - gGL.begin( LLRender::LINE_STRIP ); - gGL.vertex2i(left, top); - gGL.vertex2i(left, bottom); - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, top); - gGL.vertex2i(left, top); - gGL.end(); - } - } - stop_glerror(); -} - -void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled ) -{ - gGL.color4fv( color.mV ); - gl_rect_2d( left, top, right, bottom, filled ); -} - - -void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled ) -{ - gGL.color4fv( color.mV ); - gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled ); -} - -// Given a rectangle on the screen, draws a drop shadow _outside_ -// the right and bottom edges of it. Along the right it has width "lines" -// and along the bottom it has height "lines". -void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines) -{ - stop_glerror(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // HACK: Overlap with the rectangle by a single pixel. - right--; - bottom++; - lines++; - - LLColor4 end_color = start_color; - end_color.mV[VALPHA] = 0.f; - - gGL.begin(LLRender::QUADS); - - // Right edge, CCW faces screen - gGL.color4fv(start_color.mV); - gGL.vertex2i(right, top-lines); - gGL.vertex2i(right, bottom); - gGL.color4fv(end_color.mV); - gGL.vertex2i(right+lines, bottom); - gGL.vertex2i(right+lines, top-lines); - - // Bottom edge, CCW faces screen - gGL.color4fv(start_color.mV); - gGL.vertex2i(right, bottom); - gGL.vertex2i(left+lines, bottom); - gGL.color4fv(end_color.mV); - gGL.vertex2i(left+lines, bottom-lines); - gGL.vertex2i(right, bottom-lines); - - // bottom left Corner - gGL.color4fv(start_color.mV); - gGL.vertex2i(left+lines, bottom); - gGL.color4fv(end_color.mV); - gGL.vertex2i(left, bottom); - // make the bottom left corner not sharp - gGL.vertex2i(left+1, bottom-lines+1); - gGL.vertex2i(left+lines, bottom-lines); - - // bottom right corner - gGL.color4fv(start_color.mV); - gGL.vertex2i(right, bottom); - gGL.color4fv(end_color.mV); - gGL.vertex2i(right, bottom-lines); - // make the rightmost corner not sharp - gGL.vertex2i(right+lines-1, bottom-lines+1); - gGL.vertex2i(right+lines, bottom); - - // top right corner - gGL.color4fv(start_color.mV); - gGL.vertex2i( right, top-lines ); - gGL.color4fv(end_color.mV); - gGL.vertex2i( right+lines, top-lines ); - // make the corner not sharp - gGL.vertex2i( right+lines-1, top-1 ); - gGL.vertex2i( right, top ); - - gGL.end(); - stop_glerror(); -} - -void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 ) -{ - // Work around bug in ATI driver: vertical lines are offset by (-1,-1) - if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines ) - { - x1++; - x2++; - y1++; - y2++; - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.begin(LLRender::LINES); - gGL.vertex2i(x1, y1); - gGL.vertex2i(x2, y2); - gGL.end(); -} - -void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color ) -{ - // Work around bug in ATI driver: vertical lines are offset by (-1,-1) - if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines ) - { - x1++; - x2++; - y1++; - y2++; - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.color4fv( color.mV ); - - gGL.begin(LLRender::LINES); - gGL.vertex2i(x1, y1); - gGL.vertex2i(x2, y2); - gGL.end(); -} - -void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled) -{ - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.color4fv(color.mV); - - if (filled) - { - gGL.begin(LLRender::TRIANGLES); - } - else - { - gGL.begin(LLRender::LINE_LOOP); - } - gGL.vertex2i(x1, y1); - gGL.vertex2i(x2, y2); - gGL.vertex2i(x3, y3); - gGL.end(); -} - -void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac) -{ - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - length = llmin((S32)(max_frac*(right - left)), length); - length = llmin((S32)(max_frac*(top - bottom)), length); - gGL.begin(LLRender::LINES); - gGL.vertex2i(left, top); - gGL.vertex2i(left + length, top); - - gGL.vertex2i(left, top); - gGL.vertex2i(left, top - length); - - gGL.vertex2i(left, bottom); - gGL.vertex2i(left + length, bottom); - - gGL.vertex2i(left, bottom); - gGL.vertex2i(left, bottom + length); - - gGL.vertex2i(right, top); - gGL.vertex2i(right - length, top); - - gGL.vertex2i(right, top); - gGL.vertex2i(right, top - length); - - gGL.vertex2i(right, bottom); - gGL.vertex2i(right - length, bottom); - - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, bottom + length); - gGL.end(); -} - - -void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect ) -{ - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect ); -} - -void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) -{ - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect ); -} - -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect) -{ - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - - // scale screen size of borders down - F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0); - F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0); - - LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction); - gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect); -} - -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect) -{ - stop_glerror(); - - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - - // add in offset of current image to current UI translation - const LLVector3 ui_scale = LLVector3(1.f,1.f,1.f);//gGL.getUIScale(); - const LLVector3 ui_translation = LLVector3(x,y,0.f);//(gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale); - - F32 uv_width = uv_outer_rect.getWidth(); - F32 uv_height = uv_outer_rect.getHeight(); - - // shrink scaling region to be proportional to clipped image region - LLRectf uv_center_rect( - uv_outer_rect.mLeft + (center_rect.mLeft * uv_width), - uv_outer_rect.mBottom + (center_rect.mTop * uv_height), - uv_outer_rect.mLeft + (center_rect.mRight * uv_width), - uv_outer_rect.mBottom + (center_rect.mBottom * uv_height)); - - F32 image_width = image->getWidth(0); - F32 image_height = image->getHeight(0); - - S32 image_natural_width = llround(image_width * uv_width); - S32 image_natural_height = llround(image_height * uv_height); - - LLRectf draw_center_rect( uv_center_rect.mLeft * image_width, - uv_center_rect.mTop * image_height, - uv_center_rect.mRight * image_width, - uv_center_rect.mBottom * image_height); - - { // scale fixed region of image to drawn region - draw_center_rect.mRight += width - image_natural_width; - draw_center_rect.mTop += height - image_natural_height; - - F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight); - F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop); - - F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth())); - F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight())); - - F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio); - - draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]); - draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]); - draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]); - draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]); - } - - LLRectf draw_outer_rect(ui_translation.mV[VX], - ui_translation.mV[VY] + height * ui_scale.mV[VY], - ui_translation.mV[VX] + width * ui_scale.mV[VX], - ui_translation.mV[VY]); - - LLGLSUIDefault gls_ui; - - if (solid_color) - { - if (LLGLSLShader::sNoFixedFunction) - { - gSolidColorProgram.bind(); - } - else - { - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); - gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); - } - } - - gGL.getTexUnit(0)->bind(image, true); - - gGL.color4fv(color.mV); - - const S32 NUM_VERTICES = 9 * 4; // 9 quads - LLVector2 uv[NUM_VERTICES]; - LLVector4a pos[NUM_VERTICES]; - - S32 index = 0; - - gGL.begin(LLRender::QUADS); - { - // draw bottom left - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom); - pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); - pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); - pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; - - // draw bottom middle - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); - pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); - pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; - - uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; - - // draw bottom right - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); - pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom); - pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); - pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; - - // draw left - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); - pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); - pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; - - // draw middle - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; - - // draw right - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); - pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); - index++; - - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); - pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); - index++; - - // draw top left - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); - pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); - pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop); - pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f); - index++; - - // draw top middle - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); - pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); - pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); - index++; - - // draw top right - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); - pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop); - pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f); - index++; - - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); - pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); - index++; - - gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); - } - gGL.end(); - - if (solid_color) - { - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } - else - { - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - } - } -} - -void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) -{ - gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect ); -} - -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) -{ - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - - LLGLSUIDefault gls_ui; - - - gGL.getTexUnit(0)->bind(image, true); - - gGL.color4fv(color.mV); - - if (degrees == 0.f) - { - const S32 NUM_VERTICES = 4; // 9 quads - LLVector2 uv[NUM_VERTICES]; - LLVector4a pos[NUM_VERTICES]; - - gGL.begin(LLRender::QUADS); - { - LLVector3 ui_scale = LLVector3(1.f,1.f,1.f);//gGL.getUIScale(); - LLVector3 ui_translation = LLVector3(0.f,0.f,0.f); //gGL.getUITranslation(); - ui_translation.mV[VX] += x; - ui_translation.mV[VY] += y; - ui_translation.scaleVec(ui_scale); - S32 index = 0; - S32 scaled_width = llround(width * ui_scale.mV[VX]); - S32 scaled_height = llround(height * ui_scale.mV[VY]); - - uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); - pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f); - index++; - - uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop); - pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f); - index++; - - uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); - pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY], 0.f); - index++; - - uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); - pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f); - index++; - - gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); - } - gGL.end(); - } - else - { - gGL.pushMatrix(); - gGL.translatef((F32)x, (F32)y, 0.f); - - F32 offset_x = F32(width/2); - F32 offset_y = F32(height/2); - - gGL.translatef(offset_x, offset_y, 0.f); - - LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD); - - gGL.getTexUnit(0)->bind(image, true); - - gGL.color4fv(color.mV); - - gGL.begin(LLRender::QUADS); - { - LLVector3 v; - - v = LLVector3(offset_x, offset_y, 0.f) * quat; - gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); - gGL.vertex2f(v.mV[0], v.mV[1] ); - - v = LLVector3(-offset_x, offset_y, 0.f) * quat; - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); - gGL.vertex2f(v.mV[0], v.mV[1] ); - - v = LLVector3(-offset_x, -offset_y, 0.f) * quat; - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); - gGL.vertex2f(v.mV[0], v.mV[1] ); - - v = LLVector3(offset_x, -offset_y, 0.f) * quat; - gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); - gGL.vertex2f(v.mV[0], v.mV[1] ); - } - gGL.end(); - gGL.popMatrix(); - } - -} - - -void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase ) -{ - phase = fmod(phase, 1.f); - - S32 shift = S32(phase * 4.f) % 4; - - // Stippled line - LLGLEnable stipple(GL_LINE_STIPPLE); - - gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]); - - gGL.flush(); - glLineWidth(2.5f); - if (!LLGLSLShader::sNoFixedFunction) - { - glLineStipple(2, 0x3333 << shift); - } - - - gGL.begin(LLRender::LINES); - { - gGL.vertex3fv( start.mV ); - gGL.vertex3fv( end.mV ); - } - gGL.end(); - - LLUI::setLineWidth(1.f); -} - -void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle) -{ - if (end_angle < start_angle) - { - end_angle += F_TWO_PI; - } - - gGL.pushMatrix(); - { - gGL.translatef(center_x, center_y, 0.f); - - // Inexact, but reasonably fast. - F32 delta = (end_angle - start_angle) / steps; - F32 sin_delta = sin( delta ); - F32 cos_delta = cos( delta ); - F32 x = cosf(start_angle) * radius; - F32 y = sinf(start_angle) * radius; - - if (filled) - { - gGL.begin(LLRender::TRIANGLE_FAN); - gGL.vertex2f(0.f, 0.f); - // make sure circle is complete - steps += 1; - } - else - { - gGL.begin(LLRender::LINE_STRIP); - } - - while( steps-- ) - { - // Successive rotations - gGL.vertex2f( x, y ); - F32 x_new = x * cos_delta - y * sin_delta; - y = x * sin_delta + y * cos_delta; - x = x_new; - } - gGL.end(); - } - gGL.popMatrix(); -} - -void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled) -{ - gGL.pushMatrix(); - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.translatef(center_x, center_y, 0.f); - - // Inexact, but reasonably fast. - F32 delta = F_TWO_PI / steps; - F32 sin_delta = sin( delta ); - F32 cos_delta = cos( delta ); - F32 x = radius; - F32 y = 0.f; - - if (filled) - { - gGL.begin(LLRender::TRIANGLE_FAN); - gGL.vertex2f(0.f, 0.f); - // make sure circle is complete - steps += 1; - } - else - { - gGL.begin(LLRender::LINE_LOOP); - } - - while( steps-- ) - { - // Successive rotations - gGL.vertex2f( x, y ); - F32 x_new = x * cos_delta - y * sin_delta; - y = x * sin_delta + y * cos_delta; - x = x_new; - } - gGL.end(); - } - gGL.popMatrix(); -} - -// Renders a ring with sides (tube shape) -void gl_deep_circle( F32 radius, F32 depth, S32 steps ) -{ - F32 x = radius; - F32 y = 0.f; - F32 angle_delta = F_TWO_PI / (F32)steps; - gGL.begin( LLRender::TRIANGLE_STRIP ); - { - S32 step = steps + 1; // An extra step to close the circle. - while( step-- ) - { - gGL.vertex3f( x, y, depth ); - gGL.vertex3f( x, y, 0.f ); - - F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta); - y = x * sinf(angle_delta) + y * cosf(angle_delta); - x = x_new; - } - } - gGL.end(); -} - -void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center ) -{ - gGL.pushMatrix(); - { - gGL.translatef(0.f, 0.f, -width / 2); - if( render_center ) - { - gGL.color4fv(center_color.mV); - gGL.diffuseColor4fv(center_color.mV); - gl_deep_circle( radius, width, steps ); - } - else - { - gGL.diffuseColor4fv(side_color.mV); - gl_washer_2d(radius, radius - width, steps, side_color, side_color); - gGL.translatef(0.f, 0.f, width); - gl_washer_2d(radius - width, radius, steps, side_color, side_color); - } - } - gGL.popMatrix(); -} - -// Draw gray and white checkerboard with black border -void gl_rect_2d_checkerboard(const LLRect& parent_screen_rect, const LLRect& rect, GLfloat alpha) -{ - //Already reffed in LLImageList via uuid_ui_image_map_t mUIImages. Don't use LLPointer here! - static LLUIImage* checkboard_image = LLUI::getUIImage("checkerboard.tga"); - static F32 image_width = checkboard_image->getWidth(); - static F32 image_height = checkboard_image->getHeight(); - - F32 scale_x = rect.getWidth() / image_width; - F32 scale_y = rect.getHeight() / image_height; - F32 offs_x = (parent_screen_rect.mLeft + rect.mLeft) / image_width; - F32 offs_y = (parent_screen_rect.mBottom + rect.mBottom) / image_height; - LLRectf uv_rect(offs_x,offs_y+scale_y,offs_x+scale_x,offs_y); - - LLColor4 color=UI_VERTEX_COLOR; - color.mV[VALPHA] = alpha; - gl_draw_scaled_image(rect.mLeft,rect.mBottom,rect.getWidth(),rect.getHeight(),checkboard_image->getImage(), color, uv_rect); - - gGL.flush(); -} - - -// Draws the area between two concentric circles, like -// a doughnut or washer. -void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color) -{ - const F32 DELTA = F_TWO_PI / steps; - const F32 SIN_DELTA = sin( DELTA ); - const F32 COS_DELTA = cos( DELTA ); - - F32 x1 = outer_radius; - F32 y1 = 0.f; - F32 x2 = inner_radius; - F32 y2 = 0.f; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.begin( LLRender::TRIANGLE_STRIP ); - { - steps += 1; // An extra step to close the circle. - while( steps-- ) - { - gGL.color4fv(outer_color.mV); - gGL.vertex2f( x1, y1 ); - gGL.color4fv(inner_color.mV); - gGL.vertex2f( x2, y2 ); - - F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; - y1 = x1 * SIN_DELTA + y1 * COS_DELTA; - x1 = x1_new; - - F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; - y2 = x2 * SIN_DELTA + y2 * COS_DELTA; - x2 = x2_new; - } - } - gGL.end(); -} - -// Draws the area between two concentric circles, like -// a doughnut or washer. -void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color) -{ - const F32 DELTA = (end_radians - start_radians) / steps; - const F32 SIN_DELTA = sin( DELTA ); - const F32 COS_DELTA = cos( DELTA ); - - F32 x1 = outer_radius * cos( start_radians ); - F32 y1 = outer_radius * sin( start_radians ); - F32 x2 = inner_radius * cos( start_radians ); - F32 y2 = inner_radius * sin( start_radians ); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin( LLRender::TRIANGLE_STRIP ); - { - steps += 1; // An extra step to close the circle. - while( steps-- ) - { - gGL.color4fv(outer_color.mV); - gGL.vertex2f( x1, y1 ); - gGL.color4fv(inner_color.mV); - gGL.vertex2f( x2, y2 ); - - F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; - y1 = x1 * SIN_DELTA + y1 * COS_DELTA; - x1 = x1_new; - - F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; - y2 = x2 * SIN_DELTA + y2 * COS_DELTA; - x2 = x2_new; - } - } - gGL.end(); -} - -// Draws spokes around a circle. -void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color) -{ - const F32 DELTA = F_TWO_PI / count; - const F32 HALF_DELTA = DELTA * 0.5f; - const F32 SIN_DELTA = sin( DELTA ); - const F32 COS_DELTA = cos( DELTA ); - - F32 x1 = outer_radius * cos( HALF_DELTA ); - F32 y1 = outer_radius * sin( HALF_DELTA ); - F32 x2 = inner_radius * cos( HALF_DELTA ); - F32 y2 = inner_radius * sin( HALF_DELTA ); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.begin( LLRender::LINES ); - { - while( count-- ) - { - gGL.color4fv(outer_color.mV); - gGL.vertex2f( x1, y1 ); - gGL.color4fv(inner_color.mV); - gGL.vertex2f( x2, y2 ); - - F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; - y1 = x1 * SIN_DELTA + y1 * COS_DELTA; - x1 = x1_new; - - F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; - y2 = x2 * SIN_DELTA + y2 * COS_DELTA; - x2 = x2_new; - } - } - gGL.end(); -} - -void gl_rect_2d_simple_tex( S32 width, S32 height ) -{ - gGL.begin( LLRender::QUADS ); - - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2i(width, height); - - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(0, height); - - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2i(0, 0); - - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(width, 0); - - gGL.end(); -} - -void gl_rect_2d_simple( S32 width, S32 height ) -{ - gGL.begin( LLRender::QUADS ); - gGL.vertex2i(width, height); - gGL.vertex2i(0, height); - gGL.vertex2i(0, 0); - gGL.vertex2i(width, 0); - gGL.end(); -} - -void gl_segmented_rect_2d_tex(const S32 left, - const S32 top, - const S32 right, - const S32 bottom, - const S32 texture_width, - const S32 texture_height, - const S32 border_size, - const U32 edges) -{ - S32 width = llabs(right - left); - S32 height = llabs(top - bottom); - - gGL.pushMatrix(); - - gGL.translatef((F32)left, (F32)bottom, 0.f); - LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height); - - if (border_uv_scale.mV[VX] > 0.5f) - { - border_uv_scale *= 0.5f / border_uv_scale.mV[VX]; - } - if (border_uv_scale.mV[VY] > 0.5f) - { - border_uv_scale *= 0.5f / border_uv_scale.mV[VY]; - } - - F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f); - LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; - LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; - LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; - LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; - LLVector2 width_vec((F32)width, 0.f); - LLVector2 height_vec(0.f, (F32)height); - - gGL.begin(LLRender::QUADS); - { - // draw bottom left - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2f(0.f, 0.f); - - gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv(border_width_left.mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + border_height_bottom).mV); - - gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); - gGL.vertex2fv(border_height_bottom.mV); - - // draw bottom middle - gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv(border_width_left.mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv((width_vec - border_width_right).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + border_height_bottom).mV); - - // draw bottom right - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv((width_vec - border_width_right).mV); - - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2fv(width_vec.mV); - - gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec + border_height_bottom).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - - // draw left - gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); - gGL.vertex2fv(border_height_bottom.mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + border_height_bottom).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - - gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((height_vec - border_height_top).mV); - - // draw middle - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + border_height_bottom).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - - // draw right - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - - gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec + border_height_bottom).mV); - - gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - - // draw top left - gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((height_vec - border_height_top).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((border_width_left + height_vec).mV); - - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2fv((height_vec).mV); - - // draw top middle - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((border_width_left + height_vec).mV); - - // draw top right - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2fv((width_vec + height_vec).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); - } - gGL.end(); - - gGL.popMatrix(); -} - -//FIXME: rewrite to use scissor? -void gl_segmented_rect_2d_fragment_tex(const S32 left, - const S32 top, - const S32 right, - const S32 bottom, - const S32 texture_width, - const S32 texture_height, - const S32 border_size, - const F32 start_fragment, - const F32 end_fragment, - const U32 edges) -{ - S32 width = llabs(right - left); - S32 height = llabs(top - bottom); - - gGL.pushMatrix(); - - gGL.translatef((F32)left, (F32)bottom, 0.f); - LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height); - - if (border_uv_scale.mV[VX] > 0.5f) - { - border_uv_scale *= 0.5f / border_uv_scale.mV[VX]; - } - if (border_uv_scale.mV[VY] > 0.5f) - { - border_uv_scale *= 0.5f / border_uv_scale.mV[VY]; - } - - F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f); - LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; - LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; - LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; - LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; - LLVector2 width_vec((F32)width, 0.f); - LLVector2 height_vec(0.f, (F32)height); - - F32 middle_start = border_scale / (F32)width; - F32 middle_end = 1.f - middle_start; - - F32 u_min; - F32 u_max; - LLVector2 x_min; - LLVector2 x_max; - - gGL.begin(LLRender::QUADS); - { - if (start_fragment < middle_start) - { - u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX]; - u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX]; - x_min = (start_fragment / middle_start) * border_width_left; - x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left; - - // draw bottom left - gGL.texCoord2f(u_min, 0.f); - gGL.vertex2fv(x_min.mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv(x_max.mV); - - gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - // draw left - gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - // draw top left - gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_max, 1.f); - gGL.vertex2fv((x_max + height_vec).mV); - - gGL.texCoord2f(u_min, 1.f); - gGL.vertex2fv((x_min + height_vec).mV); - } - - if (end_fragment > middle_start || start_fragment < middle_end) - { - x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec; - x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec; - - // draw bottom middle - gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv(x_min.mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv((x_max).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - // draw middle - gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - // draw top middle - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((x_max + height_vec).mV); - - gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((x_min + height_vec).mV); - } - - if (end_fragment > middle_end) - { - u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX]; - u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]; - x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right); - x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right); - - // draw bottom right - gGL.texCoord2f(u_min, 0.f); - gGL.vertex2fv((x_min).mV); - - gGL.texCoord2f(u_max, 0.f); - gGL.vertex2fv(x_max.mV); - - gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - // draw right - gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + border_height_bottom).mV); - - gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + border_height_bottom).mV); - - gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - // draw top right - gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - - gGL.texCoord2f(u_max, 1.f); - gGL.vertex2fv((x_max + height_vec).mV); - - gGL.texCoord2f(u_min, 1.f); - gGL.vertex2fv((x_min + height_vec).mV); - } - } - gGL.end(); - - gGL.popMatrix(); -} - -void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, - const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, - const U32 edges) -{ - LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero; - LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero; - - LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero; - LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero; - - - gGL.begin(LLRender::QUADS); - { - // draw bottom left - gGL.texCoord2f(0.f, 0.f); - gGL.vertex3f(0.f, 0.f, 0.f); - - gGL.texCoord2f(border_scale.mV[VX], 0.f); - gGL.vertex3fv(left_border_width.mV); - - gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + bottom_border_height).mV); - - gGL.texCoord2f(0.f, border_scale.mV[VY]); - gGL.vertex3fv(bottom_border_height.mV); - - // draw bottom middle - gGL.texCoord2f(border_scale.mV[VX], 0.f); - gGL.vertex3fv(left_border_width.mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f); - gGL.vertex3fv((width_vec - right_border_width).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - - gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + bottom_border_height).mV); - - // draw bottom right - gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f); - gGL.vertex3fv((width_vec - right_border_width).mV); - - gGL.texCoord2f(1.f, 0.f); - gGL.vertex3fv(width_vec.mV); - - gGL.texCoord2f(1.f, border_scale.mV[VY]); - gGL.vertex3fv((width_vec + bottom_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - - // draw left - gGL.texCoord2f(0.f, border_scale.mV[VY]); - gGL.vertex3fv(bottom_border_height.mV); - - gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + bottom_border_height).mV); - - gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]); - gGL.vertex3fv((height_vec - top_border_height).mV); - - // draw middle - gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + bottom_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - - // draw right - gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - - gGL.texCoord2f(1.f, border_scale.mV[VY]); - gGL.vertex3fv((width_vec + bottom_border_height).mV); - - gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec + height_vec - top_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - - // draw top left - gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]); - gGL.vertex3fv((height_vec - top_border_height).mV); - - gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(border_scale.mV[VX], 1.f); - gGL.vertex3fv((left_border_width + height_vec).mV); - - gGL.texCoord2f(0.f, 1.f); - gGL.vertex3fv((height_vec).mV); - - // draw top middle - gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f); - gGL.vertex3fv((width_vec - right_border_width + height_vec).mV); - - gGL.texCoord2f(border_scale.mV[VX], 1.f); - gGL.vertex3fv((left_border_width + height_vec).mV); - - // draw top right - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - - gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]); - gGL.vertex3fv((width_vec + height_vec - top_border_height).mV); - - gGL.texCoord2f(1.f, 1.f); - gGL.vertex3fv((width_vec + height_vec).mV); - - gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f); - gGL.vertex3fv((width_vec - right_border_width + height_vec).mV); - } - gGL.end(); - -} - -void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec) -{ - gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP); -} - bool handleShowXUINamesChanged(const LLSD& newvalue) { LLUI::sShowXUINames = newvalue.asBoolean(); @@ -1614,6 +123,7 @@ void LLUI::initClass(LLControlGroup* config, const std::string& language ) { + LLRender2D::initClass(image_provider, scale_factor); sConfigGroup = config; sIgnoresGroup = ignores; sColorsGroup = colors; @@ -1625,9 +135,7 @@ void LLUI::initClass(LLControlGroup* config, llerrs << "Failure to initialize configuration groups" << llendl; } - sImageProvider = image_provider; sAudioCallback = audio_callback; - sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor; sWindow = NULL; // set later in startup LLFontGL::sShadowColor = colors->getColor("ColorDropShadow"); @@ -1637,64 +145,16 @@ void LLUI::initClass(LLControlGroup* config, void LLUI::cleanupClass() { - sImageProvider->cleanUp(); + LLRender2D::cleanupClass(); LLLineEditor::cleanupLineEditor(); } - -//static -void LLUI::translate(F32 x, F32 y, F32 z) -{ - gGL.translatef(x,y,z); - LLFontGL::sCurOrigin.mX += (S32) x; - LLFontGL::sCurOrigin.mY += (S32) y; - LLFontGL::sCurDepth += z; -} - -//static -void LLUI::pushMatrix() -{ - gGL.pushMatrix(); - LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth)); -} - -//static -void LLUI::popMatrix() -{ - gGL.popMatrix(); - LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first; - LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second; - LLFontGL::sOriginStack.pop_back(); -} - -//static -void LLUI::loadIdentity() -{ - gGL.loadIdentity(); - LLFontGL::sCurOrigin.mX = 0; - LLFontGL::sCurOrigin.mY = 0; - LLFontGL::sCurDepth = 0.f; -} - -//static -void LLUI::setScaleFactor(const LLVector2 &scale_factor) -{ - sGLScaleFactor = scale_factor; -} - -//static -void LLUI::setLineWidth(F32 width) -{ - gGL.flush(); - glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f)); -} - //static void LLUI::setMousePositionScreen(S32 x, S32 y) { S32 screen_x, screen_y; - screen_x = llround((F32)x * sGLScaleFactor.mV[VX]); - screen_y = llround((F32)y * sGLScaleFactor.mV[VY]); + screen_x = llround((F32)x * getScaleFactor().mV[VX]); + screen_y = llround((F32)y * getScaleFactor().mV[VY]); LLCoordWindow window_point; LLView::getWindow()->convertCoords(LLCoordGL(screen_x, screen_y), &window_point); @@ -1709,8 +169,8 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y) LLView::getWindow()->getCursorPosition(&cursor_pos_window); LLCoordGL cursor_pos_gl; LLView::getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl); - *x = llround((F32)cursor_pos_gl.mX / sGLScaleFactor.mV[VX]); - *y = llround((F32)cursor_pos_gl.mY / sGLScaleFactor.mV[VX]); + *x = llround((F32)cursor_pos_gl.mX / getScaleFactor().mV[VX]); + *y = llround((F32)cursor_pos_gl.mY / getScaleFactor().mV[VX]); } //static @@ -1795,21 +255,21 @@ LLVector2 LLUI::getWindowSize() LLCoordWindow window_rect; sWindow->getSize(&window_rect); - return LLVector2(window_rect.mX / sGLScaleFactor.mV[VX], window_rect.mY / sGLScaleFactor.mV[VY]); + return LLVector2(window_rect.mX / getScaleFactor().mV[VX], window_rect.mY / getScaleFactor().mV[VY]); } //static void LLUI::screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y) { - *gl_x = llround((F32)screen_x * sGLScaleFactor.mV[VX]); - *gl_y = llround((F32)screen_y * sGLScaleFactor.mV[VY]); + *gl_x = llround((F32)screen_x * getScaleFactor().mV[VX]); + *gl_y = llround((F32)screen_y * getScaleFactor().mV[VY]); } //static void LLUI::glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y) { - *screen_x = llround((F32)gl_x / sGLScaleFactor.mV[VX]); - *screen_y = llround((F32)gl_y / sGLScaleFactor.mV[VY]); + *screen_x = llround((F32)gl_x / getScaleFactor().mV[VX]); + *screen_y = llround((F32)gl_y / getScaleFactor().mV[VY]); } //static @@ -1826,28 +286,6 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen) glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom); } -//static -LLPointer LLUI::getUIImageByID(const LLUUID& image_id, S32 priority) -{ - if (sImageProvider) - { - return sImageProvider->getUIImageByID(image_id, priority); - } - else - { - return NULL; - } -} - -//static -LLPointer LLUI::getUIImage(const std::string& name, S32 priority) -{ - if (!name.empty() && sImageProvider) - return sImageProvider->getUIImage(name, priority); - else - return NULL; -} - // static void LLUI::setHtmlHelp(LLHtmlHelp* html_help) { diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 556a3b895..570f668e8 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -1,145 +1,52 @@ /** * @file llui.h - * @brief GL function declarations and other general static UI services. + * @brief General static UI services. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -// All immediate-mode gl drawing should happen here. #ifndef LL_LLUI_H #define LL_LLUI_H -#include "llpointer.h" // LLPointer<> #include "llrect.h" #include "llcontrol.h" #include "llcoord.h" -#include "llglslshader.h" -//#include "llhtmlhelp.h" -#include "llgl.h" // *TODO: break this dependency -#include -#include "lltexture.h" +#include "v2math.h" +#include "llrender2dutils.h" +#include "llpointer.h" +#include "lluiimage.h" #include // LLUIFactory #include "llsd.h" -class LLColor4; class LLHtmlHelp; -class LLVector3; -class LLVector2; -class LLUIImage; class LLUUID; class LLWindow; class LLView; -// UI colors -extern const LLColor4 UI_VERTEX_COLOR; void make_ui_sound(const char* name); -BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom); -void gl_state_for_2d(S32 width, S32 height); - -void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2); -void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color ); -void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled); -void gl_rect_2d_simple( S32 width, S32 height ); - -void gl_draw_x(const LLRect& rect, const LLColor4& color); - -void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE ); -void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE ); -void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE ); -void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE ); -void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE ); -void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE ); -void gl_rect_2d_checkerboard(const LLRect& parent_screen_rect, const LLRect& rect, GLfloat alpha = 1.0f); - -void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines); - -void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled); -void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle); -void gl_deep_circle( F32 radius, F32 depth ); -void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center ); -void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac); -void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); -void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); -void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color); - -void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); - -void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); - -void gl_rect_2d_simple_tex( S32 width, S32 height ); - -// segmented rectangles - -/* - TL |______TOP_________| TR - /| |\ - _/_|__________________|_\_ - L| | MIDDLE | |R - _|_|__________________|_|_ - \ | BOTTOM | / - BL\|__________________|/ BR - | | -*/ - -typedef enum e_rounded_edge -{ - ROUNDED_RECT_LEFT = 0x1, - ROUNDED_RECT_TOP = 0x2, - ROUNDED_RECT_RIGHT = 0x4, - ROUNDED_RECT_BOTTOM = 0x8, - ROUNDED_RECT_ALL = 0xf -}ERoundedEdge; - - -void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL); -void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL); -void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL); -void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec); - -inline void gl_rect_2d( const LLRect& rect, BOOL filled ) -{ - gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled ); -} - -inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled) -{ - gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled ); -} - // Used to hide the flashing text cursor when window doesn't have focus. extern BOOL gShowTextEditCursor; @@ -163,10 +70,10 @@ public: const std::string& language = LLStringUtil::null); static void cleanupClass(); - static void pushMatrix(); - static void popMatrix(); - static void loadIdentity(); - static void translate(F32 x, F32 y, F32 z = 0.0f); + static void pushMatrix() { LLRender2D::pushMatrix(); } + static void popMatrix() { LLRender2D::popMatrix(); } + static void loadIdentity() { LLRender2D::loadIdentity(); } + static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); } // Return the ISO639 language name ("en", "ko", etc.) for the viewer UI. // http://www.loc.gov/standards/iso639-2/php/code_list.php @@ -178,10 +85,13 @@ public: static void getMousePositionScreen(S32 *x, S32 *y); static void setMousePositionLocal(const LLView* viewp, S32 x, S32 y); static void getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y); - static void setScaleFactor(const LLVector2& scale_factor); - static void setLineWidth(F32 width); - static LLPointer getUIImageByID(const LLUUID& image_id, S32 priority = 0); - static LLPointer getUIImage(const std::string& name, S32 priority = 0); + static LLVector2& getScaleFactor() { return LLRender2D::sGLScaleFactor; } + static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::setScaleFactor(scale_factor); } + static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); } + static LLPointer getUIImageByID(const LLUUID& image_id, S32 priority = 0) + { return LLRender2D::getUIImageByID(image_id, priority); } + static LLPointer getUIImage(const std::string& name, S32 priority = 0) + { return LLRender2D::getUIImage(name, priority); } static LLVector2 getWindowSize(); static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y); static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y); @@ -195,9 +105,7 @@ public: static LLControlGroup* sConfigGroup; static LLControlGroup* sIgnoresGroup; static LLControlGroup* sColorsGroup; - static LLImageProviderInterface* sImageProvider; static LLUIAudioCallback sAudioCallback; - static LLVector2 sGLScaleFactor; static LLWindow* sWindow; static BOOL sShowXUINames; static LLHtmlHelp* sHtmlHelp; @@ -388,18 +296,7 @@ private: template T* LLUISingleton::sInstance = NULL; - -//RN: maybe this needs to moved elsewhere? -class LLImageProviderInterface -{ -protected: - LLImageProviderInterface() {}; - virtual ~LLImageProviderInterface() {}; -public: - virtual LLPointer getUIImage(const std::string& name, S32 priority) = 0; - virtual LLPointer getUIImageByID(const LLUUID& id, S32 priority) = 0; - virtual void cleanUp() = 0; -}; +// Moved LLLocalClipRect to lllocalcliprect.h class LLCallbackRegistry { diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 23d4290b5..58cb3e5fa 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -527,10 +527,6 @@ BOOL LLUICtrl::getTentative() const return mTentative; } -// virtual -void LLUICtrl::setDoubleClickCallback( void (*cb)(void*) ) -{ -} // virtual void LLUICtrl::setColor(const LLColor4& color) diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index c8f9b4b85..69841a042 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -37,11 +37,13 @@ #include "llview.h" #include "llrect.h" #include "llsd.h" +#include +#include #include "llviewmodel.h" // *TODO move dependency to .cpp file class LLUICtrl -: public LLView +: public LLView, public boost::signals2::trackable { public: typedef boost::function commit_callback_t; @@ -103,7 +105,6 @@ public: // Default to no-op: virtual void onTabInto(); virtual void clear(); - virtual void setDoubleClickCallback( void (*cb)(void*) ); virtual void setColor(const LLColor4& color); virtual void setAlpha(F32 alpha); virtual void setMinValue(LLSD min_value); diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 24a13d36e..eb86f1e96 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -64,7 +64,6 @@ #include "llmultisliderctrl.h" #include "llspinctrl.h" #include "lltabcontainer.h" -#include "lltabcontainervertical.h" #include "lltextbox.h" #include "lltexteditor.h" #include "llui.h" diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index ae81cce24..07f99132b 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1185,7 +1185,7 @@ void LLView::drawChildren() { // Only draw views that are within the root view LLRect screen_rect = viewp->calcScreenRect(); - if ( rootp->getLocalRect().overlaps(screen_rect) ) + if ( rootp->getRect().overlaps(screen_rect) ) { //gGL.matrixMode(LLRender::MM_MODELVIEW); LLUI::pushMatrix(); diff --git a/indra/llui/llview.h b/indra/llui/llview.h index a742b2c56..233e56bbc 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -132,8 +132,8 @@ public: class LLView : public LLMouseHandler, // handles mouse events public LLFocusableElement, // handles keyboard events - public LLMortician // lazy deletion - //public LLHandleProvider // passes out weak references to self + public LLMortician, // lazy deletion + public LLHandleProvider // passes out weak references to self { public: struct Follows : public LLInitParam::ChoiceBlock @@ -344,8 +344,6 @@ public: void popVisible() { setVisible(mLastVisible); } BOOL getLastVisible() const { return mLastVisible; } - LLHandle getHandle() { mHandle.bind(this); return mHandle; } - U32 getFollows() const { return mReshapeFlags; } BOOL followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; } BOOL followsRight() const { return mReshapeFlags & FOLLOWS_RIGHT; } @@ -679,7 +677,6 @@ private: BOOL mIsFocusRoot; BOOL mUseBoundingRect; // hit test against bounding rectangle that includes all child elements - LLRootHandle mHandle; BOOL mLastVisible; S32 mNextInsertionOrdinal; diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 63023a28e..78e856d0d 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -2,31 +2,25 @@ * @file lldir.cpp * @brief implementation of directory utilities base class * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h index 250369b78..d87249fd6 100644 --- a/indra/llvfs/lldir.h +++ b/indra/llvfs/lldir.h @@ -1,32 +1,26 @@ -/** +/** * @file lldir.h * @brief Definition of directory utilities class * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -62,7 +56,7 @@ typedef enum ELLPath LL_PATH_LAST } ELLPath; - +/// Directory operations class LLDir { public: diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp index 3c74e50a4..e3090d8c5 100644 --- a/indra/llvfs/lldir_linux.cpp +++ b/indra/llvfs/lldir_linux.cpp @@ -2,31 +2,25 @@ * @file lldir_linux.cpp * @brief Implementation of directory utilities for linux * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp index c15bc7ee0..114dc0c47 100644 --- a/indra/llvfs/lldir_mac.cpp +++ b/indra/llvfs/lldir_mac.cpp @@ -2,33 +2,27 @@ * @file lldir_mac.cpp * @brief Implementation of directory utilities for Mac OS X * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ - */ + */ #if LL_DARWIN diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index 009add14b..194fe617a 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -2,31 +2,25 @@ * @file lldir_win32.cpp * @brief Implementation of directory utilities for windows * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llvfs/lllfsthread.cpp b/indra/llvfs/lllfsthread.cpp index ed5894434..249e6a172 100644 --- a/indra/llvfs/lllfsthread.cpp +++ b/indra/llvfs/lllfsthread.cpp @@ -2,31 +2,25 @@ * @file lllfsthread.cpp * @brief LLLFSThread base class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -51,7 +45,7 @@ void LLLFSThread::initClass(bool local_is_threaded) //static S32 LLLFSThread::updateClass(U32 ms_elapsed) { - sLocal->update(ms_elapsed); + sLocal->update((F32)ms_elapsed); return sLocal->getPending(); } diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp index 85d41b5d3..f45b88b1b 100644 --- a/indra/llvfs/llpidlock.cpp +++ b/indra/llvfs/llpidlock.cpp @@ -3,31 +3,25 @@ * @date January 2007 * @brief string formatting utility * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp index d381a01f1..7825c35fe 100644 --- a/indra/llvfs/llvfile.cpp +++ b/indra/llvfs/llvfile.cpp @@ -2,31 +2,25 @@ * @file llvfile.cpp * @brief Implementation of virtual file * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llvfs/llvfile.h b/indra/llvfs/llvfile.h index 6a112cc45..aaf78228f 100644 --- a/indra/llvfs/llvfile.h +++ b/indra/llvfs/llvfile.h @@ -2,31 +2,25 @@ * @file llvfile.h * @brief Definition of virtual file * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp index 44bdc54a7..1f87c1440 100644 --- a/indra/llvfs/llvfs.cpp +++ b/indra/llvfs/llvfs.cpp @@ -2,31 +2,25 @@ * @file llvfs.cpp * @brief Implementation of virtual file system * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llvfs/llvfs.h b/indra/llvfs/llvfs.h index da57d0468..87a83c192 100644 --- a/indra/llvfs/llvfs.h +++ b/indra/llvfs/llvfs.h @@ -2,31 +2,25 @@ * @file llvfs.h * @brief Definition of virtual file system * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -122,19 +116,19 @@ private: // Use createLLVFS() to open a VFS file // Pass 0 to not presize LLVFS(const std::string& index_filename, - const std::string& data_filename, - const BOOL read_only, - const U32 presize, - const BOOL remove_after_crash); + const std::string& data_filename, + const BOOL read_only, + const U32 presize, + const BOOL remove_after_crash); public: ~LLVFS(); // Use this function normally to create LLVFS files // Pass 0 to not presize - static LLVFS * createLLVFS(const std::string& index_filename, - const std::string& data_filename, - const BOOL read_only, - const U32 presize, + static LLVFS * createLLVFS(const std::string& index_filename, + const std::string& data_filename, + const BOOL read_only, + const U32 presize, const BOOL remove_after_crash); BOOL isValid() const { return (VFSVALID_OK == mValid); } diff --git a/indra/llvfs/llvfsthread.cpp b/indra/llvfs/llvfsthread.cpp index 69da4b75e..a57e2b15a 100644 --- a/indra/llvfs/llvfsthread.cpp +++ b/indra/llvfs/llvfsthread.cpp @@ -2,31 +2,25 @@ * @file llvfsthread.cpp * @brief LLVFSThread implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -52,7 +46,7 @@ void LLVFSThread::initClass(bool local_is_threaded) //static S32 LLVFSThread::updateClass(U32 ms_elapsed) { - sLocal->update(ms_elapsed); + sLocal->update((F32)ms_elapsed); return sLocal->getPending(); } diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index f0f618aef..09502ebac 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -2,31 +2,25 @@ * @file llkeyboard.cpp * @brief Handler for assignable key bindings * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,7 +30,6 @@ #include "llwindowcallbacks.h" - // // Globals // diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index 0261bcbeb..f8b155bf1 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -2,31 +2,25 @@ * @file llkeyboard.h * @brief Handler for assignable key bindings * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp index f53773c39..ecc263166 100644 --- a/indra/llwindow/llkeyboardmacosx.cpp +++ b/indra/llwindow/llkeyboardmacosx.cpp @@ -2,31 +2,25 @@ * @file llkeyboardmacosx.cpp * @brief Handler for assignable key bindings * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp index 8a0b1de98..4bb960336 100644 --- a/indra/llwindow/llkeyboardsdl.cpp +++ b/indra/llwindow/llkeyboardsdl.cpp @@ -2,31 +2,25 @@ * @file llkeyboardsdl.cpp * @brief Handler for assignable key bindings * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp index 1d3fa0fc6..df78816bd 100644 --- a/indra/llwindow/llkeyboardwin32.cpp +++ b/indra/llwindow/llkeyboardwin32.cpp @@ -2,31 +2,25 @@ * @file llkeyboardwin32.cpp * @brief Handler for assignable key bindings * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,6 +37,7 @@ #include "llwindowcallbacks.h" + LLKeyboardWin32::LLKeyboardWin32() { // Set up key mapping for windows - eventually can read this from a file? diff --git a/indra/llwindow/llmousehandler.h b/indra/llwindow/llmousehandler.h index 2163b54e5..3f94ec46f 100644 --- a/indra/llwindow/llmousehandler.h +++ b/indra/llwindow/llmousehandler.h @@ -2,31 +2,25 @@ * @file llmousehandler.h * @brief LLMouseHandler class definition * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llpreeditor.h b/indra/llwindow/llpreeditor.h index 623406f30..02b64f07e 100644 --- a/indra/llwindow/llpreeditor.h +++ b/indra/llwindow/llpreeditor.h @@ -4,31 +4,25 @@ * an "input method editor" to type Kanji. * @author Open source patch, incorporated by Dave Simmons * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index f3e28cd26..9d0d73b81 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -2,31 +2,25 @@ * @file llwindow.cpp * @brief Basic graphical window class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,8 +42,9 @@ #include "linked_lists.h" #include "llwindowcallbacks.h" + // -// LLWindowCallbacks +// Globals // LLSplashScreen *gSplashScreenp = NULL; BOOL gDebugClicks = FALSE; diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 82e9e190a..792a7587f 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -2,31 +2,25 @@ * @file llwindow.h * @brief Basic graphical window class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -179,7 +173,7 @@ public: virtual void setTitle(const std::string &title){}; protected: -LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags); + LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags); virtual ~LLWindow(); // Defaults to true virtual BOOL isValid(); diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp index 6486b0a36..e6e6bc67f 100644 --- a/indra/llwindow/llwindowheadless.cpp +++ b/indra/llwindow/llwindowheadless.cpp @@ -2,31 +2,25 @@ * @file llwindowheadless.cpp * @brief Headless implementation of LLWindow class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index b73c349f9..1e911d754 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -2,31 +2,25 @@ * @file llwindowheadless.h * @brief Headless definition of LLWindow class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 08a4fab67..0f4883665 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1,32 +1,26 @@ -/** +/** * @file llwindowmacosx.cpp * @brief Platform-dependent implementation of llwindow * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -2787,43 +2781,43 @@ const char* cursorIDToName(int id) { switch (id) { - case UI_CURSOR_ARROW: return "UI_CURSOR_ARROW"; - case UI_CURSOR_WAIT: return "UI_CURSOR_WAIT"; - case UI_CURSOR_HAND: return "UI_CURSOR_HAND"; - case UI_CURSOR_IBEAM: return "UI_CURSOR_IBEAM"; - case UI_CURSOR_CROSS: return "UI_CURSOR_CROSS"; - case UI_CURSOR_SIZENWSE: return "UI_CURSOR_SIZENWSE"; - case UI_CURSOR_SIZENESW: return "UI_CURSOR_SIZENESW"; - case UI_CURSOR_SIZEWE: return "UI_CURSOR_SIZEWE"; - case UI_CURSOR_SIZENS: return "UI_CURSOR_SIZENS"; - case UI_CURSOR_NO: return "UI_CURSOR_NO"; - case UI_CURSOR_WORKING: return "UI_CURSOR_WORKING"; - case UI_CURSOR_TOOLGRAB: return "UI_CURSOR_TOOLGRAB"; - case UI_CURSOR_TOOLLAND: return "UI_CURSOR_TOOLLAND"; - case UI_CURSOR_TOOLFOCUS: return "UI_CURSOR_TOOLFOCUS"; - case UI_CURSOR_TOOLCREATE: return "UI_CURSOR_TOOLCREATE"; - case UI_CURSOR_ARROWDRAG: return "UI_CURSOR_ARROWDRAG"; - case UI_CURSOR_ARROWCOPY: return "UI_CURSOR_ARROWCOPY"; - case UI_CURSOR_ARROWDRAGMULTI: return "UI_CURSOR_ARROWDRAGMULTI"; - case UI_CURSOR_ARROWCOPYMULTI: return "UI_CURSOR_ARROWCOPYMULTI"; - case UI_CURSOR_NOLOCKED: return "UI_CURSOR_NOLOCKED"; - case UI_CURSOR_ARROWLOCKED: return "UI_CURSOR_ARROWLOCKED"; - case UI_CURSOR_GRABLOCKED: return "UI_CURSOR_GRABLOCKED"; - case UI_CURSOR_TOOLTRANSLATE: return "UI_CURSOR_TOOLTRANSLATE"; - case UI_CURSOR_TOOLROTATE: return "UI_CURSOR_TOOLROTATE"; - case UI_CURSOR_TOOLSCALE: return "UI_CURSOR_TOOLSCALE"; - case UI_CURSOR_TOOLCAMERA: return "UI_CURSOR_TOOLCAMERA"; - case UI_CURSOR_TOOLPAN: return "UI_CURSOR_TOOLPAN"; - case UI_CURSOR_TOOLZOOMIN: return "UI_CURSOR_TOOLZOOMIN"; - case UI_CURSOR_TOOLPICKOBJECT3: return "UI_CURSOR_TOOLPICKOBJECT3"; - case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY"; - case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE"; - case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN"; - case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE"; - case UI_CURSOR_TOOLSIT: return "UI_CURSOR_TOOLSIT"; - case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY"; - case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN"; - case UI_CURSOR_TOOLPAY: return "UI_CURSOR_TOOLPAY"; + case UI_CURSOR_ARROW: return "UI_CURSOR_ARROW"; + case UI_CURSOR_WAIT: return "UI_CURSOR_WAIT"; + case UI_CURSOR_HAND: return "UI_CURSOR_HAND"; + case UI_CURSOR_IBEAM: return "UI_CURSOR_IBEAM"; + case UI_CURSOR_CROSS: return "UI_CURSOR_CROSS"; + case UI_CURSOR_SIZENWSE: return "UI_CURSOR_SIZENWSE"; + case UI_CURSOR_SIZENESW: return "UI_CURSOR_SIZENESW"; + case UI_CURSOR_SIZEWE: return "UI_CURSOR_SIZEWE"; + case UI_CURSOR_SIZENS: return "UI_CURSOR_SIZENS"; + case UI_CURSOR_NO: return "UI_CURSOR_NO"; + case UI_CURSOR_WORKING: return "UI_CURSOR_WORKING"; + case UI_CURSOR_TOOLGRAB: return "UI_CURSOR_TOOLGRAB"; + case UI_CURSOR_TOOLLAND: return "UI_CURSOR_TOOLLAND"; + case UI_CURSOR_TOOLFOCUS: return "UI_CURSOR_TOOLFOCUS"; + case UI_CURSOR_TOOLCREATE: return "UI_CURSOR_TOOLCREATE"; + case UI_CURSOR_ARROWDRAG: return "UI_CURSOR_ARROWDRAG"; + case UI_CURSOR_ARROWCOPY: return "UI_CURSOR_ARROWCOPY"; + case UI_CURSOR_ARROWDRAGMULTI: return "UI_CURSOR_ARROWDRAGMULTI"; + case UI_CURSOR_ARROWCOPYMULTI: return "UI_CURSOR_ARROWCOPYMULTI"; + case UI_CURSOR_NOLOCKED: return "UI_CURSOR_NOLOCKED"; + case UI_CURSOR_ARROWLOCKED: return "UI_CURSOR_ARROWLOCKED"; + case UI_CURSOR_GRABLOCKED: return "UI_CURSOR_GRABLOCKED"; + case UI_CURSOR_TOOLTRANSLATE: return "UI_CURSOR_TOOLTRANSLATE"; + case UI_CURSOR_TOOLROTATE: return "UI_CURSOR_TOOLROTATE"; + case UI_CURSOR_TOOLSCALE: return "UI_CURSOR_TOOLSCALE"; + case UI_CURSOR_TOOLCAMERA: return "UI_CURSOR_TOOLCAMERA"; + case UI_CURSOR_TOOLPAN: return "UI_CURSOR_TOOLPAN"; + case UI_CURSOR_TOOLZOOMIN: return "UI_CURSOR_TOOLZOOMIN"; + case UI_CURSOR_TOOLPICKOBJECT3: return "UI_CURSOR_TOOLPICKOBJECT3"; + case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY"; + case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE"; + case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN"; + case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE"; + case UI_CURSOR_TOOLSIT: return "UI_CURSOR_TOOLSIT"; + case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY"; + case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN"; + case UI_CURSOR_TOOLPAY: return "UI_CURSOR_TOOLPAY"; } llerrs << "cursorIDToName: unknown cursor id" << id << llendl; diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index c3ec80167..89eca5750 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -2,31 +2,25 @@ * @file llwindowmacosx.h * @brief Mac implementation of LLWindow class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llwindowmesaheadless.cpp b/indra/llwindow/llwindowmesaheadless.cpp index 48736d920..11c22ac94 100644 --- a/indra/llwindow/llwindowmesaheadless.cpp +++ b/indra/llwindow/llwindowmesaheadless.cpp @@ -2,31 +2,25 @@ * @file llwindowmesaheadless.cpp * @brief Platform-dependent implementation of llwindow * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index cb4447232..db7cb4375 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -2,31 +2,25 @@ * @file llwindowmesaheadless.h * @brief Windows implementation of LLWindow class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 68bb663a3..e50956403 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -3,31 +3,25 @@ * @brief SDL implementation of LLWindow class * @author This module has many fathers, and it shows. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -1372,7 +1366,7 @@ BOOL LLWindowSDL::pasteTextFromPrimary(LLWString &dst) BOOL LLWindowSDL::copyTextToPrimary(const LLWString &s) { - return FALSE; // unsupported + return FALSE; // unsupported } #endif // LL_GTK diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index f9dba726d..4ec4236af 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -2,31 +2,25 @@ * @file llwindowsdl.h * @brief SDL implementation of LLWindow class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 53ba137d0..01d198783 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2,31 +2,25 @@ * @file llwindowwin32.cpp * @brief Platform-dependent implementation of llwindow * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -866,7 +860,9 @@ BOOL LLWindowWin32::setPosition(const LLCoordScreen position) return FALSE; } getSize(&size); + moveWindow(position, size); + return TRUE; } @@ -881,6 +877,7 @@ BOOL LLWindowWin32::setSize(const LLCoordScreen size) } moveWindow(position, size); + return TRUE; } @@ -1655,6 +1652,23 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre // THIS CAUSES DEV-15484 and DEV-15949 //ShowWindow(mWindowHandle, SW_RESTORE); + + // Singu note: Attempt at fixing this in a different way. Keep an eye out for regression. DEV-15484 showed graphical corruption, especially on impostors. + LLCoordScreen old_pos; + LLCoordScreen old_size; + getSize(&old_size); + getPosition(&old_pos); + if(position != old_pos || size != old_size) + { + WINDOWPLACEMENT placement; + placement.length = sizeof(WINDOWPLACEMENT); + if(GetWindowPlacement(mWindowHandle, &placement)) + { + placement.showCmd = SW_NORMAL; + SetWindowPlacement(mWindowHandle, &placement); + } + } + // NOW we can call MoveWindow MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE); } @@ -2468,7 +2482,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONUP"); LLFastTimer t2(FTM_MOUSEHANDLER); - // Because we move the cursor position in tllviewerhe app, we need to query + // Because we move the cursor position in the llviewer app, we need to query // to find out where the cursor at the time the event is handled. // If we don't do this, many clicks could get buffered up, and if the // first click changes the cursor position, all subsequent clicks @@ -3273,6 +3287,8 @@ void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url, bool async) // let the OS decide what to use to open the URL SHELLEXECUTEINFO sei = { sizeof( sei ) }; + // NOTE: this assumes that SL will stick around long enough to complete the DDE message exchange + // necessary for ShellExecuteEx to complete if (async) { sei.fMask = SEE_MASK_ASYNCOK; diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 63912592f..c24fbdca7 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -2,31 +2,25 @@ * @file llwindowwin32.h * @brief Windows implementation of LLWindow class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 86dd63f37..66ac78657 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -2,31 +2,25 @@ * @file llcontrol.cpp * @brief Holds global state for viewer. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -1513,7 +1507,6 @@ DECL_LLCC(S32, (S32)-666); DECL_LLCC(F32, (F32)-666.666); DECL_LLCC(bool, true); DECL_LLCC(BOOL, FALSE); -static LLCachedControl mySetting_string("TestCachedControlstring", "Default String Value"); DECL_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); DECL_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); DECL_LLCC(LLRect, LLRect(0, 0, 100, 500)); @@ -1523,10 +1516,11 @@ DECL_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f)); LLSD test_llsd = LLSD()["testing1"] = LLSD()["testing2"]; DECL_LLCC(LLSD, test_llsd); -static LLCachedControl test_BrowserHomePage("BrowserHomePage", "hahahahahha", "Not the real comment"); - void test_cached_control() { + static const LLCachedControl mySetting_string("TestCachedControlstring", "Default String Value"); + static const LLCachedControl test_BrowserHomePage("BrowserHomePage", "hahahahahha", "Not the real comment"); + #define TEST_LLCC(T, V) if((T)mySetting_##T != V) llerrs << "Fail "#T << llendl; \ mySetting_##T = V;\ if((T)mySetting_##T != V) llerrs << "Fail "#T << "Pass # 2" << llendl; diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 6ce9745cc..18861cb23 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -2,31 +2,25 @@ * @file llcontrol.h * @brief A mechanism for storing "control state" for a program * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llxml/llcontrolgroupreader.h b/indra/llxml/llcontrolgroupreader.h index ef8ee18c9..791551d60 100644 --- a/indra/llxml/llcontrolgroupreader.h +++ b/indra/llxml/llcontrolgroupreader.h @@ -2,31 +2,25 @@ * @file llcontrolgroupreader.h * @brief Interface providing readonly access to LLControlGroup (intended for unit testing) * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index b35585527..9a1e4b3b9 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -3,31 +3,25 @@ * @author Tom Yedwab * @brief LLXMLNode implementation * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,6 +41,7 @@ #include "llquaternion.h" #include "llstring.h" #include "lluuid.h" +//#include "lldir.h" // Do not need. const S32 MAX_COLUMN_WIDTH = 80; @@ -150,7 +145,7 @@ LLXMLNodePtr LLXMLNode::deepCopy() if (mChildren.notNull()) { for (LLXMLChildList::iterator iter = mChildren->map.begin(); - iter != mChildren->map.end(); ++iter) + iter != mChildren->map.end(); ++iter) { newnode->addChild(iter->second->deepCopy()); } @@ -412,6 +407,7 @@ void XMLCALL StartXMLNode(void *userData, { // Create a new node LLXMLNode *new_node_ptr = new LLXMLNode(name, FALSE); + LLXMLNodePtr new_node = new_node_ptr; new_node->mID.clear(); LLXMLNodePtr ptr_new_node = new_node; @@ -901,7 +897,8 @@ bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, std::vector::const_iterator itor; - for (itor = paths.begin(), ++itor; itor != paths.end(); ++itor) + // We've already dealt with the first item, skip that one + for (itor = paths.begin() + 1; itor != paths.end(); ++itor) { std::string layer_filename = *itor; if(layer_filename.empty() || layer_filename == filename) diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index 463d7fc61..90bec6903 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -2,31 +2,25 @@ * @file llxmltree.cpp * @brief LLXmlTree implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llxml/llxmltree.h b/indra/llxml/llxmltree.h index 2ac75046e..9b0f2492f 100644 --- a/indra/llxml/llxmltree.h +++ b/indra/llxml/llxmltree.h @@ -3,31 +3,25 @@ * @author Aaron Yonas, Richard Nelson * @brief LLXmlTree class definition * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3ef620b2b..c74a56c62 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -17,7 +17,7 @@ endif(FMOD) include(OPENAL) include(FindOpenGL) include(Hunspell) -#include(JsonCpp) +include(JsonCpp) include(LLAddBuildTest) include(LLAudio) include(LLCharacter) @@ -44,6 +44,7 @@ include(UI) include(LLKDU) include(ViewerMiscLibs) include(ViewerArtwork.cmake) +include(LLAppearance) if (WINDOWS) include(CopyWinLibs) @@ -70,6 +71,7 @@ include_directories( ${LLVFS_INCLUDE_DIRS} ${LLWINDOW_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} + ${LLAPPEARANCE_INCLUDE_DIRS} # ${LSCRIPT_INCLUDE_DIRS} # ${LSCRIPT_INCLUDE_DIRS}/lscript_compile ) @@ -151,7 +153,6 @@ set(viewer_SOURCE_FILES lldrawpooltree.cpp lldrawpoolwater.cpp lldrawpoolwlsky.cpp - lldriverparam.cpp lldroptarget.cpp lldynamictexture.cpp llemote.cpp @@ -196,8 +197,9 @@ set(viewer_SOURCE_FILES llfloaterevent.cpp llfloaterexploreanimations.cpp llfloaterexploresounds.cpp - llfloaterfriends.cpp + llfloaterfeed.cpp llfloaterfonttest.cpp + llfloaterfriends.cpp llfloatergesture.cpp llfloatergodtools.cpp llfloatergroupinfo.cpp @@ -297,10 +299,10 @@ set(viewer_SOURCE_FILES lljoystickbutton.cpp lllandmarklist.cpp lllocalinventory.cpp - lllocaltextureobject.cpp lllogchat.cpp llloginhandler.cpp llmainlooprepeater.cpp + llmakeoutfitdialog.cpp llmanip.cpp llmaniprotate.cpp llmanipscale.cpp @@ -312,6 +314,7 @@ set(viewer_SOURCE_FILES llmediaremotectrl.cpp llmemoryview.cpp llmenucommands.cpp + llmenuoptionpathfindingrebakenavmesh.cpp llmeshrepository.cpp llmimetypes.cpp llmorphview.cpp @@ -366,10 +369,10 @@ set(viewer_SOURCE_FILES llpanelnetwork.cpp llpanelobject.cpp llpanelobjectinventory.cpp - llpanelpathfindingrebakenavmesh.cpp llpanelpermissions.cpp llpanelpick.cpp llpanelplace.cpp + llpanelprofile.cpp llpanelskins.cpp llpanelvolume.cpp llpanelweb.cpp @@ -386,8 +389,6 @@ set(viewer_SOURCE_FILES llpathfindingobjectlist.cpp llphysicsmotion.cpp llphysicsshapebuilderutil.cpp - llpolymesh.cpp - llpolymorph.cpp llprefschat.cpp llprefsim.cpp llprefsvoice.cpp @@ -421,9 +422,6 @@ set(viewer_SOURCE_FILES llstylemap.cpp llsurface.cpp llsurfacepatch.cpp - lltexglobalcolor.cpp - lltexlayer.cpp - lltexlayerparams.cpp lltexturecache.cpp lltexturectrl.cpp lltexturefetch.cpp @@ -504,17 +502,17 @@ set(viewer_SOURCE_FILES llviewershadermgr.cpp llviewerstats.cpp llviewerstatsrecorder.cpp + llviewertexlayer.cpp llviewertexteditor.cpp llviewertexture.cpp llviewertextureanim.cpp llviewertexturelist.cpp llviewerthrottle.cpp - llviewervisualparam.cpp + llviewerwearable.cpp llviewerwindow.cpp llvlcomposition.cpp llvlmanager.cpp llvoavatar.cpp - llvoavatardefines.cpp llvoavatarself.cpp llvocache.cpp llvoclouds.cpp @@ -534,10 +532,9 @@ set(viewer_SOURCE_FILES llwatchdog.cpp llwaterparammanager.cpp llwaterparamset.cpp - llwearable.cpp llwearablelist.cpp - llwearabletype.cpp llweb.cpp + llwebprofile.cpp llwind.cpp llwlanimator.cpp llwldaycycle.cpp @@ -546,6 +543,7 @@ set(viewer_SOURCE_FILES llwlparamset.cpp llworld.cpp llworldmap.cpp + llworldmapmessage.cpp llworldmipmap.cpp llworldmapview.cpp llxmlrpcresponder.cpp @@ -655,7 +653,6 @@ set(viewer_HEADER_FILES lldrawpooltree.h lldrawpoolwater.h lldrawpoolwlsky.h - lldriverparam.h lldroptarget.h lldynamictexture.h llemote.h @@ -700,6 +697,7 @@ set(viewer_HEADER_FILES llfloaterexploreanimations.h llfloaterexploresounds.h llfloaterevent.h + llfloaterfeed.h llfloaterfonttest.h llfloaterfriends.h llfloatergesture.h @@ -801,10 +799,10 @@ set(viewer_HEADER_FILES lllandmarklist.h lllightconstants.h lllocalinventory.h - lllocaltextureobject.h lllogchat.h llloginhandler.h llmainlooprepeater.h + llmakeoutfitdialog.h llmanip.h llmaniprotate.h llmanipscale.h @@ -815,6 +813,7 @@ set(viewer_HEADER_FILES llmediactrl.h llmediaremotectrl.h llmemoryview.h + llmenuoptionpathfindingrebakenavmesh.h llmenucommands.h llmeshrepository.h llmimetypes.h @@ -870,10 +869,10 @@ set(viewer_HEADER_FILES llpanelnetwork.h llpanelobject.h llpanelobjectinventory.h - llpanelpathfindingrebakenavmesh.h llpanelpermissions.h llpanelpick.h llpanelplace.h + llpanelprofile.h llpanelskins.h llpanelvolume.h llpanelweb.h @@ -890,8 +889,6 @@ set(viewer_HEADER_FILES llpathfindingobjectlist.h llphysicsmotion.h llphysicsshapebuilderutil.h - llpolymesh.h - llpolymorph.h llprefschat.h llprefsim.h llprefsvoice.h @@ -927,9 +924,6 @@ set(viewer_HEADER_FILES llsurface.h llsurfacepatch.h lltable.h - lltexglobalcolor.h - lltexlayer.h - lltexlayerparams.h lltexturecache.h lltexturectrl.h lltexturefetch.h @@ -1012,17 +1006,17 @@ set(viewer_HEADER_FILES llviewershadermgr.h llviewerstats.h llviewerstatsrecorder.h + llviewertexlayer.h llviewertexteditor.h llviewertexture.h llviewertextureanim.h llviewertexturelist.h llviewerthrottle.h - llviewervisualparam.h + llviewerwearable.h llviewerwindow.h llvlcomposition.h llvlmanager.h llvoavatar.h - llvoavatardefines.h llvoavatarself.h llvocache.h llvoclouds.h @@ -1043,10 +1037,9 @@ set(viewer_HEADER_FILES llwatchdog.h llwaterparammanager.h llwaterparamset.h - llwearable.h llwearablelist.h - llwearabletype.h llweb.h + llwebprofile.h llwind.h llwindebug.h llwlanimator.h @@ -1056,6 +1049,7 @@ set(viewer_HEADER_FILES llwlparamset.h llworld.h llworldmap.h + llworldmapmessage.h llworldmipmap.h llworldmapview.h llxmlrpcresponder.h @@ -1576,6 +1570,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${XMLRPCEPI_LIBRARIES} ${ELFIO_LIBRARIES} ${HUNSPELL_LIBRARY} + ${LLAPPEARANCE_LIBRARIES} ) if (LINUX) diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index dd50567cd..0cc3d6693 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -701,7 +701,23 @@ CHARACTER_MAX_TURN_RADIUS TODO: add documentation # --- OpenSim and Aurora-Sim constants Below --- # OpenSim Constants (\OpenSim\Region\ScriptEngine\Shared\Api\Runtime\LSL_Constants.cs) # Constants for cmWindlight (\OpenSim\Region\ScriptEngine\Shared\Api\Runtime\CM_Constants.cs) -CHANGED_ANIMATION OpenSim change event animation change detection. +CHANGED_ANIMATION OpenSim change event animation change detection. +CAMERA_FOCUS_OFFSET_X OpenSim enhancement for llSetCameraParams(), adjusts the camera focus x position relative to the target. (float) +CAMERA_FOCUS_OFFSET_Y OpenSim enhancement for llSetCameraParams(), adjusts the camera focus y position relative to the target. (float) +CAMERA_FOCUS_OFFSET_Z OpenSim enhancement for llSetCameraParams(), adjusts the camera focus z position relative to the target. (float) +CAMERA_POSITION_X OpenSim enhancement for llSetCameraParams(), sets camera x position in region coordinates. (float) +CAMERA_POSITION_Y OpenSim enhancement for llSetCameraParams(), sets camera y position in region coordinates. (float) +CAMERA_POSITION_Z OpenSim enhancement for llSetCameraParams(), sets camera z position in region coordinates. (float) +CAMERA_FOCUS_X OpenSim enhancement for llSetCameraParams(), sets camera x focus (target position) in region coordinates. (float) +CAMERA_FOCUS_Y OpenSim enhancement for llSetCameraParams(), sets camera y focus (target position) in region coordinates. (float) +CAMERA_FOCUS_Z OpenSim enhancement for llSetCameraParams(), sets camera z focus (target position) in region coordinates. (float) +OS_LISTEN_REGEX_NAME Value 0x1, process name parameter as regex +OS_LISTEN_REGEX_MESSAGE Value 0x2, process name parameter as regex +OS_ATTACH_MSG_ALL Used with osMessageAttachements +OS_ATTACH_MSG_INVERT_POINTS Used with osMessageAttachements +OS_ATTACH_MSG_OBJECT_CREATOR Used with osMessageAttachements +OS_ATTACH_MSG_SCRIPT_CREATOR Used with osMessageAttachements +PARCEL_DETAILS_CLAIMDATE Used with osSetParcelDetails # osGetRegionStats STATS_TIME_DILATION returned value from osGetRegionStats(), 1st of 21 items in returned list. STATS_SIM_FPS returned value from osGetRegionStats(), 2nd of 21 items in returned list. @@ -725,14 +741,15 @@ STATS_PENDING_UPLOADS returned value from osGetRegionStats(), 19th of 21 items STATS_ACTIVE_SCRIPTS returned value from osGetRegionStats(), 20th of 21 items in returned list. STATS_SCRIPT_LPS returned value from osGetRegionStats(), 21st of 21 items in returned list. # OpenSim NPC -OS_NPC_FLY used by osNPC. -OS_NPC_NO_FLY used by osNPC. -OS_NPC_LAND_AT_TARGET used by osNPC. -OS_NPC_SIT_NOW used by osNPC. -OS_NPC_CREATOR_OWNED used by osNPC. -OS_NPC_NOT_OWNED used by osNPC. -OS_NPC_SENSE_AS_AGENT used by osNPC. -OS_NPC_RUNNING used by osNPC. +OS_NPC used by osNPC. Value 0x01000000 +OS_NPC_FLY used by osNPC. Value 0 +OS_NPC_NO_FLY used by osNPC. Value 1 +OS_NPC_LAND_AT_TARGET used by osNPC. Value 2 +OS_NPC_SIT_NOW used by osNPC. Value 0 +OS_NPC_CREATOR_OWNED used by osNPC. Value 0x1 +OS_NPC_NOT_OWNED used by osNPC. Value 0x2 +OS_NPC_SENSE_AS_AGENT used by osNPC. Value 0x4 +OS_NPC_RUNNING used by osNPC. Value 4 # Windlight/Lightshare WL_WATER_COLOR Windlight Water Colour WL_WATER_FOG_DENSITY_EXPONENT Windlight Water Fog Density Exponent @@ -771,7 +788,15 @@ WL_CLOUD_SCROLL_Y Windlight Cloud Scroll Y WL_CLOUD_SCROLL_Y_LOCK Windlight Cloud Scroll Y Lock WL_CLOUD_SCROLL_X_LOCK Windlight Cloud Scroll X Lock WL_DRAW_CLASSIC_CLOUDS Windlight Draw Classic Clouds -# Aurora-Sim Constants (\Aurora\AuroraDotNetEngine\APIs\AA_Constants.cs) --> +# WL Constants added unique to Aurora-Sim +WL_OK Value -1 +WL_ERROR Value -2 +WL_ERROR_NO_SCENE_SET Value -3 +WL_ERROR_SCENE_MUST_BE_STATIC Value -4 +WL_ERROR_SCENE_MUST_NOT_BE_STATIC Value -5 +WL_ERROR_BAD_SETTING Value -6 +WL_ERROR_NO_PRESET_FOUND Value -7 +# Aurora-Sim Constants (\Aurora\AuroraDotNetEngine\APIs\AA_Constants.cs) ENABLE_GRAVITY enable_gravity. GRAVITY_FORCE_X gravity_force_x. GRAVITY_FORCE_Y gravity_force_y. diff --git a/indra/newview/app_settings/lsl_functions_os.xml b/indra/newview/app_settings/lsl_functions_os.xml index 05e1c94f8..f7f0ab1e8 100644 --- a/indra/newview/app_settings/lsl_functions_os.xml +++ b/indra/newview/app_settings/lsl_functions_os.xml @@ -247,6 +247,46 @@ osNpcWhisper + osForceAttachToAvatar + + osForceAttachToAvatarFromInventory + + osForceAttachToOtherAvatarFromInventory + + osNpcTouch + + osNpcTouch + + osIsUUID + + osMin + + osMax + + osMax + + osGetRezzingObject + + osGetHealth + + osSetContentType + + osGetNumberOfAttachments + + osMessageAttachments + + osDropAttachment + + osDropAttachmentAt + + osForceDropAttachment + + osForceDropAttachmentAt + + osListenRegex + + osRegexIsMatch + osReturnObject @@ -334,6 +374,24 @@ aaGetIsInfiniteRegion + aaSetCharacterStat + + aaAllRegionInstanceSay + + aaWindlightGetDayCycle + + aaWindlightAddDayCycleFrame + + aaWindlightRemoveDayCycleFrame + + aaWindlightSetScene + + aaWindlightGetScene + + aaWindlightGetSceneIsStatic + + aaWindlightGetSceneDayCycleKeyFrameCount + botGetWaitingTime @@ -370,4 +428,4 @@ botRemoveBotsWithTag - \ No newline at end of file + diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6bae8e6ed..c4f0cc038 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9,6 +9,17 @@ settings_rlv.xml + UseNewTargetOmegaCode + + Comment + Enable target omega code from Viewer 3.4 + Persist + 1 + Type + Boolean + Value + 0 + SGIgnoreSimulatorCameraConstraints Comment @@ -90,51 +101,6 @@ Value 0 - - WaterPresetName - - Comment - Water preset to use. May be superseded by region settings - Persist - 1 - Type - String - Value - Default - - SkyPresetName - - Comment - Sky preset to use. May be superseded by region settings - Persist - 1 - Type - String - Value - Default - - DayCycleName - - Comment - Day Cycle to use. May be superseded by region settings - Persist - 1 - Type - String - Value - Default - - UseEnvironmentFromRegion - - Comment - Choose whether to use the region's environment settings, or override them with the local settings. - Persist - 1 - Type - Boolean - Value - 1 - UseEnvironmentFromRegionAlways Comment @@ -147,17 +113,6 @@ Value 1 - UseDayCycle - - Comment - Whether to use use a day cycle or a fixed sky. - Persist - 1 - Type - Boolean - Value - 1 - PhoenixInterpolateParcelWL Comment @@ -692,11 +647,55 @@ Boolean Value 0 - + + LiruAddNotReplace + + Comment + Add clothing and attachments instead of having them replace the currently worn or attached item at their destination. + Persist + 1 + Type + Boolean + Value + 0 + + LiruContinueFlyingOnUnsit + + Comment + Fly after standing up, if you were flying when you sat down + Persist + 1 + Type + Boolean + Value + 0 + + LiruFlyAfterTeleport + + Comment + Fly after teleports + Persist + 1 + Type + Boolean + Value + 0 + + LiruNoTransactionClutter + + Comment + Use notifytips for transactions instead of notifys, this way they do not collect in the top right of the screen. + Persist + 1 + Type + Boolean + Value + 0 + LiruSensibleARC Comment - Use the old-style way to calculate Avatar Render Cost. + Use the old-style way to calculate Avatar Render Cost. Found in Advanced->Rendering->Info Displays Persist 1 @@ -704,7 +703,95 @@ Found in Advanced->Rendering->Info Displays Boolean Value 1 - + + ContactsUseHorizontalButtons + + Comment + Whether or not groups and friends lists use horizontal buttons at the bottom of the panel or vertical ones on the right, requires a restart. + Persist + 1 + Type + Boolean + Value + 0 + + UseConciseIMButtons + + Comment + Whether or not IMs use buttons concisely on the same line as the name of the receiver, changes apply to new IMs only. + Persist + 1 + Type + Boolean + Value + 0 + + UseConciseGroupChatButtons + + Comment + Whether or not group chats use buttons concisely on the same line as the group name, changes apply to new group chats only. + Persist + 1 + Type + Boolean + Value + 0 + + UseConciseConferenceButtons + + Comment + Whether or not conferences use buttons concisely on the same line as the name of the conference, changes apply to new conferences only. + Persist + 1 + Type + Boolean + Value + 0 + + ShowLocalChatFloaterBar + + Comment + Whether or not local chat should have an input bar, requires a restart. + Persist + 1 + Type + Boolean + Value + 1 + + OtherChatsTornOff + + Comment + When true, chats other than local chat open torn off of the Communicate window. + Persist + 1 + Type + Boolean + Value + 0 + + OtherChatsTornOffAndMinimized + + Comment + When this and OtherChatsTornOff are true, new chats open torn off and minimized. + Persist + 1 + Type + Boolean + Value + 1 + + CommunicateSpecificShortcut + + Comment + When true, the keyboard shortcut for Communicate will not bring up the torn off Friends List. + Persist + 1 + Type + Boolean + Value + 0 + MarketImporterUpdateFreq Comment @@ -799,6 +886,28 @@ This should be as low as possible, but too low may break functionality Value 1 + AnnounceSnapshots + + Comment + Announce if someone nearby has taken a snapshot in chat (Won't work on people who hide/quiet snapshots) + Persist + 1 + Type + Boolean + Value + 0 + + AnnounceStreamMetadata + + Comment + Announce the metadata of the track playing, in chat, during streams. + Persist + 1 + Type + Boolean + Value + 0 + InventorySortOrder Comment @@ -865,6 +974,17 @@ This should be as low as possible, but too low may break functionality Value 0 + TurnAroundWhenWalkingBackwards + + Comment + Turn your avatar around to face the camera while walking backwards. + Persist + 1 + Type + Boolean + Value + 1 + EmeraldBoobMass Comment @@ -1761,6 +1881,17 @@ This should be as low as possible, but too low may break functionality Value 0 + AgentAppearanceServiceURL + + Comment + Current Session Agent Appearance Service URL + Persist + 0 + Type + String + Value + + AlertedUnsupportedHardware Comment @@ -2322,6 +2453,28 @@ This should be as low as possible, but too low may break functionality Value 2 + AvatarRotateThresholdSlow + + Comment + Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving slowly (degrees) + Persist + 1 + Type + F32 + Value + 60 + + AvatarRotateThresholdFast + + Comment + Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving fast (degrees) + Persist + 1 + Type + F32 + Value + 2 + AvatarBakedTextureUploadTimeout Comment @@ -2494,14 +2647,25 @@ This should be as low as possible, but too low may break functionality BlockAvatarAppearanceMessages Comment - Ignore's appearance messages (for simulating Ruth) + Ignores appearance messages (for simulating Ruth) Persist 1 Type Boolean Value - 0 - + 0 + + BlockSomeAvatarAppearanceVisualParams + + Comment + Drop around 50% of VisualParam occurances in appearance messages (for simulating Ruth) + Persist + 1 + Type + Boolean + Value + 0 + BrowserProxyAddress Comment @@ -4383,6 +4547,17 @@ This should be as low as possible, but too low may break functionality Value + DebugAvatarAppearanceMessage + + Comment + Dump a bunch of XML files when handling appearance messages + Persist + 1 + Type + Boolean + Value + 0 + DebugAvatarRezTime Comment @@ -4403,6 +4578,17 @@ This should be as low as possible, but too low may break functionality Type Boolean Value + 1 + + DebugAvatarCompositeBaked + + Comment + Colorize avatar meshes based on baked/composite state. + Persist + 1 + Type + Boolean + Value 0 DebugBeaconLineWidth @@ -4507,7 +4693,7 @@ This should be as low as possible, but too low may break functionality DebugShowTime Comment - Show depth buffer contents + Show time info Persist 1 Type @@ -5758,6 +5944,17 @@ This should be as low as possible, but too low may break functionality Value 0 + SecondsInLog + + Comment + TRUE to add seconds to timestamps for Log + Persist + 1 + Type + Boolean + Value + 0 + FloaterAboutRect Comment @@ -6004,6 +6201,22 @@ This should be as low as possible, but too low may break functionality 0 + FloaterChatBarlessRect + + Comment + Rectangle for chat history without input bar + Persist + 1 + Type + Rect + Value + + 0 + 172 + 500 + 0 + + FloaterClothingRect Comment @@ -6023,7 +6236,23 @@ This should be as low as possible, but too low may break functionality FloaterContactsRect Comment - Rectangle for chat history + Rectangle for contacts floater + Persist + 1 + Type + Rect + Value + + 0 + 390 + 395 + 0 + + + FloaterContactsHorizRect + + Comment + Rectangle for contacts floater in horizontal mode Persist 1 Type @@ -6068,6 +6297,22 @@ This should be as low as possible, but too low may break functionality 0 + FloaterDebugSettingsRect + + Comment + Rectangle for the Debug Settings floater + Persist + 1 + Type + Rect + Value + + 0 + 300 + 245 + 0 + + FloaterEnvRect Comment @@ -6274,6 +6519,160 @@ This should be as low as possible, but too low may break functionality 0 + RadarColumnMarkWidth + + Comment + Width for radar's mark column + Persist + 1 + Type + S32 + Value + 12 + + RadarColumnPositionWidth + + Comment + Width for radar's position column + Persist + 1 + Type + S32 + Value + 60 + + RadarColumnAltitudeWidth + + Comment + Width for radar's altitude column + Persist + 1 + Type + S32 + Value + 48 + + RadarColumnActivityWidth + + Comment + Width for radar's activity column + Persist + 1 + Type + S32 + Value + 24 + + RadarColumnAgeWidth + + Comment + Width for radar's age column + Persist + 1 + Type + S32 + Value + 45 + + RadarColumnTimeWidth + + Comment + Width for radar's time column + Persist + 1 + Type + S32 + Value + 52 + + RadarColumnNameWidth + + Comment + Width for radar's name column + Persist + 1 + Type + S32 + Value + 80 + + RadarColumnMarkHidden + + Comment + Hide radar's mark column + Persist + 1 + Type + Boolean + Value + 0 + + RadarColumnPositionHidden + + Comment + Hide radar's position column + Persist + 1 + Type + Boolean + Value + 0 + + RadarColumnAltitudeHidden + + Comment + Hide radar's altitude column + Persist + 1 + Type + Boolean + Value + 0 + + RadarColumnActivityHidden + + Comment + Hide radar's activity column + Persist + 1 + Type + Boolean + Value + 0 + + RadarColumnAgeHidden + + Comment + Hide radar's age column + Persist + 1 + Type + Boolean + Value + 0 + + RadarColumnTimeHidden + + Comment + Hide radar's time column + Persist + 1 + Type + Boolean + Value + 1 + + RadarColumnClientHidden + + Comment + Hide radar's client column + Persist + 1 + Type + Boolean + Value + 0 + RadarKeepOpen Comment @@ -6340,6 +6739,28 @@ This should be as low as possible, but too low may break functionality Value 1 + RadarAlertAge + + Comment + Whether the radar emits chat alerts for avatars younger than AvatarAgeAlertDays appearing. + Persist + 1 + Type + Boolean + Value + 0 + + AvatarAgeAlertDays + + Comment + Age below which avatars will be made known to you + Persist + 1 + Type + U32 + Value + 3 + RadarChatAlerts Comment @@ -6354,7 +6775,18 @@ This should be as low as possible, but too low may break functionality RadarChatKeys Comment - Enable private chat alerts for avatars entering the region + Enable alerting scripts about avatars detected by the radar + Persist + 1 + Type + Boolean + Value + 0 + + RadarChatKeysStopAsking + + Comment + Do not ask if RadarChatKeys should be enabled when a script requests for the radar's keys. Persist 1 Type @@ -6490,6 +6922,22 @@ This should be as low as possible, but too low may break functionality 0 + FloaterOutboxRect + + Comment + Rectangle for merchant outbox window + Persist + 1 + Type + Rect + Value + + 0 + 342 + 310 + 52 + + FloaterPayRectB Comment @@ -6570,6 +7018,38 @@ This should be as low as possible, but too low may break functionality 400 + FloaterSnapshotFeedRect + + Comment + Rectangle for snapshot feed window + Persist + 1 + Type + Rect + Value + + 0 + 200 + 200 + 400 + + + FloaterSnapshotPostcardRect + + Comment + Rectangle for snapshot postcard window + Persist + 1 + Type + Rect + Value + + 0 + 346 + 450 + 400 + + FloaterSoundsRect Comment @@ -7602,6 +8082,17 @@ This should be as low as possible, but too low may break functionality Value 1.0 + InventoryDebugSimulateOpFailureRate + + Comment + Rate at which we simulate failures of copy/link requests in some operations + Persist + 1 + Type + F32 + Value + 0.0 + InventoryDisplayInbox Comment @@ -7866,17 +8357,6 @@ This should be as low as possible, but too low may break functionality Value 64 - KeepAspectForSnapshot - - Comment - Use full window when taking snapshot, regardless of requested image size - Persist - 1 - Type - Boolean - Value - 1 - LandBrushSize Comment @@ -8047,6 +8527,50 @@ This should be as low as possible, but too low may break functionality Value 0.0.0 + LastSnapshotToFeedAspect + + Comment + The aspect ratio spinner value for snapshots uploaded to my.secondlife.com + Persist + 0 + Type + F32 + Value + 1.33333 + + LastSnapshotToFeedHeight + + Comment + The height of the last my.secondlife.com feed snapshot, in px + Persist + 1 + Type + S32 + Value + 525 + + LastSnapshotToFeedWidth + + Comment + The width of the last my.secondlife.com feed snapshot, in px + Persist + 1 + Type + S32 + Value + 700 + + LastSnapshotToEmailAspect + + Comment + The aspect ratio spinner value for snapshots sent by email + Persist + 0 + Type + F32 + Value + 0 + LastSnapshotToEmailHeight Comment @@ -8069,6 +8593,17 @@ This should be as low as possible, but too low may break functionality Value 1024 + LastSnapshotToDiskAspect + + Comment + The aspect ratio spinner value for snapshots written to disk + Persist + 0 + Type + F32 + Value + 0 + LastSnapshotToDiskHeight Comment @@ -8091,6 +8626,17 @@ This should be as low as possible, but too low may break functionality Value 1024 + LastSnapshotToInventoryAspect + + Comment + The aspect ratio spinner value for snapshots uploaded to inventory + Persist + 0 + Type + F32 + Value + 0 + LastSnapshotToInventoryHeight Comment @@ -8124,6 +8670,17 @@ This should be as low as possible, but too low may break functionality Value 0 + SnapshotFeedAddLocation + + Comment + Include your location in your uploads to profile feed. + Persist + 1 + Type + Boolean + Value + 0 + LeftClickShowMenu Comment @@ -8322,17 +8879,6 @@ This should be as low as possible, but too low may break functionality Value 20.0 - MapServerURL - - Comment - World map URL template for locating map tiles - Persist - 0 - Type - String - Value - http://map.secondlife.com.s3.amazonaws.com/ - UseWebMapTiles Comment @@ -8366,6 +8912,17 @@ This should be as low as possible, but too low may break functionality Value 128.0 + MapServerURL + + Comment + World map URL template for locating map tiles + Persist + 0 + Type + String + Value + http://map.secondlife.com.s3.amazonaws.com/ + MapShowAgentCount Comment @@ -9894,17 +10451,6 @@ This should be as low as possible, but too low may break functionality 0 - SaveScriptsAsMono - - Comment - When set to TRUE, save scripts in inventory as Mono scripts instead of LSL2 - Persist - 1 - Type - Boolean - Value - 1 - PreviewSoundRect Comment @@ -10163,6 +10709,18 @@ This should be as low as possible, but too low may break functionality 128 + OctreeReserveNodeCapacity + + Comment + Default number of elements to pre-allocate for in a single octree node + Persist + 1 + Type + U32 + Value + 4 + + OctreeStaticObjectSizeFactor Comment @@ -10421,6 +10979,20 @@ This should be as low as possible, but too low may break functionality Value 0 + RenderPerformanceTest + + Comment + + Disable rendering of everything but in-world content for + performance testing + + Persist + 1 + Type + Boolean + Value + 0 + RenderLocalLights @@ -10536,7 +11108,7 @@ This should be as low as possible, but too low may break functionality Type F32 Value - 500.0 + 1500.0 RenderSSAOMaxScale @@ -10547,7 +11119,7 @@ This should be as low as possible, but too low may break functionality Type U32 Value - 200 + 250 RenderSSAOFactor @@ -10558,19 +11130,19 @@ This should be as low as possible, but too low may break functionality Type F32 Value - 0.30 + 5.0 RenderSSAOEffect Comment - Multiplier for (1) value and (2) saturation (HSV definition), for areas which are totally occluded. Blends with original color for partly-occluded areas. (Third component is unused.) + Multiplier for (1) value for areas which are totally occluded. Blends with original color for partly-occluded areas. (Third component is unused.) Persist 1 Type Vector3 Value - 0.80 + 0.50 1.00 0.00 @@ -10847,6 +11419,18 @@ This should be as low as possible, but too low may break functionality 0 + RenderDepthPrePass + + Comment + EXPERIMENTAL: Prime the depth buffer with simple prim geometry before rendering with textures. + Persist + 1 + Type + Boolean + Value + 0 + + RenderDepthOfField Comment @@ -11157,7 +11741,7 @@ This should be as low as possible, but too low may break functionality Vector3 Value - 3.0 + 1.0 2.0 0.0 @@ -11172,7 +11756,7 @@ This should be as low as possible, but too low may break functionality Type F32 Value - 1.4 + 3.0 RenderShadowBlurSamples @@ -11469,6 +12053,28 @@ This should be as low as possible, but too low may break functionality Value 1 + DisableAllRenderTypes + + Comment + Disables all rendering types. + Persist + 0 + Type + Boolean + Value + 0 + + DisableAllRenderFeatures + + Comment + Disables all rendering features. + Persist + 0 + Type + Boolean + Value + 0 + RenderHUDInSnapshot Comment @@ -11645,17 +12251,6 @@ This should be as low as possible, but too low may break functionality Value 1 - ReSit - - Comment - Sit again if unsat - Persist - 0 - Type - Boolean - Value - 0 - SpecifiedChannel Comment @@ -11981,7 +12576,7 @@ This should be as low as possible, but too low may break functionality RenderUseVAO Comment - Use GL Vertex Array Objects + [EXPERIMENTAL] Use GL Vertex Array Objects Persist 1 Type @@ -11989,6 +12584,17 @@ This should be as low as possible, but too low may break functionality Value 0 + RenderUseTransformFeedback + + Comment + [EXPERIMENTAL] Use transform feedback shaders for LoD updates + Persist + 1 + Type + Boolean + Value + 0 + RenderVBOMappingDisable Comment @@ -13388,6 +13994,28 @@ This should be as low as possible, but too low may break functionality Value 0 + SnapshotFeedLastAspect + + Comment + Take next feed snapshot at this aspect + Persist + 0 + Type + S32 + Value + 0 + + SnapshotFeedLastResolution + + Comment + Take next feed snapshot at this resolution + Persist + 1 + Type + S32 + Value + 0 + SnapshotFormat Comment @@ -13399,6 +14027,28 @@ This should be as low as possible, but too low may break functionality Value 0 + SnapshotLayerType + + Comment + Save snapshots in this format (0 = Colors, 1 = Depth) + Persist + 1 + Type + S32 + Value + 0 + + SnapshotLocalLastAspect + + Comment + Take next local snapshot at this aspect + Persist + 0 + Type + S32 + Value + 0 + SnapshotLocalLastResolution Comment @@ -13410,6 +14060,17 @@ This should be as low as possible, but too low may break functionality Value 0 + SnapshotPostcardLastAspect + + Comment + Take next postcard snapshot at this aspect + Persist + 0 + Type + S32 + Value + 0 + SnapshotPostcardLastResolution Comment @@ -13432,6 +14093,17 @@ This should be as low as possible, but too low may break functionality Value 75 + SnapshotTextureLastAspect + + Comment + Take next texture snapshot at this aspect + Persist + 0 + Type + S32 + Value + 0 + SnapshotTextureLastResolution Comment @@ -13443,6 +14115,17 @@ This should be as low as possible, but too low may break functionality Value 0 + SnapshotOpenFreezeTime + + Comment + When opening the snapshot floater, immediately freeze time. + Persist + 1 + Type + Boolean + Value + 0 + SpeakingColor Comment @@ -13701,6 +14384,72 @@ This should be as low as possible, but too low may break functionality Value 0 + TextureFetchUpdateHighPriority + + Comment + Number of high priority textures to update per frame + Persist + 1 + Type + S32 + Value + 32 + + TextureFetchUpdateMaxMediumPriority + + Comment + Maximum number of medium priority textures to update per frame + Persist + 1 + Type + S32 + Value + 256 + + TextureFetchUpdateMinMediumPriority + + Comment + Minimum number of medium priority textures to update per frame + Persist + 1 + Type + S32 + Value + 32 + + TextureFetchUpdatePriorityThreshold + + Comment + Threshold under which textures will be considered too low priority and skipped for update + Persist + 1 + Type + F32 + Value + 0.0 + + TextureFetchUpdateSkipLowPriority + + Comment + Flag indicating if we want to skip textures with too low of a priority + Persist + 1 + Type + Boolean + Value + 0 + + TextureFetchUpdatePriorities + + Comment + Number of priority texture to update per frame + Persist + 1 + Type + S32 + Value + 32 + TextureLoadFullRes Comment @@ -14144,6 +14893,61 @@ This should be as low as possible, but too low may break functionality Value 1 + UseEnvironmentFromRegion + + Comment + Choose whether to use the region's environment settings, or override them with the local settings. + Persist + 1 + Type + Boolean + Value + 1 + + UseDayCycle + + Comment + Whether to use use a day cycle or a fixed sky. + Persist + 1 + Type + Boolean + Value + 1 + + WaterPresetName + + Comment + Water preset to use. May be superseded by region settings. + Persist + 1 + Type + String + Value + Default + + SkyPresetName + + Comment + Sky preset to use. May be superseded by region settings or by a day cycle (see DayCycleName). + Persist + 1 + Type + String + Value + Default + + DayCycleName + + Comment + Day cycle to use. May be superseded by region settings. + Persist + 1 + Type + String + Value + Default + UseExternalBrowser Comment @@ -14153,18 +14957,7 @@ This should be as low as possible, but too low may break functionality Type Boolean Value - 0 - - UseFreezeFrame - - Comment - Freeze time when taking snapshots. - Persist - 1 - Type - Boolean - Value - 0 + 1 UseInventoryLinks @@ -14188,6 +14981,17 @@ This should be as low as possible, but too low may break functionality Value 1 + RenderSynchronousOcclusion + + Comment + Don't let occlusion queries get more than one frame behind (block until they complete). + Persist + 1 + Type + Boolean + Value + 1 + SkipReflectOcclusionUpdates Comment @@ -15122,6 +15926,17 @@ This should be as low as possible, but too low may break functionality Value -1 + ForcePeriodicRenderingTime + + Comment + Periodically enable all rendering masks for a single frame. + Persist + 1 + Type + F32 + Value + -1.0 + ZoomDirect Comment @@ -15320,6 +16135,17 @@ This should be as low as possible, but too low may break functionality Value 1 + SimulateFBOFailure + + Comment + [DEBUG] Make allocateScreenBuffer return false. Used to test error handling. + Persist + 0 + Type + Boolean + Value + 0 + FloaterUploadRect Comment diff --git a/indra/newview/app_settings/settings_ascent_coa.xml b/indra/newview/app_settings/settings_ascent_coa.xml index 792c600e7..2cb809679 100644 --- a/indra/newview/app_settings/settings_ascent_coa.xml +++ b/indra/newview/app_settings/settings_ascent_coa.xml @@ -31,7 +31,7 @@ 1 - MoyMiniMapCustomColor + MoyMiniMapCustomColor Comment Custom minimap color you wish to have. @@ -135,7 +135,7 @@ AscentFriendColor Comment - Color of chat messages from other residents + Special color to distinguish friends from other residents Persist 1 Type @@ -153,7 +153,7 @@ AscentLindenColor Comment - Color of chat messages from other residents + Special color to distinguish Lindens(/grid operators) from other residents Persist 1 Type @@ -171,7 +171,7 @@ AscentMutedColor Comment - Color of chat messages from other residents + Special color to distinguish those who have been muted from other residents Persist 1 Type @@ -189,7 +189,7 @@ AscentEstateOwnerColor Comment - Color of chat messages from other residents + Special color to distinguish estate owners from other residents Persist 1 Type @@ -204,7 +204,73 @@ IsCOA 1 - AscentReportClientUUID + ColorFriendChat + + Comment + Color chat from friends using AscentFriendColor + Persist + 1 + Type + Boolean + Value + 0 + IsCOA + 1 + + ColorLindenChat + + Comment + Color chat from Lindens(/grid operators) using AscentLindenColor + Persist + 1 + Type + Boolean + Value + 0 + IsCOA + 1 + + ColorMutedChat + + Comment + Color chat from muted residents using AscentMutedColor + Persist + 1 + Type + Boolean + Value + 0 + IsCOA + 1 + + ColorEstateOwnerChat + + Comment + Color chat from estate owners using AscentEstateOwnerColor + Persist + 1 + Type + Boolean + Value + 0 + IsCOA + 1 + + + AscentReportClientUUID Comment Broadcasted Client Key diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index b422fae32..d30cb4343 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -357,22 +357,6 @@ This is an autoresponse! - MoyMiniMapCustomColor - - Comment - Custom minimap color you wish to have. - Persist - 1 - Type - Color4 - Value - - 0.375 - 1.0 - 1.0 - 1.0 - - rkeastInventoryPreviousCount diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml index 81659467c..411bc1e36 100644 --- a/indra/newview/app_settings/settings_sh.xml +++ b/indra/newview/app_settings/settings_sh.xml @@ -174,5 +174,38 @@ Value 0 + SHPackDeferredNormals + + Comment + Pack deferred normals into two components. + Persist + 1 + Type + Boolean + Value + 0 + + SHPrecisionDeferredNormals + + Comment + Enable usage of RGB10A2 for the deferred normalMap format. Reduces normalmapping artifacts. + Persist + 1 + Type + Boolean + Value + 0 + + SHOcclusionFudge + + Comment + Padding added to occlusion bounds. Larger = less aggressive occlusion/less pop-in. + Persist + 1 + Type + F32 + Value + 0.25 + diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 46d2aa487..cf57a33d9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -34,6 +34,17 @@ uniform sampler2D diffuseMap; VARYING vec3 vary_normal; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy); @@ -46,6 +57,6 @@ void main() frag_data[0] = vec4(diff.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn), 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index f400eb7a5..9a9b889da 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -64,32 +64,45 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec2 tc = vary_fragcoord.xy; - vec3 norm = texture2DRect(normalMap, tc).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(tc); // unpack norm + vec3 pos = getPosition(tc).xyz; vec4 ccol = texture2DRect(lightMap, tc).rgba; - vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); + vec2 dlt = kern_scale * delta / (vec2(1.0)+norm.xy*norm.xy); dlt /= max(-pos.z*dist_factor, 1.0); vec2 defined_weight = getKern(0).xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' vec4 col = defined_weight.xyxx * ccol; // relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances - float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005; + float pointplanedist_tolerance_pow2 = pos.z*-0.001; // perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large - float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2) - tc_mod -= floor(tc_mod); - tc_mod *= 2.0; + vec2 tc_v = fract(0.5 * tc.xy); // we now have floor(mod(tc,2.0))*0.5 + float tc_mod = 2.0 * abs(tc_v.x - tc_v.y); // diff of x,y makes checkerboard tc += ( (tc_mod - 0.5) * getKern(1).z * dlt * 0.5 ); for (int i = 1; i < 4; i++) { - vec2 samptc = tc + getKern(i).z*dlt; + vec2 samptc = (tc + getKern(i).z * dlt); vec3 samppos = getPosition(samptc).xyz; float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane if (d*d <= pointplanedist_tolerance_pow2) @@ -100,7 +113,7 @@ void main() } for (int i = 1; i < 4; i++) { - vec2 samptc = tc - getKern(i).z*dlt; + vec2 samptc = (tc - getKern(i).z * dlt); vec3 samppos = getPosition(samptc).xyz; float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane if (d*d <= pointplanedist_tolerance_pow2) @@ -111,7 +124,7 @@ void main() } col /= defined_weight.xyxx; - col.y *= col.y; + col.y *= col.y; // delinearize SSAO effect post-blur frag_color = col; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 680eadb85..db80a8e87 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -39,6 +39,17 @@ VARYING vec3 vary_mat2; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; @@ -52,5 +63,5 @@ void main() frag_data[1] = vertex_color.aaaa; // spec //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(tnorm); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn), 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl index 1d8ca04cc..9f6b1ea1f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl @@ -102,6 +102,11 @@ void main() /// Gamma correct for WL (soft clip effect). frag_data[0] = vec4(scaleSoftClip(color.rgb), alpha1); frag_data[1] = vec4(0.0,0.0,0.0,0.0); - frag_data[2] = vec4(0,0,1,0); +//#define PACK_NORMALS +#ifdef PACK_NORMALS + frag_data[2] = vec4(0.5,0.5,0.0,0.0); +#else + frag_data[2] = vec4(0.0,0.0,1.0,0.0); +#endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index b2027d3a5..d31cbfa28 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -37,6 +37,17 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color; @@ -49,6 +60,6 @@ void main() frag_data[0] = vec4(col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); // spec vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index ead384b07..c65539d43 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -36,6 +36,17 @@ uniform float minimum_alpha; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color; @@ -48,5 +59,5 @@ void main() frag_data[0] = vec4(col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn), 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl index f73fa6f23..252975aad 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl @@ -37,6 +37,17 @@ uniform sampler2D diffuseMap; VARYING vec3 vary_normal; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); @@ -49,6 +60,6 @@ void main() frag_data[0] = vec4(col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); // spec vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 227aa2aae..ac33fd261 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -35,6 +35,17 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; @@ -42,6 +53,6 @@ void main() frag_data[1] = vertex_color.aaaa; // spec //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index d442e5403..b97cd060d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -33,6 +33,17 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb; @@ -41,5 +52,5 @@ void main() frag_data[1] = vertex_color.aaaa; // spec //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 4d01eeb64..26aa34107 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -69,6 +69,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; @@ -78,9 +92,8 @@ void main() discard; } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - norm = normalize(norm); + vec3 norm = unpack(frag.xy); // unpack norm + //norm = normalize(norm); // may be superfluous vec4 spec = texture2DRect(specularRect, frag.xy); vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; float noise = texture2D(noiseMap, frag.xy/128.0).b; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index bff87cb6a..a82ba899a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -125,6 +125,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec4 frag = vary_fragcoord; @@ -141,10 +155,9 @@ void main() discard; } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0, norm.z); + vec3 norm = unpack(frag.xy); // unpack norm - norm = normalize(norm); + //norm = normalize(norm); // may be superfluous float l_dist = -dot(lv, proj_n); vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index f671d5b75..6c1ff1660 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -67,6 +67,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec4 frag = vary_fragcoord; @@ -83,15 +97,14 @@ void main() discard; } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(frag.xy); // unpack norm float da = dot(norm, lv); if (da < 0.0) { discard; } - norm = normalize(norm); + //norm = normalize(norm); // may be superfluous lv = normalize(lv); da = dot(norm, lv); diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index faa54a316..4eefdd8b6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -60,7 +60,12 @@ void main() /// Gamma correct for WL (soft clip effect). frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0); - frag_data[1] = vec4(0.0,0.0,0.0,0.0); - frag_data[2] = vec4(0,0,1,0); + frag_data[1] = vec4(vary_HazeColor.a,0.0,0.0,0.0); +//#define PACK_NORMALS +#ifdef PACK_NORMALS + frag_data[2] = vec4(0.5,0.5,0.0,0.0); +#else + frag_data[2] = vec4(0.0,0.0,1.0,0.0); +#endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index 7c02d31d4..f5a0bfec6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -53,6 +53,13 @@ uniform vec4 glow; uniform vec4 cloud_color; +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + void main() { @@ -151,6 +158,7 @@ void main() // At horizon, blend high altitude sky color towards the darker color below the clouds vary_HazeColor += (additiveColorBelowCloud - vary_HazeColor) * (1. - sqrt(temp1)); + vary_HazeColor.a = pow(clamp(luminance(vary_HazeColor.rgb)-.5,0,1),2); // won't compile on mac without this being set //vary_AtmosAttenuation = vec3(0.0,0.0,0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 66e3cf6d1..066cdd348 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -62,7 +62,7 @@ uniform float max_y; uniform vec4 glow; uniform float scene_light_strength; uniform mat3 env_mat; -uniform mat3 ssao_effect_mat; +uniform float ssao_effect; uniform vec3 sun_dir; VARYING vec2 vary_fragcoord; @@ -203,22 +203,15 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { //increase ambient when there are more clouds vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; - /* decrease value and saturation (that in HSV, not HSL) for occluded areas - * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html - * // The following line of code performs the equivalent of: - * float ambAlpha = tmpAmbient.a; - * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis - * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); - * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); - */ - tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); - //haze color setAdditiveColor( vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x + tmpAmbient))); + // decrease value for occluded areas + tmpAmbient = vec4(mix(ssao_effect * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + //brightness of surface both sunlight and ambient setSunlitColor(vec3(sunlight * .5)); setAmblitColor(vec3(tmpAmbient * .25)); @@ -271,13 +264,33 @@ vec3 scaleSoftClip(vec3 light) return light; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + void main() { vec2 tc = vary_fragcoord.xy; float depth = texture2DRect(depthMap, tc.xy).r; vec3 pos = getPosition_d(tc, depth).xyz; - vec3 norm = texture2DRect(normalMap, tc).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(tc); // unpack norm float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); @@ -310,17 +323,20 @@ void main() //add environmentmap vec3 env_vec = env_mat * refnormpersp; - col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb, - max(spec.a-diffuse.a*2.0, 0.0)); + vec3 env = textureCube(environmentMap, env_vec).rgb; + bloom = (luminance(env) - .45)*.25; + col = mix(col.rgb, env, + max(spec.a-diffuse.a*2.0, 0.0)); } col = atmosLighting(col); col = scaleSoftClip(col); - col = mix(col.rgb, diffuse.rgb, diffuse.a); + col = mix(col, diffuse.rgb, diffuse.a); } else { + bloom = spec.r; col = diffuse.rgb; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index cca63872d..ae64d8937 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -127,6 +127,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec4 frag = vary_fragcoord; @@ -143,10 +157,9 @@ void main() discard; } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0, norm.z); + vec3 norm = unpack(frag.xy); // unpack norm - norm = normalize(norm); + //norm = normalize(norm); // may be superfluous float l_dist = -dot(lv, proj_n); vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl index 821058804..2e4b416c4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl @@ -29,6 +29,8 @@ out vec4 frag_data[3]; #define frag_data gl_FragData #endif +uniform float custom_alpha; + VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; @@ -38,7 +40,12 @@ void main() { vec4 col = vertex_color * texture2D(diffuseMap, vary_texcoord0.xy); - frag_data[0] = col; + frag_data[0] = vec4(col.rgb,col.a*custom_alpha); frag_data[1] = vec4(0,0,0,0); - frag_data[2] = vec4(0,0,1,0); +//#define PACK_NORMALS +#ifdef PACK_NORMALS + frag_data[2] = vec4(0.5,0.5,0.0,0.0); +#else + frag_data[2] = vec4(0.0,0.0,1.0,0.0); +#endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 2422d73a3..24a827e91 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -65,8 +65,6 @@ vec4 getPosition(vec2 pos_screen) //calculate decreases in ambient lighting when crowded out (SSAO) float calcAmbientOcclusion(vec4 pos, vec3 norm) { - float ret = 1.0; - vec2 kern[8]; // exponentially (^2) distant occlusion samples spread around origin kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; @@ -82,38 +80,54 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) vec3 pos_world = pos.xyz; vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; + // We treat the first sample as the origin, which definitely doesn't obscure itself thanks to being visible for sampling in the first place. + float points = 1.0; float angle_hidden = 0.0; - int points = 0; - - float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); - - // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations unrolling?) + + // use a kernel scale that diminishes with distance. + // a scale of less than 32 is just wasting good samples, though. + float scale = max(32.0, min(ssao_radius / -pos.z, ssao_max_radius)); + + // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) for (int i = 0; i < 8; i++) { vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); - vec3 samppos_world = getPosition(samppos_screen).xyz; - - vec3 diff = pos_world - samppos_world; - float dist2 = dot(diff, diff); - - // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area - // --> solid angle shrinking by the square of distance - //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 - //(k should vary inversely with # of samples, but this is taken care of later) - - angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); - - // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" - points = points + int(diff.z > -1.0); + vec3 samppos_world = getPosition(samppos_screen).xyz; + + vec3 diff = samppos_world - pos.xyz; + + if (diff.z < ssao_factor && diff.z != 0.0) + { + float dist = length(diff); + float angrel = max(0.0, dot(norm.xyz, diff/dist)); + float distrel = 1.0/(1.0+dist*dist); + float samplehidden = min(angrel, distrel); + + angle_hidden += (samplehidden); + points += 1.0; + } } - angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); - - ret = (1.0 - (float(points != 0) * angle_hidden)); - - return min(ret, 1.0); + angle_hidden /= points; + + float rtn = (1.0 - angle_hidden); + + return (rtn * rtn); } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} void main() { vec2 pos_screen = vary_fragcoord.xy; @@ -122,8 +136,7 @@ void main() vec4 pos = getPosition(pos_screen); - vec3 norm = texture2DRect(normalMap, pos_screen).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(pos_screen); // unpack norm frag_color[0] = 1.0; frag_color[1] = calcAmbientOcclusion(pos, norm); diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 8a5e482e8..3e4c5fc9c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -39,6 +39,17 @@ VARYING vec3 vary_normal; VARYING vec4 vary_texcoord0; VARYING vec4 vary_texcoord1; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { /// Note: This should duplicate the blending functionality currently used for the terrain rendering. @@ -56,6 +67,6 @@ void main() frag_data[0] = vec4(outColor.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index 6cf6106b5..6cd309fdb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -37,6 +37,17 @@ VARYING vec2 vary_texcoord0; uniform float minimum_alpha; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); @@ -48,5 +59,5 @@ void main() frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 42dc7c098..b27822814 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -67,6 +67,17 @@ VARYING vec4 littleWave; VARYING vec4 view; VARYING vec4 vary_position; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 color; @@ -151,8 +162,9 @@ void main() //spec *= shadow; //color.rgb += spec * specular; - //color.rgb = atmosTransport(color.rgb); - //color.rgb = scaleSoftClip(color.rgb); + color.rgb = atmosTransport(color.rgb); + color.rgb = scaleSoftClip(color.rgb); + //color.a = spec * sunAngle2; //wavef.z *= 0.1f; @@ -161,5 +173,5 @@ void main() frag_data[0] = vec4(color.rgb, 0.5); // diffuse frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec - frag_data[2] = vec4(screenspacewavef.xy*0.5+0.5, screenspacewavef.z, screenspacewavef.z*0.5); // normalxyz, displace + frag_data[2] = vec4(pack(screenspacewavef), 0.5); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl index 9734acf00..ece34dcc4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl @@ -85,7 +85,7 @@ void main() pos.w = 1.0; pos = modelview_matrix*pos; - calcAtmospherics(pos.xyz); + calcAtmospherics(view.xyz); //pass wave parameters to pixel shader vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055; diff --git a/indra/newview/app_settings/shaders/class1/effects/VignetteF.glsl b/indra/newview/app_settings/shaders/class1/effects/VignetteF.glsl new file mode 100644 index 000000000..ad989e1a0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/effects/VignetteF.glsl @@ -0,0 +1,54 @@ +/** + * @file colorFilterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2DRect tex0; +uniform float vignette_strength; //0 - 1 +uniform float vignette_radius; //0 - 8 +uniform float vignette_darkness; //0 - 1 +uniform float vignette_desaturation; //0 - 10 +uniform float vignette_chromatic_aberration; //0 - .1 +uniform vec2 screen_res; + +VARYING vec2 vary_texcoord0; + +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + +void main(void) +{ + vec3 color = texture2DRect(tex0, vary_texcoord0).rgb; + vec2 norm_texcood = (vary_texcoord0/screen_res); + vec2 offset = norm_texcood-vec2(.5); + float vignette = clamp(pow(1 - dot(offset,offset),vignette_radius) + 1-vignette_strength, 0.0, 1.0); + float inv_vignette = 1-vignette; + + //vignette chromatic aberration (g + vec2 shift = screen_res * offset * vignette_chromatic_aberration * inv_vignette; + float g = texture2DRect(tex0,vary_texcoord0-shift).g; + float b = texture2DRect(tex0,vary_texcoord0-2*shift).b; + color.gb = vec2(g,b); + + //vignette 'black' overlay. + color = mix(color * vignette, color, 1-vignette_darkness); + + //vignette desaturation + color = mix(vec3(luminance(color)), color, clamp(1-inv_vignette*vignette_desaturation,0,1)); + + frag_color = vec4(color,1.0); +} diff --git a/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl b/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl index e03b83113..6acd277bb 100644 --- a/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl @@ -25,6 +25,13 @@ uniform float gamma; VARYING vec2 vary_texcoord0; +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + void main(void) { vec3 color = vec3(texture2DRect(tex0, vary_texcoord0.st)); @@ -39,7 +46,7 @@ void main(void) color = mix(contrastBase, color, contrast); /// Modulate saturation - color = mix(vec3(dot(color, lumWeights)), color, saturation); + color = mix(vec3(luminance(color)), color, saturation); frag_color = vec4(color, 1.0); } diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl index f66ba1d2d..f77edde70 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl @@ -81,7 +81,7 @@ void main() pos.w = 1.0; pos = modelview_matrix*pos; - calcAtmospherics(pos.xyz); + calcAtmospherics(view.xyz); //pass wave parameters to pixel shader diff --git a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl index 01eed18de..4c8d1b2d1 100644 --- a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl +++ b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl @@ -30,7 +30,7 @@ uniform int texture_index_in; ATTRIBUTE vec3 position; VARYING vec3 position_out; -VARYING int texture_index_out; +VARYING_FLAT int texture_index_out; void main() { diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index f7f1f649c..7f6a31ef7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -126,6 +126,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec4 frag = vary_fragcoord; @@ -153,10 +167,9 @@ void main() shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(frag.xy); // unpack norm - norm = normalize(norm); + //norm = normalize(norm); // may be superfluous float l_dist = -dot(lv, proj_n); vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index a137bea30..d490b5d46 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -63,7 +63,7 @@ uniform vec4 glow; uniform float scene_light_strength; uniform mat3 env_mat; uniform vec4 shadow_clip; -uniform mat3 ssao_effect_mat; +uniform float ssao_effect; uniform mat4 inv_proj; uniform vec2 screen_res; @@ -79,6 +79,13 @@ vec3 vary_AmblitColor; vec3 vary_AdditiveColor; vec3 vary_AtmosAttenuation; +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + vec4 getPosition_d(vec2 pos_screen, float depth) { vec2 sc = pos_screen.xy*2.0; @@ -205,22 +212,15 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { //increase ambient when there are more clouds vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; - /* decrease value and saturation (that in HSV, not HSL) for occluded areas - * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html - * // The following line of code performs the equivalent of: - * float ambAlpha = tmpAmbient.a; - * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis - * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); - * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); - */ - tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); - //haze color setAdditiveColor( vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x + tmpAmbient))); + // decrease ambient value for occluded areas + tmpAmbient *= mix(ssao_effect, 1.0, ambFactor); + //brightness of surface both sunlight and ambient setSunlitColor(vec3(sunlight * .5)); setAmblitColor(vec3(tmpAmbient * .25)); @@ -273,25 +273,37 @@ vec3 scaleSoftClip(vec3 light) return light; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec2 tc = vary_fragcoord.xy; float depth = texture2DRect(depthMap, tc.xy).r; vec3 pos = getPosition_d(tc, depth).xyz; - vec3 norm = texture2DRect(normalMap, tc).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(tc); // unpack norm float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); vec4 diffuse = texture2DRect(diffuseRect, tc); + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); vec3 col; float bloom = 0.0; if (diffuse.a < 0.9) { - vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); - vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; float scol = max(scol_ambocc.r, diffuse.a); float ambocc = scol_ambocc.g; @@ -318,7 +330,9 @@ void main() //add environmentmap vec3 env_vec = env_mat * refnormpersp; - col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb, + vec3 env = textureCube(environmentMap, env_vec).rgb; + bloom = (luminance(env) - .45)*.25; + col = mix(col.rgb, env, max(spec.a-diffuse.a*2.0, 0.0)); } @@ -329,6 +343,7 @@ void main() } else { + bloom = spec.r; col = diffuse.rgb; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index ab077d9e0..3a556e913 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -126,6 +126,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec4 frag = vary_fragcoord; @@ -153,10 +167,9 @@ void main() shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(frag.xy); // unpack norm - norm = normalize(norm); + //norm = normalize(norm); // may be superfluous float l_dist = -dot(lv, proj_n); vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index db3d76035..f8f57e5e7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -116,6 +116,22 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) return shadow*0.2; } +vec4 unpack(vec2 tc) +{ + vec4 norm = texture2DRect(normalMap, tc).xyzw; +//#define PACK_NORMALS +#ifdef PACK_NORMALS + norm.xy = (norm.xy*4.0)-2.0; + float prod = dot(norm.xy,norm.xy); + norm.xy *= sqrt(1.0-prod*.25); + norm.z = 1.0-prod*.5; +#else + norm.xyz = norm.xyz*2.0-1.0; +#endif + norm.w *= norm.z; + return norm; +} + void main() { vec2 pos_screen = vary_fragcoord.xy; @@ -124,8 +140,7 @@ void main() vec4 pos = getPosition(pos_screen); - vec4 nmap4 = texture2DRect(normalMap, pos_screen); - nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm + vec4 nmap4 = unpack(pos_screen); // unpack norm float displace = nmap4.w; vec3 norm = nmap4.xyz; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 32b206e63..ddcb024a9 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -97,46 +97,40 @@ vec2 getKern(int i) //calculate decreases in ambient lighting when crowded out (SSAO) float calcAmbientOcclusion(vec4 pos, vec3 norm) { - float ret = 1.0; - vec2 pos_screen = vary_fragcoord.xy; - vec3 pos_world = pos.xyz; vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; - + + // We treat the first sample as the origin, which definitely doesn't obscure itself thanks to being visible for sampling in the first place. + float points = 1.0; float angle_hidden = 0.0; - float points = 0; - float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); + // use a kernel scale that diminishes with distance. + // a scale of less than 32 is just wasting good samples, though. + float scale = max(32.0, min(ssao_radius / -pos.z, ssao_max_radius)); // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) for (int i = 0; i < 8; i++) { vec2 samppos_screen = pos_screen + scale * reflect(getKern(i), noise_reflect); vec3 samppos_world = getPosition(samppos_screen).xyz; - - vec3 diff = pos_world - samppos_world; - float dist2 = dot(diff, diff); - - // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area - // --> solid angle shrinking by the square of distance - //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 - //(k should vary inversely with # of samples, but this is taken care of later) - - float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0; - angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv); - - // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" - float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0; - points = points + diffz_val; - } - - angle_hidden = min(ssao_factor*angle_hidden/points, 1.0); - - float points_val = (points > 0.0) ? 1.0 : 0.0; - ret = (1.0 - (points_val * angle_hidden)); - ret = max(ret, 0.0); - return min(ret, 1.0); + vec3 diff = samppos_world - pos.xyz; + + if (diff.z < ssao_factor && diff.z != 0.0) + { + float dist = length(diff); + float angrel = max(0.0, dot(norm.xyz, diff/dist)); + float distrel = 1.0/(1.0+dist*dist); + float samplehidden = min(angrel, distrel); + + angle_hidden += (samplehidden); + points += 1.0; + } + } + + angle_hidden /= points; + float rtn = (1.0 - angle_hidden); + return (rtn * rtn); } float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) @@ -177,6 +171,22 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) return shadow*0.2; } +vec4 unpack(vec2 tc) +{ + vec4 norm = texture2DRect(normalMap, tc).xyzw; +//#define PACK_NORMALS +#ifdef PACK_NORMALS + norm.xy = (norm.xy*4.0)-2.0; + float prod = dot(norm.xy,norm.xy); + norm.xy *= sqrt(1.0-prod*.25); + norm.z = 1.0-prod*.5; +#else + norm.xyz = norm.xyz*2.0-1.0; +#endif + norm.w *= norm.z; + return norm; +} + void main() { vec2 pos_screen = vary_fragcoord.xy; @@ -185,8 +195,7 @@ void main() vec4 pos = getPosition(pos_screen); - vec4 nmap4 = texture2DRect(normalMap, pos_screen); - nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm + vec4 nmap4 = unpack(pos_screen); // unpack norm float displace = nmap4.w; vec3 norm = nmap4.xyz; diff --git a/indra/newview/app_settings/windlight/postprocesseffects.xml b/indra/newview/app_settings/windlight/postprocesseffects.xml index b5b173b40..5a498009c 100644 --- a/indra/newview/app_settings/windlight/postprocesseffects.xml +++ b/indra/newview/app_settings/windlight/postprocesseffects.xml @@ -177,6 +177,8 @@ enable_posterize 0 enable_motionblur + 0 + enable_vignette 0 gauss_blur_passes 2 @@ -194,6 +196,16 @@ 10 blur_strength 10 + vignette_strength + 0.85 + vignette_radius + 0.7 + vignette_darkness + 1.0 + vignette_desaturation + 1.0 + vignette_chromatic_aberration + 0.01 \ No newline at end of file diff --git a/indra/newview/ascentfloatercontactgroups.cpp b/indra/newview/ascentfloatercontactgroups.cpp index d4097493d..f1d867fca 100644 --- a/indra/newview/ascentfloatercontactgroups.cpp +++ b/indra/newview/ascentfloatercontactgroups.cpp @@ -30,7 +30,7 @@ #include "llfloaterchat.h" ASFloaterContactGroups* ASFloaterContactGroups::sInstance = NULL; -LLDynamicArray ASFloaterContactGroups::mSelectedUUIDs; +uuid_vec_t ASFloaterContactGroups::mSelectedUUIDs; LLSD ASFloaterContactGroups::mContactGroupData; ASFloaterContactGroups::ASFloaterContactGroups() @@ -40,7 +40,7 @@ ASFloaterContactGroups::ASFloaterContactGroups() } // static -void ASFloaterContactGroups::show(LLDynamicArray ids) +void ASFloaterContactGroups::show(const uuid_vec_t& ids) { if (!sInstance) sInstance = new ASFloaterContactGroups(); @@ -84,7 +84,8 @@ void ASFloaterContactGroups::onBtnAdd(void* userdata) self->createContactGroup(name); combo->selectByValue(name); } - for (S32 i = (self->mSelectedUUIDs.count() - 1); i >= 0; --i) + uuid_vec_t::reverse_iterator it = self->mSelectedUUIDs.rbegin(); + for (;it != self->mSelectedUUIDs.rend();++it) { //self->addContactMember(combo->getSimple(), self->mSelectedUUIDs.get(i)); } @@ -98,19 +99,21 @@ void ASFloaterContactGroups::onBtnRemove(void* userdata) if(self) { - if (self->mSelectedUUIDs.count() > 0) + if (!self->mSelectedUUIDs.empty()) { LLScrollListCtrl* scroller = self->getChild("group_scroll_list"); if(scroller != NULL) { - for (S32 i = (self->mSelectedUUIDs.count() - 1); i >= 0; --i) + uuid_vec_t::size_type i = self->mSelectedUUIDs.size(); + uuid_vec_t::reverse_iterator it = self->mSelectedUUIDs.rbegin(); + for (;it != self->mSelectedUUIDs.rend();++it) { std::string i_str; - LLResMgr::getInstance()->getIntegerString(i_str, i); - LLChat msg("Adding index " + i_str + ": " + self->mSelectedUUIDs.get(i).asString()); + LLResMgr::getInstance()->getIntegerString(i_str, --i); + LLChat msg("Adding index " + i_str + ": " + it->asString()); LLFloaterChat::addChat(msg); - self->addContactMember(scroller->getValue().asString(), self->mSelectedUUIDs.get(i)); + self->addContactMember(scroller->getValue().asString(), *it); } } } diff --git a/indra/newview/ascentfloatercontactgroups.h b/indra/newview/ascentfloatercontactgroups.h index 809dce781..e20a67d38 100644 --- a/indra/newview/ascentfloatercontactgroups.h +++ b/indra/newview/ascentfloatercontactgroups.h @@ -29,7 +29,7 @@ public: virtual ~ASFloaterContactGroups(); // by convention, this shows the floater and does instance management - static void show(LLDynamicArray ids); + static void show(const uuid_vec_t& ids); void populateGroupList(); void populateActiveGroupList(LLUUID to_add); @@ -47,7 +47,7 @@ public: private: //assuming we just need one, which is typical static ASFloaterContactGroups* sInstance; - static LLDynamicArray mSelectedUUIDs; + static uuid_vec_t mSelectedUUIDs; static LLSD mContactGroupData; }; diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index f937571c3..dd8531965 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -325,7 +325,6 @@ void LLPrefsAscentChat::onCommitKeywords(LLUICtrl* ctrl, void* user_data) void LLPrefsAscentChat::refreshValues() { //Chat/IM ----------------------------------------------------------------------------- - mWoLfVerticalIMTabs = gSavedSettings.getBOOL("WoLfVerticalIMTabs"); mIMAnnounceIncoming = gSavedSettings.getBOOL("AscentInstantMessageAnnounceIncoming"); mHideTypingNotification = gSavedSettings.getBOOL("AscentHideTypingNotification"); mShowGroupNameInChatIM = gSavedSettings.getBOOL("OptionShowGroupNameInChatIM"); @@ -335,6 +334,7 @@ void LLPrefsAscentChat::refreshValues() mEnableOOCAutoClose = gSavedSettings.getBOOL("AscentAutoCloseOOC"); mLinksForChattingObjects = gSavedSettings.getU32("LinksForChattingObjects"); mSecondsInChatAndIMs = gSavedSettings.getBOOL("SecondsInChatAndIMs"); + mSecondsInLog = gSavedSettings.getBOOL("SecondsInLog"); std::string format = gSavedSettings.getString("ShortTimeFormat"); if (format.find("%p") == -1) @@ -372,6 +372,16 @@ void LLPrefsAscentChat::refreshValues() mIMResponseItem = gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseItem"); mIMResponseText = gSavedPerAccountSettings.getString("AscentInstantMessageResponse"); + //Chat UI ----------------------------------------------------------------------------- + mWoLfVerticalIMTabs = gSavedSettings.getBOOL("WoLfVerticalIMTabs"); + mOtherChatsTornOff = gSavedSettings.getBOOL("OtherChatsTornOff"); + mShowLocalChatFloaterBar = gSavedSettings.getBOOL("ShowLocalChatFloaterBar"); + mHorizButt = gSavedSettings.getBOOL("ContactsUseHorizontalButtons"); + mOneLineIMButt = gSavedSettings.getBOOL("UseConciseIMButtons"); + mOneLineGroupButt = gSavedSettings.getBOOL("UseConciseGroupChatButtons"); + mOneLineConfButt = gSavedSettings.getBOOL("UseConciseConferenceButtons"); + mOnlyComm = gSavedSettings.getBOOL("CommunicateSpecificShortcut"); + //Spam -------------------------------------------------------------------------------- mEnableAS = gSavedSettings.getBOOL("AntiSpamEnabled"); mGlobalQueue = gSavedSettings.getBOOL("_NACL_AntiSpamGlobalQueue"); @@ -390,6 +400,7 @@ void LLPrefsAscentChat::refreshValues() mSoundMulti = gSavedSettings.getU32("_NACL_AntiSpamSoundMulti"); mNewLines = gSavedSettings.getU32("_NACL_AntiSpamNewlines"); mPreloadMulti = gSavedSettings.getU32("_NACL_AntiSpamSoundPreloadMulti"); + mEnableGestureSounds = gSavedSettings.getBOOL("EnableGestureSounds"); //Text Options ------------------------------------------------------------------------ mSpellDisplay = gSavedSettings.getBOOL("SpellDisplay"); @@ -529,7 +540,6 @@ void LLPrefsAscentChat::refresh() void LLPrefsAscentChat::cancel() { //Chat/IM ----------------------------------------------------------------------------- - gSavedSettings.setBOOL("WoLfVerticalIMTabs", mWoLfVerticalIMTabs); gSavedSettings.setBOOL("AscentInstantMessageAnnounceIncoming", mIMAnnounceIncoming); gSavedSettings.setBOOL("AscentHideTypingNotification", mHideTypingNotification); gSavedSettings.setBOOL("OptionShowGroupNameInChatIM", mShowGroupNameInChatIM); @@ -539,6 +549,7 @@ void LLPrefsAscentChat::cancel() gSavedSettings.setBOOL("AscentAutoCloseOOC", mEnableOOCAutoClose); gSavedSettings.setU32("LinksForChattingObjects", mLinksForChattingObjects); gSavedSettings.setBOOL("SecondsInChatAndIMs", mSecondsInChatAndIMs); + gSavedSettings.setBOOL("SecondsInLog", mSecondsInLog); std::string short_date, long_date, short_time, long_time, timestamp; @@ -589,6 +600,16 @@ void LLPrefsAscentChat::cancel() gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseItem", mIMResponseItem); gSavedPerAccountSettings.setString("AscentInstantMessageResponse", mIMResponseText); + //Chat UI ----------------------------------------------------------------------------- + gSavedSettings.setBOOL("WoLfVerticalIMTabs", mWoLfVerticalIMTabs); + gSavedSettings.setBOOL("OtherChatsTornOff", mOtherChatsTornOff); + gSavedSettings.setBOOL("ShowLocalChatFloaterBar", mShowLocalChatFloaterBar); + gSavedSettings.setBOOL("ContactsUseHorizontalButtons", mHorizButt); + gSavedSettings.setBOOL("UseConciseIMButtons", mOneLineIMButt); + gSavedSettings.setBOOL("UseConciseGroupChatButtons", mOneLineGroupButt); + gSavedSettings.setBOOL("UseConciseConferenceButtons", mOneLineConfButt); + gSavedSettings.setBOOL("CommunicateSpecificShortcut", mOnlyComm); + //Spam -------------------------------------------------------------------------------- gSavedSettings.setBOOL("AntiSpamEnabled", mEnableAS); gSavedSettings.setBOOL("_NACL_AntiSpamGlobalQueue", mGlobalQueue); @@ -607,6 +628,7 @@ void LLPrefsAscentChat::cancel() gSavedSettings.setU32("_NACL_AntiSpamSoundMulti", mSoundMulti); gSavedSettings.setU32("_NACL_AntiSpamNewlines", mNewLines); gSavedSettings.setU32("_NACL_AntiSpamSoundPreloadMulti", mPreloadMulti); + gSavedSettings.setBOOL("EnableGestureSounds", mEnableGestureSounds); //Text Options ------------------------------------------------------------------------ gSavedSettings.setBOOL("SpellDisplay", mSpellDisplay); diff --git a/indra/newview/ascentprefschat.h b/indra/newview/ascentprefschat.h index 8bbfad0c0..63cedf611 100644 --- a/indra/newview/ascentprefschat.h +++ b/indra/newview/ascentprefschat.h @@ -62,7 +62,6 @@ protected: static void onCommitKeywords(LLUICtrl* ctrl, void* user_data); //Chat/IM ----------------------------------------------------------------------------- - BOOL mWoLfVerticalIMTabs; BOOL mIMAnnounceIncoming; BOOL mHideTypingNotification; BOOL mShowGroupNameInChatIM; @@ -76,6 +75,7 @@ protected: U32 tempTimeFormat; U32 tempDateFormat; BOOL mSecondsInChatAndIMs; + BOOL mSecondsInLog; BOOL mIMResponseAnyone; BOOL mIMResponseFriends; @@ -86,6 +86,16 @@ protected: BOOL mIMResponseItem; std::string mIMResponseText; + //Chat UI ----------------------------------------------------------------------------- + bool mWoLfVerticalIMTabs; + bool mOtherChatsTornOff; + bool mShowLocalChatFloaterBar; + bool mHorizButt; + bool mOneLineIMButt; + bool mOneLineGroupButt; + bool mOneLineConfButt; + bool mOnlyComm; + //Spam -------------------------------------------------------------------------------- BOOL mEnableAS; BOOL mGlobalQueue; @@ -104,6 +114,7 @@ protected: BOOL mSoundMulti; U32 mNewLines; U32 mPreloadMulti; + bool mEnableGestureSounds; //Text Options ------------------------------------------------------------------------ BOOL mSpellDisplay; diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp index 8b90011f2..ba835d7ac 100644 --- a/indra/newview/ascentprefssys.cpp +++ b/indra/newview/ascentprefssys.cpp @@ -267,8 +267,10 @@ void LLPrefsAscentSys::refreshValues() mDoubleClickTeleport = gSavedSettings.getBOOL("DoubleClickTeleport"); mResetCameraAfterTP = gSavedSettings.getBOOL("OptionRotateCamAfterLocalTP"); mOffsetTPByUserHeight = gSavedSettings.getBOOL("OptionOffsetTPByAgentHeight"); + mLiruFlyAfterTeleport = gSavedSettings.getBOOL("LiruFlyAfterTeleport"); + mLiruContinueFlying = gSavedSettings.getBOOL("LiruContinueFlyingOnUnsit"); mPreviewAnimInWorld = gSavedSettings.getBOOL("PreviewAnimInWorld"); -// mSaveScriptsAsMono = gSavedSettings.getBOOL("SaveScriptsAsMono"); + mSaveScriptsAsMono = gSavedSettings.getBOOL("SaveInventoryScriptsAsMono"); mAlwaysRezInGroup = gSavedSettings.getBOOL("AscentAlwaysRezInGroup"); mBuildAlwaysEnabled = gSavedSettings.getBOOL("AscentBuildAlwaysEnabled"); mAlwaysShowFly = gSavedSettings.getBOOL("AscentFlyAlwaysEnabled"); @@ -416,8 +418,10 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("DoubleClickTeleport", mDoubleClickTeleport); gSavedSettings.setBOOL("OptionRotateCamAfterLocalTP", mResetCameraAfterTP); gSavedSettings.setBOOL("OptionOffsetTPByAgentHeight", mOffsetTPByUserHeight); + gSavedSettings.setBOOL("LiruFlyAfterTeleport", mLiruFlyAfterTeleport); + gSavedSettings.setBOOL("LiruContinueFlyingOnUnsit", mLiruContinueFlying); gSavedSettings.setBOOL("PreviewAnimInWorld", mPreviewAnimInWorld); -// gSavedSettings.setBOOL("SaveScriptsAsMono", mSaveScriptsAsMono); + gSavedSettings.setBOOL("SaveInventoryScriptsAsMono", mSaveScriptsAsMono); gSavedSettings.setBOOL("AscentAlwaysRezInGroup", mAlwaysRezInGroup); gSavedSettings.setBOOL("AscentBuildAlwaysEnabled", mBuildAlwaysEnabled); gSavedSettings.setBOOL("AscentFlyAlwaysEnabled", mAlwaysShowFly); diff --git a/indra/newview/ascentprefssys.h b/indra/newview/ascentprefssys.h index 3b233bb28..73765ee39 100644 --- a/indra/newview/ascentprefssys.h +++ b/indra/newview/ascentprefssys.h @@ -58,8 +58,10 @@ protected: BOOL mDoubleClickTeleport; BOOL mResetCameraAfterTP; BOOL mOffsetTPByUserHeight; + bool mLiruFlyAfterTeleport; + bool mLiruContinueFlying; BOOL mPreviewAnimInWorld; -// BOOL mSaveScriptsAsMono; + BOOL mSaveScriptsAsMono; BOOL mAlwaysRezInGroup; BOOL mBuildAlwaysEnabled; BOOL mAlwaysShowFly; diff --git a/indra/newview/ascentprefsvan.cpp b/indra/newview/ascentprefsvan.cpp index 53f0d5751..2d9b32144 100644 --- a/indra/newview/ascentprefsvan.cpp +++ b/indra/newview/ascentprefsvan.cpp @@ -36,7 +36,10 @@ #include "ascentprefsvan.h" //project includes +#include "llaudioengine.h" //For gAudiop +#include "llstreamingaudio.h" //For LLStreamingAudioInterface #include "llcolorswatch.h" +#include "llvoavatar.h" #include "llvoavatarself.h" #include "llagent.h" #include "llfloaterchat.h" @@ -54,6 +57,8 @@ LLPrefsAscentVan::LLPrefsAscentVan() { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_ascent_vanity.xml"); + childSetVisible("announce_streaming_metadata", gAudiop && gAudiop->getStreamingAudioImpl() && gAudiop->getStreamingAudioImpl()->supportsMetaData()); + childSetCommitCallback("tag_spoofing_combobox", onCommitClientTag, this); childSetCommitCallback("show_my_tag_check", onCommitCheckBox, this); @@ -152,12 +157,16 @@ void LLPrefsAscentVan::onCommitCheckBox(LLUICtrl* ctrl, void* user_data) if (ctrl->getName() == "use_status_check") { - BOOL showCustomColors = gSavedSettings.getBOOL("AscentUseStatusColors"); - self->childSetEnabled("friends_color_textbox", showCustomColors); - self->childSetEnabled("friend_color_swatch", showCustomColors); - self->childSetEnabled("estate_owner_color_swatch", showCustomColors); - self->childSetEnabled("linden_color_swatch", showCustomColors); - self->childSetEnabled("muted_color_swatch", showCustomColors); + bool showCustomColors = gSavedSettings.getBOOL("AscentUseStatusColors"); + self->childSetEnabled("friends_color_textbox", showCustomColors); + bool frColors = gSavedSettings.getBOOL("ColorFriendChat"); + self->childSetEnabled("friend_color_swatch", showCustomColors || frColors); + bool eoColors = gSavedSettings.getBOOL("ColorEstateOwnerChat"); + self->childSetEnabled("estate_owner_color_swatch", showCustomColors || eoColors); + bool lindColors = gSavedSettings.getBOOL("ColorLindenChat"); + self->childSetEnabled("linden_color_swatch", showCustomColors || lindColors); + bool muteColors = gSavedSettings.getBOOL("ColorMutedChat"); + self->childSetEnabled("muted_color_swatch", showCustomColors || muteColors); } else if (ctrl->getName() == "customize_own_tag_check") { @@ -172,12 +181,16 @@ void LLPrefsAscentVan::onCommitCheckBox(LLUICtrl* ctrl, void* user_data) // Store current settings for cancel void LLPrefsAscentVan::refreshValues() { - //General -------------------------------------------------------------------------------- + //Main ----------------------------------------------------------------------------------- mUseAccountSettings = gSavedSettings.getBOOL("AscentStoreSettingsPerAccount"); mShowTPScreen = !gSavedSettings.getBOOL("AscentDisableTeleportScreens"); mPlayTPSound = gSavedSettings.getBOOL("OptionPlayTpSound"); mShowLogScreens = !gSavedSettings.getBOOL("AscentDisableLogoutScreens"); mDisableChatAnimation = gSavedSettings.getBOOL("SGDisableChatAnimation"); + mAddNotReplace = gSavedSettings.getBOOL("LiruAddNotReplace"); + mTurnAround = gSavedSettings.getBOOL("TurnAroundWhenWalkingBackwards"); + mAnnounceSnapshots = gSavedSettings.getBOOL("AnnounceSnapshots"); + mAnnounceStreamMetadata = gSavedSettings.getBOOL("AnnounceStreamMetadata"); //Tags\Colors ---------------------------------------------------------------------------- mAscentUseTag = gSavedSettings.getBOOL("AscentUseTag"); @@ -199,7 +212,12 @@ void LLPrefsAscentVan::refreshValues() mEstateOwnerColor = gSavedSettings.getColor4("AscentEstateOwnerColor"); mLindenColor = gSavedSettings.getColor4("AscentLindenColor"); mMutedColor = gSavedSettings.getColor4("AscentMutedColor"); - //mCustomColor = gSavedSettings.getColor4("MoyMiniMapCustomColor"); + mCustomColor = gSavedSettings.getColor4("MoyMiniMapCustomColor"); + mColorFriendChat = gSavedSettings.getBOOL("ColorFriendChat"); + mColorEOChat = gSavedSettings.getBOOL("ColorEstateOwnerChat"); + mColorLindenChat = gSavedSettings.getBOOL("ColorLindenChat"); + mColorMutedChat = gSavedSettings.getBOOL("ColorMutedChat"); +// mColorCustomChat = gSavedSettings.getBOOL("ColorCustomChat"); //Body Dynamics -------------------------------------------------------------------------- mBreastPhysicsToggle = gSavedSettings.getBOOL("EmeraldBreastPhysicsToggle"); @@ -217,17 +235,17 @@ void LLPrefsAscentVan::refreshValues() // Update controls based on current settings void LLPrefsAscentVan::refresh() { - //General -------------------------------------------------------------------------------- + //Main ----------------------------------------------------------------------------------- //Tags\Colors ---------------------------------------------------------------------------- LLComboBox* combo = getChild("tag_spoofing_combobox"); combo->setCurrentByIndex(mSelectedClient); childSetEnabled("friends_color_textbox", mUseStatusColors); - childSetEnabled("friend_color_swatch", mUseStatusColors); - childSetEnabled("estate_owner_color_swatch", mUseStatusColors); - childSetEnabled("linden_color_swatch", mUseStatusColors); - childSetEnabled("muted_color_swatch", mUseStatusColors); + childSetEnabled("friend_color_swatch", mUseStatusColors || mColorFriendChat); + childSetEnabled("estate_owner_color_swatch", mUseStatusColors || mColorEOChat); + childSetEnabled("linden_color_swatch", mUseStatusColors || mColorLindenChat); + childSetEnabled("muted_color_swatch", mUseStatusColors || mColorMutedChat); childSetEnabled("custom_tag_label_text", mCustomTagOn); childSetEnabled("custom_tag_label_box", mCustomTagOn); @@ -246,12 +264,16 @@ void LLPrefsAscentVan::refresh() // Reset settings to local copy void LLPrefsAscentVan::cancel() { - //General -------------------------------------------------------------------------------- + //Main ----------------------------------------------------------------------------------- gSavedSettings.setBOOL("AscentStoreSettingsPerAccount", mUseAccountSettings); gSavedSettings.setBOOL("AscentDisableTeleportScreens", !mShowTPScreen); gSavedSettings.setBOOL("OptionPlayTpSound", mPlayTPSound); gSavedSettings.setBOOL("AscentDisableLogoutScreens", !mShowLogScreens); gSavedSettings.setBOOL("SGDisableChatAnimation", mDisableChatAnimation); + gSavedSettings.setBOOL("LiruAddNotReplace", mAddNotReplace); + gSavedSettings.setBOOL("TurnAroundWhenWalkingBackwards", mTurnAround); + gSavedSettings.setBOOL("AnnounceSnapshots", mAnnounceSnapshots); + gSavedSettings.setBOOL("AnnounceStreamMetadata", mAnnounceStreamMetadata); //Tags\Colors ---------------------------------------------------------------------------- gSavedSettings.setBOOL("AscentUseTag", mAscentUseTag); @@ -273,7 +295,12 @@ void LLPrefsAscentVan::cancel() gSavedSettings.setColor4("AscentEstateOwnerColor", mEstateOwnerColor); gSavedSettings.setColor4("AscentLindenColor", mLindenColor); gSavedSettings.setColor4("AscentMutedColor", mMutedColor); -// gSavedSettings.setColor4("MoyMiniMapCustomColor", mCustomColor); + gSavedSettings.setColor4("MoyMiniMapCustomColor", mCustomColor); + gSavedSettings.setBOOL("ColorFriendChat", mColorFriendChat); + gSavedSettings.setBOOL("ColorEstateOwnerChat", mColorEOChat); + gSavedSettings.setBOOL("ColorLindenChat", mColorLindenChat); + gSavedSettings.setBOOL("ColorMutedChat", mColorMutedChat); +// gSavedSettings.setBOOL("ColorCustomChat", mColorCustomChat); //Body Dynamics -------------------------------------------------------------------------- gSavedSettings.setBOOL("EmeraldBreastPhysicsToggle", mBreastPhysicsToggle); diff --git a/indra/newview/ascentprefsvan.h b/indra/newview/ascentprefsvan.h index 115b1c206..62600a264 100644 --- a/indra/newview/ascentprefsvan.h +++ b/indra/newview/ascentprefsvan.h @@ -52,12 +52,16 @@ protected: static void onCommitCheckBox(LLUICtrl* ctrl, void* user_data); static void onCommitTextModified(LLUICtrl* ctrl, void* userdata); static void onManualClientUpdate(void* data); - //General + //Main BOOL mUseAccountSettings; BOOL mShowTPScreen; BOOL mPlayTPSound; BOOL mShowLogScreens; bool mDisableChatAnimation; + bool mAddNotReplace; + bool mTurnAround; + bool mAnnounceSnapshots; + bool mAnnounceStreamMetadata; //Tags\Colors BOOL mAscentUseTag; std::string mReportClientUUID; @@ -78,6 +82,12 @@ protected: LLColor4 mEstateOwnerColor; LLColor4 mLindenColor; LLColor4 mMutedColor; + LLColor4 mCustomColor; + bool mColorFriendChat; + bool mColorEOChat; + bool mColorLindenChat; + bool mColorMutedChat; +// bool mColorCustomChat; //Body Dynamics BOOL mBreastPhysicsToggle; F32 mBoobMass; diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index 5f416241c..6d19d693c 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -300,8 +300,6 @@ bool cmd_line_chat(std::string revised_text, EChatType type) if(LLUUID::parseUUID(avatarKey, &tempUUID)) { char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ - LLDynamicArray ids; - ids.push_back(tempUUID); std::string tpMsg="Join me!"; LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_StartLure); @@ -312,11 +310,8 @@ bool cmd_line_chat(std::string revised_text, EChatType type) msg->addU8Fast(_PREHASH_LureType, (U8)0); msg->addStringFast(_PREHASH_Message, tpMsg); - for(LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) - { - msg->nextBlockFast(_PREHASH_TargetData); - msg->addUUIDFast(_PREHASH_TargetID, *itr); - } + msg->nextBlockFast(_PREHASH_TargetData); + msg->addUUIDFast(_PREHASH_TargetID, tempUUID); gAgent.sendReliableMessage(); snprintf(buffer,sizeof(buffer),"Offered TP to key %s",tempUUID.asString().c_str()); cmdline_printchat(std::string(buffer)); @@ -466,7 +461,7 @@ bool cmd_line_chat(std::string revised_text, EChatType type) return true; } -//case insensative search for avatar in draw distance +//case insensitive search for avatar in draw distance //TODO: make this use the avatar list floaters list so we have EVERYONE // even if they are out of draw distance. LLUUID cmdline_partial_name2key(std::string partial_name) @@ -476,7 +471,7 @@ LLUUID cmdline_partial_name2key(std::string partial_name) LLStringUtil::toLower(partial_name); LLWorld::getInstance()->getAvatars(&avatars); typedef std::vector::const_iterator av_iter; - bool has_avatarlist = (LLFloaterAvatarList::getInstance() ? true : false); + bool has_avatarlist = LLFloaterAvatarList::instanceExists(); if(has_avatarlist) LLFloaterAvatarList::getInstance()->updateAvatarList(); for(av_iter i = avatars.begin(); i != avatars.end(); ++i) @@ -516,7 +511,7 @@ void cmdline_tp2name(std::string target) cmdline_printchat("Avatar not found."); return; } - LLFloaterAvatarList* avlist = LLFloaterAvatarList::getInstance(); + LLFloaterAvatarList* avlist = LLFloaterAvatarList::instanceExists() ? LLFloaterAvatarList::getInstance() : NULL; LLVOAvatar* avatarp = gObjectList.findAvatar(avkey); if(avatarp) { diff --git a/indra/newview/floaterao.cpp b/indra/newview/floaterao.cpp index f7bdf090f..59f922cca 100644 --- a/indra/newview/floaterao.cpp +++ b/indra/newview/floaterao.cpp @@ -356,9 +356,9 @@ BOOL LLFloaterAO::postBuild() childSetAction("newcard",onClickNewCard,this); childSetAction("prevstand",onClickPrevStand,this); childSetAction("nextstand",onClickNextStand,this); - childSetCommitCallback("AOEnabled",onClickToggleAO); - childSetCommitCallback("AOSitsEnabled",onClickToggleSits); - childSetCommitCallback("standtime",onSpinnerCommit); + getChild("AOEnabled")->setCommitCallback(boost::bind(&LLFloaterAO::onClickToggleAO)); + getChild("AOSitsEnabled")->setCommitCallback(boost::bind(&LLFloaterAO::onClickToggleSits)); + getChild("standtime")->setCommitCallback(boost::bind(&LLFloaterAO::onSpinnerCommit,_1)); mcomboBox_stands = getChild("stands"); mcomboBox_walks = getChild("walks"); mcomboBox_runs = getChild("runs"); @@ -376,28 +376,28 @@ BOOL LLFloaterAO::postBuild() mcomboBox_lands = getChild("lands"); mcomboBox_standups = getChild("standups"); mcomboBox_prejumps = getChild("prejumps"); - getChild("stands")->setCommitCallback(onComboBoxCommit); - getChild("walks")->setCommitCallback(onComboBoxCommit); - getChild("runs")->setCommitCallback(onComboBoxCommit); - getChild("jumps")->setCommitCallback(onComboBoxCommit); - getChild("sits")->setCommitCallback(onComboBoxCommit); - getChild("gsits")->setCommitCallback(onComboBoxCommit); - getChild("crouchs")->setCommitCallback(onComboBoxCommit); - getChild("cwalks")->setCommitCallback(onComboBoxCommit); - getChild("falls")->setCommitCallback(onComboBoxCommit); - getChild("hovers")->setCommitCallback(onComboBoxCommit); - getChild("flys")->setCommitCallback(onComboBoxCommit); - getChild("flyslows")->setCommitCallback(onComboBoxCommit); - getChild("flyups")->setCommitCallback(onComboBoxCommit); - getChild("flydowns")->setCommitCallback(onComboBoxCommit); - getChild("lands")->setCommitCallback(onComboBoxCommit); - getChild("standups")->setCommitCallback(onComboBoxCommit); - getChild("prejumps")->setCommitCallback(onComboBoxCommit); + getChild("stands")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("walks")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("runs")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("jumps")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("sits")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("gsits")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("crouchs")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("cwalks")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("falls")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("hovers")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("flys")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("flyslows")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("flyups")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("flydowns")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("lands")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("standups")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("prejumps")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); return TRUE; } -void LLFloaterAO::onSpinnerCommit(LLUICtrl* ctrl, void* userdata) +void LLFloaterAO::onSpinnerCommit(LLUICtrl* ctrl) { LLSpinCtrl* spin = (LLSpinCtrl*) ctrl; if(spin) @@ -409,7 +409,7 @@ void LLFloaterAO::onSpinnerCommit(LLUICtrl* ctrl, void* userdata) } } -void LLFloaterAO::onComboBoxCommit(LLUICtrl* ctrl, void* userdata) +void LLFloaterAO::onComboBoxCommit(LLUICtrl* ctrl) { LLComboBox* box = (LLComboBox*)ctrl; if(box) @@ -727,12 +727,12 @@ void LLFloaterAO::onClickLess(void* data) updateLayout(sInstance); } -void LLFloaterAO::onClickToggleAO(LLUICtrl *, void*) +void LLFloaterAO::onClickToggleAO() { run(); } -void LLFloaterAO::onClickToggleSits(LLUICtrl *, void*) +void LLFloaterAO::onClickToggleSits() { run(); } diff --git a/indra/newview/floaterao.h b/indra/newview/floaterao.h index 55cc7c052..72bdf2903 100644 --- a/indra/newview/floaterao.h +++ b/indra/newview/floaterao.h @@ -68,8 +68,8 @@ public: static void show(void*); static void init(); - static void onClickToggleAO(LLUICtrl *, void*); - static void onClickToggleSits(LLUICtrl *, void*); + static void onClickToggleAO(); + static void onClickToggleSits(); static void run(); static void updateLayout(LLFloaterAO* floater); @@ -115,8 +115,8 @@ private: static AONoteCardDropTarget* mAOItemDropTarget; static void AOItemDrop(LLViewerInventoryItem* item); - static void onSpinnerCommit(LLUICtrl* ctrl, void* userdata); - static void onComboBoxCommit(LLUICtrl* ctrl, void* userdata); + static void onSpinnerCommit(LLUICtrl* ctrl); + static void onComboBoxCommit(LLUICtrl* ctrl); static BOOL SetDefault(void *userdata, LLUUID ao_id, std::string defaultanim); BOOL mDirty; diff --git a/indra/newview/floaterlocalassetbrowse.cpp b/indra/newview/floaterlocalassetbrowse.cpp index eeb1ebfd4..ef6de943d 100644 --- a/indra/newview/floaterlocalassetbrowse.cpp +++ b/indra/newview/floaterlocalassetbrowse.cpp @@ -800,13 +800,13 @@ FloaterLocalAssetBrowser::FloaterLocalAssetBrowser() mUploadBtn->setClickedCallback( onClickUpload, this); // combo callback - mTypeComboBox->setCommitCallback(onCommitTypeCombo); + mTypeComboBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onCommitTypeCombo,this)); // scrolllist callbacks - mBitmapList->setCommitCallback(onChooseBitmapList); + mBitmapList->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onChooseBitmapList,this)); // checkbox callbacks - mUpdateChkBox->setCommitCallback(onClickUpdateChkbox); + mUpdateChkBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onClickUpdateChkbox,this)); } @@ -857,34 +857,33 @@ void FloaterLocalAssetBrowser::onClickUpload(void* userdata) } } -void FloaterLocalAssetBrowser::onChooseBitmapList(LLUICtrl* ctrl, void *userdata) +void FloaterLocalAssetBrowser::onChooseBitmapList() { - bool button_status = sLFInstance->mBitmapList->isEmpty(); - sLFInstance->mDelBtn->setEnabled(!button_status); - sLFInstance->mUploadBtn->setEnabled(!button_status); + bool button_status = mBitmapList->isEmpty(); + mDelBtn->setEnabled(!button_status); + mUploadBtn->setEnabled(!button_status); - sLFInstance->UpdateRightSide(); + UpdateRightSide(); } -void FloaterLocalAssetBrowser::onClickUpdateChkbox(LLUICtrl *ctrl, void *userdata) +void FloaterLocalAssetBrowser::onClickUpdateChkbox() { - std::string temp_str = sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); + std::string temp_str = mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); if ( !temp_str.empty() ) { gLocalBrowser->onUpdateBool( (LLUUID)temp_str ); - sLFInstance->UpdateRightSide(); + UpdateRightSide(); } } -void FloaterLocalAssetBrowser::onCommitTypeCombo(LLUICtrl* ctrl, void *userdata) +void FloaterLocalAssetBrowser::onCommitTypeCombo() { - std::string temp_str = sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); + std::string temp_str = mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); if ( !temp_str.empty() ) { S32 selection = sLFInstance->mTypeComboBox->getCurrentIndex(); gLocalBrowser->onSetType( (LLUUID)temp_str, selection ); - } } diff --git a/indra/newview/floaterlocalassetbrowse.h b/indra/newview/floaterlocalassetbrowse.h index fb26cdccc..b95845710 100644 --- a/indra/newview/floaterlocalassetbrowse.h +++ b/indra/newview/floaterlocalassetbrowse.h @@ -236,13 +236,13 @@ private: static void onClickUpload(void* userdata); // ScrollList callback declarations - static void onChooseBitmapList(LLUICtrl* ctrl, void* userdata); + void onChooseBitmapList(); // Checkbox callback declarations - static void onClickUpdateChkbox(LLUICtrl* ctrl, void* userdata); + void onClickUpdateChkbox(); // Combobox type select - static void onCommitTypeCombo(LLUICtrl* ctrl, void* userdata); + void onCommitTypeCombo(); // Widgets LLButton* mAddBtn; diff --git a/indra/newview/floatervoicelicense.cpp b/indra/newview/floatervoicelicense.cpp index 322c4778e..17dff4a5e 100644 --- a/indra/newview/floatervoicelicense.cpp +++ b/indra/newview/floatervoicelicense.cpp @@ -85,13 +85,13 @@ class LLIamHereVoice : public LLHTTPClient::ResponderWithResult mParent = parentIn; }; - virtual void result( const LLSD& content ) + /*virtual*/ void result( const LLSD& content ) { if ( mParent ) mParent->setSiteIsAlive( true ); }; - virtual void error( U32 status, const std::string& reason ) + /*virtual*/ void error( U32 status, const std::string& reason ) { if ( mParent ) { @@ -103,7 +103,8 @@ class LLIamHereVoice : public LLHTTPClient::ResponderWithResult } }; - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return iamHereVoice_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return iamHereVoice_timeout; } + /*virtual*/ char const* getName(void) const { return "LLIamHereVoice"; } }; // this is global and not a class member to keep crud out of the header file diff --git a/indra/newview/hbfloatergrouptitles.cpp b/indra/newview/hbfloatergrouptitles.cpp index bd6de9efd..9ebdae508 100644 --- a/indra/newview/hbfloatergrouptitles.cpp +++ b/indra/newview/hbfloatergrouptitles.cpp @@ -127,8 +127,7 @@ BOOL HBFloaterGroupTitles::postBuild() { return FALSE; } - mTitlesList->setCallbackUserData(this); - mTitlesList->setDoubleClickCallback(onActivate); + mTitlesList->setDoubleClickCallback(boost::bind(&HBFloaterGroupTitles::onActivate,this)); childSetAction("activate", onActivate, this); update_titles_list(this); return TRUE; diff --git a/indra/newview/hgfloatertexteditor.cpp b/indra/newview/hgfloatertexteditor.cpp index 12342b4ba..fdda09ea3 100644 --- a/indra/newview/hgfloatertexteditor.cpp +++ b/indra/newview/hgfloatertexteditor.cpp @@ -142,7 +142,7 @@ void HGFloaterTextEditor::imageCallback(BOOL success, } else { - src_vi->setBoostLevel(LLViewerTexture::BOOST_UI); + src_vi->setBoostLevel(LLGLTexture::BOOST_UI); } } diff --git a/indra/newview/hippogridmanager.cpp b/indra/newview/hippogridmanager.cpp index c0ceef71d..674206e79 100644 --- a/indra/newview/hippogridmanager.cpp +++ b/indra/newview/hippogridmanager.cpp @@ -51,6 +51,7 @@ HippoGridInfo::HippoGridInfo(const std::string& gridName) : mGridMessage(""), mXmlState(XML_VOID), mVoiceConnector("SLVoice"), + mIsInProductionGrid(false), mRenderCompat(true), mInvLinks(false), mAutoUpdate(false), @@ -72,7 +73,12 @@ HippoGridInfo::Platform HippoGridInfo::getPlatform() bool HippoGridInfo::isOpenSimulator() const { - return (mPlatform == HippoGridInfo::PLATFORM_OPENSIM); + return (mPlatform == HippoGridInfo::PLATFORM_OPENSIM || mPlatform == HippoGridInfo::PLATFORM_AURORA); +} + +bool HippoGridInfo::isAurora() const +{ + return (mPlatform == HippoGridInfo::PLATFORM_AURORA); } bool HippoGridInfo::isSecondLife() const @@ -80,16 +86,26 @@ bool HippoGridInfo::isSecondLife() const return (mPlatform == HippoGridInfo::PLATFORM_SECONDLIFE); } +bool HippoGridInfo::isInProductionGrid() const +{ + llassert(mPlatform == HippoGridInfo::PLATFORM_SECONDLIFE); + return mIsInProductionGrid; +} + const std::string& HippoGridInfo::getGridName() const { return mGridName; } -const std::string& HippoGridInfo::getGridOwner() const { - if(isSecondLife()) { +const std::string& HippoGridInfo::getGridOwner() const +{ + if(isSecondLife()) + { static const std::string ll = "Linden Lab"; return ll; - } else { + } + else + { return this->getGridName(); } } @@ -220,12 +236,20 @@ void HippoGridInfo::setGridNick(std::string gridNick) { setGridName(gridNick); } + if(gridNick == "secondlife") + { + mIsInProductionGrid = true; + } } void HippoGridInfo::setLoginUri(const std::string& loginUri) { std::string uri = loginUri; mLoginUri = sanitizeUri(uri); + if (utf8str_tolower(LLURI(uri).hostName()) == "login.agni.lindenlab.com") + { + mIsInProductionGrid = true; + } } void HippoGridInfo::setLoginPage(const std::string& loginPage) diff --git a/indra/newview/hippogridmanager.h b/indra/newview/hippogridmanager.h index 4f3ef634e..310033af7 100644 --- a/indra/newview/hippogridmanager.h +++ b/indra/newview/hippogridmanager.h @@ -38,7 +38,9 @@ public: Platform getPlatform(); bool isOpenSimulator() const; + bool isAurora() const; bool isSecondLife() const; + bool isInProductionGrid() const; // Should only be called if isSecondLife() returns true. const std::string& getGridName() const; const std::string& getGridOwner() const; const std::string& getLoginUri() const; @@ -110,6 +112,7 @@ private: std::string mPasswordUrl; std::string mSearchUrl; std::string mVoiceConnector; + bool mIsInProductionGrid; bool mRenderCompat; bool mInvLinks; bool mAutoUpdate; diff --git a/indra/newview/hippolimits.cpp b/indra/newview/hippolimits.cpp index 3bdec44d3..2ee9a7344 100644 --- a/indra/newview/hippolimits.cpp +++ b/indra/newview/hippolimits.cpp @@ -21,6 +21,8 @@ void HippoLimits::setLimits() { if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_SECONDLIFE) { setSecondLifeLimits(); + } else if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_AURORA) { + setAuroraLimits(); } else { setOpenSimLimits(); } @@ -46,6 +48,17 @@ void HippoLimits::setOpenSimLimits() } } +void HippoLimits::setAuroraLimits() +{ + mMaxAgentGroups = gHippoGridManager->getConnectedGrid()->getMaxAgentGroups(); + if (mMaxAgentGroups < 0) mMaxAgentGroups = 50; + mMaxPrimScale = 8192.0f; + mMinPrimScale = 0.001f; + mMaxHeight = 10000.0f; + mMinHoleSize = 0.001f; + mMaxHollow = 99.0f; +} + void HippoLimits::setSecondLifeLimits() { llinfos << "Using Second Life limits." << llendl; diff --git a/indra/newview/hippolimits.h b/indra/newview/hippolimits.h index 78d42a7df..91625276b 100644 --- a/indra/newview/hippolimits.h +++ b/indra/newview/hippolimits.h @@ -26,6 +26,7 @@ private: float mMinPrimScale; void setOpenSimLimits(); + void setAuroraLimits(); void setSecondLifeLimits(); }; diff --git a/indra/newview/importtracker.cpp b/indra/newview/importtracker.cpp index ce2e6bb1e..68a75796a 100644 --- a/indra/newview/importtracker.cpp +++ b/indra/newview/importtracker.cpp @@ -301,7 +301,9 @@ void ImportTracker::get_update(S32 newid, BOOL justCreated, BOOL createSelected) break;*/ } } -/*struct InventoryImportInfo + +#if 0 +struct InventoryImportInfo { U32 localid; LLAssetType::EType type; @@ -372,7 +374,7 @@ public: { } - virtual void uploadComplete(const LLSD& content) + /*virtual*/ void uploadComplete(const LLSD& content) { LLPointer cb = new JCImportTransferCallback(data); LLPermissions perm; @@ -385,6 +387,7 @@ public: cb); } + /*virtual*/ char const* getName(void) const { return "JCImportInventoryResponder"; } private: InventoryImportInfo* data; }; @@ -405,13 +408,14 @@ public: LLAssetType::EType asset_type) : LLAssetUploadResponder(post_data, file_name, asset_type) { } - virtual void uploadComplete(const LLSD& content) + /*virtual*/ void uploadComplete(const LLSD& content) { //cmdline_printchat("completed upload, inserting"); LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(item_id); LLViewerObject* objectp = find(data->localid); insert(item, objectp, data); } + /*virtual*/ char const* getName(void) const { return "JCPostInvUploadResponder"; } private: LLUUID item_id; InventoryImportInfo* data; @@ -642,7 +646,7 @@ void ImportTracker::send_inventory(LLSD& prim) LLFILE* fp = LLFile::fopen(data->filename, "rb"); if(fp)//HACK LOL LOL LOL { - LLWearable* wearable = new LLWearable(LLUUID::null); + LLViewerWearable* wearable = new LLWearable(LLUUID::null); wearable->importFile( fp ); //if (!res) { @@ -1119,4 +1123,4 @@ void ImportTracker::plywood_above_head() msg->addUUIDFast(_PREHASH_RayTargetID, LLUUID::null); msg->sendReliable(region->getHost()); } -*/ +#endif diff --git a/indra/newview/jcfloaterareasearch.cpp b/indra/newview/jcfloaterareasearch.cpp index 3cb15b052..8479b9a3b 100644 --- a/indra/newview/jcfloaterareasearch.cpp +++ b/indra/newview/jcfloaterareasearch.cpp @@ -88,8 +88,7 @@ void JCFloaterAreaSearch::close(bool app) BOOL JCFloaterAreaSearch::postBuild() { mResultList = getChild("result_list"); - mResultList->setCallbackUserData(this); - mResultList->setDoubleClickCallback(onDoubleClick); + mResultList->setDoubleClickCallback(onDoubleClick,this); mResultList->sortByColumn("Name", TRUE); mCounterText = getChild("counter"); @@ -235,7 +234,7 @@ void JCFloaterAreaSearch::results() if (!(sInstance->getVisible())) return; if (sRequested > 0 && sInstance->mLastUpdateTimer.getElapsedTimeF32() < min_refresh_interval) return; //llinfos << "results()" << llendl; - LLDynamicArray selected = sInstance->mResultList->getSelectedIDs(); + uuid_vec_t selected = sInstance->mResultList->getSelectedIDs(); S32 scrollpos = sInstance->mResultList->getScrollPos(); sInstance->mResultList->deleteAllItems(); S32 i; @@ -303,7 +302,7 @@ void JCFloaterAreaSearch::results() } } - sInstance->mResultList->sortItems(); + sInstance->mResultList->updateSort(); sInstance->mResultList->selectMultiple(selected); sInstance->mResultList->setScrollPos(scrollpos); sInstance->mCounterText->setText(llformat("%d listed/%d pending/%d total", sInstance->mResultList->getItemCount(), sRequested, sObjectDetails.size())); diff --git a/indra/newview/lggdicdownload.cpp b/indra/newview/lggdicdownload.cpp index d4caa10ae..8207ed0bc 100644 --- a/indra/newview/lggdicdownload.cpp +++ b/indra/newview/lggdicdownload.cpp @@ -57,12 +57,13 @@ class EmeraldDicDownloader : public LLHTTPClient::ResponderWithCompleted public: EmeraldDicDownloader(lggDicDownloadFloater* spanel, std::string sname); ~EmeraldDicDownloader() { } - void completedRaw( + /*virtual*/ void completedRaw( U32 status, const std::string& reason, const LLChannelDescriptors& channels, const buffer_ptr_t& buffer); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return emeraldDicDownloader_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return emeraldDicDownloader_timeout; } + /*virtual*/ char const* getName(void) const { return "EmeraldDicDownloader"; } private: lggDicDownloadFloater* panel; std::string name; diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index a319e38d7..d4a5108c5 100644 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -54,13 +54,13 @@ public: } } - void error( U32 statusNum, const std::string& reason ) + /*virtual*/ void error( U32 statusNum, const std::string& reason ) { llwarns << "Transport error "< -LLUUID gReSitTargetID; -LLVector3 gReSitOffset; -// +class LLTeleportRequest +{ +public: + enum EStatus + { + kPending, + kStarted, + kFailed, + kRestartPending + }; + + LLTeleportRequest(); + virtual ~LLTeleportRequest(); + + EStatus getStatus() const {return mStatus;}; + void setStatus(EStatus pStatus) {mStatus = pStatus;}; + + virtual bool canRestartTeleport(); + + virtual void startTeleport() = 0; + virtual void restartTeleport(); + +protected: + +private: + EStatus mStatus; +}; + +class LLTeleportRequestViaLandmark : public LLTeleportRequest +{ +public: + LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId); + virtual ~LLTeleportRequestViaLandmark(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + virtual void restartTeleport(); + +protected: + inline const LLUUID &getLandmarkId() const {return mLandmarkId;}; + +private: + LLUUID mLandmarkId; +}; + +class LLTeleportRequestViaLure : public LLTeleportRequestViaLandmark +{ +public: + LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike); + virtual ~LLTeleportRequestViaLure(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + +protected: + inline BOOL isLureGodLike() const {return mIsLureGodLike;}; + +private: + BOOL mIsLureGodLike; +}; + +class LLTeleportRequestViaLocation : public LLTeleportRequest +{ +public: + LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal); + virtual ~LLTeleportRequestViaLocation(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + virtual void restartTeleport(); + +protected: + inline const LLVector3d &getPosGlobal() const {return mPosGlobal;}; + +private: + LLVector3d mPosGlobal; +}; + + +class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation +{ +public: + LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal); + virtual ~LLTeleportRequestViaLocationLookAt(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + virtual void restartTeleport(); + +protected: + +private: + +}; //-------------------------------------------------------------------- // Statics // @@ -200,6 +295,19 @@ LLAgent::LLAgent() : mbTeleportKeepsLookAt(false), mAgentAccess(new LLAgentAccess(gSavedSettings)), + mGodLevelChangeSignal(), + mCanEditParcel(false), + mTeleportRequest(), + mTeleportFinishedSlot(), + mTeleportFailedSlot(), + mIsMaturityRatingChangingDuringTeleport(false), + mMaturityRatingChange(0U), + mIsDoSendMaturityPreferenceToServer(false), + mMaturityPreferenceRequestId(0U), + mMaturityPreferenceResponseId(0U), + mMaturityPreferenceNumRetries(0U), + mLastKnownRequestMaturity(SIM_ACCESS_MIN), + mLastKnownResponseMaturity(SIM_ACCESS_MIN), mTeleportState( TELEPORT_NONE ), mRegionp(NULL), @@ -276,9 +384,21 @@ void LLAgent::init() gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2)); gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2)); + mLastKnownResponseMaturity = static_cast(gSavedSettings.getU32("PreferredMaturity")); + mLastKnownRequestMaturity = mLastKnownResponseMaturity; + mIsDoSendMaturityPreferenceToServer = true; LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback)); + if (!mTeleportFinishedSlot.connected()) + { + mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this)); + } + if (!mTeleportFailedSlot.connected()) + { + mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this)); + } + mInitialized = TRUE; } @@ -291,6 +411,14 @@ void LLAgent::cleanup() if(mPendingLure) delete mPendingLure; mPendingLure = NULL; + if (mTeleportFinishedSlot.connected()) + { + mTeleportFinishedSlot.disconnect(); + } + if (mTeleportFailedSlot.connected()) + { + mTeleportFailedSlot.disconnect(); + } } //----------------------------------------------------------------------------- @@ -644,6 +772,18 @@ void LLAgent::toggleTPosed() setTPosed(posed); } +void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id) +{ + llinfos << "called" << llendl; + + if (isAgentAvatarValid() && + !gAgentAvatarp->isUsingServerBakes() && + (mRegionp->getCentralBakeVersion()>0)) + { + LLAppearanceMgr::instance().requestServerAppearanceUpdate(); + } +} + //----------------------------------------------------------------------------- // setRegion() @@ -735,6 +875,19 @@ void LLAgent::setRegion(LLViewerRegion *regionp) { LLEnvManagerNew::instance().onRegionCrossing(); } + + // If the newly entered region is using server bakes, and our + // current appearance is non-baked, request appearance update from + // server. + if (mRegionp->capabilitiesReceived()) + { + handleServerBakeRegionTransition(mRegionp->getRegionID()); + } + else + { + // Need to handle via callback after caps arrive. + mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::handleServerBakeRegionTransition,this,_1)); + } } @@ -1421,7 +1574,7 @@ void LLAgent::setAutoPilotTargetGlobal(const LLVector3d &target_global) LLViewerObject *obj; LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); - F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); + F64 target_height = llmax((F64)(isAgentAvatarValid() ? gAgentAvatarp->getPelvisToFoot() : 0.0), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); // clamp z value of target to minimum height above ground mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height; @@ -1574,12 +1727,10 @@ void LLAgent::autoPilot(F32 *delta_yaw) *delta_yaw = yaw; // Compute when to start slowing down and when to stop - F32 stop_distance = mAutoPilotStopDistance; F32 slow_distance; if (getFlying()) { slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f); - stop_distance = llmax(2.f, mAutoPilotStopDistance); } else { @@ -1865,7 +2016,6 @@ void LLAgent::endAnimationUpdateUI() gMenuBarView->setVisible(TRUE); gStatusBar->setVisibleForMouselook(true); - LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(TRUE); LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); @@ -1959,7 +2109,6 @@ void LLAgent::endAnimationUpdateUI() gMenuBarView->setVisible(FALSE); gStatusBar->setVisibleForMouselook(false); - LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(FALSE); // clear out camera lag effect gAgentCamera.clearCameraLag(); @@ -2376,38 +2525,272 @@ int LLAgent::convertTextToMaturity(char text) return LLAgentAccess::convertTextToMaturity(text); } -bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity) +extern AIHTTPTimeoutPolicy maturityPreferences_timeout; +class LLMaturityPreferencesResponder : public LLHTTPClient::ResponderWithResult { - if (!getRegion()) - return false; - - // Update agent access preference on the server - std::string url = getRegion()->getCapability("UpdateAgentInformation"); - if (!url.empty()) - { - // Set new access preference - LLSD access_prefs = LLSD::emptyMap(); - if (preferredMaturity == SIM_ACCESS_PG) - { - access_prefs["max"] = "PG"; - } - else if (preferredMaturity == SIM_ACCESS_MATURE) - { - access_prefs["max"] = "M"; - } - if (preferredMaturity == SIM_ACCESS_ADULT) - { - access_prefs["max"] = "A"; - } +public: + LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity); + virtual ~LLMaturityPreferencesResponder(); - LLSD body = LLSD::emptyMap(); - body["access_prefs"] = access_prefs; - llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: " - << url << llendl; - LLHTTPClient::post(url, body, new LLHTTPClient::ResponderIgnore); // Ignore response - return true; + /*virtual*/ void result(const LLSD &pContent); + /*virtual*/ void error(U32 pStatus, const std::string& pReason); + + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return maturityPreferences_timeout; } + /*virtual*/ char const* getName(void) const { return "LLMaturityPreferencesResponder"; } + +private: + U8 parseMaturityFromServerResponse(const LLSD &pContent); + + LLAgent *mAgent; + U8 mPreferredMaturity; + U8 mPreviousMaturity; +}; + +LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity) : + mAgent(pAgent), + mPreferredMaturity(pPreferredMaturity), + mPreviousMaturity(pPreviousMaturity) +{ +} + +LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder() +{ +} + +void LLMaturityPreferencesResponder::result(const LLSD &pContent) +{ + U8 actualMaturity = parseMaturityFromServerResponse(pContent); + + if (actualMaturity != mPreferredMaturity) + { + llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) + << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', the server responded with '" + << LLViewerRegion::accessToString(actualMaturity) << "' [value:" << static_cast(actualMaturity) << ", llsd:" + << pContent << "]" << llendl; + } + mAgent->handlePreferredMaturityResult(actualMaturity); +} + +void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason) +{ + llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) + << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '" + << pReason << "' [status:" << pStatus << "]" << llendl; + mAgent->handlePreferredMaturityError(); +} + +U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent) +{ + // stinson 05/24/2012 Pathfinding regions have re-defined the response behavior. In the old server code, + // if you attempted to change the preferred maturity to the same value, the response content would be an + // undefined LLSD block. In the new server code with pathfinding, the response content should always be + // defined. Thus, the check for isUndefined() can be replaced with an assert after pathfinding is merged + // into server trunk and fully deployed. + U8 maturity = SIM_ACCESS_MIN; + if (pContent.isUndefined()) + { + maturity = mPreferredMaturity; + } + else + { + llassert(!pContent.isUndefined()); + llassert(pContent.isMap()); + + if (!pContent.isUndefined() && pContent.isMap()) + { + // stinson 05/24/2012 Pathfinding regions have re-defined the response syntax. The if statement catches + // the new syntax, and the else statement catches the old syntax. After pathfinding is merged into + // server trunk and fully deployed, we can remove the else statement. + if (pContent.has("access_prefs")) + { + llassert(pContent.has("access_prefs")); + llassert(pContent.get("access_prefs").isMap()); + llassert(pContent.get("access_prefs").has("max")); + llassert(pContent.get("access_prefs").get("max").isString()); + if (pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max") && + pContent.get("access_prefs").get("max").isString()) + { + LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString(); + LLStringUtil::trim(actualPreference); + maturity = LLViewerRegion::shortStringToAccess(actualPreference); + } + } + else if (pContent.has("max")) + { + llassert(pContent.get("max").isString()); + if (pContent.get("max").isString()) + { + LLSD::String actualPreference = pContent.get("max").asString(); + LLStringUtil::trim(actualPreference); + maturity = LLViewerRegion::shortStringToAccess(actualPreference); + } + } + } + } + + return maturity; +} + +void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity) +{ + // Update the number of responses received + ++mMaturityPreferenceResponseId; + llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId); + + // Update the last known server maturity response + mLastKnownResponseMaturity = pServerMaturity; + + // Ignore all responses if we know there are more unanswered requests that are expected + if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId) + { + // If we received a response that matches the last known request, then we are good + if (mLastKnownRequestMaturity == mLastKnownResponseMaturity) + { + mMaturityPreferenceNumRetries = 0; + reportPreferredMaturitySuccess(); + llassert(static_cast(gSavedSettings.getU32("PreferredMaturity")) == mLastKnownResponseMaturity); + } + // Else, the viewer is out of sync with the server, so let's try to re-sync with the + // server by re-sending our last known request. Cap the re-tries at 3 just to be safe. + else if (++mMaturityPreferenceNumRetries <= 3) + { + llinfos << "Retrying attempt #" << mMaturityPreferenceNumRetries << " to set viewer preferred maturity to '" + << LLViewerRegion::accessToString(mLastKnownRequestMaturity) << "'" << llendl; + sendMaturityPreferenceToServer(mLastKnownRequestMaturity); + } + // Else, the viewer is style out of sync with the server after 3 retries, so inform the user + else + { + mMaturityPreferenceNumRetries = 0; + reportPreferredMaturityError(); + } + } +} + +void LLAgent::handlePreferredMaturityError() +{ + // Update the number of responses received + ++mMaturityPreferenceResponseId; + llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId); + + // Ignore all responses if we know there are more unanswered requests that are expected + if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId) + { + mMaturityPreferenceNumRetries = 0; + + // If we received a response that matches the last known request, then we are synced with + // the server, but not quite sure why we are + if (mLastKnownRequestMaturity == mLastKnownResponseMaturity) + { + llwarns << "Got an error but maturity preference '" << LLViewerRegion::accessToString(mLastKnownRequestMaturity) + << "' seems to be in sync with the server" << llendl; + reportPreferredMaturitySuccess(); + } + // Else, the more likely case is that the last request does not match the last response, + // so inform the user + else + { + reportPreferredMaturityError(); + } + } +} + +void LLAgent::reportPreferredMaturitySuccess() +{ + // If there is a pending teleport request waiting for the maturity preference to be synced with + // the server, let's start the pending request + if (hasPendingTeleportRequest()) + { + startTeleportRequest(); + } +} + +void LLAgent::reportPreferredMaturityError() +{ + // If there is a pending teleport request waiting for the maturity preference to be synced with + // the server, we were unable to successfully sync with the server on maturity preference, so let's + // just raise the screen. + mIsMaturityRatingChangingDuringTeleport = false; + if (hasPendingTeleportRequest()) + { + setTeleportState(LLAgent::TELEPORT_NONE); + } + + // Get the last known maturity request from the user activity + std::string preferredMaturity = LLViewerRegion::accessToString(mLastKnownRequestMaturity); + LLStringUtil::toLower(preferredMaturity); + + // Get the last known maturity response from the server + std::string actualMaturity = LLViewerRegion::accessToString(mLastKnownResponseMaturity); + LLStringUtil::toLower(actualMaturity); + + // Notify the user + LLSD args = LLSD::emptyMap(); + args["PREFERRED_MATURITY"] = preferredMaturity; + args["ACTUAL_MATURITY"] = actualMaturity; + LLNotificationsUtil::add("MaturityChangeError", args); + + // Check the saved settings to ensure that we are consistent. If we are not consistent, update + // the viewer, but do not send anything to server + U8 localMaturity = static_cast(gSavedSettings.getU32("PreferredMaturity")); + if (localMaturity != mLastKnownResponseMaturity) + { + bool tmpIsDoSendMaturityPreferenceToServer = mIsDoSendMaturityPreferenceToServer; + mIsDoSendMaturityPreferenceToServer = false; + llinfos << "Setting viewer preferred maturity to '" << LLViewerRegion::accessToString(mLastKnownResponseMaturity) << "'" << llendl; + gSavedSettings.setU32("PreferredMaturity", static_cast(mLastKnownResponseMaturity)); + mIsDoSendMaturityPreferenceToServer = tmpIsDoSendMaturityPreferenceToServer; + } +} + +bool LLAgent::isMaturityPreferenceSyncedWithServer() const +{ + return (mMaturityPreferenceRequestId == mMaturityPreferenceResponseId); +} + +void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity) +{ + // Only send maturity preference to the server if enabled + if (mIsDoSendMaturityPreferenceToServer) + { + // Increment the number of requests. The handlers manage a separate count of responses. + ++mMaturityPreferenceRequestId; + + // Update the last know maturity request + mLastKnownRequestMaturity = pPreferredMaturity; + + // Create a response handler + boost::intrusive_ptr responderPtr = new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity); + + // If we don't have a region, report it as an error + if (getRegion() == NULL) + { + responderPtr->error(0U, "region is not defined"); + } + else + { + // Find the capability to send maturity preference + std::string url = getRegion()->getCapability("UpdateAgentInformation"); + + // If the capability is not defined, report it as an error + if (url.empty()) + { + responderPtr->error(0U, "capability 'UpdateAgentInformation' is not defined for region"); + } + else + { + // Set new access preference + LLSD access_prefs = LLSD::emptyMap(); + access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity); + + LLSD body = LLSD::emptyMap(); + body["access_prefs"] = access_prefs; + llinfos << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity) + << "' via capability to: " << url << llendl; + LLHTTPClient::post(url, body, responderPtr); + } + } } - return false; } BOOL LLAgent::getAdminOverride() const @@ -2428,6 +2811,12 @@ void LLAgent::setAdminOverride(BOOL b) void LLAgent::setGodLevel(U8 god_level) { mAgentAccess->setGodLevel(god_level); + mGodLevelChangeSignal(god_level); +} + +LLAgent::god_level_change_slot_t LLAgent::registerGodLevelChanageListener(god_level_change_callback_t pGodLevelChangeCallback) +{ + return mGodLevelChangeSignal.connect(pGodLevelChangeCallback); } void LLAgent::setAOTransition() @@ -2445,9 +2834,9 @@ bool LLAgent::validateMaturity(const LLSD& newvalue) return mAgentAccess->canSetMaturity(newvalue.asInteger()); } -void LLAgent::handleMaturity(const LLSD& newvalue) +void LLAgent::handleMaturity(const LLSD &pNewValue) { - sendMaturityPreferenceToServer(newvalue.asInteger()); + sendMaturityPreferenceToServer(static_cast(pNewValue.asInteger())); } void LLAgent::buildFullname(std::string& name) const @@ -3335,7 +3724,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * return; } - if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) + if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance()) { // ignore baked textures when in customize mode return; @@ -3359,7 +3748,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * if ((S32)texture_index < TEX_NUM_INDICES ) { - const LLVOAvatarDictionary::TextureEntry *texture_entry = LLVOAvatarDictionary::instance().getTexture((ETextureIndex)texture_index); + const LLAvatarAppearanceDictionary::TextureEntry *texture_entry = LLAvatarAppearanceDictionary::instance().getTexture((ETextureIndex)texture_index); if (texture_entry) { EBakedTextureIndex baked_index = texture_entry->mBakedTextureIndex; @@ -3459,7 +3848,7 @@ void LLAgent::clearVisualParams(void *data) // protected bool LLAgent::teleportCore(bool is_local) { - if(TELEPORT_NONE != mTeleportState) + if ((TELEPORT_NONE != mTeleportState) && (mTeleportState != TELEPORT_PENDING)) { llwarns << "Attempt to teleport when already teleporting." << llendl; // @@ -3518,8 +3907,12 @@ bool LLAgent::teleportCore(bool is_local) gTeleportDisplay = TRUE; gAgent.setTeleportState( LLAgent::TELEPORT_START ); - //release geometry from old location - gPipeline.resetVertexBuffers(); + /*static const LLCachedControl hide_tp_screen("AscentDisableTeleportScreens",false); + if(!hide_tp_screen) + { + //release geometry from old location + gPipeline.resetVertexBuffers(); + }*/ if (gSavedSettings.getBOOL("SpeedRez")) { @@ -3542,6 +3935,102 @@ bool LLAgent::teleportCore(bool is_local) return true; } +bool LLAgent::hasRestartableFailedTeleportRequest() +{ + return ((mTeleportRequest != NULL) && (mTeleportRequest->getStatus() == LLTeleportRequest::kFailed) && + mTeleportRequest->canRestartTeleport()); +} + +void LLAgent::restartFailedTeleportRequest() +{ + if (hasRestartableFailedTeleportRequest()) + { + mTeleportRequest->setStatus(LLTeleportRequest::kRestartPending); + startTeleportRequest(); + } +} + +void LLAgent::clearTeleportRequest() +{ + mTeleportRequest.reset(); +} + +void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange) +{ + mIsMaturityRatingChangingDuringTeleport = true; + mMaturityRatingChange = pMaturityRatingChange; +} + +bool LLAgent::hasPendingTeleportRequest() +{ + return ((mTeleportRequest != NULL) && + ((mTeleportRequest->getStatus() == LLTeleportRequest::kPending) || + (mTeleportRequest->getStatus() == LLTeleportRequest::kRestartPending))); +} + +void LLAgent::startTeleportRequest() +{ + if (hasPendingTeleportRequest()) + { + if (!isMaturityPreferenceSyncedWithServer()) + { + gTeleportDisplay = TRUE; + setTeleportState(TELEPORT_PENDING); + } + else + { + switch (mTeleportRequest->getStatus()) + { + case LLTeleportRequest::kPending : + mTeleportRequest->setStatus(LLTeleportRequest::kStarted); + mTeleportRequest->startTeleport(); + break; + case LLTeleportRequest::kRestartPending : + llassert(mTeleportRequest->canRestartTeleport()); + mTeleportRequest->setStatus(LLTeleportRequest::kStarted); + mTeleportRequest->restartTeleport(); + break; + default : + llassert(0); + break; + } + } + } +} + +void LLAgent::handleTeleportFinished() +{ + clearTeleportRequest(); + if (mIsMaturityRatingChangingDuringTeleport) + { + // notify user that the maturity preference has been changed + std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange); + LLStringUtil::toLower(maturityRating); + LLSD args; + args["RATING"] = maturityRating; + LLNotificationsUtil::add("PreferredMaturityChanged", args); + mIsMaturityRatingChangingDuringTeleport = false; + } +} + +void LLAgent::handleTeleportFailed() +{ + if (mTeleportRequest != NULL) + { + mTeleportRequest->setStatus(LLTeleportRequest::kFailed); + } + if (mIsMaturityRatingChangingDuringTeleport) + { + // notify user that the maturity preference has been changed + std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange); + LLStringUtil::toLower(maturityRating); + LLSD args; + args["RATING"] = maturityRating; + LLNotificationsUtil::add("PreferredMaturityChanged", args); + mIsMaturityRatingChangingDuringTeleport = false; + } +} + void LLAgent::teleportRequest( const U64& region_handle, const LLVector3& pos_local, @@ -3588,7 +4077,12 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) return; } // [/RLVa:KB] + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id)); + startTeleportRequest(); +} +void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id) +{ LLViewerRegion *regionp = getRegion(); if(regionp && teleportCore()) { @@ -3603,6 +4097,12 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) } void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike) +{ + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike)); + startTeleportRequest(); +} + +void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike) { LLViewerRegion* regionp = getRegion(); if(regionp && teleportCore()) @@ -3635,18 +4135,21 @@ void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike) // James Cook, July 28, 2005 void LLAgent::teleportCancel() { - LLViewerRegion* regionp = getRegion(); - if(regionp) + if (!hasPendingTeleportRequest()) { - // send the message - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("TeleportCancel"); - msg->nextBlockFast(_PREHASH_Info); - msg->addUUIDFast(_PREHASH_AgentID, getID()); - msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); - sendReliableMessage(); - } - gTeleportDisplay = FALSE; + LLViewerRegion* regionp = getRegion(); + if(regionp) + { + // send the message + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("TeleportCancel"); + msg->nextBlockFast(_PREHASH_Info); + msg->addUUIDFast(_PREHASH_AgentID, getID()); + msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); + sendReliableMessage(); + } + } + clearTeleportRequest(); gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } @@ -3671,13 +4174,24 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) } } // [/RLVa:KB] + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global)); + startTeleportRequest(); +} +void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global) +{ LLViewerRegion* regionp = getRegion(); + + if (!regionp) + { + return; + } + U64 handle = to_region_handle(pos_global); LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); bool calc = gSavedSettings.getBOOL("OptionOffsetTPByAgentHeight"); LLVector3 offset = LLVector3(0.f,0.f,0.f); - if(calc) + if(calc && isAgentAvatarValid()) offset += LLVector3(0.f,0.f,gAgentAvatarp->getScale().mV[2] / 2.0); if(regionp && info) { @@ -3687,7 +4201,7 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) (F32)(pos_global.mdV[VY] - region_origin.mdV[VY]), (F32)(pos_global.mdV[VZ])); pos_local += offset; - teleportRequest(info->getHandle(), pos_local); + teleportRequest(handle, pos_local); } else if(regionp && teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY]))) @@ -3732,14 +4246,15 @@ void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global) return; } // [/RLVa:KB] + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global)); + startTeleportRequest(); +} +void LLAgent::doTeleportViaLocationLookAt(const LLVector3d& pos_global) +{ mbTeleportKeepsLookAt = true; gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); // detach camera form avatar, so it keeps direction U64 region_handle = to_region_handle(pos_global); - LLSimInfo* simInfo = LLWorldMap::instance().simInfoFromHandle(region_handle); - if(simInfo) - region_handle = simInfo->getHandle(); - LLVector3 pos_local = (LLVector3)(pos_global - from_region_handle(region_handle)); teleportRequest(region_handle, pos_local, getTeleportKeepsLookAt()); } @@ -3909,13 +4424,19 @@ void LLAgent::requestLeaveGodMode() //----------------------------------------------------------------------------- void LLAgent::sendAgentSetAppearance() { - if (!isAgentAvatarValid()) return; + // FIXME DRANO - problems around new-style appearance in an old-style region. + // - does this get called? + // - need to change mUseServerBakes->FALSE in that case + // - need to call processAvatarAppearance as if server had returned this result? + // gAgentAvatarp->mUseServerBakes = FALSE; - if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures())) + if (gAgentQueryManager.mNumPendingQueries > 0) { return; } + if (!isAgentAvatarValid() || (getRegion() && getRegion()->getCentralBakeVersion())) return; + LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL; //dumpAvatarTEs( "sendAgentSetAppearance()" ); @@ -3955,7 +4476,7 @@ void LLAgent::sendAgentSetAppearance() for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ ) { - const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index); + const ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index); // if we're not wearing a skirt, we don't need the texture to be baked if (texture_index == TEX_SKIRT_BAKED && !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT)) @@ -3978,7 +4499,7 @@ void LLAgent::sendAgentSetAppearance() for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { BOOL generate_valid_hash = TRUE; - if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index)) + if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLAvatarAppearanceDefines::EBakedTextureIndex)baked_index)) { generate_valid_hash = FALSE; LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << LL_ENDL; @@ -3987,7 +4508,7 @@ void LLAgent::sendAgentSetAppearance() const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash); if (hash.notNull()) { - ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index); + ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index); msg->nextBlockFast(_PREHASH_WearableData); msg->addUUIDFast(_PREHASH_CacheID, hash); msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index); @@ -4179,7 +4700,7 @@ void LLAgent::showLureDestination(const std::string fromname, const int global_x { U16 grid_x = (U16)(global_x / REGION_WIDTH_UNITS); U16 grid_y = (U16)(global_y / REGION_WIDTH_UNITS); - LLWorldMap::getInstance()->sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true); //Will call onFoundLureDestination on response + LLWorldMapMessage::getInstance()->sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true); //Will call onFoundLureDestination on response } } @@ -4232,4 +4753,148 @@ LLAgentQueryManager::~LLAgentQueryManager() { } +//----------------------------------------------------------------------------- +// LLTeleportRequest +//----------------------------------------------------------------------------- + +LLTeleportRequest::LLTeleportRequest() + : mStatus(kPending) +{ +} + +LLTeleportRequest::~LLTeleportRequest() +{ +} + +bool LLTeleportRequest::canRestartTeleport() +{ + return false; +} + +void LLTeleportRequest::restartTeleport() +{ + llassert(0); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLandmark +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId) + : LLTeleportRequest(), + mLandmarkId(pLandmarkId) +{ +} + +LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark() +{ +} + +bool LLTeleportRequestViaLandmark::canRestartTeleport() +{ + return true; +} + +void LLTeleportRequestViaLandmark::startTeleport() +{ + gAgent.doTeleportViaLandmark(getLandmarkId()); +} + +void LLTeleportRequestViaLandmark::restartTeleport() +{ + gAgent.doTeleportViaLandmark(getLandmarkId()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLure +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike) + : LLTeleportRequestViaLandmark(pLureId), + mIsLureGodLike(pIsLureGodLike) +{ +} + +LLTeleportRequestViaLure::~LLTeleportRequestViaLure() +{ +} + +bool LLTeleportRequestViaLure::canRestartTeleport() +{ + // stinson 05/17/2012 : cannot restart a teleport via lure because of server-side restrictions + // The current scenario is as follows: + // 1. User A initializes a request for User B to teleport via lure + // 2. User B accepts the teleport via lure request + // 3. The server sees the init request from User A and the accept request from User B and matches them up + // 4. The server then removes the paired requests up from the "queue" + // 5. The server then fails User B's teleport for reason of maturity level (for example) + // 6. User B's viewer prompts user to increase their maturity level profile value. + // 7. User B confirms and accepts increase in maturity level + // 8. User B's viewer then attempts to teleport via lure again + // 9. This request will time-out on the viewer-side because User A's initial request has been removed from the "queue" in step 4 + + return false; +} + +void LLTeleportRequestViaLure::startTeleport() +{ + gAgent.doTeleportViaLure(getLandmarkId(), isLureGodLike()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLocation +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLocation::LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal) + : LLTeleportRequest(), + mPosGlobal(pPosGlobal) +{ +} + +LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation() +{ +} + +bool LLTeleportRequestViaLocation::canRestartTeleport() +{ + return true; +} + +void LLTeleportRequestViaLocation::startTeleport() +{ + gAgent.doTeleportViaLocation(getPosGlobal()); +} + +void LLTeleportRequestViaLocation::restartTeleport() +{ + gAgent.doTeleportViaLocation(getPosGlobal()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLocationLookAt +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLocationLookAt::LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal) + : LLTeleportRequestViaLocation(pPosGlobal) +{ +} + +LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt() +{ +} + +bool LLTeleportRequestViaLocationLookAt::canRestartTeleport() +{ + return true; +} + +void LLTeleportRequestViaLocationLookAt::startTeleport() +{ + gAgent.doTeleportViaLocationLookAt(getPosGlobal()); +} + +void LLTeleportRequestViaLocationLookAt::restartTeleport() +{ + gAgent.doTeleportViaLocationLookAt(getPosGlobal()); +} // EOF diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 82513766e..7a37a05f1 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -42,11 +42,13 @@ #include "llagentdata.h" // gAgentID, gAgentSessionID #include "llcharacter.h" #include "llcoordframe.h" // for mFrameAgent -#include "llvoavatardefines.h" +#include "llavatarappearancedefines.h" #include "llviewerinventory.h" #include "llinventorymodel.h" #include "v3dmath.h" +#include +#include #include extern const BOOL ANIMATE; @@ -67,8 +69,10 @@ class LLViewerObject; class LLAgentDropGroupViewerNode; class LLAgentAccess; class LLSimInfo; +class LLTeleportRequest; typedef std::vector llvo_vec_t; +typedef boost::shared_ptr LLTeleportRequestPtr; enum EAnimRequest { @@ -557,7 +561,8 @@ public: TELEPORT_MOVING = 3, // Viewer has received destination location from source simulator TELEPORT_START_ARRIVAL = 4, // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator TELEPORT_ARRIVING = 5, // Make the user wait while content "pre-caches" - TELEPORT_LOCAL = 6 // Teleporting in-sim without showing the progress screen + TELEPORT_LOCAL = 6, // Teleporting in-sim without showing the progress screen + TELEPORT_PENDING = 7 }; public: @@ -573,9 +578,6 @@ public: // Teleport Actions //-------------------------------------------------------------------- public: - void teleportRequest(const U64& region_handle, - const LLVector3& pos_local, // Go to a named location home - bool look_at_from_camera = false); void teleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark void teleportHome() { teleportViaLandmark(LLUUID::null); } // Go home void teleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location @@ -586,6 +588,45 @@ public: protected: bool teleportCore(bool is_local = false); // Stuff for all teleports; returns true if the teleport can proceed + //-------------------------------------------------------------------- + // Teleport State + //-------------------------------------------------------------------- + +public: + bool hasRestartableFailedTeleportRequest(); + void restartFailedTeleportRequest(); + void clearTeleportRequest(); + void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange); + +private: + friend class LLTeleportRequest; + friend class LLTeleportRequestViaLandmark; + friend class LLTeleportRequestViaLure; + friend class LLTeleportRequestViaLocation; + friend class LLTeleportRequestViaLocationLookAt; + + LLTeleportRequestPtr mTeleportRequest; + boost::signals2::connection mTeleportFinishedSlot; + boost::signals2::connection mTeleportFailedSlot; + + bool mIsMaturityRatingChangingDuringTeleport; + U8 mMaturityRatingChange; + + bool hasPendingTeleportRequest(); + void startTeleportRequest(); + + void teleportRequest(const U64& region_handle, + const LLVector3& pos_local, // Go to a named location home + bool look_at_from_camera = false); + void doTeleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark + void doTeleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location + void doTeleportViaLocation(const LLVector3d& pos_global); // To a global location - this will probably need to be deprecated + void doTeleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation + + void handleTeleportFinished(); + void handleTeleportFailed(); + void handleServerBakeRegionTransition(const LLUUID& region_id); + //-------------------------------------------------------------------- // Teleport State //-------------------------------------------------------------------- @@ -648,6 +689,16 @@ public: void requestEnterGodMode(); void requestLeaveGodMode(); + typedef boost::function god_level_change_callback_t; + typedef boost::signals2::signal god_level_change_signal_t; + typedef boost::signals2::connection god_level_change_slot_t; + + god_level_change_slot_t registerGodLevelChanageListener(god_level_change_callback_t pGodLevelChangeCallback); + +private: + god_level_change_signal_t mGodLevelChangeSignal; + + //-------------------------------------------------------------------- // Maturity //-------------------------------------------------------------------- @@ -670,10 +721,25 @@ public: void setTeen(bool teen); void setMaturity(char text); static int convertTextToMaturity(char text); - bool sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"? +private: + bool mIsDoSendMaturityPreferenceToServer; + unsigned int mMaturityPreferenceRequestId; + unsigned int mMaturityPreferenceResponseId; + unsigned int mMaturityPreferenceNumRetries; + U8 mLastKnownRequestMaturity; + U8 mLastKnownResponseMaturity; + + bool isMaturityPreferenceSyncedWithServer() const; + void sendMaturityPreferenceToServer(U8 pPreferredMaturity); + + friend class LLMaturityPreferencesResponder; + void handlePreferredMaturityResult(U8 pServerMaturity); + void handlePreferredMaturityError(); + void reportPreferredMaturitySuccess(); + void reportPreferredMaturityError(); // Maturity callbacks for PreferredMaturity control variable - void handleMaturity(const LLSD& newvalue); + void handleMaturity(const LLSD &pNewValue); bool validateMaturity(const LLSD& newvalue); @@ -887,16 +953,12 @@ private: S32 mNumPendingQueries; S32 mWearablesCacheQueryID; //mTextureCacheQueryID; U32 mUpdateSerialNum; //mAgentWearablesUpdateSerialNum - S32 mActiveCacheQueries[LLVOAvatarDefines::BAKED_NUM_INDICES]; + S32 mActiveCacheQueries[LLAvatarAppearanceDefines::BAKED_NUM_INDICES]; }; extern LLAgentQueryManager gAgentQueryManager; extern std::string gAuthString; -// -extern LLUUID gReSitTargetID; -extern LLVector3 gReSitOffset; -// void update_group_floaters(const LLUUID& group_id); #endif diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 93390e1e5..ed7165e50 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -55,7 +55,7 @@ #include "rlvhandler.h" // [/RLVa:KB] -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines; extern LLMenuBarGL* gMenuBarView; @@ -161,7 +161,6 @@ LLAgentCamera::LLAgentCamera() : mFocusObjectDist(0.f), mFocusObjectOffset(), mFocusDotRadius( 0.1f ), // meters - mTrackFocusObject(TRUE), mUIOffset(0.f), mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed @@ -225,7 +224,6 @@ void LLAgentCamera::init() mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"); mTargetCameraDistance = mCurrentCameraDistance; mCameraZoomFraction = 1.f; - mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject"); mInitialized = true; } @@ -410,11 +408,7 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi } LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation - LLVector3 object_extents = object->getScale(); - //this stuff just seems to make camera snapping worse... - //const LLVector4a* oe4 = object->mDrawable->getSpatialExtents(); - //object_extents.set( oe4[1][0], oe4[1][1], oe4[1][2] ); - + LLVector3 object_extents = object->getScale(); // make sure they object extents are non-zero object_extents.clamp(0.001f, F32_MAX); @@ -615,7 +609,6 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance) abs_target_offset.abs(); LLVector3 target_offset_dir = target_offset_origin; - F32 object_radius = mFocusObject->getVObjRadius(); BOOL target_outside_object_extents = FALSE; @@ -710,17 +703,6 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance) LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent()); - // length projected orthogonal to target offset - F32 camera_offset_dist = (camera_offset_object - target_offset_dir * (camera_offset_object * target_offset_dir)).magVec(); - - // calculate whether the target point would be "visible" if it were outside the bounding box - // on the opposite of the splitting plane defined by object_split_axis; - BOOL exterior_target_visible = FALSE; - if (camera_offset_dist > object_radius) - { - // target is visible from camera, so turn off fov zoom - exterior_target_visible = TRUE; - } F32 camera_offset_clip = camera_offset_object * object_split_axis; F32 target_offset_clip = target_offset_dir * object_split_axis; @@ -1114,8 +1096,8 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y) if (!isAgentAvatarValid()) return; - LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot.getWorldRotation(); - LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot.getWorldRotation(); + LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation(); + LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation(); if ((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) && (root_at * last_at_axis > 0.95f)) @@ -1434,7 +1416,7 @@ void LLAgentCamera::updateCamera() // llinfos << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << llendl; F32 ui_offset = 0.f; - if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) + if( LLFloaterCustomize::instanceExists() /*CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode*/ ) { ui_offset = calcCustomizeAvatarUIOffset( camera_pos_global ); } @@ -1477,7 +1459,7 @@ void LLAgentCamera::updateCamera() LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() + LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation(); LLVector3 diff = mCameraPositionAgent - head_pos; - diff = diff * ~gAgentAvatarp->mRoot.getWorldRotation(); + diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation(); LLJoint* torso_joint = gAgentAvatarp->mTorsop; LLJoint* chest_joint = gAgentAvatarp->mChestp; @@ -1501,7 +1483,7 @@ void LLAgentCamera::updateCamera() gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff); - gAgentAvatarp->mRoot.updateWorldMatrixChildren(); + gAgentAvatarp->mRoot->updateWorldMatrixChildren(); for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); iter != gAgentAvatarp->mAttachmentPoints.end(); ) @@ -1561,9 +1543,9 @@ F32 LLAgentCamera::calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_glo { F32 ui_offset = 0.f; - if( gFloaterCustomize ) + if( LLFloaterCustomize::instanceExists() ) { - const LLRect& rect = gFloaterCustomize->getRect(); + const LLRect& rect = LLFloaterCustomize::getInstance()->getRect(); // Move the camera so that the avatar isn't covered up by this floater. F32 fraction_of_fov = 0.5f - (0.5f * (1.f - llmin(1.f, ((F32)rect.getWidth() / (F32)gViewerWindow->getWindowWidth())))); @@ -1627,17 +1609,15 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal() { LLDrawable* drawablep = mFocusObject->mDrawable; - if (mTrackFocusObject && - drawablep && - drawablep->isActive()) + if (gSavedSettings.getBOOL("TrackFocusObject") && drawablep) { - if (!mFocusObject->isAvatar()) + if (drawablep->isActive() && !mFocusObject->isAvatar()) { if (mFocusObject->isSelected()) { gPipeline.updateMoveNormalAsync(drawablep); } - else + else if(!drawablep->isState(LLDrawable::ON_MOVE_LIST)) { if (drawablep->isState(LLDrawable::MOVE_UNDAMPED)) { @@ -1734,7 +1714,6 @@ F32 LLAgentCamera::calcCameraFOVZoomFactor() else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar) { // don't FOV zoom on mostly transparent objects - LLVector3 focus_offset = mFocusObjectOffset; F32 obj_min_dist = 0.f; if (!gSavedSettings.getBOOL("AscentDisableMinZoomDist")) calcCameraMinDistance(obj_min_dist); @@ -1762,7 +1741,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) F32 camera_land_height; LLVector3d frame_center_global = !isAgentAvatarValid() ? gAgent.getPositionGlobal() : - gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition()); + gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition()); BOOL isConstrained = FALSE; LLVector3d head_offset; @@ -1844,8 +1823,9 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) local_camera_offset = gAgent.getFrameAgent().rotateToAbsolute( local_camera_offset ); } + static const LLCachedControl sg_ignore_sim_cam_consts("SGIgnoreSimulatorCameraConstraints",false); if ( !mCameraCollidePlane.isExactlyZero() - && !gSavedSettings.getBOOL("SGIgnoreSimulatorCameraConstraints") + && !sg_ignore_sim_cam_consts && isAgentAvatarValid() && !gAgentAvatarp->isSitting()) { @@ -1900,7 +1880,6 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) // set the global camera position LLVector3d camera_offset; - LLVector3 av_pos = !isAgentAvatarValid() ? LLVector3::zero : gAgentAvatarp->getRenderPosition(); camera_offset.setVec( local_camera_offset ); camera_position_global = frame_center_global + head_offset + camera_offset; @@ -2311,12 +2290,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) } updateLastCamera(); mCameraMode = CAMERA_MODE_THIRD_PERSON; - U32 old_flags = gAgent.getControlFlags(); gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK); - if (old_flags != gAgent.getControlFlags()) - { - gAgent.setFlagsDirty(); - } } // Remove any pitch from the avatar @@ -2353,7 +2327,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToCustomizeAvatar() { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) + if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid()) { return; } @@ -2392,29 +2366,21 @@ void LLAgentCamera::changeCameraToCustomizeAvatar() gFocusMgr.setKeyboardFocus( NULL ); gFocusMgr.setMouseCapture( NULL ); - LLVOAvatarSelf::onCustomizeStart(); + // Remove any pitch or rotation from the avatar + LLVector3 at = gAgent.getAtAxis(); + at.mV[VZ] = 0.f; + at.normalize(); + gAgent.resetAxes(at); - if (isAgentAvatarValid()) + gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); + gAgent.setCustomAnim(TRUE); + gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); + LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); + + if (turn_motion) { - // Remove any pitch or rotation from the avatar - LLVector3 at = gAgent.getAtAxis(); - at.mV[VZ] = 0.f; - at.normalize(); - gAgent.resetAxes(at); - - gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); - gAgent.setCustomAnim(TRUE); - gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); - LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); - - if (turn_motion) - { - // delay camera animation long enough to play through turn animation - setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); - } - - gAgentAvatarp->invalidateAll(); - gAgentAvatarp->updateMeshTextures(); + // delay camera animation long enough to play through turn animation + setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); } } // @@ -2522,9 +2488,10 @@ void LLAgentCamera::setFocusObject(LLViewerObject* object) //----------------------------------------------------------------------------- void LLAgentCamera::setFocusGlobal(const LLPickInfo& pick) { + static const LLCachedControl freeze_time("FreezeTime",false); LLViewerObject* objectp = gObjectList.findObject(pick.mObjectID); - if (objectp) + if (objectp && !freeze_time) { // focus on object plus designated offset // which may or may not be same as pick.mPosGlobal @@ -2636,7 +2603,7 @@ void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, con { startCameraAnimation(); - if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) + if( LLFloaterCustomize::instanceExists()/*CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode*/ ) { // Compensate for the fact that the camera has already been offset to make room for LLFloaterCustomize. mAnimationCameraStartGlobal -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * calcCustomizeAvatarUIOffset( mAnimationCameraStartGlobal )); @@ -2802,18 +2769,18 @@ void LLAgentCamera::lookAtLastChat() } //Pulled implementation out of lookAtLastChat and adapted to work for for general objects -void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) +bool LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) { // Block if camera is animating or not in normal third person camera mode if (mCameraAnimating || !cameraThirdPerson()) { - return; + return false; } LLViewerObject *chatter = gObjectList.findObject(object_id); if (!chatter) { - return; + return false; } LLVector3 delta_pos; @@ -2844,7 +2811,7 @@ void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) new_camera_pos += left * 0.3f; new_camera_pos += up * 0.2f; - //setFocusOnAvatar(FALSE, FALSE); + setFocusOnAvatar(FALSE, FALSE); if (chatter_av->mHeadp) { @@ -2862,7 +2829,6 @@ void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) else mCameraFocusOffsetTarget.setVec(radius, radius, 0.f); } - setFocusOnAvatar(FALSE, TRUE); } else { @@ -2882,17 +2848,15 @@ void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) new_camera_pos += left * 0.3f; new_camera_pos += up * 0.2f; - //setFocusOnAvatar(FALSE, FALSE); - + setFocusOnAvatar(FALSE, FALSE); setFocusGlobal(chatter->getPositionGlobal(), object_id); if(self) mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); else mCameraFocusOffsetTarget.setVec(radius, radius, 0.f); - - setFocusOnAvatar(FALSE, TRUE); } + return true; } diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index 663742751..3a2ced058 100644 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -211,7 +211,6 @@ public: void setCameraPosAndFocusGlobal(const LLVector3d& pos, const LLVector3d& focus, const LLUUID &object_id); void clearFocusObject(); void setFocusObject(LLViewerObject* object); - void setObjectTracking(BOOL track) { mTrackFocusObject = track; } const LLVector3d &getFocusGlobal() const { return mFocusGlobal; } const LLVector3d &getFocusTargetGlobal() const { return mFocusTargetGlobal; } private: @@ -224,7 +223,6 @@ private: F32 mFocusObjectDist; LLVector3 mFocusObjectOffset; F32 mFocusDotRadius; // Meters - BOOL mTrackFocusObject; //-------------------------------------------------------------------- // Lookat / Pointat @@ -234,7 +232,7 @@ public: BOOL setLookAt(ELookAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero); ELookAtType getLookAtType(); void lookAtLastChat(); - void lookAtObject(const LLUUID &object_id, bool self=true); + bool lookAtObject(const LLUUID &object_id, bool self=true); void slamLookAt(const LLVector3 &look_at); // Set the physics data BOOL setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero); EPointAtType getPointAtType(); diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index ab33da86c..44aac869e 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -69,24 +69,21 @@ BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE; bool LLAgentWearables::mInitialWearablesLoaded = false; // [/SL:KB] -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines; /////////////////////////////////////////////////////////////////////////////// // Callback to wear and start editing an item that has just been created. -class LLWearAndEditCallback : public LLInventoryCallback +void wear_and_edit_cb(const LLUUID& inv_item) { - void fire(const LLUUID& inv_item) - { - if (inv_item.isNull()) return; - - // Request editing the item after it gets worn. - gAgentWearables.requestEditingWearable(inv_item); - - // Wear it. - LLAppearanceMgr::instance().wearItemOnAvatar(inv_item); - } -}; + if (inv_item.isNull()) return; + + // Request editing the item after it gets worn. + gAgentWearables.requestEditingWearable(inv_item); + + // Wear it. + LLAppearanceMgr::instance().wearItemOnAvatar(inv_item); +} /////////////////////////////////////////////////////////////////////////////// @@ -95,7 +92,7 @@ class LLWearAndEditCallback : public LLInventoryCallback // wearable type stored in asset is some other value. // Calling this function whenever a wearable is added to increase visibility if this problem // turns up in other inventories. -void checkWearableAgainstInventory(LLWearable *wearable) +void checkWearableAgainstInventory(LLViewerWearable *wearable) { if (wearable->getItemID().isNull()) return; @@ -132,7 +129,7 @@ void LLAgentWearables::dump() llinfos << "Type: " << i << " count " << count << llendl; for (U32 j=0; joutputRezTiming("Sending wearables request"); sendAgentWearablesRequest(); + setAvatarAppearance(avatar); } } @@ -226,7 +226,7 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal * @param todo Bitmask of actions to take on completion. */ LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback( - LLPointer cb, LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo) : + LLPointer cb, LLWearableType::EType type, U32 index, LLViewerWearable* wearable, U32 todo) : mType(type), mIndex(index), mWearable(wearable), @@ -279,7 +279,7 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::EType type, const U32 index, const LLUUID& item_id, - LLWearable* wearable) + LLViewerWearable* wearable) { llinfos << "type " << type << " index " << index << " item " << item_id.asString() << llendl; @@ -326,7 +326,7 @@ void LLAgentWearables::sendAgentWearablesUpdate() { for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index) { - LLWearable* wearable = getWearable((LLWearableType::EType)type,index); + LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type,index); if (wearable) { if (wearable->getItemID().isNull()) @@ -368,7 +368,7 @@ void LLAgentWearables::sendAgentWearablesUpdate() U8 type_u8 = (U8)type; gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8 ); - LLWearable* wearable = getWearable((LLWearableType::EType)type, 0); + LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type, 0); if( wearable ) { //llinfos << "Sending wearable " << wearable->getName() << llendl; @@ -397,14 +397,14 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 const std::string new_name) { //llassert_always(index == 0); - LLWearable* old_wearable = getWearable(type, index); + LLViewerWearable* old_wearable = getViewerWearable(type, index); if(!old_wearable) return; bool name_changed = !new_name.empty() && (new_name != old_wearable->getName()); if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion()) { LLUUID old_item_id = old_wearable->getItemID(); - LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); - new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()? + LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); + new_wearable->setItemID(old_item_id); // should this be in LLViewerWearable::copyDataFrom()? setWearable(type,index,new_wearable); // old_wearable may still be referred to by other inventory items. Revert @@ -470,7 +470,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 } } -LLWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType type, +LLViewerWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found) @@ -480,7 +480,7 @@ LLWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType type, llwarns << "LLAgent::saveWearableAs() not copyable." << llendl; return NULL; } - LLWearable* old_wearable = getWearable(type, index); + LLViewerWearable* old_wearable = getViewerWearable(type, index); if (!old_wearable) { llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl; @@ -495,7 +495,7 @@ LLWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType type, } std::string trunc_name(new_name); LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN); - LLWearable* new_wearable = LLWearableList::instance().createCopy( + LLViewerWearable* new_wearable = LLWearableList::instance().createCopy( old_wearable, trunc_name); LLPointer cb = @@ -534,7 +534,7 @@ LLWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType type, void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index) { - LLWearable* wearable = getWearable(type, index); + LLViewerWearable* wearable = getViewerWearable(type, index); llassert(wearable); if (wearable) { @@ -551,7 +551,7 @@ void LLAgentWearables::saveAllWearables() // return; //} - for( S32 i=0; i < LLWearableType::WT_COUNT; i++ ) + for (S32 i=0; i < LLWearableType::WT_COUNT; i++) { for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) saveWearable((LLWearableType::EType)i, j, FALSE); @@ -559,23 +559,23 @@ void LLAgentWearables::saveAllWearables() sendAgentWearablesUpdate(); } -// Called when the user changes the name of a wearable inventory item that is currenlty being worn. -void LLAgentWearables::setWearableName( const LLUUID& item_id, const std::string& new_name ) +// Called when the user changes the name of a wearable inventory item that is currently being worn. +void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& new_name) { - for( S32 i=0; i < LLWearableType::WT_COUNT; i++ ) + for (S32 i=0; i < LLWearableType::WT_COUNT; i++) { for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) { LLUUID curr_item_id = getWearableItemID((LLWearableType::EType)i,j); if (curr_item_id == item_id) { - LLWearable* old_wearable = getWearable((LLWearableType::EType)i,j); + LLViewerWearable* old_wearable = getViewerWearable((LLWearableType::EType)i,j); llassert(old_wearable); if (!old_wearable) continue; std::string old_name = old_wearable->getName(); old_wearable->setName(new_name); - LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); + LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); new_wearable->setItemID(item_id); LLInventoryItem* item = gInventory.getItem(item_id); if (item) @@ -659,14 +659,14 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::ETyp return item; } -const LLWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id ) const +const LLViewerWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id ) const { const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id); for (S32 i=0; i < LLWearableType::WT_COUNT; i++) { for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) { - const LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j); + const LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j); if (curr_wearable && (curr_wearable->getItemID() == base_item_id)) { return curr_wearable; @@ -676,14 +676,14 @@ const LLWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id return NULL; } -LLWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id ) +LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) { const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id); for (S32 i=0; i < LLWearableType::WT_COUNT; i++) { for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) { - LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j); + LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j); if (curr_wearable && (curr_wearable->getItemID() == base_item_id)) { return curr_wearable; @@ -693,13 +693,13 @@ LLWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id ) return NULL; } -LLWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id) +LLViewerWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id) { for (S32 i=0; i < LLWearableType::WT_COUNT; i++) { for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) { - LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j); + LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j); if (curr_wearable && (curr_wearable->getAssetID() == asset_id)) { return curr_wearable; @@ -718,240 +718,63 @@ void LLAgentWearables::sendAgentWearablesRequest() gAgent.sendReliableMessage(); } -// Used to enable/disable menu items. +LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) +{ + return dynamic_cast (getWearable(type, index)); +} + +const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const +{ + return dynamic_cast (getWearable(type, index)); +} + // static BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type) { return (gAgentWearables.getWearableCount(type) > 0); } -LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) +// virtual +void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed) { - //llassert_always(index == 0); - wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); - if (wearable_iter == mWearableDatas.end()) + if (isAgentAvatarValid()) { - return NULL; - } - wearableentry_vec_t& wearable_vec = wearable_iter->second; - if (index>=wearable_vec.size()) - { - return NULL; - } - else - { - return wearable_vec[index]; - } -} - -void LLAgentWearables::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable) -{ - //llassert_always(index == 0); - LLWearable *old_wearable = getWearable(type,index); - if (!old_wearable) - { - pushWearable(type,wearable); - return; + const BOOL upload_result = removed; + gAgentAvatarp->wearableUpdated(wearable->getType(), upload_result); } - wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); - if (wearable_iter == mWearableDatas.end()) - { - llwarns << "invalid type, type " << type << " index " << index << llendl; - return; - } - wearableentry_vec_t& wearable_vec = wearable_iter->second; - if (index>=wearable_vec.size()) - { - llwarns << "invalid index, type " << type << " index " << index << llendl; - } - else - { - wearable_vec[index] = wearable; - old_wearable->setLabelUpdated(); - wearableUpdated(wearable); - checkWearableAgainstInventory(wearable); - } -} + LLWearableData::wearableUpdated(wearable, removed); -U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable *wearable) -{ - if (wearable == NULL) + if (!removed) { - // no null wearables please! - llwarns << "Null wearable sent for type " << type << llendl; - return MAX_CLOTHING_PER_TYPE; - } -// if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) -// { -// mWearableDatas[type].push_back(wearable); -// wearableUpdated(wearable); -// checkWearableAgainstInventory(wearable); -// return mWearableDatas[type].size()-1; -// } -// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g - if ( (type < LLWearableType::WT_COUNT) && (mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) ) - { - // Don't add the same wearable twice - U32 idxWearable = getWearableIndex(wearable); - RLV_ASSERT(MAX_CLOTHING_PER_TYPE == idxWearable); // pushWearable() on an already added wearable is a bug *somewhere* - if (MAX_CLOTHING_PER_TYPE == idxWearable) + LLViewerWearable* viewer_wearable = dynamic_cast(wearable); + viewer_wearable->refreshName(); + + // Hack pt 2. If the wearable we just loaded has definition version 24, + // then force a re-save of this wearable after slamming the version number to 22. + // This number was incorrectly incremented for internal builds before release, and + // this fix will ensure that the affected wearables are re-saved with the right version number. + // the versions themselves are compatible. This code can be removed before release. + if( wearable->getDefinitionVersion() == 24 ) { - mWearableDatas[type].push_back(wearable); - idxWearable = mWearableDatas[type].size() - 1; + wearable->setDefinitionVersion(22); + U32 index = getWearableIndex(wearable); + llinfos << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << llendl; + saveWearable(wearable->getType(),index,TRUE); } - wearableUpdated(wearable); - checkWearableAgainstInventory(wearable); - return idxWearable; -// [/RLVa:KB] + + //Needed as wearable 'save' process is a mess and fires superfluous updateScrollingPanelList calls + //while the wearable being created has not yet been stuffed into the wearable list. + //This results in the param hints being buggered and screwing up the current wearable during LLVisualParamHint::preRender, + //thus making the wearable 'dirty'. The code below basically 'forces' a refresh of the panel to fix this. + if( LLFloaterCustomize::instanceExists() ) + LLFloaterCustomize::getInstance()->wearablesChanged(wearable->getType()); + + checkWearableAgainstInventory(viewer_wearable); } - return MAX_CLOTHING_PER_TYPE; -} - -void LLAgentWearables::wearableUpdated(LLWearable *wearable) -{ - gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE); - wearable->refreshName(); - wearable->setLabelUpdated(); - - wearable->pullCrossWearableValues(); - - // Hack pt 2. If the wearable we just loaded has definition version 24, - // then force a re-save of this wearable after slamming the version number to 22. - // This number was incorrectly incremented for internal builds before release, and - // this fix will ensure that the affected wearables are re-saved with the right version number. - // the versions themselves are compatible. This code can be removed before release. - if( wearable->getDefinitionVersion() == 24 ) - { - wearable->setDefinitionVersion(22); - U32 index = getWearableIndex(wearable); - llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl; - saveWearable(wearable->getType(),index,TRUE); - } - - //Needed as wearable 'save' process is a mess and fires superfluous updateScrollingPanelList calls - //while the wearable being created has not yet been stuffed into the wearable list. - //This results in the param hints being buggered and screwing up the current wearable during LLVisualParamHint::preRender, - //thus making the wearable 'dirty'. The code below basically 'forces' a refresh of the panel to fix this. - if(gFloaterCustomize) - gFloaterCustomize->wearablesChanged(wearable->getType()); } -void LLAgentWearables::popWearable(LLWearable *wearable) -{ - if (wearable == NULL) - { - // nothing to do here. move along. - return; - } - - U32 index = getWearableIndex(wearable); - LLWearableType::EType type = wearable->getType(); - - if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type)) - { - popWearable(type, index); - } -} - -void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index) -{ - //llassert_always(index == 0); - LLWearable *wearable = getWearable(type, index); - if (wearable) - { - mWearableDatas[type].erase(mWearableDatas[type].begin() + index); - if (isAgentAvatarValid()) - { - gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE); - } - wearable->setLabelUpdated(); - } -} - -U32 LLAgentWearables::getWearableIndex(const LLWearable *wearable) const -{ - if (wearable == NULL) - { - return MAX_CLOTHING_PER_TYPE; - } - - const LLWearableType::EType type = wearable->getType(); - wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); - if (wearable_iter == mWearableDatas.end()) - { - llwarns << "tried to get wearable index with an invalid type!" << llendl; - return MAX_CLOTHING_PER_TYPE; - } - const wearableentry_vec_t& wearable_vec = wearable_iter->second; - for(U32 index = 0; index < wearable_vec.size(); index++) - { - if (wearable_vec[index] == wearable) - { - return index; - } - } - - return MAX_CLOTHING_PER_TYPE; -} - -const LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) const -{ - //llassert_always(index == 0); - wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); - if (wearable_iter == mWearableDatas.end()) - { - return NULL; - } - const wearableentry_vec_t& wearable_vec = wearable_iter->second; - if (index>=wearable_vec.size()) - { - return NULL; - } - else - { - return wearable_vec[index]; - } -} - -LLWearable* LLAgentWearables::getTopWearable(const LLWearableType::EType type) -{ - U32 count = getWearableCount(type); - if ( count == 0) - { - return NULL; - } - - return getWearable(type, count-1); -} - -LLWearable* LLAgentWearables::getBottomWearable(const LLWearableType::EType type) -{ - if (getWearableCount(type) == 0) - { - return NULL; - } - - return getWearable(type, 0); -} - -U32 LLAgentWearables::getWearableCount(const LLWearableType::EType type) const -{ - wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); - if (wearable_iter == mWearableDatas.end()) - { - return 0; - } - const wearableentry_vec_t& wearable_vec = wearable_iter->second; - return wearable_vec.size(); -} - -U32 LLAgentWearables::getWearableCount(const U32 tex_index) const -{ - const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)tex_index); - return getWearableCount(wearable_type); -} BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const @@ -966,7 +789,7 @@ U32 LLAgentWearables::itemUpdatePendingCount() const const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 index) const { - const LLWearable *wearable = getWearable(type,index); + const LLViewerWearable *wearable = getViewerWearable(type,index); if (wearable) return wearable->getItemID(); else @@ -991,7 +814,9 @@ void LLAgentWearables::getWearableItemIDs(LLWearableType::EType eType, uuid_vec_ for (wearableentry_vec_t::const_iterator itWearable = itWearableType->second.begin(), endWearable = itWearableType->second.end(); itWearable != endWearable; ++itWearable) { - idItems.push_back((*itWearable)->getItemID()); + LLViewerWearable* wearable = dynamic_cast(*itWearable); + if(wearable) + idItems.push_back(wearable->getItemID()); } } } @@ -999,7 +824,7 @@ void LLAgentWearables::getWearableItemIDs(LLWearableType::EType eType, uuid_vec_ const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U32 index) const { - const LLWearable *wearable = getWearable(type,index); + const LLViewerWearable *wearable = getViewerWearable(type,index); if (wearable) return wearable->getAssetID(); else @@ -1080,7 +905,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i ); if( asset_id.isNull() ) { - LLWearable::removeFromAvatar( type, FALSE ); + LLViewerWearable::removeFromAvatar( type, FALSE ); } else { @@ -1127,7 +952,7 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type, // Try to recover by replacing missing wearable with a new one. LLNotificationsUtil::add("ReplacedMissingWearable"); lldebugs << "Wearable " << LLWearableType::getTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << llendl; - LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type); + LLViewerWearable* new_wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp); setWearable(type,index,new_wearable); //new_wearable->writeToAvatar( TRUE ); @@ -1162,9 +987,9 @@ void LLAgentWearables::recoverMissingWearableDone() } } -void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index) +void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index) { - LLWearable* wearable = getWearable((LLWearableType::EType)wearable_type, wearable_index); + LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)wearable_type, wearable_index); if (!wearable) { llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl; @@ -1197,7 +1022,7 @@ public: mItemsToLink, link_waiter); } - void addPendingWearable(LLWearable *wearable) + void addPendingWearable(LLViewerWearable *wearable) { if (!wearable) { @@ -1232,7 +1057,7 @@ public: LLWearableType::EType type = item->getWearableType(); if (type < LLWearableType::WT_COUNT) { - LLWearable *wearable = mWearablesAwaitingItems[type]; + LLViewerWearable *wearable = mWearablesAwaitingItems[type]; if (wearable) wearable->setItemID(inv_item); } @@ -1245,7 +1070,7 @@ public: private: LLInventoryModel::item_array_t mItemsToLink; - std::vector mWearablesAwaitingItems; + std::vector mWearablesAwaitingItems; }; void LLAgentWearables::createStandardWearables() @@ -1258,20 +1083,20 @@ void LLAgentWearables::createStandardWearables() { TRUE, //LLWearableType::WT_SHAPE TRUE, //LLWearableType::WT_SKIN - TRUE, //WT_HAIR - TRUE, //WT_EYES - TRUE, //WT_SHIRT - TRUE, //WT_PANTS - TRUE, //WT_SHOES - TRUE, //WT_SOCKS - FALSE, //WT_JACKET - FALSE, //WT_GLOVES - TRUE, //WT_UNDERSHIRT - TRUE, //WT_UNDERPANTS - FALSE, //WT_SKIRT - FALSE, //WT_ALPHA - FALSE, //WT_TATTOO - FALSE, //WT_PHYSICS + TRUE, //LLWearableType::WT_HAIR + TRUE, //LLWearableType::WT_EYES + TRUE, //LLWearableType::WT_SHIRT + TRUE, //LLWearableType::WT_PANTS + TRUE, //LLWearableType::WT_SHOES + TRUE, //LLWearableType::WT_SOCKS + FALSE, //LLWearableType::WT_JACKET + FALSE, //LLWearableType::WT_GLOVES + TRUE, //LLWearableType::WT_UNDERSHIRT + TRUE, //LLWearableType::WT_UNDERPANTS + FALSE, //LLWearableType::WT_SKIRT + FALSE, //LLWearableType::WT_ALPHA + FALSE, //LLWearableType::WT_TATTOO + FALSE //LLWearableType::WT_PHYSICS }; LLPointer cb = new OnWearableItemCreatedCB; @@ -1280,7 +1105,7 @@ void LLAgentWearables::createStandardWearables() if (create[i]) { llassert(getWearableCount((LLWearableType::EType)i) == 0); - LLWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i); + LLViewerWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i, gAgentAvatarp); ((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable); // no need to update here... LLUUID category_id = LLUUID::null; @@ -1339,7 +1164,7 @@ void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index) void LLAgentWearables::addWearableToAgentInventory(LLPointer cb, - LLWearable* wearable, + LLViewerWearable* wearable, const LLUUID& category_id, BOOL notify) { @@ -1377,7 +1202,7 @@ void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_ } else { - LLWearable* old_wearable = getWearable(type,index); + LLViewerWearable* old_wearable = getViewerWearable(type,index); // if (old_wearable) // [RLVa:KB] - Checked: 2010-05-11 (RLVa-1.2.0c) | Modified: RLVa-1.2.0g @@ -1436,10 +1261,10 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_ //llassert_always(index == 0); if (do_remove_all) { - S32 max_entry = mWearableDatas[type].size()-1; + S32 max_entry = getWearableCount(type)-1; for (S32 i=max_entry; i>=0; i--) { - LLWearable* old_wearable = getWearable(type,i); + LLViewerWearable* old_wearable = getViewerWearable(type,i); //queryWearableCache(); // moved below // if (old_wearable) // [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g @@ -1458,7 +1283,7 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_ } else { - LLWearable* old_wearable = getWearable(type, index); + LLViewerWearable* old_wearable = getViewerWearable(type, index); //queryWearableCache(); // moved below // if (old_wearable) @@ -1504,7 +1329,7 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_ // Assumes existing wearables are not dirty. void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items, - const LLDynamicArray< LLWearable* >& wearables, + const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove) { llinfos << "setWearableOutfit() start" << llendl; @@ -1535,7 +1360,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it S32 i; for (i = 0; i < count; i++) { - LLWearable* new_wearable = wearables[i]; + LLViewerWearable* new_wearable = wearables[i]; LLPointer new_item = items[i]; llassert(new_wearable); @@ -1601,8 +1426,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it idxCurPerType[type]++; // [/RLVa:KB] - wearableUpdated(new_wearable); - checkWearableAgainstInventory(new_wearable); + const BOOL removed = FALSE; + wearableUpdated(new_wearable, removed); } } @@ -1645,7 +1470,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // User has picked "wear on avatar" from a menu. -void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append) +void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append) { //LLAgentDumper dumper("setWearableItem"); if (isWearingItem(new_item->getUUID())) @@ -1670,7 +1495,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne { // Remove old wearable, if any // MULTI_WEARABLE: hardwired to 0 - LLWearable* old_wearable = getWearable(type,0); + LLViewerWearable* old_wearable = getViewerWearable(type,0); if( old_wearable ) { const LLUUID& old_item_id = old_wearable->getItemID(); @@ -1696,7 +1521,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne } // static -bool LLAgentWearables::onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable ) +bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); LLInventoryItem* new_item = gInventory.getItem( notification["payload"]["item_id"].asUUID()); @@ -1732,7 +1557,7 @@ bool LLAgentWearables::onSetWearableDialog( const LLSD& notification, const LLSD // Called from setWearableItem() and onSetWearableDialog() to actually set the wearable. // MULTI_WEARABLE: unify code after null objects are gone. -void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append) +void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append) { const LLWearableType::EType type = new_wearable->getType(); @@ -1750,7 +1575,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n // Replace the old wearable with a new one. llassert(new_item->getAssetUUID() == new_wearable->getAssetID()); - LLWearable *old_wearable = getWearable(type,0); + LLViewerWearable *old_wearable = getViewerWearable(type,0); LLUUID old_item_id; if (old_wearable) { @@ -1765,7 +1590,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n gInventory.notifyObservers(); } llinfos << "Replaced current element 0 for type " << type - << " size is now " << mWearableDatas[type].size() << llendl; + << " size is now " << getWearableCount(type) << llendl; } //llinfos << "LLVOAvatar::setWearableItem()" << llendl; @@ -1777,7 +1602,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n void LLAgentWearables::queryWearableCache() { - if (!areWearablesLoaded()) + if (!areWearablesLoaded() || (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())) { return; } @@ -1806,7 +1631,7 @@ void LLAgentWearables::queryWearableCache() num_queries++; // *NOTE: make sure at least one request gets packed - ETextureIndex te_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index); + ETextureIndex te_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index); //llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl; gMessageSystem->nextBlockFast(_PREHASH_WearableData); @@ -1831,46 +1656,14 @@ void LLAgentWearables::queryWearableCache() } } -LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index, - BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache +// virtual +void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const { - LLUUID hash_id; - bool hash_computed = false; - LLMD5 hash; - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index); - - for (U8 i=0; i < baked_dict->mWearables.size(); i++) + // Add some garbage into the hash so that it becomes invalid. + if (isAgentAvatarValid()) { - const LLWearableType::EType baked_type = baked_dict->mWearables[i]; - const U32 num_wearables = getWearableCount(baked_type); - for (U32 index = 0; index < num_wearables; ++index) - { - const LLWearable* wearable = getWearable(baked_type,index); - if (wearable) - { - LLUUID asset_id = wearable->getAssetID(); - hash.update((const unsigned char*)asset_id.mData, UUID_BYTES); - hash_computed = true; - } - } + hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES); } - if (hash_computed) - { - hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES); - - // Add some garbage into the hash so that it becomes invalid. - if (!generate_valid_hash) - { - if (isAgentAvatarValid()) - { - hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES); - } - } - hash.finalize(); - hash.raw_digest(hash_id.mData); - } - - return hash_id; } // User has picked "remove from avatar" from a menu. @@ -2027,31 +1820,6 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo gMessageSystem->sendReliable(gAgent.getRegionHost()); } -void LLAgentWearables::userRemoveAllAttachments() -{ - if (!isAgentAvatarValid()) return; - - llvo_vec_t objects_to_remove; - - for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); - iter != gAgentAvatarp->mAttachmentPoints.end();) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - LLViewerObject *attached_object = (*attachment_iter); - if (attached_object) - { - objects_to_remove.push_back(attached_object); - } - } - } - userRemoveMultipleAttachments(objects_to_remove); -} - void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array) { // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1b) | Added: RLVa-1.3.1b @@ -2146,7 +1914,7 @@ void LLAgentWearables::checkWearablesLoaded() const // Returns false if the given wearable is already topmost/bottommost // (depending on closer_to_body parameter). -bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body) +bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body) const { const LLWearable* wearable = getWearableFromItemID(item_id); if (!wearable) return false; @@ -2174,7 +1942,7 @@ void LLAgentWearables::updateWearablesLoaded() } } -bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const +bool LLAgentWearables::canWearableBeRemoved(const LLViewerWearable* wearable) const { if (!wearable) return false; @@ -2189,7 +1957,7 @@ void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake) { for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count) { - LLWearable *wearable = getWearable((LLWearableType::EType)type,count); + LLViewerWearable *wearable = getViewerWearable((LLWearableType::EType)type,count); llassert(wearable); if (wearable) { @@ -2204,32 +1972,43 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos if (!item) return false; if (!item->isWearableType()) return false; - wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(item->getWearableType()); - if (wearable_iter == mWearableDatas.end()) return false; - - wearableentry_vec_t& wearable_vec = wearable_iter->second; - if (wearable_vec.empty()) return false; + LLWearableType::EType type = item->getWearableType(); + U32 wearable_count = getWearableCount(type); + if (0 == wearable_count) return false; const LLUUID& asset_id = item->getAssetUUID(); //nowhere to move if the wearable is already on any boundary (closest to the body/furthest from the body) - if (closer_to_body && asset_id == wearable_vec.front()->getAssetID()) return false; - if (!closer_to_body && asset_id == wearable_vec.back()->getAssetID()) return false; - - for (U32 i = 0; i < wearable_vec.size(); ++i) + if (closer_to_body) { - LLWearable* wearable = wearable_vec[i]; + LLViewerWearable* bottom_wearable = dynamic_cast( getBottomWearable(type) ); + if (bottom_wearable->getAssetID() == asset_id) + { + return false; + } + } + else // !closer_to_body + { + LLViewerWearable* top_wearable = dynamic_cast( getTopWearable(type) ); + if (top_wearable->getAssetID() == asset_id) + { + return false; + } + } + + for (U32 i = 0; i < wearable_count; ++i) + { + LLViewerWearable* wearable = getViewerWearable(type, i); if (!wearable) continue; if (wearable->getAssetID() != asset_id) continue; //swapping wearables U32 swap_i = closer_to_body ? i-1 : i+1; - wearable_vec[i] = wearable_vec[swap_i]; - wearable_vec[swap_i] = wearable; + swapWearables(type, i, swap_i); - if(gFloaterCustomize) + if( LLFloaterCustomize::instanceExists() ) { - gFloaterCustomize->wearablesChanged(item->getWearableType()); + LLFloaterCustomize::getInstance()->wearablesChanged(item->getWearableType()); } return true; @@ -2243,10 +2022,10 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con { if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return; - LLWearable* wearable = LLWearableList::instance().createNewWearable(type); + LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp); LLAssetType::EType asset_type = wearable->getAssetType(); LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; - LLPointer cb = wear ? new LLWearAndEditCallback : NULL; + LLPointer cb = wear ? new LLBoostFuncInventoryCallback(wear_and_edit_cb) : NULL; LLUUID folder_id; if (parent_id.notNull()) @@ -2276,7 +2055,7 @@ void LLAgentWearables::editWearable(const LLUUID& item_id) return; } - LLWearable* wearable = gAgentWearables.getWearableFromItemID(item_id); + LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id); if (!wearable) { llwarns << "Cannot get wearable" << llendl; @@ -2289,16 +2068,10 @@ void LLAgentWearables::editWearable(const LLUUID& item_id) return; } - //const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(wearable->getType()); + const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(wearable->getType()); // Set the tab to the right wearable. - LLFloaterCustomize::setCurrentWearableType( wearable->getType() ); - - if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() ) - { - // Start Avatar Customization - gAgentCamera.changeCameraToCustomizeAvatar(); - } + LLFloaterCustomize::editWearable( wearable, disable_camera_switch ); } // Request editing the item after it gets worn. diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index c3aad9500..b6738604d 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -36,16 +36,16 @@ // newview #include "llinventorymodel.h" #include "llviewerinventory.h" -#include "llvoavatardefines.h" +#include "llavatarappearancedefines.h" +#include "llwearabledata.h" class LLInventoryItem; class LLVOAvatarSelf; -class LLWearable; +class LLViewerWearable; class LLInitialWearablesFetch; class LLViewerObject; -class LLTexLayerTemplate; -class LLAgentWearables : public LLInitClass +class LLAgentWearables : public LLInitClass, public LLWearableData { //-------------------------------------------------------------------- // Constructors / destructors / Initializers @@ -82,10 +82,10 @@ public: bool isCOFChangeInProgress() const { return mCOFChangeInProgress; } void updateWearablesLoaded(); void checkWearablesLoaded() const; - bool canMoveWearable(const LLUUID& item_id, bool closer_to_body); + bool canMoveWearable(const LLUUID& item_id, bool closer_to_body) const; // Note: False for shape, skin, eyes, and hair, unless you have MORE than 1. - bool canWearableBeRemoved(const LLWearable* wearable) const; + bool canWearableBeRemoved(const LLViewerWearable* wearable) const; void animateAllWearableParams(F32 delta, BOOL upload_bake); @@ -99,52 +99,38 @@ public: // [/RLVa:KB] const LLUUID getWearableItemID(LLWearableType::EType type, U32 index /*= 0*/) const; const LLUUID getWearableAssetID(LLWearableType::EType type, U32 index /*= 0*/) const; - const LLWearable* getWearableFromItemID(const LLUUID& item_id) const; - LLWearable* getWearableFromItemID(const LLUUID& item_id); - LLWearable* getWearableFromAssetID(const LLUUID& asset_id); + const LLViewerWearable* getWearableFromItemID(const LLUUID& item_id) const; + LLViewerWearable* getWearableFromItemID(const LLUUID& item_id); + LLViewerWearable* getWearableFromAssetID(const LLUUID& asset_id); + LLViewerWearable* getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/); + const LLViewerWearable* getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const; LLInventoryItem* getWearableInventoryItem(LLWearableType::EType type, U32 index /*= 0*/); static BOOL selfHasWearable(LLWearableType::EType type); - LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/); - const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const; - LLWearable* getTopWearable(const LLWearableType::EType type); - LLWearable* getBottomWearable(const LLWearableType::EType type); - U32 getWearableCount(const LLWearableType::EType type) const; - U32 getWearableCount(const U32 tex_index) const; - - static const U32 MAX_CLOTHING_PER_TYPE = 5; - //-------------------------------------------------------------------- // Setters //-------------------------------------------------------------------- - private: - // Low-level data structure setter - public access is via setWearableItem, etc. - void setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable); - U32 pushWearable(const LLWearableType::EType type, LLWearable *wearable); - void wearableUpdated(LLWearable *wearable); - void popWearable(LLWearable *wearable); - void popWearable(const LLWearableType::EType type, U32 index); - + /*virtual*/void wearableUpdated(LLWearable *wearable, BOOL removed); public: - void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false); - void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove); + void setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false); + void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove); void setWearableName(const LLUUID& item_id, const std::string& new_name); - void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index); - U32 getWearableIndex(const LLWearable *wearable) const; + // *TODO: Move this into llappearance/LLWearableData ? + void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index); protected: - void setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false); - static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable); + void setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append = false); + static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable); void addWearableToAgentInventory(LLPointer cb, - LLWearable* wearable, + LLViewerWearable* wearable, const LLUUID& category_id = LLUUID::null, BOOL notify = TRUE); void addWearabletoAgentInventoryDone(const LLWearableType::EType type, const U32 index, const LLUUID& item_id, - LLWearable* wearable); + LLViewerWearable* wearable); void recoverMissingWearable(const LLWearableType::EType type, U32 index /*= 0*/); void recoverMissingWearableDone(); @@ -179,15 +165,15 @@ protected: public: // Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant) static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data); - LLUUID computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index, - BOOL generate_valid_hash = TRUE); protected: + + /*virtual*/ void invalidateBakedTextureHash(LLMD5& hash) const; void sendAgentWearablesUpdate(); void sendAgentWearablesRequest(); void queryWearableCache(); void updateServer(); - static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata); + static void onInitialWearableAssetArrived(LLViewerWearable* wearable, void* userdata); //-------------------------------------------------------------------- // Outfits @@ -205,7 +191,7 @@ private: // Save Wearables //-------------------------------------------------------------------- public: - LLWearable* saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found); + LLViewerWearable* saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found); void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE, const std::string new_name = ""); void saveAllWearables(); @@ -226,7 +212,6 @@ public: static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly = false); // [/SL:KB] static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array); - static void userRemoveAllAttachments(); static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array); BOOL itemUpdatePending(const LLUUID& item_id) const; @@ -262,10 +247,6 @@ private: // Member variables //-------------------------------------------------------------------- private: - typedef std::vector wearableentry_vec_t; // all wearables of a certain type (EG all shirts) - typedef std::map wearableentry_map_t; // wearable "categories" arranged by wearable type - wearableentry_map_t mWearableDatas; - static BOOL mInitialWearablesUpdateReceived; // [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-3.0.0a) | Added: Catznip-2.2.0a static bool mInitialWearablesLoaded; @@ -309,13 +290,13 @@ private: addWearableToAgentInventoryCallback(LLPointer cb, LLWearableType::EType type, U32 index, - LLWearable* wearable, + LLViewerWearable* wearable, U32 todo = CALL_NONE); virtual void fire(const LLUUID& inv_item); private: LLWearableType::EType mType; U32 mIndex; - LLWearable* mWearable; + LLViewerWearable* mWearable; U32 mTodo; LLPointer mCB; }; diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index ec645e9a1..40b311a95 100644 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -40,13 +40,9 @@ #include "rlvhelper.h" // [/RLVa:KB] -class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback -{ -public: - LLOrderMyOutfitsOnDestroy() {}; - virtual ~LLOrderMyOutfitsOnDestroy() - { +void order_my_outfits_cb() +{ if (!LLApp::isRunning()) { llwarns << "called during shutdown, skipping" << llendl; @@ -79,15 +75,11 @@ public: // saved initial outfit already contains wearables ordering information if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue; - LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id); - } - - llinfos << "Finished updating My Outfits with wearables ordering information" << llendl; + LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id); } - /* virtual */ void fire(const LLUUID& inv_item) {}; -}; - + llinfos << "Finished updating My Outfits with wearables ordering information" << llendl; +} LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) : LLInventoryFetchDescendentsObserver(cof_id) @@ -634,7 +626,7 @@ void LLLibraryOutfitsFetch::contentsDone() LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t wearable_array; - LLPointer order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy; + LLPointer order_myoutfits_on_destroy = new LLBoostFuncInventoryCallback(no_op_inventory_func, order_my_outfits_cb); for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin(); folder_iter != mImportedClothingFolders.end(); diff --git a/indra/newview/llappearance.h b/indra/newview/llappearance.h index 901815014..05dfac4e4 100644 --- a/indra/newview/llappearance.h +++ b/indra/newview/llappearance.h @@ -2,31 +2,25 @@ * @file llappearance.h * @brief LLAppearance class definition * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,14 +38,14 @@ public: void addParam( S32 id, F32 value ) { mParamMap[id] = value; } F32 getParam( S32 id, F32 defval ) { return get_if_there(mParamMap, id, defval ); } - void addTexture( S32 te, const LLUUID& uuid ) { if( te < LLVOAvatarDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; } - const LLUUID& getTexture( S32 te ) { return ( te < LLVOAvatarDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; } + void addTexture( S32 te, const LLUUID& uuid ) { if( te < LLAvatarAppearanceDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; } + const LLUUID& getTexture( S32 te ) { return ( te < LLAvatarAppearanceDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; } - void clear() { mParamMap.clear(); for( S32 i=0; i param_map_t; param_map_t mParamMap; - LLUUID mTextures[LLVOAvatarDefines::TEX_NUM_INDICES]; + LLUUID mTextures[LLAvatarAppearanceDefines::TEX_NUM_INDICES]; }; #endif // LL_LLAPPEARANCE_H diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 4cab987ae..5947ff919 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -46,8 +46,10 @@ #include "llvoavatar.h" #include "llvoavatarself.h" #include "llviewerregion.h" +#include "llviewerstats.h" #include "llwearablelist.h" #include "llinventorypanel.h" +#include "llfloatercustomize.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvhandler.h" #include "rlvhelper.h" @@ -56,7 +58,10 @@ std::string self_av_string() { - return gAgentAvatarp->avString(); + if(isAgentAvatarValid()) + return gAgentAvatarp->avString(); + else + return std::string(); } // RAII thingy to guarantee that a variable gets reset when the Setter @@ -158,81 +163,343 @@ LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string } } -class LLWearInventoryCategoryCallback : public LLInventoryCallback +class LLCallAfterInventoryBatchMgr: public LLEventTimer { public: - LLWearInventoryCategoryCallback(const LLUUID& cat_id, bool append) + LLCallAfterInventoryBatchMgr(const LLUUID& dst_cat_id, + const std::string& phase_name, + nullary_func_t on_completion_func, + nullary_func_t on_failure_func = no_op, + F32 retry_after = 15.0, + S32 max_retries = 2 + ): + mDstCatID(dst_cat_id), + mTrackingPhase(phase_name), + mOnCompletionFunc(on_completion_func), + mOnFailureFunc(on_failure_func), + mRetryAfter(retry_after), + mMaxRetries(max_retries), + mPendingRequests(0), + mFailCount(0), + mCompletionOrFailureCalled(false), + mRetryCount(0), + LLEventTimer(retry_after) { - mCatID = cat_id; - mAppend = append; - - LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; - } - void fire(const LLUUID& item_id) - { - /* - * Do nothing. We only care about the destructor - * - * The reason for this is that this callback is used in a hack where the - * same callback is given to dozens of items, and the destructor is called - * after the last item has fired the event and dereferenced it -- if all - * the events actually fire! - */ - LL_DEBUGS("Avatar") << self_av_string() << " fired on copied item, id " << item_id << LL_ENDL; - } - -protected: - ~LLWearInventoryCategoryCallback() - { - LL_INFOS("Avatar") << self_av_string() << "done all inventory callbacks" << LL_ENDL; - - // Is the destructor called by ordinary dereference, or because the app's shutting down? - // If the inventory callback manager goes away, we're shutting down, no longer want the callback. - if( LLInventoryCallbackManager::is_instantiated() ) + if (!mTrackingPhase.empty()) { - LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend); + //selfStartPhase(mTrackingPhase); + } + } + + void addItems(LLInventoryModel::item_array_t& src_items) + { + for (LLInventoryModel::item_array_t::const_iterator it = src_items.begin(); + it != src_items.end(); + ++it) + { + LLViewerInventoryItem* item = *it; + llassert(item); + addItem(item->getUUID()); + } + } + + // Request or re-request operation for specified item. + void addItem(const LLUUID& item_id) + { + LLUUID linked_id; + if (gInventory.getItem(item_id)) + { + linked_id = gInventory.getItem(item_id)->getLinkedUUID(); + } + else if (gInventory.getCategory(item_id)) + { + linked_id = item_id; } else { - llwarns << self_av_string() << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl; + llwarns << "no referent found for item_id " << item_id << llendl; + return; + } + LL_DEBUGS("Avatar") << "item_id " << item_id << " -> linked_id " << linked_id << llendl; + + if (ll_frand()::iterator it = mWaitTimes.begin(); + it != mWaitTimes.end();) + { + // Use a copy of iterator because it may be erased/invalidated. + std::map::iterator curr_it = it; + ++it; + + F32 time_waited = curr_it->second.getElapsedTimeF32(); + S32 retries = mRetryCounts[curr_it->first]; + if (time_waited > mRetryAfter) + { + if (retries < mMaxRetries) + { + LL_DEBUGS("Avatar") << "Waited " << time_waited << + " for " << curr_it->first << ", retrying" << llendl; + mRetryCount++; + addItem(curr_it->first); + } + else + { + llwarns << "Giving up on " << curr_it->first << " after too many retries" << llendl; + mWaitTimes.erase(curr_it); + mFailCount++; + } + } + if (mWaitTimes.empty()) + { + onCompletionOrFailure(); + } + + } + } + return all_done; + } + + void reportStats() + { + LL_DEBUGS("Avatar") << "Phase: " << mTrackingPhase << llendl; + LL_DEBUGS("Avatar") << "mFailCount: " << mFailCount << llendl; + LL_DEBUGS("Avatar") << "mRetryCount: " << mRetryCount << llendl; + LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << llendl; + LL_DEBUGS("Avatar") << "Mean " << mTimeStats.getMean() << " stddev " << mTimeStats.getStdDev() << llendl; + } + + virtual ~LLCallAfterInventoryBatchMgr() + { + LL_DEBUGS("Avatar") << "deleting" << llendl; + } + +protected: + std::string mTrackingPhase; + std::map mWaitTimes; + std::map mRetryCounts; + LLUUID mDstCatID; + nullary_func_t mOnCompletionFunc; + nullary_func_t mOnFailureFunc; + F32 mRetryAfter; + S32 mMaxRetries; + S32 mPendingRequests; + S32 mFailCount; + S32 mRetryCount; + bool mCompletionOrFailureCalled; + LLViewerStats::StatsAccumulator mTimeStats; }; - -//Inventory callback updating "dirty" state when destroyed -class LLUpdateDirtyState: public LLInventoryCallback +class LLCallAfterInventoryCopyMgr: public LLCallAfterInventoryBatchMgr { public: - LLUpdateDirtyState() {} - virtual ~LLUpdateDirtyState() + LLCallAfterInventoryCopyMgr(LLInventoryModel::item_array_t& src_items, + const LLUUID& dst_cat_id, + const std::string& phase_name, + nullary_func_t on_completion_func, + nullary_func_t on_failure_func = no_op, + F32 retry_after = 15.0, + S32 max_retries = 2 + ): + LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries) { - if (LLAppearanceMgr::instanceExists()) - { - LLAppearanceMgr::getInstance()->updateIsDirty(); - } + addItems(src_items); + } + + virtual bool requestOperation(const LLUUID& item_id) + { + LLViewerInventoryItem *item = gInventory.getItem(item_id); + llassert(item); + LL_DEBUGS("Avatar") << "copying item " << item_id << llendl; + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + mDstCatID, + std::string(), + new LLBoostFuncInventoryCallback(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer())) + ); + return true; } - virtual void fire(const LLUUID&) {} }; +class LLCallAfterInventoryLinkMgr: public LLCallAfterInventoryBatchMgr +{ +public: + LLCallAfterInventoryLinkMgr(LLInventoryModel::item_array_t& src_items, + const LLUUID& dst_cat_id, + const std::string& phase_name, + nullary_func_t on_completion_func, + nullary_func_t on_failure_func = no_op, + F32 retry_after = 15.0, + S32 max_retries = 2 + ): + LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries) + { + addItems(src_items); + } + + virtual bool requestOperation(const LLUUID& item_id) + { + bool request_sent = false; + LLViewerInventoryItem *item = gInventory.getItem(item_id); + if (item) + { + LL_DEBUGS("Avatar") << "linking item " << item_id << " name " << item->getName() << " to " << mDstCatID << llendl; + // create an inventory item link. + link_inventory_item(gAgent.getID(), + item_id, + mDstCatID, + item->getName(), + item->LLInventoryItem::getDescription(), + LLAssetType::AT_LINK, + new LLBoostFuncInventoryCallback( + boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer()))); + request_sent = true; + } + else + { + // create a base outfit link if appropriate. + LLViewerInventoryCategory *catp = gInventory.getCategory(item_id); + if (!catp) + { + llwarns << "id not found as inventory item or category " << item_id << llendl; + return false; + } + const LLUUID cof = LLAppearanceMgr::instance().getCOF(); + std::string new_outfit_name = ""; + + LLAppearanceMgr::instance().purgeBaseOutfitLink(cof); + + if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT) + { + LL_DEBUGS("Avatar") << "linking folder " << item_id << " name " << catp->getName() << " to cof " << cof << llendl; + link_inventory_item(gAgent.getID(), item_id, cof, catp->getName(), "", + LLAssetType::AT_LINK_FOLDER, + new LLBoostFuncInventoryCallback( + boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer()))); + new_outfit_name = catp->getName(); + request_sent = true; + } + + LLAppearanceMgr::instance().updatePanelOutfitName(new_outfit_name); + } + return request_sent; + } +}; LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering): mFireCount(0), mUpdateBaseOrder(update_base_outfit_ordering) { + //selfStartPhase("update_appearance_on_destroy"); } LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy() { - LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL; - llinfos << "done update appearance on destroy" << llendl; - if (!LLApp::isExiting()) { + // speculative fix for MAINT-1150 + LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL; + + //selfStopPhase("update_appearance_on_destroy"); + LLAppearanceMgr::instance().updateAppearanceFromCOF(mUpdateBaseOrder); } } @@ -274,7 +541,7 @@ struct LLFoundData std::string mName; LLAssetType::EType mAssetType; LLWearableType::EType mWearableType; - LLWearable* mWearable; + LLViewerWearable* mWearable; bool mIsReplacement; }; @@ -298,7 +565,7 @@ public: void recoverMissingWearable(LLWearableType::EType type); void clearCOFLinksForMissingWearables(); - void onWearableAssetFetch(LLWearable *wearable); + void onWearableAssetFetch(LLViewerWearable *wearable); void onAllComplete(); // [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-3.0.0a) | Added: Catznip-2.0.0a @@ -328,7 +595,7 @@ private: typedef std::set type_set_hp; static type_set_hp sActiveHoldingPatterns; bool mIsMostRecent; - std::set mLateArrivals; + std::set mLateArrivals; bool mIsAllComplete; }; @@ -356,11 +623,16 @@ LLWearableHoldingPattern::LLWearableHoldingPattern(): } sActiveHoldingPatterns.insert(this); + //selfStartPhase("holding_pattern"); } LLWearableHoldingPattern::~LLWearableHoldingPattern() { sActiveHoldingPatterns.erase(this); + if (isMostRecent()) + { + //selfStopPhase("holding_pattern"); + } } bool LLWearableHoldingPattern::isMostRecent() @@ -449,6 +721,8 @@ void LLWearableHoldingPattern::checkMissingWearables() } resetTime(60.0F); + + //selfStartPhase("get_missing_wearables"); if (!pollMissingWearables()) { doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this)); @@ -513,6 +787,8 @@ void LLWearableHoldingPattern::onAllComplete() void LLWearableHoldingPattern::onFetchCompletion() { + //selfStopPhase("get_wearables"); + if (!isMostRecent()) { // runway skip here? @@ -558,104 +834,77 @@ bool LLWearableHoldingPattern::pollFetchCompletion() return done; } -class RecoveredItemLinkCB: public LLInventoryCallback +void recovered_item_link_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder) { -public: - RecoveredItemLinkCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder): - mHolder(holder), - mWearable(wearable), - mType(type) + if (!holder->isMostRecent()) { + llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? } - void fire(const LLUUID& item_id) + + llinfos << "Recovered item link for type " << type << llendl; + holder->eraseTypeToLink(type); + // Add wearable to FoundData for actual wearing + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; + + if (linked_item) { - if (!mHolder->isMostRecent()) - { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; - } - - llinfos << "Recovered item link for type " << mType << llendl; - mHolder->eraseTypeToLink(mType); - // Add wearable to FoundData for actual wearing - LLViewerInventoryItem *item = gInventory.getItem(item_id); - LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; - - if (linked_item) - { - gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); + gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); - if (item) - { - LLFoundData found(linked_item->getUUID(), - linked_item->getAssetUUID(), - linked_item->getName(), - linked_item->getType(), - linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID, - true // is replacement - ); - found.mWearable = mWearable; - mHolder->getFoundList().push_front(found); - } - else - { - llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl; - } + if (item) + { + LLFoundData found(linked_item->getUUID(), + linked_item->getAssetUUID(), + linked_item->getName(), + linked_item->getType(), + linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID, + true // is replacement + ); + found.mWearable = wearable; + holder->getFoundList().push_front(found); } else { - llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl; + llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl; } } -private: - LLWearableHoldingPattern* mHolder; - LLWearable *mWearable; - LLWearableType::EType mType; -}; - -class RecoveredItemCB: public LLInventoryCallback -{ -public: - RecoveredItemCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder): - mHolder(holder), - mWearable(wearable), - mType(type) + else { + llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl; } - void fire(const LLUUID& item_id) +} + +void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder) +{ + if (!holder->isMostRecent()) { - if (!mHolder->isMostRecent()) - { - // runway skip here? - llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; // [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-3.0.0a) | Added: Catznip-2.0.0a - // If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves - return; + // If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves + return; // [/SL:KB] - } - - LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << mType << LL_ENDL; - LLViewerInventoryItem *itemp = gInventory.getItem(item_id); - mWearable->setItemID(item_id); - LLPointer cb = new RecoveredItemLinkCB(mType,mWearable,mHolder); - mHolder->eraseTypeToRecover(mType); - llassert(itemp); - if (itemp) - { - link_inventory_item( gAgent.getID(), - item_id, - LLAppearanceMgr::instance().getCOF(), - itemp->getName(), - itemp->getDescription(), - LLAssetType::AT_LINK, - cb); - } } -private: - LLWearableHoldingPattern* mHolder; - LLWearable *mWearable; - LLWearableType::EType mType; -}; + + LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL; + LLViewerInventoryItem *itemp = gInventory.getItem(item_id); + wearable->setItemID(item_id); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder)); + holder->eraseTypeToRecover(type); + llassert(itemp); + if (itemp) + { + link_inventory_item( gAgent.getID(), + item_id, + LLAppearanceMgr::instance().getCOF(), + itemp->getName(), + itemp->getDescription(), + LLAssetType::AT_LINK, + cb); + } +} void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type) { @@ -669,11 +918,11 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type LLNotificationsUtil::add("ReplacedMissingWearable"); lldebugs << "Wearable " << LLWearableType::getTypeLabel(type) << " could not be downloaded. Replaced inventory item with default wearable." << llendl; - LLWearable* wearable = LLWearableList::instance().createNewWearable(type); + LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp); // Add a new one in the lost and found folder. const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); - LLPointer cb = new RecoveredItemCB(type,wearable,this); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this)); create_inventory_item(gAgent.getID(), gAgent.getSessionID(), @@ -702,7 +951,7 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables() { // Wearable link that was never resolved; remove links to it from COF LL_INFOS("Avatar") << self_av_string() << "removing link for unresolved item " << data.mItemID.asString() << LL_ENDL; - LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false); + LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID); } } } @@ -749,6 +998,8 @@ bool LLWearableHoldingPattern::pollMissingWearables() if (done) { + //selfStopPhase("get_missing_wearables"); + gAgentAvatarp->debugWearablesLoaded(); // BAP - if we don't call clearCOFLinksForMissingWearables() @@ -793,11 +1044,11 @@ void LLWearableHoldingPattern::handleLateArrivals() iter != getFoundList().end(); ++iter) { LLFoundData& data = *iter; - for (std::set::iterator wear_it = mLateArrivals.begin(); + for (std::set::iterator wear_it = mLateArrivals.begin(); wear_it != mLateArrivals.end(); ++wear_it) { - LLWearable *wearable = *wear_it; + LLViewerWearable *wearable = *wear_it; if(wearable->getAssetID() == data.mAssetID) { @@ -833,7 +1084,7 @@ void LLWearableHoldingPattern::handleLateArrivals() if (data.mWearable && data.mIsReplacement && replaced_types.find(data.mWearableType) != replaced_types.end()) { - LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false); + LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID); std::list::iterator clobber_ator = iter; ++iter; getFoundList().erase(clobber_ator); @@ -857,7 +1108,7 @@ void LLWearableHoldingPattern::resetTime(F32 timeout) mWaitTime.setTimerExpirySec(timeout); } -void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) +void LLWearableHoldingPattern::onWearableAssetFetch(LLViewerWearable *wearable) { if (!isMostRecent()) { @@ -908,7 +1159,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) } } -static void onWearableAssetFetch(LLWearable* wearable, void* data) +static void onWearableAssetFetch(LLViewerWearable* wearable, void* data) { LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; holder->onWearableAssetFetch(wearable); @@ -964,6 +1215,18 @@ const LLUUID LLAppearanceMgr::getCOF() const return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); } +S32 LLAppearanceMgr::getCOFVersion() const +{ + LLViewerInventoryCategory *cof = gInventory.getCategory(getCOF()); + if (cof) + { + return cof->getVersion(); + } + else + { + return LLViewerInventoryCategory::VERSION_UNKNOWN; + } +} const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink() { @@ -1032,6 +1295,18 @@ const LLUUID LLAppearanceMgr::getBaseOutfitUUID() return outfit_cat->getUUID(); } +void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace/*= false*/) +{ + if (inv_item.isNull()) + return; + + LLViewerInventoryItem *item = gInventory.getItem(inv_item); + if (item) + { + LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, do_replace); + } +} + bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_update, bool replace, LLPointer cb) { if (item_id_to_wear.isNull()) return false; @@ -1051,8 +1326,8 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID())) { - LLPointer cb = new WearOnAvatarCallback(replace); - copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&wear_on_avatar_cb,_1,replace)); + copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb); return false; } else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID())) @@ -1105,7 +1380,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up if ((replace && wearable_count != 0) || (wearable_count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) ) { - removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false); + removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1)); } addCOFItemLink(item_to_wear, do_update, cb); } @@ -1115,7 +1390,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up // Remove the existing wearables of the same type. // Remove existing body parts anyway because we must not be able to wear e.g. two skins. - removeCOFLinksOfType(item_to_wear->getWearableType(), false); + removeCOFLinksOfType(item_to_wear->getWearableType()); addCOFItemLink(item_to_wear, do_update, cb); break; @@ -1213,11 +1488,13 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id) LLInventoryModel::item_array_t::const_iterator it = items.begin(); const LLInventoryModel::item_array_t::const_iterator it_end = items.end(); + uuid_vec_t uuids_to_remove; for( ; it_end != it; ++it) { LLViewerInventoryItem* item = *it; - removeItemFromAvatar(item->getUUID()); + uuids_to_remove.push_back(item->getUUID()); } + removeItemsFromAvatar(uuids_to_remove); } // Create a copy of src_id + contents as a subfolder of dst_id. @@ -1485,7 +1762,7 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin } // [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f -void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLPointer cb) +void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLCallAfterInventoryLinkMgr* link_waiter) { const LLUUID idCOF = getCOF(); LLInventoryModel::item_array_t cur_cof_items, new_cof_items = items; @@ -1516,9 +1793,7 @@ void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, LLAss // Link to whatever remains in new_cof_items for (S32 idxNewItem = 0, cntNewItem = new_cof_items.count(); idxNewItem < cntNewItem; idxNewItem++) { - const LLInventoryItem* pItem = new_cof_items.get(idxNewItem); - link_inventory_item( - gAgent.getID(), pItem->getLinkedUUID(), idCOF, pItem->getName(), pItem->LLInventoryItem::getDescription(), LLAssetType::AT_LINK, cb); + link_waiter->addItem(new_cof_items.get(idxNewItem)->getLinkedUUID()); } } // [/SL:KB] @@ -1591,7 +1866,7 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t& wear_items_new, LLInventoryModel::item_array_t& obj_items_new, LLInventoryModel::item_array_t& gest_items_new, - bool append /*=false*/, const LLUUID& idOutfit /*=LLUUID::null*/) + bool append /*=false*/, const LLUUID& category /*=LLUUID::null*/) // [/RLVa:KB] { // LLViewerInventoryCategory *pcat = gInventory.getCategory(category); @@ -1700,37 +1975,37 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, // [/RLVa:KB] removeDuplicateItems(gest_items); +#ifndef LL_RELEASE_FOR_DOWNLOAD + LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL; +#endif + // Create links to new COF contents. - LL_DEBUGS("Avatar") << self_av_string() << "creating LLUpdateAppearanceOnDestroy" << LL_ENDL; - LLPointer link_waiter = new LLUpdateAppearanceOnDestroy(!append); + LL_DEBUGS("Avatar") << self_av_string() << "creating LLCallAfterInventoryLinkMgr" << LL_ENDL; + bool update_base_outfit_ordering = !append; + LLCallAfterInventoryLinkMgr *link_waiter = + new LLCallAfterInventoryLinkMgr(body_items,cof,"update_appearance_on_destroy", + boost::bind(&LLAppearanceMgr::updateAppearanceFromCOF, + LLAppearanceMgr::getInstance(), + update_base_outfit_ordering)); // [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f if (!append) { // [/SL:KB] - // Remove current COF contents. - bool keep_outfit_links = append; - purgeCategory(cof, keep_outfit_links); - gInventory.notifyObservers(); -#ifndef LL_RELEASE_FOR_DOWNLOAD - LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL; -#endif - linkAll(cof, body_items, link_waiter); - #ifndef LL_RELEASE_FOR_DOWNLOAD LL_DEBUGS("Avatar") << self_av_string() << "Linking wear items" << LL_ENDL; #endif - linkAll(cof, wear_items, link_waiter); + link_waiter->addItems(wear_items); #ifndef LL_RELEASE_FOR_DOWNLOAD LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL; #endif - linkAll(cof, obj_items, link_waiter); + link_waiter->addItems(obj_items); #ifndef LL_RELEASE_FOR_DOWNLOAD LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL; #endif - linkAll(cof, gest_items, link_waiter); + link_waiter->addItems(gest_items); // [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f } else @@ -1741,21 +2016,25 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, syncCOF(wear_items, LLAssetType::AT_CLOTHING, link_waiter); syncCOF(obj_items, LLAssetType::AT_OBJECT, link_waiter); syncCOF(gest_items, LLAssetType::AT_GESTURE, link_waiter); - gInventory.notifyObservers(); } // [/SL:KB] // Add link to outfit if category is an outfit. -// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0z) | Added: RLVa-1.2.0b - if ( (!append) && (idOutfit.notNull()) ) - { - createBaseOutfitLink(idOutfit, link_waiter); - } +// [RLVa:KB] - Checked: Never | Added: RLVa-1.2.0b + if (!append && category.notNull()) // [/RLVa:KB] // if (!append) -// { -// createBaseOutfitLink(category, link_waiter); -// } + { + link_waiter->addItem(category); + } + + // Remove current COF contents. Have to do this after creating + // the link_waiter so links can be followed for any items that get + // carried over (e.g. keeping old shape if the new outfit does not + // contain one) + bool keep_outfit_links = append; + purgeCategory(cof, keep_outfit_links); + gInventory.notifyObservers(); LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL; } @@ -1793,7 +2072,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo { lldebugs << "updateAgentWearables()" << llendl; LLInventoryItem::item_array_t items; - LLDynamicArray< LLWearable* > wearables; + LLDynamicArray< LLViewerWearable* > wearables; // [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f uuid_vec_t idsCurrent; LLInventoryModel::item_array_t itemsNew; if (rlv_handler_t::isEnabled()) @@ -1810,7 +2089,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo iter != holder->getFoundList().end(); ++iter) { LLFoundData& data = *iter; - LLWearable* wearable = data.mWearable; + LLViewerWearable* wearable = data.mWearable; if( wearable && ((S32)wearable->getType() == i) ) { LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID); @@ -1859,7 +2138,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo // We need to report removals before additions or scripts will get confused for (uuid_vec_t::const_iterator itItemID = idsCurrent.begin(); itItemID != idsCurrent.end(); ++itItemID) { - const LLWearable* pWearable = gAgentWearables.getWearableFromItemID(*itItemID); + const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(*itItemID); if (pWearable) RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true); } @@ -2001,6 +2280,15 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) // the saved outfit stored as a folder link updateIsDirty(); + // Send server request for appearance update + if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()) + { + requestServerAppearanceUpdate(); + } + // DRANO really should wait for the appearance message to set this. + // verify that deleting this line doesn't break anything. + gAgentAvatarp->setIsUsingServerBakes(gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()); + //dumpCat(getCOF(),"COF, start"); bool follow_folder_links = true; @@ -2136,6 +2424,8 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) } } + //selfStartPhase("get_wearables"); + for (LLWearableHoldingPattern::found_list_t::iterator it = holder->getFoundList().begin(); it != holder->getFoundList().end(); ++it) { @@ -2146,6 +2436,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) // Fetch the wearables about to be worn. LLWearableList::instance().getAsset(found.mAssetID, found.mName, + gAgentAvatarp, found.mAssetType, onWearableAssetFetch, (void*)holder); @@ -2228,11 +2519,15 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool { if(!category) return; + //selfClearPhases(); + //selfStartPhase("wear_inventory_category"); + gAgentWearables.notifyLoadingStarted(); LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategory( " << category->getName() << " )" << LL_ENDL; + //selfStartPhase("wear_inventory_category_fetch"); callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal, &LLAppearanceMgr::instance(), category->getUUID(), copy, append)); @@ -2241,6 +2536,8 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append) { LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; + + //selfStopPhase("wear_inventory_category_fetch"); // We now have an outfit ready to be copied to agent inventory. Do // it, and wear that outfit normally. @@ -2289,22 +2586,15 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap pid, LLFolderType::FT_NONE, name); - LLPointer cb = new LLWearInventoryCategoryCallback(new_cat_id, append); - it = items->begin(); - for(; it < end; ++it) - { - item = *it; - if(item) - { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - new_cat_id, - std::string(), - cb); - } - } + + // Create a CopyMgr that will copy items, manage its own destruction + new LLCallAfterInventoryCopyMgr( + *items, new_cat_id, std::string("wear_inventory_category_callback"), + boost::bind(&LLAppearanceMgr::wearInventoryCategoryOnAvatar, + LLAppearanceMgr::getInstance(), + gInventory.getCategory(new_cat_id), + append)); + // BAP fixes a lag in display of created dir. gInventory.notifyObservers(); } @@ -2321,12 +2611,18 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego // Avoid unintentionally overwriting old wearables. We have to do // this up front to avoid having to deal with the case of multiple // wearables being dirty. - if(!category) return; + if (!category) return; + + if ( !LLInventoryCallbackManager::is_instantiated() ) + { + // shutting down, ignore. + return; + } LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName() << "'" << LL_ENDL; - if (gAgentCamera.cameraCustomizeAvatar()) + if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance()) { // switching to outfit editor should automagically save any currently edited wearable //LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit")); // MULTI-WEARABLES TODO @@ -2436,6 +2732,25 @@ void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPo } } +void modified_cof_cb(const LLUUID& inv_item) +{ + LLAppearanceMgr::instance().updateAppearanceFromCOF(); + + // Start editing the item if previously requested. + gAgentWearables.editWearableIfRequested(inv_item); + + // TODO: camera mode may not be changed if a debug setting is tweaked + if( LLFloaterCustomize::instanceExists() ) + { + // If we're in appearance editing mode, the current tab may need to be refreshed + /*LLSidepanelAppearance *panel = dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance")); + if (panel) + { + panel->showDefaultSubpart(); + }*/ + LLFloaterCustomize::getInstance()->switchToDefaultSubpart(); + } +} void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer cb) { const LLViewerInventoryItem *vitem = dynamic_cast(item); @@ -2506,12 +2821,12 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update { if(do_update && cb.isNull()) { - cb = new ModifiedCOFCallback; + cb = new LLBoostFuncInventoryCallback(modified_cof_cb); } std::string description = vitem->getIsLinkType() ? vitem->getDescription() : ""; if(description.empty()) { - LLWearable* wearable = gAgentWearables.getWearableFromItemID(vitem->getLinkedUUID()); + LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(vitem->getLinkedUUID()); if(wearable) { U32 index = gAgentWearables.getWearableIndex(wearable); @@ -2534,23 +2849,67 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update return; } -// BAP remove ensemble code for 2.1? -void LLAppearanceMgr::addEnsembleLink( LLInventoryCategory* cat, bool do_update ) +void LLAppearanceMgr::removeAllClothesFromAvatar() { -#if SUPPORT_ENSEMBLES - // BAP add check for already in COF. - LLPointer cb = do_update ? new ModifiedCOFCallback : 0; - link_inventory_item( gAgent.getID(), - cat->getLinkedUUID(), - getCOF(), - cat->getName(), - cat->getDescription(), - LLAssetType::AT_LINK_FOLDER, - cb); -#endif + // Fetch worn clothes (i.e. the ones in COF). + LLInventoryModel::item_array_t clothing_items; + LLInventoryModel::cat_array_t dummy; + LLIsType is_clothing(LLAssetType::AT_CLOTHING); + gInventory.collectDescendentsIf(getCOF(), + dummy, + clothing_items, + LLInventoryModel::EXCLUDE_TRASH, + is_clothing, + false); + uuid_vec_t item_ids; + // Take them off by removing from COF. + for (LLInventoryModel::item_array_t::const_iterator it = clothing_items.begin(); + it != clothing_items.end(); ++it) + { +// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g + if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(*it)) ) + continue; +// [/RLVa:KB] + item_ids.push_back((*it).get()->getLinkedUUID()); + } + + // Take them off by removing from COF. + removeItemsFromAvatar(item_ids); } -void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update) +void LLAppearanceMgr::removeAllAttachmentsFromAvatar() +{ + if (!isAgentAvatarValid()) return; + + LLAgentWearables::llvo_vec_t objects_to_remove; + + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end();) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *attached_object = (*attachment_iter); + if (attached_object) + { + objects_to_remove.push_back(attached_object); + } + } + } + uuid_vec_t ids_to_remove; + for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_remove.begin(); + it != objects_to_remove.end(); + ++it) + { + ids_to_remove.push_back((*it)->getAttachmentItemID()); + } + removeItemsFromAvatar(ids_to_remove); +} + +void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id) { gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); @@ -2568,13 +2927,9 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update) gInventory.purgeObject(item->getUUID()); } } - if (do_update) - { - LLAppearanceMgr::updateAppearanceFromCOF(); - } } -void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, bool do_update) +void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type) { LLFindWearablesOfType filter_wearables_of_type(type); LLInventoryModel::cat_array_t cats; @@ -2590,11 +2945,6 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, bool do_u gInventory.purgeObject(item->getUUID()); } } - - if (do_update) - { - updateAppearanceFromCOF(); - } } bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2) @@ -2731,7 +3081,7 @@ void LLAppearanceMgr::copyLibraryGestures() folder_name == COMMON_GESTURES_FOLDER || folder_name == OTHER_GESTURES_FOLDER) { - cb = new ActivateGestureCallback; + cb = new LLBoostFuncInventoryCallback(activate_gesture_cb); } LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name); @@ -2785,6 +3135,16 @@ void LLAppearanceMgr::onFirstFullyVisible() } } +// update "dirty" state - defined outside class to allow for calling +// after appearance mgr instance has been destroyed. +void appearance_mgr_update_dirty_state() +{ + if (LLAppearanceMgr::instanceExists()) + { + LLAppearanceMgr::getInstance()->updateIsDirty(); + } +} + bool LLAppearanceMgr::updateBaseOutfit() { if (isOutfitLocked()) @@ -2805,8 +3165,8 @@ bool LLAppearanceMgr::updateBaseOutfit() // in a Base Outfit we do not remove items, only links purgeCategory(base_outfit_id, false); - - LLPointer dirty_state_updater = new LLUpdateDirtyState(); + LLPointer dirty_state_updater = + new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state); //COF contains only links so we copy to the Base Outfit only links shallowCopyCategoryContents(getCOF(), base_outfit_id, dirty_state_updater); @@ -2937,79 +3297,206 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base if (inventory_changed) gInventory.notifyObservers(); } - - -class LLScrollOnFirstItem : public LLInventoryCallback +// This is intended for use with HTTP Clients/Responders, but is not +// specifically coupled with those classes. +class LLHTTPRetryPolicy: public LLThreadSafeRefCount { public: - LLScrollOnFirstItem(const LLUUID&folder_id, bool do_scroll) : mFirstItemCreated(!do_scroll), mFolderID(folder_id) - {} - - virtual void fire(const LLUUID& item_id) - { - if(mFirstItemCreated) - return; - mFirstItemCreated = true; - if (LLInventoryPanel::getActiveInventoryPanel()) - { - if( LLFolderView* root = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()) - { - LLFolderViewItem* folder = dynamic_cast(root->getItemByID(mFolderID)); - if(folder) - { - folder->openItem(); - root->setSelection(folder,true,false); - root->scrollToShowSelection(); - } - } - } - } - bool mFirstItemCreated; - LLUUID mFolderID; + LLHTTPRetryPolicy() {} + virtual ~LLHTTPRetryPolicy() {} + virtual bool shouldRetry(U32 status, F32& seconds_to_wait) = 0; }; -class LLShowCreatedOutfit: public LLScrollOnFirstItem +// Example of simplest possible policy, not necessarily recommended. +class LLAlwaysRetryImmediatelyPolicy: public LLHTTPRetryPolicy { public: - LLShowCreatedOutfit(const LLUUID& folder_id, bool show_panel = true): LLScrollOnFirstItem(folder_id, show_panel), mFolderID(folder_id), mShowPanel(show_panel) - {} - - virtual ~LLShowCreatedOutfit() + LLAlwaysRetryImmediatelyPolicy() {} + bool shouldRetry(U32 status, F32& seconds_to_wait) { - if (!LLApp::isRunning()) - { - llwarns << "called during shutdown, skipping" << llendl; - return; - } + seconds_to_wait = 0.0; + return true; + } +}; - LLSD key; +// Very general policy with geometric back-off after failures, +// up to a maximum delay, and maximum number of retries. +class LLAdaptiveRetryPolicy: public LLHTTPRetryPolicy +{ +public: + LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries): + mMinDelay(min_delay), + mMaxDelay(max_delay), + mBackoffFactor(backoff_factor), + mMaxRetries(max_retries), + mDelay(min_delay), + mRetryCount(0) + { + } + + bool shouldRetry(U32 status, F32& seconds_to_wait) + { + seconds_to_wait = mDelay; + mDelay = llclamp(mDelay*mBackoffFactor,mMinDelay,mMaxDelay); + mRetryCount++; + return (mRetryCount<=mMaxRetries); + } + +private: + F32 mMinDelay; // delay never less than this value + F32 mMaxDelay; // delay never exceeds this value + F32 mBackoffFactor; // delay increases by this factor after each retry, up to mMaxDelay. + U32 mMaxRetries; // maximum number of times shouldRetry will return true. + F32 mDelay; // current delay. + U32 mRetryCount; // number of times shouldRetry has been called. +}; + +extern AIHTTPTimeoutPolicy requestAgentUpdateAppearance_timeout; +class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::ResponderWithResult +{ +public: + virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return requestAgentUpdateAppearance_timeout; } + RequestAgentUpdateAppearanceResponder() + { + mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 16.0, 2.0, 5); + } + + virtual ~RequestAgentUpdateAppearanceResponder() + { + } + + // Successful completion. + /* virtual */ void result(const LLSD& content) + { + llinfos << "request OK" << llendl; + } + + // Error + /*virtual*/ void error(U32 status, const std::string& reason) + { + llwarns << "appearance update request failed, status: " << status << " reason: " << reason << llendl; + F32 seconds_to_wait; + if (mRetryPolicy->shouldRetry(status,seconds_to_wait)) + { + llinfos << "retrying" << llendl; + doAfterInterval(boost::bind(&LLAppearanceMgr::requestServerAppearanceUpdate, + LLAppearanceMgr::getInstance(), + LLHTTPClient::ResponderPtr(this)), + seconds_to_wait); + } + else + { + llwarns << "giving up after too many retries" << llendl; + } + } + + LLPointer mRetryPolicy; + + /*virtual*/ char const* getName(void) const { return "RequestAgentUpdateAppearanceResponder"; } +}; + +void LLAppearanceMgr::requestServerAppearanceUpdate(LLHTTPClient::ResponderPtr responder_ptr) +{ + if (!gAgent.getRegion()) + { + llwarns << "Region not set, cannot request server appearance update" << llendl; + return; //Avoid a crash here. RequestAgentUpdateAppearanceResponder crams requestServerAppearanceUpdate into an event... + //which results in gAgent.getRegion() legitimately returning NULL under some scenarios. + } + if (gAgent.getRegion()->getCentralBakeVersion()==0) + { + llwarns << "Region does not support baking" << llendl; + } + std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance"); + if (url.empty()) + { + llwarns << "No cap for UpdateAvatarAppearance." << llendl; + return; + } + + LLSD body; + S32 cof_version = getCOFVersion(); + body["cof_version"] = cof_version; + LL_DEBUGS("Avatar") << "my_cof_version " << cof_version << llendl; + + //LLHTTPClient::ResponderPtr responder_ptr; + if (!responder_ptr.get()) + { + responder_ptr = new RequestAgentUpdateAppearanceResponder; + } + LLHTTPClient::post(url, body, responder_ptr); + llassert(cof_version >= mLastUpdateRequestCOFVersion); + mLastUpdateRequestCOFVersion = cof_version; +} + +void show_created_outfit(const LLUUID& folder_id, bool show_panel = true) +{ + if (!LLApp::isRunning()) + { + llwarns << "called during shutdown, skipping" << llendl; + return; + } + + LLSD key; + + //EXT-7727. For new accounts LLShowCreatedOutfit is created during login process + // add may be processed after login process is finished + // MULTI-WEARABLES TODO + /*if (mShowPanel) + { + LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key); - //EXT-7727. For new accounts LLShowCreatedOutfit is created during login process - // add may be processed after login process is finished - // MULTI-WEARABLES TODO - /*if (mShowPanel) - { - LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key); - - } - LLOutfitsList *outfits_list = - dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab")); - if (outfits_list) - { - outfits_list->setSelectedOutfitByUUID(mFolderID); - }*/ - - LLAppearanceMgr::getInstance()->updateIsDirty(); - gAgentWearables.notifyLoadingFinished(); // New outfit is saved. - LLAppearanceMgr::getInstance()->updatePanelOutfitName(""); } + LLOutfitsList *outfits_list = + dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab")); + if (outfits_list) + { + outfits_list->setSelectedOutfitByUUID(mFolderID); + }*/ -protected: - LLUUID mFolderID; - bool mShowPanel; + LLAppearanceMgr::getInstance()->updateIsDirty(); + gAgentWearables.notifyLoadingFinished(); // New outfit is saved. + LLAppearanceMgr::getInstance()->updatePanelOutfitName(""); +} + +void scroll_to_folder(const LLUUID& folder_id) +{ + if (LLInventoryPanel::getActiveInventoryPanel()) + { + if( LLFolderView* root = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()) + { + LLFolderViewItem* item = root->getItemByID(folder_id); + if(!root) + return; + LLFolderViewFolder* folder = dynamic_cast(item); + if(folder) + { + folder->openItem(); + } + root->setSelection(item,true,false); + root->scrollToShowSelection(); + } + } +} + +class LLBoostFuncInventoryCallbackFireOnce : public LLBoostFuncInventoryCallback +{ +public: + LLBoostFuncInventoryCallbackFireOnce(inventory_func_type fire_func, nullary_func_type destroy_func = no_op) : + LLBoostFuncInventoryCallback(fire_func, destroy_func), mFired(false) + {} +private: + void fire(const LLUUID& item_id) + { + if(mFired) + return; + mFired = true; + LLBoostFuncInventoryCallback::fire(item_id); + } + bool mFired; }; -LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel) +LLUUID LLAppearanceMgr::makeNewOutfitCore(const std::string& new_folder_name, bool show_panel, LLInventoryModel::item_array_t* items /*=NULL*/) { if (!isAgentAvatarValid()) return LLUUID::null; @@ -3024,39 +3511,34 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, b updateClothingOrderingInfo(); - LLPointer cb = new LLShowCreatedOutfit(folder_id,show_panel); - shallowCopyCategoryContents(getCOF(),folder_id, cb); + inventory_func_type fire_fn = no_op_inventory_func; + if(show_panel) + fire_fn = boost::bind(&scroll_to_folder,folder_id); + + LLPointer cb = new LLBoostFuncInventoryCallbackFireOnce( fire_fn, + boost::bind(&show_created_outfit,folder_id,show_panel)); + + if(items) + copyItems(folder_id,items,cb); + else + shallowCopyCategoryContents(getCOF(),folder_id,cb); + createBaseOutfitLink(folder_id, cb); dumpCat(folder_id,"COF, new outfit"); return folder_id; } +LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel/*=true*/) +{ + return makeNewOutfitCore(new_folder_name, show_panel); +} //Given an array of items from COF. v3 outfit behavior. -LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, LLInventoryModel::item_array_t& items, bool show_panel ) +LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, LLInventoryModel::item_array_t& items) { - if (!isAgentAvatarValid()) return LLUUID::null; - else if (items.empty()) return LLUUID::null; - - gAgentWearables.notifyLoadingStarted(); - - // First, make a folder in the My Outfits directory. - const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); - LLUUID folder_id = gInventory.createNewCategory( - parent_id, - LLFolderType::FT_OUTFIT, - new_folder_name); - - updateClothingOrderingInfo(); - - LLPointer cb = new LLShowCreatedOutfit(folder_id,show_panel); - copyItems(folder_id, &items, cb); - createBaseOutfitLink(folder_id, cb); - - dumpCat(folder_id,"COF, new outfit"); - - return folder_id; + if (items.empty()) return LLUUID::null; + return makeNewOutfitCore(new_folder_name, true, &items); } //Creates item copies before links and ties all requests to a sole handler @@ -3072,12 +3554,14 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, L // 2) Stuff with requests via makeLink and makeCopy // 3) Call dispatch() // 4) Let the LLPointer go out of scope. -class LLCreateLegacyOutfit : public LLShowCreatedOutfit +class LLCreateLegacyOutfit : public LLBoostFuncInventoryCallbackFireOnce { public: - LLCreateLegacyOutfit(const LLUUID& folder_id, bool show_panel) : - LLShowCreatedOutfit(folder_id, show_panel), mFolderID(folder_id), mFailed(false) + LLCreateLegacyOutfit(const LLUUID& folder_id, inventory_func_type fire_func, nullary_func_type destroy_func = no_op) : + LLBoostFuncInventoryCallbackFireOnce(fire_func, destroy_func), + mFolderID(folder_id), mFailed(false) {} + virtual ~LLCreateLegacyOutfit() { if (!LLApp::isRunning() || mFailed) @@ -3204,7 +3688,7 @@ public: return; } if(item_id.notNull()) - LLShowCreatedOutfit::fire(item_id); + show_created_outfit(item_id); std::vector::iterator it = std::find(mActiveRequests.begin(), mActiveRequests.end(),cb); if(it != mActiveRequests.end()) @@ -3279,7 +3763,7 @@ private: //Given an array of items from COF. Will only use links for no-copy, no-mod, or multi-worn clothing. -LLUUID LLAppearanceMgr::makeNewOutfitLegacy(const std::string& new_folder_name, LLInventoryModel::item_array_t& items, bool use_links, bool show_panel ) +LLUUID LLAppearanceMgr::makeNewOutfitLegacy(const std::string& new_folder_name, LLInventoryModel::item_array_t& items, bool use_links ) { if (!isAgentAvatarValid()) return LLUUID::null; else if (items.empty()) return LLUUID::null; @@ -3298,7 +3782,7 @@ LLUUID LLAppearanceMgr::makeNewOutfitLegacy(const std::string& new_folder_name, LLInventoryModel::item_array_t base_items; LLInventoryModel::item_array_t remove_items; - LLPointer cb = new LLCreateLegacyOutfit(folder_id,show_panel); + LLPointer cb = new LLCreateLegacyOutfit(folder_id,boost::bind(&scroll_to_folder,folder_id),boost::bind(&show_created_outfit,folder_id,true)); for (LLInventoryModel::item_array_t::const_iterator iter = items.begin(); iter != items.end(); @@ -3334,56 +3818,42 @@ void LLAppearanceMgr::wearBaseOutfit() updateCOF(base_outfit_id); } +void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) +{ + if (ids_to_remove.empty()) + { + llwarns << "called with empty list, nothing to do" << llendl; + } + for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) + { + const LLUUID& id_to_remove = *it; + const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove); + + // [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-3.0.0a) | Added: Catznip-2.1.1d +// [RLVa:KB] - Checked: Never | Added: RLVa-1.2.1c + LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove); + if (!item_to_remove) + continue; + if (rlv_handler_t::isEnabled() && !gRlvWearableLocks.canRemove(item_to_remove)) + continue; + if (item_to_remove->getType() == LLAssetType::AT_CLOTHING) + { + const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(item_to_remove->getLinkedUUID()); + if(!pWearable || pWearable->getAssetType() == LLAssetType::AT_BODYPART || gAgentWearables.getWearableIndex(pWearable) >= LLAgentWearables::MAX_CLOTHING_PER_TYPE ) + continue; + RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true); + } +// [/RLVa:KB] + removeCOFItemLinks(linked_item_id); + } + updateAppearanceFromCOF(); +} + void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) { - LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove); - if (!item_to_remove) return; - - switch (item_to_remove->getType()) - { - case LLAssetType::AT_CLOTHING: -// if (get_is_item_worn(id_to_remove)) -// { -// //*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future -// LLWearableBridge::removeItemFromAvatar(item_to_remove); -// } -// [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-3.0.0a) | Added: Catznip-2.1.1d -// [RLVa:KB] - Checked: 2010-09-04 (RLVa-1.2.1c) | Added: RLVa-1.2.1c - if ( (!rlv_handler_t::isEnabled()) || (gRlvWearableLocks.canRemove(item_to_remove)) ) -// [/RLVa:KB] - { - const LLWearable* pWearable = gAgentWearables.getWearableFromItemID(item_to_remove->getLinkedUUID()); - if ( (pWearable) && (LLAssetType::AT_BODYPART != pWearable->getAssetType()) ) - { - U32 idxWearable = gAgentWearables.getWearableIndex(pWearable); - if (idxWearable < LLAgentWearables::MAX_CLOTHING_PER_TYPE) - { - gAgentWearables.removeWearable(pWearable->getType(), false, idxWearable); - - LLAppearanceMgr::instance().removeCOFItemLinks(item_to_remove->getLinkedUUID(), false); - gInventory.notifyObservers(); - -// [RLVa:KB] - Checked: 2011-06-07 (RLVa-1.3.1b) | Added: RLVa-1.3.1b - RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true); -// [/RLVa:KB] - } - } - } -// [/SL:KB] - break; - case LLAssetType::AT_OBJECT: - LLVOAvatarSelf::detachAttachmentIntoInventory(item_to_remove->getLinkedUUID()); - default: - break; - } - - // *HACK: Force to remove garbage from COF. - // Unworn links or objects can't be processed by existed removing functionality - // since it is not designed for such cases. As example attachment object can't be removed - // since sever don't sends message _PREHASH_KillObject in that case. - // Also we can't check is link was successfully removed from COF since in case - // deleting attachment link removing performs asynchronously in process_kill_object callback. - removeCOFItemLinks(id_to_remove,false); + LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove); + removeCOFItemLinks(linked_item_id); + updateAppearanceFromCOF(); } bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body) @@ -3428,7 +3898,7 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b //to cause appearance of the agent to be updated bool result = false; - if ((result = gAgentWearables.moveWearable(item, closer_to_body))) + if (result = gAgentWearables.moveWearable(item, closer_to_body)) { gAgentAvatarp->wearableUpdated(item->getWearableType(), FALSE); } @@ -3492,7 +3962,8 @@ LLAppearanceMgr::LLAppearanceMgr(): mAttachmentInvLinkEnabled(false), mOutfitIsDirty(false), mOutfitLocked(false), - mIsInUpdateAppearanceFromCOF(false) + mIsInUpdateAppearanceFromCOF(false), + mLastUpdateRequestCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) { LLOutfitObserver& outfit_observer = LLOutfitObserver::instance(); @@ -3580,7 +4051,7 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id) if (mAttachmentInvLinkEnabled) { - LLAppearanceMgr::removeCOFItemLinks(item_id, false); + LLAppearanceMgr::removeCOFItemLinks(item_id); } else { @@ -3616,7 +4087,7 @@ void LLAppearanceMgr::onRegisterAttachmentComplete(const LLUUID& idItem) // It may have been detached already in which case we should remove the COF link if ( (isAgentAvatarValid()) && (!gAgentAvatarp->isWearingAttachment(idItemBase)) ) - removeCOFItemLinks(idItemBase, false); + removeCOFItemLinks(idItemBase); } // [/SL:KB] diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 57ec94a27..2db333aa8 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -34,11 +34,13 @@ #include "llinventorymodel.h" #include "llinventoryobserver.h" #include "llviewerinventory.h" +#include "llhttpclient.h" class LLWearable; class LLWearableHoldingPattern; class LLInventoryCallback; class LLOutfitUnLockTimer; +class LLCallAfterInventoryLinkMgr; class LLAppearanceMgr: public LLSingleton { @@ -103,6 +105,9 @@ public: // Find the Current Outfit folder. const LLUUID getCOF() const; + S32 getCOFVersion() const; + + S32 mLastUpdateRequestCOFVersion; // Finds the folder link to the currently worn outfit const LLViewerInventoryItem *getBaseOutfitLink(); @@ -117,6 +122,7 @@ public: // Update the displayed outfit name in UI. void updatePanelOutfitName(const std::string& name); + void purgeBaseOutfitLink(const LLUUID& category); void createBaseOutfitLink(const LLUUID& category, LLPointer link_waiter); void updateAgentWearables(LLWearableHoldingPattern* holder, bool append); @@ -140,11 +146,10 @@ public: void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer cb = NULL); // Remove COF entries - void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true); - void removeCOFLinksOfType(LLWearableType::EType type, bool do_update = true); - - // Add COF link to ensemble folder. - void addEnsembleLink(LLInventoryCategory* item, bool do_update = true); + void removeCOFItemLinks(const LLUUID& item_id); + void removeCOFLinksOfType(LLWearableType::EType type); + void removeAllClothesFromAvatar(); + void removeAllAttachmentsFromAvatar(); //has the current outfit changed since it was loaded? bool isOutfitDirty() { return mOutfitIsDirty; } @@ -172,12 +177,15 @@ public: bool updateBaseOutfit(); //Remove clothing or detach an object from the agent (a bodypart cannot be removed) + void removeItemsFromAvatar(const uuid_vec_t& item_ids); void removeItemFromAvatar(const LLUUID& item_id); - - LLUUID makeNewOutfitLinks(const std::string& new_folder_name,bool show_panel = true); - LLUUID makeNewOutfitLinks(const std::string& new_folder_name, LLInventoryModel::item_array_t& item_list, bool show_panel = true); - LLUUID makeNewOutfitLegacy(const std::string& new_folder_name, LLInventoryModel::item_array_t& items, bool use_links, bool show_panel = true); +private: + LLUUID makeNewOutfitCore(const std::string& new_folder_name, bool show_panel/*=true*/, LLInventoryModel::item_array_t* items = NULL); +public: + LLUUID makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel/*=true*/); + LLUUID makeNewOutfitLinks(const std::string& new_folder_name, LLInventoryModel::item_array_t& item_list); + LLUUID makeNewOutfitLegacy(const std::string& new_folder_name, LLInventoryModel::item_array_t& items, bool use_links); bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body); @@ -194,6 +202,8 @@ public: bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; } + void requestServerAppearanceUpdate(LLHTTPClient::ResponderPtr responder_ptr = NULL); + protected: LLAppearanceMgr(); ~LLAppearanceMgr(); @@ -214,14 +224,13 @@ private: bool follow_folder_links); void purgeCategory(const LLUUID& category, bool keep_outfit_links); - void purgeBaseOutfitLink(const LLUUID& category); static void onOutfitRename(const LLSD& notification, const LLSD& response); void setOutfitLocked(bool locked); // [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f - void syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLPointer cb); + void syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLCallAfterInventoryLinkMgr* link_waiter); // [/SL:KB] bool mAttachmentInvLinkEnabled; @@ -291,4 +300,5 @@ void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb); // Wear all items in a uuid vector. void wear_multiple(const uuid_vec_t& ids, bool replace); +void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace = false); #endif diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4ce4f662d..9875b1879 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -507,7 +507,7 @@ static void settings_to_globals() gAllowIdleAFK = gSavedSettings.getBOOL("AllowIdleAFK"); gAllowTapTapHoldRun = gSavedSettings.getBOOL("AllowTapTapHoldRun"); gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); - LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale"); + LLWorldMapView::sMapScale = llmax(.1f,gSavedSettings.getF32("MapScale")); LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips"); } @@ -563,7 +563,6 @@ LLAppViewer::LLAppViewer() : mSavedFinalSnapshot(false), mQuitRequested(false), mLogoutRequestSent(false), - mYieldTime(-1), mMainloopTimeout(NULL), mAgentRegionLastAlive(false) { @@ -584,6 +583,15 @@ LLAppViewer::~LLAppViewer() removeMarkerFile(); } +class LLUITranslationBridge : public LLTranslationBridge +{ +public: + virtual std::string getString(const std::string &xml_desc) + { + return LLTrans::getString(xml_desc); + } +}; + bool LLAppViewer::init() { // @@ -595,6 +603,10 @@ bool LLAppViewer::init() // LLFastTimer::reset(); + // initialize LLWearableType translation bridge. + // Memory will be cleaned up in ::cleanupClass() + LLWearableType::initClass(new LLUITranslationBridge()); + // // We can call this early. LLFrameTimer::global_initialization(); @@ -731,7 +743,7 @@ bool LLAppViewer::init() &gColors, LLUIImageList::getInstance(), ui_audio_callback, - &LLUI::sGLScaleFactor + &LLUI::getScaleFactor() ); LLWeb::initClass(); // do this after LLUI @@ -848,8 +860,10 @@ bool LLAppViewer::init() { // can't use an alert here since we're exiting and // all hell breaks lose. + std::string msg = LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"); + LLStringUtil::format(msg,LLTrans::getDefaultArgs()); OSMessageBox( - LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"), + msg, LLStringUtil::null, OSMB_OK); return 0; @@ -861,8 +875,10 @@ bool LLAppViewer::init() { // can't use an alert here since we're exiting and // all hell breaks lose. + std::string msg = LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2"); + LLStringUtil::format(msg,LLTrans::getDefaultArgs()); OSMessageBox( - LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2"), + msg, LLStringUtil::null, OSMB_OK); return 0; @@ -873,8 +889,10 @@ bool LLAppViewer::init() { // can't use an alert here since we're exiting and // all hell breaks lose. + std::string msg = LNotifications::instance().getGlobalString("UnsupportedCPUSSE2"); + LLStringUtil::format(msg,LLTrans::getDefaultArgs()); OSMessageBox( - LLNotifications::instance().getGlobalString("UnsupportedCPUSSE"), + msg, LLStringUtil::null, OSMB_OK); return 0; @@ -1070,7 +1088,7 @@ bool LLAppViewer::mainLoop() LLVoiceChannel::initClass(); LLVoiceClient::init(gServicePump); - LLTimer frameTimer,idleTimer; + LLTimer frameTimer,idleTimer,periodicRenderingTimer; LLTimer debugTime; LLFrameTimer memCheckTimer; LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); @@ -1083,6 +1101,7 @@ bool LLAppViewer::mainLoop() // point of posting. LLSD newFrame; + BOOL restore_rendering_masks = FALSE; // Handle messages while (!LLApp::isExiting()) @@ -1097,6 +1116,28 @@ bool LLAppViewer::mainLoop() try { + // Check if we need to restore rendering masks. + if (restore_rendering_masks) + { + gPipeline.popRenderDebugFeatureMask(); + gPipeline.popRenderTypeMask(); + } + // Check if we need to temporarily enable rendering. + static const LLCachedControl periodic_rendering("ForcePeriodicRenderingTime", 0.f); + if (periodic_rendering > F_APPROXIMATELY_ZERO && periodicRenderingTimer.getElapsedTimeF64() > periodic_rendering) + { + periodicRenderingTimer.reset(); + restore_rendering_masks = TRUE; + gPipeline.pushRenderTypeMask(); + gPipeline.pushRenderDebugFeatureMask(); + gPipeline.setAllRenderTypes(); + gPipeline.setAllRenderDebugFeatures(); + } + else + { + restore_rendering_masks = FALSE; + } + pingMainloopTimeout("Main:MiscNativeWindowEvents"); if (gViewerWindow) @@ -1206,7 +1247,6 @@ bool LLAppViewer::mainLoop() pingMainloopTimeout("Main:Display"); gGLActive = TRUE; display(); - pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots gGLActive = FALSE; @@ -1223,12 +1263,12 @@ bool LLAppViewer::mainLoop() LLMemType mt_sleep(LLMemType::MTYPE_SLEEP); LLFastTimer t2(FTM_SLEEP); static const LLCachedControl run_multiple_threads("RunMultipleThreads",false); - + static const LLCachedControl yield_time("YieldTime", -1); // yield some time to the os based on command line option - if(mYieldTime >= 0) + if(yield_time >= 0) { LLFastTimer t(FTM_YIELD); - ms_sleep(mYieldTime); + ms_sleep(yield_time); } // yield cooperatively when not running as foreground window @@ -1567,6 +1607,8 @@ bool LLAppViewer::cleanup() LLViewerObject::cleanupVOClasses(); + LLAvatarAppearance::cleanupClass(); + LLPostProcess::cleanupClass(); LLTracker::cleanupInstance(); @@ -1791,6 +1833,8 @@ bool LLAppViewer::cleanup() llinfos << "File launched." << llendflush; } + LLWearableType::cleanupClass(); + LLMainLoopRepeater::instance().stop(); //release all private memory pools. @@ -2340,8 +2384,6 @@ bool LLAppViewer::initConfiguration() gDirUtilp->setSkinFolder(skinfolder->getValue().asString()); } - mYieldTime = gSavedSettings.getS32("YieldTime"); - // XUI:translate gSecondLife = "Singularity Viewer"; @@ -3952,6 +3994,13 @@ void LLAppViewer::idle() return; } + static const LLCachedControl hide_tp_screen("AscentDisableTeleportScreens",false); + LLAgent::ETeleportState tp_state = gAgent.getTeleportState(); + if (!hide_tp_screen && tp_state != LLAgent::TELEPORT_NONE && tp_state != LLAgent::TELEPORT_LOCAL && tp_state != LLAgent::TELEPORT_PENDING) + { + return; + } + gViewerWindow->updateUI(); /////////////////////////////////////// diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 1b0e5614f..681cb505d 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -243,7 +243,6 @@ private: bool mQuitRequested; // User wants to quit, may have modified documents open. bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. - S32 mYieldTime; LLSD mSettingsLocationList; LLWatchdogTimeout* mMainloopTimeout; diff --git a/indra/newview/llassetuploadqueue.cpp b/indra/newview/llassetuploadqueue.cpp index bb022bafa..f0d0fa761 100644 --- a/indra/newview/llassetuploadqueue.cpp +++ b/indra/newview/llassetuploadqueue.cpp @@ -75,7 +75,7 @@ public: delete mData; } - virtual void error(U32 statusNum, const std::string& reason) + /*virtual*/ void error(U32 statusNum, const std::string& reason) { llwarns << "Error: " << reason << llendl; LLUpdateTaskInventoryResponder::error(statusNum, reason); @@ -86,7 +86,7 @@ public: } } - virtual void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { LLUpdateTaskInventoryResponder::result(content); LLAssetUploadQueue *queue = mSupplier->get(); @@ -136,13 +136,14 @@ public: LLUpdateTaskInventoryResponder::uploadComplete(content); } + /*virtual*/ char const* getName(void) const { return "LLAssetUploadChainResponder"; } + LLAssetUploadQueueSupplier *mSupplier; char* mData; U32 mDataSize; std::string mScriptName; }; - LLAssetUploadQueue::LLAssetUploadQueue(LLAssetUploadQueueSupplier *supplier) : mSupplier(supplier) { diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 173666a12..77a0558f1 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -54,8 +54,8 @@ #include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "llviewermenufile.h" +#include "llviewertexlayer.h" #include "llviewerwindow.h" -#include "lltexlayer.h" #include "lltrans.h" // library includes @@ -317,8 +317,10 @@ void LLAssetUploadResponder::uploadComplete(const LLSD& content) LLNewAgentInventoryResponder::LLNewAgentInventoryResponder( const LLSD& post_data, const LLUUID& vfile_id, - LLAssetType::EType asset_type) - : LLAssetUploadResponder(post_data, vfile_id, asset_type) + LLAssetType::EType asset_type, + void (*callback)(bool, void*), + void* user_data) + : LLAssetUploadResponder(post_data, vfile_id, asset_type), mCallBack(callback), mUserData(user_data) { } @@ -326,13 +328,17 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder( const LLSD& post_data, const std::string& file_name, LLAssetType::EType asset_type) - : LLAssetUploadResponder(post_data, file_name, asset_type) + : LLAssetUploadResponder(post_data, file_name, asset_type), mCallBack(NULL), mUserData(NULL) { } // virtual void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason) { + if (mCallBack) + { + (*mCallBack)(false, mUserData); + } LLAssetUploadResponder::error(statusNum, reason); //LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE); } @@ -340,6 +346,10 @@ void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reaso //virtual void LLNewAgentInventoryResponder::uploadFailure(const LLSD& content) { + if (mCallBack) + { + (*mCallBack)(false, mUserData); + } LLAssetUploadResponder::uploadFailure(content); //LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, content["new_asset"], FALSE); } @@ -349,6 +359,11 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) { lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; + if (mCallBack) + { + (*mCallBack)(true, mUserData); + } + //std::ostringstream llsdxml; //LLSDSerialize::toXML(content, llsdxml); //llinfos << "upload complete content:\n " << llsdxml.str() << llendl; @@ -446,7 +461,7 @@ LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data, LLSendTexLayerResponder::~LLSendTexLayerResponder() { - // mBakedUploadData is normally deleted by calls to LLTexLayerSetBuffer::onTextureUploadComplete() below + // mBakedUploadData is normally deleted by calls to LLViewerTexLayerSetBuffer::onTextureUploadComplete() below if (mBakedUploadData) { // ...but delete it in the case where uploadComplete() is never called delete mBakedUploadData; @@ -467,12 +482,12 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content) if (result == "complete" && mBakedUploadData != NULL) { // Invoke - LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE); + LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE); mBakedUploadData = NULL; // deleted in onTextureUploadComplete() } else { // Invoke the original callback with an error result - LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); + LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); mBakedUploadData = NULL; // deleted in onTextureUploadComplete() } } @@ -482,7 +497,7 @@ void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason) llinfos << "status: " << statusNum << " reason: " << reason << llendl; // Invoke the original callback with an error result - LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); + LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); mBakedUploadData = NULL; // deleted in onTextureUploadComplete() } diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index fa4e5a8eb..bdcf41390 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -61,9 +61,10 @@ public: const std::string& file_name, LLAssetType::EType asset_type); ~LLAssetUploadResponder(); - virtual void error(U32 statusNum, const std::string& reason); - virtual void result(const LLSD& content); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return assetUploadResponder_timeout; } + /*virtual*/ void error(U32 statusNum, const std::string& reason); + /*virtual*/ void result(const LLSD& content); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return assetUploadResponder_timeout; } + virtual void uploadUpload(const LLSD& content); virtual void uploadComplete(const LLSD& content); virtual void uploadFailure(const LLSD& content); @@ -77,18 +78,23 @@ protected: class LLNewAgentInventoryResponder : public LLAssetUploadResponder { + void (*mCallBack)(bool, void*); + void* mUserData; public: LLNewAgentInventoryResponder( const LLSD& post_data, const LLUUID& vfile_id, - LLAssetType::EType asset_type); + LLAssetType::EType asset_type, + void (*callback)(bool, void*) = NULL, + void* user_data = NULL); LLNewAgentInventoryResponder( const LLSD& post_data, const std::string& file_name, LLAssetType::EType asset_type); - virtual void error(U32 statusNum, const std::string& reason); + /*virtual*/ void error(U32 statusNum, const std::string& reason); virtual void uploadComplete(const LLSD& content); virtual void uploadFailure(const LLSD& content); + /*virtual*/ char const* getName(void) const { return "LLNewAgentInventoryResponder"; } }; // A base class which goes through and performs some default @@ -110,12 +116,12 @@ public: const LLSD& inventory_info); virtual ~LLNewAgentInventoryVariablePriceResponder(); - void errorWithContent( + /*virtual*/ void errorWithContent( U32 statusNum, const std::string& reason, const LLSD& content); - void result(const LLSD& content); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return newAgentInventoryVariablePriceResponder_timeout; } + /*virtual*/ void result(const LLSD& content); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return newAgentInventoryVariablePriceResponder_timeout; } virtual void onApplicationLevelError( const LLSD& error); @@ -141,8 +147,9 @@ public: ~LLSendTexLayerResponder(); - virtual void uploadComplete(const LLSD& content); - virtual void error(U32 statusNum, const std::string& reason); + /*virtual*/ void uploadComplete(const LLSD& content); + /*virtual*/ void error(U32 statusNum, const std::string& reason); + /*virtual*/ char const* getName(void) const { return "LLSendTexLayerResponder"; } LLBakedUploadData * mBakedUploadData; }; @@ -157,6 +164,7 @@ public: const std::string& file_name, LLAssetType::EType asset_type); virtual void uploadComplete(const LLSD& content); + /*virtual*/ char const* getName(void) const { return "LLUpdateAgentInventoryResponder"; } }; class LLUpdateTaskInventoryResponder : public LLAssetUploadResponder @@ -174,7 +182,8 @@ public: LLAssetType::EType asset_type); virtual void uploadComplete(const LLSD& content); - + /*virtual*/ char const* getName(void) const { return "LLUpdateTaskInventoryResponder"; } + private: LLUUID mQueueId; }; diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp index 1bfd2cb9b..79ec43dfe 100644 --- a/indra/newview/llcallbacklist.cpp +++ b/indra/newview/llcallbacklist.cpp @@ -2,37 +2,32 @@ * @file llcallbacklist.cpp * @brief A simple list of callback functions to call. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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 "llcallbacklist.h" +#include "lleventtimer.h" // Library includes #include "llerror.h" @@ -186,6 +181,54 @@ void doOnIdleRepeating(bool_func_t callable) gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor); } +class NullaryFuncEventTimer: public LLEventTimer +{ +public: + NullaryFuncEventTimer(nullary_func_t callable, F32 seconds): + LLEventTimer(seconds), + mCallable(callable) + { + } + +private: + BOOL tick() + { + mCallable(); + return TRUE; + } + + nullary_func_t mCallable; +}; + +// Call a given callable once after specified interval. +void doAfterInterval(nullary_func_t callable, F32 seconds) +{ + new NullaryFuncEventTimer(callable, seconds); +} + +class BoolFuncEventTimer: public LLEventTimer +{ +public: + BoolFuncEventTimer(bool_func_t callable, F32 seconds): + LLEventTimer(seconds), + mCallable(callable) + { + } +private: + BOOL tick() + { + return mCallable(); + } + + bool_func_t mCallable; +}; + +// Call a given callable every specified number of seconds, until it returns true. +void doPeriodically(bool_func_t callable, F32 seconds) +{ + new BoolFuncEventTimer(callable, seconds); +} + #ifdef _DEBUG void test1(void *data) diff --git a/indra/newview/llcallbacklist.h b/indra/newview/llcallbacklist.h index 1819f865a..0516c9cdb 100644 --- a/indra/newview/llcallbacklist.h +++ b/indra/newview/llcallbacklist.h @@ -2,31 +2,25 @@ * @file llcallbacklist.h * @brief A simple list of callback functions to call. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,7 +28,6 @@ #define LL_LLCALLBACKLIST_H #include "llstl.h" -#include class LLCallbackList { @@ -68,6 +61,12 @@ void doOnIdleOneTime(nullary_func_t callable); // Repeatedly call a callable in idle loop until it returns true. void doOnIdleRepeating(bool_func_t callable); +// Call a given callable once after specified interval. +void doAfterInterval(nullary_func_t callable, F32 seconds); + +// Call a given callable every specified number of seconds, until it returns true. +void doPeriodically(bool_func_t callable, F32 seconds); + extern LLCallbackList gIdleCallbacks; #endif diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 12dd4a4b9..34b8785c9 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -638,22 +638,11 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) { if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) { - std::string first, last; std::string fullname; LLSD args; - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) - { - switch (gSavedSettings.getS32("PhoenixNameSystem")) - { - case 0 : fullname = avatar_name.getLegacyName(); break; - case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : fullname = avatar_name.mDisplayName; break; - default : fullname = avatar_name.getCompleteName(); break; - } + if (LLAvatarNameCache::getPNSName(agent_id, fullname)) args["NAME"] = fullname; - } - + LLSD payload; payload["from_id"] = agent_id; if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights) @@ -740,15 +729,11 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id, { // Popup a notify box with online status of this agent // Use display name only because this user is your friend + std::string name; + LLAvatarNameCache::getPNSName(av_name, name); LLSD args; - switch (gSavedSettings.getS32("PhoenixNameSystem")) - { - case 0 : args["NAME"] = av_name.getLegacyName(); break; - case 1 : args["NAME"] = (av_name.mIsDisplayNameDefault ? av_name.mDisplayName : av_name.getCompleteName()); break; - case 2 : args["NAME"] = av_name.mDisplayName; break; - default : args["NAME"] = av_name.getCompleteName(); break; - } - + args["NAME"] = name; + // Popup a notify box with online status of this agent LLNotificationPtr notification = LLNotificationsUtil::add(online ? "FriendOnline" : "FriendOffline", args, payload); diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h index f317d5851..d44d43f78 100644 --- a/indra/newview/llclassifiedstatsresponder.h +++ b/indra/newview/llclassifiedstatsresponder.h @@ -45,10 +45,11 @@ class LLClassifiedStatsResponder : public LLHTTPClient::ResponderWithResult public: LLClassifiedStatsResponder(LLHandle classified_panel_handle, LLUUID classified_id); //If we get back a normal response, handle it here - virtual void result(const LLSD& content); + /*virtual*/ void result(const LLSD& content); //If we get back an error (not found, etc...), handle it here - virtual void error(U32 status, const std::string& reason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return classifiedStatsResponder_timeout; } + /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return classifiedStatsResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLClassifiedStatsResponder"; } protected: LLHandle mClassifiedPanelHandle; diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 874299df3..dd260711a 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -55,6 +55,7 @@ #include "llviewerobject.h" #include "llviewerregion.h" #include "llresmgr.h" + #include "llbutton.h" #include "lldir.h" #include "llnotificationsutil.h" @@ -190,25 +191,12 @@ BOOL LLFloaterScriptQueue::start() //llinfos << "LLFloaterCompileQueue::start()" << llendl; std::string buffer; - LLSelectMgr *mgr = LLSelectMgr::getInstance(); - LLObjectSelectionHandle selectHandle = mgr->getSelection(); - U32 n_objects = 0; - if (gSavedSettings.getBOOL("EditLinkedParts")) - { - n_objects = selectHandle->getObjectCount(); - } - else - { - n_objects = selectHandle->getRootObjectCount(); - } - LLStringUtil::format_map_t args; args["[START]"] = mStartString; args["[COUNT]"] = llformat ("%d", mObjectIDs.count()); buffer = getString ("Starting", args); - LLScrollListCtrl* list = getChild("queue output"); - list->addCommentText(buffer); + getChild("queue output")->addSimpleElement(buffer, ADD_BOTTOM); return nextObject(); } @@ -240,12 +228,9 @@ BOOL LLFloaterScriptQueue::nextObject() } while((mObjectIDs.count() > 0) && !successful_start); if(isDone() && !mDone) { - - LLScrollListCtrl* list = getChild("queue output"); - - mDone = TRUE; - list->addCommentText(getString("Done")); - childSetEnabled("close",TRUE); + mDone = true; + getChild("queue output")->addSimpleElement(getString("Done"), ADD_BOTTOM); + getChildView("close")->setEnabled(TRUE); } return successful_start; } @@ -283,6 +268,40 @@ BOOL LLFloaterScriptQueue::popNext() /// Class LLFloaterCompileQueue ///---------------------------------------------------------------------------- +class LLCompileFloaterUploadQueueSupplier : public LLAssetUploadQueueSupplier +{ +public: + + LLCompileFloaterUploadQueueSupplier(const LLUUID& queue_id) : + mQueueId(queue_id) + { + } + + virtual LLAssetUploadQueue* get() const + { + LLFloaterCompileQueue* queue = (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId); + if(NULL == queue) + { + return NULL; + } + return queue->getUploadQueue(); + } + + virtual void log(std::string message) const + { + LLFloaterCompileQueue* queue = (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId); + if(NULL == queue) + { + return; + } + + queue->getChild("queue output")->addSimpleElement(message, ADD_BOTTOM); + } + +private: + LLUUID mQueueId; +}; + // static LLFloaterCompileQueue* LLFloaterCompileQueue::create(BOOL mono) { @@ -291,48 +310,8 @@ LLFloaterCompileQueue* LLFloaterCompileQueue::create(BOOL mono) LLRect rect = gSavedSettings.getRect("CompileOutputRect"); rect.translate(left - rect.mLeft, top - rect.mTop); LLFloaterCompileQueue* new_queue = new LLFloaterCompileQueue("queue", rect); - - class LLCompileFloaterUploadQueueSupplier : public LLAssetUploadQueueSupplier - { - public: - - LLCompileFloaterUploadQueueSupplier(const LLUUID& queue_id) : - mQueueId(queue_id) - { - } - - virtual LLAssetUploadQueue* get() const - { - LLFloaterCompileQueue* queue = - (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId); - - if(NULL == queue) - { - return NULL; - } - - return queue->mUploadQueue; - } - virtual void log(std::string message) const - { - LLFloaterCompileQueue* queue = - (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId); - - if(NULL == queue) - { - return; - } - - LLScrollListCtrl* list = queue->getChild("queue output"); - list->addCommentText(message.c_str()); - } - - private: - LLUUID mQueueId; - }; - - new_queue->mUploadQueue = new LLAssetUploadQueue(new LLCompileFloaterUploadQueueSupplier(new_queue->getID())); + new_queue->mUploadQueue = new LLAssetUploadQueue(new LLCompileFloaterUploadQueueSupplier(new_queue->getID())); new_queue->mMono = mono; new_queue->open(); return new_queue; @@ -414,8 +393,8 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id, llinfos << "LLFloaterCompileQueue::scriptArrived()" << llendl; LLScriptQueueData* data = (LLScriptQueueData*)user_data; if(!data) return; - LLFloaterCompileQueue* queue = static_cast - (LLFloaterScriptQueue::findInstance(data->mQueueID)); + LLFloaterCompileQueue* queue = static_cast (LLFloaterScriptQueue::findInstance(data->mQueueID)); + std::string buffer; if(queue && (0 == status)) { @@ -519,12 +498,12 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id, } if(queue && (buffer.size() > 0)) { - LLScrollListCtrl* list = queue->getChild("queue output"); - list->addCommentText(buffer); + queue->getChild("queue output")->addSimpleElement(buffer, ADD_BOTTOM); } delete data; } +#if 0 //Client side compiling disabled. // static void LLFloaterCompileQueue::onSaveTextComplete(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) { @@ -543,8 +522,7 @@ void LLFloaterCompileQueue::onSaveBytecodeComplete(const LLUUID& asset_id, void* { llinfos << "LLFloaterCompileQueue::onSaveBytecodeComplete()" << llendl; LLCompileQueueData* data = (LLCompileQueueData*)user_data; - LLFloaterCompileQueue* queue = static_cast - (LLFloaterScriptQueue::findInstance(data->mQueueID)); + LLFloaterCompileQueue* queue = static_cast (LLFloaterScriptQueue::findInstance(data->mQueueID)); if(queue && (0 == status) && data) { queue->saveItemByItemID(data->mItemId); @@ -562,7 +540,6 @@ void LLFloaterCompileQueue::onSaveBytecodeComplete(const LLUUID& asset_id, void* } // compile the file given and save it out. -#if 0 //Client side compiling disabled. void LLFloaterCompileQueue::compile(const std::string& filename, const LLUUID& item_id) { @@ -692,7 +669,7 @@ void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj, // find all of the lsl, leaving off duplicates. We'll remove // all matching asset uuids on compilation success. LLDynamicArray names; - + LLInventoryObject::object_list_t::const_iterator it = inv->begin(); LLInventoryObject::object_list_t::const_iterator end = inv->end(); for ( ; it != end; ++it) @@ -704,10 +681,9 @@ void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj, if (object) { LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); - LLScrollListCtrl* list = getChild("queue output"); std::string buffer; buffer = getString("Resetting") + LLTrans::getString(":") + " " + item->getName(); - list->addCommentText(buffer); + getChild("queue output")->addSimpleElement(buffer, ADD_BOTTOM); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_ScriptReset); msg->nextBlockFast(_PREHASH_AgentData); @@ -754,7 +730,7 @@ void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj, // find all of the lsl, leaving off duplicates. We'll remove // all matching asset uuids on compilation success. LLDynamicArray names; - + LLInventoryObject::object_list_t::const_iterator it = inv->begin(); LLInventoryObject::object_list_t::const_iterator end = inv->end(); for ( ; it != end; ++it) @@ -769,7 +745,7 @@ void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj, LLScrollListCtrl* list = getChild("queue output"); std::string buffer; buffer = getString("Running") + LLTrans::getString(":") + " " + item->getName(); - list->addCommentText(buffer); + list->addSimpleElement(buffer, ADD_BOTTOM); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_SetScriptRunning); @@ -818,7 +794,7 @@ void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj, // find all of the lsl, leaving off duplicates. We'll remove // all matching asset uuids on compilation success. LLDynamicArray names; - + LLInventoryObject::object_list_t::const_iterator it = inv->begin(); LLInventoryObject::object_list_t::const_iterator end = inv->end(); for ( ; it != end; ++it) @@ -833,8 +809,8 @@ void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj, LLScrollListCtrl* list = getChild("queue output"); std::string buffer; buffer = getString("NotRunning") + LLTrans::getString(":") + " " + item->getName(); - list->addCommentText(buffer); - + list->addSimpleElement(buffer, ADD_BOTTOM); + LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_SetScriptRunning); msg->nextBlockFast(_PREHASH_AgentData); diff --git a/indra/newview/llcompilequeue.h b/indra/newview/llcompilequeue.h index e4bccff52..9114ce484 100644 --- a/indra/newview/llcompilequeue.h +++ b/indra/newview/llcompilequeue.h @@ -79,7 +79,7 @@ protected: 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; @@ -105,7 +105,7 @@ protected: // Object Queue LLDynamicArray mObjectIDs; LLUUID mCurrentObjectID; - BOOL mDone; + bool mDone; LLUUID mID; static LLMap sInstances; @@ -136,13 +136,11 @@ public: // will be responsible for it's own destruction. static LLFloaterCompileQueue* create(BOOL mono); - static void onSaveBytecodeComplete(const LLUUID& asset_id, - void* user_data, - S32 status); - // remove any object in mScriptScripts with the matching uuid. void removeItemByItemID(const LLUUID& item_id); + LLAssetUploadQueue* getUploadQueue() { return mUploadQueue; } + protected: LLFloaterCompileQueue(const std::string& name, const LLRect& rect); virtual ~LLFloaterCompileQueue(); @@ -156,6 +154,7 @@ protected: LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status); +#if 0 //Client side compiling disabled. static void onSaveTextComplete(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status); static void onSaveBytecodeComplete(const LLUUID& asset_id, @@ -163,7 +162,6 @@ protected: S32 status, LLExtStat ext_status); // compile the file given and save it out. -#if 0 //Client side compiling disabled. void compile(const std::string& filename, const LLUUID& asset_id); #endif @@ -200,12 +198,10 @@ public: protected: LLFloaterResetQueue(const std::string& name, const LLRect& rect); virtual ~LLFloaterResetQueue(); - + // This is called by inventoryChanged virtual void handleInventory(LLViewerObject* viewer_obj, - LLInventoryObject::object_list_t* inv); - -protected: + LLInventoryObject::object_list_t* inv); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -224,12 +220,10 @@ public: protected: LLFloaterRunQueue(const std::string& name, const LLRect& rect); virtual ~LLFloaterRunQueue(); - + // This is called by inventoryChanged virtual void handleInventory(LLViewerObject* viewer_obj, LLInventoryObject::object_list_t* inv); - -protected: }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -252,8 +246,6 @@ protected: // This is called by inventoryChanged virtual void handleInventory(LLViewerObject* viewer_obj, LLInventoryObject::object_list_t* inv); - -protected: }; #endif // LL_LLCOMPILEQUEUE_H diff --git a/indra/newview/lldebugmessagebox.cpp b/indra/newview/lldebugmessagebox.cpp index 4188ecc0e..ab5ddf18b 100644 --- a/indra/newview/lldebugmessagebox.cpp +++ b/indra/newview/lldebugmessagebox.cpp @@ -112,7 +112,7 @@ void LLDebugVarMessageBox::show(const std::string& title, F32 *var, F32 max_valu { box->mSlider1->setValue(*var); } - box->mSlider1->setCommitCallback(slider_changed); + box->mSlider1->setCommitCallback(boost::bind(&LLDebugVarMessageBox::slider_changed,_1,box)); box->mSlider1->setCallbackUserData(box); #endif } @@ -129,8 +129,7 @@ void LLDebugVarMessageBox::show(const std::string& title, S32 *var, S32 max_valu { box->mSlider1->setValue((F32)*var); } - box->mSlider1->setCommitCallback(slider_changed); - box->mSlider1->setCallbackUserData(box); + box->mSlider1->setCommitCallback(boost::bind(&LLDebugVarMessageBox::slider_changed,_1,box)); #endif } @@ -142,20 +141,17 @@ void LLDebugVarMessageBox::show(const std::string& title, LLVector3 *var, LLVect box->mSlider1->setMaxValue(max_value.mV[VX]); box->mSlider1->setMinValue(-max_value.mV[VX]); box->mSlider1->setIncrement(increment.mV[VX]); - box->mSlider1->setCommitCallback(slider_changed); - box->mSlider1->setCallbackUserData(box); + box->mSlider1->setCommitCallback(boost::bind(&LLDebugVarMessageBox::slider_changed,_1,box)); box->mSlider2->setMaxValue(max_value.mV[VX]); box->mSlider2->setMinValue(-max_value.mV[VX]); box->mSlider2->setIncrement(increment.mV[VX]); - box->mSlider2->setCommitCallback(slider_changed); - box->mSlider2->setCallbackUserData(box); + box->mSlider2->setCommitCallback(boost::bind(&LLDebugVarMessageBox::slider_changed,_1,box)); box->mSlider3->setMaxValue(max_value.mV[VX]); box->mSlider3->setMinValue(-max_value.mV[VX]); box->mSlider3->setIncrement(increment.mV[VX]); - box->mSlider3->setCommitCallback(slider_changed); - box->mSlider3->setCallbackUserData(box); + box->mSlider3->setCommitCallback(boost::bind(&LLDebugVarMessageBox::slider_changed,_1,box)); #endif } diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 97b9764ab..afe3040c4 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -2,31 +2,25 @@ * @file lldrawable.cpp * @brief LLDrawable class implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -63,6 +57,8 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f; static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); +extern bool gShiftFrame; + //////////////////////// // @@ -102,7 +98,6 @@ void LLDrawable::init() mPositionGroup.clear(); mExtents[0].clear(); mExtents[1].clear(); - mQuietCount = 0; mState = 0; mVObjp = NULL; @@ -410,6 +405,8 @@ void LLDrawable::makeActive() if (!isRoot() && !mParent->isActive()) { mParent->makeActive(); + //NOTE: linked set will now NEVER become static + mParent->setState(LLDrawable::ACTIVE_CHILD); } //all child objects must also be active @@ -427,14 +424,6 @@ void LLDrawable::makeActive() } } - if (mVObjp->getPCode() == LL_PCODE_VOLUME) - { - if (mVObjp->isFlexible()) - { - return; - } - } - if (mVObjp->getPCode() == LL_PCODE_VOLUME) { gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE); @@ -442,28 +431,22 @@ void LLDrawable::makeActive() updatePartition(); } - if (isRoot()) - { - mQuietCount = 0; - } - else - { - getParent()->mQuietCount = 0; - } + llassert(isAvatar() || isRoot() || mParent->isActive()); } void LLDrawable::makeStatic(BOOL warning_enabled) { - if (isState(ACTIVE)) + if (isState(ACTIVE) && + !isState(ACTIVE_CHILD) && + !mVObjp->isAttachment() && + !mVObjp->isFlexible()) { clearState(ACTIVE | ANIMATED_CHILD); - if (mParent.notNull() && mParent->isActive() && warning_enabled) - { - LL_WARNS_ONCE("Drawable") << "Drawable becomes static with active parent!" << LL_ENDL; - } - + //drawable became static with active parent, not acceptable + llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled); + LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) @@ -490,8 +473,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled) mSpatialBridge->markDead(); setSpatialBridge(NULL); } + updatePartition(); } - updatePartition(); } // Returns "distance" between target destination and resulting xfrom @@ -519,7 +502,6 @@ F32 LLDrawable::updateXform(BOOL undamped) //scaling LLVector3 target_scale = mVObjp->getScale(); LLVector3 old_scale = mCurrentScale; - LLVector3 dest_scale = target_scale; // Damping F32 dist_squared = 0.f; @@ -642,7 +624,7 @@ BOOL LLDrawable::updateMove() } makeActive(); - + BOOL done; if (isState(MOVE_UNDAMPED)) @@ -722,6 +704,11 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) return; } + if (gShiftFrame) + { + return; + } + //switch LOD with the spatial group to avoid artifacts //LLSpatialGroup* sg = getSpatialGroup(); @@ -820,14 +807,19 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector) mXform.setPosition(mVObjp->getPositionAgent()); } - mXform.setRotation(mVObjp->getRotation()); - mXform.setScale(1,1,1); mXform.updateMatrix(); if (isStatic()) { LLVOVolume* volume = getVOVolume(); - if (!volume) + + bool rebuild = (!volume && + getRenderType() != LLPipeline::RENDER_TYPE_TREE && + getRenderType() != LLPipeline::RENDER_TYPE_TERRAIN && + getRenderType() != LLPipeline::RENDER_TYPE_SKY && + getRenderType() != LLPipeline::RENDER_TYPE_GROUND); + + if (rebuild) { gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); } @@ -841,7 +833,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector) facep->mExtents[0].add(shift_vector); facep->mExtents[1].add(shift_vector); - if (!volume && facep->hasGeometry()) + if (rebuild && facep->hasGeometry()) { facep->clearVertexBuffer(); } @@ -960,6 +952,12 @@ LLSpatialGroup* LLDrawable::getSpatialGroup() const void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) { + //precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this + llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this)); + + //precondition: groupp MUST be null or groupp MUST contain this + llassert(!groupp || groupp->hasElement(this)); + /*if (mSpatialGroupp && (groupp != mSpatialGroupp)) { mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY); @@ -979,9 +977,12 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) } } - mSpatialGroupp = groupp; + //postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1 + //postcondition: if next group is NOT NULL, binIndex must not be -1 + llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 : + getBinIndex() != -1); - llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1); + mSpatialGroupp = groupp; } LLSpatialPartition* LLDrawable::getSpatialPartition() @@ -1224,7 +1225,6 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) LLCamera ret = camera; LLXformMatrix* mat = mDrawable->getXform(); LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix(); - LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix()); LLVector3 delta = ret.getOrigin() - center; LLQuaternion rot = ~mat->getRotation(); @@ -1416,6 +1416,11 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) return; } + if (gShiftFrame) + { + return; + } + if (mDrawable->getVObj()) { if (mDrawable->getVObj()->isAttachment()) @@ -1499,13 +1504,11 @@ void LLSpatialBridge::cleanupReferences() LLDrawable::cleanupReferences(); if (mDrawable) { - LLSpatialGroup* group = mDrawable->getSpatialGroup(); - if (group) - { - group->mOctreeNode->remove(mDrawable); - mDrawable->setSpatialGroup(NULL); - } + /* + DON'T DO THIS -- this should happen through octree destruction + + mDrawable->setSpatialGroup(NULL); if (mDrawable->getVObj()) { LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); @@ -1516,15 +1519,10 @@ void LLSpatialBridge::cleanupReferences() LLDrawable* drawable = child->mDrawable; if (drawable) { - LLSpatialGroup* group = drawable->getSpatialGroup(); - if (group) - { - group->mOctreeNode->remove(drawable); - drawable->setSpatialGroup(NULL); - } + drawable->setSpatialGroup(NULL); } } - } + }*/ LLDrawable* drawablep = mDrawable; mDrawable = NULL; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index bd2d23c5f..e2ea0140f 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -65,6 +65,7 @@ class LLViewerTexture; const U32 SILHOUETTE_HIGHLIGHT = 0; // All data for new renderer goes into this class. +LL_ALIGN_PREFIX(16) class LLDrawable : public LLRefCount { public: @@ -81,6 +82,16 @@ public: static void initClass(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLDrawable() { init(); } MEM_TYPE_NEW(LLMemType::MTYPE_DRAWABLE); @@ -287,11 +298,12 @@ public: RIGGED = 0x08000000, PARTITION_MOVE = 0x10000000, ANIMATED_CHILD = 0x20000000, + ACTIVE_CHILD = 0x40000000, } EDrawableFlags; private: //aligned members - LLVector4a mExtents[2]; - LLVector4a mPositionGroup; + LL_ALIGN_16(LLVector4a mExtents[2]); + LL_ALIGN_16(LLVector4a mPositionGroup); public: LLXformMatrix mXform; @@ -300,8 +312,6 @@ public: LLPointer mParent; F32 mDistanceWRTCamera; - - S32 mQuietCount; static S32 getCurrentFrame() { return sCurVisible; } static S32 getMinVisFrameRange(); @@ -333,7 +343,7 @@ private: static U32 sNumZombieDrawables; static LLDynamicArrayPtr > sDeadList; -}; +} LL_ALIGN_POSTFIX(16); inline LLFace* LLDrawable::getFace(const S32 i) const diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 69a3cf419..909cec540 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -2,31 +2,25 @@ * @file lldrawpool.cpp * @brief LLDrawPool class implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -257,48 +251,6 @@ void LLFacePool::dirtyTextures(const std::set& textures { } -// static -S32 LLFacePool::drawLoop(face_array_t& face_list) -{ - S32 res = 0; - if (!face_list.empty()) - { - for (std::vector::iterator iter = face_list.begin(); - iter != face_list.end(); iter++) - { - LLFace *facep = *iter; - res += facep->renderIndexed(); - } - } - return res; -} - -// static -S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage) -{ - S32 res = 0; - if (!face_list.empty()) - { - for (std::vector::iterator iter = face_list.begin(); - iter != face_list.end(); iter++) - { - LLFace *facep = *iter; - gGL.getTexUnit(stage)->bind(facep->getTexture(), TRUE); - gGL.getTexUnit(0)->activate(); - res += facep->renderIndexed(); - } - } - return res; -} - -void LLFacePool::drawLoop() -{ - if (!mDrawFace.empty()) - { - drawLoop(mDrawFace); - } -} - void LLFacePool::enqueue(LLFace* facep) { mDrawFace.push_back(facep); @@ -464,6 +416,7 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params) gGL.loadMatrix(gGLModelView); if (params.mModelMatrix) { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix); } gPipeline.mMatrixOpCount++; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 341583996..31cd72628 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -2,31 +2,25 @@ * @file lldrawpool.h * @brief LLDrawPool class definition * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -192,10 +186,6 @@ public: void buildEdges(); - static S32 drawLoop(face_array_t& face_list); - static S32 drawLoopSetTex(face_array_t& face_list, S32 stage); - void drawLoop(); - void addFaceReference(LLFace *facep); void removeFaceReference(LLFace *facep); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 865e89f89..aad2a8acb 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -205,7 +205,7 @@ void LLDrawPoolAlpha::endRenderPass( S32 pass ) LLFastTimer t(FTM_RENDER_ALPHA); LLRenderPass::endRenderPass(pass); - if(gPipeline.canUseWindLightShaders()) + if(mVertexShaderLevel > 0) { LLGLSLShader::bindNoShader(); } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index dd8b4e80c..7236c8b12 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -159,7 +159,7 @@ void LLStandardBumpmap::addstandard() gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id)); - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP) ; + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::BOOST_BUMP) ; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL ); gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0) ; LLStandardBumpmap::sStandardBumpmapCount++; @@ -1075,7 +1075,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText src_image->getHeight() != bump->getHeight())// || //(LLPipeline::sRenderDeferred && bump->getComponents() != 4)) { - src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ; + src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ; src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL ); src_image->forceToSaveRawImage(0) ; } @@ -1572,16 +1572,21 @@ void LLDrawPoolInvisible::render(S32 pass) gOcclusionProgram.unbind(); } - if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + /*if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) // invisible (deprecated) { beginShiny(true); renderShiny(true); endShiny(true); - } + }*/ } void LLDrawPoolInvisible::beginDeferredPass(S32 pass) { + static const LLCachedControl enable("SianaRenderDeferredInvisiprim"); + if (!enable) + { + return; + } beginRenderPass(pass); } @@ -1593,7 +1598,8 @@ void LLDrawPoolInvisible::endDeferredPass( S32 pass ) void LLDrawPoolInvisible::renderDeferred( S32 pass ) { //render invisiprims; this doesn't work becaue it also blocks all the post-deferred stuff static const LLCachedControl enable("SianaRenderDeferredInvisiprim"); - if (!enable) { + if (!enable) + { return; } @@ -1610,10 +1616,10 @@ void LLDrawPoolInvisible::renderDeferred( S32 pass ) gOcclusionProgram.unbind(); - if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + /*if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) // invisible (deprecated) { beginShiny(true); renderShiny(true); endShiny(true); - } + }*/ } diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 6e0ea78af..4bc06580f 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -351,16 +351,20 @@ void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) void LLDrawPoolFullbright::renderPostDeferred(S32 pass) { LLFastTimer t(FTM_RENDER_FULLBRIGHT); - + gGL.setColorMask(true, true); gGL.setSceneBlendType(LLRender::BT_ALPHA); + U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); + + gGL.setColorMask(true, false); } void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) { gDeferredFullbrightProgram.unbind(); LLRenderPass::endRenderPass(pass); + } void LLDrawPoolFullbright::beginRenderPass(S32 pass) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index b98cc84e8..dc48a4e29 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -75,7 +75,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga", - TRUE, LLViewerTexture::BOOST_UI, + TRUE, LLGLTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, format, int_format, LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb")); @@ -84,7 +84,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c", - TRUE, LLViewerTexture::BOOST_UI, + TRUE, LLGLTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, format, int_format, LLUUID("38b86f85-2575-52a9-a531-23108d8da837")); @@ -92,7 +92,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : //gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - mTexturep->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); + mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN); //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -177,7 +177,7 @@ void LLDrawPoolTerrain::render(S32 pass) LLVLComposition *compp = regionp->getComposition(); for (S32 i = 0; i < 4; i++) { - compp->mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); + compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area } @@ -302,6 +302,35 @@ void LLDrawPoolTerrain::renderShadow(S32 pass) //glCullFace(GL_BACK); } + +void LLDrawPoolTerrain::drawLoop() +{ + if (!mDrawFace.empty()) + { + for (std::vector::iterator iter = mDrawFace.begin(); + iter != mDrawFace.end(); iter++) + { + LLFace *facep = *iter; + + LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix); + + if (model_matrix != gGLLastMatrix) + { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); + gGLLastMatrix = model_matrix; + gGL.loadMatrix(gGLModelView); + if (model_matrix) + { + gGL.multMatrix((GLfloat*) model_matrix->mMatrix); + } + gPipeline.mMatrixOpCount++; + } + + facep->renderIndexed(); + } + } +} + void LLDrawPoolTerrain::renderFullShader() { // Hack! Get the region that this draw pool is rendering from! @@ -765,6 +794,7 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.loadIdentity(); gGL.translatef(-2.f, 0.f, 0.f); gGL.matrixMode(LLRender::MM_MODELVIEW); + // Care about alpha only gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 24ed06500..a9fb48bac 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -89,6 +89,7 @@ protected: void renderFull2TU(); void renderFull4TU(); void renderFullShader(); + void drawLoop(); }; #endif // LL_LLDRAWPOOLSIMPLE_H diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 9500f5aff..d2faca835 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -43,6 +43,7 @@ #include "llviewershadermgr.h" #include "llrender.h" #include "llviewercontrol.h" +#include "llviewerregion.h" S32 LLDrawPoolTree::sDiffTex = 0; static LLGLSLShader* shader = NULL; @@ -116,8 +117,23 @@ void LLDrawPoolTree::render(S32 pass) { LLFace *face = *iter; LLVertexBuffer* buff = face->getVertexBuffer(); + if(buff) { + LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix); + + if (model_matrix != gGLLastMatrix) + { + gGLLastMatrix = model_matrix; + gGL.loadMatrix(gGLModelView); + if (model_matrix) + { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); + gGL.multMatrix((GLfloat*) model_matrix->mMatrix); + } + gPipeline.mMatrixOpCount++; + } + buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); gPipeline.addTrianglesDrawn(buff->getNumIndices()); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 371f979a0..2154c0495 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -53,6 +53,8 @@ #include "pipeline.h" #include "llviewershadermgr.h" #include "llwaterparammanager.h" +#include "llappviewer.h" +#include "lltexturecache.h" const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004"); const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055"); @@ -72,11 +74,11 @@ LLVector3 LLDrawPoolWater::sLightDir; LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER) { - mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI); + mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLGLTexture::BOOST_UI); gGL.getTexUnit(0)->bind(mHBTex[0]) ; mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP); - mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI); + mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLGLTexture::BOOST_UI); gGL.getTexUnit(0)->bind(mHBTex[1]); mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -235,7 +237,10 @@ void LLDrawPoolWater::render(S32 pass) glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); // Slowly move over time. - F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f); + static const LLCachedControl freeze_time("FreezeTime",false); + static F32 frame_time; + if (!freeze_time) frame_time = gFrameTimeSeconds; + F32 offset = fmod(frame_time*2.f, 100.f); F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f}; F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f}; glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); @@ -260,8 +265,11 @@ void LLDrawPoolWater::render(S32 pass) { continue; } - gGL.getTexUnit(0)->bind(face->getTexture()); - face->renderIndexed(); + if(face->getTexture() && face->getTexture()->hasGLTexture()) + { + gGL.getTexUnit(0)->bind(face->getTexture()); + face->renderIndexed(); + } } // Now, disable texture coord generation on texture state 1 @@ -367,6 +375,32 @@ void LLDrawPoolWater::renderOpaqueLegacyWater() gPipeline.disableLights(); + //Singu note: This is a hack around bizarre opensim behavior. The opaque water texture we get is pure white and only has one channel. + // This behavior is clearly incorrect, so we try to detect that case, purge it from the cache, and try to re-fetch the texture. + // If the re-fetched texture is still invalid, or doesn't exist, we use transparent water, which is fine since alphablend is unset. + // The current logic for refetching is crude here, and probably wont work if, say, a prim were to also have the texture for some reason, + // however it works well enough otherwise, and is much cleaner than diving into LLTextureList, LLViewerFetchedTexture, and LLViewerTexture. + // Perhaps a proper reload mechanism could be done if we ever add user-level texture reloading, but until then it's not a huge priority. + // Failing to fully refetch will just give us the same invalid texture we started with, which will result in the fallback texture being used. + if(mOpaqueWaterImagep != mWaterImagep) + { + if(mOpaqueWaterImagep->isMissingAsset()) + { + mOpaqueWaterImagep = mWaterImagep; + } + else if(mOpaqueWaterImagep->hasGLTexture() && mOpaqueWaterImagep->getComponents() < 3) + { + LLAppViewer::getTextureCache()->removeFromCache(mOpaqueWaterImagep->getID()); + static bool sRefetch = true; + if(sRefetch) + { + sRefetch = false; + ((LLViewerFetchedTexture*)mOpaqueWaterImagep.get())->forceRefetch(); + } + else + mOpaqueWaterImagep = mWaterImagep; + } + } mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); // Activate the texture binding and bind one @@ -380,18 +414,21 @@ void LLDrawPoolWater::renderOpaqueLegacyWater() { glEnable(GL_TEXTURE_GEN_S); //texture unit 0 glEnable(GL_TEXTURE_GEN_T); //texture unit 0 - glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); } // Use the fact that we know all water faces are the same size // to save some computation - // Slowly move texture coordinates over time so the watter appears + // Slowly move texture coordinates over time so the water appears // to be moving. F32 movement_period_secs = 50.f; - F32 offset = fmod(gFrameTimeSeconds, movement_period_secs); + static const LLCachedControl freeze_time("FreezeTime",false); + static F32 frame_time; + if (!freeze_time) frame_time = gFrameTimeSeconds; + F32 offset = fmod(frame_time, movement_period_secs); if (movement_period_secs != 0) { @@ -549,7 +586,11 @@ void LLDrawPoolWater::shade() shader->bind(); } - sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; + static const LLCachedControl freeze_time("FreezeTime",false); + if (!freeze_time) + { + sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; + } S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX); @@ -674,7 +715,7 @@ void LLDrawPoolWater::shade() } LLVOWater* water = (LLVOWater*) face->getViewerObject(); - if(diffTex > -1 && face->getTexture()->hasGLTexture()) + if(diffTex > -1 && face->getTexture() && face->getTexture()->hasGLTexture()) gGL.getTexUnit(diffTex)->bind(face->getTexture()); sNeedsReflectionUpdate = TRUE; diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index df9895906..d119f247f 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -54,7 +54,7 @@ LLPointer LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; static LLGLSLShader* cloud_shader = NULL; static LLGLSLShader* sky_shader = NULL; - +static LLGLSLShader* star_shader = NULL; LLDrawPoolWLSky::LLDrawPoolWLSky(void) : LLDrawPool(POOL_WL_SKY) @@ -113,6 +113,8 @@ void LLDrawPoolWLSky::beginRenderPass( S32 pass ) LLPipeline::sUnderWaterRender ? &gObjectFullbrightNoColorWaterProgram : &gWLCloudProgram; + + star_shader = &gCustomAlphaProgram; } void LLDrawPoolWLSky::endRenderPass( S32 pass ) @@ -123,6 +125,7 @@ void LLDrawPoolWLSky::beginDeferredPass(S32 pass) { sky_shader = &gDeferredWLSkyProgram; cloud_shader = &gDeferredWLCloudProgram; + star_shader = &gDeferredStarProgram; } void LLDrawPoolWLSky::endDeferredPass(S32 pass) @@ -182,6 +185,15 @@ void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const void LLDrawPoolWLSky::renderStars(void) const { + // *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid + // clamping and allow the star_alpha param to brighten the stars. + bool error; + LLColor4 star_alpha(LLColor4::black); + star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f; + llassert_always(!error); + if(star_alpha.mV[3] <= 0) + return; + LLGLSPipelineSkyBox gls_sky; LLGLEnable blend(GL_BLEND); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -198,26 +210,16 @@ void LLDrawPoolWLSky::renderStars(void) const glPointSize(2.f); }*/ - // *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid - // clamping and allow the star_alpha param to brighten the stars. - bool error; - LLColor4 star_alpha(LLColor4::black); - star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f; - llassert_always(!error); - + gGL.pushMatrix(); + gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f); // gl_FragColor.rgb = gl_Color.rgb; // gl_FragColor.a = gl_Color.a * star_alpha.a; //New gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex()); - gGL.pushMatrix(); - gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f); - // gl_FragColor.rgb = gl_Color.rgb; - // gl_FragColor.a = gl_Color.a * star_alpha.a; - if (LLGLSLShader::sNoFixedFunction) + if (gPipeline.canUseVertexShaders()) { - gCustomAlphaProgram.bind(); - gCustomAlphaProgram.uniform1f("custom_alpha", star_alpha.mV[3]); + star_shader->uniform1f("custom_alpha", star_alpha.mV[3]); } else { @@ -230,11 +232,7 @@ void LLDrawPoolWLSky::renderStars(void) const gGL.popMatrix(); - if (LLGLSLShader::sNoFixedFunction) - { - gCustomAlphaProgram.unbind(); - } - else + if (!gPipeline.canUseVertexShaders()) { // and disable the combiner states gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); @@ -261,8 +259,15 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const void LLDrawPoolWLSky::renderHeavenlyBodies() { + LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor(), gSky.mVOSkyp->getMoon().getDirection().mV[2]); + if (color.mV[VW] <= 0.f) + return; + + color.mV[VW] = llclamp(color.mV[VW]*color.mV[VW]*4.f,0.f,1.f); + LLGLSPipelineSkyBox gls_skybox; LLGLEnable blend_on(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ALPHA); gPipeline.disableLights(); #if 0 // when we want to re-add a texture sun disc, here's where to do it. @@ -279,33 +284,31 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]; - if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount()) + if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount() && face->getVertexBuffer()) { // *NOTE: even though we already bound this texture above for the // stars register combiners, we bind again here for defensive reasons, // since LLImageGL::bind detects that it's a noop, and optimizes it out. gGL.getTexUnit(0)->bind(face->getTexture()); - LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor()); - F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2]; - if (a > 0.f) - { - a = a*a*4.f; - } - - color.mV[3] = llclamp(a, 0.f, 1.f); if (gPipeline.canUseVertexShaders()) { - gHighlightProgram.bind(); + // Okay, so the moon isn't a star, but it's close enough. + star_shader->uniform1f("custom_alpha", color.mV[VW]); + } + else + { + gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR); + gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_CONST_ALPHA, LLTexUnit::TBS_TEX_ALPHA); + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color.mV); } - LLFacePool::LLOverrideFaceColor color_override(this, color); + face->getVertexBuffer()->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK); + face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getVertexBuffer()->getNumIndices(), 0); - face->renderIndexed(); - - if (gPipeline.canUseVertexShaders()) + if (!gPipeline.canUseVertexShaders()) { - gHighlightProgram.unbind(); + gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); } } } @@ -324,7 +327,7 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) LLGLDepthTest depth(GL_TRUE, GL_FALSE); LLGLDisable clip(GL_CLIP_PLANE0); - gGL.setColorMask(true, false); + gGL.setColorMask(true, false); //Just in case. LLGLSquashToFarClip far_clip(glh_get_current_projection()); @@ -336,7 +339,7 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); - gDeferredStarProgram.bind(); + star_shader->bind(); // *NOTE: have to bind a texture here since register combiners blending in // renderStars() requires something to be bound and we might as well only // bind the moon's texture once. @@ -346,13 +349,12 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) renderStars(); - gDeferredStarProgram.unbind(); + star_shader->unbind(); gGL.popMatrix(); renderSkyClouds(camHeightLocal); - gGL.setColorMask(true, true); //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -373,6 +375,8 @@ void LLDrawPoolWLSky::render(S32 pass) LLGLSquashToFarClip far_clip(glh_get_current_projection()); + gGL.setColorMask(true, false); //Just in case. + renderSkyHaze(camHeightLocal); LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); @@ -380,6 +384,8 @@ void LLDrawPoolWLSky::render(S32 pass) gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); + if(gPipeline.canUseVertexShaders()) + star_shader->bind(); // *NOTE: have to bind a texture here since register combiners blending in // renderStars() requires something to be bound and we might as well only // bind the moon's texture once. @@ -388,6 +394,9 @@ void LLDrawPoolWLSky::render(S32 pass) renderHeavenlyBodies(); renderStars(); + + if(gPipeline.canUseVertexShaders()) + star_shader->unbind(); gGL.popMatrix(); diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index 398a41cef..603a73ce6 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -36,6 +36,16 @@ class LLViewerDynamicTexture : public LLViewerTexture { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + enum { LL_VIEWER_DYNAMIC_TEXTURE = LLViewerTexture::DYNAMIC_TEXTURE, @@ -62,8 +72,8 @@ public: /*virtual*/ S8 getType() const ; - S32 getOriginX() { return mOrigin.mX; } - S32 getOriginY() { return mOrigin.mY; } + S32 getOriginX() const { return mOrigin.mX; } + S32 getOriginY() const { return mOrigin.mY; } S32 getSize() { return mFullWidth * mFullHeight * mComponents; } @@ -85,7 +95,7 @@ protected: protected: BOOL mClamp; LLCoordGL mOrigin; - LLCamera mCamera; + LL_ALIGN_16(LLCamera mCamera); typedef std::set instance_list_t; static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp index 7e5377bd1..3033d4e07 100644 --- a/indra/newview/llenvmanager.cpp +++ b/indra/newview/llenvmanager.cpp @@ -47,6 +47,8 @@ #include "rlvhandler.h" // [/RLVa:KB] +#include "hippogridmanager.h" + std::string LLEnvPrefs::getWaterPresetName() const { if (mWaterPresetName.empty()) @@ -509,7 +511,8 @@ void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content) mRegionSettingsChangeSignal(); // reset - mInterpNextChangeMessage = false; + if (!gHippoGridManager->getConnectedGrid()->isAurora()) // On Aurora, the region says when to refresh + mInterpNextChangeMessage = false; } void LLEnvManagerNew::onRegionSettingsApplyResponse(bool ok) @@ -698,3 +701,36 @@ void LLEnvManagerNew::onRegionChange(bool interpolate) // Let interested parties know agent region has been changed. mRegionChangeSignal(); } + +// Aurora-sim windlight refresh +class WindLightRefresh : public LLHTTPNode +{ + /*virtual*/ void post(LLHTTPNode::ResponsePtr response, const LLSD& context, const LLSD& input) const + { + if (!input || !context || !input.isMap() || !input.has("body")) + { + llinfos << "malformed WindLightRefresh!" << llendl; + return; + } + + //std::string dump = input["body"].asString(); + //llwarns << dump << llendl; + + LLSD body = input["body"]; + LLEnvManagerNew *env = &LLEnvManagerNew::instance(); + + LLViewerRegion* regionp = gAgent.getRegion(); + LLUUID region_uuid = regionp ? regionp->getRegionID() : LLUUID::null; + + env->mNewRegionPrefs.clear(); + env->mCurRegionUUID = region_uuid; + + env->mInterpNextChangeMessage = !body.has("Interpolate") || body["Interpolate"].asInteger() == 1; + + llinfos << "Windlight Refresh, interpolate:" << env->mInterpNextChangeMessage << llendl; + env->requestRegionSettings(); + env->mRegionChangeSignal(); + } +}; + +LLHTTPRegistration gHTTPRegistrationWindLightRefresh("/message/WindLightRefresh"); diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h index ad7550aff..8d5317996 100644 --- a/indra/newview/llenvmanager.h +++ b/indra/newview/llenvmanager.h @@ -35,11 +35,11 @@ #include "llmemory.h" #include "llsd.h" -#include class LLWLParamManager; class LLWaterParamManager; class LLWLAnimator; +class WindLightRefresh; // generic key struct LLEnvKey @@ -257,6 +257,7 @@ public: bool useRegionWater(); private: + friend class WindLightRefresh; bool useDefaultSky(); bool useDefaultWater(); diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index 6548d520b..3efc942da 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -73,9 +73,10 @@ namespace void handleMessage(const LLSD& content); - virtual void error(U32 status, const std::string& reason); - virtual void result(const LLSD& content); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return eventPollResponder_timeout; } + /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ void result(const LLSD& content); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return eventPollResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLEventPollResponder"; } private: diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index c42846b6f..0092f5277 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -563,8 +563,8 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) /* removed in lieu of raycast uv detection void LLFace::renderSelectedUV() { - LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLViewerTexture::BOOST_UI); - LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLViewerTexture::BOOST_UI); + LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLGLTexture::BOOST_UI); + LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLGLTexture::BOOST_UI); LLGLSUVSelect object_select; @@ -1374,7 +1374,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, static LLCachedControl use_transform_feedback("RenderUseTransformFeedback", false); -#if 0//#ifdef GL_TRANSFORM_FEEDBACK_BUFFER +#ifdef GL_TRANSFORM_FEEDBACK_BUFFER if (use_transform_feedback && gTransformPositionProgram.mProgramObject && //transform shaders are loaded mVertexBuffer->useVBOs() && //target buffer is in VRAM @@ -1639,7 +1639,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (!do_xform) { LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM); - LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); + S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, tc_size); } else { diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 4cab49205..b59dff8f0 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -64,6 +64,17 @@ class LLFace { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + + LLFace(const LLFace& rhs) { *this = rhs; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 9f1cbca6c..22539595e 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -971,7 +971,7 @@ void LLFastTimerView::draw() gGL.color4f(col[0], col[1], col[2], alpha); gGL.begin(LLRender::TRIANGLE_STRIP); for (U32 j = llmax(0, LLFastTimer::NamedTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex()); - j < LLFastTimer::NamedTimer::HISTORY_NUM; + j < (U32)LLFastTimer::NamedTimer::HISTORY_NUM; j++) { U64 ticks = idp->getHistoricalCount(j); diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 8b0fd109f..a8d36867b 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -44,6 +44,8 @@ #include "llvoavatar.h" /*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f; +std::vector LLVolumeImplFlexible::sInstanceList; +std::vector LLVolumeImplFlexible::sUpdateDelay; static LLFastTimer::DeclareTimer FTM_FLEXIBLE_REBUILD("Rebuild"); static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Update"); @@ -70,8 +72,44 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD { mVO->mDrawable->makeActive() ; } + + mInstanceIndex = sInstanceList.size(); + sInstanceList.push_back(this); + sUpdateDelay.push_back(0); }//----------------------------------------------- +LLVolumeImplFlexible::~LLVolumeImplFlexible() +{ + S32 end_idx = sInstanceList.size()-1; + + if (end_idx != mInstanceIndex) + { + sInstanceList[mInstanceIndex] = sInstanceList[end_idx]; + sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex; + sUpdateDelay[mInstanceIndex] = sUpdateDelay[end_idx]; + } + + sInstanceList.pop_back(); + sUpdateDelay.pop_back(); +} + +//static +void LLVolumeImplFlexible::updateClass() +{ + std::vector::iterator delay_iter = sUpdateDelay.begin(); + + for (std::vector::iterator iter = sInstanceList.begin(); + iter != sInstanceList.end(); + ++iter) + { + if(!*delay_iter || !--*delay_iter) + { + (*iter)->doIdleUpdate(); + } + ++delay_iter; + } +} + LLVector3 LLVolumeImplFlexible::getFramePosition() const { return mVO->getRenderPosition(); @@ -231,9 +269,6 @@ void LLVolumeImplFlexible::setAttributesOfAllSections(LLVector3* inScale) mSection[0].mVelocity.setVec(0,0,0); mSection[0].mAxisRotation.setQuat(begin_rot,0,0,1); - LLVector3 parentSectionPosition = mSection[0].mPosition; - LLVector3 last_direction = mSection[0].mDirection; - remapSections(mSection, mInitializedRes, mSection, mSimulateRes); mInitializedRes = mSimulateRes; @@ -296,22 +331,17 @@ void LLVolumeImplFlexible::updateRenderRes() // optimization similar to what Havok does for objects that are stationary. //--------------------------------------------------------------------------------- static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies"); -void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVolumeImplFlexible::doIdleUpdate() { LLDrawable* drawablep = mVO->mDrawable; if (drawablep) { //LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); - - //flexible objects never go static - drawablep->mQuietCount = 0; - if (!drawablep->isRoot()) - { - LLViewerObject* parent = (LLViewerObject*) mVO->getParent(); - parent->mDrawable->mQuietCount = 0; - } - + + //ensure drawable is active + drawablep->makeActive(); + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) { bool visible = drawablep->isVisible(); @@ -321,32 +351,46 @@ void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 updateRenderRes(); gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); } - else if (visible && - !drawablep->isState(LLDrawable::IN_REBUILD_Q1) && - mVO->getPixelArea() > 256.f) + else { - U32 id; F32 pixel_area = mVO->getPixelArea(); - if (mVO->isRootEdit()) + U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1; + update_period = llclamp(update_period,1U,(U32)llmax((U32)llceil(gFPSClamped*2.f),32U)); + + if (visible) { - id = mID; + if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1) && + mVO->getPixelArea() > 256.f) + { + U32 id; + + if (mVO->isRootEdit()) + { + id = mID; + } + else + { + LLVOVolume* parent = (LLVOVolume*) mVO->getParent(); + id = parent->getVolumeInterfaceID(); + } + + if ((LLDrawable::getCurrentFrame()+id)%update_period == 0) + { + sUpdateDelay[mInstanceIndex] = update_period-1; + + updateRenderRes(); + + gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); + } + } } else { - LLVOVolume* parent = (LLVOVolume*) mVO->getParent(); - id = parent->getVolumeInterfaceID(); - } - - U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1; - - if ((LLDrawable::getCurrentFrame()+id)%update_period == 0) - { - updateRenderRes(); - gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); + sUpdateDelay[mInstanceIndex] = update_period; } } - } + } if(!mInitialized) updateRenderRes(); } @@ -372,7 +416,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate() { BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE; - doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0); + doIdleUpdate(); if (!force_update || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) { @@ -385,6 +429,15 @@ void LLVolumeImplFlexible::doFlexibleUpdate() //the object is not visible return ; } + + // stinson 11/12/2012: Need to check with davep on the following. + // Skipping the flexible update if render res is negative. If we were to continue with a negative value, + // the subsequent S32 num_render_sections = 1< sInstanceList; + static std::vector sUpdateDelay; + S32 mInstanceIndex; + public: + static void resetTimers() { sUpdateDelay.assign(sUpdateDelay.size(),0); } + static void updateClass(); + LLVolumeImplFlexible(LLViewerObject* volume, LLFlexibleObjectData* attributes); + ~LLVolumeImplFlexible(); // Implements LLVolumeInterface U32 getID() const { return mID; } @@ -85,7 +88,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface LLQuaternion getFrameRotation() const; LLVolumeInterfaceType getInterfaceType() const { return INTERFACE_FLEXIBLE; } void updateRenderRes(); - void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + void doIdleUpdate(); BOOL doUpdateGeometry(LLDrawable *drawable); LLVector3 getPivotPosition() const; void onSetVolume(const LLVolumeParams &volume_params, const S32 detail); diff --git a/indra/newview/llfloateractivespeakers.cpp b/indra/newview/llfloateractivespeakers.cpp index 9aa5a7adf..26cdb0752 100644 --- a/indra/newview/llfloateractivespeakers.cpp +++ b/indra/newview/llfloateractivespeakers.cpp @@ -70,6 +70,8 @@ const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f); const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f); const F32 TYPING_ANIMATION_FPS = 2.5f; +static void on_avatar_name_lookup(const LLUUID&, const LLAvatarName& avatar_name, std::string& mDisplayName); + LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerType type) : mStatus(LLSpeaker::STATUS_TEXT_ONLY), mLastSpokeTime(0.f), @@ -102,41 +104,22 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy void LLSpeaker::lookupName() { - // [Ansariel: Display name support] - LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onAvatarNameLookup, _1, _2, new LLHandle(getHandle()))); - // [/Ansariel: Display name support] + LLAvatarNameCache::get(mID, boost::bind(&on_avatar_name_lookup, _1, _2, boost::ref(mDisplayName))); + + // Also set the legacy name. We will need it to initiate a new + // IM session. + gCacheName->getFullName(mID, mLegacyName); + mLegacyName = LLCacheName::cleanFullName(mLegacyName); } -//static -// [Ansariel: Display name support] -void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data) -// [/Ansariel: Display name support] +static void on_avatar_name_lookup(const LLUUID&, const LLAvatarName& avatar_name, std::string& mDisplayName) { - LLSpeaker* speaker_ptr = ((LLHandle*)user_data)->get(); - delete (LLHandle*)user_data; - - if (speaker_ptr) - { - // [Ansariel: Display name support] - switch (gSavedSettings.getS32("PhoenixNameSystem")) - { - case 0 : speaker_ptr->mDisplayName = avatar_name.getLegacyName(); break; - case 1 : speaker_ptr->mDisplayName = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : speaker_ptr->mDisplayName = avatar_name.mDisplayName; break; - default : speaker_ptr->mDisplayName = avatar_name.getLegacyName(); break; - } - - // Also set the legacy name. We will need it to initiate a new - // IM session. - speaker_ptr->mLegacyName = LLCacheName::cleanFullName(avatar_name.getLegacyName()); - // [/Ansariel: Display name support] - + LLAvatarNameCache::getPNSName(avatar_name, mDisplayName); // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g - // TODO-RLVa: this seems to get called per frame which is very likely an LL bug that will eventuall get fixed - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - speaker_ptr->mDisplayName = RlvStrings::getAnonym(speaker_ptr->mDisplayName); + // TODO-RLVa: this seems to get called per frame which is very likely an LL bug that will eventually get fixed + if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) + mDisplayName = RlvStrings::getAnonym(mDisplayName); // [/RLVa:KB] - } } LLSpeakerTextModerationEvent::LLSpeakerTextModerationEvent(LLSpeaker* source) @@ -333,10 +316,10 @@ BOOL LLPanelActiveSpeakers::postBuild() mSpeakerList = getChild("speakers_list"); mSpeakerList->sortByColumn(sort_column, sort_ascending); - mSpeakerList->setDoubleClickCallback(onDoubleClickSpeaker); + mSpeakerList->setDoubleClickCallback(boost::bind(&onDoubleClickSpeaker,this)); mSpeakerList->setCommitOnSelectionChange(TRUE); - mSpeakerList->setCommitCallback(onSelectSpeaker); - mSpeakerList->setSortChangedCallback(onSortChanged); + mSpeakerList->setCommitCallback(boost::bind(&LLPanelActiveSpeakers::handleSpeakerSelect,this)); + mSpeakerList->setSortChangedCallback(boost::bind(&LLPanelActiveSpeakers::onSortChanged,this)); mSpeakerList->setCallbackUserData(this); mMuteTextCtrl = getChild("mute_text_btn"); @@ -610,7 +593,7 @@ void LLPanelActiveSpeakers::refreshSpeakers() } // we potentially modified the sort order by touching the list items - mSpeakerList->setSorted(FALSE); + mSpeakerList->setNeedsSort(); LLPointer selected_speakerp = mSpeakerMgr->findSpeaker(selected_id); // update UI for selected participant @@ -813,14 +796,6 @@ void LLPanelActiveSpeakers::onDoubleClickSpeaker(void* user_data) } } -//static -void LLPanelActiveSpeakers::onSelectSpeaker(LLUICtrl* source, void* user_data) -{ - LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data; - panelp->handleSpeakerSelect(); -} - - //static void LLPanelActiveSpeakers::onSortChanged(void* user_data) { @@ -857,7 +832,7 @@ void LLPanelActiveSpeakers::onModeratorMuteVoice(LLUICtrl* ctrl, void* user_data mSessionID = session_id; } - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { llwarns << status << ": " << reason << llendl; @@ -887,7 +862,8 @@ void LLPanelActiveSpeakers::onModeratorMuteVoice(LLUICtrl* ctrl, void* user_data } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return muteVoiceResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return muteVoiceResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "MuteVoiceResponder"; } private: LLUUID mSessionID; @@ -924,7 +900,7 @@ void LLPanelActiveSpeakers::onModeratorMuteText(LLUICtrl* ctrl, void* user_data) mSessionID = session_id; } - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { llwarns << status << ": " << reason << llendl; @@ -954,7 +930,8 @@ void LLPanelActiveSpeakers::onModeratorMuteText(LLUICtrl* ctrl, void* user_data) } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return muteTextResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return muteTextResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "MuteTextResponder"; } private: LLUUID mSessionID; @@ -992,11 +969,12 @@ void LLPanelActiveSpeakers::onChangeModerationMode(LLUICtrl* ctrl, void* user_da struct ModerationModeResponder : public LLHTTPClient::ResponderIgnoreBody { - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { llwarns << status << ": " << reason << llendl; } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return moderationModeResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return moderationModeResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "ModerationModeResponder"; } }; LLHTTPClient::post(url, data, new ModerationModeResponder()); diff --git a/indra/newview/llfloateractivespeakers.h b/indra/newview/llfloateractivespeakers.h index b8a9ece01..757c00bc7 100644 --- a/indra/newview/llfloateractivespeakers.h +++ b/indra/newview/llfloateractivespeakers.h @@ -77,11 +77,6 @@ public: ~LLSpeaker() {}; void lookupName(); - // [Ansariel: Display name support] - //static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data); - static void onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data); - // [/Ansariel: Display name support] - ESpeakerStatus mStatus; // current activity status in speech group F32 mLastSpokeTime; // timestamp when this speaker last spoke F32 mSpeechVolume; // current speech amplitude (timea average rms amplitude?) @@ -232,7 +227,6 @@ public: static void onVolumeChange(LLUICtrl* source, void* user_data); static void onClickProfile(void* user_data); static void onDoubleClickSpeaker(void* user_data); - static void onSelectSpeaker(LLUICtrl* source, void* user_data); static void onSortChanged(void* user_data); static void onModeratorMuteVoice(LLUICtrl* ctrl, void* user_data); static void onModeratorMuteText(LLUICtrl* ctrl, void* user_data); diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index 52eee0eb8..6aa573ba8 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -1547,12 +1547,12 @@ BOOL LLPreviewAnimation::render() gGL.flush(); - LLVector3 target_pos = avatarp->mRoot.getWorldPosition(); + LLVector3 target_pos = avatarp->mRoot->getWorldPosition(); LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * LLQuaternion(mCameraYaw, LLVector3::z_axis); - LLQuaternion av_rot = avatarp->mRoot.getWorldRotation() * camera_rot; + LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot; LLViewerCamera::getInstance()->setOriginAndLookAt( target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera LLVector3::z_axis, // up diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp index c4121fae9..37ebd6f16 100644 --- a/indra/newview/llfloaterauction.cpp +++ b/indra/newview/llfloaterauction.cpp @@ -180,7 +180,7 @@ void LLFloaterAuction::onClickSnapshot(void* data) BOOL success = gViewerWindow->rawSnapshot(raw, gViewerWindow->getWindowWidth(), gViewerWindow->getWindowHeight(), - TRUE, FALSE, + (F32)gViewerWindow->getWindowWidth() / gViewerWindow->getWindowHeight(), FALSE, FALSE); gForceRenderLandFence = FALSE; diff --git a/indra/newview/llfloateravatarinfo.cpp b/indra/newview/llfloateravatarinfo.cpp index f60e24623..224099794 100644 --- a/indra/newview/llfloateravatarinfo.cpp +++ b/indra/newview/llfloateravatarinfo.cpp @@ -294,13 +294,3 @@ LLPreview::EAssetStatus LLFloaterAvatarInfo::getAssetStatus() } return mAssetStatus; } - -std::string getProfileURL(const std::string& agent_name) -{ - std::string url = gSavedSettings.getString("WebProfileURL"); - LLSD subs; - subs["AGENT_NAME"] = agent_name; - url = LLWeb::expandURLSubstitutions(url,subs); - LLStringUtil::toLower(url); - return url; -} diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index c214f3480..92a80a517 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -52,7 +52,9 @@ #include #include - +#include +#include +#include #include "llworld.h" #include "llsdutil.h" @@ -79,20 +81,25 @@ typedef enum e_radar_alert_type ALERT_TYPE_DRAW = 2, ALERT_TYPE_SHOUTRANGE = 4, ALERT_TYPE_CHATRANGE = 8, + ALERT_TYPE_AGE = 16, } ERadarAlertType; +namespace +{ void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool entering) { + if(gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) return; //RLVa:LF Don't announce people are around when blind, that cheats the system. static LLCachedControl radar_chat_alerts(gSavedSettings, "RadarChatAlerts"); if (!radar_chat_alerts) return; static LLCachedControl radar_alert_sim(gSavedSettings, "RadarAlertSim"); static LLCachedControl radar_alert_draw(gSavedSettings, "RadarAlertDraw"); static LLCachedControl radar_alert_shout_range(gSavedSettings, "RadarAlertShoutRange"); static LLCachedControl radar_alert_chat_range(gSavedSettings, "RadarAlertChatRange"); - static LLCachedControl radar_chat_keys(gSavedSettings, "RadarChatKeys"); + static LLCachedControl radar_alert_age(gSavedSettings, "RadarAlertAge"); LLFloaterAvatarList* self = LLFloaterAvatarList::getInstance(); LLStringUtil::format_map_t args; + args["[NAME]"] = name; switch(type) { case ALERT_TYPE_SIM: @@ -122,10 +129,21 @@ void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool args["[RANGE]"] = self->getString("chat_range"); } break; + + case ALERT_TYPE_AGE: + if (radar_alert_age) + { + LLChat chat; + chat.mFromName = name; + chat.mText = name + " " + self->getString("has_triggered_your_avatar_age_alert") + "."; + chat.mURL = llformat("secondlife:///app/agent/%s/about",key.asString().c_str()); + chat.mSourceType = CHAT_SOURCE_SYSTEM; + LLFloaterChat::addChat(chat); + } + break; } if (args.find("[RANGE]") != args.end()) { - args["[NAME]"] = name; args["[ACTION]"] = self->getString(entering ? "has_entered" : "has_left"); LLChat chat; chat.mText = self->getString("template", args); @@ -136,12 +154,57 @@ void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool } } + void send_keys_message(const int transact_num, const int num_ids, const std::string ids) + { + gMessageSystem->newMessage("ScriptDialogReply"); + gMessageSystem->nextBlock("AgentData"); + gMessageSystem->addUUID("AgentID", gAgent.getID()); + gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); + gMessageSystem->nextBlock("Data"); + gMessageSystem->addUUID("ObjectID", gAgent.getID()); + gMessageSystem->addS32("ChatChannel", -777777777); + gMessageSystem->addS32("ButtonIndex", 1); + gMessageSystem->addString("ButtonLabel", llformat("%d,%d", transact_num, num_ids) + ids); + gAgent.sendReliableMessage(); + } +} //namespace + LLAvatarListEntry::LLAvatarListEntry(const LLUUID& id, const std::string &name, const LLVector3d &position) : - mID(id), mName(name), mPosition(position), mDrawPosition(), mMarked(FALSE), mFocused(FALSE), + mID(id), mName(name), mPosition(position), mDrawPosition(), mMarked(false), mFocused(false), mUpdateTimer(), mFrame(gFrameCount), mInSimFrame(U32_MAX), mInDrawFrame(U32_MAX), mInChatFrame(U32_MAX), mInShoutFrame(U32_MAX), - mActivityType(ACTIVITY_NEW), mActivityTimer() + mActivityType(ACTIVITY_NEW), mActivityTimer(), + mIsInList(false), mAge(-1), mAgeAlert(false), mTime(time(NULL)) { + if (mID.notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->addObserver(mID, this); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(mID); + } +} + +LLAvatarListEntry::~LLAvatarListEntry() +{ + if (mID.notNull()) + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mID, this); +} + +// virtual +void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) +{ + if(type == APT_PROPERTIES) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mID, this); + const LLAvatarData* pAvatarData = static_cast(data); + if (pAvatarData && (pAvatarData->avatar_id != LLUUID::null)) + { + using namespace boost::gregorian; + int year, month, day; + sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year); + mAge = (day_clock::local_day() - date(year, month, day)).days(); + // If one wanted more information that gets displayed on profiles to be displayed, here would be the place to do it. + } + } } void LLAvatarListEntry::setPosition(LLVector3d position, bool this_sim, bool drawn, bool chatrange, bool shoutrange) @@ -220,12 +283,12 @@ bool LLAvatarListEntry::getAlive() return ((current - mFrame) <= 2); } -F32 LLAvatarListEntry::getEntryAgeSeconds() +F32 LLAvatarListEntry::getEntryAgeSeconds() const { return mUpdateTimer.getElapsedTimeF32(); } -BOOL LLAvatarListEntry::isDead() +bool LLAvatarListEntry::isDead() const { return getEntryAgeSeconds() > DEAD_KEEP_TIME; } @@ -239,7 +302,7 @@ void LLAvatarListEntry::setActivity(ACTIVITY_TYPE activity) } } -LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity() +const LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity() { if ( mActivityTimer.getElapsedTimeF32() > ACTIVITY_TIMEOUT ) { @@ -250,10 +313,14 @@ LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity() return mActivityType; } -LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar")) +LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar")), + mTracking(false), + mUpdate(true), + mDirtyAvatarSorting(false), + mUpdateRate(gSavedSettings.getU32("RadarUpdateRate") * 3 + 3), + mAvatarList(NULL) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_radar.xml"); - mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3; } LLFloaterAvatarList::~LLFloaterAvatarList() @@ -315,64 +382,140 @@ void LLFloaterAvatarList::onClose(bool app_quitting) } } +static void cmd_profile(const LLAvatarListEntry* entry); +static void cmd_toggle_mark(LLAvatarListEntry* entry); +static void cmd_ar(const LLAvatarListEntry* entry); +static void cmd_teleport(const LLAvatarListEntry* entry); BOOL LLFloaterAvatarList::postBuild() { - // Default values - mTracking = FALSE; - mUpdate = TRUE; - // Set callbacks - childSetAction("profile_btn", onClickProfile, this); - childSetAction("im_btn", onClickIM, this); - childSetAction("offer_btn", onClickTeleportOffer, this); - childSetAction("track_btn", onClickTrack, this); - childSetAction("mark_btn", onClickMark, this); - childSetAction("focus_btn", onClickFocus, this); - childSetAction("prev_in_list_btn", onClickPrevInList, this); - childSetAction("next_in_list_btn", onClickNextInList, this); - childSetAction("prev_marked_btn", onClickPrevMarked, this); - childSetAction("next_marked_btn", onClickNextMarked, this); + childSetAction("profile_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_profile, false)); + childSetAction("im_btn", boost::bind(&LLFloaterAvatarList::onClickIM, this)); + childSetAction("offer_btn", boost::bind(&LLFloaterAvatarList::onClickTeleportOffer, this)); + childSetAction("track_btn", boost::bind(&LLFloaterAvatarList::onClickTrack, this)); + childSetAction("mark_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_toggle_mark, false)); + childSetAction("focus_btn", boost::bind(&LLFloaterAvatarList::onClickFocus, this)); + childSetAction("prev_in_list_btn", boost::bind(&LLFloaterAvatarList::focusOnPrev, this, FALSE)); + childSetAction("next_in_list_btn", boost::bind(&LLFloaterAvatarList::focusOnNext, this, FALSE)); + childSetAction("prev_marked_btn", boost::bind(&LLFloaterAvatarList::focusOnPrev, this, TRUE)); + childSetAction("next_marked_btn", boost::bind(&LLFloaterAvatarList::focusOnNext, this, TRUE)); - childSetAction("get_key_btn", onClickGetKey, this); + childSetAction("get_key_btn", boost::bind(&LLFloaterAvatarList::onClickGetKey, this)); - childSetAction("freeze_btn", onClickFreeze, this); - childSetAction("eject_btn", onClickEject, this); - childSetAction("mute_btn", onClickMute, this); - childSetAction("ar_btn", onClickAR, this); - childSetAction("teleport_btn", onClickTeleport, this); - childSetAction("estate_eject_btn", onClickEjectFromEstate, this); - childSetAction("estate_ban_btn", onClickBanFromEstate, this); + childSetAction("freeze_btn", boost::bind(&LLFloaterAvatarList::onClickFreeze, this)); + childSetAction("eject_btn", boost::bind(&LLFloaterAvatarList::onClickEject, this)); + childSetAction("mute_btn", boost::bind(&LLFloaterAvatarList::onClickMute, this)); + childSetAction("ar_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_ar, true)); + childSetAction("teleport_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_teleport, true)); + childSetAction("estate_eject_btn", boost::bind(&LLFloaterAvatarList::onClickEjectFromEstate, this)); + childSetAction("estate_ban_btn",boost::bind(&LLFloaterAvatarList:: onClickBanFromEstate, this)); - childSetAction("send_keys_btn", onClickSendKeys, this); + childSetAction("send_keys_btn", boost::bind(&LLFloaterAvatarList::sendKeys, this)); getChild("update_rate")->setSelectedIndex(gSavedSettings.getU32("RadarUpdateRate")); - childSetCommitCallback("update_rate", onCommitUpdateRate, this); + getChild("update_rate")->setCommitCallback(boost::bind(&LLFloaterAvatarList::onCommitUpdateRate, this)); + + getChild("hide_mark")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + getChild("hide_pos")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + getChild("hide_alt")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + getChild("hide_act")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + getChild("hide_age")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + getChild("hide_time")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); // Get a pointer to the scroll list from the interface mAvatarList = getChild("avatar_list"); mAvatarList->sortByColumn("distance", TRUE); mAvatarList->setCommitOnSelectionChange(TRUE); - mAvatarList->setCallbackUserData(this); - mAvatarList->setCommitCallback(onSelectName); - mAvatarList->setDoubleClickCallback(onClickFocus); + mAvatarList->setCommitCallback(boost::bind(&LLFloaterAvatarList::onSelectName,this)); + mAvatarList->setDoubleClickCallback(boost::bind(&LLFloaterAvatarList::onClickFocus,this)); + mAvatarList->setSortChangedCallback(boost::bind(&LLFloaterAvatarList::onAvatarSortingChanged,this)); refreshAvatarList(); gIdleCallbacks.addFunction(LLFloaterAvatarList::callbackIdle); - if(gHippoGridManager->getConnectedGrid()->isSecondLife()){ - LLScrollListCtrl* list = getChild("avatar_list"); - list->getColumn(LIST_AVATAR_NAME)->setWidth(0); - list->getColumn(LIST_CLIENT)->setWidth(0); - list->getColumn(LIST_CLIENT)->mDynamicWidth = FALSE; - list->getColumn(LIST_CLIENT)->mRelWidth = 0; - list->getColumn(LIST_AVATAR_NAME)->mDynamicWidth = TRUE; - list->getColumn(LIST_AVATAR_NAME)->mRelWidth = -1; - list->updateLayout(); - } + assessColumns(); + + if(gHippoGridManager->getConnectedGrid()->isSecondLife()) + childSetVisible("hide_client", false); + else + getChild("hide_client")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); return TRUE; } +void col_helper(const bool hide, LLCachedControl &setting, LLScrollListColumn* col) +{ + // Brief Explanation: + // Check if we want the column hidden, and if it's still showing. If so, hide it, but save its width. + // Otherwise, if we don't want it hidden, but it is, unhide it to the saved width. + // We only store width of columns when hiding here for the purpose of hiding and unhiding. + const int width = col->getWidth(); + + if (hide && width) + { + setting = width; + col->setWidth(0); + } + else if(!hide && !width) + { + col->setWidth(setting); + } +} + +//Macro to reduce redundant lines. Preprocessor concatenation and stringizing avoids bloat that +//wrapping in a class would create. +#define BIND_COLUMN_TO_SETTINGS(col, name)\ + static const LLCachedControl hide_##name(gSavedSettings, "RadarColumn"#name"Hidden");\ + static LLCachedControl width_##name(gSavedSettings, "RadarColumn"#name"Width");\ + col_helper(hide_##name, width_##name, mAvatarList->getColumn(col)); + +void LLFloaterAvatarList::assessColumns() +{ + BIND_COLUMN_TO_SETTINGS(LIST_MARK,Mark); + BIND_COLUMN_TO_SETTINGS(LIST_POSITION,Position); + BIND_COLUMN_TO_SETTINGS(LIST_ALTITUDE,Altitude); + BIND_COLUMN_TO_SETTINGS(LIST_ACTIVITY,Activity); + BIND_COLUMN_TO_SETTINGS(LIST_AGE,Age); + BIND_COLUMN_TO_SETTINGS(LIST_TIME,Time); + + static const LLCachedControl hide_client(gSavedSettings, "RadarColumnClientHidden"); + static LLCachedControl width_name(gSavedSettings, "RadarColumnNameWidth"); + bool client_hidden = hide_client || gHippoGridManager->getConnectedGrid()->isSecondLife(); + LLScrollListColumn* name_col = mAvatarList->getColumn(LIST_AVATAR_NAME); + LLScrollListColumn* client_col = mAvatarList->getColumn(LIST_CLIENT); + + if (client_hidden != !!name_col->mDynamicWidth) + { + //Don't save if its being hidden because of detected grid. Not that it really matters, as this setting(along with the other RadarColumn*Width settings) + //isn't handled in a way that allows it to carry across sessions, but I assume that may want to be fixed in the future.. + if(client_hidden && !gHippoGridManager->getConnectedGrid()->isSecondLife() && name_col->getWidth() > 0) + width_name = name_col->getWidth(); + + //MUST call setWidth(0) first to clear out mTotalStaticColumnWidth accumulation in parent before changing the mDynamicWidth value + client_col->setWidth(0); + name_col->setWidth(0); + + client_col->mDynamicWidth = !client_hidden; + name_col->mDynamicWidth = client_hidden; + + if(!client_hidden) + { + name_col->setWidth(width_name); + } + } + else if (!hide_client) + { + mAvatarList->getColumn(LIST_CLIENT)->setWidth(0); + mAvatarList->getColumn(LIST_AVATAR_NAME)->setWidth(0); + mAvatarList->getColumn(LIST_AVATAR_NAME)->mDynamicWidth = FALSE; + mAvatarList->getColumn(LIST_AVATAR_NAME)->mRelWidth = 0; + mAvatarList->getColumn(LIST_CLIENT)->mDynamicWidth = TRUE; + mAvatarList->getColumn(LIST_CLIENT)->mRelWidth = -1; + } + + mAvatarList->updateLayout(); +} + void updateParticleActivity(LLDrawable *drawablep) { if (LLFloaterAvatarList::instanceExists()) @@ -438,9 +581,9 @@ void LLFloaterAvatarList::updateAvatarList() sorted_avatar_ids = avatar_ids; std::sort(sorted_avatar_ids.begin(), sorted_avatar_ids.end()); - for (std::vector::const_iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) + BOOST_FOREACH(std::vector::value_type& iter, LLCharacter::sInstances) { - LLUUID avid = (*iter)->getID(); + LLUUID avid = iter->getID(); if (!std::binary_search(sorted_avatar_ids.begin(), sorted_avatar_ids.end(), avid)) { @@ -451,14 +594,12 @@ void LLFloaterAvatarList::updateAvatarList() size_t i; size_t count = avatar_ids.size(); - bool announce = gSavedSettings.getBOOL("RadarChatKeys"); + static LLCachedControl announce(gSavedSettings, "RadarChatKeys"); std::queue announce_keys; for (i = 0; i < count; ++i) { std::string name; - std::string first; - std::string last; const LLUUID &avid = avatar_ids[i]; LLVector3d position; @@ -478,29 +619,13 @@ void LLFloaterAvatarList::updateAvatarList() position = gAgent.getPosGlobalFromAgent(avatarp->getCharacterPosition()); name = avatarp->getFullname(); - // [Ansariel: Display name support] - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(avatarp->getID(), &avatar_name)) - { - static LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : name = avatar_name.getLegacyName(); break; - case 1 : name = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : name = avatar_name.mDisplayName; break; - default : name = avatar_name.getLegacyName(); break; - } - - first = avatar_name.mLegacyFirstName; - last = avatar_name.mLegacyLastName; - } - else continue; - // [/Ansariel: Display name support] + if (!LLAvatarNameCache::getPNSName(avatarp->getID(), name)) + continue; //duped for lower section if (name.empty() || (name.compare(" ") == 0))// || (name.compare(gCacheName->getDefaultName()) == 0)) { - if (!gCacheName->getFullName(avid, name)) //seems redudant with LLAvatarNameCache::get above... + if (!gCacheName->getFullName(avid, name)) //seems redudant with LLAvatarNameCache::getPNSName above... { continue; } @@ -512,20 +637,20 @@ void LLFloaterAvatarList::updateAvatarList() continue; } - if (mAvatars.count(avid) > 0) + LLAvatarListEntry* entry = getAvatarEntry(avid); + if (entry) { // Avatar already in list, update position F32 dist = (F32)(position - mypos).magVec(); - mAvatars[avid].setPosition(position, (avatarp->getRegion() == gAgent.getRegion()), true, dist < 20.0, dist < 100.0); - if(avatarp->isTyping())mAvatars[avid].setActivity(LLAvatarListEntry::ACTIVITY_TYPING); + entry->setPosition(position, (avatarp->getRegion() == gAgent.getRegion()), true, dist < 20.0, dist < 100.0); + if(avatarp->isTyping())entry->setActivity(LLAvatarListEntry::ACTIVITY_TYPING); } else { // Avatar not there yet, add it - LLAvatarListEntry entry(avid, name, position); if(announce && avatarp->getRegion() == gAgent.getRegion()) announce_keys.push(avid); - mAvatars[avid] = entry; + mAvatars.push_back(LLAvatarListEntryPtr(new LLAvatarListEntry(avid, name, position))); } } else @@ -539,30 +664,31 @@ void LLFloaterAvatarList::updateAvatarList() continue; } - if (!gCacheName->getFullName(avid, name)) + if (!LLAvatarNameCache::getPNSName(avid, name)) { //name = gCacheName->getDefaultName(); continue; //prevent (Loading...) } - if (mAvatars.count(avid) > 0) + LLAvatarListEntry* entry = getAvatarEntry(avid); + if (entry) { // Avatar already in list, update position F32 dist = (F32)(position - mypos).magVec(); - mAvatars[avid].setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), false, dist < 20.0, dist < 100.0); + entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), false, dist < 20.0, dist < 100.0); } else { - LLAvatarListEntry entry(avid, name, position); if(announce && gAgent.getRegion()->pointInRegionGlobal(position)) announce_keys.push(avid); - mAvatars[avid] = entry; + mAvatars.push_back(LLAvatarListEntryPtr(new LLAvatarListEntry(avid, name, position))); } } } //let us send the keys in a more timely fashion - if(announce && !announce_keys.empty()) + if (announce && !announce_keys.empty()) { + // NOTE: This fragment is repeated in sendKey std::ostringstream ids; int transact_num = (int)gFrameCount; int num_ids = 0; @@ -574,37 +700,17 @@ void LLFloaterAvatarList::updateAvatarList() ids << "," << id.asString(); ++num_ids; - if(ids.tellp() > 200) + if (ids.tellp() > 200) { - gMessageSystem->newMessage("ScriptDialogReply"); - gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgent.getID()); - gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); - gMessageSystem->nextBlock("Data"); - gMessageSystem->addUUID("ObjectID", gAgent.getID()); - gMessageSystem->addS32("ChatChannel", -777777777); - gMessageSystem->addS32("ButtonIndex", 1); - gMessageSystem->addString("ButtonLabel",llformat("%d,%d", transact_num, num_ids) + ids.str()); - gAgent.sendReliableMessage(); + send_keys_message(transact_num, num_ids, ids.str()); num_ids = 0; ids.seekp(0); ids.str(""); } } - if(num_ids > 0) - { - gMessageSystem->newMessage("ScriptDialogReply"); - gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgent.getID()); - gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); - gMessageSystem->nextBlock("Data"); - gMessageSystem->addUUID("ObjectID", gAgent.getID()); - gMessageSystem->addS32("ChatChannel", -777777777); - gMessageSystem->addS32("ButtonIndex", 1); - gMessageSystem->addString("ButtonLabel",llformat("%d,%d", transact_num, num_ids) + ids.str()); - gAgent.sendReliableMessage(); - } + if (num_ids > 0) + send_keys_message(transact_num, num_ids, ids.str()); } } @@ -618,28 +724,48 @@ void LLFloaterAvatarList::updateAvatarList() void LLFloaterAvatarList::expireAvatarList() { // llinfos << "radar: expiring" << llendl; - std::map::iterator iter; - std::queue delete_queue; - bool alive; - - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) + for(av_list_t::iterator it = mAvatars.begin(); it != mAvatars.end();) { - LLAvatarListEntry *entry = &iter->second; - - alive = entry->getAlive(); - - if (entry->isDead()) + LLAvatarListEntry* entry = it->get(); + if(!entry->isDead()) { - //llinfos << "radar: expiring avatar " << entry->getName() << llendl; - LLUUID av_id = entry->getID(); - delete_queue.push(av_id); + entry->getAlive(); + ++it; + } + else + { + if(mAvatars.back() == *it) + { + mAvatars.pop_back(); + return; + } + *it = mAvatars.back(); + mAvatars.pop_back(); + if(mAvatars.empty()) + return; } } +} - while (!delete_queue.empty()) +void LLFloaterAvatarList::updateAvatarSorting() +{ + if(mDirtyAvatarSorting) { - mAvatars.erase(delete_queue.front()); - delete_queue.pop(); + mDirtyAvatarSorting = false; + if(mAvatars.size() <= 1) //Nothing to sort. + return; + const std::vector list = mAvatarList->getAllData(); + av_list_t::iterator insert_it = mAvatars.begin(); + for(std::vector::const_iterator it=list.begin();it!=list.end();++it) + { + av_list_t::iterator av_it = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch((*it)->getUUID())); + if(av_it!=mAvatars.end()) + { + std::iter_swap(insert_it++,av_it); + if(insert_it+1 == mAvatars.end()) //We've ran out of elements to sort + return; + } + } } } @@ -656,7 +782,7 @@ void LLFloaterAvatarList::refreshAvatarList() // We rebuild the list fully each time it's refreshed // The assumption is that it's faster to refill it and sort than // to rebuild the whole list. - LLDynamicArray selected = mAvatarList->getSelectedIDs(); + uuid_vec_t selected = mAvatarList->getSelectedIDs(); S32 scrollpos = mAvatarList->getScrollPos(); mAvatarList->deleteAllItems(); @@ -666,21 +792,20 @@ void LLFloaterAvatarList::refreshAvatarList() posagent.setVec(gAgent.getPositionAgent()); LLVector3d simpos = mypos - posagent; - std::map::iterator iter; - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) + BOOST_FOREACH(av_list_t::value_type& entry, mAvatars) { LLSD element; LLUUID av_id; std::string av_name; - LLAvatarListEntry* entry = &iter->second; - // Skip if avatar hasn't been around if (entry->isDead()) { continue; } + entry->setInList(); + av_id = entry->getID(); av_name = entry->getName().c_str(); @@ -716,6 +841,7 @@ void LLFloaterAvatarList::refreshAvatarList() continue; } + element["id"] = av_id; element["columns"][LIST_MARK]["column"] = "marked"; @@ -755,6 +881,7 @@ void LLFloaterAvatarList::refreshAvatarList() static LLCachedControl sRadarTextChatRange(gColors, "RadarTextChatRange"); static LLCachedControl sRadarTextShoutRange(gColors, "RadarTextShoutRange"); static LLCachedControl sRadarTextDrawDist(gColors, "RadarTextDrawDist"); + static LLCachedControl sRadarTextYoung(gColors, "RadarTextYoung"); LLColor4 name_color = sDefaultListText; //Lindens are always more Linden than your friend, make that take precedence @@ -872,28 +999,50 @@ void LLFloaterAvatarList::refreshAvatarList() element["columns"][LIST_ACTIVITY]["type"] = "icon"; std::string activity_icon = ""; + std::string activity_tip = ""; switch(entry->getActivity()) { case LLAvatarListEntry::ACTIVITY_MOVING: - activity_icon = "inv_item_animation.tga"; + { + activity_icon = "inv_item_animation.tga"; + activity_tip = getString("Moving"); + } break; case LLAvatarListEntry::ACTIVITY_GESTURING: - activity_icon = "inv_item_gesture.tga"; + { + activity_icon = "inv_item_gesture.tga"; + activity_tip = getString("Playing a gesture"); + } break; case LLAvatarListEntry::ACTIVITY_SOUND: - activity_icon = "inv_item_sound.tga"; + { + activity_icon = "inv_item_sound.tga"; + activity_tip = getString("Playing a sound"); + } break; case LLAvatarListEntry::ACTIVITY_REZZING: - activity_icon = "ff_edit_theirs.tga"; + { + activity_icon = "ff_edit_theirs.tga"; + activity_tip = getString("Rezzing objects"); + } break; case LLAvatarListEntry::ACTIVITY_PARTICLES: - activity_icon = "particles_scan.tga"; + { + activity_icon = "particles_scan.tga"; + activity_tip = getString("Creating particles"); + } break; case LLAvatarListEntry::ACTIVITY_NEW: - activity_icon = "avatar_new.tga"; + { + activity_icon = "avatar_new.tga"; + activity_tip = getString("Just arrived"); + } break; case LLAvatarListEntry::ACTIVITY_TYPING: - activity_icon = "avatar_typing.tga"; + { + activity_icon = "avatar_typing.tga"; + activity_tip = getString("Typing"); + } break; default: break; @@ -901,6 +1050,40 @@ void LLFloaterAvatarList::refreshAvatarList() element["columns"][LIST_ACTIVITY]["value"] = activity_icon;//icon_image_id; //"icn_active-speakers-dot-lvl0.tga"; //element["columns"][LIST_AVATAR_ACTIVITY]["color"] = icon_color.getValue(); + element["columns"][LIST_ACTIVITY]["tool_tip"] = activity_tip; + + element["columns"][LIST_AGE]["column"] = "age"; + element["columns"][LIST_AGE]["type"] = "text"; + color = sDefaultListText; + std::string age = boost::lexical_cast(entry->mAge); + if (entry->mAge > -1) + { + static LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays"); + if ((U32)entry->mAge < sAvatarAgeAlertDays) + { + color = sRadarTextYoung; + if (!entry->mAgeAlert) //Only announce age once per entry. + { + entry->mAgeAlert = true; + chat_avatar_status(entry->getName().c_str(), av_id, ALERT_TYPE_AGE, true); + } + } + } + else + { + age = "?"; + } + element["columns"][LIST_AGE]["value"] = age; + element["columns"][LIST_AGE]["color"] = color.getValue(); + + int dur = difftime(time(NULL), entry->getTime()); + int hours = dur / 3600; + int mins = (dur % 3600) / 60; + int secs = (dur % 3600) % 60; + + element["columns"][LIST_TIME]["column"] = "time"; + element["columns"][LIST_TIME]["type"] = "text"; + element["columns"][LIST_TIME]["value"] = llformat("%d:%02d:%02d", hours, mins, secs); element["columns"][LIST_CLIENT]["column"] = "client"; element["columns"][LIST_CLIENT]["type"] = "text"; @@ -944,36 +1127,44 @@ void LLFloaterAvatarList::refreshAvatarList() } // finish - mAvatarList->sortItems(); + mAvatarList->updateSort(); mAvatarList->selectMultiple(selected); mAvatarList->setScrollPos(scrollpos); + + mDirtyAvatarSorting = true; + + if (mAvatars.empty()) + setTitle(getString("Title")); + else if (mAvatars.size() == 1) + setTitle(getString("TitleOneAvatar")); + else + { + LLStringUtil::format_map_t args; + args["[COUNT]"] = boost::lexical_cast(mAvatars.size()); + setTitle(getString("TitleWithCount", args)); + } // llinfos << "radar refresh: done" << llendl; } -// static -void LLFloaterAvatarList::onClickIM(void* userdata) +void LLFloaterAvatarList::onClickIM() { //llinfos << "LLFloaterFriends::onClickIM()" << llendl; - LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata; - - LLDynamicArray ids = self->mAvatarList->getSelectedIDs(); - if (ids.size() > 0) + const uuid_vec_t ids = mAvatarList->getSelectedIDs(); + if (!ids.empty()) { if (ids.size() == 1) { // Single avatar LLUUID agent_id = ids[0]; - // [Ansariel: Display name support] - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) + std::string avatar_name; + if (gCacheName->getFullName(agent_id, avatar_name)) { gIMMgr->setFloaterOpen(TRUE); - gIMMgr->addSession(LLCacheName::cleanFullName(avatar_name.getLegacyName()),IM_NOTHING_SPECIAL,agent_id); + gIMMgr->addSession(avatar_name,IM_NOTHING_SPECIAL,agent_id); } - // [Ansariel: Display name support] } else { @@ -986,42 +1177,34 @@ void LLFloaterAvatarList::onClickIM(void* userdata) } } -void LLFloaterAvatarList::onClickTeleportOffer(void* userdata) +void LLFloaterAvatarList::onClickTeleportOffer() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - LLDynamicArray ids = self->mAvatarList->getSelectedIDs(); + uuid_vec_t ids = mAvatarList->getSelectedIDs(); if (ids.size() > 0) { handle_lure(ids); } } -void LLFloaterAvatarList::onClickTrack(void* userdata) +void LLFloaterAvatarList::onClickTrack() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); + LLScrollListItem* item = mAvatarList->getFirstSelected(); if (!item) return; LLUUID agent_id = item->getUUID(); - if (self->mTracking && self->mTrackedAvatar == agent_id) { + if (mTracking && mTrackedAvatar == agent_id) + { LLTracker::stopTracking(NULL); - self->mTracking = FALSE; + mTracking = FALSE; } else { - self->mTracking = TRUE; - self->mTrackedAvatar = agent_id; + mTracking = TRUE; + mTrackedAvatar = agent_id; // trackAvatar only works for friends allowing you to see them on map... // LLTracker::trackAvatar(agent_id, self->mAvatars[agent_id].getName()); - std::string name = self->mAvatars[agent_id].getName(); - if (!self->mUpdate) - { - name += "\n(last known position)"; - } - LLTracker::trackLocation(self->mAvatars[agent_id].getPosition(), name, name); + trackAvatar(getAvatarEntry(mTrackedAvatar)); } } @@ -1031,15 +1214,12 @@ void LLFloaterAvatarList::refreshTracker() if (LLTracker::isTracking(NULL)) { - LLVector3d pos = mAvatars[mTrackedAvatar].getPosition(); - if (pos != LLTracker::getTrackedPositionGlobal()) + if(LLAvatarListEntry* entry = getAvatarEntry(mTrackedAvatar)) { - std::string name = mAvatars[mTrackedAvatar].getName(); - if (!mUpdate) + if (entry->getPosition() != LLTracker::getTrackedPositionGlobal()) { - name += "\n(last known position)"; + trackAvatar(entry); } - LLTracker::trackLocation(pos, name, name); } } else @@ -1050,6 +1230,17 @@ void LLFloaterAvatarList::refreshTracker() } } +void LLFloaterAvatarList::trackAvatar(const LLAvatarListEntry* entry) +{ + if(!entry) return; + std::string name = entry->getName(); + if (!mUpdate) + { + name += "\n(last known position)"; + } + LLTracker::trackLocation(entry->getPosition(), name, name); +} + LLAvatarListEntry * LLFloaterAvatarList::getAvatarEntry(LLUUID avatar) { if (avatar.isNull()) @@ -1057,32 +1248,11 @@ LLAvatarListEntry * LLFloaterAvatarList::getAvatarEntry(LLUUID avatar) return NULL; } - std::map::iterator iter; - - iter = mAvatars.find(avatar); - if (iter == mAvatars.end()) - { + av_list_t::iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(avatar)); + if(iter != mAvatars.end()) + return iter->get(); + else return NULL; - } - - return &iter->second; -} - -//static -void LLFloaterAvatarList::onClickMark(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - LLDynamicArray ids = self->mAvatarList->getSelectedIDs(); - - for (LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) - { - LLUUID avid = *itr; - LLAvatarListEntry* entry = self->getAvatarEntry(avid); - if (entry != NULL) - { - entry->toggleMark(); - } - } } BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) @@ -1094,8 +1264,7 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) LLUUID agent_id = item->getUUID(); if (( KEY_RETURN == key ) && (MASK_NONE == mask)) { - self->mFocusedAvatar = agent_id; - self->focusOnCurrent(); + self->setFocusAvatar(agent_id); return TRUE; } else if (( KEY_RETURN == key ) && (MASK_CONTROL == mask)) @@ -1112,7 +1281,7 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) if (( KEY_RETURN == key ) && (MASK_SHIFT == mask)) { - LLDynamicArray ids = self->mAvatarList->getSelectedIDs(); + uuid_vec_t ids = self->mAvatarList->getSelectedIDs(); if (ids.size() > 0) { if (ids.size() == 1) @@ -1120,14 +1289,12 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) // Single avatar LLUUID agent_id = ids[0]; - // [Ansariel: Display name support] - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) + std::string avatar_name; + if (gCacheName->getFullName(agent_id, avatar_name)) { gIMMgr->setFloaterOpen(TRUE); - gIMMgr->addSession(LLCacheName::cleanFullName(avatar_name.getLegacyName()),IM_NOTHING_SPECIAL,agent_id); + gIMMgr->addSession(avatar_name,IM_NOTHING_SPECIAL,agent_id); } - // [Ansariel: Display name support] } else { @@ -1142,143 +1309,73 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) return LLPanel::handleKeyHere(key, mask); } -void LLFloaterAvatarList::onClickFocus(void* userdata) +void LLFloaterAvatarList::onClickFocus() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); + LLScrollListItem* item = mAvatarList->getFirstSelected(); if (item) { - self->mFocusedAvatar = item->getUUID(); - self->focusOnCurrent(); + setFocusAvatar(item->getUUID()); } } void LLFloaterAvatarList::removeFocusFromAll() { - std::map::iterator iter; - - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) + BOOST_FOREACH(av_list_t::value_type& entry, mAvatars) { - LLAvatarListEntry* entry = &iter->second; entry->setFocus(FALSE); } } -void LLFloaterAvatarList::focusOnCurrent() +void LLFloaterAvatarList::setFocusAvatar(const LLUUID& id) { - std::map::iterator iter; - LLAvatarListEntry* entry; - - if (mAvatars.size() == 0) + av_list_t::iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(id)); + if(iter != mAvatars.end()) { - return; + if(!gAgentCamera.lookAtObject(id, false)) + return; + removeFocusFromAll(); + (*iter)->setFocus(TRUE); } +} - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) +template +void decrement_focus_target(T begin, T end, BOOL marked_only) +{ + T iter = begin; + while(iter != end && !(*iter)->isFocused()) ++iter; + if(iter == end) + return; + T prev_iter = iter; + while(prev_iter != begin) { - entry = &iter->second; - - if (entry->isDead()) - continue; - - if (entry->getID() == mFocusedAvatar) + const LLAvatarListEntry& entry = *((--prev_iter)->get()); + if(entry.isInList() && (entry.isMarked() || !marked_only) && gAgentCamera.lookAtObject(entry.getID(), false)) { - removeFocusFromAll(); - entry->setFocus(TRUE); - gAgentCamera.lookAtObject(mFocusedAvatar, false); + (*iter)->setFocus(FALSE); + (*prev_iter)->setFocus(TRUE); + gAgentCamera.lookAtObject((*prev_iter)->getID(), false); return; } } + gAgentCamera.lookAtObject((*iter)->getID(), false); } void LLFloaterAvatarList::focusOnPrev(BOOL marked_only) { - std::map::iterator iter; - LLAvatarListEntry* prev = NULL; - LLAvatarListEntry* entry; - - if (mAvatars.size() == 0) - { - return; - } - - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) - { - entry = &iter->second; - - if (entry->isDead()) - continue; - - if (prev != NULL && entry->getID() == mFocusedAvatar) - { - break; - } - - if ((!marked_only && entry->isDrawn()) || entry->isMarked()) - { - prev = entry; - } - } - - if (prev != NULL) - { - removeFocusFromAll(); - prev->setFocus(TRUE); - mFocusedAvatar = prev->getID(); - gAgentCamera.lookAtObject(mFocusedAvatar, false); - } + updateAvatarSorting(); + decrement_focus_target(mAvatars.begin(), mAvatars.end(), marked_only); } void LLFloaterAvatarList::focusOnNext(BOOL marked_only) { - std::map::iterator iter; - BOOL found = FALSE; - LLAvatarListEntry* next = NULL; - LLAvatarListEntry* entry; - - if (mAvatars.size() == 0) - { - return; - } - - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) - { - entry = &iter->second; - - if (entry->isDead()) - continue; - - if (next == NULL && ((!marked_only && entry->isDrawn()) || entry->isMarked())) - { - next = entry; - } - - if (found && ((!marked_only && entry->isDrawn()) || entry->isMarked())) - { - next = entry; - break; - } - - if (entry->getID() == mFocusedAvatar) - { - found = TRUE; - } - } - - if (next != NULL) - { - removeFocusFromAll(); - next->setFocus(TRUE); - mFocusedAvatar = next->getID(); - gAgentCamera.lookAtObject(mFocusedAvatar, false); - } + updateAvatarSorting(); + decrement_focus_target(mAvatars.rbegin(), mAvatars.rend(), marked_only); } /*static*/ void LLFloaterAvatarList::lookAtAvatar(LLUUID &uuid) { // twisted laws - LLViewerObject* voavatar = gObjectList.findObject(uuid); + LLVOAvatar* voavatar = gObjectList.findAvatar(uuid); if(voavatar && voavatar->isAvatar()) { gAgentCamera.setFocusOnAvatar(FALSE, FALSE); @@ -1291,39 +1388,9 @@ void LLFloaterAvatarList::lookAtAvatar(LLUUID &uuid) } } -//static -void LLFloaterAvatarList::onClickPrevInList(void* userdata) +void LLFloaterAvatarList::onClickGetKey() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - self->focusOnPrev(FALSE); -} - -//static -void LLFloaterAvatarList::onClickNextInList(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - self->focusOnNext(FALSE); -} - -//static -void LLFloaterAvatarList::onClickPrevMarked(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - self->focusOnPrev(TRUE); -} - -//static -void LLFloaterAvatarList::onClickNextMarked(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - self->focusOnNext(TRUE); -} - -//static -void LLFloaterAvatarList::onClickGetKey(void *userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); + LLScrollListItem* item = mAvatarList->getFirstSelected(); if (NULL == item) return; @@ -1334,22 +1401,20 @@ void LLFloaterAvatarList::onClickGetKey(void *userdata) gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer)); } -//static + void LLFloaterAvatarList::sendKeys() { + // This would break for send_keys_btn callback, check this beforehand, if it matters. + //static LLCachedControl radar_chat_keys(gSavedSettings, "RadarChatKeys"); + //if (radar_chat_keys) return; + LLViewerRegion* regionp = gAgent.getRegion(); - if(!regionp)return;//ALWAYS VALIDATE DATA - std::ostringstream ids; + if (!regionp) return;//ALWAYS VALIDATE DATA + static int last_transact_num = 0; int transact_num = (int)gFrameCount; - int num_ids = 0; - if(!gSavedSettings.getBOOL("RadarChatKeys")) - { - return; - } - - if(transact_num > last_transact_num) + if (transact_num > last_transact_num) { last_transact_num = transact_num; } @@ -1360,7 +1425,9 @@ void LLFloaterAvatarList::sendKeys() return; } - if (!regionp) return; // caused crash if logged out/connection lost + std::ostringstream ids; + int num_ids = 0; + for (int i = 0; i < regionp->mMapAvatarIDs.count(); i++) { const LLUUID &id = regionp->mMapAvatarIDs.get(i); @@ -1369,74 +1436,56 @@ void LLFloaterAvatarList::sendKeys() ++num_ids; - if(ids.tellp() > 200) + if (ids.tellp() > 200) { - gMessageSystem->newMessage("ScriptDialogReply"); - gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgent.getID()); - gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); - gMessageSystem->nextBlock("Data"); - gMessageSystem->addUUID("ObjectID", gAgent.getID()); - gMessageSystem->addS32("ChatChannel", -777777777); - gMessageSystem->addS32("ButtonIndex", 1); - gMessageSystem->addString("ButtonLabel",llformat("%d,%d", transact_num, num_ids) + ids.str()); - gAgent.sendReliableMessage(); + send_keys_message(transact_num, num_ids, ids.str()); num_ids = 0; ids.seekp(0); ids.str(""); } } - if(num_ids > 0) - { - gMessageSystem->newMessage("ScriptDialogReply"); - gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgent.getID()); - gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); - gMessageSystem->nextBlock("Data"); - gMessageSystem->addUUID("ObjectID", gAgent.getID()); - gMessageSystem->addS32("ChatChannel", -777777777); - gMessageSystem->addS32("ButtonIndex", 1); - gMessageSystem->addString("ButtonLabel",llformat("%d,%d", transact_num, num_ids) + ids.str()); - gAgent.sendReliableMessage(); - } + if (num_ids > 0) + send_keys_message(transact_num, num_ids, ids.str()); } //static void LLFloaterAvatarList::sound_trigger_hook(LLMessageSystem* msg,void **) { + if (!LLFloaterAvatarList::instanceExists()) return; // Don't bother if we're closed. + LLUUID sound_id,owner_id; msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_SoundID, sound_id); msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_OwnerID, owner_id); - if(owner_id == gAgent.getID() && sound_id == LLUUID("76c78607-93f9-f55a-5238-e19b1a181389")) + if (owner_id == gAgent.getID() && sound_id == LLUUID("76c78607-93f9-f55a-5238-e19b1a181389")) { - //let's ask if they want to turn it on. - if(gSavedSettings.getBOOL("RadarChatKeys")) - { + static LLCachedControl on("RadarChatKeys"); + static LLCachedControl do_not_ask("RadarChatKeysStopAsking"); + if (on) LLFloaterAvatarList::getInstance()->sendKeys(); - }else - { - LLSD args; - args["MESSAGE"] = "An object owned by you has request the keys from your radar.\nWould you like to enable announcing keys to objects in the sim?"; - LLNotificationsUtil::add("GenericAlertYesCancel", args, LLSD(), onConfirmRadarChatKeys); - } + else if (!do_not_ask) // Let's ask if they want to turn it on, but not pester them. + LLNotificationsUtil::add("RadarChatKeysRequest", LLSD(), LLSD(), onConfirmRadarChatKeys); } } // static bool LLFloaterAvatarList::onConfirmRadarChatKeys(const LLSD& notification, const LLSD& response ) { S32 option = LLNotification::getSelectedOption(notification, response); - if(option == 0) // yes + if (option == 1) // no { - gSavedSettings.setBOOL("RadarChatKeys",TRUE); + return false; + } + else if (option == 0) // yes + { + gSavedSettings.setBOOL("RadarChatKeys", true); LLFloaterAvatarList::getInstance()->sendKeys(); } + else if (option == 2) // No, and stop asking!! + { + gSavedSettings.setBOOL("RadarChatKeysStopAsking", true); + } + return false; } -//static -void LLFloaterAvatarList::onClickSendKeys(void *userdata) -{ - LLFloaterAvatarList::getInstance()->sendKeys(); -} static void send_freeze(const LLUUID& avatar_id, bool freeze) { @@ -1521,46 +1570,44 @@ static void send_estate_message( msg->sendReliable(gAgent.getRegion()->getHost()); } -static void cmd_freeze(const LLUUID& avatar, const std::string& name) { send_freeze(avatar, true); } -static void cmd_unfreeze(const LLUUID& avatar, const std::string& name) { send_freeze(avatar, false); } -static void cmd_eject(const LLUUID& avatar, const std::string& name) { send_eject(avatar, false); } -static void cmd_ban(const LLUUID& avatar, const std::string& name) { send_eject(avatar, true); } -static void cmd_profile(const LLUUID& avatar, const std::string& name) { LLFloaterAvatarInfo::showFromDirectory(avatar); } -static void cmd_estate_eject(const LLUUID& avatar, const std::string& name){ send_estate_message("teleporthomeuser", avatar); } -static void cmd_estate_ban(const LLUUID &avatar, const std::string &name) { LLPanelEstateInfo::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, avatar); } +static void cmd_append_names(const LLAvatarListEntry* entry, std::string &str, std::string &sep) + { if(!str.empty())str.append(sep);str.append(entry->getName()); } +static void cmd_toggle_mark(LLAvatarListEntry* entry) { entry->toggleMark(); } +static void cmd_ar(const LLAvatarListEntry* entry) { LLFloaterReporter::showFromObject(entry->getID()); } +static void cmd_profile(const LLAvatarListEntry* entry) { LLFloaterAvatarInfo::showFromDirectory(entry->getID()); } +static void cmd_teleport(const LLAvatarListEntry* entry) { gAgent.teleportViaLocation(entry->getPosition()); } +static void cmd_freeze(const LLAvatarListEntry* entry) { send_freeze(entry->getID(), true); } +static void cmd_unfreeze(const LLAvatarListEntry* entry) { send_freeze(entry->getID(), false); } +static void cmd_eject(const LLAvatarListEntry* entry) { send_eject(entry->getID(), false); } +static void cmd_ban(const LLAvatarListEntry* entry) { send_eject(entry->getID(), true); } +static void cmd_estate_eject(const LLAvatarListEntry* entry){ send_estate_message("teleporthomeuser", entry->getID()); } +static void cmd_estate_ban(const LLAvatarListEntry* entry) { LLPanelEstateInfo::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, entry->getID()); } -void LLFloaterAvatarList::doCommand(void (*func)(const LLUUID& avatar, const std::string& name)) +void LLFloaterAvatarList::doCommand(avlist_command_t func, bool single/*=false*/) { - LLDynamicArray ids = mAvatarList->getSelectedIDs(); - - for (LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) + uuid_vec_t ids; + if(!single) + ids = mAvatarList->getSelectedIDs(); + else + ids.push_back(getSelectedID()); + for (uuid_vec_t::iterator itr = ids.begin(); itr != ids.end(); ++itr) { - LLUUID avid = *itr; + LLUUID& avid = *itr; + if(avid.isNull()) + continue; LLAvatarListEntry* entry = getAvatarEntry(avid); if (entry != NULL) { llinfos << "Executing command on " << entry->getName() << llendl; - func(avid, entry->getName()); + func(entry); } } } std::string LLFloaterAvatarList::getSelectedNames(const std::string& separator) { - std::string ret = ""; - - LLDynamicArray ids = mAvatarList->getSelectedIDs(); - for (LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) - { - LLUUID avid = *itr; - LLAvatarListEntry* entry = getAvatarEntry(avid); - if (entry != NULL) - { - if (!ret.empty()) ret += separator; - ret += entry->getName(); - } - } - + std::string ret; + doCommand(boost::bind(&cmd_append_names,_1,boost::ref(ret),separator)); return ret; } @@ -1585,6 +1632,9 @@ LLUUID LLFloaterAvatarList::getSelectedID() //static void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& response) { + if(!instanceExists()) + return; + S32 option = LLNotification::getSelectedOption(notification, response); if (option == 0) @@ -1600,6 +1650,9 @@ void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& r //static void LLFloaterAvatarList::callbackEject(const LLSD& notification, const LLSD& response) { + if(!instanceExists()) + return; + S32 option = LLNotification::getSelectedOption(notification, response); if (option == 0) @@ -1615,6 +1668,9 @@ void LLFloaterAvatarList::callbackEject(const LLSD& notification, const LLSD& re //static void LLFloaterAvatarList::callbackEjectFromEstate(const LLSD& notification, const LLSD& response) { + if(!instanceExists()) + return; + S32 option = LLNotification::getSelectedOption(notification, response); if (option == 0) @@ -1626,6 +1682,9 @@ void LLFloaterAvatarList::callbackEjectFromEstate(const LLSD& notification, cons //static void LLFloaterAvatarList::callbackBanFromEstate(const LLSD& notification, const LLSD& response) { + if(!instanceExists()) + return; + S32 option = LLNotification::getSelectedOption(notification, response); if (option == 0) @@ -1648,32 +1707,28 @@ void LLFloaterAvatarList::callbackIdle(void* userdata) } } -void LLFloaterAvatarList::onClickFreeze(void* userdata) +void LLFloaterAvatarList::onClickFreeze() { LLSD args; LLSD payload; - args["AVATAR_NAME"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); + args["AVATAR_NAME"] = getSelectedNames(); LLNotificationsUtil::add("FreezeAvatarFullname", args, payload, callbackFreeze); } -//static -void LLFloaterAvatarList::onClickEject(void* userdata) +void LLFloaterAvatarList::onClickEject() { LLSD args; LLSD payload; - args["AVATAR_NAME"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); + args["AVATAR_NAME"] = getSelectedNames(); LLNotificationsUtil::add("EjectAvatarFullname", args, payload, callbackEject); } -//static -void LLFloaterAvatarList::onClickMute(void* userdata) +void LLFloaterAvatarList::onClickMute() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - LLDynamicArray ids = self->mAvatarList->getSelectedIDs(); + uuid_vec_t ids = mAvatarList->getSelectedIDs(); if (ids.size() > 0) { - for (LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) + for (uuid_vec_t::iterator itr = ids.begin(); itr != ids.end(); ++itr) { LLUUID agent_id = *itr; @@ -1695,86 +1750,45 @@ void LLFloaterAvatarList::onClickMute(void* userdata) } } -//static -void LLFloaterAvatarList::onClickEjectFromEstate(void* userdata) +void LLFloaterAvatarList::onClickEjectFromEstate() { LLSD args; LLSD payload; - args["EVIL_USER"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); + args["EVIL_USER"] = getSelectedNames(); LLNotificationsUtil::add("EstateKickUser", args, payload, callbackEjectFromEstate); } -//static -void LLFloaterAvatarList::onClickBanFromEstate(void* userdata) +void LLFloaterAvatarList::onClickBanFromEstate() { LLSD args; LLSD payload; - args["EVIL_USER"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); + args["EVIL_USER"] = getSelectedNames(); LLNotificationsUtil::add("EstateBanUser", args, payload, callbackBanFromEstate); } -//static -void LLFloaterAvatarList::onClickAR(void* userdata) +void LLFloaterAvatarList::onAvatarSortingChanged() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); + mDirtyAvatarSorting = true; +} + +void LLFloaterAvatarList::onSelectName() +{ + LLScrollListItem* item = mAvatarList->getFirstSelected(); if (item) { LLUUID agent_id = item->getUUID(); - LLAvatarListEntry* entry = self->getAvatarEntry(agent_id); - if (entry) - { - LLFloaterReporter::showFromObject(entry->getID()); - } - } -} - -// static -void LLFloaterAvatarList::onClickProfile(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - self->doCommand(cmd_profile); -} - -//static -void LLFloaterAvatarList::onClickTeleport(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); - if (item) - { - LLUUID agent_id = item->getUUID(); - LLAvatarListEntry* entry = self->getAvatarEntry(agent_id); - if (entry) - { -// llinfos << "Trying to teleport to " << entry->getName() << " at " << entry->getPosition() << llendl; - gAgent.teleportViaLocation(entry->getPosition()); - } - } -} - -void LLFloaterAvatarList::onSelectName(LLUICtrl*, void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); - if (item) - { - LLUUID agent_id = item->getUUID(); - LLAvatarListEntry* entry = self->getAvatarEntry(agent_id); + LLAvatarListEntry* entry = getAvatarEntry(agent_id); if (entry) { BOOL enabled = entry->isDrawn(); - self->childSetEnabled("focus_btn", enabled); - self->childSetEnabled("prev_in_list_btn", enabled); - self->childSetEnabled("next_in_list_btn", enabled); + childSetEnabled("focus_btn", enabled); + childSetEnabled("prev_in_list_btn", enabled); + childSetEnabled("next_in_list_btn", enabled); } } } -void LLFloaterAvatarList::onCommitUpdateRate(LLUICtrl*, void* userdata) +void LLFloaterAvatarList::onCommitUpdateRate() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - self->mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3; + mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3; } diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index 46bdd1a0f..3bcf4ea67 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -11,6 +11,7 @@ // // #include "llavatarname.h" +#include "llavatarpropertiesprocessor.h" #include "llfloater.h" #include "llfloaterreporter.h" #include "lluuid.h" @@ -21,6 +22,8 @@ #include #include +#include + class LLFloaterAvatarList; /** @@ -29,7 +32,8 @@ class LLFloaterAvatarList; * Instances are kept in a map. We keep track of the * frame where the avatar was last seen. */ -class LLAvatarListEntry { +class LLAvatarListEntry : public LLAvatarPropertiesObserver +{ public: @@ -52,6 +56,10 @@ enum ACTIVITY_TYPE * @param position Avatar's current position */ LLAvatarListEntry(const LLUUID& id = LLUUID::null, const std::string &name = "", const LLVector3d &position = LLVector3d::zero); + ~LLAvatarListEntry(); + + // Get properties, such as age and other niceties displayed on profiles. + /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); /** * Update world position. @@ -59,7 +67,7 @@ enum ACTIVITY_TYPE */ void setPosition(LLVector3d position, bool this_sim, bool drawn, bool chatrange, bool shoutrange); - LLVector3d getPosition() { return mPosition; } + const LLVector3d& getPosition() const { return mPosition; } /** * @brief Returns the age of this entry in frames @@ -72,55 +80,75 @@ enum ACTIVITY_TYPE /** * @brief Returns the age of this entry in seconds */ - F32 getEntryAgeSeconds(); + F32 getEntryAgeSeconds() const; /** * @brief Returns the name of the avatar */ - std::string getName() { return mName; } + const std::string& getName() const { return mName; } + const time_t& getTime() const { return mTime; } /** * @brief Returns the ID of the avatar */ - LLUUID getID() { return mID; } + const LLUUID& getID() const { return mID; } void setActivity(ACTIVITY_TYPE activity); /** * @brief Returns the activity type */ - ACTIVITY_TYPE getActivity(); + const ACTIVITY_TYPE getActivity(); /** * @brief Sets the 'focus' status on this entry (camera focused on this avatar) */ void setFocus(BOOL value) { mFocused = value; } - BOOL isFocused() { return mFocused; } + bool isFocused() const { return mFocused; } - BOOL isMarked() { return mMarked; } + bool isMarked() const { return mMarked; } - BOOL isDrawn() { return (mInDrawFrame != U32_MAX); } + bool isDrawn() const { return (mInDrawFrame != U32_MAX); } - BOOL isInSim() { return (mInSimFrame != U32_MAX); } + bool isInSim() const { return (mInSimFrame != U32_MAX); } + /** + * @brief 'InList' signifies that the entry has been displayed in the floaters avatar list + * Until this happens our focusprev/focusnext logic should ignore this entry. + */ + + void setInList() { mIsInList = true; } + + bool isInList() const { return mIsInList; } /** * @brief Returns whether the item is dead and shouldn't appear in the list * @returns TRUE if dead */ - BOOL isDead(); + bool isDead() const; void toggleMark() { mMarked = !mMarked; } + struct uuidMatch + { + uuidMatch(const LLUUID& id) : mID(id) {} + bool operator()(const boost::shared_ptr& l) { return l->getID() == mID; } + LLUUID mID; + }; + private: friend class LLFloaterAvatarList; LLUUID mID; std::string mName; + time_t mTime; LLVector3d mPosition; LLVector3d mDrawPosition; - BOOL mMarked; - BOOL mFocused; + bool mMarked; + bool mFocused; + bool mIsInList; + bool mAgeAlert; + int mAge; /** * @brief Timer to keep track of whether avatars are still there @@ -186,6 +214,9 @@ public: static void showInstance(); + // Decides which user-chosen columns to show and hide. + void assessColumns(); + /** * @brief Updates the internal avatar list with the currently present avatars. */ @@ -212,7 +243,10 @@ public: static void lookAtAvatar(LLUUID &uuid); static void sound_trigger_hook(LLMessageSystem* msg,void **); - static void sendKeys(); + void sendKeys(); + + typedef boost::shared_ptr LLAvatarListEntryPtr; + typedef std::vector< LLAvatarListEntryPtr > av_list_t; private: // when a line editor loses keyboard focus, it is committed. @@ -227,11 +261,12 @@ private: LIST_POSITION, LIST_ALTITUDE, LIST_ACTIVITY, + LIST_AGE, + LIST_TIME, LIST_CLIENT, }; - - typedef void (*avlist_command_t)(const LLUUID &avatar, const std::string &name); + typedef boost::function avlist_command_t; /** * @brief Removes focus status from all avatars in list @@ -239,9 +274,9 @@ private: void removeFocusFromAll(); /** - * @brief Focus camera on current avatar + * @brief Focus camera on specified avatar */ - void focusOnCurrent(); + void setFocusAvatar(const LLUUID& id); /** * @brief Focus camera on previous avatar @@ -255,6 +290,9 @@ private: */ void focusOnNext(BOOL marked_only); + void refreshTracker(); + void trackAvatar(const LLAvatarListEntry* entry); + /** * @brief Handler for the "refresh" button click. * I am unsure whether this is actually necessary at the time. @@ -263,42 +301,38 @@ private: * @param userdata Pointer to user data (LLFloaterAvatarList instance) */ - static void onClickProfile(void *userdata); - static void onClickIM(void *userdata); - static void onClickTeleportOffer(void *userdata); - static void onClickTrack(void *userdata); - static void onClickMark(void *userdata); - static void onClickFocus(void *userdata); + void onClickIM(); + void onClickTeleportOffer(); + void onClickTrack(); + void onClickMute(); + void onClickFocus(); + void onClickGetKey(); - static void onClickPrevInList(void *userdata); - static void onClickNextInList(void *userdata); - static void onClickPrevMarked(void *userdata); - static void onClickNextMarked(void *userdata); - static void onClickGetKey(void *userdata); + void onSelectName(); + void onCommitUpdateRate(); - static void onClickFreeze(void *userdata); - static void onClickEject(void *userdata); - static void onClickMute(void *userdata); - static void onClickAR(void *userdata); - static void onClickTeleport(void *userdata); - static void onClickEjectFromEstate(void *userdata); - static void onClickBanFromEstate(void *userdata); + /** + * @brief These callbacks fire off notifications, which THEN fire the related callback* functions. + */ + void onClickFreeze(); + void onClickEject(); + void onClickEjectFromEstate(); + void onClickBanFromEstate(); + void onAvatarSortingChanged(); + /** + * @brief Called via notification feedback. + */ static void callbackFreeze(const LLSD& notification, const LLSD& response); static void callbackEject(const LLSD& notification, const LLSD& response); - static void callbackAR(void *userdata); static void callbackEjectFromEstate(const LLSD& notification, const LLSD& response); static void callbackBanFromEstate(const LLSD& notification, const LLSD& response); - static void onSelectName(LLUICtrl*, void *userdata); - - static void onCommitUpdateRate(LLUICtrl*, void *userdata); - static void onClickSendKeys(void *userdata); static bool onConfirmRadarChatKeys(const LLSD& notification, const LLSD& response ); static void callbackIdle(void *userdata); - void doCommand(avlist_command_t cmd); + void doCommand(avlist_command_t cmd, bool single = false); /** * @brief Cleanup avatar list, removing dead entries from it. @@ -307,28 +341,28 @@ private: * to do something to them. */ void expireAvatarList(); + void updateAvatarSorting(); private: /** * @brief Pointer to the avatar scroll list */ LLScrollListCtrl* mAvatarList; - std::map mAvatars; + av_list_t mAvatars; + bool mDirtyAvatarSorting; /** * @brief TRUE when Updating */ - BOOL mUpdate; + bool mUpdate; /** * @brief Update rate (if min frames per update) */ U32 mUpdateRate; - - void refreshTracker(); // tracking data - BOOL mTracking; // Tracking ? + bool mTracking; // Tracking ? LLUUID mTrackedAvatar; // Who we are tracking /** diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index b93812506..f0593517f 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -33,21 +33,26 @@ #include "llfloateravatarpicker.h" -#include "message.h" - +// Viewer includes #include "llagent.h" -#include "llbutton.h" #include "llfocusmgr.h" #include "llfoldervieweventlistener.h" -#include "llinventorypanel.h" -#include "llinventorymodel.h" #include "llinventoryfunctions.h" +#include "llinventorymodel.h" +#include "llinventorypanel.h" +#include "llviewercontrol.h" +#include "llviewerregion.h" +#include "llworld.h" + +// Linden libraries +#include "llavatarnamecache.h" // IDEVO +#include "llbutton.h" +#include "llcachename.h" #include "lllineeditor.h" #include "llscrolllistctrl.h" #include "lltextbox.h" #include "lluictrlfactory.h" -#include "llviewercontrol.h" -#include "llworld.h" +#include "message.h" // [RLVa:KB] #include "rlvhandler.h" @@ -60,45 +65,36 @@ const std::string FLOATER_TITLE = "Choose Resident"; // static LLFloaterAvatarPicker* LLFloaterAvatarPicker::sInstance = NULL; +static std::map sAvatarNameMap; - -LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback, - void* userdata, +LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback, BOOL allow_multiple, BOOL closeOnSelect) { // TODO: This class should not be a singleton as it's used in multiple places // and therefore can't be used simultaneously. -MG - if (!sInstance) + + LLFloaterAvatarPicker* floater = sInstance ? sInstance : new LLFloaterAvatarPicker(); + floater->open(); /* Flawfinder: ignore */ + if(!sInstance) { - sInstance = new LLFloaterAvatarPicker(); - sInstance->mCallback = callback; - sInstance->mCallbackUserdata = userdata; - sInstance->mCloseOnSelect = FALSE; - - sInstance->open(); /* Flawfinder: ignore */ - sInstance->center(); - sInstance->setAllowMultiple(allow_multiple); - } - else - { - sInstance->open(); /*Flawfinder: ignore*/ - sInstance->mCallback = callback; - sInstance->mCallbackUserdata = userdata; - sInstance->setAllowMultiple(allow_multiple); + sInstance = floater; + floater->center(); } - sInstance->mNearMeListComplete = FALSE; - sInstance->mCloseOnSelect = closeOnSelect; - return sInstance; + floater->mSelectionCallback = callback; + floater->setAllowMultiple(allow_multiple); + floater->mNearMeListComplete = FALSE; + floater->mCloseOnSelect = closeOnSelect; + return floater; } // Default constructor LLFloaterAvatarPicker::LLFloaterAvatarPicker() : LLFloater(std::string("avatarpicker"), FLOATER_RECT, FLOATER_TITLE, TRUE, MIN_WIDTH, MIN_HEIGHT), - mResultsReturned(FALSE), - mCallback(NULL), - mCallbackUserdata(NULL) + mNumResultsReturned(0), + mNearMeListComplete(FALSE), + mCloseOnSelect(FALSE) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_picker.xml", NULL); } @@ -108,23 +104,25 @@ BOOL LLFloaterAvatarPicker::postBuild() childSetKeystrokeCallback("Edit", editKeystroke, this); childSetKeystrokeCallback("EditUUID", editKeystroke, this); - childSetAction("Find", onBtnFind, this); - childDisable("Find"); - childSetAction("Refresh", onBtnRefresh, this); - childSetCommitCallback("near_me_range", onRangeAdjust, this); + childSetAction("Find", boost::bind(&LLFloaterAvatarPicker::onBtnFind, this)); + getChildView("Find")->setEnabled(FALSE); + childSetAction("Refresh", boost::bind(&LLFloaterAvatarPicker::onBtnRefresh, this)); + getChild("near_me_range")->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onRangeAdjust, this)); - childSetDoubleClickCallback("SearchResults", onBtnSelect); - childSetDoubleClickCallback("NearMe", onBtnSelect); - childSetCommitCallback("SearchResults", onList, this); - childSetCommitCallback("NearMe", onList, this); - childDisable("SearchResults"); + LLScrollListCtrl* searchresults = getChild("SearchResults"); + searchresults->setDoubleClickCallback( boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); + searchresults->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onList, this)); + getChildView("SearchResults")->setEnabled(FALSE); - childSetAction("Select", onBtnSelect, this); - childDisable("Select"); + LLScrollListCtrl* nearme = getChild("NearMe"); + nearme->setDoubleClickCallback(boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); + nearme->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onList, this)); - childSetAction("Cancel", onBtnClose, this); + childSetAction("Select", boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); + getChildView("Select")->setEnabled(FALSE); + childSetAction("Cancel", boost::bind(&LLFloaterAvatarPicker::onBtnClose, this)); - childSetFocus("Edit"); + getChild("Edit")->setFocus(TRUE); LLPanel* search_panel = getChild("SearchPanel"); if (search_panel) @@ -133,16 +131,17 @@ BOOL LLFloaterAvatarPicker::postBuild() search_panel->setDefaultBtn("Find"); } - getChild("SearchResults")->addCommentText(getString("no_results")); + getChild("SearchResults")->setCommentText(getString("no_results")); LLInventoryPanel* inventory_panel = getChild("InventoryPanel"); inventory_panel->setFilterTypes(0x1 << LLInventoryType::IT_CALLINGCARD); inventory_panel->setFollowsAll(); inventory_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); inventory_panel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD); - inventory_panel->setSelectCallback(boost::bind(&LLFloaterAvatarPicker::onCallingCardSelectionChange, _1, _2, (void*)this)); + inventory_panel->setSelectCallback(boost::bind(&LLFloaterAvatarPicker::onCallingCardSelectionChange, this, _1, _2)); - getChild("ResidentChooserTabs")->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onTabChanged,this)); + getChild("ResidentChooserTabs")->setCommitCallback( + boost::bind(&LLFloaterAvatarPicker::onTabChanged,this)); setAllowMultiple(FALSE); @@ -162,13 +161,12 @@ LLFloaterAvatarPicker::~LLFloaterAvatarPicker() sInstance = NULL; } -void LLFloaterAvatarPicker::onBtnFind(void* userdata) +void LLFloaterAvatarPicker::onBtnFind() { - LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; - if(self) self->find(); + find(); } -static void getSelectedAvatarData(const LLScrollListCtrl* from, std::vector& avatar_names, std::vector& avatar_ids) +static void getSelectedAvatarData(const LLScrollListCtrl* from, uuid_vec_t& avatar_ids, std::vector& avatar_names) { std::vector items = from->getAllSelected(); for (std::vector::iterator iter = items.begin(); iter != items.end(); ++iter) @@ -176,105 +174,141 @@ static void getSelectedAvatarData(const LLScrollListCtrl* from, std::vectorgetUUID().notNull()) { - avatar_names.push_back(item->getColumn(0)->getValue().asString()); avatar_ids.push_back(item->getUUID()); + + std::map::iterator iter = sAvatarNameMap.find(item->getUUID()); + if (iter != sAvatarNameMap.end()) + { + avatar_names.push_back(iter->second); + } + else + { + // the only case where it isn't in the name map is friends + // but it should be in the name cache + LLAvatarName av_name; + LLAvatarNameCache::get(item->getUUID(), &av_name); + avatar_names.push_back(av_name); + } } } } -void LLFloaterAvatarPicker::onBtnSelect(void* userdata) +void LLFloaterAvatarPicker::onBtnSelect() { - LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; - if(self->mCallback) + // If select btn not enabled then do not callback + if (!visibleItemsSelected()) + return; + + if(mSelectionCallback) { - LLPanel* active_panel = self->childGetVisibleTab("ResidentChooserTabs"); - - if(active_panel == self->getChild("CallingCardsPanel")) + std::vector avatar_names; + std::vector avatar_ids; + std::string active_panel_name; + LLScrollListCtrl* list = NULL; + LLPanel* active_panel = childGetVisibleTab("ResidentChooserTabs"); + if(active_panel) { - self->mCallback(self->mSelectedInventoryAvatarNames, self->mSelectedInventoryAvatarIDs, self->mCallbackUserdata); + active_panel_name = active_panel->getName(); } - else if(active_panel == self->getChild("SearchPanel")) + if(active_panel_name == "CallingCardsPanel") { - std::vector avatar_names; - std::vector avatar_ids; - getSelectedAvatarData(self->getChild("SearchResults"), avatar_names, avatar_ids); - self->mCallback(avatar_names, avatar_ids, self->mCallbackUserdata); + avatar_ids = mSelectedInventoryAvatarIDs; + for(std::vector::size_type i = 0; i < avatar_ids.size(); ++i) + { + std::map::iterator iter = sAvatarNameMap.find(avatar_ids[i]); + LLAvatarName av_name; + if (iter != sAvatarNameMap.end()) + { + avatar_names.push_back(iter->second); + } + else if(LLAvatarNameCache::get(avatar_ids[i], &av_name)) + { + avatar_names.push_back(av_name); + } + else + { + std::string name = gCacheName->buildLegacyName(mSelectedInventoryAvatarNames[i]); + std::string::size_type pos = name.find(' '); + av_name.mLegacyFirstName = name.substr(pos); + av_name.mLegacyLastName = pos!=std::string::npos ? name.substr(pos+1) : "Resident"; + av_name.mDisplayName = name; + av_name.mUsername = ""; + avatar_names.push_back(av_name); + } + } } - else if(active_panel == self->getChild("NearMePanel")) + else if(active_panel_name == "SearchPanel") { - std::vector avatar_names; - std::vector avatar_ids; - getSelectedAvatarData(self->getChild("NearMe"), avatar_names, avatar_ids); - self->mCallback(avatar_names, avatar_ids, self->mCallbackUserdata); + list = getChild("SearchResults"); } - else if(active_panel == self->getChild("KeyPanel")) + else if(active_panel_name == "NearMePanel") { - LLUUID specified = self->getChild("EditUUID")->getValue().asUUID(); + list = getChild("NearMe"); + } + else if(active_panel_name == "KeyPanel") + { + LLUUID specified = getChild("EditUUID")->getValue().asUUID(); if(specified.isNull()) return; - std::vector avatar_names; - std::vector avatar_ids; avatar_ids.push_back(specified); - avatar_names.push_back(specified.asString()); - self->mCallback(avatar_names, avatar_ids, self->mCallbackUserdata); + + std::map::iterator iter = sAvatarNameMap.find(specified); + if (iter != sAvatarNameMap.end()) + { + avatar_names.push_back(iter->second); + } + else + { + LLAvatarName av_name; + LLAvatarNameCache::get(specified, &av_name); + avatar_names.push_back(av_name); + } + } + + if(list) + { + getSelectedAvatarData(list, avatar_ids, avatar_names); + } + if(!avatar_names.empty() && !avatar_ids.empty()) + { + mSelectionCallback(avatar_ids, avatar_names); } } - self->getChild("InventoryPanel")->setSelection(LLUUID::null, FALSE); - self->getChild("SearchResults")->deselectAllItems(TRUE); - self->getChild("NearMe")->deselectAllItems(TRUE); - if(self->mCloseOnSelect) + getChild("InventoryPanel")->setSelection(LLUUID::null, FALSE); + getChild("SearchResults")->deselectAllItems(TRUE); + getChild("NearMe")->deselectAllItems(TRUE); + if(mCloseOnSelect) { - self->mCloseOnSelect = FALSE; - self->close(); + mCloseOnSelect = FALSE; + close(); } } -void LLFloaterAvatarPicker::onBtnRefresh(void* userdata) +void LLFloaterAvatarPicker::onBtnRefresh() { - LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; - if (!self) - { - return; - } - - self->getChild("NearMe")->deleteAllItems(); - self->getChild("NearMe")->addCommentText(self->getString("searching")); - self->mNearMeListComplete = FALSE; + getChild("NearMe")->deleteAllItems(); + getChild("NearMe")->setCommentText(getString("searching")); + mNearMeListComplete = FALSE; } -void LLFloaterAvatarPicker::onBtnClose(void* userdata) +void LLFloaterAvatarPicker::onBtnClose() { - LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; - if(self) self->close(); + close(); } -void LLFloaterAvatarPicker::onRangeAdjust(LLUICtrl* source, void* data) +void LLFloaterAvatarPicker::onRangeAdjust() { - LLFloaterAvatarPicker::onBtnRefresh(data); + onBtnRefresh(); } -void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata) +void LLFloaterAvatarPicker::onList() { - LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; - if (self) - { - self->childSetEnabled("Select", self->visibleItemsSelected()); - } -} - -// static callback for inventory picker (select from calling cards) -void LLFloaterAvatarPicker::onCallingCardSelectionChange(const std::deque &items, BOOL user_action, void* data) -{ - LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)data; - if (self) - { - self->doCallingCardSelectionChange( items, user_action, data ); - } + getChildView("Select")->setEnabled(visibleItemsSelected()); } // Callback for inventory picker (select from calling cards) -void LLFloaterAvatarPicker::doCallingCardSelectionChange(const std::deque &items, BOOL user_action, void* data) +void LLFloaterAvatarPicker::onCallingCardSelectionChange(const std::deque &items, BOOL user_action) { bool panel_active = (childGetVisibleTab("ResidentChooserTabs") == getChild("CallingCardsPanel")); @@ -314,7 +348,7 @@ void LLFloaterAvatarPicker::populateNearMe() LLScrollListCtrl* near_me_scroller = getChild("NearMe"); near_me_scroller->deleteAllItems(); - std::vector avatar_ids; + uuid_vec_t avatar_ids; LLWorld::getInstance()->getAvatars(&avatar_ids, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange")); for(U32 i=0; igetFullName(av, fullname)) + LLAvatarName av_name; + + if (!LLAvatarNameCache::get(av, &av_name)) { + element["columns"][0]["column"] = "name"; element["columns"][0]["value"] = LLCacheName::getDefaultName(); all_loaded = FALSE; } else { - element["columns"][0]["value"] = fullname; + element["columns"][0]["column"] = "name"; + element["columns"][0]["value"] = av_name.mDisplayName; + element["columns"][1]["column"] = "username"; + element["columns"][1]["value"] = av_name.mUsername; + + sAvatarNameMap[av] = av_name; } near_me_scroller->addElement(element); empty = FALSE; @@ -338,16 +379,16 @@ void LLFloaterAvatarPicker::populateNearMe() if (empty) { - childDisable("NearMe"); - childDisable("Select"); - near_me_scroller->addCommentText(getString("no_one_near")); + getChildView("NearMe")->setEnabled(FALSE); + getChildView("Select")->setEnabled(FALSE); + near_me_scroller->setCommentText(getString("no_one_near")); } else { - childEnable("NearMe"); - childEnable("Select"); + getChildView("NearMe")->setEnabled(TRUE); + getChildView("Select")->setEnabled(TRUE); near_me_scroller->selectFirstItem(); - onList(near_me_scroller, this); + onList(); near_me_scroller->setFocus(TRUE); } @@ -400,38 +441,104 @@ BOOL LLFloaterAvatarPicker::visibleItemsSelected() const } else if(active_panel == getChild("CallingCardsPanel")) { - return mSelectedInventoryAvatarIDs.size() > 0; + return !mSelectedInventoryAvatarIDs.empty(); } else if(active_panel == getChild("NearMePanel")) { return getChild("NearMe")->getFirstSelectedIndex() >= 0; } + else if(active_panel == getChild("KeyPanel")) + { + LLUUID specified = getChild("EditUUID")->getValue().asUUID(); + return !specified.isNull(); + } return FALSE; } +extern AIHTTPTimeoutPolicy avatarPickerResponder_timeout; +class LLAvatarPickerResponder : public LLHTTPClient::ResponderWithCompleted +{ +public: + LLUUID mQueryID; + + LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { } + + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) + { + //std::ostringstream ss; + //LLSDSerialize::toPrettyXML(content, ss); + //llinfos << ss.str() << llendl; + + // in case of invalid characters, the avatar picker returns a 400 + // just set it to process so it displays 'not found' + if ((200 <= status && status < 300) || status == 400) + { + LLFloaterAvatarPicker* floater = LLFloaterAvatarPicker::sInstance; + if (floater) + { + floater->processResponse(mQueryID, content); + } + } + else + { + llinfos << "avatar picker failed " << status + << " reason " << reason << llendl; + + } + } + + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return avatarPickerResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLAvatarPickerResponder"; } +}; + void LLFloaterAvatarPicker::find() { + //clear our stored LLAvatarNames + sAvatarNameMap.clear(); + const std::string& text = childGetValue("Edit").asString(); mQueryID.generate(); - LLMessageSystem* msg = gMessageSystem; + std::string url; + url.reserve(128); // avoid a memory allocation or two - 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(); + LLViewerRegion* region = gAgent.getRegion(); + url = region->getCapability("AvatarPickerSearch"); + // Prefer use of capabilities to search on both SLID and display name + // but allow display name search to be manually turned off for test + if (!url.empty() + && LLAvatarNameCache::useDisplayNames()) + { + // 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="; + url += LLURI::escape(text); + llinfos << "avatar picker " << url << llendl; + LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID)); + } + 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("SearchResults")->deleteAllItems(); - getChild("SearchResults")->addCommentText(getString("searching")); + getChild("SearchResults")->setCommentText(getString("searching")); childSetEnabled("Select", FALSE); - mResultsReturned = FALSE; + mNumResultsReturned = 0; } void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple) @@ -457,21 +564,21 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* if (agent_id != gAgent.getID()) return; // Dialog already closed - LLFloaterAvatarPicker *self = sInstance; - if (!self) return; + LLFloaterAvatarPicker *floater = sInstance; - // these are not results from our last request - if (query_id != self->mQueryID) + // floater is closed or these are not results from our last request + if (NULL == floater || query_id != floater->mQueryID) { return; } - LLScrollListCtrl* search_results = self->getChild("SearchResults"); + LLScrollListCtrl* search_results = floater->getChild("SearchResults"); // clear "Searching" label on first results - search_results->deleteAllItems(); - - self->mResultsReturned = TRUE; + if (floater->mNumResultsReturned++ == 0) + { + search_results->deleteAllItems(); + } BOOL found_one = FALSE; S32 num_new_rows = msg->getNumberOfBlocks("Data"); @@ -485,32 +592,92 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* if (avatar_id.isNull()) { LLStringUtil::format_map_t map; - map["[TEXT]"] = self->childGetText("Edit"); - avatar_name = self->getString("not_found", map); + map["[TEXT]"] = floater->childGetText("Edit"); + avatar_name = floater->getString("not_found", map); search_results->setEnabled(FALSE); - self->childDisable("Select"); + floater->getChildView("Select")->setEnabled(FALSE); } else { - avatar_name = first_name + " " + last_name; + avatar_name = LLCacheName::buildFullName(first_name, last_name); search_results->setEnabled(TRUE); found_one = TRUE; + + LLAvatarName av_name; + av_name.mLegacyFirstName = first_name; + av_name.mLegacyLastName = last_name; + av_name.mDisplayName = avatar_name; + const LLUUID& agent_id = avatar_id; + sAvatarNameMap[agent_id] = av_name; + } LLSD element; element["id"] = avatar_id; // value + element["columns"][0]["column"] = "name"; element["columns"][0]["value"] = avatar_name; search_results->addElement(element); } if (found_one) { - self->childEnable("Select"); + floater->getChildView("Select")->setEnabled(TRUE); search_results->selectFirstItem(); - self->onList(search_results, self); + floater->onList(); search_results->setFocus(TRUE); } } +void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& content) +{ + // Check for out-of-date query + if (query_id != mQueryID) return; + + LLScrollListCtrl* search_results = getChild("SearchResults"); + + LLSD agents = content["agents"]; + if (agents.size() == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = childGetText("Edit"); + LLSD item; + item["id"] = LLUUID::null; + item["columns"][0]["column"] = "name"; + item["columns"][0]["value"] = getString("not_found", map); + search_results->addElement(item); + search_results->setEnabled(false); + getChildView("Select")->setEnabled(false); + return; + } + + // clear "Searching" label on first results + search_results->deleteAllItems(); + + LLSD item; + LLSD::array_const_iterator it = agents.beginArray(); + for ( ; it != agents.endArray(); ++it) + { + const LLSD& row = *it; + item["id"] = row["id"]; + LLSD& columns = item["columns"]; + columns[0]["column"] = "name"; + columns[0]["value"] = row["display_name"]; + columns[1]["column"] = "username"; + columns[1]["value"] = row["username"]; + search_results->addElement(item); + + // add the avatar name to our list + LLAvatarName avatar_name; + avatar_name.fromLLSD(row); + sAvatarNameMap[row["id"].asUUID()] = avatar_name; + } + + getChildView("Select")->setEnabled(true); + search_results->setEnabled(true); + search_results->selectFirstItem(); + onList(); + search_results->setFocus(TRUE); +} + //static void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data) { @@ -530,13 +697,13 @@ BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask) { if (key == KEY_RETURN && mask == MASK_NONE) { - if (childHasFocus("Edit")) + if (getChild("Edit")->hasFocus()) { - onBtnFind(this); + onBtnFind(); } else { - onBtnSelect(this); + onBtnSelect(); } return TRUE; } diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index 17b928f40..2fc8543a8 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -37,35 +37,40 @@ #include +class LLAvatarName; +class LLScrollListCtrl; class LLFloaterAvatarPicker : public LLFloater { public: - // Call this to select an avatar. + typedef boost::signals2::signal validate_signal_t; + typedef validate_signal_t::slot_type validate_callback_t; + // The callback function will be called with an avatar name and UUID. - typedef void(*callback_t)(const std::vector&, const std::vector&, void*); - static LLFloaterAvatarPicker* show(callback_t callback, - void* userdata, + typedef boost::function&)> select_callback_t; + // Call this to select an avatar. + static LLFloaterAvatarPicker* show(select_callback_t callback, BOOL allow_multiple = FALSE, BOOL closeOnSelect = FALSE); virtual BOOL postBuild(); static void processAvatarPickerReply(class LLMessageSystem* msg, void**); + void processResponse(const LLUUID& query_id, const LLSD& content); + static LLFloaterAvatarPicker* sInstance; private: static void editKeystroke(class LLLineEditor* caller, void* user_data); - static void onBtnFind(void* userdata); - static void onBtnSelect(void* userdata); - static void onBtnRefresh(void* userdata); - static void onRangeAdjust(LLUICtrl* source, void* data); - static void onBtnClose(void* userdata); - static void onList(class LLUICtrl* ctrl, void* userdata); + void onBtnFind(); + void onBtnSelect(); + void onBtnRefresh(); + void onRangeAdjust(); + void onBtnClose(); + void onList(); void onTabChanged(); - void doCallingCardSelectionChange(const std::deque &items, BOOL user_action, void* data); - static void onCallingCardSelectionChange(const std::deque &items, BOOL user_action, void* data); + void onCallingCardSelectionChange(const std::deque &items, BOOL user_action); void populateNearMe(); BOOL visibleItemsSelected() const; // Returns true if any items in the current tab are selected. @@ -79,14 +84,11 @@ private: std::vector mSelectedInventoryAvatarIDs; std::vector mSelectedInventoryAvatarNames; LLUUID mQueryID; - BOOL mResultsReturned; + int mNumResultsReturned; BOOL mNearMeListComplete; BOOL mCloseOnSelect; - void (*mCallback)(const std::vector& name, const std::vector& id, void* userdata); - void* mCallbackUserdata; - - static LLFloaterAvatarPicker* sInstance; + select_callback_t mSelectionCallback; // do not call these directly LLFloaterAvatarPicker(); diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index 70f79f3c5..4e6312175 100644 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -40,7 +40,7 @@ #include "llviewerobjectlist.h" #include "llvoavatar.h" -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines; LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLUUID& id) : LLFloater(std::string("avatar_texture_debug")), @@ -72,7 +72,7 @@ BOOL LLFloaterAvatarTextures::postBuild() { for (U32 i=0; i < TEX_NUM_INDICES; i++) { - const std::string tex_name = LLVOAvatarDictionary::getInstance()->getTexture(ETextureIndex(i))->mName; + const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(ETextureIndex(i))->mName; mTextures[i] = getChild(tex_name); } mTitle = getTitle(); diff --git a/indra/newview/llfloateravatartextures.h b/indra/newview/llfloateravatartextures.h index 4138edeb4..82bf95423 100644 --- a/indra/newview/llfloateravatartextures.h +++ b/indra/newview/llfloateravatartextures.h @@ -36,7 +36,7 @@ #include "llfloater.h" #include "lluuid.h" #include "llstring.h" -#include "llvoavatardefines.h" +#include "llavatarappearancedefines.h" class LLTextureCtrl; @@ -59,7 +59,7 @@ private: private: LLUUID mID; std::string mTitle; - LLTextureCtrl* mTextures[LLVOAvatarDefines::TEX_NUM_INDICES]; + LLTextureCtrl* mTextures[LLAvatarAppearanceDefines::TEX_NUM_INDICES]; }; #endif diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index 287b799bd..78aefe250 100644 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -95,7 +95,7 @@ void LLFloaterBulkPermission::doApply() LLSelectMgr::getInstance()->getSelection()->applyToNodes(&gatherer); if(mObjectIDs.empty()) { - list->addCommentText(getString("nothing_to_modify_text")); + list->setCommentText(getString("nothing_to_modify_text")); } else { @@ -180,7 +180,7 @@ void LLFloaterBulkPermission::onCommitCopy(LLUICtrl* ctrl, void* data) BOOL LLFloaterBulkPermission::start() { // note: number of top-level objects to modify is mObjectIDs.count(). - getChild("queue output")->addCommentText(getString("start_text")); + getChild("queue output")->addSimpleElement(getString("start_text")); return nextObject(); } @@ -203,7 +203,7 @@ BOOL LLFloaterBulkPermission::nextObject() if(isDone() && !mDone) { - getChild("queue output")->addCommentText(getString("done_text")); + getChild("queue output")->addSimpleElement(getString("done_text")); mDone = TRUE; } return successful_start; @@ -349,7 +349,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInv status_text.setArg("[STATUS]", ""); } - list->addCommentText(status_text.getString()); + list->addSimpleElement(status_text.getString()); //TODO if we are an object inside an object we should check a recuse flag and if set //open the inventory of the object and recurse - Michelle2 Zenovka diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index 66a417dda..0bde0cfee 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -54,6 +54,7 @@ #include "llviewerregion.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" +#include "llinventoryicon.h" #include "hippogridmanager.h" diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 2c1631987..02468dd65 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -512,7 +512,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo() LLTextBox* resellable_clause = getChild("resellable_clause"); if (resellable_clause) { - if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) + if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)) { resellable_clause->setText(getString("can_not_resell")); } @@ -525,7 +525,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo() LLTextBox* changeable_clause = getChild("changeable_clause"); if (changeable_clause) { - if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) + if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES)) { changeable_clause->setText(getString("can_change")); } diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index 22281826d..db38f8009 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -108,7 +108,8 @@ LLFloaterChat::LLFloaterChat(const LLSD& seed) mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL); // do not automatically open singleton floaters (as result of getInstance()) BOOL no_open = FALSE; - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_chat_history.xml",&getFactoryMap(),no_open); + bool show_bar = gSavedSettings.getBOOL("ShowLocalChatFloaterBar"); + LLUICtrlFactory::getInstance()->buildFloater(this, (show_bar ? "floater_chat_history.xml" : "floater_chat_history_barless.xml"), &getFactoryMap(), no_open); childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes childSetCommitCallback("translate chat",onClickToggleTranslateChat,this); @@ -317,8 +318,9 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) } else { + static LLCachedControl color_muted_chat("ColorMutedChat"); // desaturate muted chat - LLColor4 muted_color = lerp(color, LLColor4::grey, 0.5f); + LLColor4 muted_color = lerp(color, color_muted_chat ? gSavedSettings.getColor4("AscentMutedColor") : LLColor4::grey, 0.5f); add_timestamped_line(history_editor_with_mute, chat, muted_color); } @@ -493,7 +495,7 @@ void LLFloaterChat::triggerAlerts(const std::string& text) { // Cannot instantiate LLTextParser before logging in. if (gDirUtilp->getLindenUserDir(true).empty()) - return; + return; LLTextParser* parser = LLTextParser::getInstance(); // bool spoken=FALSE; @@ -539,7 +541,11 @@ LLColor4 get_text_color(const LLChat& chat) if(chat.mMuted) { - text_color.setVec(0.8f, 0.8f, 0.8f, 1.f); + static LLCachedControl color_muted_chat("ColorMutedChat"); + if (color_muted_chat) + text_color = gSavedSettings.getColor4("AscentMutedColor"); + else + text_color.setVec(0.8f, 0.8f, 0.8f, 1.f); } else { @@ -549,7 +555,7 @@ LLColor4 get_text_color(const LLChat& chat) text_color = gSavedSettings.getColor4("SystemChatColor"); break; case CHAT_SOURCE_AGENT: - if (chat.mFromID.isNull()) + if (chat.mFromID.isNull()) { text_color = gSavedSettings.getColor4("SystemChatColor"); } @@ -561,7 +567,34 @@ LLColor4 get_text_color(const LLChat& chat) } else { - text_color = gSavedSettings.getColor4("AgentChatColor"); + static LLCachedControl color_linden_chat("ColorLindenChat"); + if (color_linden_chat && LLMuteList::getInstance()->isLinden(chat.mFromName)) + { + text_color = gSavedSettings.getColor4("AscentLindenColor"); + } + else if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) + { + static LLCachedControl color_friend_chat("ColorFriendChat"); + static LLCachedControl color_eo_chat("ColorEstateOwnerChat"); + if (color_friend_chat && LLAvatarTracker::instance().isBuddy(chat.mFromID)) + { + text_color = gSavedSettings.getColor4("AscentFriendColor"); + } + else if (color_eo_chat) + { + LLViewerRegion* parent_estate = gAgent.getRegion(); + if (parent_estate && parent_estate->isAlive() && chat.mFromID == parent_estate->getOwner()) + text_color = gSavedSettings.getColor4("AscentEstateOwnerColor"); + else + text_color = gSavedSettings.getColor4("AgentChatColor"); + } + else + text_color = gSavedSettings.getColor4("AgentChatColor"); + } + else + { + text_color = gSavedSettings.getColor4("AgentChatColor"); + } } } break; diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp index 9e41340fe..876e2c321 100644 --- a/indra/newview/llfloaterchatterbox.cpp +++ b/indra/newview/llfloaterchatterbox.cpp @@ -54,7 +54,8 @@ LLFloaterMyFriends::LLFloaterMyFriends(const LLSD& seed) mFactoryMap["groups_panel"] = LLCallbackMap(LLFloaterMyFriends::createGroupsPanel, NULL); // do not automatically open singleton floaters (as result of getInstance()) BOOL no_open = FALSE; - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_my_friends.xml", &getFactoryMap(), no_open); + static LLCachedControl horiz("ContactsUseHorizontalButtons"); + LLUICtrlFactory::getInstance()->buildFloater(this, (horiz ? "floater_my_friends_horiz.xml" : "floater_my_friends.xml"), &getFactoryMap(), no_open); } LLFloaterMyFriends::~LLFloaterMyFriends() diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 474e4d874..d44e6f7cb 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -78,8 +78,7 @@ const F32 CONTEXT_FADE_TIME = 0.08f; ////////////////////////////////////////////////////////////////////////////// // default ctor -LLFloaterColorPicker:: -LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate ) +LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate ) : LLFloater (std::string("Color Picker Floater")), mComponents ( 3 ), mMouseDownInLumRegion ( FALSE ), @@ -124,10 +123,7 @@ LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate ) } } -////////////////////////////////////////////////////////////////////////////// -// dtor -LLFloaterColorPicker:: -~LLFloaterColorPicker() +LLFloaterColorPicker::~LLFloaterColorPicker() { // destroy the UI we created destroyUI (); @@ -135,9 +131,7 @@ LLFloaterColorPicker:: ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -createUI () +void LLFloaterColorPicker::createUI () { // build the majority of the gui using the factory builder LLUICtrlFactory::getInstance()->buildFloater ( this, "floater_color_picker.xml" ); @@ -184,9 +178,7 @@ createUI () ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -showUI () +void LLFloaterColorPicker::showUI () { setVisible ( TRUE ); setFocus ( TRUE ); @@ -219,27 +211,24 @@ showUI () ////////////////////////////////////////////////////////////////////////////// // called after the dialog is rendered -BOOL -LLFloaterColorPicker:: -postBuild() +BOOL LLFloaterColorPicker::postBuild() { mCancelBtn = getChild( "cancel_btn" ); - mCancelBtn->setClickedCallback ( boost::bind(&LLFloaterColorPicker::onClickCancel,this) ); + mCancelBtn->setClickedCallback ( onClickCancel, this ); mSelectBtn = getChild( "select_btn"); - mSelectBtn->setClickedCallback ( boost::bind(&LLFloaterColorPicker::onClickSelect,this) ); + mSelectBtn->setClickedCallback ( onClickSelect, this ); mSelectBtn->setFocus ( TRUE ); mPipetteBtn = getChild("color_pipette" ); mPipetteBtn->setImages(std::string("eye_button_inactive.tga"), std::string("eye_button_active.tga")); - mPipetteBtn->setClickedCallback( boost::bind(&LLFloaterColorPicker::onClickPipette,this) ); + mPipetteBtn->setClickedCallback( boost::bind(&LLFloaterColorPicker::onClickPipette,this )); mApplyImmediateCheck = getChild("apply_immediate"); mApplyImmediateCheck->set(gSavedSettings.getBOOL("ApplyColorImmediately")); - mApplyImmediateCheck->setCommitCallback(onImmediateCheck); - mApplyImmediateCheck->setCallbackUserData(this); + mApplyImmediateCheck->setCommitCallback(onImmediateCheck, this); childSetCommitCallback("rspin", onTextCommit, (void*)this ); childSetCommitCallback("gspin", onTextCommit, (void*)this ); @@ -249,14 +238,14 @@ postBuild() childSetCommitCallback("lspin", onTextCommit, (void*)this ); childSetCommitCallback("hexval", onHexCommit, (void*)this ); + LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterColorPicker::onColorSelect, this, _1)); + return TRUE; } ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -initUI ( F32 rValIn, F32 gValIn, F32 bValIn ) +void LLFloaterColorPicker::initUI ( F32 rValIn, F32 gValIn, F32 bValIn ) { // start catching lose-focus events from entry widgets enableTextCallbacks ( TRUE ); @@ -278,9 +267,7 @@ initUI ( F32 rValIn, F32 gValIn, F32 bValIn ) ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -destroyUI () +void LLFloaterColorPicker::destroyUI () { // shut down pipette tool if active stopUsingPipette(); @@ -296,7 +283,7 @@ destroyUI () if ( mSwatchView ) { this->removeChild ( mSwatchView ); - delete mSwatchView; + mSwatchView->die();; mSwatchView = NULL; } } @@ -304,9 +291,7 @@ destroyUI () ////////////////////////////////////////////////////////////////////////////// // -F32 -LLFloaterColorPicker:: -hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn ) +F32 LLFloaterColorPicker::hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn ) { if ( valHUeIn < 0.0f ) valHUeIn += 1.0f; if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f; @@ -318,9 +303,7 @@ hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn ) ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -hslToRgb ( F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& bValOut ) +void LLFloaterColorPicker::hslToRgb ( F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& bValOut ) { if ( sValIn < 0.00001f ) { @@ -348,9 +331,7 @@ hslToRgb ( F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& ////////////////////////////////////////////////////////////////////////////// // mutator for original RGB value -void -LLFloaterColorPicker:: -setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn ) +void LLFloaterColorPicker::setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn ) { origR = origRIn; origG = origGIn; @@ -359,9 +340,7 @@ setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn ) ////////////////////////////////////////////////////////////////////////////// // accessor for original RGB value -void -LLFloaterColorPicker:: -getOrigRgb ( F32& origROut, F32& origGOut, F32& origBOut ) +void LLFloaterColorPicker::getOrigRgb ( F32& origROut, F32& origGOut, F32& origBOut ) { origROut = origR; origGOut = origG; @@ -370,9 +349,7 @@ getOrigRgb ( F32& origROut, F32& origGOut, F32& origBOut ) ////////////////////////////////////////////////////////////////////////////// // mutator for current RGB value -void -LLFloaterColorPicker:: -setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn ) +void LLFloaterColorPicker::setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn ) { // save current RGB curR = curRIn; @@ -392,9 +369,7 @@ setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn ) ////////////////////////////////////////////////////////////////////////////// // accessor for current RGB value -void -LLFloaterColorPicker:: -getCurRgb ( F32& curROut, F32& curGOut, F32& curBOut ) +void LLFloaterColorPicker::getCurRgb ( F32& curROut, F32& curGOut, F32& curBOut ) { curROut = curR; curGOut = curG; @@ -403,9 +378,7 @@ getCurRgb ( F32& curROut, F32& curGOut, F32& curBOut ) ////////////////////////////////////////////////////////////////////////////// // mutator for current HSL value -void -LLFloaterColorPicker:: -setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn ) +void LLFloaterColorPicker::setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn ) { // save current HSL curH = curHIn; @@ -418,9 +391,7 @@ setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn ) ////////////////////////////////////////////////////////////////////////////// // accessor for current HSL value -void -LLFloaterColorPicker:: -getCurHsl ( F32& curHOut, F32& curSOut, F32& curLOut ) +void LLFloaterColorPicker::getCurHsl ( F32& curHOut, F32& curSOut, F32& curLOut ) { curHOut = curH; curSOut = curS; @@ -429,9 +400,7 @@ getCurHsl ( F32& curHOut, F32& curSOut, F32& curLOut ) ////////////////////////////////////////////////////////////////////////////// // called when 'cancel' clicked -void -LLFloaterColorPicker:: -onClickCancel ( void* data ) +void LLFloaterColorPicker::onClickCancel ( void* data ) { if (data) { @@ -447,9 +416,7 @@ onClickCancel ( void* data ) ////////////////////////////////////////////////////////////////////////////// // called when 'select' clicked -void -LLFloaterColorPicker:: -onClickSelect ( void* data ) +void LLFloaterColorPicker::onClickSelect ( void* data ) { if (data) { @@ -464,31 +431,23 @@ onClickSelect ( void* data ) } } -void LLFloaterColorPicker::onClickPipette( void* data ) +void LLFloaterColorPicker::onClickPipette() { - LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data; - - if ( self) + BOOL pipette_active = mPipetteBtn->getToggleState(); + pipette_active = !pipette_active; + if (pipette_active) { - BOOL pipette_active = self->mPipetteBtn->getToggleState(); - pipette_active = !pipette_active; - if (pipette_active) - { - LLToolPipette::getInstance()->setSelectCallback(onColorSelect, self); - LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); - } - else - { - LLToolMgr::getInstance()->clearTransientTool(); - } + LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); + } + else + { + LLToolMgr::getInstance()->clearTransientTool(); } } ////////////////////////////////////////////////////////////////////////////// // called when 'text is committed' - i,e. focus moves from a text field -void -LLFloaterColorPicker:: -onTextCommit ( LLUICtrl* ctrl, void* data ) +void LLFloaterColorPicker::onTextCommit ( LLUICtrl* ctrl, void* data ) { if ( data ) { @@ -514,16 +473,12 @@ void LLFloaterColorPicker::onImmediateCheck( LLUICtrl* ctrl, void* data) } } -void LLFloaterColorPicker::onColorSelect( const LLTextureEntry& te, void *data ) +void LLFloaterColorPicker::onColorSelect( const LLTextureEntry& te) { - LLFloaterColorPicker* self = (LLFloaterColorPicker*)data; - if (self) + setCurRgb(te.getColor().mV[VRED], te.getColor().mV[VGREEN], te.getColor().mV[VBLUE]); + if (mApplyImmediateCheck->get()) { - self->setCurRgb(te.getColor().mV[VRED], te.getColor().mV[VGREEN], te.getColor().mV[VBLUE]); - if (self->mApplyImmediateCheck->get()) - { - LLColorSwatchCtrl::onColorChanged ( self->getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE ); - } + LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE ); } } @@ -678,9 +633,7 @@ void LLFloaterColorPicker::draw() ////////////////////////////////////////////////////////////////////////////// // find a complimentary color to the one passed in that can be used to highlight -const LLColor4& -LLFloaterColorPicker:: -getComplimentaryColor ( const LLColor4& backgroundColor ) +const LLColor4& LLFloaterColorPicker::getComplimentaryColor ( const LLColor4& backgroundColor ) { // going to base calculation on luminance F32 hVal, sVal, lVal; @@ -700,9 +653,7 @@ getComplimentaryColor ( const LLColor4& backgroundColor ) ////////////////////////////////////////////////////////////////////////////// // draw color palette -void -LLFloaterColorPicker:: -drawPalette () +void LLFloaterColorPicker::drawPalette () { S32 curEntry = 0; @@ -764,9 +715,7 @@ std::string RGBToHex(int rNum, int gNum, int bNum) } //Called when a hex value is entered into the Hex field - Convert and set values. -void -LLFloaterColorPicker:: -onHexCommit ( LLUICtrl* ctrl, void* data ) +void LLFloaterColorPicker::onHexCommit ( LLUICtrl* ctrl, void* data ) { if ( data ) { @@ -839,9 +788,7 @@ enableTextCallbacks ( BOOL stateIn ) ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -onTextEntryChanged ( LLUICtrl* ctrl ) +void LLFloaterColorPicker::onTextEntryChanged ( LLUICtrl* ctrl ) { // value in RGB boxes changed std::string name = ctrl->getName(); @@ -910,9 +857,7 @@ onTextEntryChanged ( LLUICtrl* ctrl ) ////////////////////////////////////////////////////////////////////////////// // -BOOL -LLFloaterColorPicker:: -updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn ) +BOOL LLFloaterColorPicker::updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn ) { if ( xPosIn >= mRGBViewerImageLeft && xPosIn <= mRGBViewerImageLeft + mRGBViewerImageWidth && @@ -948,9 +893,7 @@ updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn ) ////////////////////////////////////////////////////////////////////////////// // -BOOL -LLFloaterColorPicker:: -handleMouseDown ( S32 x, S32 y, MASK mask ) +BOOL LLFloaterColorPicker::handleMouseDown ( S32 x, S32 y, MASK mask ) { // make it the frontmost gFloaterView->bringToFront(this); @@ -1052,9 +995,7 @@ handleMouseDown ( S32 x, S32 y, MASK mask ) ////////////////////////////////////////////////////////////////////////////// // -BOOL -LLFloaterColorPicker:: -handleHover ( S32 x, S32 y, MASK mask ) +BOOL LLFloaterColorPicker::handleHover ( S32 x, S32 y, MASK mask ) { // if we're the front most window if ( isFrontmost () ) @@ -1130,9 +1071,7 @@ void LLFloaterColorPicker::onClose(bool app_quitting) ////////////////////////////////////////////////////////////////////////////// // reverts state once mouse button is released -BOOL -LLFloaterColorPicker:: -handleMouseUp ( S32 x, S32 y, MASK mask ) +BOOL LLFloaterColorPicker::handleMouseUp ( S32 x, S32 y, MASK mask ) { getWindow()->setCursor ( UI_CURSOR_ARROW ); @@ -1207,9 +1146,7 @@ handleMouseUp ( S32 x, S32 y, MASK mask ) ////////////////////////////////////////////////////////////////////////////// // cancel current color selection, revert to original and close picker -void -LLFloaterColorPicker:: -cancelSelection () +void LLFloaterColorPicker::cancelSelection () { // restore the previous color selection setCurRgb ( getOrigR (), getOrigG (), getOrigB () ); diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index b93ea664c..185b2a400 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -123,11 +123,11 @@ class LLFloaterColorPicker // callbacks static void onClickCancel ( void* data ); static void onClickSelect ( void* data ); - static void onClickPipette ( void* data ); + void onClickPipette ( ); static void onTextCommit ( LLUICtrl* ctrl, void* data ); - static void onHexCommit ( LLUICtrl* ctrl, void* data ); static void onImmediateCheck ( LLUICtrl* ctrl, void* data ); - static void onColorSelect( const LLTextureEntry& te, void *data ); + static void onHexCommit ( LLUICtrl* ctrl, void* data ); + void onColorSelect( const LLTextureEntry& te ); private: // turns on or off text entry commit call backs void enableTextCallbacks ( BOOL stateIn ); diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index 890d80829..f46daa693 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -32,7 +32,6 @@ #include "llviewerprecompiledheaders.h" -#include "llappearancemgr.h" #include "llimagejpeg.h" #include "llfloatercustomize.h" #include "llfontgl.h" @@ -51,7 +50,6 @@ #include "llscrollcontainer.h" #include "llscrollingpanelparam.h" #include "llsliderctrl.h" -#include "lltabcontainervertical.h" #include "llviewerwindow.h" #include "llinventoryfunctions.h" #include "llinventoryobserver.h" @@ -64,7 +62,6 @@ #include "llviewercamera.h" #include "llappearance.h" #include "imageids.h" -#include "llmodaldialog.h" #include "llassetstorage.h" #include "lltexturectrl.h" #include "lltextureentry.h" @@ -79,17 +76,15 @@ #include "lluictrlfactory.h" #include "llnotificationsutil.h" #include "llpaneleditwearable.h" +#include "llmakeoutfitdialog.h" +#include "llagentcamera.h" #include "statemachine/aifilepicker.h" -#include "hippogridmanager.h" -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines; // *TODO:translate : The ui xml for this really needs to be integrated with the appearance paramaters -// Globals -LLFloaterCustomize* gFloaterCustomize = NULL; - ///////////////////////////////////////////////////////////////////// // LLFloaterCustomizeObserver @@ -119,240 +114,23 @@ BOOL edit_wearable_for_teens(LLWearableType::EType type) } } -class LLMakeOutfitDialog : public LLModalDialog -{ -private: - std::string mFolderName; - void (*mCommitCallback)(LLMakeOutfitDialog*,void*); - void* mCallbackUserData; - std::vector > mCheckBoxList; - -public: - LLMakeOutfitDialog( void(*commit_cb)(LLMakeOutfitDialog*,void*), void* userdata ) - : LLModalDialog(LLStringUtil::null,515, 510, TRUE ), - mCommitCallback( commit_cb ), - mCallbackUserData( userdata ) - { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_new_outfit_dialog.xml"); - - // Build list of check boxes - for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ ) - { - std::string name = std::string("checkbox_") + LLWearableType::getTypeLabel( (LLWearableType::EType)i ); - mCheckBoxList.push_back(std::make_pair(name,i)); - // Hide teen items - if (gAgent.isTeen() && - !edit_wearable_for_teens((LLWearableType::EType)i)) - { - // hide wearable checkboxes that don't apply to this account - std::string name = std::string("checkbox_") + LLWearableType::getTypeLabel( (LLWearableType::EType)i ); - childSetVisible(name, FALSE); - } - } - - // NOTE: .xml needs to be updated if attachments are added or their names are changed! - LLVOAvatar* avatar = gAgentAvatarp; - if( avatar ) - { - for (LLVOAvatar::attachment_map_t::iterator iter = avatar->mAttachmentPoints.begin(); - iter != avatar->mAttachmentPoints.end(); ) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - S32 attachment_pt = curiter->first; - BOOL object_attached = ( attachment->getNumObjects() > 0 ); - std::string name = std::string("checkbox_") + attachment->getName(); - mCheckBoxList.push_back(std::make_pair(name,attachment_pt)); - childSetEnabled(name, object_attached); - } - } - - if(!gHippoGridManager->getConnectedGrid()->supportsInvLinks()) { - childSetEnabled("checkbox_use_links", FALSE); - childSetValue("checkbox_use_links", FALSE); - childSetEnabled("checkbox_use_outfits", FALSE); - childSetValue("checkbox_use_outfits", FALSE); - } - - childSetAction("Save", onSave, this ); - childSetAction("Cancel", onCancel, this ); - childSetAction("Check All", onCheckAll, this ); - childSetAction("Uncheck All", onUncheckAll, this ); - - LLCheckBoxCtrl* pOutfitFoldersCtrl = getChild("checkbox_use_outfits"); - pOutfitFoldersCtrl->setCommitCallback(&LLMakeOutfitDialog::onOutfitFoldersToggle); - pOutfitFoldersCtrl->setCallbackUserData(this); - } - - bool getUseOutfits() - { - return childGetValue("checkbox_use_outfits").asBoolean(); - } - bool getUseLinks() - { - return childGetValue("checkbox_use_links").asBoolean(); - } - /*bool getRenameClothing() - { - return childGetValue("rename").asBoolean(); - }*/ - virtual void draw() - { - BOOL one_or_more_items_selected = FALSE; - for( S32 i = 0; i < (S32)mCheckBoxList.size(); i++ ) - { - if( childGetValue(mCheckBoxList[i].first).asBoolean() ) - { - one_or_more_items_selected = TRUE; - break; - } - } - - childSetEnabled("Save", one_or_more_items_selected ); - - LLModalDialog::draw(); - } - - const std::string& getFolderName() { return mFolderName; } - - void setWearableToInclude( S32 wearable, S32 enabled, S32 selected ) - { - LLWearableType::EType wtType = (LLWearableType::EType)wearable; - if ( ( (0 <= wtType) && (wtType < LLWearableType::WT_COUNT) ) && - ( (LLAssetType::AT_BODYPART != LLWearableType::getAssetType(wtType)) || (!getUseOutfits()) ) ) - { - std::string name = std::string("checkbox_") + LLWearableType::getTypeLabel(wtType); - childSetEnabled(name, enabled); - childSetValue(name, selected); - } - } - - void getIncludedItems( LLInventoryModel::item_array_t& item_list ) - { - LLInventoryModel::cat_array_t *cats; - LLInventoryModel::item_array_t *items; - gInventory.getDirectDescendentsOf(LLAppearanceMgr::instance().getCOF(), cats, items); - for (LLInventoryModel::item_array_t::const_iterator iter = items->begin(); - iter != items->end(); - ++iter) - { - LLViewerInventoryItem* item = (*iter); - if(!item) - continue; - if(item->isWearableType()) - { - LLWearableType::EType type = item->getWearableType(); - if (type < LLWearableType::WT_COUNT && childGetValue(mCheckBoxList[type].first).asBoolean()) - { - item_list.push_back(item); - } - } - else - { - LLViewerJointAttachment* attachment = gAgentAvatarp->getWornAttachmentPoint(item->getLinkedUUID()); - if(attachment && childGetValue(std::string("checkbox_")+attachment->getName()).asBoolean()) - { - item_list.push_back(item); - } - } - } - } - - static void onSave( void* userdata ) - { - LLMakeOutfitDialog* self = (LLMakeOutfitDialog*) userdata; - self->mFolderName = self->childGetValue("name ed").asString(); - LLStringUtil::trim(self->mFolderName); - if( !self->mFolderName.empty() ) - { - if( self->mCommitCallback ) - { - self->mCommitCallback( self, self->mCallbackUserData ); - } - self->close(); // destroys this object - } - } - - static void onCheckAll( void* userdata ) - { - LLMakeOutfitDialog* self = (LLMakeOutfitDialog*) userdata; - for( S32 i = 0; i < (S32)(self->mCheckBoxList.size()); i++) - { - std::string name = self->mCheckBoxList[i].first; - if(self->childIsEnabled(name))self->childSetValue(name,TRUE); - } - } - - static void onUncheckAll( void* userdata ) - { - LLMakeOutfitDialog* self = (LLMakeOutfitDialog*) userdata; - for( S32 i = 0; i < (S32)(self->mCheckBoxList.size()); i++) - { - std::string name = self->mCheckBoxList[i].first; - if(self->childIsEnabled(name))self->childSetValue(name,FALSE); - } - } - - static void onCancel( void* userdata ) - { - LLMakeOutfitDialog* self = (LLMakeOutfitDialog*) userdata; - self->close(); // destroys this object - } - - BOOL postBuild() - { - refresh(); - return TRUE; - } - - void refresh() - { - BOOL fUseOutfits = getUseOutfits(); - - for (S32 idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++ ) - { - LLWearableType::EType wtType = (LLWearableType::EType)idxType; - if (LLAssetType::AT_BODYPART != LLWearableType::getAssetType(wtType)) - continue; - LLCheckBoxCtrl* pCheckCtrl = getChild(std::string("checkbox_") + LLWearableType::getTypeLabel(wtType)); - if (!pCheckCtrl) - continue; - - pCheckCtrl->setEnabled(!fUseOutfits); - if (fUseOutfits) - pCheckCtrl->setValue(TRUE); - } - childSetEnabled("checkbox_use_links", !fUseOutfits); - } - - static void onOutfitFoldersToggle(LLUICtrl*, void* pParam) - { - LLMakeOutfitDialog* pSelf = (LLMakeOutfitDialog*)pParam; - if (pSelf) - pSelf->refresh(); - } -}; - //////////////////////////////////////////////////////////////////////////// void updateAvatarHeightDisplay() { - if (gFloaterCustomize && isAgentAvatarValid()) + if (LLFloaterCustomize::instanceExists() && isAgentAvatarValid()) { F32 avatar_size = (gAgentAvatarp->mBodySize.mV[VZ]) + (F32)0.17; //mBodySize is actually quite a bit off. - gFloaterCustomize->getChild("HeightTextM")->setValue(llformat("%.2f", avatar_size) + "m"); + LLFloaterCustomize::getInstance()->getChild("HeightTextM")->setValue(llformat("%.2f", avatar_size) + "m"); F32 feet = avatar_size / 0.3048; F32 inches = (feet - (F32)((U32)feet)) * 12.0; - gFloaterCustomize->getChild("HeightTextI")->setValue(llformat("%d'%d\"", (U32)feet, (U32)inches)); + LLFloaterCustomize::getInstance()->getChild("HeightTextI")->setValue(llformat("%d'%d\"", (U32)feet, (U32)inches)); } } ///////////////////////////////////////////////////////////////////// // LLFloaterCustomize -// statics -LLWearableType::EType LLFloaterCustomize::sCurrentWearableType = LLWearableType::WT_INVALID; - struct WearablePanelData { WearablePanelData(LLFloaterCustomize* floater, LLWearableType::EType type) @@ -364,7 +142,8 @@ struct WearablePanelData LLFloaterCustomize::LLFloaterCustomize() : LLFloater(std::string("customize")), mScrollingPanelList( NULL ), - mInventoryObserver(NULL) + mInventoryObserver(NULL), + mCurrentWearableType(LLWearableType::WT_INVALID) { memset(&mWearablePanelList[0],0,sizeof(char*)*LLWearableType::WT_COUNT); //Initialize to 0 @@ -389,26 +168,38 @@ LLFloaterCustomize::LLFloaterCustomize() } LLUICtrlFactory::getInstance()->buildFloater(this, "floater_customize.xml", &factory_map); + + fetchInventory(); //May as well start requesting now. + + LLFloater::open(); + + setVisible(false); } +LLFloaterCustomize::~LLFloaterCustomize() +{ + llinfos << "Destroying LLFloaterCustomize" << llendl; + mResetParams = NULL; + gInventory.removeObserver(mInventoryObserver); + delete mInventoryObserver; +} + +// virtual BOOL LLFloaterCustomize::postBuild() { - childSetAction("Make Outfit", LLFloaterCustomize::onBtnMakeOutfit, (void*)this); - childSetAction("Ok", LLFloaterCustomize::onBtnOk, (void*)this); - childSetAction("Cancel", LLFloater::onClickClose, (void*)this); + getChild("Make Outfit")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnMakeOutfit, this)); + getChild("Ok")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnOk, this)); + getChild("Cancel")->setCommitCallback(boost::bind(&LLFloater::onClickClose, this)); // reX - childSetAction("Import", LLFloaterCustomize::onBtnImport, (void*)this); - childSetAction("Export", LLFloaterCustomize::onBtnExport, (void*)this); + getChild("Import")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnImport, this)); + getChild("Export")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnExport, this)); - // Wearable panels - initWearablePanels(); - // Tab container LLTabContainer* tab_container = getChild("customize tab container"); if(tab_container) { - tab_container->setCommitCallback(boost::bind(&LLFloaterCustomize::onTabChanged, _2)); + tab_container->setCommitCallback(boost::bind(&LLFloaterCustomize::onTabChanged, this, _2)); tab_container->setValidateCallback(boost::bind(&LLFloaterCustomize::onTabPrecommit, this, _1, _2)); } @@ -430,36 +221,76 @@ BOOL LLFloaterCustomize::postBuild() return TRUE; } -void LLFloaterCustomize::open() +//static +void LLFloaterCustomize::editWearable(LLViewerWearable* wearable, bool disable_camera_switch) { - LLFloater::open(); - // childShowTab depends on gFloaterCustomize being defined and therefore must be called after the constructor. - Nyx - childShowTab("customize tab container", "Shape", true); - setCurrentWearableType(LLWearableType::WT_SHAPE); + if(!wearable) + return; + LLFloaterCustomize::getInstance()->setCurrentWearableType(wearable->getType(), disable_camera_switch); +} + +//static +void LLFloaterCustomize::show() +{ + if(!LLFloaterCustomize::instanceExists()) + { + const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(LLWearableType::WT_SHAPE); + LLFloaterCustomize::getInstance()->setCurrentWearableType(LLWearableType::WT_SHAPE, disable_camera_switch); + } + else + LLFloaterCustomize::getInstance()->setFrontmost(true); +} + +// virtual +void LLFloaterCustomize::onClose(bool app_quitting) +{ + // since this window is potentially staying open, push to back to let next window take focus + gFloaterView->sendChildToBack(this); + // askToSaveIfDirty will call delayedClose immediately if there's nothing to save. + askToSaveIfDirty( boost::bind(&LLFloaterCustomize::delayedClose, this, _1, app_quitting) ); +} + +void LLFloaterCustomize::delayedClose(bool proceed, bool app_quitting) +{ + if(proceed) + { + LLVOAvatarSelf::onCustomizeEnd(); + LLFloater::onClose(app_quitting); + } } //////////////////////////////////////////////////////////////////////////// -// static -void LLFloaterCustomize::setCurrentWearableType( LLWearableType::EType type ) +void LLFloaterCustomize::setCurrentWearableType( LLWearableType::EType type, bool disable_camera_switch ) { - if( LLFloaterCustomize::sCurrentWearableType != type ) + if( mCurrentWearableType != type ) { - LLFloaterCustomize::sCurrentWearableType = type; + mCurrentWearableType = type; + + if (!gAgentCamera.cameraCustomizeAvatar()) + { + LLVOAvatarSelf::onCustomizeStart(disable_camera_switch); + } + else if(!gSavedSettings.getBOOL("AppearanceCameraMovement") || disable_camera_switch) //Break out to free camera. + { + gAgentCamera.changeCameraToDefault(); + gAgentCamera.resetView(); + } S32 type_int = (S32)type; - if( gFloaterCustomize - && gFloaterCustomize->mWearablePanelList[type_int]) + if(mWearablePanelList[type_int]) { - std::string panelname = gFloaterCustomize->mWearablePanelList[type_int]->getName(); - gFloaterCustomize->childShowTab("customize tab container", panelname); - gFloaterCustomize->switchToDefaultSubpart(); + std::string panelname = mWearablePanelList[type_int]->getName(); + childShowTab("customize tab container", panelname); + switchToDefaultSubpart(); } + + updateVisiblity(disable_camera_switch); } } // reX: new function -void LLFloaterCustomize::onBtnImport( void* userdata ) +void LLFloaterCustomize::onBtnImport() { AIFilePicker* filepicker = AIFilePicker::create(); filepicker->open(FFLOAD_XML); @@ -519,7 +350,7 @@ void LLFloaterCustomize::onBtnImport_continued(AIFilePicker* filepicker) } // reX: new function -void LLFloaterCustomize::onBtnExport( void* userdata ) +void LLFloaterCustomize::onBtnExport() { AIFilePicker* filepicker = AIFilePicker::create(); filepicker->open("", FFSAVE_XML); @@ -544,7 +375,7 @@ void LLFloaterCustomize::onBtnExport_continued(AIFilePicker* filepicker) for( S32 i=0; i < LLWearableType::WT_COUNT; i++ ) { is_modifiable = FALSE; - LLWearable* old_wearable = gAgentWearables.getWearable((LLWearableType::EType)i, 0); // TODO: MULTI-WEARABLE + LLViewerWearable* old_wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)i, 0); // TODO: MULTI-WEARABLE if( old_wearable ) { item = gInventory.getItem(old_wearable->getItemID()); @@ -568,7 +399,7 @@ void LLFloaterCustomize::onBtnExport_continued(AIFilePicker* filepicker) for( S32 i=0; i < LLWearableType::WT_COUNT; i++ ) { is_modifiable = FALSE; - LLWearable* old_wearable = gAgentWearables.getWearable((LLWearableType::EType)i, 0); // TODO: MULTI-WEARABLE + LLViewerWearable* old_wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)i, 0); // TODO: MULTI-WEARABLE if( old_wearable ) { item = gInventory.getItem(old_wearable->getItemID()); @@ -592,10 +423,8 @@ void LLFloaterCustomize::onBtnExport_continued(AIFilePicker* filepicker) fclose(fp); } -// static -void LLFloaterCustomize::onBtnOk( void* userdata ) +void LLFloaterCustomize::onBtnOk() { - LLFloaterCustomize* floater = (LLFloaterCustomize*) userdata; gAgentWearables.saveAllWearables(); if ( gAgentAvatarp ) @@ -607,55 +436,13 @@ void LLFloaterCustomize::onBtnOk( void* userdata ) gAgent.sendAgentSetAppearance(); } - gFloaterView->sendChildToBack(floater); - handle_reset_view(); // Calls askToSaveIfDirty + gFloaterView->sendChildToBack(this); + close(false); } -// static -void LLFloaterCustomize::onBtnMakeOutfit( void* userdata ) +void LLFloaterCustomize::onBtnMakeOutfit() { - LLVOAvatar* avatar = gAgentAvatarp; - if(avatar) - { - LLMakeOutfitDialog* dialog = new LLMakeOutfitDialog( onMakeOutfitCommit, NULL ); - // LLMakeOutfitDialog deletes itself. - - for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ ) - { - BOOL enabled = (gAgentWearables.getWearableCount( (LLWearableType::EType) i )); // TODO: MULTI-WEARABLE - BOOL selected = (enabled && (LLWearableType::WT_SHIRT <= i) && (i < LLWearableType::WT_COUNT)); // only select clothing by default - if (gAgent.isTeen() - && !edit_wearable_for_teens((LLWearableType::EType)i)) - { - dialog->setWearableToInclude( i, FALSE, FALSE ); - } - else - { - dialog->setWearableToInclude( i, enabled, selected ); - } - } - dialog->startModal(); - } -} - -// static -void LLFloaterCustomize::onMakeOutfitCommit( LLMakeOutfitDialog* dialog, void* userdata ) -{ - LLVOAvatar* avatar = gAgentAvatarp; - if(avatar) - { - LLDynamicArray wearables_to_include; - LLDynamicArray attachments_to_include; // attachment points - - LLInventoryModel::item_array_t item_list; - dialog->getIncludedItems(item_list); - - // MULTI-WEARABLES TODO - if(dialog->getUseOutfits()) - LLAppearanceMgr::instance().makeNewOutfitLinks( dialog->getFolderName(), item_list); - else - LLAppearanceMgr::instance().makeNewOutfitLegacy( dialog->getFolderName(), item_list, dialog->getUseLinks()); - } + new LLMakeOutfitDialog(true); // LLMakeOutfitDialog deletes itself. } //////////////////////////////////////////////////////////////////////////// @@ -665,34 +452,17 @@ void* LLFloaterCustomize::createWearablePanel(void* userdata) { WearablePanelData* data = (WearablePanelData*)userdata; LLWearableType::EType type = data->mType; - LLPanelEditWearable* panel; - if ((gAgent.isTeen() && !edit_wearable_for_teens(data->mType) )) - { - panel = NULL; - } + LLPanelEditWearable* &panel = data->mFloater->mWearablePanelList[type]; + if (!gAgent.isTeen() || edit_wearable_for_teens(type)) + panel = new LLPanelEditWearable( type, data->mFloater ); else - { - panel = new LLPanelEditWearable( type ); - } - data->mFloater->mWearablePanelList[type] = panel; + panel = NULL; delete data; return panel; } -void LLFloaterCustomize::initWearablePanels() -{ -} - //////////////////////////////////////////////////////////////////////////// -LLFloaterCustomize::~LLFloaterCustomize() -{ - llinfos << "Destroying LLFloaterCustomize" << llendl; - mResetParams = NULL; - gInventory.removeObserver(mInventoryObserver); - delete mInventoryObserver; -} - void LLFloaterCustomize::switchToDefaultSubpart() { getCurrentWearablePanel()->showDefaultSubpart(); @@ -720,12 +490,12 @@ void LLFloaterCustomize::draw() LLFloater::draw(); } -BOOL LLFloaterCustomize::isDirty() const +bool LLFloaterCustomize::isWearableDirty() const { LLWearableType::EType cur = getCurrentWearableType(); for(U32 i = 0; i < gAgentWearables.getWearableCount(cur); ++i) { - LLWearable* wearable = gAgentWearables.getWearable(cur,i); + LLViewerWearable* wearable = gAgentWearables.getViewerWearable(cur,i); if(wearable && wearable->isDirty()) return TRUE; } @@ -742,9 +512,9 @@ bool LLFloaterCustomize::onTabPrecommit( LLUICtrl* ctrl, const LLSD& param ) if(type_name == panel_name) { - if(LLFloaterCustomize::sCurrentWearableType != type) + if(mCurrentWearableType != type) { - askToSaveIfDirty(boost::bind(&LLFloaterCustomize::onCommitChangeTab, _1, (LLTabContainer*)ctrl, param.asString(), (LLWearableType::EType)type)); + askToSaveIfDirty(boost::bind(&LLFloaterCustomize::onCommitChangeTab, this, _1, (LLTabContainer*)ctrl, param.asString(), (LLWearableType::EType)type)); return false; } } @@ -753,7 +523,6 @@ bool LLFloaterCustomize::onTabPrecommit( LLUICtrl* ctrl, const LLSD& param ) } -// static void LLFloaterCustomize::onTabChanged( const LLSD& param ) { std::string panel_name = param.asString(); @@ -764,28 +533,22 @@ void LLFloaterCustomize::onTabChanged( const LLSD& param ) if(type_name == panel_name) { - LLFloaterCustomize::setCurrentWearableType((LLWearableType::EType)type); + const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch((LLWearableType::EType)type); + setCurrentWearableType((LLWearableType::EType)type, disable_camera_switch); break; } } } -void LLFloaterCustomize::onClose(bool app_quitting) -{ - // since this window is potentially staying open, push to back to let next window take focus - gFloaterView->sendChildToBack(this); - handle_reset_view(); // Calls askToSaveIfDirty -} - -// static void LLFloaterCustomize::onCommitChangeTab(BOOL proceed, LLTabContainer* ctrl, std::string panel_name, LLWearableType::EType type) { - if (!proceed || !gFloaterCustomize) + if (!proceed) { return; } - LLFloaterCustomize::setCurrentWearableType(type); + const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(type); + setCurrentWearableType(type, disable_camera_switch); ctrl->selectTabByName(panel_name); } @@ -827,6 +590,15 @@ void LLFloaterCustomize::wearablesChanged(LLWearableType::EType type) } } +void LLFloaterCustomize::updateVisiblity(bool force_disable_camera_switch/*=false*/) +{ + if(!getVisible()) + { + if(force_disable_camera_switch || !gAgentCamera.cameraCustomizeAvatar() || !gAgentCamera.getCameraAnimating() || (gMorphView && gMorphView->getVisible())) + setVisibleAndFrontmost(TRUE); + } +} + void LLFloaterCustomize::updateScrollingPanelList() { getCurrentWearablePanel()->updateScrollingPanelList(); @@ -834,7 +606,7 @@ void LLFloaterCustomize::updateScrollingPanelList() void LLFloaterCustomize::askToSaveIfDirty( boost::function cb ) { - if(isDirty()) + if(isWearableDirty()) { // Ask if user wants to save, then continue to next step afterwards mNextStepAfterSaveCallback.connect(cb); @@ -859,7 +631,7 @@ bool LLFloaterCustomize::onSaveDialog(const LLSD& notification, const LLSD& resp for(U32 i = 0;i < gAgentWearables.getWearableCount(cur);++i) { - LLWearable* wearable = gAgentWearables.getWearable(cur,i); + LLViewerWearable* wearable = gAgentWearables.getViewerWearable(cur,i); if(wearable && wearable->isDirty()) { switch( option ) @@ -938,7 +710,7 @@ void LLFloaterCustomize::updateInventoryUI() panel = mWearablePanelList[i]; if(panel) { - LLWearable* wearable = panel->getWearable(); + LLViewerWearable* wearable = panel->getWearable(); if(wearable) item = gInventory.getItem(wearable->getItemID()); } @@ -956,7 +728,7 @@ void LLFloaterCustomize::updateInventoryUI() is_complete = false; perm_mask = 0x0; } - if(i == sCurrentWearableType) + if(i == mCurrentWearableType) { if(panel) { diff --git a/indra/newview/llfloatercustomize.h b/indra/newview/llfloatercustomize.h index e603209fe..56047db1e 100644 --- a/indra/newview/llfloatercustomize.h +++ b/indra/newview/llfloatercustomize.h @@ -43,6 +43,7 @@ #include "llviewermenu.h" #include "llwearable.h" #include "lliconctrl.h" +#include "llsingleton.h" class LLButton; class LLIconCtrl; @@ -62,6 +63,7 @@ class LLViewerJointMesh; class LLViewerVisualParam; class LLVisualParam; class LLVisualParamReset; +class LLViewerWearable; class LLWearableSaveAsDialog; class LLPanelEditWearable; class AIFilePicker; @@ -69,74 +71,82 @@ class AIFilePicker; ///////////////////////////////////////////////////////////////////// // LLFloaterCustomize -class LLFloaterCustomize : public LLFloater +class LLFloaterCustomize : public LLFloater, public LLSingleton { public: + // Ctor/Dtor LLFloaterCustomize(); virtual ~LLFloaterCustomize(); - virtual BOOL postBuild(); - // Inherted methods from LLFloater (and above) - virtual void onClose(bool app_quitting); - virtual void draw(); - /*virtual*/ void open(); - - - // New methods - - void wearablesChanged(LLWearableType::EType type); - void updateScrollingPanelList(); - LLPanelEditWearable* getCurrentWearablePanel() { return mWearablePanelList[ sCurrentWearableType ]; } - - virtual BOOL isDirty() const; - - void askToSaveIfDirty( boost::function cb ); - - void switchToDefaultSubpart(); - - static void setCurrentWearableType( LLWearableType::EType type ); - static LLWearableType::EType getCurrentWearableType() { return sCurrentWearableType; } - - // Callbacks - static void onBtnOk( void* userdata ); - static void onBtnMakeOutfit( void* userdata ); - static void onMakeOutfitCommit( LLMakeOutfitDialog* dialog, void* userdata ); - static void onBtnImport( void* userdata ); - static void onBtnImport_continued(AIFilePicker* filepicker); - static void onBtnExport( void* userdata ); - static void onBtnExport_continued(AIFilePicker* filepicker); - - static void onTabChanged( const LLSD& param ); - bool onTabPrecommit( LLUICtrl* ctrl, const LLSD& param ); - bool onSaveDialog(const LLSD& notification, const LLSD& response); - static void onCommitChangeTab(BOOL proceed, LLTabContainer* ctrl, std::string panel_name, LLWearableType::EType type); - - void fetchInventory(); - void updateInventoryUI(); - - LLScrollingPanelList* getScrollingPanelList() const { return mScrollingPanelList; } -protected: - LLPanelEditWearable* mWearablePanelList[ LLWearableType::WT_COUNT ]; - - static LLWearableType::EType sCurrentWearableType; - - LLScrollingPanelList* mScrollingPanelList; - LLScrollableContainerView* mScrollContainer; - LLPointer mResetParams; - - LLInventoryObserver* mInventoryObserver; - - boost::signals2::signal mNextStepAfterSaveCallback; - -protected: - - static void* createWearablePanel(void* userdata); + // Inherted methods + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose(bool app_quitting); + /*virtual*/ void draw(); + // Creation procedures + static void editWearable(LLViewerWearable* wearable, bool disable_camera_switch); + static void show(); + + +private: + // Initilization void initWearablePanels(); void initScrollingPanelList(); + + // Deinitilization + void delayedClose(bool proceed, bool app_quitting); + + // Setters/Getters + void setCurrentWearableType(LLWearableType::EType type, bool disable_camera_switch); +public: + LLWearableType::EType getCurrentWearableType() const { return mCurrentWearableType; } + LLPanelEditWearable* getCurrentWearablePanel() const { return mWearablePanelList[ mCurrentWearableType ]; } + LLScrollingPanelList* getScrollingPanelList() const { return mScrollingPanelList; } //LLPanelEditWearable needs access to this. + + // Updates + void wearablesChanged(LLWearableType::EType type); +public: + void updateScrollingPanelList(); + void updateVisiblity(bool force_disable_camera_switch = false); +private: + void updateInventoryUI(); + + // Utility + void fetchInventory(); + bool isWearableDirty() const; + +public: + void askToSaveIfDirty( boost::function cb ); + void switchToDefaultSubpart(); + +private: + // Callbacks + void onBtnOk(); + void onBtnMakeOutfit(); + void onBtnImport(); + static void onBtnImport_continued(AIFilePicker* filepicker); + void onBtnExport(); + static void onBtnExport_continued(AIFilePicker* filepicker); + void onTabChanged( const LLSD& param ); + bool onTabPrecommit( LLUICtrl* ctrl, const LLSD& param ); + bool onSaveDialog(const LLSD& notification, const LLSD& response); + void onCommitChangeTab(BOOL proceed, LLTabContainer* ctrl, std::string panel_name, LLWearableType::EType type); + + // LLCallbackMap callback. + static void* createWearablePanel(void* userdata); + + // Member variables + LLPanelEditWearable* mWearablePanelList[ LLWearableType::WT_COUNT ]; + + LLWearableType::EType mCurrentWearableType; + + LLScrollingPanelList* mScrollingPanelList; + LLScrollableContainerView* mScrollContainer; + LLPointer mResetParams; + + LLInventoryObserver* mInventoryObserver; + + boost::signals2::signal mNextStepAfterSaveCallback; }; -extern LLFloaterCustomize* gFloaterCustomize; - - #endif // LL_LLFLOATERCUSTOMIZE_H diff --git a/indra/newview/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp index 7028e5016..3a4e829cf 100644 --- a/indra/newview/llfloaterdaycycle.cpp +++ b/indra/newview/llfloaterdaycycle.cpp @@ -156,7 +156,7 @@ void LLFloaterDayCycle::initCallbacks(void) childSetAction("DayCycleSavePreset", onSavePreset, comboBox); childSetAction("DayCycleDeletePreset", onDeletePreset, comboBox); - comboBox->setCommitCallback(onChangePresetName); + comboBox->setCommitCallback(boost::bind(&LLFloaterDayCycle::onChangePresetName,_1)); childSetAction("WLAddKey", onAddKey, NULL); @@ -478,7 +478,7 @@ bool LLFloaterDayCycle::newPromptCallback(const LLSD& notification, const LLSD& } -void LLFloaterDayCycle::onChangePresetName(LLUICtrl* ctrl, void * userData) +void LLFloaterDayCycle::onChangePresetName(LLUICtrl* ctrl) { LLComboBox * combo_box = static_cast(ctrl); diff --git a/indra/newview/llfloaterdaycycle.h b/indra/newview/llfloaterdaycycle.h index 9adfc3a02..863ed5418 100644 --- a/indra/newview/llfloaterdaycycle.h +++ b/indra/newview/llfloaterdaycycle.h @@ -117,7 +117,7 @@ public: static bool newPromptCallback(const LLSD& notification, const LLSD& response); /// what to do when you change the preset name - static void onChangePresetName(LLUICtrl* ctrl, void* userData); + static void onChangePresetName(LLUICtrl* ctrl); /// toggle for Linden time static void onUseLindenTime(void* userData); diff --git a/indra/newview/llfloaterexploresounds.cpp b/indra/newview/llfloaterexploresounds.cpp index 6ada9c155..4ce0cf111 100644 --- a/indra/newview/llfloaterexploresounds.cpp +++ b/indra/newview/llfloaterexploresounds.cpp @@ -75,15 +75,16 @@ void LLFloaterExploreSounds::close(bool app_quitting) BOOL LLFloaterExploreSounds::postBuild(void) { - childSetDoubleClickCallback("sound_list", handle_play_locally, this); + LLScrollListCtrl* soundlist = getChild("sound_list"); + soundlist->setDoubleClickCallback(boost::bind(&LLFloaterExploreSounds::handle_play_locally,this)); + soundlist->sortByColumn("playing", TRUE); childSetAction("play_locally_btn", handle_play_locally, this); childSetAction("look_at_btn", handle_look_at, this); childSetAction("stop_btn", handle_stop, this); childSetAction("bl_btn", blacklistSound, this); - LLScrollListCtrl* list = getChild("sound_list"); - list->sortByColumn("playing", TRUE); + return TRUE; } @@ -165,13 +166,7 @@ BOOL LLFloaterExploreSounds::tick() // Save scroll pos and selection so they can be restored S32 scroll_pos = list->getScrollPos(); - LLDynamicArray selected_ids; - std::vector selected_items = list->getAllSelected(); - std::vector::iterator selection_iter = selected_items.begin(); - std::vector::iterator selection_end = selected_items.end(); - for(; selection_iter != selection_end; ++selection_iter) - selected_ids.push_back((*selection_iter)->getUUID()); - + uuid_vec_t selected_ids = list->getSelectedIDs(); list->clearRows(); std::list unique_asset_list; diff --git a/indra/newview/llfloaterfeed.cpp b/indra/newview/llfloaterfeed.cpp new file mode 100644 index 000000000..44aa7ed67 --- /dev/null +++ b/indra/newview/llfloaterfeed.cpp @@ -0,0 +1,194 @@ +/** + * @file llfloaterfeed.cpp + * @brief Feed send floater, allows setting caption and whether or to add location, etc. + * + * $LicenseInfo:firstyear=2012&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * Copyright (c) 2012, Aleric Ingelwood. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterfeed.h" + +#include "llfloatersnapshot.h" +#include "llimagepng.h" +#include "llnotificationsutil.h" +#include "lluictrlfactory.h" +#include "llviewertexture.h" +#include "llviewerwindow.h" +#include "llwebprofile.h" +#include "lluploaddialog.h" +#include "lltexteditor.h" + +#include + +///---------------------------------------------------------------------------- +/// Class LLFloaterFeed +///---------------------------------------------------------------------------- + +LLFloaterFeed::LLFloaterFeed(LLImagePNG* png, LLViewerTexture* img, LLVector2 const& img_scale, int index) : + LLFloater(std::string("Feed Floater")), + mPNGImage(png), mViewerImage(img), mImageScale(img_scale), mSnapshotIndex(index), mHasFirstMsgFocus(false) +{ +} + +// Destroys the object +LLFloaterFeed::~LLFloaterFeed() +{ + mPNGImage = NULL; +} + +BOOL LLFloaterFeed::postBuild() +{ + getChild("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterFeed::onClickCancel, this)); + getChild("post_btn")->setCommitCallback(boost::bind(&LLFloaterFeed::onClickPost, this)); + LLTextEditor* caption = getChild("caption"); + if (caption) + { + // For the first time a user focusess to the msg box, all text will be selected. + caption->setFocusChangedCallback(boost::bind(&LLFloaterFeed::onMsgFormFocusRecieved, this, _1, caption)); + } + childSetFocus("cancel_btn", TRUE); + + return true; +} + +void LLFloaterFeed::onMsgFormFocusRecieved(LLFocusableElement* receiver, LLTextEditor* caption) +{ + if (caption && caption == receiver && caption->hasFocus() && !mHasFirstMsgFocus) + { + mHasFirstMsgFocus = true; + caption->setText(LLStringUtil::null); + } +} + +// static +LLFloaterFeed* LLFloaterFeed::showFromSnapshot(LLImagePNG* png, LLViewerTexture* img, LLVector2 const& image_scale, int index) +{ + // Take the images from the caller + // It's now our job to clean them up + LLFloaterFeed* instance = new LLFloaterFeed(png, img, image_scale, index); + + LLUICtrlFactory::getInstance()->buildFloater(instance, "floater_snapshot_feed.xml"); + + S32 left, top; + gFloaterView->getNewFloaterPosition(&left, &top); + instance->setOrigin(left, top - instance->getRect().getHeight()); + + instance->open(); + + return instance; +} + +void LLFloaterFeed::draw(void) +{ + LLGLSUIDefault gls_ui; + LLFloater::draw(); + + if (!isMinimized() && mViewerImage.notNull() && mPNGImage.notNull()) + { + LLRect rect(getRect()); + + // First set the max extents of our preview. + rect.translate(-rect.mLeft, -rect.mBottom); + rect.mLeft += 10; + rect.mRight -= 10; + rect.mTop -= 25; + rect.mBottom = rect.mTop - 150; + + // Then fix the aspect ratio. + F32 ratio = (F32)mPNGImage->getWidth() / (F32)mPNGImage->getHeight(); + if ((F32)rect.getWidth() / (F32)rect.getHeight() >= ratio) + { + rect.mRight = (S32)((F32)rect.mLeft + ((F32)rect.getHeight() * ratio)); + } + else + { + rect.mBottom = (S32)((F32)rect.mTop - ((F32)rect.getWidth() / ratio)); + } + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f)); + rect.stretch(-1); + } + { + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.pushMatrix(); + { + gGL.scalef(mImageScale.mV[VX], mImageScale.mV[VY], 1.f); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), mViewerImage, LLColor4::white); + } + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } + } +} + +void LLFloaterFeed::onClickCancel() +{ + // Cancel is the same as just closing the floater. + close(false); +} + +void LLFloaterFeed::onClose(bool app_quitting) +{ + LLFloaterSnapshot::saveFeedDone(false, mSnapshotIndex); + destroy(); +} + +void LLFloaterFeed::onClickPost() +{ + if (!mHasFirstMsgFocus) + { + // The user never switched focus to the messagee window. + // Using the default string. + childSetValue("caption", getString("default_message")); + } + if (mPNGImage.notNull()) + { + static LLCachedControl add_location("SnapshotFeedAddLocation"); + const std::string caption = childGetValue("caption").asString(); + LLWebProfile::setImageUploadResultCallback(boost::bind(&LLFloaterSnapshot::saveFeedDone, _1, mSnapshotIndex)); + LLFloaterSnapshot::saveStart(mSnapshotIndex); + LLWebProfile::uploadImage(mPNGImage, caption, add_location); + + // give user feedback of the event + gViewerWindow->playSnapshotAnimAndSound(); + LLUploadDialog::modalUploadDialog(getString("upload_message")); + + // don't destroy the window until the upload is done + // this way we keep the information in the form + setVisible(FALSE); + } + else + { + LLNotificationsUtil::add("ErrorProcessingSnapshot"); + } +} diff --git a/indra/llui/lltabcontainervertical.cpp b/indra/newview/llfloaterfeed.h similarity index 50% rename from indra/llui/lltabcontainervertical.cpp rename to indra/newview/llfloaterfeed.h index a729c95fd..8db4f3c79 100644 --- a/indra/llui/lltabcontainervertical.cpp +++ b/indra/newview/llfloaterfeed.h @@ -1,10 +1,9 @@ /** - * @file lltabcontainervertical.cpp - * @brief LLTabContainerVertical base class + * @file llfloaterfeed.h + * @brief Feed send floater, allows setting caption and whether or not to include location. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. + * Copyright (c) 2004-2009, Linden Research, Inc. + * Copyright (c) 2012, Aleric Inglewood. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -30,4 +29,40 @@ * $/LicenseInfo$ */ -// deprecated: see LLTabContainer +#ifndef LL_LLFLOATERFEED_H +#define LL_LLFLOATERFEED_H + +#include "llfloater.h" // LLFloater +#include "v2math.h" // LLVector2 +#include "llpointer.h" // LLPointer + +class LLImagePNG; +class LLViewerTexture; +class LLFocusableElement; +class LLTextEditor; + +class LLFloaterFeed : public LLFloater +{ +public: + LLFloaterFeed(LLImagePNG* png, LLViewerTexture* img, LLVector2 const& img_scale, int index); + virtual ~LLFloaterFeed(); + + /*virtual*/ void onClose(bool app_quitting); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + + static LLFloaterFeed* showFromSnapshot(LLImagePNG* png, LLViewerTexture* img, LLVector2 const& img_scale, int index); + + void onClickCancel(); + void onClickPost(); + void onMsgFormFocusRecieved(LLFocusableElement* receiver, LLTextEditor* caption); + +protected: + LLPointer mPNGImage; + LLPointer mViewerImage; + LLVector2 const mImageScale; + int mSnapshotIndex; + bool mHasFirstMsgFocus; +}; + +#endif // LL_LLFLOATERFEED_H diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 2b09b57d4..e0ac0a06e 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -44,10 +44,7 @@ #include "llagent.h" #include "llappviewer.h" // for gLastVersionChannel -// [Ansariel: Display name support] -#include "llavatarname.h" #include "llavatarnamecache.h" -// [/Ansariel: Display name support] #include "llfloateravatarpicker.h" #include "llviewerwindow.h" @@ -78,7 +75,7 @@ #include "llfloaterchat.h" // stuff for Contact groups -#include "ascentfloatercontactgroups.h" +//#include "ascentfloatercontactgroups.h" #define DEFAULT_PERIOD 5.0 #define RIGHTS_CHANGE_TIMEOUT 5.0 @@ -87,18 +84,40 @@ #define ONLINE_SIP_ICON_NAME "slim_icon_16_viewer.tga" // simple class to observe the calling cards. -class LLLocalFriendsObserver : public LLFriendObserver, public LLEventTimer + + +class LLAvatarListUpdater : public LLEventTimer { -public: - LLLocalFriendsObserver(LLPanelFriends* floater) : mFloater(floater), LLEventTimer(OBSERVER_TIMEOUT) +public: + LLAvatarListUpdater(F32 period) + : LLEventTimer(period) { mEventTimer.stop(); } - virtual ~LLLocalFriendsObserver() + + virtual BOOL tick() // from LLEventTimer { - mFloater = NULL; + return FALSE; } - virtual void changed(U32 mask) +}; + +class LLLocalFriendsObserver : public LLAvatarListUpdater, public LLFriendObserver +{ + LOG_CLASS(LLLocalFriendsObserver); +public: + LLLocalFriendsObserver(LLPanelFriends* floater) + : mFloater(floater), LLAvatarListUpdater(OBSERVER_TIMEOUT) + { + LLAvatarTracker::instance().addObserver(this); + // For notification when SIP online status changes. + LLVoiceClient::getInstance()->addObserver(this); + } + /*virtual*/ ~LLLocalFriendsObserver() + { + LLVoiceClient::getInstance()->removeObserver(this); + LLAvatarTracker::instance().removeObserver(this); + } + /*virtual*/ void changed(U32 mask) { // events can arrive quickly in bulk - we need not process EVERY one of them - // so we wait a short while to let others pile-in, and process them in aggregate. @@ -107,9 +126,9 @@ public: // save-up all the mask-bits which have come-in mMask |= mask; } - virtual BOOL tick() + /*virtual*/ BOOL tick() { - mFloater->populateContactGroupSelect(); + //mFloater->populateContactGroupSelect(); mFloater->updateFriends(mMask); mEventTimer.stop(); @@ -134,16 +153,10 @@ LLPanelFriends::LLPanelFriends() : { mEventTimer.stop(); mObserver = new LLLocalFriendsObserver(this); - LLAvatarTracker::instance().addObserver(mObserver); - // For notification when SIP online status changes. - LLVoiceClient::getInstance()->addObserver(mObserver); } LLPanelFriends::~LLPanelFriends() { - // For notification when SIP online status changes. - LLVoiceClient::getInstance()->removeObserver(mObserver); - LLAvatarTracker::instance().removeObserver(mObserver); delete mObserver; } @@ -168,7 +181,7 @@ void LLPanelFriends::updateFriends(U32 changed_mask) // if the maximum amount of friends are selected mShowMaxSelectWarning = false; - LLDynamicArray selected_friends = getSelectedIDs(); + const uuid_vec_t selected_friends = mFriendsList->getSelectedIDs(); if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE)) { refreshNames(changed_mask); @@ -187,13 +200,13 @@ void LLPanelFriends::updateFriends(U32 changed_mask) tick(); } } - if(selected_friends.size() > 0) + if(!selected_friends.empty()) { // only non-null if friends was already found. This may fail, // but we don't really care here, because refreshUI() will // clean up the interface. friends_list->setCurrentByID(selected_id); - for(LLDynamicArray::iterator itr = selected_friends.begin(); itr != selected_friends.end(); ++itr) + for(uuid_vec_t::const_iterator itr = selected_friends.begin(); itr != selected_friends.end(); ++itr) { friends_list->setSelectedByValue(*itr, true); } @@ -218,7 +231,7 @@ std::string LLPanelFriends::cleanFileName(std::string filename) return filename; } -void LLPanelFriends::populateContactGroupSelect() +/*void LLPanelFriends::populateContactGroupSelect() { LLComboBox* combo = getChild("buddy_group_combobox"); @@ -241,18 +254,18 @@ void LLPanelFriends::populateContactGroupSelect() LLChat msg("Null combo"); LLFloaterChat::addChat(msg); } -} +}*/ -void LLPanelFriends::setContactGroup(std::string contact_grp) +/*void LLPanelFriends::setContactGroup(std::string contact_grp) { LLChat msg("Group set to " + contact_grp); LLFloaterChat::addChat(msg); refreshNames(LLFriendObserver::ADD); refreshUI(); categorizeContacts(); -} +}*/ -void LLPanelFriends::categorizeContacts() +/*void LLPanelFriends::categorizeContacts() { LLSD contact_groups = gSavedPerAccountSettings.getLLSD("AscentContactGroups"); std::string group_name = "All"; @@ -306,7 +319,7 @@ void LLPanelFriends::categorizeContacts() LLChat msg("Null combo."); LLFloaterChat::addChat(msg); } -} +}*/ void LLPanelFriends::filterContacts(const std::string& search_name) { @@ -350,7 +363,7 @@ void LLPanelFriends::onContactSearchEdit(const std::string& search_string, void* } } -void LLPanelFriends::onChangeContactGroup(LLUICtrl* ctrl, void* user_data) +/*void LLPanelFriends::onChangeContactGroup(LLUICtrl* ctrl, void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; @@ -359,7 +372,7 @@ void LLPanelFriends::onChangeContactGroup(LLUICtrl* ctrl, void* user_data) LLComboBox* combo = panelp->getChild("buddy_group_combobox"); panelp->setContactGroup(combo->getValue().asString()); } -} +}*/ // -- // virtual @@ -367,9 +380,9 @@ BOOL LLPanelFriends::postBuild() { mFriendsList = getChild("friend_list"); mFriendsList->setCommitOnSelectionChange(TRUE); - childSetCommitCallback("friend_list", onSelectName, this); - childSetCommitCallback("buddy_group_combobox", onChangeContactGroup, this); - childSetDoubleClickCallback("friend_list", onClickIM); + mFriendsList->setCommitCallback(onSelectName, this); + //childSetCommitCallback("buddy_group_combobox", onChangeContactGroup, this); + mFriendsList->setDoubleClickCallback(onClickIM, this); // // Contact search and group system. @@ -387,7 +400,7 @@ BOOL LLPanelFriends::postBuild() refreshNames(changed_mask); childSetAction("im_btn", onClickIM, this); - childSetAction("assign_btn", onClickAssign, this); + //childSetAction("assign_btn", onClickAssign, this); childSetAction("expand_collapse_btn", onClickExpand, this); childSetAction("profile_btn", onClickProfile, this); childSetAction("offer_teleport_btn", onClickOfferTeleport, this); @@ -421,26 +434,8 @@ BOOL LLPanelFriends::addFriend(const LLUUID& agent_id) bool isOnline = relationInfo->isOnline(); std::string fullname; - // [Ansariel: Display name support] - //BOOL have_name = gCacheName->getFullName(agent_id, fullname); - LLAvatarName avatar_name; - BOOL have_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : fullname = avatar_name.getLegacyName(); break; - case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : fullname = avatar_name.mDisplayName; break; - default : fullname = avatar_name.getCompleteName(); break; - } + BOOL have_name = LLAvatarNameCache::getPNSName(agent_id, fullname); - have_name = TRUE; - } - else have_name = FALSE; - // [/Ansariel: Display name support] - LLSD element; element["id"] = agent_id; LLSD& friend_column = element["columns"][LIST_FRIEND_NAME]; @@ -520,26 +515,8 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh bool isOnlineSIP = LLVoiceClient::getInstance()->isOnlineSIP(itemp->getUUID()); bool isOnline = info->isOnline(); - std::string fullname; - // [Ansariel: Display name support] - //BOOL have_name = gCacheName->getFullName(agent_id, fullname); - LLAvatarName avatar_name; - BOOL have_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : fullname = avatar_name.getLegacyName(); break; - case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : fullname = avatar_name.mDisplayName; break; - default : fullname = avatar_name.getCompleteName(); break; - } - - have_name = TRUE; - } - else have_name = FALSE; - // [/Ansariel: Display name support] + std::string fullname; + BOOL have_name = LLAvatarNameCache::getPNSName(agent_id, fullname); // Name of the status icon to use std::string statusIcon; @@ -580,6 +557,8 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh // enable this item, in case it was disabled after user input itemp->setEnabled(TRUE); + mFriendsList->setNeedsSort(); + // Do not resort, this function can be called frequently. return have_name; } @@ -587,7 +566,7 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh void LLPanelFriends::refreshRightsChangeList() { - LLDynamicArray friends = getSelectedIDs(); + const uuid_vec_t friends = mFriendsList->getSelectedIDs(); S32 num_selected = friends.size(); bool can_offer_teleport = num_selected >= 1; @@ -610,7 +589,7 @@ void LLPanelFriends::refreshRightsChangeList() processing_label->setVisible(false); } Making Dummy View -HgB */ const LLRelationship* friend_status = NULL; - for(LLDynamicArray::iterator itr = friends.begin(); itr != friends.end(); ++itr) + for(uuid_vec_t::const_iterator itr = friends.begin(); itr != friends.end(); ++itr) { friend_status = LLAvatarTracker::instance().getBuddyInfo(*itr); if (friend_status) @@ -635,7 +614,7 @@ void LLPanelFriends::refreshRightsChangeList() if (num_selected == 0) // nothing selected { childSetEnabled("im_btn", FALSE); - childSetEnabled("assign_btn", FALSE); + //childSetEnabled("assign_btn", FALSE); childSetEnabled("offer_teleport_btn", FALSE); } else // we have at least one friend selected... @@ -644,7 +623,7 @@ void LLPanelFriends::refreshRightsChangeList() // to be consistent with context menus in inventory and because otherwise // offline friends would be silently dropped from the session childSetEnabled("im_btn", selected_friends_online || num_selected == 1); - childSetEnabled("assign_btn", num_selected == 1); + //childSetEnabled("assign_btn", num_selected == 1); childSetEnabled("offer_teleport_btn", can_offer_teleport); } } @@ -659,7 +638,7 @@ struct SortFriendsByID void LLPanelFriends::refreshNames(U32 changed_mask) { - LLDynamicArray selected_ids = getSelectedIDs(); + const uuid_vec_t selected_ids = mFriendsList->getSelectedIDs(); S32 pos = mFriendsList->getScrollPos(); // get all buddies we know about @@ -685,7 +664,7 @@ void LLPanelFriends::refreshNames(U32 changed_mask) // Changed item in place, need to request sort and update columns // because we might have changed data in a column on which the user // has already sorted. JC - mFriendsList->sortItems(); + mFriendsList->updateSort(); // re-select items mFriendsList->selectMultiple(selected_ids); @@ -776,7 +755,7 @@ void LLPanelFriends::refreshUI() //Options that can only be performed with one friend selected childSetEnabled("profile_btn", single_selected && !multiple_selected); childSetEnabled("pay_btn", single_selected && !multiple_selected); - childSetEnabled("assign_btn", single_selected && !multiple_selected); + //childSetEnabled("assign_btn", single_selected && !multiple_selected); //Options that can be performed with up to MAX_FRIEND_SELECT friends selected //(single_selected will always be true in this situations) @@ -787,18 +766,6 @@ void LLPanelFriends::refreshUI() refreshRightsChangeList(); } -LLDynamicArray LLPanelFriends::getSelectedIDs() -{ - LLUUID selected_id; - LLDynamicArray friend_ids; - std::vector selected = mFriendsList->getAllSelected(); - for(std::vector::iterator itr = selected.begin(); itr != selected.end(); ++itr) - { - friend_ids.push_back((*itr)->getUUID()); - } - return friend_ids; -} - // static void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data) { @@ -818,8 +785,8 @@ void LLPanelFriends::onClickProfile(void* user_data) LLPanelFriends* panelp = (LLPanelFriends*)user_data; //llinfos << "LLPanelFriends::onClickProfile()" << llendl; - LLDynamicArray ids = panelp->getSelectedIDs(); - if(ids.size() > 0) + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); + if(!ids.empty()) { LLUUID agent_id = ids[0]; BOOL online; @@ -829,15 +796,15 @@ void LLPanelFriends::onClickProfile(void* user_data) } // static -void LLPanelFriends::onClickAssign(void* user_data) +/*void LLPanelFriends::onClickAssign(void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; if (panelp) { - LLDynamicArray ids = panelp->getSelectedIDs(); + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); ASFloaterContactGroups::show(ids); } -} +}*/ // static void LLPanelFriends::onClickExpand(void* user_data) @@ -885,31 +852,23 @@ void LLPanelFriends::onClickIM(void* user_data) LLPanelFriends* panelp = (LLPanelFriends*)user_data; //llinfos << "LLPanelFriends::onClickIM()" << llendl; - LLDynamicArray ids = panelp->getSelectedIDs(); - if(ids.size() > 0) + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); + if(!ids.empty()) { + static LLCachedControl tear_off("OtherChatsTornOff"); + if(!tear_off) gIMMgr->setFloaterOpen(TRUE); if(ids.size() == 1) { LLUUID agent_id = ids[0]; const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(agent_id); - // [Ansariel: Display name support] - //std::string fullname; - //if(info && gCacheName->getFullName(agent_id, fullname)) - //{ - // gIMMgr->setFloaterOpen(TRUE); - // gIMMgr->addSession(fullname, IM_NOTHING_SPECIAL, agent_id); - //} - LLAvatarName avatar_name; - if (info && LLAvatarNameCache::get(agent_id, &avatar_name)) + std::string fullname; + if(info && gCacheName->getFullName(agent_id, fullname)) { - gIMMgr->setFloaterOpen(TRUE); - gIMMgr->addSession(LLCacheName::cleanFullName(avatar_name.getLegacyName()),IM_NOTHING_SPECIAL,agent_id); + gIMMgr->addSession(fullname, IM_NOTHING_SPECIAL, agent_id); } - // [/Ansariel: Display name support] } else { - gIMMgr->setFloaterOpen(TRUE); gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], ids); } make_ui_sound("UISndStartIM"); @@ -959,13 +918,12 @@ bool LLPanelFriends::callbackAddFriend(const LLSD& notification, const LLSD& res } // static -void LLPanelFriends::onPickAvatar(const std::vector& names, - const std::vector& ids, - void* ) +void LLPanelFriends::onPickAvatar( const uuid_vec_t& ids, + const std::vector& names ) { if (names.empty()) return; if (ids.empty()) return; - requestFriendshipDialog(ids[0], names[0]); + requestFriendshipDialog(ids[0], names[0].getCompleteName()); } // static @@ -1001,7 +959,7 @@ void LLPanelFriends::onClickAddFriend(void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; LLFloater* root_floater = gFloaterView->getParentFloater(panelp); - LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(onPickAvatar, user_data, FALSE, TRUE); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelFriends::onPickAvatar, _1, _2), FALSE, TRUE); if (root_floater) { root_floater->addDependentFloater(picker); @@ -1014,38 +972,17 @@ void LLPanelFriends::onClickRemove(void* user_data) LLPanelFriends* panelp = (LLPanelFriends*)user_data; //llinfos << "LLPanelFriends::onClickRemove()" << llendl; - LLDynamicArray ids = panelp->getSelectedIDs(); + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); LLSD args; - if(ids.size() > 0) + if(!ids.empty()) { std::string msgType = "RemoveFromFriends"; if(ids.size() == 1) { LLUUID agent_id = ids[0]; - // [Ansariel: Display name support] - //std::string first, last; - //if(gCacheName->getName(agent_id, first, last)) - //{ - // args["FIRST_NAME"] = first; - // args["LAST_NAME"] = last; - //} - - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) - { - std::string fullname; - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : fullname = avatar_name.getLegacyName(); break; - case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : fullname = avatar_name.mDisplayName; break; - default : fullname = avatar_name.getCompleteName(); break; - } - + std::string fullname; + if (LLAvatarNameCache::getPNSName(agent_id, fullname)) args["NAME"] = fullname; - } - // [/Ansariel: Display name support] } else { @@ -1053,7 +990,7 @@ void LLPanelFriends::onClickRemove(void* user_data) } LLSD payload; - for (LLDynamicArray::iterator it = ids.begin(); + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { @@ -1257,8 +1194,8 @@ void LLPanelFriends::onClickOfferTeleport(void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; - LLDynamicArray ids = panelp->getSelectedIDs(); - if(ids.size() > 0) + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); + if(!ids.empty()) { handle_lure(ids); } @@ -1269,8 +1206,8 @@ void LLPanelFriends::onClickPay(void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; - LLDynamicArray ids = panelp->getSelectedIDs(); - if(ids.size() == 1) + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); + if(!ids.empty()) { handle_pay_by_id(ids[0]); } @@ -1281,7 +1218,7 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command if (ids.empty()) return; LLSD args; - if(ids.size() > 0) + if(!ids.empty()) { rights_map_t* rights = new rights_map_t(ids); @@ -1289,28 +1226,9 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command if(ids.size() == 1) { LLUUID agent_id = ids.begin()->first; - //std::string first, last; - //if(gCacheName->getName(agent_id, first, last)) - //{ - // args["FIRST_NAME"] = first; - // args["LAST_NAME"] = last; - //} - - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) - { - std::string fullname; - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : fullname = avatar_name.getLegacyName(); break; - case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : fullname = avatar_name.mDisplayName; break; - default : fullname = avatar_name.getCompleteName(); break; - } - + std::string fullname; + if (LLAvatarNameCache::getPNSName(agent_id, fullname)) args["NAME"] = fullname; - } if (command == GRANT) { @@ -1407,6 +1325,7 @@ void LLPanelFriends::applyRightsToFriends() rights &= ~LLRelationship::GRANT_MAP_LOCATION; // propagate rights constraint to UI (*itr)->getColumn(LIST_VISIBLE_MAP)->setValue(FALSE); + mFriendsList->setNeedsSortColumn(LIST_VISIBLE_MAP); } } if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION) != show_map_location) @@ -1418,6 +1337,7 @@ void LLPanelFriends::applyRightsToFriends() rights |= LLRelationship::GRANT_MAP_LOCATION; rights |= LLRelationship::GRANT_ONLINE_STATUS; (*itr)->getColumn(LIST_VISIBLE_ONLINE)->setValue(TRUE); + mFriendsList->setNeedsSortColumn(LIST_VISIBLE_ONLINE); } else { diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h index e97aecc0f..94bfe17b0 100644 --- a/indra/newview/llfloaterfriends.h +++ b/indra/newview/llfloaterfriends.h @@ -41,6 +41,7 @@ #include "lleventtimer.h" #include "llcallingcard.h" +class LLAvatarName; class LLFriendObserver; class LLRelationship; class LLScrollListItem; @@ -126,15 +127,12 @@ private: void confirmModifyRights(rights_map_t& ids, EGrantRevoke command); void sendRightsGrant(rights_map_t& ids); - // return LLUUID::null if nothing is selected - LLDynamicArray getSelectedIDs(); - // callback methods static void onSelectName(LLUICtrl* ctrl, void* user_data); static void onChangeContactGroup(LLUICtrl* ctrl, void* user_data); static bool callbackAddFriend(const LLSD& notification, const LLSD& response); static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); - static void onPickAvatar(const std::vector& names, const std::vector& ids, void* user_data); + static void onPickAvatar(const uuid_vec_t& ids, const std::vector& names ); static void onContactSearchEdit(const std::string& search_string, void* user_data); static void onClickIM(void* user_data); static void onClickAssign(void* user_data); diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index c2d7ac14b..66c41cd7b 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -114,8 +114,9 @@ BOOL LLFloaterGesture::postBuild() setTitle(label); - childSetCommitCallback("gesture_list", onCommitList, this); - childSetDoubleClickCallback("gesture_list", onClickPlay); + LLScrollListCtrl* gesture_list = getChild("avatar_list"); + gesture_list->setCommitCallback(boost::bind(&LLFloaterGesture::onCommitList,this)); + gesture_list->setDoubleClickCallback(boost::bind(&LLFloaterGesture::onClickPlay,this)); childSetAction("inventory_btn", onClickInventory, this); @@ -168,7 +169,7 @@ void LLFloaterGesture::show() self->mSelectedID = LLUUID::null; // Update button labels - onCommitList(NULL, self); + self->onCommitList(); self->open(); /*Flawfinder: ignore*/ } @@ -213,7 +214,7 @@ void LLFloaterGesture::refreshAll() } // Update button labels - onCommitList(NULL, sInstance); + sInstance->onCommitList(); } } @@ -404,22 +405,19 @@ void LLFloaterGesture::onClickEdit(void* data) } } -// static -void LLFloaterGesture::onCommitList(LLUICtrl* ctrl, void* data) +void LLFloaterGesture::onCommitList() { - LLFloaterGesture* self = (LLFloaterGesture*)data; + const LLUUID& item_id = childGetValue("gesture_list").asUUID(); - const LLUUID& item_id = self->childGetValue("gesture_list").asUUID(); - - self->mSelectedID = item_id; + mSelectedID = item_id; if (LLGestureMgr::instance().isGesturePlaying(item_id)) { - self->childSetVisible("play_btn", false); - self->childSetVisible("stop_btn", true); + childSetVisible("play_btn", false); + childSetVisible("stop_btn", true); } else { - self->childSetVisible("play_btn", true); - self->childSetVisible("stop_btn", false); + childSetVisible("play_btn", true); + childSetVisible("stop_btn", false); } } diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h index 4e11a10e6..ba4da14f2 100644 --- a/indra/newview/llfloatergesture.h +++ b/indra/newview/llfloatergesture.h @@ -74,7 +74,7 @@ protected: static void onClickEdit(void* data); static void onClickPlay(void* data); static void onClickNew(void* data); - static void onCommitList(LLUICtrl* ctrl, void* data); + void onCommitList(); protected: LLUUID mSelectedID; diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index ba047ae41..4ab128f1b 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -2,31 +2,25 @@ * @file llfloatergodtools.cpp * @brief The on-screen rectangle with tool options. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,6 +28,7 @@ #include "llfloatergodtools.h" +#include "llavatarnamecache.h" #include "llcoord.h" #include "llfontgl.h" #include "llframetimer.h" @@ -83,30 +78,33 @@ const F32 SECONDS_BETWEEN_UPDATE_REQUESTS = 5.0f; -static LLFloaterGodTools* sGodTools = NULL; - // ***************************************************************************** // LLFloaterGodTools // ***************************************************************************** -// static -LLFloaterGodTools* LLFloaterGodTools::instance() +void LLFloaterGodTools::onOpen() { - if (!sGodTools) + center(); + setFocus(TRUE); +// LLPanel *panel = getChild("GodTools Tabs")->getCurrentPanel(); +// if (panel) +// panel->setFocus(TRUE); + LLPanel *panel = childGetVisibleTab("GodTools Tabs"); + if (panel) panel->setFocus(TRUE); + if (mPanelObjectTools) + mPanelObjectTools->setTargetAvatar(LLUUID::null); + + if (gAgent.getRegionHost() != mCurrentHost) { - sGodTools = new LLFloaterGodTools(); - sGodTools->open(); /*Flawfinder: ignore*/ - sGodTools->center(); - sGodTools->setFocus(TRUE); + // we're in a new region + sendRegionInfoRequest(); } - return sGodTools; } - // static void LLFloaterGodTools::refreshAll() { - LLFloaterGodTools* god_tools = instance(); + LLFloaterGodTools* god_tools = instanceExists() ? getInstance() : NULL; if (god_tools) { if (gAgent.getRegionHost() != god_tools->mCurrentHost) @@ -130,14 +128,17 @@ LLFloaterGodTools::LLFloaterGodTools() factory_map["objects"] = LLCallbackMap(createPanelObjects, this); factory_map["request"] = LLCallbackMap(createPanelRequest, this); LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml", &factory_map); +} +BOOL LLFloaterGodTools::postBuild() +{ getChild("GodTools Tabs")->setCommitCallback(boost::bind(&LLFloaterGodTools::onTabChanged,_1,_2)); sendRegionInfoRequest(); - - childShowTab("GodTools Tabs", "region"); + getChild("GodTools Tabs")->selectTabByName("region"); childSetTextArg("land cost text", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); + return TRUE; } // static @@ -174,9 +175,9 @@ LLFloaterGodTools::~LLFloaterGodTools() } -U32 LLFloaterGodTools::computeRegionFlags() const +U64 LLFloaterGodTools::computeRegionFlags() const { - U32 flags = gAgent.getRegion()->getRegionFlags(); + U64 flags = gAgent.getRegion()->getRegionFlags(); if (mPanelRegionTools) flags = mPanelRegionTools->computeRegionFlags(flags); if (mPanelObjectTools) flags = mPanelObjectTools->computeRegionFlags(flags); return flags; @@ -187,15 +188,6 @@ void LLFloaterGodTools::updatePopup(LLCoordGL center, MASK mask) { } -// virtual -void LLFloaterGodTools::onClose(bool app_quitting) -{ - if (sGodTools) - { - sGodTools->setVisible(FALSE); - } -} - // virtual void LLFloaterGodTools::draw() { @@ -216,31 +208,23 @@ void LLFloaterGodTools::draw() // static void LLFloaterGodTools::show(void *) { - LLFloaterGodTools* god_tools = instance(); - god_tools->open(); - LLPanel *panel = god_tools->childGetVisibleTab("GodTools Tabs"); - if (panel) panel->setFocus(TRUE); - if (god_tools->mPanelObjectTools) god_tools->mPanelObjectTools->setTargetAvatar(LLUUID::null); - - if (gAgent.getRegionHost() != god_tools->mCurrentHost) - { - // we're in a new region - god_tools->sendRegionInfoRequest(); - } + getInstance()->open(); } -void LLFloaterGodTools::hide(void *) +// static +void LLFloaterGodTools::hide() { - if(sGodTools) - sGodTools->setVisible(FALSE);; + if(instanceExists()) + getInstance()->close(); } void LLFloaterGodTools::showPanel(const std::string& panel_name) { - childShowTab("GodTools Tabs", panel_name); + getChild("GodTools Tabs")->selectTabByName(panel_name); open(); /*Flawfinder: ignore*/ - LLPanel *panel = childGetVisibleTab("GodTools Tabs"); - if (panel) panel->setFocus(TRUE); + LLPanel *panel = getChild("GodTools Tabs")->getCurrentPanel(); + if (panel) + panel->setFocus(TRUE); } //static @@ -258,7 +242,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) if (!msg) return; //const S32 SIM_NAME_BUF = 256; - U32 region_flags; + U64 region_flags; U8 sim_access; U8 agent_limit; std::string sim_name; @@ -279,13 +263,23 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, sim_name); msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, estate_id); msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, parent_estate_id); - msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, region_flags); msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, sim_access); msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, agent_limit); msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, object_bonus_factor); msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, billable_factor); msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height); + if (msg->has(_PREHASH_RegionInfo3)) + { + msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, region_flags); + } + else + { + U32 flags = 0; + msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags); + region_flags = flags; + } + if (host != gAgent.getRegionHost()) { // Update is for a different region than the one we're in. @@ -311,15 +305,16 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) regionp->setBillableFactor(billable_factor); } - if (!sGodTools) return; + LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL; + if (!god_tools) return; // push values to god tools, if available if ( gAgent.isGodlike() - && sGodTools->mPanelRegionTools - && sGodTools->mPanelObjectTools) + && god_tools->mPanelRegionTools + && god_tools->mPanelObjectTools) { - LLPanelRegionTools* rtool = sGodTools->mPanelRegionTools; - sGodTools->mCurrentHost = host; + LLPanelRegionTools* rtool = god_tools->mPanelRegionTools; + god_tools->mCurrentHost = host; // store locally rtool->setSimName(sim_name); @@ -332,7 +327,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) rtool->setRedirectGridY(redirect_grid_y); rtool->enableAllWidgets(); - LLPanelObjectTools *otool = sGodTools->mPanelObjectTools; + LLPanelObjectTools *otool = god_tools->mPanelObjectTools; otool->setCheckFlags(region_flags); otool->enableAllWidgets(); @@ -375,17 +370,19 @@ void LLFloaterGodTools::sendRegionInfoRequest() void LLFloaterGodTools::sendGodUpdateRegionInfo() { - if (!sGodTools) return; + LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL; + if (!god_tools) return; LLViewerRegion *regionp = gAgent.getRegion(); if (gAgent.isGodlike() - && sGodTools->mPanelRegionTools + && god_tools->mPanelRegionTools && regionp && gAgent.getRegionHost() == mCurrentHost) { LLMessageSystem *msg = gMessageSystem; - LLPanelRegionTools *rtool = sGodTools->mPanelRegionTools; + LLPanelRegionTools *rtool = god_tools->mPanelRegionTools; + U64 region_flags = computeRegionFlags(); msg->newMessage("GodUpdateRegionInfo"); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); @@ -394,11 +391,14 @@ void LLFloaterGodTools::sendGodUpdateRegionInfo() msg->addStringFast(_PREHASH_SimName, rtool->getSimName()); msg->addU32Fast(_PREHASH_EstateID, rtool->getEstateID()); msg->addU32Fast(_PREHASH_ParentEstateID, rtool->getParentEstateID()); - msg->addU32Fast(_PREHASH_RegionFlags, computeRegionFlags()); + // Legacy flags + msg->addU32Fast(_PREHASH_RegionFlags, U32(region_flags)); msg->addF32Fast(_PREHASH_BillableFactor, rtool->getBillableFactor()); msg->addS32Fast(_PREHASH_PricePerMeter, rtool->getPricePerMeter()); msg->addS32Fast(_PREHASH_RedirectGridX, rtool->getRedirectGridX()); msg->addS32Fast(_PREHASH_RedirectGridY, rtool->getRedirectGridY()); + msg->nextBlockFast(_PREHASH_RegionInfo2); + msg->addU64Fast(_PREHASH_RegionFlagsExtended, region_flags); gAgent.sendReliableMessage(); } @@ -448,54 +448,54 @@ LLPanelRegionTools::LLPanelRegionTools(const std::string& title) BOOL LLPanelRegionTools::postBuild() { - childSetCommitCallback("region name", onChangeAnything, this); + getChild("region name")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); childSetKeystrokeCallback("region name", onChangeSimName, this); childSetPrevalidate("region name", &LLLineEditor::prevalidatePrintableNotPipe); - childSetCommitCallback("check prelude", onChangePrelude, this); - childSetCommitCallback("check fixed sun", onChangeAnything, this); - childSetCommitCallback("check reset home", onChangeAnything, this); - childSetCommitCallback("check visible", onChangeAnything, this); - childSetCommitCallback("check damage", onChangeAnything, this); - childSetCommitCallback("block dwell", onChangeAnything, this); - childSetCommitCallback("block terraform", onChangeAnything, this); - childSetCommitCallback("allow transfer", onChangeAnything, this); - childSetCommitCallback("is sandbox", onChangeAnything, this); + getChild("check prelude")->setCommitCallback(boost::bind(&LLPanelRegionTools:: onChangePrelude, this)); + getChild("check fixed sun")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + getChild("check reset home")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + getChild("check visible")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + getChild("check damage")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + getChild("block dwell")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + getChild("block terraform")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + getChild("allow transfer")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + getChild("is sandbox")->setCommitCallback( boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - childSetAction("Bake Terrain", onBakeTerrain, this); - childSetAction("Revert Terrain", onRevertTerrain, this); - childSetAction("Swap Terrain", onSwapTerrain, this); + childSetAction("Bake Terrain", boost::bind(&LLPanelRegionTools::onBakeTerrain, this)); + childSetAction("Revert Terrain", boost::bind(&LLPanelRegionTools::onRevertTerrain, this)); + childSetAction("Swap Terrain", boost::bind(&LLPanelRegionTools::onSwapTerrain, this)); - childSetCommitCallback("estate", onChangeAnything, this); + getChild("estate")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); childSetPrevalidate("estate", &LLLineEditor::prevalidatePositiveS32); - childSetCommitCallback("parentestate", onChangeAnything, this); + getChild("parentestate")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); childSetPrevalidate("parentestate", &LLLineEditor::prevalidatePositiveS32); childDisable("parentestate"); - childSetCommitCallback("gridposx", onChangeAnything, this); + getChild("gridposx")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); childSetPrevalidate("gridposx", &LLLineEditor::prevalidatePositiveS32); childDisable("gridposx"); - childSetCommitCallback("gridposy", onChangeAnything, this); + getChild("gridposy")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); childSetPrevalidate("gridposy", &LLLineEditor::prevalidatePositiveS32); childDisable("gridposy"); - childSetCommitCallback("redirectx", onChangeAnything, this); + getChild("redirectx")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); childSetPrevalidate("redirectx", &LLLineEditor::prevalidatePositiveS32); - childSetCommitCallback("redirecty", onChangeAnything, this); + getChild("redirecty")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); childSetPrevalidate("redirecty", &LLLineEditor::prevalidatePositiveS32); - childSetCommitCallback("billable factor", onChangeAnything, this); + getChild("billable factor")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - childSetCommitCallback("land cost", onChangeAnything, this); + getChild("land cost")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - childSetAction("Refresh", onRefresh, this); - childSetAction("Apply", onApplyChanges, this); + childSetAction("Refresh", boost::bind(&LLPanelRegionTools::onRefresh, this)); + childSetAction("Apply", boost::bind(&LLPanelRegionTools::onApplyChanges, this)); - childSetAction("Select Region", onSelectRegion, this); - childSetAction("Autosave now", onSaveState, this); + childSetAction("Select Region", boost::bind(&LLPanelRegionTools::onSelectRegion, this)); + childSetAction("Autosave now", boost::bind(onSaveState, this)); return TRUE; } @@ -506,7 +506,7 @@ LLPanelRegionTools::~LLPanelRegionTools() // base class will take care of everything } -U32 LLPanelRegionTools::computeRegionFlags(U32 flags) const +U64 LLPanelRegionTools::computeRegionFlags(U64 flags) const { flags &= getRegionFlagsMask(); flags |= getRegionFlags(); @@ -522,42 +522,42 @@ void LLPanelRegionTools::refresh() void LLPanelRegionTools::clearAllWidgets() { // clear all widgets - childSetValue("region name", "unknown"); - childSetFocus("region name", FALSE); + getChild("region name")->setValue("unknown"); + getChild("region name")->setFocus( FALSE); - childSetValue("check prelude", FALSE); - childDisable("check prelude"); + getChild("check prelude")->setValue(FALSE); + getChildView("check prelude")->setEnabled(FALSE); - childSetValue("check fixed sun", FALSE); - childDisable("check fixed sun"); + getChild("check fixed sun")->setValue(FALSE); + getChildView("check fixed sun")->setEnabled(FALSE); - childSetValue("check reset home", FALSE); - childDisable("check reset home"); + getChild("check reset home")->setValue(FALSE); + getChildView("check reset home")->setEnabled(FALSE); - childSetValue("check damage", FALSE); - childDisable("check damage"); + getChild("check damage")->setValue(FALSE); + getChildView("check damage")->setEnabled(FALSE); - childSetValue("check visible", FALSE); - childDisable("check visible"); + getChild("check visible")->setValue(FALSE); + getChildView("check visible")->setEnabled(FALSE); - childSetValue("block terraform", FALSE); - childDisable("block terraform"); + getChild("block terraform")->setValue(FALSE); + getChildView("block terraform")->setEnabled(FALSE); - childSetValue("block dwell", FALSE); - childDisable("block dwell"); + getChild("block dwell")->setValue(FALSE); + getChildView("block dwell")->setEnabled(FALSE); - childSetValue("is sandbox", FALSE); - childDisable("is sandbox"); + getChild("is sandbox")->setValue(FALSE); + getChildView("is sandbox")->setEnabled(FALSE); - childSetValue("billable factor", BILLABLE_FACTOR_DEFAULT); - childDisable("billable factor"); + getChild("billable factor")->setValue(BILLABLE_FACTOR_DEFAULT); + getChildView("billable factor")->setEnabled(FALSE); - childSetValue("land cost", PRICE_PER_METER_DEFAULT); - childDisable("land cost"); + getChild("land cost")->setValue(PRICE_PER_METER_DEFAULT); + getChildView("land cost")->setEnabled(FALSE); - childDisable("Apply"); - childDisable("Bake Terrain"); - childDisable("Autosave now"); + getChildView("Apply")->setEnabled(FALSE); + getChildView("Bake Terrain")->setEnabled(FALSE); + getChildView("Autosave now")->setEnabled(FALSE); } @@ -565,25 +565,23 @@ void LLPanelRegionTools::enableAllWidgets() { // enable all of the widgets - childEnable("check prelude"); - childEnable("check fixed sun"); - childEnable("check reset home"); - childEnable("check damage"); - childDisable("check visible"); // use estates to update... - childEnable("block terraform"); - childEnable("block dwell"); - childEnable("is sandbox"); + getChildView("check prelude")->setEnabled(TRUE); + getChildView("check fixed sun")->setEnabled(TRUE); + getChildView("check reset home")->setEnabled(TRUE); + getChildView("check damage")->setEnabled(TRUE); + getChildView("check visible")->setEnabled(FALSE); // use estates to update... + getChildView("block terraform")->setEnabled(TRUE); + getChildView("block dwell")->setEnabled(TRUE); + getChildView("is sandbox")->setEnabled(TRUE); - childEnable("billable factor"); - childEnable("land cost"); + getChildView("billable factor")->setEnabled(TRUE); + getChildView("land cost")->setEnabled(TRUE); - childDisable("Apply"); // don't enable this one - childEnable("Bake Terrain"); - childEnable("Autosave now"); + getChildView("Apply")->setEnabled(FALSE); // don't enable this one + getChildView("Bake Terrain")->setEnabled(TRUE); + getChildView("Autosave now")->setEnabled(TRUE); } - -// static void LLPanelRegionTools::onSaveState(void* userdata) { if (gAgent.isGodlike()) @@ -601,112 +599,112 @@ void LLPanelRegionTools::onSaveState(void* userdata) const std::string LLPanelRegionTools::getSimName() const { - return childGetValue("region name"); + return getChild("region name")->getValue(); } U32 LLPanelRegionTools::getEstateID() const { - U32 id = (U32)childGetValue("estate").asInteger(); + U32 id = (U32)getChild("estate")->getValue().asInteger(); return id; } U32 LLPanelRegionTools::getParentEstateID() const { - U32 id = (U32)childGetValue("parentestate").asInteger(); + U32 id = (U32)getChild("parentestate")->getValue().asInteger(); return id; } S32 LLPanelRegionTools::getRedirectGridX() const { - return childGetValue("redirectx").asInteger(); + return getChild("redirectx")->getValue().asInteger(); } S32 LLPanelRegionTools::getRedirectGridY() const { - return childGetValue("redirecty").asInteger(); + return getChild("redirecty")->getValue().asInteger(); } S32 LLPanelRegionTools::getGridPosX() const { - return childGetValue("gridposx").asInteger(); + return getChild("gridposx")->getValue().asInteger(); } S32 LLPanelRegionTools::getGridPosY() const { - return childGetValue("gridposy").asInteger(); + return getChild("gridposy")->getValue().asInteger(); } -U32 LLPanelRegionTools::getRegionFlags() const +U64 LLPanelRegionTools::getRegionFlags() const { - U32 flags = 0x0; - flags = childGetValue("check prelude").asBoolean() + U64 flags = 0x0; + flags = getChild("check prelude")->getValue().asBoolean() ? set_prelude_flags(flags) : unset_prelude_flags(flags); // override prelude - if (childGetValue("check fixed sun").asBoolean()) + if (getChild("check fixed sun")->getValue().asBoolean()) { flags |= REGION_FLAGS_SUN_FIXED; } - if (childGetValue("check reset home").asBoolean()) + if (getChild("check reset home")->getValue().asBoolean()) { flags |= REGION_FLAGS_RESET_HOME_ON_TELEPORT; } - if (childGetValue("check visible").asBoolean()) + if (getChild("check visible")->getValue().asBoolean()) { flags |= REGION_FLAGS_EXTERNALLY_VISIBLE; } - if (childGetValue("check damage").asBoolean()) + if (getChild("check damage")->getValue().asBoolean()) { flags |= REGION_FLAGS_ALLOW_DAMAGE; } - if (childGetValue("block terraform").asBoolean()) + if (getChild("block terraform")->getValue().asBoolean()) { flags |= REGION_FLAGS_BLOCK_TERRAFORM; } - if (childGetValue("block dwell").asBoolean()) + if (getChild("block dwell")->getValue().asBoolean()) { flags |= REGION_FLAGS_BLOCK_DWELL; } - if (childGetValue("is sandbox").asBoolean()) + if (getChild("is sandbox")->getValue().asBoolean()) { flags |= REGION_FLAGS_SANDBOX; } return flags; } -U32 LLPanelRegionTools::getRegionFlagsMask() const +U64 LLPanelRegionTools::getRegionFlagsMask() const { - U32 flags = 0xffffffff; - flags = childGetValue("check prelude").asBoolean() + U64 flags = 0xFFFFFFFFFFFFFFFFULL; + flags = getChild("check prelude")->getValue().asBoolean() ? set_prelude_flags(flags) : unset_prelude_flags(flags); - if (!childGetValue("check fixed sun").asBoolean()) + if (!getChild("check fixed sun")->getValue().asBoolean()) { flags &= ~REGION_FLAGS_SUN_FIXED; } - if (!childGetValue("check reset home").asBoolean()) + if (!getChild("check reset home")->getValue().asBoolean()) { flags &= ~REGION_FLAGS_RESET_HOME_ON_TELEPORT; } - if (!childGetValue("check visible").asBoolean()) + if (!getChild("check visible")->getValue().asBoolean()) { flags &= ~REGION_FLAGS_EXTERNALLY_VISIBLE; } - if (!childGetValue("check damage").asBoolean()) + if (!getChild("check damage")->getValue().asBoolean()) { flags &= ~REGION_FLAGS_ALLOW_DAMAGE; } - if (!childGetValue("block terraform").asBoolean()) + if (!getChild("block terraform")->getValue().asBoolean()) { flags &= ~REGION_FLAGS_BLOCK_TERRAFORM; } - if (!childGetValue("block dwell").asBoolean()) + if (!getChild("block dwell")->getValue().asBoolean()) { flags &= ~REGION_FLAGS_BLOCK_DWELL; } - if (!childGetValue("is sandbox").asBoolean()) + if (!getChild("is sandbox")->getValue().asBoolean()) { flags &= ~REGION_FLAGS_SANDBOX; } @@ -715,150 +713,145 @@ U32 LLPanelRegionTools::getRegionFlagsMask() const F32 LLPanelRegionTools::getBillableFactor() const { - return (F32)childGetValue("billable factor").asReal(); + return (F32)getChild("billable factor")->getValue().asReal(); } S32 LLPanelRegionTools::getPricePerMeter() const { - return childGetValue("land cost"); + return getChild("land cost")->getValue(); } void LLPanelRegionTools::setSimName(const std::string& name) { - childSetValue("region name", name); + getChild("region name")->setValue(name); } void LLPanelRegionTools::setEstateID(U32 id) { - childSetValue("estate", (S32)id); + getChild("estate")->setValue((S32)id); } void LLPanelRegionTools::setGridPosX(S32 pos) { - childSetValue("gridposx", pos); + getChild("gridposx")->setValue(pos); } void LLPanelRegionTools::setGridPosY(S32 pos) { - childSetValue("gridposy", pos); + getChild("gridposy")->setValue(pos); } void LLPanelRegionTools::setRedirectGridX(S32 pos) { - childSetValue("redirectx", pos); + getChild("redirectx")->setValue(pos); } void LLPanelRegionTools::setRedirectGridY(S32 pos) { - childSetValue("redirecty", pos); + getChild("redirecty")->setValue(pos); } void LLPanelRegionTools::setParentEstateID(U32 id) { - childSetValue("parentestate", (S32)id); + getChild("parentestate")->setValue((S32)id); } -void LLPanelRegionTools::setCheckFlags(U32 flags) +void LLPanelRegionTools::setCheckFlags(U64 flags) { - childSetValue("check prelude", is_prelude(flags) ? TRUE : FALSE); - childSetValue("check fixed sun", flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE); - childSetValue("check reset home", flags & REGION_FLAGS_RESET_HOME_ON_TELEPORT ? TRUE : FALSE); - childSetValue("check damage", flags & REGION_FLAGS_ALLOW_DAMAGE ? TRUE : FALSE); - childSetValue("check visible", flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE); - childSetValue("block terraform", flags & REGION_FLAGS_BLOCK_TERRAFORM ? TRUE : FALSE); - childSetValue("block dwell", flags & REGION_FLAGS_BLOCK_DWELL ? TRUE : FALSE); - childSetValue("is sandbox", flags & REGION_FLAGS_SANDBOX ? TRUE : FALSE ); + getChild("check prelude")->setValue(is_prelude(flags) ? TRUE : FALSE); + getChild("check fixed sun")->setValue(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE); + getChild("check reset home")->setValue(flags & REGION_FLAGS_RESET_HOME_ON_TELEPORT ? TRUE : FALSE); + getChild("check damage")->setValue(flags & REGION_FLAGS_ALLOW_DAMAGE ? TRUE : FALSE); + getChild("check visible")->setValue(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE); + getChild("block terraform")->setValue(flags & REGION_FLAGS_BLOCK_TERRAFORM ? TRUE : FALSE); + getChild("block dwell")->setValue(flags & REGION_FLAGS_BLOCK_DWELL ? TRUE : FALSE); + getChild("is sandbox")->setValue(flags & REGION_FLAGS_SANDBOX ? TRUE : FALSE ); } void LLPanelRegionTools::setBillableFactor(F32 billable_factor) { - childSetValue("billable factor", billable_factor); + getChild("billable factor")->setValue(billable_factor); } void LLPanelRegionTools::setPricePerMeter(S32 price) { - childSetValue("land cost", price); + getChild("land cost")->setValue(price); } -// static -void LLPanelRegionTools::onChangeAnything(LLUICtrl* ctrl, void* userdata) +void LLPanelRegionTools::onChangeAnything() { - if (sGodTools && userdata && gAgent.isGodlike()) + if (gAgent.isGodlike()) { - LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata; - region_tools->childEnable("Apply"); + getChildView("Apply")->setEnabled(TRUE); } } -// static -void LLPanelRegionTools::onChangePrelude(LLUICtrl* ctrl, void* data) +void LLPanelRegionTools::onChangePrelude() { // checking prelude auto-checks fixed sun - LLPanelRegionTools* self = (LLPanelRegionTools*)data; - if (self->childGetValue("check prelude").asBoolean()) + if (getChild("check prelude")->getValue().asBoolean()) { - self->childSetValue("check fixed sun", TRUE); - self->childSetValue("check reset home", TRUE); + getChild("check fixed sun")->setValue(TRUE); + getChild("check reset home")->setValue(TRUE); } // pass on to default onChange handler - onChangeAnything(ctrl, data); + onChangeAnything(); } // static void LLPanelRegionTools::onChangeSimName(LLLineEditor* caller, void* userdata ) { - if (sGodTools && userdata && gAgent.isGodlike()) + if (userdata && gAgent.isGodlike()) { LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata; - region_tools->childEnable("Apply"); + region_tools->getChildView("Apply")->setEnabled(TRUE); } } -//static -void LLPanelRegionTools::onRefresh(void* userdata) + +void LLPanelRegionTools::onRefresh() { - if(!sGodTools) return; + LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL; + if(!god_tools) return; LLViewerRegion *region = gAgent.getRegion(); if (region && gAgent.isGodlike()) { - sGodTools->sendRegionInfoRequest(); + god_tools->sendRegionInfoRequest(); + //LLFloaterGodTools::getInstance()->sendRegionInfoRequest(); + //LLFloaterReg::getTypedInstance("god_tools")->sendRegionInfoRequest(); } } -// static -void LLPanelRegionTools::onApplyChanges(void* userdata) +void LLPanelRegionTools::onApplyChanges() { - if(!sGodTools) return; + LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL; + if(!god_tools) return; LLViewerRegion *region = gAgent.getRegion(); - if (region && userdata && gAgent.isGodlike()) + if (region && gAgent.isGodlike()) { - LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata; - - region_tools->childDisable("Apply"); - sGodTools->sendGodUpdateRegionInfo(); + getChildView("Apply")->setEnabled(FALSE); + god_tools->sendGodUpdateRegionInfo(); + //LLFloaterReg::getTypedInstance("god_tools")->sendGodUpdateRegionInfo(); } } -// static -void LLPanelRegionTools::onBakeTerrain(void *userdata) +void LLPanelRegionTools::onBakeTerrain() { LLPanelRequestTools::sendRequest("terrain", "bake", gAgent.getRegionHost()); } -// static -void LLPanelRegionTools::onRevertTerrain(void *userdata) +void LLPanelRegionTools::onRevertTerrain() { LLPanelRequestTools::sendRequest("terrain", "revert", gAgent.getRegionHost()); } -// static -void LLPanelRegionTools::onSwapTerrain(void *userdata) + +void LLPanelRegionTools::onSwapTerrain() { LLPanelRequestTools::sendRequest("terrain", "swap", gAgent.getRegionHost()); } -// static -void LLPanelRegionTools::onSelectRegion(void* userdata) +void LLPanelRegionTools::onSelectRegion() { llinfos << "LLPanelRegionTools::onSelectRegion" << llendl; @@ -913,8 +906,8 @@ LLPanelGridTools::~LLPanelGridTools() BOOL LLPanelGridTools::postBuild() { - childSetAction("Kick all users", onClickKickAll, this); - childSetAction("Flush This Region's Map Visibility Caches", onClickFlushMapVisibilityCaches, this); + childSetAction("Kick all users", boost::bind(&LLPanelGridTools::onClickKickAll, this)); + childSetAction("Flush This Region's Map Visibility Caches", boost::bind(&LLPanelGridTools::onClickFlushMapVisibilityCaches, this)); return TRUE; } @@ -924,17 +917,12 @@ void LLPanelGridTools::refresh() } -// static -void LLPanelGridTools::onClickKickAll(void* userdata) +void LLPanelGridTools::onClickKickAll() { - S32 left, top; - gFloaterView->getNewFloaterPosition(&left, &top); - LLRect rect(left, top, left+400, top-300); - LLNotificationsUtil::add("KickAllUsers", LLSD(), LLSD(), LLPanelGridTools::confirmKick); } - +// static bool LLPanelGridTools::confirmKick(const LLSD& notification, const LLSD& response) { if (LLNotification::getSelectedOption(notification, response) == 0) @@ -946,7 +934,6 @@ bool LLPanelGridTools::confirmKick(const LLSD& notification, const LLSD& respons return false; } - // static bool LLPanelGridTools::finishKick(const LLSD& notification, const LLSD& response) { @@ -968,9 +955,7 @@ bool LLPanelGridTools::finishKick(const LLSD& notification, const LLSD& response return false; } - -// static -void LLPanelGridTools::onClickFlushMapVisibilityCaches(void* data) +void LLPanelGridTools::onClickFlushMapVisibilityCaches() { LLNotificationsUtil::add("FlushMapVisibilityCaches", LLSD(), LLSD(), flushMapVisibilityCachesConfirm); } @@ -978,7 +963,7 @@ void LLPanelGridTools::onClickFlushMapVisibilityCaches(void* data) // static bool LLPanelGridTools::flushMapVisibilityCachesConfirm(const LLSD& notification, const LLSD& response) { - S32 option = LLNotification::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option != 0) return false; // HACK: Send this as an EstateOwnerRequest so it gets routed @@ -1038,22 +1023,23 @@ LLPanelObjectTools::~LLPanelObjectTools() BOOL LLPanelObjectTools::postBuild() { - childSetCommitCallback("disable scripts", onChangeAnything, this); - childSetCommitCallback("disable collisions", onChangeAnything, this); - childSetCommitCallback("disable physics", onChangeAnything, this); + getChild("disable scripts")->setCommitCallback(boost::bind(&LLPanelObjectTools::onChangeAnything, this)); + getChild("disable collisions")->setCommitCallback(boost::bind(&LLPanelObjectTools::onChangeAnything, this)); + getChild("disable physics")->setCommitCallback(boost::bind(&LLPanelObjectTools::onChangeAnything, this)); - childSetAction("Apply", onApplyChanges, this); + childSetAction("Apply", boost::bind(&LLPanelObjectTools::onApplyChanges, this)); - childSetAction("Set Target", onClickSet, this); + childSetAction("Set Target", boost::bind(&LLPanelObjectTools::onClickSet, this)); - childSetAction("Delete Target's Scripted Objects On Others Land", onClickDeletePublicOwnedBy, this); - childSetAction("Delete Target's Scripted Objects On *Any* Land", onClickDeleteAllScriptedOwnedBy, this); - childSetAction("Delete *ALL* Of Target's Objects", onClickDeleteAllOwnedBy, this); + childSetAction("Delete Target's Scripted Objects On Others Land", boost::bind(&LLPanelObjectTools::onClickDeletePublicOwnedBy, this)); + childSetAction("Delete Target's Scripted Objects On *Any* Land", boost::bind(&LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy, this)); + childSetAction("Delete *ALL* Of Target's Objects", boost::bind(&LLPanelObjectTools::onClickDeleteAllOwnedBy, this)); - childSetAction("Get Top Colliders", onGetTopColliders, this); - childSetAction("Get Top Scripts", onGetTopScripts, this); - childSetAction("Scripts digest", onGetScriptDigest, this); + childSetAction("Get Top Colliders", boost::bind(&LLPanelObjectTools::onGetTopColliders, this)); + childSetAction("Get Top Scripts", boost::bind(&LLPanelObjectTools::onGetTopScripts, this)); + childSetAction("Scripts digest", boost::bind(&LLPanelObjectTools::onGetScriptDigest, this)); + refresh(); return TRUE; } @@ -1062,7 +1048,7 @@ void LLPanelObjectTools::setTargetAvatar(const LLUUID &target_id) mTargetAvatar = target_id; if (target_id.isNull()) { - childSetValue("target_avatar_name", getString("no_target")); + getChild("target_avatar_name")->setValue(getString("no_target")); } } @@ -1072,14 +1058,14 @@ void LLPanelObjectTools::refresh() LLViewerRegion *regionp = gAgent.getRegion(); if (regionp) { - childSetText("region name", regionp->getName()); + getChild("region name")->setValue(regionp->getName()); } } -U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const +U64 LLPanelObjectTools::computeRegionFlags(U64 flags) const { - if (childGetValue("disable scripts").asBoolean()) + if (getChild("disable scripts")->getValue().asBoolean()) { flags |= REGION_FLAGS_SKIP_SCRIPTS; } @@ -1087,7 +1073,7 @@ U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const { flags &= ~REGION_FLAGS_SKIP_SCRIPTS; } - if (childGetValue("disable collisions").asBoolean()) + if (getChild("disable collisions")->getValue().asBoolean()) { flags |= REGION_FLAGS_SKIP_COLLISIONS; } @@ -1095,7 +1081,7 @@ U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const { flags &= ~REGION_FLAGS_SKIP_COLLISIONS; } - if (childGetValue("disable physics").asBoolean()) + if (getChild("disable physics")->getValue().asBoolean()) { flags |= REGION_FLAGS_SKIP_PHYSICS; } @@ -1107,46 +1093,45 @@ U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const } -void LLPanelObjectTools::setCheckFlags(U32 flags) +void LLPanelObjectTools::setCheckFlags(U64 flags) { - childSetValue("disable scripts", flags & REGION_FLAGS_SKIP_SCRIPTS ? TRUE : FALSE); - childSetValue("disable collisions", flags & REGION_FLAGS_SKIP_COLLISIONS ? TRUE : FALSE); - childSetValue("disable physics", flags & REGION_FLAGS_SKIP_PHYSICS ? TRUE : FALSE); + getChild("disable scripts")->setValue(flags & REGION_FLAGS_SKIP_SCRIPTS ? TRUE : FALSE); + getChild("disable collisions")->setValue(flags & REGION_FLAGS_SKIP_COLLISIONS ? TRUE : FALSE); + getChild("disable physics")->setValue(flags & REGION_FLAGS_SKIP_PHYSICS ? TRUE : FALSE); } void LLPanelObjectTools::clearAllWidgets() { - childSetValue("disable scripts", FALSE); - childDisable("disable scripts"); + getChild("disable scripts")->setValue(FALSE); + getChildView("disable scripts")->setEnabled(FALSE); - childDisable("Apply"); - childDisable("Set Target"); - childDisable("Delete Target's Scripted Objects On Others Land"); - childDisable("Delete Target's Scripted Objects On *Any* Land"); - childDisable("Delete *ALL* Of Target's Objects"); + getChildView("Apply")->setEnabled(FALSE); + getChildView("Set Target")->setEnabled(FALSE); + getChildView("Delete Target's Scripted Objects On Others Land")->setEnabled(FALSE); + getChildView("Delete Target's Scripted Objects On *Any* Land")->setEnabled(FALSE); + getChildView("Delete *ALL* Of Target's Objects")->setEnabled(FALSE); } void LLPanelObjectTools::enableAllWidgets() { - childEnable("disable scripts"); + getChildView("disable scripts")->setEnabled(TRUE); - childDisable("Apply"); // don't enable this one - childEnable("Set Target"); - childEnable("Delete Target's Scripted Objects On Others Land"); - childEnable("Delete Target's Scripted Objects On *Any* Land"); - childEnable("Delete *ALL* Of Target's Objects"); - childEnable("Get Top Colliders"); - childEnable("Get Top Scripts"); + getChildView("Apply")->setEnabled(FALSE); // don't enable this one + getChildView("Set Target")->setEnabled(TRUE); + getChildView("Delete Target's Scripted Objects On Others Land")->setEnabled(TRUE); + getChildView("Delete Target's Scripted Objects On *Any* Land")->setEnabled(TRUE); + getChildView("Delete *ALL* Of Target's Objects")->setEnabled(TRUE); + getChildView("Get Top Colliders")->setEnabled(TRUE); + getChildView("Get Top Scripts")->setEnabled(TRUE); } - -// static -void LLPanelObjectTools::onGetTopColliders(void* userdata) +void LLPanelObjectTools::onGetTopColliders() { - if(!sGodTools) return; - + LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL; + if(!god_tools) + return; if (gAgent.isGodlike()) { LLFloaterTopObjects::show(); @@ -1155,11 +1140,11 @@ void LLPanelObjectTools::onGetTopColliders(void* userdata) } } -// static -void LLPanelObjectTools::onGetTopScripts(void* userdata) +void LLPanelObjectTools::onGetTopScripts() { - if(!sGodTools) return; - + LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL; + if(!god_tools) + return; if (gAgent.isGodlike()) { LLFloaterTopObjects::show(); @@ -1168,10 +1153,9 @@ void LLPanelObjectTools::onGetTopScripts(void* userdata) } } -// static -void LLPanelObjectTools::onGetScriptDigest(void* userdata) +void LLPanelObjectTools::onGetScriptDigest() { - if (sGodTools && gAgent.isGodlike()) + if (gAgent.isGodlike()) { // get the list of scripts and number of occurences of each // (useful for finding self-replicating objects) @@ -1179,66 +1163,62 @@ void LLPanelObjectTools::onGetScriptDigest(void* userdata) } } -void LLPanelObjectTools::onClickDeletePublicOwnedBy(void* userdata) +void LLPanelObjectTools::onClickDeletePublicOwnedBy() { // Bring up view-modal dialog - LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata; - if (!panelp->mTargetAvatar.isNull()) + + if (!mTargetAvatar.isNull()) { - panelp->mSimWideDeletesFlags = + mSimWideDeletesFlags = SWD_SCRIPTED_ONLY | SWD_OTHERS_LAND_ONLY; LLSD args; - args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + args["AVATAR_NAME"] = getChild("target_avatar_name")->getValue().asString(); LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - payload["flags"] = (S32)panelp->mSimWideDeletesFlags; + payload["avatar_id"] = mTargetAvatar; + payload["flags"] = (S32)mSimWideDeletesFlags; - LLNotifications::instance().add( "GodDeleteAllScriptedPublicObjectsByUser", + LLNotificationsUtil::add( "GodDeleteAllScriptedPublicObjectsByUser", args, payload, callbackSimWideDeletes); } } -// static -void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy(void* userdata) +void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy() { // Bring up view-modal dialog - LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata; - if (!panelp->mTargetAvatar.isNull()) + if (!mTargetAvatar.isNull()) { - panelp->mSimWideDeletesFlags = SWD_SCRIPTED_ONLY; + mSimWideDeletesFlags = SWD_SCRIPTED_ONLY; LLSD args; - args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + args["AVATAR_NAME"] = getChild("target_avatar_name")->getValue().asString(); LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - payload["flags"] = (S32)panelp->mSimWideDeletesFlags; + payload["avatar_id"] = mTargetAvatar; + payload["flags"] = (S32)mSimWideDeletesFlags; - LLNotifications::instance().add( "GodDeleteAllScriptedObjectsByUser", + LLNotificationsUtil::add( "GodDeleteAllScriptedObjectsByUser", args, payload, callbackSimWideDeletes); } } -// static -void LLPanelObjectTools::onClickDeleteAllOwnedBy(void* userdata) +void LLPanelObjectTools::onClickDeleteAllOwnedBy() { // Bring up view-modal dialog - LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata; - if (!panelp->mTargetAvatar.isNull()) + if (!mTargetAvatar.isNull()) { - panelp->mSimWideDeletesFlags = 0; + mSimWideDeletesFlags = 0; LLSD args; - args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + args["AVATAR_NAME"] = getChild("target_avatar_name")->getValue().asString(); LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - payload["flags"] = (S32)panelp->mSimWideDeletesFlags; + payload["avatar_id"] = mTargetAvatar; + payload["flags"] = (S32)mSimWideDeletesFlags; - LLNotifications::instance().add( "GodDeleteAllObjectsByUser", + LLNotificationsUtil::add( "GodDeleteAllObjectsByUser", args, payload, callbackSimWideDeletes); @@ -1248,7 +1228,7 @@ void LLPanelObjectTools::onClickDeleteAllOwnedBy(void* userdata) // static bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const LLSD& response ) { - S32 option = LLNotification::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option == 0) { if (!notification["payload"]["avatar_id"].asUUID().isNull()) @@ -1260,11 +1240,14 @@ bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const return false; } -void LLPanelObjectTools::onClickSet(void* data) +void LLPanelObjectTools::onClickSet() { - LLPanelObjectTools* panelp = (LLPanelObjectTools*) data; + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2)); // grandparent is a floater, which can have a dependent - gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, data)); + if (picker) + { + gFloaterView->getParentFloater(this)->addDependentFloater(picker); + } } void LLPanelObjectTools::onClickSetBySelection(void* data) @@ -1285,42 +1268,36 @@ void LLPanelObjectTools::onClickSetBySelection(void* data) args["[OBJECT]"] = node->mName; args["[OWNER]"] = owner_name; std::string name = LLTrans::getString("GodToolsObjectOwnedBy", args); - panelp->childSetValue("target_avatar_name", name); + panelp->getChild("target_avatar_name")->setValue(name); } -// static -void LLPanelObjectTools::callbackAvatarID(const std::vector& names, const std::vector& ids, void* data) +void LLPanelObjectTools::callbackAvatarID(const uuid_vec_t& ids, const std::vector names) { - LLPanelObjectTools* object_tools = (LLPanelObjectTools*) data; if (ids.empty() || names.empty()) return; - object_tools->mTargetAvatar = ids[0]; - object_tools->childSetValue("target_avatar_name", names[0]); - object_tools->refresh(); + mTargetAvatar = ids[0]; + getChild("target_avatar_name")->setValue(names[0].getCompleteName()); + refresh(); } -// static -void LLPanelObjectTools::onChangeAnything(LLUICtrl* ctrl, void* userdata) +void LLPanelObjectTools::onChangeAnything() { - if (sGodTools - && userdata - && gAgent.isGodlike()) + if (gAgent.isGodlike()) { - LLPanelObjectTools* object_tools = (LLPanelObjectTools*) userdata; - object_tools->childEnable("Apply"); + getChildView("Apply")->setEnabled(TRUE); } } -// static -void LLPanelObjectTools::onApplyChanges(void* userdata) +void LLPanelObjectTools::onApplyChanges() { - if(!sGodTools) return; + LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL; + if(!god_tools) return; LLViewerRegion *region = gAgent.getRegion(); - if (region && userdata && gAgent.isGodlike()) + if (region && gAgent.isGodlike()) { - LLPanelObjectTools* object_tools = (LLPanelObjectTools*) userdata; // TODO -- implement this - object_tools->childDisable("Apply"); - sGodTools->sendGodUpdateRegionInfo(); + getChildView("Apply")->setEnabled(FALSE); + god_tools->sendGodUpdateRegionInfo(); + //LLFloaterReg::getTypedInstance("god_tools")->sendGodUpdateRegionInfo(); } } @@ -1343,7 +1320,7 @@ LLPanelRequestTools::~LLPanelRequestTools() BOOL LLPanelRequestTools::postBuild() { - childSetAction("Make Request", onClickRequest, this); + childSetAction("Make Request", boost::bind(&LLPanelRequestTools::onClickRequest, this)); refresh(); @@ -1352,7 +1329,7 @@ BOOL LLPanelRequestTools::postBuild() void LLPanelRequestTools::refresh() { - std::string buffer = childGetValue("destination"); + std::string buffer = getChild("destination")->getValue(); LLCtrlListInterface *list = childGetListInterface("destination"); if (!list) return; @@ -1401,21 +1378,19 @@ void LLPanelRequestTools::sendRequest(const std::string& request, msg->sendReliable(host); } -// static -void LLPanelRequestTools::onClickRequest(void* data) +void LLPanelRequestTools::onClickRequest() { - LLPanelRequestTools* self = (LLPanelRequestTools*)data; - const std::string dest = self->childGetValue("destination").asString(); + const std::string dest = getChild("destination")->getValue().asString(); if(dest == SELECTION) { - std::string req = self->childGetValue("request"); + std::string req =getChild("request")->getValue(); req = req.substr(0, req.find_first_of(" ")); - std::string param = self->childGetValue("parameter"); + std::string param = getChild("parameter")->getValue(); LLSelectMgr::getInstance()->sendGodlikeRequest(req, param); } else if(dest == AGENT_REGION) { - self->sendRequest(gAgent.getRegionHost()); + sendRequest(gAgent.getRegionHost()); } else { @@ -1427,7 +1402,7 @@ void LLPanelRequestTools::onClickRequest(void* data) if(dest == regionp->getName()) { // found it - self->sendRequest(regionp->getHost()); + sendRequest(regionp->getHost()); } } } @@ -1449,7 +1424,7 @@ void LLPanelRequestTools::sendRequest(const LLHost& host) { // intercept viewer local actions here - std::string req = childGetValue("request"); + std::string req = getChild("request")->getValue(); if (req == "terrain download") { gXferManager->requestFile(std::string("terrain.raw"), std::string("terrain.raw"), LL_PATH_NONE, @@ -1461,7 +1436,7 @@ void LLPanelRequestTools::sendRequest(const LLHost& host) else { req = req.substr(0, req.find_first_of(" ")); - sendRequest(req, childGetValue("parameter").asString(), host); + sendRequest(req, getChild("parameter")->getValue().asString(), host); } } diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h index 3c36f256f..6e6d271b7 100644 --- a/indra/newview/llfloatergodtools.h +++ b/indra/newview/llfloatergodtools.h @@ -2,31 +2,25 @@ * @file llfloatergodtools.h * @brief The on-screen rectangle with tool options. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,6 +35,7 @@ #include "llpanel.h" #include +class LLAvatarName; class LLButton; class LLCheckBoxCtrl; class LLComboBox; @@ -57,12 +52,10 @@ class LLTextBox; class LLMessageSystem; class LLFloaterGodTools -: public LLFloater +: public LLFloater, public LLSingleton { public: - static LLFloaterGodTools* instance(); - enum EGodPanel { PANEL_GRID, @@ -73,7 +66,7 @@ public: }; static void show(void *); - static void hide(void *); + static void hide(); static void* createPanelGrid(void *userdata); static void* createPanelRegion(void *userdata); @@ -84,7 +77,7 @@ public: void showPanel(const std::string& panel_name); - virtual void onClose(bool app_quitting); + virtual void onOpen(); virtual void draw(); @@ -103,19 +96,21 @@ public: static void onTabChanged(LLUICtrl* ctrl, const LLSD& param); -protected: - U32 computeRegionFlags() const; - -protected: +public: + LLFloaterGodTools(); ~LLFloaterGodTools(); + +protected: + U64 computeRegionFlags() const; +protected: + + /*virtual*/ BOOL postBuild(); // When the floater is going away, reset any options that need to be // cleared. void resetToolState(); - static LLFloaterGodTools* sInstance; - public: LLPanelRegionTools *mPanelRegionTools; LLPanelObjectTools *mPanelObjectTools; @@ -140,23 +135,24 @@ public: /*virtual*/ void refresh(); - static void onSaveState(void* data); - static void onChangeAnything(LLUICtrl* ctrl, void* userdata); - static void onChangePrelude(LLUICtrl* ctrl, void* data); + static void onSaveState(void* userdata); static void onChangeSimName(LLLineEditor* caller, void* userdata); - static void onApplyChanges(void* userdata); - static void onBakeTerrain(void *userdata); - static void onRevertTerrain(void *userdata); - static void onSwapTerrain(void *userdata); - static void onSelectRegion(void *userdata); - static void onRefresh(void* userdata); + + void onChangeAnything(); + void onChangePrelude(); + void onApplyChanges(); + void onBakeTerrain(); + void onRevertTerrain(); + void onSwapTerrain(); + void onSelectRegion(); + void onRefresh(); // set internal checkboxes/spinners/combos const std::string getSimName() const; U32 getEstateID() const; U32 getParentEstateID() const; - U32 getRegionFlags() const; - U32 getRegionFlagsMask() const; + U64 getRegionFlags() const; + U64 getRegionFlagsMask() const; F32 getBillableFactor() const; S32 getPricePerMeter() const; S32 getGridPosX() const; @@ -168,7 +164,7 @@ public: void setSimName(const std::string& name); void setEstateID(U32 id); void setParentEstateID(U32 id); - void setCheckFlags(U32 flags); + void setCheckFlags(U64 flags); void setBillableFactor(F32 billable_factor); void setPricePerMeter(S32 price); void setGridPosX(S32 pos); @@ -176,7 +172,7 @@ public: void setRedirectGridX(S32 pos); void setRedirectGridY(S32 pos); - U32 computeRegionFlags(U32 initial_flags) const; + U64 computeRegionFlags(U64 initial_flags) const; void clearAllWidgets(); void enableAllWidgets(); @@ -201,11 +197,11 @@ public: void refresh(); - static void onClickKickAll(void *data); + void onClickKickAll(); static bool confirmKick(const LLSD& notification, const LLSD& response); static bool finishKick(const LLSD& notification, const LLSD& response); static void onDragSunPhase(LLUICtrl *ctrl, void *userdata); - static void onClickFlushMapVisibilityCaches(void* data); + void onClickFlushMapVisibilityCaches(); static bool flushMapVisibilityCachesConfirm(const LLSD& notification, const LLSD& response); protected: @@ -229,22 +225,22 @@ public: /*virtual*/ void refresh(); void setTargetAvatar(const LLUUID& target_id); - U32 computeRegionFlags(U32 initial_flags) const; + U64 computeRegionFlags(U64 initial_flags) const; void clearAllWidgets(); void enableAllWidgets(); - void setCheckFlags(U32 flags); + void setCheckFlags(U64 flags); - static void onChangeAnything(LLUICtrl* ctrl, void* data); - static void onApplyChanges(void* data); - static void onClickSet(void* data); - static void callbackAvatarID(const std::vector& names, const std::vector& ids, void* data); - static void onClickDeletePublicOwnedBy(void* data); - static void onClickDeleteAllScriptedOwnedBy(void* data); - static void onClickDeleteAllOwnedBy(void* data); + void onChangeAnything(); + void onApplyChanges(); + void onClickSet(); + void callbackAvatarID(const uuid_vec_t& ids, const std::vector names); + void onClickDeletePublicOwnedBy(); + void onClickDeleteAllScriptedOwnedBy(); + void onClickDeleteAllOwnedBy(); static bool callbackSimWideDeletes(const LLSD& notification, const LLSD& response); - static void onGetTopColliders(void* data); - static void onGetTopScripts(void* data); - static void onGetScriptDigest(void* data); + void onGetTopColliders(); + void onGetTopScripts(); + void onGetScriptDigest(); static void onClickSetBySelection(void* data); protected: @@ -274,7 +270,7 @@ public: const LLHost& host); protected: - static void onClickRequest(void *data); + void onClickRequest(); void sendRequest(const LLHost& host); }; diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index ddc601f9d..eff6d409b 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -70,9 +70,6 @@ std::map LLFloaterGroupPicker::sInstances; // helper functions void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask = GP_ALL_POWERS); -//callbacks -void onGroupSortChanged(void* user_data); - ///---------------------------------------------------------------------------- /// Class LLFloaterGroupPicker ///---------------------------------------------------------------------------- @@ -128,7 +125,8 @@ BOOL LLFloaterGroupPicker::postBuild() { const std::string none_text = getString("none"); - init_group_list(getChild("group list"), gAgent.getGroupID(), none_text, mPowersMask); + LLScrollListCtrl* group_list = getChild("group list"); + init_group_list(group_list, gAgent.getGroupID(), none_text, mPowersMask); childSetAction("OK", onBtnOK, this); @@ -136,8 +134,7 @@ BOOL LLFloaterGroupPicker::postBuild() setDefaultBtn("OK"); - childSetDoubleClickCallback("group list", onBtnOK); - childSetUserData("group list", this); + group_list->setDoubleClickCallback(boost::bind(&LLFloaterGroupPicker::onBtnOK,this)); childEnable("OK"); @@ -214,15 +211,15 @@ void LLPanelGroups::reset() BOOL LLPanelGroups::postBuild() { - childSetCommitCallback("group list", onGroupList, this); - childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count())); childSetTextArg("groupcount", "[MAX]", llformat("%d", gHippoLimits->getMaxAgentGroups())); const std::string none_text = getString("none"); LLScrollListCtrl *group_list = getChild("group list"); init_group_list(group_list, gAgent.getGroupID(), none_text); - group_list->setSortChangedCallback(onGroupSortChanged); //Force 'none' to always be first entry. + group_list->setCommitCallback(boost::bind(&LLPanelGroups::onGroupList,this)); + group_list->setSortChangedCallback(boost::bind(&LLPanelGroups::onGroupSortChanged,this)); //Force 'none' to always be first entry. + group_list->setDoubleClickCallback(boost::bind(&LLPanelGroups::onBtnIM,this)); childSetAction("Activate", onBtnActivate, this); @@ -242,9 +239,6 @@ BOOL LLPanelGroups::postBuild() setDefaultBtn("IM"); - childSetDoubleClickCallback("group list", onBtnIM); - childSetUserData("group list", this); - reset(); return TRUE; @@ -392,7 +386,9 @@ void LLPanelGroups::startIM() LLGroupData group_data; if (gAgent.getGroupData(group_id, group_data)) { - gIMMgr->setFloaterOpen(TRUE); + static LLCachedControl tear_off("OtherChatsTornOff"); + if (!tear_off) + gIMMgr->setFloaterOpen(TRUE); gIMMgr->addSession( group_data.mName, IM_SESSION_GROUP_START, @@ -478,15 +474,20 @@ bool LLPanelGroups::callbackLeaveGroup(const LLSD& notification, const LLSD& res return false; } -void LLPanelGroups::onGroupList(LLUICtrl* ctrl, void* userdata) +void LLPanelGroups::onGroupSortChanged() { - LLPanelGroups *self = (LLPanelGroups*)userdata; - if(!self) + LLScrollListCtrl *group_list = getChild("group list"); + if(!group_list) return; - self->enableButtons(); + group_list->moveToFront(group_list->getItemIndex(LLUUID::null)); +} - LLScrollListCtrl *group_list = (LLScrollListCtrl*)self->getChild("group list"); +void LLPanelGroups::onGroupList() +{ + enableButtons(); + + LLScrollListCtrl *group_list = getChild("group list"); if(!group_list) return; @@ -561,18 +562,6 @@ LLSD create_group_element(const LLGroupData *group_datap, const LLUUID &active_g return element; } -void onGroupSortChanged(void* user_data) -{ - LLPanelGroups *panel = (LLPanelGroups*)user_data; - if(!panel) - return; - LLScrollListCtrl *group_list = (LLScrollListCtrl*)panel->getChild("group list"); - if(!group_list) - return; - - group_list->moveToFront(group_list->getItemIndex(LLUUID::null)); -} - void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask) { S32 count = gAgent.mGroups.count(); diff --git a/indra/newview/llfloatergroups.h b/indra/newview/llfloatergroups.h index 5311809eb..ebf37acd7 100644 --- a/indra/newview/llfloatergroups.h +++ b/indra/newview/llfloatergroups.h @@ -103,7 +103,8 @@ protected: // highlight_id is a group id to highlight void enableButtons(); - static void onGroupList(LLUICtrl* ctrl, void* userdata); + void onGroupSortChanged(); + void onGroupList(); static void onBtnCreate(void* userdata); static void onBtnActivate(void* userdata); static void onBtnInfo(void* userdata); diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index edb961685..013c9aa49 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -82,21 +82,23 @@ const S32 PREVIEW_TEXTURE_HEIGHT = 300; LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) : LLFloaterNameDesc(filename), mAvatarPreview(NULL), - mSculptedPreview(NULL) + mSculptedPreview(NULL), + mLastMouseX(0), + mLastMouseY(0), + mImagep(NULL) { - mLastMouseX = 0; - mLastMouseY = 0; - mImagep = NULL ; loadImage(mFilenameAndPath); } // LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename, void* item) : - LLFloaterNameDesc(filename, item) + LLFloaterNameDesc(filename, item), + mAvatarPreview(NULL), + mSculptedPreview(NULL), + mLastMouseX(0), + mLastMouseY(0), + mImagep(NULL) { - mLastMouseX = 0; - mLastMouseY = 0; - mImagep = NULL ; loadImage(mFilenameAndPath); } // @@ -664,7 +666,7 @@ S8 LLImagePreviewAvatar::getType() const void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male) { - mTargetJoint = mDummyAvatar->mRoot.findJoint(joint_name); + mTargetJoint = mDummyAvatar->mRoot->findJoint(joint_name); // clear out existing test mesh if (mTargetMesh) { @@ -683,9 +685,9 @@ void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const mDummyAvatar->updateVisualParams(); mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable); } - mDummyAvatar->mRoot.setVisible(FALSE, TRUE); + mDummyAvatar->mRoot->setVisible(FALSE, TRUE); - mTargetMesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name); + mTargetMesh = dynamic_cast(mDummyAvatar->mRoot->findJoint(mesh_name)); mTargetMesh->setTestTexture(mTextureName); mTargetMesh->setVisible(TRUE, FALSE); mCameraDistance = distance; @@ -702,7 +704,7 @@ void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name) { if (mDummyAvatar) { - LLViewerJointMesh *mesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name); + LLViewerJointMesh *mesh = dynamic_cast(mDummyAvatar->mRoot->findJoint(mesh_name)); // clear out existing test mesh if (mesh) { diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 4ba6cc806..007a4670d 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -166,7 +166,7 @@ BOOL LLFloaterInspect::postBuild() mObjectList = getChild("object_list"); childSetAction("button owner",onClickOwnerProfile, this); childSetAction("button creator",onClickCreatorProfile, this); - childSetCommitCallback("object_list", onSelectObject); + childSetCommitCallback("object_list", onSelectObject, this); return TRUE; } diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 3d1a4452f..37d795a49 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -37,6 +37,7 @@ #include "llfloaterland.h" +#include "llavatarnamecache.h" #include "llcachename.h" #include "llfocusmgr.h" #include "llnotificationsutil.h" @@ -518,7 +519,7 @@ void LLPanelLandGeneral::refresh() BOOL is_leased = (LLParcel::OS_LEASED == parcel->getOwnershipStatus()); BOOL region_xfer = FALSE; if(regionp - && !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)) + && !regionp->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)) { region_xfer = TRUE; } @@ -653,20 +654,26 @@ void LLPanelLandGeneral::refresh() S32 area; S32 claim_price; S32 rent_price; - F32 dwell; + F32 dwell = DWELL_NAN; LLViewerParcelMgr::getInstance()->getDisplayInfo(&area, &claim_price, &rent_price, &for_sale, &dwell); - // Area LLUIString price = getString("area_size_text"); price.setArg("[AREA]", llformat("%d",area)); mTextPriceLabel->setText(getString("area_text")); mTextPrice->setText(price.getString()); - mTextDwell->setText(llformat("%.0f", dwell)); + if (dwell == DWELL_NAN) + { + mTextDwell->setText(LLTrans::getString("LoadingData")); + } + else + { + mTextDwell->setText(llformat("%.0f", dwell)); + } if (for_sale) { @@ -1125,8 +1132,8 @@ BOOL LLPanelLandObjects::postBuild() mOwnerList = getChild("owner list"); mOwnerList->sortByColumnIndex(3, FALSE); - childSetCommitCallback("owner list", onCommitList, this); - mOwnerList->setDoubleClickCallback(onDoubleClickOwner); + mOwnerList->setCommitCallback(boost::bind(&LLPanelLandObjects::onCommitList,this)); + mOwnerList->setDoubleClickCallback(boost::bind(&LLPanelLandObjects::onDoubleClickOwner, this)); return TRUE; } @@ -1499,7 +1506,7 @@ void LLPanelLandObjects::onClickRefresh(void* userdata) // ready the list for results self->mOwnerList->deleteAllItems(); - self->mOwnerList->addCommentText(LLTrans::getString("Searching")); + self->mOwnerList->setCommentText(LLTrans::getString("Searching")); self->mOwnerList->setEnabled(FALSE); self->mFirstReply = TRUE; @@ -1526,8 +1533,6 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo return; } - const LLFontGL* FONT = LLFontGL::getFontSansSerif(); - // Extract all of the owners. S32 rows = msg->getNumberOfBlocksFast(_PREHASH_Data); //uuid_list_t return_ids; @@ -1568,44 +1573,64 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo BOOL in_sim = (std::find(avatar_ids.begin(), avatar_ids.end(), owner_id) != avatar_ids.end()); - LLScrollListItem *row = new LLScrollListItem( TRUE, NULL, owner_id); + LLSD item; + item["id"] = owner_id; + LLSD& row = item["columns"]; + LLSD icon_column; + LLSD status_column; + icon_column["type"] = "icon"; + icon_column["column"] = "type"; + status_column["font"] = "SANSSERIF"; + status_column["column"] = "online_status"; + if (is_group_owned) { - row->addColumn(self->mIconGroup); - row->addColumn(OWNER_GROUP, FONT); + icon_column["value"] = self->mIconGroup->getName(); + status_column["value"] = OWNER_GROUP; } else if (in_sim) { - row->addColumn(self->mIconAvatarInSim); - row->addColumn(OWNER_INSIM, FONT); + icon_column["value"] = self->mIconAvatarInSim->getName(); + status_column["value"] = OWNER_INSIM; } else if (is_online) { - row->addColumn(self->mIconAvatarOnline); - row->addColumn(OWNER_ONLINE, FONT); + icon_column["value"] = self->mIconAvatarOnline->getName(); + status_column["value"] = OWNER_ONLINE; } else // offline { - row->addColumn(self->mIconAvatarOffline); - row->addColumn(OWNER_OFFLINE, FONT); + icon_column["value"] = self->mIconAvatarOffline->getName(); + status_column["value"] = OWNER_OFFLINE; } + row.append(icon_column); + row.append(status_column); + // Placeholder for name. - row->addColumn(LLStringUtil::null, FONT); + LLAvatarName av_name; + LLAvatarNameCache::get(owner_id, &av_name); + LLSD name_column; + name_column["value"] = av_name.getCompleteName(); + name_column["font"] = "SANSSERIF"; + name_column["column"] = "name"; + row.append(name_column); - object_count_str = llformat("%d", object_count); - row->addColumn(object_count_str, FONT); + LLSD count_column; + count_column["value"] = llformat("%d", object_count); + count_column["font"] = "SANSSERIF"; + count_column["column"] = "count"; + row.append(count_column); - row->addColumn(formatted_time((time_t)most_recent_time), FONT); + LLSD time_column; + time_column["value"] = formatted_time((time_t)most_recent_time); + time_column["font"] = "SANSSERIF"; + time_column["column"] = "mostrecent"; + row.append(time_column); - - if (is_group_owned) - { - self->mOwnerList->addGroupNameItem(row, ADD_BOTTOM); - } + if( is_group_owned ) + self->mOwnerList->addGroupNameItem(item, ADD_BOTTOM); else - { - self->mOwnerList->addNameItem(row, ADD_BOTTOM); - } + self->mOwnerList->addNameItem(item, ADD_BOTTOM); lldebugs << "object owner " << owner_id << " (" << (is_group_owned ? "group" : "agent") << ") owns " << object_count << " objects." << llendl; @@ -1613,7 +1638,7 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo // check for no results if (0 == self->mOwnerList->getItemCount()) { - self->mOwnerList->addCommentText(LLTrans::getString("NoneFound")); + self->mOwnerList->setCommentText(LLTrans::getString("NoneFound")); } else { @@ -1621,16 +1646,13 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo } } -// static -void LLPanelLandObjects::onCommitList(LLUICtrl* ctrl, void* data) +void LLPanelLandObjects::onCommitList() { - LLPanelLandObjects* self = (LLPanelLandObjects*)data; - - if (FALSE == self->mOwnerList->getCanSelect()) + if (FALSE == mOwnerList->getCanSelect()) { return; } - LLScrollListItem *item = self->mOwnerList->getFirstSelected(); + LLScrollListItem *item = mOwnerList->getFirstSelected(); if (item) { // Look up the selected name, for future dialog box use. @@ -1641,19 +1663,19 @@ void LLPanelLandObjects::onCommitList(LLUICtrl* ctrl, void* data) return; } // Is this a group? - self->mSelectedIsGroup = cell->getValue().asString() == OWNER_GROUP; + mSelectedIsGroup = cell->getValue().asString() == OWNER_GROUP; cell = item->getColumn(2); - self->mSelectedName = cell->getValue().asString(); + mSelectedName = cell->getValue().asString(); cell = item->getColumn(3); - self->mSelectedCount = atoi(cell->getValue().asString().c_str()); + mSelectedCount = atoi(cell->getValue().asString().c_str()); // Set the selection, and enable the return button. - self->mSelectedOwners.clear(); - self->mSelectedOwners.insert(item->getUUID()); - self->mBtnReturnOwnerList->setEnabled(TRUE); + mSelectedOwners.clear(); + mSelectedOwners.insert(item->getUUID()); + mBtnReturnOwnerList->setEnabled(TRUE); // Highlight this user's objects - clickShowCore(self, RT_LIST, &(self->mSelectedOwners)); + clickShowCore(this, RT_LIST, &(mSelectedOwners)); } } @@ -2164,7 +2186,7 @@ void LLPanelLandOptions::refreshSearch() LLViewerParcelMgr::isParcelModifiableByAgent( parcel, GP_LAND_CHANGE_IDENTITY) && region - && !(region->getRegionFlags() & REGION_FLAGS_BLOCK_PARCEL_SEARCH); + && !(region->getRegionFlag(REGION_FLAGS_BLOCK_PARCEL_SEARCH)); // There is a bug with this panel whereby the Show Directory bit can be // slammed off by the Region based on an override. Since this data is cached @@ -2361,7 +2383,7 @@ void LLPanelLandOptions::onClickPublishHelp(void*) bool can_change_identity = region && parcel ? LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_IDENTITY) && - ! (region->getRegionFlags() & REGION_FLAGS_BLOCK_PARCEL_SEARCH) : false; + !region->getRegionFlag(REGION_FLAGS_BLOCK_PARCEL_SEARCH) : false; if(! can_change_identity) { @@ -2442,7 +2464,11 @@ void LLPanelLandAccess::refresh() childSetLabelArg("GroupCheck", "[GROUP]", group_name ); // Allow list + if (mListAccess) { + // Clear the sort order so we don't re-sort on every add. + mListAccess->clearSortOrder(); + mListAccess->deleteAllItems(); S32 count = parcel->mAccessList.size(); childSetToolTipArg("AccessList", "[LISTED]", llformat("%d",count)); childSetToolTipArg("AccessList", "[MAX]", llformat("%d",PARCEL_MAX_ACCESS_LIST)); @@ -2478,13 +2504,17 @@ void LLPanelLandAccess::refresh() } suffix.append(" " + getString("remaining") + ")"); } - if (mListAccess) - mListAccess->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix); + mListAccess->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix); } + mListAccess->sortByName(TRUE); } // Ban List + if(mListBanned) { + // Clear the sort order so we don't re-sort on every add. + mListBanned->clearSortOrder(); + mListBanned->deleteAllItems(); S32 count = parcel->mBanList.size(); childSetToolTipArg("BannedList", "[LISTED]", llformat("%d",count)); @@ -2523,6 +2553,7 @@ void LLPanelLandAccess::refresh() } mListBanned->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix); } + mListBanned->sortByName(TRUE); } if(parcel->getRegionDenyAnonymousOverride()) @@ -2790,23 +2821,21 @@ void LLPanelLandAccess::onClickAddAccess(void* data) LLPanelLandAccess* panelp = (LLPanelLandAccess*)data; if (panelp) { - gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarCBAccess, data) ); + gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, panelp, _1))); } } -// static -void LLPanelLandAccess::callbackAvatarCBAccess(const std::vector& names, const std::vector& ids, void* userdata) +void LLPanelLandAccess::callbackAvatarCBAccess(const uuid_vec_t& ids) { - LLPanelLandAccess* panelp = (LLPanelLandAccess*)userdata; - if (!names.empty() && !ids.empty()) + if (!ids.empty()) { LLUUID id = ids[0]; - LLParcel* parcel = panelp->mParcel->getParcel(); + LLParcel* parcel = mParcel->getParcel(); if (parcel) { parcel->addToAccessList(id, 0); LLViewerParcelMgr::getInstance()->sendParcelAccessListUpdate(AL_ACCESS); - panelp->refresh(); + refresh(); } } } @@ -2838,22 +2867,20 @@ void LLPanelLandAccess::onClickRemoveAccess(void* data) void LLPanelLandAccess::onClickAddBanned(void* data) { LLPanelLandAccess* panelp = (LLPanelLandAccess*)data; - gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarCBBanned, data) ); + gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, panelp, _1))); } -// static -void LLPanelLandAccess::callbackAvatarCBBanned(const std::vector& names, const std::vector& ids, void* userdata) +void LLPanelLandAccess::callbackAvatarCBBanned(const uuid_vec_t& ids) { - LLPanelLandAccess* panelp = (LLPanelLandAccess*)userdata; - if (!names.empty() && !ids.empty()) + if (!ids.empty()) { LLUUID id = ids[0]; - LLParcel* parcel = panelp->mParcel->getParcel(); + LLParcel* parcel = mParcel->getParcel(); if (parcel) { parcel->addToBanList(id, 0); LLViewerParcelMgr::getInstance()->sendParcelAccessListUpdate(AL_BAN); - panelp->refresh(); + refresh(); } } } @@ -2927,7 +2954,7 @@ void LLPanelLandCovenant::refresh() LLTextBox* resellable_clause = getChild("resellable_clause"); if (resellable_clause) { - if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) + if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)) { resellable_clause->setText(getString("can_not_resell")); } @@ -2940,7 +2967,7 @@ void LLPanelLandCovenant::refresh() LLTextBox* changeable_clause = getChild("changeable_clause"); if (changeable_clause) { - if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) + if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES)) { changeable_clause->setText(getString("can_change")); } diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 19e8b5260..d7c0cfeef 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -274,7 +274,7 @@ public: static void onDoubleClickOwner(void*); - static void onCommitList(LLUICtrl* ctrl, void* data); + void onCommitList(); static void onLostFocus(LLFocusableElement* caller, void* user_data); static void onCommitClean(LLUICtrl* caller, void* user_data); static void processParcelObjectOwnersReply(LLMessageSystem *msg, void **); @@ -383,10 +383,10 @@ public: static void onCommitPublicAccess(LLUICtrl* ctrl, void *userdata); static void onCommitAny(LLUICtrl* ctrl, void *userdata); static void onClickAddAccess(void*); - static void callbackAvatarCBAccess(const std::vector& names, const std::vector& ids, void* userdata); + void callbackAvatarCBAccess(const uuid_vec_t& ids); static void onClickRemoveAccess(void*); static void onClickAddBanned(void*); - static void callbackAvatarCBBanned(const std::vector& names, const std::vector& ids, void* userdata); + void callbackAvatarCBBanned(const uuid_vec_t& ids); static void onClickRemoveBanned(void*); virtual BOOL postBuild(); diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index bd1186b15..832bf6b86 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -100,11 +100,12 @@ BOOL LLFloaterLandHoldings::postBuild() childSetAction("Teleport", onClickTeleport, this); childSetAction("Show on Map", onClickMap, this); - // Grant list - childSetDoubleClickCallback("grant list", onGrantList); - childSetUserData("grant list", this); + LLScrollListCtrl *grant_list = getChild("grant list"); - LLCtrlListInterface *list = childGetListInterface("grant list"); + // Grant list + grant_list->setDoubleClickCallback(boost::bind(&LLFloaterLandHoldings::onGrantList,this)); + + LLCtrlListInterface *list = grant_list->getListInterface(); if (!list) return TRUE; S32 count = gAgent.mGroups.count(); diff --git a/indra/newview/llfloatermessagelog.cpp b/indra/newview/llfloatermessagelog.cpp index ac1ecd99c..230a4b15a 100644 --- a/indra/newview/llfloatermessagelog.cpp +++ b/indra/newview/llfloatermessagelog.cpp @@ -636,18 +636,18 @@ void LLFloaterMessageLog::refreshNetList() { LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1); icon->setValue("icon_net_close_circuit.tga"); - icon->setClickCallback(onClickCloseCircuit, itemp); + icon->setClickCallback(boost::bind(&LLFloaterMessageLog::onClickCloseCircuit, itemp)); } else { LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1); icon->setValue("icon_net_close_circuit_gray.tga"); - icon->setClickCallback(NULL, NULL); + //icon->setClickCallback(NULL); } // Event queue isn't even supported yet... FIXME LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(2); icon->setValue("icon_net_close_eventpoll_gray.tga"); - icon->setClickCallback(NULL, NULL); + //icon->setClickCallback(NULL); } if(selected_id.notNull()) scrollp->selectByID(selected_id); if(scroll_pos < scrollp->getItemCount()) scrollp->setScrollPos(scroll_pos); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 89d34dea3..57219b41f 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -455,7 +455,7 @@ BOOL LLFloaterModelPreview::postBuild() std::string validate_url; if (gHippoGridManager->getCurrentGrid()->isSecondLife()) { - if (LLViewerLogin::getInstance()->isInProductionGrid()) + if (gHippoGridManager->getConnectedGrid()->isInProductionGrid()) { validate_url = "http://secondlife.com/my/account/mesh.php"; } @@ -896,7 +896,7 @@ BOOL LLFloaterModelPreview::handleScrollWheel(S32 x, S32 y, S32 clicks) } /*virtual*/ -void LLFloaterModelPreview::onOpen(const LLSD& key) +void LLFloaterModelPreview::onOpen() { requestAgentUploadPermissions(); } @@ -2487,7 +2487,7 @@ void LLModelLoader::loadTextures() if (!material.mDiffuseMapFilename.empty()) { material.mDiffuseMap = - LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW); + LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, TRUE, LLGLTexture::BOOST_PREVIEW); material.mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE); material.mDiffuseMap->forceToSaveRawImage(0, F32_MAX); mNumOfFetchingTextures++; diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index e8e21e77f..90f41c698 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -170,7 +170,7 @@ public: BOOL handleHover(S32 x, S32 y, MASK mask); BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onOpen(); static void onMouseCaptureLostModelPreview(LLMouseHandler*); static void setUploadAmount(S32 amount) { sUploadAmount = amount; } diff --git a/indra/newview/llfloatermute.cpp b/indra/newview/llfloatermute.cpp index 8e071dcde..624c244a4 100644 --- a/indra/newview/llfloatermute.cpp +++ b/indra/newview/llfloatermute.cpp @@ -43,18 +43,21 @@ // project include #include "llagent.h" +#include "llavatarnamecache.h" #include "llfloateravatarpicker.h" #include "llbutton.h" #include "lllineeditor.h" #include "llmutelist.h" +#include "llnamelistctrl.h" #include "llresizehandle.h" -#include "llscrolllistctrl.h" #include "lltextbox.h" #include "llviewertexteditor.h" #include "llviewerwindow.h" #include "lluictrlfactory.h" #include "llfocusmgr.h" +#include + // // Constants // @@ -208,7 +211,12 @@ BOOL LLFloaterMute::postBuild() childSetAction("Mute object by name...", onClickMuteByName, this); childSetAction("Unmute", onClickRemove, this); - mMuteList = getChild("mutes"); + mAvatarIcon = LLUI::getUIImage("icon_avatar_offline.tga"); + mObjectIcon = LLUI::getUIImage("inv_item_object.tga"); + mGroupIcon = LLUI::getUIImage("icon_group.tga"); + mNameIcon = LLUI::getUIImage("icon_name.tga"); + + mMuteList = getChild("mutes"); mMuteList->setCommitOnSelectionChange(TRUE); LLMuteList::getInstance()->addObserver(this); @@ -230,16 +238,63 @@ LLFloaterMute::~LLFloaterMute() //----------------------------------------------------------------------------- void LLFloaterMute::refreshMuteList() { + uuid_vec_t selected = mMuteList->getSelectedIDs(); + S32 scrollpos = mMuteList->getScrollPos(); + mMuteList->deleteAllItems(); + mMuteDict.clear(); std::vector mutes = LLMuteList::getInstance()->getMutes(); std::vector::iterator it; + U32 count = 0; for (it = mutes.begin(); it != mutes.end(); ++it) { - std::string display_name = it->getDisplayName(); - mMuteList->addStringUUIDItem(display_name, it->mID); - } + std::string display_name = it->mName; + LLSD element; + LLUUID entry_id; + if(it->mType == LLMute::GROUP || it->mType == LLMute::AGENT) + entry_id = it->mID; + else + entry_id.generate(boost::lexical_cast( count++ )); + mMuteDict.insert(std::make_pair(entry_id,*it)); + element["id"] = entry_id; + element["name"] = display_name; + LLSD& name_column = element["columns"][1]; + name_column["column"] = "name"; + name_column["type"] = "text"; + name_column["value"] = ""; + + LLSD& icon_column = element["columns"][0]; + icon_column["column"] = "icon"; + icon_column["type"] = "icon"; + + switch(it->mType) + { + case LLMute::GROUP: + icon_column["value"] = mGroupIcon->getName(); + element["target"] = LLNameListCtrl::GROUP; + break; + case LLMute::AGENT: + icon_column["value"] = mAvatarIcon->getName(); + element["target"] = LLNameListCtrl::INDIVIDUAL; + break; + case LLMute::OBJECT: + icon_column["value"] = mObjectIcon->getName(); + element["target"] = LLNameListCtrl::SPECIAL; + break; + case LLMute::BY_NAME: + default: + icon_column["value"] = mNameIcon->getName(); + element["target"] = LLNameListCtrl::SPECIAL; + + break; + } + mMuteList->addNameItemRow(element); + } + mMuteList->updateSort(); + mMuteList->selectMultiple(selected); + mMuteList->setScrollPos(scrollpos); updateButtons(); } @@ -281,17 +336,22 @@ void LLFloaterMute::onClickRemove(void *data) { LLFloaterMute* floater = (LLFloaterMute *)data; - std::string name = floater->mMuteList->getSelectedItemLabel(); - LLUUID id = floater->mMuteList->getStringUUIDSelectedItem(); - LLMute mute(id); - mute.setFromDisplayName(name); - // now mute.mName has the suffix trimmed off - S32 last_selected = floater->mMuteList->getFirstSelectedIndex(); - if (LLMuteList::getInstance()->remove(mute)) + bool removed = false; + const std::vector items = floater->mMuteList->getAllSelected(); + for(std::vector::const_iterator it = items.begin(); it != items.end(); ++it) + { + std::map::iterator mute_it = floater->mMuteDict.find((*it)->getUUID()); + if(mute_it != floater->mMuteDict.end() && LLMuteList::getInstance()->remove(mute_it->second)) + { + floater->mMuteDict.erase(mute_it); + removed = true; + } + } + + if (removed) { // Above removals may rebuild this dialog. - if (last_selected == floater->mMuteList->getItemCount()) { // we were on the last item, so select the last item again @@ -302,8 +362,12 @@ void LLFloaterMute::onClickRemove(void *data) // else select the item after the last item previously selected floater->mMuteList->selectNthItem(last_selected); } + floater->mMuteList->setNeedsSort(); + floater->mMuteList->updateSort(); + floater->updateButtons(); } - floater->updateButtons(); + + } //----------------------------------------------------------------------------- @@ -314,22 +378,20 @@ void LLFloaterMute::onClickPick(void *data) LLFloaterMute* floaterp = (LLFloaterMute*)data; const BOOL allow_multiple = FALSE; const BOOL close_on_select = TRUE; - LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(onPickUser, data, allow_multiple, close_on_select); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterMute::onPickUser, floaterp, _1, _2), allow_multiple, close_on_select); floaterp->addDependentFloater(picker); } //----------------------------------------------------------------------------- // onPickUser() //----------------------------------------------------------------------------- -void LLFloaterMute::onPickUser(const std::vector& names, const std::vector& ids, void* user_data) +void LLFloaterMute::onPickUser(const uuid_vec_t& ids, const std::vector& names) { - LLFloaterMute* floaterp = (LLFloaterMute*)user_data; - if (!floaterp) return; if (names.empty() || ids.empty()) return; - LLMute mute(ids[0], names[0], LLMute::AGENT); + LLMute mute(ids[0], names[0].getLegacyName(), LLMute::AGENT); LLMuteList::getInstance()->add(mute); - floaterp->updateButtons(); + updateButtons(); } diff --git a/indra/newview/llfloatermute.h b/indra/newview/llfloatermute.h index 93f1bb2c1..8abb6afdf 100644 --- a/indra/newview/llfloatermute.h +++ b/indra/newview/llfloatermute.h @@ -37,11 +37,13 @@ #include "llmutelist.h" #include +class LLAvatarName; class LLButton; class LLLineEditor; class LLMessageSystem; class LLUUID; -class LLScrollListCtrl; +class LLNameListCtrl; +class LLMute; class LLFloaterMute : public LLFloater, public LLMuteListObserver, public LLFloaterSingleton @@ -68,12 +70,19 @@ private: static void onClickRemove(void *data); static void onClickPick(void *data); static void onSelectName(LLUICtrl* caller, void *data); - static void onPickUser(const std::vector& names, const std::vector& ids, void* user_data); + void onPickUser(const uuid_vec_t& ids, const std::vector& names); static void onClickMuteByName(void*); static void callbackMuteByName(const std::string& text, void*); private: - LLScrollListCtrl* mMuteList; + LLNameListCtrl* mMuteList; + + LLPointer mAvatarIcon; //icon_avatar_offline.tga + LLPointer mObjectIcon; //inv_item_object.tga + LLPointer mGroupIcon; //icon_group.tga + LLPointer mNameIcon; //icon_name.tga + + std::map mMuteDict; //Easiest way to associate listitems with LLMute instances without hacking in, say, a hidden column. }; diff --git a/indra/newview/llfloaternewim.cpp b/indra/newview/llfloaternewim.cpp index de1a306da..3acca6e38 100644 --- a/indra/newview/llfloaternewim.cpp +++ b/indra/newview/llfloaternewim.cpp @@ -60,8 +60,7 @@ BOOL LLFloaterNewIM::postBuild() mSelectionList = getChild("user_list"); if (mSelectionList) { - mSelectionList->setDoubleClickCallback(&LLFloaterNewIM::onStart); - mSelectionList->setCallbackUserData(this); + mSelectionList->setDoubleClickCallback(boost::bind(&LLFloaterNewIM::onStart,this)); } else { @@ -93,7 +92,7 @@ void LLFloaterNewIM::addSpecial(const LLUUID& uuid, const std::string& name, LLSD row; row["id"] = uuid; row["name"] = name; - row["target"] = "SPECIAL"; + row["target"] = LLNameListCtrl::SPECIAL; row["columns"][0]["value"] = name; row["columns"][0]["width"] = COL_1_WIDTH; row["columns"][0]["font"] = "SANSSERIF"; @@ -114,7 +113,7 @@ void LLFloaterNewIM::addGroup(const LLUUID& uuid, void* data, BOOL bold, BOOL on { LLSD row; row["id"] = uuid; - row["target"] = "GROUP"; + row["target"] = LLNameListCtrl::GROUP; row["columns"][0]["value"] = ""; // name will be looked up row["columns"][0]["width"] = COL_1_WIDTH; row["columns"][0]["font"] = "SANSSERIF"; @@ -133,12 +132,10 @@ void LLFloaterNewIM::addGroup(const LLUUID& uuid, void* data, BOOL bold, BOOL on void LLFloaterNewIM::addAgent(const LLUUID& uuid, void* data, BOOL online) { - std::string fullname; - gCacheName->getFullName(uuid, fullname); - LLSD row; row["id"] = uuid; - row["columns"][0]["value"] = fullname; + row["target"] = LLNameListCtrl::INDIVIDUAL; + row["columns"][0]["value"] = ""; row["columns"][0]["width"] = COL_1_WIDTH; row["columns"][0]["font"] = "SANSSERIF"; row["columns"][0]["font-style"] = online ? "BOLD" : "NORMAL"; diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index e6250063f..5d6b771d5 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -77,12 +77,10 @@ BOOL LLNotificationChannelPanel::postBuild() mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false)); LLScrollListCtrl* scroll = getChild("notifications_list"); - scroll->setDoubleClickCallback(onClickNotification); - scroll->setCallbackUserData(this); + scroll->setDoubleClickCallback(boost::bind(&LLNotificationChannelPanel::onClickNotification,this)); scroll = getChild("notification_rejects_list"); - scroll->setDoubleClickCallback(onClickNotificationReject); - scroll->setCallbackUserData(this); + scroll->setDoubleClickCallback(boost::bind(&LLNotificationChannelPanel::onClickNotificationReject,this)); return TRUE; } diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index 6ff9d6695..16321763a 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -67,6 +67,7 @@ #include "llassetuploadresponders.h" #include "hippogridmanager.h" +#include "llfloatersnapshot.h" #if LL_MSVC #pragma warning( disable : 4265 ) // "class has virtual functions, but destructor is not virtual" @@ -84,13 +85,14 @@ LLFloaterPostcard::instance_list_t LLFloaterPostcard::sInstances; /// Class LLFloaterPostcard ///---------------------------------------------------------------------------- -LLFloaterPostcard::LLFloaterPostcard(LLImageJPEG* jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global) +LLFloaterPostcard::LLFloaterPostcard(LLImageJPEG* jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global, int index) : LLFloater(std::string("Postcard Floater")), mJPEGImage(jpeg), mViewerImage(img), mImageScale(img_scale), mPosTakenGlobal(pos_taken_global), - mHasFirstMsgFocus(false) + mHasFirstMsgFocus(false), + mSnapshotIndex(index) { init(); } @@ -146,11 +148,11 @@ BOOL LLFloaterPostcard::postBuild() // static -LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global) +LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global, int index) { // Take the images from the caller // It's now our job to clean them up - LLFloaterPostcard *instance = new LLFloaterPostcard(jpeg, img, image_scale, pos_taken_global); + LLFloaterPostcard *instance = new LLFloaterPostcard(jpeg, img, image_scale, pos_taken_global, index); LLUICtrlFactory::getInstance()->buildFloater(instance, "floater_postcard.xml"); @@ -221,26 +223,47 @@ void LLFloaterPostcard::onClickCancel(void* data) if (data) { LLFloaterPostcard *self = (LLFloaterPostcard *)data; - self->close(false); } } +void LLFloaterPostcard::onClose(bool app_quitting) +{ + LLFloaterSnapshot::savePostcardDone(false, mSnapshotIndex); + destroy(); +} + class LLSendPostcardResponder : public LLAssetUploadResponder { +private: + int mSnapshotIndex; + public: LLSendPostcardResponder(const LLSD &post_data, const LLUUID& vfile_id, - LLAssetType::EType asset_type): - LLAssetUploadResponder(post_data, vfile_id, asset_type) + LLAssetType::EType asset_type, + int index) : + LLAssetUploadResponder(post_data, vfile_id, asset_type), + mSnapshotIndex(index) { } // *TODO define custom uploadFailed here so it's not such a generic message - void uploadComplete(const LLSD& content) + /*virtual*/ void uploadComplete(const LLSD& content) { // we don't care about what the server returns from this post, just clean up the UI - LLUploadDialog::modalUploadFinished(); + LLFloaterSnapshot::savePostcardDone(true, mSnapshotIndex); } + /*virtual*/ void uploadFailure(const LLSD& content) + { + LLAssetUploadResponder::uploadFailure(content); + LLFloaterSnapshot::savePostcardDone(false, mSnapshotIndex); + } + /*virtual*/ void error(U32 statusNum, const std::string& reason) + { + LLAssetUploadResponder::error(statusNum, reason); + LLFloaterSnapshot::savePostcardDone(false, mSnapshotIndex); + } + /*virtual*/ char const* getName(void) const { return "LLSendPostcardResponder"; } }; // static @@ -290,8 +313,8 @@ void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data, { LLFloaterPostcard *self = (LLFloaterPostcard *)user_data; - LLUploadDialog::modalUploadFinished(); - + LLFloaterSnapshot::savePostcardDone(!result, self->mSnapshotIndex); + if (result) { LLSD args; @@ -320,7 +343,7 @@ void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data, gAgent.sendReliableMessage(); } - self->close(); + self->destroy(); } // static @@ -384,6 +407,7 @@ void LLFloaterPostcard::sendPostcard() LLVFile::writeFile(mJPEGImage->getData(), mJPEGImage->getDataSize(), gVFS, mAssetID, LLAssetType::AT_IMAGE_JPEG); // upload the image + LLFloaterSnapshot::saveStart(mSnapshotIndex); std::string url = gAgent.getRegion()->getCapability("SendPostcard"); if(!url.empty()) { @@ -396,7 +420,7 @@ void LLFloaterPostcard::sendPostcard() body["name"] = childGetValue("name_form").asString(); body["subject"] = childGetValue("subject_form").asString(); body["msg"] = childGetValue("msg_form").asString(); - LLHTTPClient::post(url, body, new LLSendPostcardResponder(body, mAssetID, LLAssetType::AT_IMAGE_JPEG)); + LLHTTPClient::post(url, body, new LLSendPostcardResponder(body, mAssetID, LLAssetType::AT_IMAGE_JPEG, mSnapshotIndex)); } else { @@ -410,11 +434,4 @@ void LLFloaterPostcard::sendPostcard() // don't destroy the window until the upload is done // this way we keep the information in the form setVisible(FALSE); - - // also remove any dependency on another floater - // so that we can be sure to outlive it while we - // need to. - LLFloater* dependee = getDependee(); - if (dependee) - dependee->removeDependentFloater(this); } diff --git a/indra/newview/llfloaterpostcard.h b/indra/newview/llfloaterpostcard.h index e2ad154ef..e40479c17 100644 --- a/indra/newview/llfloaterpostcard.h +++ b/indra/newview/llfloaterpostcard.h @@ -50,14 +50,15 @@ class LLFloaterPostcard : public LLFloater { public: - LLFloaterPostcard(LLImageJPEG* jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global); - virtual ~LLFloaterPostcard(); + LLFloaterPostcard(LLImageJPEG* jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global, int index); + /*virtual*/ ~LLFloaterPostcard(); - virtual void init(); - virtual BOOL postBuild(); - virtual void draw(); + /*virtual*/ void init(); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + /*virtual*/ void onClose(bool app_quitting); - static LLFloaterPostcard* showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global); + static LLFloaterPostcard* showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global, int index); static void onClickCancel(void* data); static void onClickSend(void* data); @@ -82,6 +83,7 @@ protected: LLVector2 mImageScale; LLVector3d mPosTakenGlobal; bool mHasFirstMsgFocus; + int mSnapshotIndex; typedef std::set instance_list_t; static instance_list_t sInstances; diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 747a3ffb5..512a9979e 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -40,7 +40,6 @@ #define LL_LLFLOATERPREFERENCE_H #include "llfloater.h" -#include "lltabcontainervertical.h" class HippoPanelGrids; class LLPanelGeneral; diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index 3e279936f..0c8e7914e 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -537,11 +537,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) if (!is_link && is_obj_modify && can_agent_manipulate) { childSetEnabled("GroupLabel", true); - childSetEnabled("CheckGroupCopy",owner_mask & PERM_TRANSFER); + childSetEnabled("CheckGroupCopy", (owner_mask & (PERM_TRANSFER|PERM_COPY)) == (PERM_TRANSFER|PERM_COPY)); childSetEnabled("CheckGroupMod", owner_mask & PERM_MODIFY); childSetEnabled("CheckGroupMove", true); childSetEnabled("EveryoneLabel", true); - childSetEnabled("CheckEveryoneCopy",(owner_mask & PERM_COPY) && (owner_mask & PERM_TRANSFER)); + childSetEnabled("CheckEveryoneCopy", (owner_mask & (PERM_TRANSFER|PERM_COPY)) == (PERM_TRANSFER|PERM_COPY)); childSetEnabled("CheckEveryoneMove",true); } else @@ -551,7 +551,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) childSetEnabled("CheckGroupMod", false); childSetEnabled("CheckGroupMove", false); childSetEnabled("EveryoneLabel", false); - childSetEnabled("CheckEveryoneCopy",FALSE); + childSetEnabled("CheckEveryoneCopy",false); childSetEnabled("CheckEveryoneMove",false); } diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp index a17eeab1e..0418dc180 100644 --- a/indra/newview/llfloaterregiondebugconsole.cpp +++ b/indra/newview/llfloaterregiondebugconsole.cpp @@ -80,12 +80,9 @@ namespace class AsyncConsoleResponder : public LLHTTPClient::ResponderIgnoreBody { public: - /* virtual */ - void error(U32 status, const std::string& reason) - { - sConsoleReplySignal(UNABLE_TO_SEND_COMMAND); - } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return asyncConsoleResponder_timeout; } + /*virtual*/ void error(U32 status, const std::string& reason) { sConsoleReplySignal(UNABLE_TO_SEND_COMMAND); } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return asyncConsoleResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "AsyncConsoleResponder"; } }; class ConsoleResponder : public LLHTTPClient::ResponderWithResult @@ -95,8 +92,7 @@ namespace { } - /*virtual*/ - void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { if (mOutput) { @@ -106,8 +102,7 @@ namespace } } - /*virtual*/ - void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { if (mOutput) { @@ -116,7 +111,8 @@ namespace } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return consoleResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return consoleResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "ConsoleResponder"; } LLTextEditor * mOutput; }; @@ -193,11 +189,6 @@ BOOL LLFloaterRegionDebugConsole::postBuild() void LLFloaterRegionDebugConsole::onClose(bool app_quitting) { LLFloater::onClose(app_quitting); - - if (!app_quitting) - { - delete this; - } } void LLFloaterRegionDebugConsole::onInput(LLUICtrl* ctrl, const LLSD& param) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 0a6b234f0..13e128f05 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -258,7 +258,8 @@ void LLFloaterRegionInfo::requestRegionInfo() void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) { static LLDispatcher dispatch; - if(!findInstance()) + LLFloaterRegionInfo* floater = findInstance(); + if(!floater) { return; } @@ -268,7 +269,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) LLPanelEstateInfo::initDispatch(dispatch); } - LLTabContainer* tab = findInstance()->getChild("region_panels"); + LLTabContainer* tab = floater->getChild("region_panels"); LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); // unpack the message @@ -285,8 +286,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) //dispatch the message dispatch.dispatch(request, invoice, strings); - LLViewerRegion* region = gAgent.getRegion(); - panel->updateControls(region); + panel->updateControls(gAgent.getRegion()); } @@ -296,12 +296,18 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) LLPanel* panel; llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl; - if(!findInstance()) + LLFloaterRegionInfo* floater = findInstance(); + if(!floater) { return; } + // We need to re-request environment setting here, + // otherwise after we apply (send) updated region settings we won't get them back, + // so our environment won't be updated. + // This is also the way to know about externally changed region environment. + LLEnvManagerNew::instance().requestRegionSettings(); - LLTabContainer* tab = findInstance()->getChild("region_panels"); + LLTabContainer* tab = floater->getChild("region_panels"); LLViewerRegion* region = gAgent.getRegion(); BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); @@ -389,7 +395,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) panel->childSetEnabled("sun_hour_slider", allow_modify && !use_estate_sun); panel->setCtrlsEnabled(allow_modify); - getInstance()->refreshFromRegion( gAgent.getRegion() ); + floater->refreshFromRegion( gAgent.getRegion() ); } // static @@ -414,6 +420,11 @@ LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) { + if (!region) + { + return; + } + // call refresh from region on all panels std::for_each( mInfoPanels.begin(), @@ -632,18 +643,18 @@ void LLPanelRegionGeneralInfo::onClickKick(void* userdata) // this depends on the grandparent view being a floater // in order to set up floater dependency LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); - LLFloater* child_floater = LLFloaterAvatarPicker::show(onKickCommit, userdata, FALSE, TRUE); - parent_floater->addDependentFloater(child_floater); + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, panelp, _1), FALSE, TRUE); + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } } -// static -void LLPanelRegionGeneralInfo::onKickCommit(const std::vector& names, const std::vector& ids, void* userdata) +void LLPanelRegionGeneralInfo::onKickCommit(const uuid_vec_t& ids) { - if (names.empty() || ids.empty()) return; + if (ids.empty()) return; if(ids[0].notNull()) { - LLPanelRegionGeneralInfo* self = (LLPanelRegionGeneralInfo*)userdata; - if(!self) return; strings_t strings; // [0] = our agent id // [1] = target agent id @@ -655,7 +666,7 @@ void LLPanelRegionGeneralInfo::onKickCommit(const std::vector& name strings.push_back(strings_t::value_type(buffer)); LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings); + sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings); } } @@ -886,17 +897,15 @@ BOOL LLPanelRegionDebugInfo::sendUpdate() void LLPanelRegionDebugInfo::onClickChooseAvatar(void* data) { - LLFloaterAvatarPicker::show(callbackAvatarID, data, FALSE, TRUE); + LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, (LLPanelRegionDebugInfo*)data, _1, _2), FALSE, TRUE); } -// static -void LLPanelRegionDebugInfo::callbackAvatarID(const std::vector& names, const std::vector& ids, void* data) +void LLPanelRegionDebugInfo::callbackAvatarID(const uuid_vec_t& ids, const std::vector& names) { - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) data; if (ids.empty() || names.empty()) return; - self->mTargetAvatar = ids[0]; - self->childSetValue("target_avatar_name", LLSD(names[0])); - self->refreshFromRegion( gAgent.getRegion() ); + mTargetAvatar = ids[0]; + childSetValue("target_avatar_name", LLSD(names[0].getCompleteName())); + refreshFromRegion( gAgent.getRegion() ); } // static @@ -1615,35 +1624,35 @@ void LLPanelEstateInfo::onClickKickUser(void *user_data) // this depends on the grandparent view being a floater // in order to set up floater dependency LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); - LLFloater* child_floater = LLFloaterAvatarPicker::show(LLPanelEstateInfo::onKickUserCommit, user_data, FALSE, TRUE); + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, panelp, _1, _2), FALSE, TRUE); + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } parent_floater->addDependentFloater(child_floater); } -void LLPanelEstateInfo::onKickUserCommit(const std::vector& names, const std::vector& ids, void* userdata) +void LLPanelEstateInfo::onKickUserCommit(const uuid_vec_t& ids, const std::vector& names) { if (names.empty() || ids.empty()) return; //check to make sure there is one valid user and id - if( (ids[0].isNull()) || - (names[0].length() == 0) ) + if( ids[0].isNull() ) { return; } - LLPanelEstateInfo* self = (LLPanelEstateInfo*)userdata; - if(!self) return; - //keep track of what user they want to kick and other misc info LLKickFromEstateInfo *kick_info = new LLKickFromEstateInfo(); - kick_info->mEstatePanelp = self; + kick_info->mEstatePanelp = this; kick_info->mAgentID = ids[0]; //Bring up a confirmation dialog LLSD args; - args["EVIL_USER"] = names[0]; + args["EVIL_USER"] = names[0].getCompleteName(); LLSD payload; payload["agent_id"] = ids[0]; - LLNotificationsUtil::add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, self, _1, _2)); + LLNotificationsUtil::add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, this, _1, _2)); } @@ -1808,14 +1817,13 @@ bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& res LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); // avatar picker yes multi-select, yes close-on-select - LLFloaterAvatarPicker::show(accessAddCore3, (void*)change_info, TRUE, TRUE); + LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, change_info), TRUE, TRUE); return false; } // static -void LLPanelEstateInfo::accessAddCore3(const std::vector& names, const std::vector& ids, void* data) +void LLPanelEstateInfo::accessAddCore3(const uuid_vec_t& ids, LLEstateAccessChangeInfo* change_info) { - LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data; if (!change_info) return; if (ids.empty()) { @@ -2063,7 +2071,6 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) BOOL owner = (region && (region->getOwner() == gAgent.getID())); BOOL manager = (region && region->isEstateManager()); setCtrlsEnabled(god || owner || manager); - childDisable("apply_btn"); childSetEnabled("add_allowed_avatar_btn", god || owner || manager); childSetEnabled("remove_allowed_avatar_btn", god || owner || manager); @@ -2313,26 +2320,34 @@ void LLPanelEstateInfo::getEstateOwner() class LLEstateChangeInfoResponder : public LLHTTPClient::ResponderWithResult { public: - LLEstateChangeInfoResponder(void* userdata) : mpPanel((LLPanelEstateInfo*)userdata) {}; + LLEstateChangeInfoResponder(LLPanelEstateInfo* panel) + { + mpPanel = panel->getHandle(); + } // if we get a normal response, handle it here - virtual void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { + LL_INFOS("Windlight") << "Successfully committed estate info" << llendl; + // refresh the panel from the database - mpPanel->refresh(); + LLPanelEstateInfo* panel = dynamic_cast(mpPanel.get()); + if (panel) + panel->refresh(); } // if we get an error response - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { llinfos << "LLEstateChangeInfoResponder::error " << status << ": " << reason << llendl; } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return estateChangeInfoResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return estateChangeInfoResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLEstateChangeInfoResponder"; } private: - LLPanelEstateInfo* mpPanel; + LLHandle mpPanel; }; // tries to send estate info using a cap; returns true if it succeeded @@ -2370,7 +2385,7 @@ bool LLPanelEstateInfo::commitEstateInfoCaps() body["owner_abuse_email"] = childGetValue("abuse_email_address").asString(); // we use a responder so that we can re-get the data after committing to the database - LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder((void*)this)); + LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder(this)); return true; } @@ -2702,7 +2717,7 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region) LLTextBox* resellable_clause = getChild("resellable_clause"); if (resellable_clause) { - if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) + if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)) { resellable_clause->setText(getString("can_not_resell")); } @@ -2715,7 +2730,7 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region) LLTextBox* changeable_clause = getChild("changeable_clause"); if (changeable_clause) { - if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) + if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES)) { changeable_clause->setText(getString("can_change")); } @@ -3200,7 +3215,8 @@ bool LLDispatchSetEstateAccess::operator()( if (allowed_agent_name_list) { - //allowed_agent_name_list->deleteAllItems(); + // Don't sort these as we add them, sort them when we are done. + allowed_agent_name_list->clearSortOrder(); for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) { LLUUID id; @@ -3208,7 +3224,7 @@ bool LLDispatchSetEstateAccess::operator()( allowed_agent_name_list->addNameItem(id); } panel->childSetEnabled("remove_allowed_avatar_btn", allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_agent_name_list->sortByColumnIndex(0, TRUE); + allowed_agent_name_list->sortByName(TRUE); } } @@ -3225,6 +3241,8 @@ bool LLDispatchSetEstateAccess::operator()( if (allowed_group_name_list) { + // Don't sort these as we add them, sort them when we are done. + allowed_group_name_list->clearSortOrder(); allowed_group_name_list->deleteAllItems(); for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) { @@ -3233,7 +3251,7 @@ bool LLDispatchSetEstateAccess::operator()( allowed_group_name_list->addGroupNameItem(id); } panel->childSetEnabled("remove_allowed_group_btn", allowed_group_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_group_name_list->sortByColumnIndex(0, TRUE); + allowed_group_name_list->sortByName(TRUE); } } @@ -3257,7 +3275,9 @@ bool LLDispatchSetEstateAccess::operator()( if (banned_agent_name_list) { - //banned_agent_name_list->deleteAllItems(); + // Don't sort these as we add them, sort them when we are done. + banned_agent_name_list->clearSortOrder(); + for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) { LLUUID id; @@ -3265,7 +3285,7 @@ bool LLDispatchSetEstateAccess::operator()( banned_agent_name_list->addNameItem(id); } panel->childSetEnabled("remove_banned_avatar_btn", banned_agent_name_list->getFirstSelected() ? TRUE : FALSE); - banned_agent_name_list->sortByColumnIndex(0, TRUE); + banned_agent_name_list->sortByName(TRUE); } } @@ -3280,6 +3300,9 @@ bool LLDispatchSetEstateAccess::operator()( panel->getChild("estate_manager_name_list"); if (estate_manager_name_list) { + // Don't sort these as we add them, sort them when we are done. + estate_manager_name_list->clearSortOrder(); + estate_manager_name_list->deleteAllItems(); // Clear existing entries // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't @@ -3292,7 +3315,7 @@ bool LLDispatchSetEstateAccess::operator()( estate_manager_name_list->addNameItem(id); } panel->childSetEnabled("remove_estate_manager_btn", estate_manager_name_list->getFirstSelected() ? TRUE : FALSE); - estate_manager_name_list->sortByColumnIndex(0, TRUE); + estate_manager_name_list->sortByName(TRUE); } } diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index c5ec3b7d6..8a3d77075 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -38,6 +38,8 @@ #include "llfloater.h" #include "llpanel.h" +class LLAvatarName; +struct LLEstateAccessChangeInfo; class LLLineEditor; class LLMessageSystem; class LLPanelRegionInfo; @@ -164,7 +166,7 @@ protected: virtual BOOL sendUpdate(); static void onClickKick(void* userdata); - static void onKickCommit(const std::vector& names, const std::vector& ids, void* userdata); + void onKickCommit(const uuid_vec_t& ids); static void onClickKickAll(void* userdata); bool onKickAllCommit(const LLSD& notification, const LLSD& response); static void onClickMessage(void* userdata); @@ -189,7 +191,7 @@ protected: virtual BOOL sendUpdate(); static void onClickChooseAvatar(void*); - static void callbackAvatarID(const std::vector& names, const std::vector& ids, void* data); + void callbackAvatarID(const uuid_vec_t& ids, const std::vector& names); static void onClickReturn(void *); bool callbackReturn(const LLSD& notification, const LLSD& response); static void onClickTopColliders(void*); @@ -282,7 +284,7 @@ public: // Core methods for all above add/remove button clicks static void accessAddCore(U32 operation_flag, const std::string& dialog_name); static bool accessAddCore2(const LLSD& notification, const LLSD& response); - static void accessAddCore3(const std::vector& names, const std::vector& ids, void* data); + static void accessAddCore3(const uuid_vec_t& ids, LLEstateAccessChangeInfo* change_info); static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name); static bool accessRemoveCore2(const LLSD& notification, const LLSD& response); @@ -294,7 +296,7 @@ public: // Send the actual EstateOwnerRequest "estateaccessdelta" message static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id); - static void onKickUserCommit(const std::vector& names, const std::vector& ids, void* userdata); + void onKickUserCommit(const uuid_vec_t& ids, const std::vector& names); static void onClickMessageEstate(void* data); bool onMessageCommit(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 9952eadd3..7c49e5184 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -378,24 +378,21 @@ void LLFloaterReporter::onClickSelectAbuser(void *userdata) { LLFloaterReporter *self = (LLFloaterReporter *)userdata; - gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, userdata, FALSE, TRUE )); + gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, self, _1, _2), FALSE, TRUE )); } -// static -void LLFloaterReporter::callbackAvatarID(const std::vector& names, const std::vector& ids, void* data) +void LLFloaterReporter::callbackAvatarID(const uuid_vec_t& ids, const std::vector& names) { - LLFloaterReporter* self = (LLFloaterReporter*) data; - if (ids.empty() || names.empty()) return; // this should never be called in a bug report but here for safety. - if ( self->mReportType != BUG_REPORT ) + if ( mReportType != BUG_REPORT ) { - self->childSetText("abuser_name_edit", names[0] ); + childSetText("abuser_name_edit", names[0].getCompleteName() ); - self->mAbuserID = ids[0]; + mAbuserID = ids[0]; - self->refresh(); + refresh(); }; } @@ -846,7 +843,7 @@ public: LLUserReportScreenshotResponder(const LLSD & post_data, const LLUUID & vfile_id, LLAssetType::EType asset_type): - LLAssetUploadResponder(post_data, vfile_id, asset_type) + LLAssetUploadResponder(post_data, vfile_id, asset_type) { } void uploadFailed(const LLSD& content) @@ -859,6 +856,8 @@ public: // we don't care about what the server returns from this post, just clean up the UI LLUploadDialog::modalUploadFinished(); } + + /*virtual*/ char const* getName(void) const { return "LLUserReportScreenshotResponder"; } }; class LLUserReportResponder : public LLHTTPClient::ResponderWithResult @@ -866,17 +865,18 @@ class LLUserReportResponder : public LLHTTPClient::ResponderWithResult public: LLUserReportResponder() { } - void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { // *TODO do some user messaging here LLUploadDialog::modalUploadFinished(); } - void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { // we don't care about what the server returns LLUploadDialog::modalUploadFinished(); } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return userReportResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return userReportResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLUserReportResponder"; } }; void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url, const LLSD& report) @@ -901,7 +901,8 @@ void LLFloaterReporter::takeScreenshot() const S32 IMAGE_HEIGHT = 768; LLPointer raw = new LLImageRaw; - if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE, TRUE, FALSE)) + // Warning: This crops left and right in case of wide-screen monitor: + if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, (F32)IMAGE_WIDTH / IMAGE_HEIGHT, TRUE, FALSE)) { llwarns << "Unable to take screenshot" << llendl; return; @@ -941,7 +942,7 @@ void LLFloaterReporter::takeScreenshot() // store in the image list so it doesn't try to fetch from the server LLPointer image_in_list = - LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::FETCHED_TEXTURE); + LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::FETCHED_TEXTURE); image_in_list->createGLTexture(0, raw, 0, TRUE, LLViewerTexture::OTHER); // the texture picker then uses that texture diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index 5f53142e4..e4d13e906 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -38,6 +38,7 @@ #include "lluuid.h" #include "v3math.h" +class LLAvatarName; class LLMessageSystem; class LLViewerTexture; class LLInventoryItem; @@ -126,7 +127,7 @@ private: void setPosBox(const LLVector3d &pos); void enableControls(BOOL own_avatar); void getObjectInfo(const LLUUID& object_id); - static void callbackAvatarID(const std::vector& names, const std::vector& ids, void* data); + void callbackAvatarID(const uuid_vec_t& ids, const std::vector& names); private: EReportType mReportType; diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp index 2c50046cc..df9ff37eb 100644 --- a/indra/newview/llfloaterscriptdebug.cpp +++ b/indra/newview/llfloaterscriptdebug.cpp @@ -129,7 +129,7 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std: if (objectp) { - objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", TRUE, LLViewerTexture::BOOST_UI)); + objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", TRUE, LLGLTexture::BOOST_UI)); floater_label = llformat("%s(%.2f, %.2f)", user_name.c_str(), objectp->getPositionRegion().mV[VX], objectp->getPositionRegion().mV[VY]); } else diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index dfb82dada..1b50f3ead 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -33,6 +33,7 @@ #include "llfloatersellland.h" +#include "llavatarnamecache.h" #include "llfloateravatarpicker.h" #include "llfloater.h" #include "llfloaterland.h" @@ -88,7 +89,7 @@ private: static void doShowObjects(void *userdata); static bool callbackHighlightTransferable(const LLSD& notification, const LLSD& response); - static void callbackAvatarPick(const std::vector& names, const std::vector& ids, void* data); + void callbackAvatarPick(const uuid_vec_t& ids, const std::vector& names); public: virtual BOOL postBuild(); @@ -413,25 +414,23 @@ void LLFloaterSellLandUI::doSelectAgent(void *userdata) { LLFloaterSellLandUI* floaterp = (LLFloaterSellLandUI*)userdata; // grandparent is a floater, in order to set up dependency - floaterp->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarPick, floaterp, FALSE, TRUE)); + floaterp->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, floaterp, _1, _2), FALSE, TRUE)); } -// static -void LLFloaterSellLandUI::callbackAvatarPick(const std::vector& names, const std::vector& ids, void* data) +void LLFloaterSellLandUI::callbackAvatarPick(const uuid_vec_t& ids, const std::vector& names) { - LLFloaterSellLandUI* floaterp = (LLFloaterSellLandUI*)data; - LLParcel* parcel = floaterp->mParcelSelection->getParcel(); + LLParcel* parcel = mParcelSelection->getParcel(); if (names.empty() || ids.empty()) return; LLUUID id = ids[0]; parcel->setAuthorizedBuyerID(id); - floaterp->mAuthorizedBuyer = ids[0]; + mAuthorizedBuyer = ids[0]; - floaterp->childSetText("sell_to_agent", names[0]); + childSetText("sell_to_agent", names[0].getCompleteName()); - floaterp->refreshUI(); + refreshUI(); } // static diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 2d7ce1da4..5bd332024 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -31,117 +31,129 @@ */ #include "llviewerprecompiledheaders.h" + #include "llfloatersettingsdebug.h" -#include "llfloater.h" -#include "lluictrlfactory.h" -#include "llfirstuse.h" -#include "llcombobox.h" -#include "llspinctrl.h" + #include "llcolorswatch.h" +//#include "llfirstuse.h" +#include "llfloater.h" +#include "llscrolllistctrl.h" +#include "llspinctrl.h" +#include "lltexteditor.h" +#include "lluictrlfactory.h" #include "llviewercontrol.h" +#include "llwindow.h" // [RLVa:KB] #include "rlvhandler.h" #include "rlvextensions.h" // [/RLVa:KB] -LLFloaterSettingsDebug* LLFloaterSettingsDebug::sInstance = NULL; - -LLFloaterSettingsDebug::LLFloaterSettingsDebug() : LLFloater(std::string("Configuration Editor")) +LLFloaterSettingsDebug::LLFloaterSettingsDebug() +: LLFloater(std::string("Configuration Editor")) +, mCurrentControlVariable(NULL) +, mOldControlVariable(NULL) +, mOldSearchTerm(std::string("---")) { + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_settings_debug.xml"); } LLFloaterSettingsDebug::~LLFloaterSettingsDebug() { - sInstance = NULL; + if (mOldControlVariable) + mOldControlVariable->getCommitSignal()->disconnect(boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this)); } BOOL LLFloaterSettingsDebug::postBuild() { - LLComboBox* settings_combo = getChild("settings_combo"); + mSettingsScrollList = getChild("settings_scroll_list"); struct f : public LLControlGroup::ApplyFunctor { - LLComboBox* combo; - f(LLComboBox* c) : combo(c) {} + settings_map_t* map; + f(settings_map_t* m) : map(m) {} virtual void apply(const std::string& name, LLControlVariable* control) { if (!control->isHiddenFromSettingsEditor()) { - combo->add(name, (void*)control); + (*map)[name]=control; } } - } func(settings_combo); + } func(&mSettingsMap); gSavedSettings.applyToAll(&func); gSavedPerAccountSettings.applyToAll(&func); gColors.applyToAll(&func); - settings_combo->sortByName(); - settings_combo->setCommitCallback(onSettingSelect); - settings_combo->setCallbackUserData(this); - settings_combo->updateSelection(); + // Populate the list + { + for(settings_map_t::iterator it = mSettingsMap.begin(); it != mSettingsMap.end(); it++) + { + LLSD item; + item["columns"][0]["value"] = it->second->getName(); + mSettingsScrollList->addElement(item, ADD_BOTTOM, it->second); + } + } + mSettingsScrollList->sortByColumnIndex(0, true); + mSettingsScrollList->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this)); - childSetCommitCallback("val_spinner_1", onCommitSettings); - childSetUserData("val_spinner_1", this); - childSetCommitCallback("val_spinner_2", onCommitSettings); - childSetUserData("val_spinner_2", this); - childSetCommitCallback("val_spinner_3", onCommitSettings); - childSetUserData("val_spinner_3", this); - childSetCommitCallback("val_spinner_4", onCommitSettings); - childSetUserData("val_spinner_4", this); - childSetCommitCallback("val_text", onCommitSettings); - childSetUserData("val_text", this); - childSetCommitCallback("boolean_combo", onCommitSettings); - childSetUserData("boolean_combo", this); - childSetCommitCallback("color_swatch", onCommitSettings); - childSetUserData("color_swatch", this); - childSetAction("default_btn", onClickDefault, this); + llinfos << mSettingsScrollList->getItemCount() << " total debug settings displayed." << llendl; + + getChild("val_spinner_1")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); + getChild("val_spinner_2")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); + getChild("val_spinner_3")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); + getChild("val_spinner_4")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); + getChild("val_text")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); + getChild("boolean_combo")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); + getChild("color_swatch")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); + getChild("copy_btn")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCopyToClipboard, this)); + getChild("default_btn")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onClickDefault, this)); + getChild("search_settings_input")->setSearchCallback(onUpdateFilter, this); mComment = getChild("comment_text"); return TRUE; } void LLFloaterSettingsDebug::draw() { - LLComboBox* settings_combo = getChild("settings_combo"); - LLControlVariable* controlp = static_cast(settings_combo->getCurrentUserdata()); - updateControl(controlp ? controlp->getCOAActive() : NULL); + // check for changes in control visibility, like RLVa does + if(mCurrentControlVariable && mCurrentControlVariable->isHiddenFromSettingsEditor() != mOldVisibility) + updateControl(); LLFloater::draw(); } -//static -void LLFloaterSettingsDebug::show(void*) +LLControlVariable* LLFloaterSettingsDebug::getControlVariable() { - if (sInstance == NULL) - { - sInstance = new LLFloaterSettingsDebug(); + LLScrollListItem* item = mSettingsScrollList->getFirstSelected(); + if (!item) return NULL; - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_settings_debug.xml"); - } + LLControlVariable* controlp = static_cast(item->getUserdata()); - sInstance->open(); /* Flawfinder: ignore */ + return controlp ? controlp->getCOAActive() : NULL; } -//static -void LLFloaterSettingsDebug::onSettingSelect(LLUICtrl* ctrl, void* user_data) +void LLFloaterSettingsDebug::onSettingSelect() { - LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data; - LLComboBox* combo_box = static_cast(ctrl); - LLControlVariable* controlp = static_cast(combo_box->getCurrentUserdata()); + mCurrentControlVariable = getControlVariable(); - floaterp->updateControl(controlp ? controlp->getCOAActive() : NULL); + if (mOldControlVariable == mCurrentControlVariable) return; + + // unbind change control signal from previously selected control + if(mOldControlVariable) + mOldControlVariable->getCommitSignal()->disconnect(boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this)); + + // bind change control signal, so we can see updates to the current control in realtime + if(mCurrentControlVariable) + mCurrentControlVariable->getCommitSignal()->connect(boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this)); + + mOldControlVariable = mCurrentControlVariable; + + updateControl(); } -//static -void LLFloaterSettingsDebug::onCommitSettings(LLUICtrl* ctrl, void* user_data) +void LLFloaterSettingsDebug::onCommitSettings() { - LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data; - - LLComboBox* settings_combo = floaterp->getChild("settings_combo"); - LLControlVariable* controlp = static_cast(settings_combo->getCurrentUserdata()); - controlp = controlp ? controlp->getCOAActive() : NULL; - if(!controlp)//Uh oh! + if (!mCurrentControlVariable) return; LLVector3 vector; @@ -152,88 +164,89 @@ void LLFloaterSettingsDebug::onCommitSettings(LLUICtrl* ctrl, void* user_data) LLColor4U col4U; LLColor4 color_with_alpha; - switch(controlp->type()) + switch(mCurrentControlVariable->type()) { case TYPE_U32: - controlp->set(floaterp->childGetValue("val_spinner_1")); + mCurrentControlVariable->set(getChild("val_spinner_1")->getValue()); break; case TYPE_S32: - controlp->set(floaterp->childGetValue("val_spinner_1")); + mCurrentControlVariable->set(getChild("val_spinner_1")->getValue()); break; case TYPE_F32: - controlp->set(LLSD(floaterp->childGetValue("val_spinner_1").asReal())); + mCurrentControlVariable->set(LLSD(getChild("val_spinner_1")->getValue().asReal())); break; case TYPE_BOOLEAN: - controlp->set(floaterp->childGetValue("boolean_combo")); + mCurrentControlVariable->set(getChild("boolean_combo")->getValue()); break; case TYPE_STRING: - controlp->set(LLSD(floaterp->childGetValue("val_text").asString())); + mCurrentControlVariable->set(LLSD(getChild("val_text")->getValue().asString())); break; case TYPE_VEC3: - vector.mV[VX] = (F32)floaterp->childGetValue("val_spinner_1").asReal(); - vector.mV[VY] = (F32)floaterp->childGetValue("val_spinner_2").asReal(); - vector.mV[VZ] = (F32)floaterp->childGetValue("val_spinner_3").asReal(); - controlp->set(vector.getValue()); + vector.mV[VX] = (F32)getChild("val_spinner_1")->getValue().asReal(); + vector.mV[VY] = (F32)getChild("val_spinner_2")->getValue().asReal(); + vector.mV[VZ] = (F32)getChild("val_spinner_3")->getValue().asReal(); + mCurrentControlVariable->set(vector.getValue()); break; case TYPE_VEC3D: - vectord.mdV[VX] = floaterp->childGetValue("val_spinner_1").asReal(); - vectord.mdV[VY] = floaterp->childGetValue("val_spinner_2").asReal(); - vectord.mdV[VZ] = floaterp->childGetValue("val_spinner_3").asReal(); - controlp->set(vectord.getValue()); + vectord.mdV[VX] = getChild("val_spinner_1")->getValue().asReal(); + vectord.mdV[VY] = getChild("val_spinner_2")->getValue().asReal(); + vectord.mdV[VZ] = getChild("val_spinner_3")->getValue().asReal(); + mCurrentControlVariable->set(vectord.getValue()); break; case TYPE_RECT: - rect.mLeft = floaterp->childGetValue("val_spinner_1").asInteger(); - rect.mRight = floaterp->childGetValue("val_spinner_2").asInteger(); - rect.mBottom = floaterp->childGetValue("val_spinner_3").asInteger(); - rect.mTop = floaterp->childGetValue("val_spinner_4").asInteger(); - controlp->set(rect.getValue()); + rect.mLeft = getChild("val_spinner_1")->getValue().asInteger(); + rect.mRight = getChild("val_spinner_2")->getValue().asInteger(); + rect.mBottom = getChild("val_spinner_3")->getValue().asInteger(); + rect.mTop = getChild("val_spinner_4")->getValue().asInteger(); + mCurrentControlVariable->set(rect.getValue()); break; case TYPE_COL4: - col3.setValue(floaterp->childGetValue("color_swatch")); - col4 = LLColor4(col3, (F32)floaterp->childGetValue("val_spinner_4").asReal()); - controlp->set(col4.getValue()); + col3.setValue(getChild("val_color_swatch")->getValue()); + col4 = LLColor4(col3, (F32)getChild("val_spinner_4")->getValue().asReal()); + mCurrentControlVariable->set(col4.getValue()); break; case TYPE_COL3: - controlp->set(floaterp->childGetValue("color_swatch")); - //col3.mV[VRED] = (F32)floaterp->childGetValue("val_spinner_1").asC(); - //col3.mV[VGREEN] = (F32)floaterp->childGetValue("val_spinner_2").asReal(); - //col3.mV[VBLUE] = (F32)floaterp->childGetValue("val_spinner_3").asReal(); - //controlp->set(col3.getValue()); + mCurrentControlVariable->set(getChild("val_color_swatch")->getValue()); + //col3.mV[VRED] = (F32)getChild("val_spinner_1")->getValue().asC(); + //col3.mV[VGREEN] = (F32)getChild("val_spinner_2")->getValue().asReal(); + //col3.mV[VBLUE] = (F32)getChild("val_spinner_3")->getValue().asReal(); + //mCurrentControlVariable->set(col3.getValue()); break; case TYPE_COL4U: - col3.setValue(floaterp->childGetValue("color_swatch")); + col3.setValue(getChild("val_color_swatch")->getValue()); col4U.setVecScaleClamp(col3); - col4U.mV[VALPHA] = floaterp->childGetValue("val_spinner_4").asInteger(); - controlp->set(col4U.getValue()); + col4U.mV[VALPHA] = getChild("val_spinner_4")->getValue().asInteger(); + mCurrentControlVariable->set(col4U.getValue()); break; default: break; } } -// static -void LLFloaterSettingsDebug::onClickDefault(void* user_data) +void LLFloaterSettingsDebug::onClickDefault() { - LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data; - LLComboBox* settings_combo = floaterp->getChild("settings_combo"); - LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata(); - - if (controlp) + if (mCurrentControlVariable) { - controlp = controlp->getCOAActive(); - controlp->resetToDefault(true); - floaterp->updateControl(controlp); + mCurrentControlVariable->resetToDefault(true); + updateControl(); } } -// we've switched controls, or doing per-frame update, so update spinners, etc. -void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) +void LLFloaterSettingsDebug::onCopyToClipboard() +{ + if (mCurrentControlVariable) + getWindow()->copyTextToClipboard(utf8str_to_wstring(mCurrentControlVariable->getName())); +} + +// we've switched controls, so update spinners, etc. +void LLFloaterSettingsDebug::updateControl() { LLSpinCtrl* spinner1 = getChild("val_spinner_1"); LLSpinCtrl* spinner2 = getChild("val_spinner_2"); LLSpinCtrl* spinner3 = getChild("val_spinner_3"); LLSpinCtrl* spinner4 = getChild("val_spinner_4"); - LLColorSwatchCtrl* color_swatch = getChild("color_swatch"); + LLColorSwatchCtrl* color_swatch = getChild("val_color_swatch"); + LLUICtrl* bool_ctrl = getChild("boolean_combo"); if (!spinner1 || !spinner2 || !spinner3 || !spinner4 || !color_swatch) { @@ -247,45 +260,33 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) spinner3->setVisible(FALSE); spinner4->setVisible(FALSE); color_swatch->setVisible(FALSE); - childSetVisible("val_text", FALSE); + getChildView("val_text")->setVisible( FALSE); mComment->setText(LLStringUtil::null); + childSetEnabled("copy_btn", false); + childSetEnabled("default_btn", false); + bool_ctrl->setVisible(false); - if (controlp) + if (mCurrentControlVariable) { -// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.1d - if (rlv_handler_t::isEnabled()) - { - // Don't allow changing DBG_WRITE debug settings under @setdebug=n - bool fEnable = !( (gRlvHandler.hasBehaviour(RLV_BHVR_SETDEBUG)) && - (RlvExtGetSet::getDebugSettingFlags(controlp->getName()) & RlvExtGetSet::DBG_WRITE) ); - // Don't allow toggling "Basic Shaders" and/or "Atmopsheric Shaders" through the debug settings under @setenv=n - fEnable &= !((gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) && - (("VertexShaderEnable" == controlp->getName()) || ("WindLightUseAtmosShaders" == controlp->getName()))); - #ifdef RLV_EXTENSION_STARTLOCATION - // Don't allow toggling RLVaLoginLastLocation - fEnable &= !(RLV_SETTING_LOGINLASTLOCATION == controlp->getName()); - #endif // RLV_EXTENSION_STARTLOCATION - - // NOTE: this runs per-frame so there's no need to explictly handle onCommitSettings() or onClickDefault() - spinner1->setEnabled(fEnable); - spinner2->setEnabled(fEnable); - spinner3->setEnabled(fEnable); - spinner4->setEnabled(fEnable); - color_swatch->setEnabled(fEnable); - childSetEnabled("val_text", fEnable); - childSetEnabled("boolean_combo", fEnable); - childSetEnabled("default_btn", fEnable); - } +// [RLVa:KB] - Checked: 2011-05-28 (RLVa-1.4.0a) | Modified: RLVa-1.4.0a + // If "HideFromEditor" was toggled while the floater is open then we need to manually disable access to the control + mOldVisibility = mCurrentControlVariable->isHiddenFromSettingsEditor(); + spinner1->setEnabled(!mOldVisibility); + spinner2->setEnabled(!mOldVisibility); + spinner3->setEnabled(!mOldVisibility); + spinner4->setEnabled(!mOldVisibility); + color_swatch->setEnabled(!mOldVisibility); + childSetEnabled("val_text", !mOldVisibility); + bool_ctrl->setEnabled(!mOldVisibility); + childSetEnabled("default_btn", !mOldVisibility); // [/RLVa:KB] - controlp = controlp->getCOAActive(); - eControlType type = controlp->type(); + childSetEnabled("copy_btn", true); - //hide combo box only for non booleans, otherwise this will result in the combo box closing every frame - childSetVisible("boolean_combo", type == TYPE_BOOLEAN); - + eControlType type = mCurrentControlVariable->type(); + + mComment->setText(mCurrentControlVariable->getName() + std::string(": ") + mCurrentControlVariable->getComment()); - mComment->setText(controlp->getComment()); spinner1->setMaxValue(F32_MAX); spinner2->setMaxValue(F32_MAX); spinner3->setMaxValue(F32_MAX); @@ -311,7 +312,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) spinner4->setIncrement(0.1f); } - LLSD sd = controlp->get(); + LLSD sd = mCurrentControlVariable->get(); switch(type) { case TYPE_U32: @@ -348,23 +349,24 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) } break; case TYPE_BOOLEAN: - if (!childHasFocus("boolean_combo")) + bool_ctrl->setVisible(true); + if (!bool_ctrl->hasFocus()) { if (sd.asBoolean()) { - childSetValue("boolean_combo", LLSD("true")); + bool_ctrl->setValue(LLSD("TRUE")); } else { - childSetValue("boolean_combo", LLSD("")); + bool_ctrl->setValue(LLSD("FALSE")); } } break; case TYPE_STRING: - childSetVisible("val_text", TRUE); - if (!childHasFocus("val_text")) + getChildView("val_text")->setVisible( TRUE); + if (!getChild("val_text")->hasFocus()) { - childSetValue("val_text", sd); + getChild("val_text")->setValue(sd); } break; case TYPE_VEC3: @@ -530,3 +532,58 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) } } + +void LLFloaterSettingsDebug::onUpdateFilter(const std::string& searchTerm, void*) +{ + LLFloaterSettingsDebug::getInstance()->updateFilter(searchTerm); +} + +void LLFloaterSettingsDebug::updateFilter(std::string searchTerm) +{ + // make sure not to reselect the first item in the list on focus restore + if (searchTerm == mOldSearchTerm) return; + + mOldSearchTerm = searchTerm; + + LLStringUtil::toLower(searchTerm); + + mSettingsScrollList->deleteAllItems(); + + for(settings_map_t::iterator it = mSettingsMap.begin(); it != mSettingsMap.end(); it++) + { + bool addItem = searchTerm.empty(); + if (!addItem) + { + std::string itemValue = it->second->getName(); + + LLStringUtil::toLower(itemValue); + + if (itemValue.find(searchTerm, 0) != std::string::npos) + { + addItem = true; + } + else // performance: broken out to save toLower calls on comments + { + std::string itemComment = it->second->getComment(); + LLStringUtil::toLower(itemComment); + if (itemComment.find(searchTerm, 0) != std::string::npos) + addItem = true; + } + } + + if (addItem) + { + LLSD item; + item["columns"][0]["value"] = it->second->getName(); + mSettingsScrollList->addElement(item, ADD_BOTTOM, it->second); + } + } + mSettingsScrollList->sortByColumnIndex(0, true); + + // if at least one match was found, highlight and select the topmost entry in the list + // but only if actually a search term was given + if (mSettingsScrollList->getItemCount() && !searchTerm.empty()) + mSettingsScrollList->selectFirstItem(); + + onSettingSelect(); +} diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h index e08e6b5d7..cce8fa481 100644 --- a/indra/newview/llfloatersettingsdebug.h +++ b/indra/newview/llfloatersettingsdebug.h @@ -35,9 +35,13 @@ #include "llcontrol.h" #include "llfloater.h" -#include "lltexteditor.h" -class LLFloaterSettingsDebug : public LLFloater +class LLScrollListCtrl; +class LLTextEditor; + +class LLFloaterSettingsDebug +: public LLFloater +, public LLSingleton { public: LLFloaterSettingsDebug(); @@ -46,17 +50,33 @@ public: virtual BOOL postBuild(); virtual void draw(); - void updateControl(LLControlVariable* control); + void updateControl(); - static void show(void*); - static void onSettingSelect(LLUICtrl* ctrl, void* user_data); - static void onCommitSettings(LLUICtrl* ctrl, void* user_data); - static void onClickDefault(void* user_data); + // updates control filter to display in the controls list on keystroke + static void onUpdateFilter(const std::string& searchTerm, void*); + void updateFilter(std::string searchTerm); + + void onSettingSelect(); + void onCommitSettings(); + void onClickDefault(); + void onCopyToClipboard(); + +private: + // returns a pointer to the currently selected control variable, or NULL + LLControlVariable* getControlVariable(); protected: - static LLFloaterSettingsDebug* sInstance; + typedef std::map settings_map_t; + + settings_map_t mSettingsMap; + + std::string mOldSearchTerm; + LLControlVariable* mCurrentControlVariable; + LLControlVariable* mOldControlVariable; + bool mOldVisibility; + + LLScrollListCtrl* mSettingsScrollList; LLTextEditor* mComment; }; #endif //LLFLOATERDEBUGSETTINGS_H - diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 393dd78af..735b033b1 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -64,13 +64,17 @@ #include "llviewerwindow.h" #include "llwindow.h" #include "llviewermenufile.h" // upload_new_resource() +#include "llresourcedata.h" #include "llfloaterpostcard.h" +#include "llfloaterfeed.h" #include "llcheckboxctrl.h" #include "llradiogroup.h" #include "lltoolfocus.h" #include "lltoolmgr.h" #include "llworld.h" #include "llagentui.h" +#include "llvoavatar.h" +#include "lluploaddialog.h" #include "llgl.h" #include "llglheaders.h" @@ -87,9 +91,10 @@ ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- -S32 LLFloaterSnapshot::sUIWinHeightLong = 546 ; -S32 LLFloaterSnapshot::sUIWinHeightShort = LLFloaterSnapshot::sUIWinHeightLong - 250 ; -S32 LLFloaterSnapshot::sUIWinWidth = 215 ; +S32 LLFloaterSnapshot::sUIWinHeightLong = 619 ; +S32 LLFloaterSnapshot::sUIWinHeightShort = LLFloaterSnapshot::sUIWinHeightLong - 260 ; +S32 LLFloaterSnapshot::sUIWinWidth = 219 ; +S32 const THUMBHEIGHT = 159; LLSnapshotFloaterView* gSnapshotFloaterView = NULL; @@ -114,11 +119,31 @@ class LLSnapshotLivePreview : public LLView public: enum ESnapshotType { + SNAPSHOT_FEED, SNAPSHOT_POSTCARD, SNAPSHOT_TEXTURE, SNAPSHOT_LOCAL }; + enum EAspectSizeProblem + { + ASPECTSIZE_OK, + CANNOT_CROP_HORIZONTALLY, + CANNOT_CROP_VERTICALLY, + SIZE_TOO_LARGE, + CANNOT_RESIZE, + DELAYED, + NO_RAW_IMAGE, + ENCODING_FAILED + }; + + U32 typeToMask(ESnapshotType type) const { return 1 << type; } + void addUsedBy(ESnapshotType type) { mUsedBy |= typeToMask(type); } + void delUsedBy(ESnapshotType type) { mUsedBy &= ~typeToMask(type); } + bool isUsedBy(ESnapshotType type) const { return (mUsedBy & typeToMask(type)) != 0; } + bool isUsed(void) const { return mUsedBy; } + void addManualOverride(ESnapshotType type) { mManualSizeOverride |= typeToMask(type); } + bool isOverriddenBy(ESnapshotType type) const { return (mManualSizeOverride & typeToMask(type)) != 0; } LLSnapshotLivePreview(const LLRect& rect); ~LLSnapshotLivePreview(); @@ -128,123 +153,280 @@ public: void setSize(S32 w, S32 h); void getSize(S32& w, S32& h) const; - S32 getDataSize() const { return mDataSize; } + void setAspect(F32 a); + F32 getAspect() const; + void getRawSize(S32& w, S32& h) const; + S32 getDataSize() const { return mFormattedDataSize; } void setMaxImageSize(S32 size) ; S32 getMaxImageSize() {return mMaxImageSize ;} ESnapshotType getSnapshotType() const { return mSnapshotType; } LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; } - BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; } + BOOL getRawSnapshotUpToDate() const; + BOOL getSnapshotUpToDate() const; BOOL isSnapshotActive() { return mSnapshotActive; } LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; } S32 getThumbnailWidth() const { return mThumbnailWidth ; } S32 getThumbnailHeight() const { return mThumbnailHeight ; } BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; } BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;} + bool getShowFreezeFrameSnapshot() const { return mShowFreezeFrameSnapshot; } LLViewerTexture* getCurrentImage(); - F32 getImageAspect(); - F32 getAspect() ; - LLRect getImageRect(); - BOOL isImageScaled(); + char const* aspectComboName() const; void setSnapshotType(ESnapshotType type) { mSnapshotType = type; } void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat type) { mSnapshotFormat = type; } void setSnapshotQuality(S32 quality); - void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; } + void setSnapshotBufferType(LLFloaterSnapshot* floater, LLViewerWindow::ESnapshotType type); + void showFreezeFrameSnapshot(bool show); void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f); + LLFloaterFeed* getCaptionAndSaveFeed(); LLFloaterPostcard* savePostcard(); void saveTexture(); + static void saveTextureDone(LLUUID const& asset_id, void* user_data, S32 status, LLExtStat ext_status); + static void saveTextureDone2(bool success, void* user_data); void saveLocal(); + void saveStart(int index); + void saveDone(ESnapshotType type, bool success, int index); + void close(LLFloaterSnapshot* view); + void doCloseAfterSave(); - BOOL setThumbnailImageSize() ; - void generateThumbnailImage(BOOL force_update = FALSE) ; - void resetThumbnailImage() { mThumbnailImage = NULL ; } + BOOL setThumbnailImageSize(); + void generateThumbnailImage(); + EAspectSizeProblem getAspectSizeProblem(S32& width_out, S32& height_out, bool& crop_vertically_out, S32& crop_offset_out); + EAspectSizeProblem generateFormattedAndFullscreenPreview(bool delayed_formatted = false); void drawPreviewRect(S32 offset_x, S32 offset_y) ; // Returns TRUE when snapshot generated, FALSE otherwise. - static BOOL onIdle( void* snapshot_preview ); + static BOOL onIdle(LLSnapshotLivePreview* previewp); private: LLColor4 mColor; - LLPointer mViewerImage[2]; //used to represent the scene when the frame is frozen. - LLRect mImageRect[2]; - S32 mWidth[2]; - S32 mHeight[2]; - BOOL mImageScaled[2]; - S32 mMaxImageSize ; + + LLPointer mFullScreenPreviewTexture; // Used to represent the scene when the frame is frozen. + LLRect mFullScreenImageRect; // The portion of the screen that is captured (the window size minus any cropping). + S32 mWidth; // The target image width. + S32 mHeight; // The target image height. + BOOL mFullScreenPreviewTextureNeedsScaling; // True when the actual data in mFullScreenPreviewTexture is smaller than its size. + + // Temporary data for the fall animation (same as the above). + LLPointer mFallFullScreenPreviewTexture; + LLRect mFallFullScreenImageRect; + S32 mFallWidth; + S32 mFallHeight; + BOOL mFallFullScreenPreviewTextureNeedsScaling; + + S32 mMaxImageSize; + F32 mAspectRatio; - //thumbnail image + // Thumbnail image. LLPointer mThumbnailImage ; + LLRect mThumbnailPreviewRect ; S32 mThumbnailWidth ; S32 mThumbnailHeight ; - LLRect mPreviewRect ; BOOL mThumbnailUpdateLock ; BOOL mThumbnailUpToDate ; - S32 mCurImageIndex; - LLPointer mPreviewImage; - LLPointer mPreviewImageEncoded; + // The last raw snapshot image. + LLPointer mRawSnapshot; + S32 mRawSnapshotWidth; + S32 mRawSnapshotHeight; + F32 mRawSnapshotAspectRatio; + BOOL mRawSnapshotRenderUI; + BOOL mRawSnapshotRenderHUD; + LLViewerWindow::ESnapshotType mRawSnapshotBufferType; + LLPointer mFormattedImage; + S32 mFormattedWidth; + S32 mFormattedHeight; + S32 mFormattedRawWidth; + S32 mFormattedRawHeight; + S32 mFormattedCropOffset; + bool mFormattedCropVertically; + LLFloaterSnapshot::ESnapshotFormat mFormattedSnapshotFormat; + S32 mFormattedSnapshotQuality; + bool mFormattedUpToDate; + LLFrameTimer mSnapshotDelayTimer; + U32 mUsedBy; + U32 mManualSizeOverride; S32 mShineCountdown; LLFrameTimer mShineAnimTimer; F32 mFlashAlpha; BOOL mNeedsFlash; LLVector3d mPosTakenGlobal; S32 mSnapshotQuality; - S32 mDataSize; + S32 mFormattedDataSize; ESnapshotType mSnapshotType; LLFloaterSnapshot::ESnapshotFormat mSnapshotFormat; - BOOL mSnapshotUpToDate; + BOOL mShowFreezeFrameSnapshot; LLFrameTimer mFallAnimTimer; LLVector3 mCameraPos; LLQuaternion mCameraRot; BOOL mSnapshotActive; LLViewerWindow::ESnapshotType mSnapshotBufferType; + int mOutstandingCallbacks; + int mSaveFailures; + LLFloaterSnapshot* mCloseCalled; + static int sSnapshotIndex; + public: static std::set sList; - BOOL mKeepAspectRatio ; + LLFrameTimer mFormattedDelayTimer; }; +///---------------------------------------------------------------------------- +/// Class LLFloaterSnapshot::Impl +///---------------------------------------------------------------------------- +class LLFloaterSnapshot::Impl +{ +public: + Impl() + : mAvatarPauseHandles(), + mLastToolset(NULL) + { + } + ~Impl() + { + //unpause avatars + mAvatarPauseHandles.clear(); + mQualityMouseUpConnection.disconnect(); + } + static void onClickKeep(void* data); + static void onCommitSave(LLUICtrl* ctrl, void* data); + static void onClickNewSnapshot(void* data); + static void onClickFreezeTime(void* data); + static void onClickAutoSnap(LLUICtrl *ctrl, void* data); + static void onClickTemporaryImage(LLUICtrl *ctrl, void* data); + //static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data); + static void onClickLess(void* data) ; + static void onClickMore(void* data) ; + static void onClickUICheck(LLUICtrl *ctrl, void* data); + static void onClickHUDCheck(LLUICtrl *ctrl, void* data); + static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data); + static void onCommitQuality(LLUICtrl* ctrl, void* data); + static void onCommitFeedResolution(LLUICtrl* ctrl, void* data); + static void onCommitPostcardResolution(LLUICtrl* ctrl, void* data); + static void onCommitTextureResolution(LLUICtrl* ctrl, void* data); + static void onCommitLocalResolution(LLUICtrl* ctrl, void* data); + static void onCommitFeedAspect(LLUICtrl* ctrl, void* data); + static void onCommitPostcardAspect(LLUICtrl* ctrl, void* data); + static void onCommitTextureAspect(LLUICtrl* ctrl, void* data); + static void onCommitLocalAspect(LLUICtrl* ctrl, void* data); + static void updateResolution(LLUICtrl* ctrl, void* data, bool update_controls = true); + static void updateAspect(LLUICtrl* ctrl, void* data, bool update_controls = true); + static void onCommitFreezeTime(LLUICtrl* ctrl, void* data); + static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); + static void onCommitSnapshotType(LLUICtrl* ctrl, void* data); + static void onCommitSnapshotFormat(LLUICtrl* ctrl, void* data); + static void onCommitCustomResolution(LLUICtrl *ctrl, void* data); + static void onCommitCustomAspect(LLUICtrl *ctrl, void* data); + static void onQualityMouseUp(void* data); + + static LLSnapshotLivePreview* getPreviewView(void); + static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname, bool visible, bool update_controls = true); + static void setAspect(LLFloaterSnapshot* floater, const std::string& comboname, bool update_controls = true); + static void updateControls(LLFloaterSnapshot* floater, bool delayed_formatted = false); + static void resetFeedAndPostcardAspect(LLFloaterSnapshot* floater); + static void updateLayout(LLFloaterSnapshot* floater); + static void freezeTime(bool on); + + static LLHandle sPreviewHandle; + +private: + static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater); + static ESnapshotFormat getFormatIndex(LLFloaterSnapshot* floater); + static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname); + static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); + +public: + std::vector mAvatarPauseHandles; + + LLToolset* mLastToolset; + boost::signals2::connection mQualityMouseUpConnection; + LLFocusableElement* mPrevDefaultKeyboardFocus; +}; + +//---------------------------------------------------------------------------- +// LLSnapshotLivePreview + +//static +int LLSnapshotLivePreview::sSnapshotIndex; + +void LLSnapshotLivePreview::setSnapshotBufferType(LLFloaterSnapshot* floater, LLViewerWindow::ESnapshotType type) +{ + mSnapshotBufferType = type; + switch(type) + { + case LLViewerWindow::SNAPSHOT_TYPE_COLOR: + floater->childSetValue("layer_types", "colors"); + break; + case LLViewerWindow::SNAPSHOT_TYPE_DEPTH: + floater->childSetValue("layer_types", "depth"); + break; + } +} + +BOOL LLSnapshotLivePreview::getRawSnapshotUpToDate() const +{ + return mRawSnapshotRenderUI == gSavedSettings.getBOOL("RenderUIInSnapshot") && + mRawSnapshotRenderHUD == gSavedSettings.getBOOL("RenderHUDInSnapshot") && + mRawSnapshotBufferType == mSnapshotBufferType; +} + +BOOL LLSnapshotLivePreview::getSnapshotUpToDate() const +{ + return mFormattedUpToDate && getRawSnapshotUpToDate(); +} + std::set LLSnapshotLivePreview::sList; + LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : LLView(std::string("snapshot_live_preview"), rect, FALSE), mColor(1.f, 0.f, 0.f, 0.5f), - mCurImageIndex(0), - mPreviewImage(NULL), + mRawSnapshot(NULL), + mRawSnapshotWidth(0), + mRawSnapshotHeight(1), + mRawSnapshotAspectRatio(1.0), + mRawSnapshotRenderUI(FALSE), + mRawSnapshotRenderHUD(FALSE), + mRawSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR), mThumbnailImage(NULL) , mThumbnailWidth(0), mThumbnailHeight(0), - mPreviewImageEncoded(NULL), mFormattedImage(NULL), + mFormattedUpToDate(false), + mUsedBy(0), + mManualSizeOverride(0), mShineCountdown(0), mFlashAlpha(0.f), mNeedsFlash(TRUE), mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")), - mDataSize(0), - mSnapshotType(SNAPSHOT_POSTCARD), + mFormattedDataSize(0), + mSnapshotType(SNAPSHOT_FEED), mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))), - mSnapshotUpToDate(FALSE), + mShowFreezeFrameSnapshot(FALSE), mCameraPos(LLViewerCamera::getInstance()->getOrigin()), mCameraRot(LLViewerCamera::getInstance()->getQuaternion()), mSnapshotActive(FALSE), - mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR) + mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR), + mCloseCalled(NULL) { + DoutEntering(dc::snapshot, "LLSnapshotLivePreview() [" << (void*)this << "]"); setSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")); mSnapshotDelayTimer.start(); -// gIdleCallbacks.addFunction( &LLSnapshotLivePreview::onIdle, (void*)this ); sList.insert(this); setFollowsAll(); - mWidth[0] = gViewerWindow->getWindowDisplayWidth(); - mWidth[1] = gViewerWindow->getWindowDisplayWidth(); - mHeight[0] = gViewerWindow->getWindowDisplayHeight(); - mHeight[1] = gViewerWindow->getWindowDisplayHeight(); - mImageScaled[0] = FALSE; - mImageScaled[1] = FALSE; + mWidth = gViewerWindow->getWindowDisplayWidth(); + mHeight = gViewerWindow->getWindowDisplayHeight(); + mAspectRatio = (F32)mWidth / mHeight; + mFallWidth = mWidth; + mFallHeight = mHeight; + mFullScreenPreviewTextureNeedsScaling = FALSE; + mFallFullScreenPreviewTextureNeedsScaling = FALSE; mMaxImageSize = MAX_SNAPSHOT_IMAGE_SIZE ; - mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; mThumbnailUpdateLock = FALSE ; mThumbnailUpToDate = FALSE ; updateSnapshot(TRUE,TRUE); //To initialize mImageRect to correct values @@ -252,13 +434,10 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : LLSnapshotLivePreview::~LLSnapshotLivePreview() { - // delete images - mPreviewImage = NULL; - mPreviewImageEncoded = NULL; - mFormattedImage = NULL; - -// gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this ); + DoutEntering(dc::snapshot, "~LLSnapshotLivePreview() [" << (void*)this << "]"); sList.erase(this); + // Stop callbacks from using this object. + ++sSnapshotIndex; } void LLSnapshotLivePreview::setMaxImageSize(S32 size) @@ -275,78 +454,51 @@ void LLSnapshotLivePreview::setMaxImageSize(S32 size) LLViewerTexture* LLSnapshotLivePreview::getCurrentImage() { - return mViewerImage[mCurImageIndex]; + return mFullScreenPreviewTexture; } -F32 LLSnapshotLivePreview::getAspect() +void LLSnapshotLivePreview::showFreezeFrameSnapshot(bool show) { - F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); - F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight()); - - if (!mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot")) + DoutEntering(dc::snapshot, "LLSnapshotLivePreview::showFreezeFrameSnapshot(" << show << ")"); + // If we stop to show the fullscreen "freeze frame" snapshot, play the "fall away" animation. + if (mShowFreezeFrameSnapshot && !show) { - return image_aspect_ratio; + mFallFullScreenPreviewTexture = mFullScreenPreviewTexture; + mFallFullScreenPreviewTextureNeedsScaling = mFullScreenPreviewTextureNeedsScaling; + mFallFullScreenImageRect = mFullScreenImageRect; + mFallWidth = mFormattedWidth; + mFallHeight = mFormattedHeight; + mFallAnimTimer.start(); } - else - { - return window_aspect_ratio; - } -} - -F32 LLSnapshotLivePreview::getImageAspect() -{ - if (!mViewerImage[mCurImageIndex]) - { - return 0.f; - } - - return getAspect() ; -} - -LLRect LLSnapshotLivePreview::getImageRect() -{ - return mImageRect[mCurImageIndex]; -} - -BOOL LLSnapshotLivePreview::isImageScaled() -{ - return mImageScaled[mCurImageIndex]; + mShowFreezeFrameSnapshot = show; } void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay) -{ - if (mSnapshotUpToDate) - { - S32 old_image_index = mCurImageIndex; - mCurImageIndex = (mCurImageIndex + 1) % 2; - mWidth[mCurImageIndex] = mWidth[old_image_index]; - mHeight[mCurImageIndex] = mHeight[old_image_index]; - mFallAnimTimer.start(); - } - mSnapshotUpToDate = FALSE; +{ + DoutEntering(dc::snapshot, "LLSnapshotLivePreview::updateSnapshot(" << new_snapshot << ", " << new_thumbnail << ", " << delay << ")"); - LLRect& rect = mImageRect[mCurImageIndex]; + LLRect& rect = mFullScreenImageRect; rect.set(0, getRect().getHeight(), getRect().getWidth(), 0); - F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); - F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight()); + S32 window_width = gViewerWindow->getWindowWidthRaw() ; + S32 window_height = gViewerWindow->getWindowHeightRaw() ; + F32 window_aspect_ratio = ((F32)window_width) / ((F32)window_height); - if (mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot")) + if (mAspectRatio > window_aspect_ratio) { - if (image_aspect_ratio > window_aspect_ratio) - { - // trim off top and bottom - S32 new_height = llround((F32)getRect().getWidth() / image_aspect_ratio); - rect.mBottom += (getRect().getHeight() - new_height) / 2; - rect.mTop -= (getRect().getHeight() - new_height) / 2; - } - else if (image_aspect_ratio < window_aspect_ratio) - { - // trim off left and right - S32 new_width = llround((F32)getRect().getHeight() * image_aspect_ratio); - rect.mLeft += (getRect().getWidth() - new_width) / 2; - rect.mRight -= (getRect().getWidth() - new_width) / 2; - } + // trim off top and bottom + S32 height_diff = llround(getRect().getHeight() - (F32)getRect().getWidth() / mAspectRatio); + S32 half_height_diff = llround((getRect().getHeight() - (F32)getRect().getWidth() / mAspectRatio) * 0.5); + rect.mBottom += half_height_diff; + rect.mTop -= height_diff - half_height_diff; + } + else if (mAspectRatio < window_aspect_ratio) + { + // trim off left and right + S32 width_diff = llround(getRect().getWidth() - (F32)getRect().getHeight() * mAspectRatio); + S32 half_width_diff = llround((getRect().getWidth() - (F32)getRect().getHeight() * mAspectRatio) * 0.5f); + rect.mLeft += half_width_diff; + rect.mRight -= width_diff - half_width_diff; } mShineAnimTimer.stop(); @@ -373,63 +525,55 @@ void LLSnapshotLivePreview::setSnapshotQuality(S32 quality) void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) { - F32 line_width ; - glGetFloatv(GL_LINE_WIDTH, &line_width) ; - glLineWidth(2.0f * line_width) ; - LLColor4 color(0.0f, 0.0f, 0.0f, 1.0f) ; - gl_rect_2d( mPreviewRect.mLeft + offset_x, mPreviewRect.mTop + offset_y, - mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ; - glLineWidth(line_width) ; - - //draw four alpha rectangles to cover areas outside of the snapshot image - if(!mKeepAspectRatio) + // Draw two alpha rectangles to cover areas outside of the snapshot image. + LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f); + if (mThumbnailWidth > mThumbnailPreviewRect.getWidth()) { - LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ; - S32 dwl = 0, dwr = 0 ; - if(mThumbnailWidth > mPreviewRect.getWidth()) - { - dwl = (mThumbnailWidth - mPreviewRect.getWidth()) >> 1 ; - dwr = mThumbnailWidth - mPreviewRect.getWidth() - dwl ; - - gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y, - mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ; - gl_rect_2d( mPreviewRect.mRight + offset_x, mPreviewRect.mTop + offset_y, - mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ; - } - - if(mThumbnailHeight > mPreviewRect.getHeight()) - { - S32 dh = (mThumbnailHeight - mPreviewRect.getHeight()) >> 1 ; - gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mBottom + offset_y , - mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ; - - dh = mThumbnailHeight - mPreviewRect.getHeight() - dh ; - gl_rect_2d( mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y + dh, - mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ; - } + gl_rect_2d( offset_x, offset_y, + mThumbnailPreviewRect.mLeft + offset_x, mThumbnailHeight + offset_y, + alpha_color, TRUE); + gl_rect_2d(mThumbnailPreviewRect.mRight + offset_x, offset_y, + mThumbnailWidth + offset_x, mThumbnailHeight + offset_y, + alpha_color, TRUE); } + if (mThumbnailHeight > mThumbnailPreviewRect.getHeight()) + { + gl_rect_2d( offset_x, offset_y, + mThumbnailWidth + offset_x, mThumbnailPreviewRect.mBottom + offset_y, + alpha_color, TRUE); + gl_rect_2d( offset_x, mThumbnailPreviewRect.mTop + offset_y, + mThumbnailWidth + offset_x, mThumbnailHeight + offset_y, + alpha_color, TRUE); + } + // Draw border around captured part. + F32 line_width; + glGetFloatv(GL_LINE_WIDTH, &line_width); + glLineWidth(2.0f * line_width); + gl_rect_2d( mThumbnailPreviewRect.mLeft + offset_x, mThumbnailPreviewRect.mTop + offset_y, + mThumbnailPreviewRect.mRight + offset_x, mThumbnailPreviewRect.mBottom + offset_y, + LLColor4::black, FALSE); + glLineWidth(line_width); } //called when the frame is frozen. void LLSnapshotLivePreview::draw() { - if (mViewerImage[mCurImageIndex].notNull() && - mPreviewImageEncoded.notNull() && - mSnapshotUpToDate) + if (mFullScreenPreviewTexture.notNull() && + mShowFreezeFrameSnapshot) { LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f); gl_rect_2d(getRect(), bg_color); - LLRect &rect = mImageRect[mCurImageIndex]; - LLRect shadow_rect = mImageRect[mCurImageIndex]; + LLRect const& rect = mFullScreenImageRect; + LLRect shadow_rect = mFullScreenImageRect; shadow_rect.stretch(BORDER_WIDTH); gl_drop_shadow(shadow_rect.mLeft, shadow_rect.mTop, shadow_rect.mRight, shadow_rect.mBottom, LLColor4(0.f, 0.f, 0.f, mNeedsFlash ? 0.f :0.5f), 10); LLColor4 image_color(1.f, 1.f, 1.f, 1.f); gGL.color4fv(image_color.mV); - gGL.getTexUnit(0)->bind(mViewerImage[mCurImageIndex]); + gGL.getTexUnit(0)->bind(mFullScreenPreviewTexture); // calculate UV scale - F32 uv_width = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mWidth[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f); - F32 uv_height = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mHeight[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f); + F32 uv_width = mFullScreenPreviewTextureNeedsScaling ? llmin((F32)mFormattedWidth / (F32)mFullScreenPreviewTexture->getWidth(), 1.f) : 1.f; + F32 uv_height = mFullScreenPreviewTextureNeedsScaling ? llmin((F32)mFormattedHeight / (F32)mFullScreenPreviewTexture->getHeight(), 1.f) : 1.f; gGL.pushMatrix(); { gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f); @@ -527,7 +671,7 @@ void LLSnapshotLivePreview::draw() { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4f(1.f, 1.f, 1.f, 1.f); - LLRect outline_rect = mImageRect[mCurImageIndex]; + LLRect outline_rect = mFullScreenImageRect; gGL.begin(LLRender::QUADS); { gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); @@ -556,22 +700,19 @@ void LLSnapshotLivePreview::draw() // draw old image dropping away if (mFallAnimTimer.getStarted()) { - S32 old_image_index = (mCurImageIndex + 1) % 2; - if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME) + if (mFallFullScreenPreviewTexture.notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME) { F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME; F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f); LLColor4 image_color(1.f, 1.f, 1.f, alpha); gGL.color4fv(image_color.mV); - gGL.getTexUnit(0)->bind(mViewerImage[old_image_index]); + gGL.getTexUnit(0)->bind(mFallFullScreenPreviewTexture); // calculate UV scale - // *FIX get this to work with old image - BOOL rescale = !mImageScaled[old_image_index] && mViewerImage[mCurImageIndex].notNull(); - F32 uv_width = rescale ? llmin((F32)mWidth[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f) : 1.f; - F32 uv_height = rescale ? llmin((F32)mHeight[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f) : 1.f; + F32 uv_width = mFallFullScreenPreviewTextureNeedsScaling ? llmin((F32)mFallWidth / (F32)mFallFullScreenPreviewTexture->getWidth(), 1.f) : 1.f; + F32 uv_height = mFallFullScreenPreviewTextureNeedsScaling ? llmin((F32)mFallHeight / (F32)mFallFullScreenPreviewTexture->getHeight(), 1.f) : 1.f; gGL.pushMatrix(); { - LLRect& rect = mImageRect[old_image_index]; + LLRect const& rect = mFallFullScreenImageRect; gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f); gGL.rotatef(-45.f * fall_interp, 0.f, 0.f, 1.f); gGL.begin(LLRender::QUADS); @@ -608,7 +749,7 @@ void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_pare BOOL LLSnapshotLivePreview::setThumbnailImageSize() { - if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10) + if(mWidth < 10 || mHeight < 10) { return FALSE ; } @@ -618,8 +759,8 @@ BOOL LLSnapshotLivePreview::setThumbnailImageSize() F32 window_aspect_ratio = ((F32)window_width) / ((F32)window_height); // UI size for thumbnail - S32 max_width = LLFloaterSnapshot::getUIWinWidth() - 20; - S32 max_height = 90; + S32 max_width = THUMBHEIGHT * 4 / 3; // == LLFloaterSnapshot::getUIWinWidth() - 7; + S32 max_height = THUMBHEIGHT; if (window_aspect_ratio > (F32)max_width / max_height) { @@ -640,49 +781,35 @@ BOOL LLSnapshotLivePreview::setThumbnailImageSize() } S32 left = 0 , top = mThumbnailHeight, right = mThumbnailWidth, bottom = 0 ; - if(!mKeepAspectRatio) + F32 ratio = mAspectRatio * window_height / window_width; + if(ratio > 1.f) { - F32 ratio_x = (F32)mWidth[mCurImageIndex] / window_width ; - F32 ratio_y = (F32)mHeight[mCurImageIndex] / window_height ; - - //if(mWidth[mCurImageIndex] > window_width || - // mHeight[mCurImageIndex] > window_height ) - { - if(ratio_x > ratio_y) - { - top = (S32)(top * ratio_y / ratio_x) ; - } - else - { - right = (S32)(right * ratio_x / ratio_y) ; - } - } - //else - //{ - // right = (S32)(right * ratio_x) ; - // top = (S32)(top * ratio_y) ; - //} - left = (S32)((mThumbnailWidth - right) * 0.5f) ; - bottom = (S32)((mThumbnailHeight - top) * 0.5f) ; - top += bottom ; - right += left ; + top = llround(top / ratio); } - mPreviewRect.set(left - 1, top + 1, right + 1, bottom - 1) ; + else + { + right = llround(right * ratio); + } + left = (mThumbnailWidth - right + 1) / 2; + bottom = (mThumbnailHeight - top + 1) / 2; + top += bottom ; + right += left ; + mThumbnailPreviewRect.set(left - 1, top + 1, right + 1, bottom - 1) ; return TRUE ; } -void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) +void LLSnapshotLivePreview::generateThumbnailImage(void) { if(mThumbnailUpdateLock) //in the process of updating { return ; } - if(mThumbnailUpToDate && !force_update)//already updated + if(mThumbnailUpToDate) //already updated { return ; } - if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10) + if(mWidth < 10 || mHeight < 10) { return ; } @@ -697,32 +824,30 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) return ; } - if(mThumbnailImage) - { - resetThumbnailImage() ; - } + Dout(dc::snapshot, "LLSnapshotLivePreview::generateThumbnailImage: Actually making a new thumbnail!"); + + mThumbnailImage = NULL; - LLPointer raw = NULL ; S32 w , h ; - w = get_lower_power_two(mThumbnailWidth, 512) * 2 ; - h = get_lower_power_two(mThumbnailHeight, 512) * 2 ; + // Set w, h to the nearest power of two that is larger or equal to mThumbnailWidth, mThumbnailHeight (but never more than 1024). + w = get_lower_power_two(mThumbnailWidth - 1, 512) * 2 ; // -1 so that w becomes mThumbnailWidth if it is a power of 2, instead of 2 * mThumbnailWidth. + h = get_lower_power_two(mThumbnailHeight - 1, 512) * 2 ; + LLPointer raw = new LLImageRaw ; + if(!gViewerWindow->thumbnailSnapshot(raw, + w, h, + gSavedSettings.getBOOL("RenderUIInSnapshot"), + FALSE, + mSnapshotBufferType) ) { - raw = new LLImageRaw ; - if(!gViewerWindow->thumbnailSnapshot(raw, - w, h, - gSavedSettings.getBOOL("RenderUIInSnapshot"), - FALSE, - mSnapshotBufferType) ) - { - raw = NULL ; - } + raw = NULL ; } if(raw) { mThumbnailImage = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); mThumbnailUpToDate = TRUE ; + Dout(dc::snapshot, "thumbnailSnapshot(" << w << ", " << h << ", ...) returns " << raw->getWidth() << ", " << raw->getHeight()); } //unlock updating @@ -733,10 +858,8 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) // Called often. Checks whether it's time to grab a new snapshot and if so, does it. // Returns TRUE if new snapshot generated, FALSE otherwise. //static -BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) +BOOL LLSnapshotLivePreview::onIdle(LLSnapshotLivePreview* previewp) { - LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview; - LLVector3 new_camera_pos = LLViewerCamera::getInstance()->getOrigin(); LLQuaternion new_camera_rot = LLViewerCamera::getInstance()->getQuaternion(); static const LLCachedControl freeze_time("FreezeTime",false); @@ -745,6 +868,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) { previewp->mCameraPos = new_camera_pos; previewp->mCameraRot = new_camera_rot; + previewp->showFreezeFrameSnapshot(false); // request a new snapshot whenever the camera moves, with a time delay BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot"); previewp->updateSnapshot( @@ -753,343 +877,717 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f); // shutter delay if 1st arg is true. } - // see if it's time yet to snap the shot and bomb out otherwise. + // See if it's time yet to snap the shot and bomb out otherwise. previewp->mSnapshotActive = (previewp->mSnapshotDelayTimer.getStarted() && previewp->mSnapshotDelayTimer.hasExpired()) && !LLToolCamera::getInstance()->hasMouseCapture(); // don't take snapshots while ALT-zoom active - if ( ! previewp->mSnapshotActive) + if (!previewp->mSnapshotActive) { + if (previewp->mFormattedDelayTimer.getStarted() && previewp->mFormattedDelayTimer.hasExpired()) + { + previewp->mFormattedDelayTimer.stop(); + LLFloaterSnapshot::updateControls(); + } return FALSE; } - // time to produce a snapshot + // Time to produce a snapshot. - if (!previewp->mPreviewImage) - { - previewp->mPreviewImage = new LLImageRaw; - } + // Reset Feed and Postcard Aspect to Default. + LLFloaterSnapshot::resetFeedAndPostcardAspect(); - if (!previewp->mPreviewImageEncoded) + if (!previewp->mRawSnapshot) { - previewp->mPreviewImageEncoded = new LLImageRaw; + previewp->mRawSnapshot = new LLImageRaw; } previewp->setVisible(FALSE); previewp->setEnabled(FALSE); previewp->getWindow()->incBusyCount(); - previewp->mImageScaled[previewp->mCurImageIndex] = FALSE; - // grab the raw image and encode it into desired format - if(gViewerWindow->rawSnapshot( - previewp->mPreviewImage, - previewp->mWidth[previewp->mCurImageIndex], - previewp->mHeight[previewp->mCurImageIndex], - previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"), - previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE, - gSavedSettings.getBOOL("RenderUIInSnapshot"), + // Grab the raw image and encode it into desired format. + Dout(dc::snapshot, "LLSnapshotLivePreview::onIdle: Actually making a new snapshot!"); + + // This should never happen, but well. If it's true then that means that the + // snapshot floater is disabled. Incrementing sSnapshotIndex will cause the + // callbacks to be ignored, so we better make sure that the floater is enabled. + if (previewp->mCloseCalled) + { + previewp->mCloseCalled->setEnabled(TRUE); + previewp->mCloseCalled->setVisible(TRUE); + } + previewp->sSnapshotIndex++; + Dout(dc::snapshot, "sSnapshotIndex is now " << previewp->sSnapshotIndex << "; mOutstandingCallbacks reset to 0."); + previewp->mOutstandingCallbacks = 0; // There are no outstanding callbacks for THIS snapshot. + previewp->mSaveFailures = 0; // There were no upload failures (or attempts for that matter) for this snapshot. + + previewp->mFormattedImage = NULL; + previewp->mFormattedUpToDate = false; + previewp->mUsedBy = 0; // This snapshot wasn't used yet. + previewp->mManualSizeOverride = 0; + previewp->mThumbnailUpToDate = FALSE; + + // Remember with what parameters this snapshot was taken. + previewp->mRawSnapshotRenderUI = gSavedSettings.getBOOL("RenderUIInSnapshot"); + previewp->mRawSnapshotRenderHUD = gSavedSettings.getBOOL("RenderHUDInSnapshot"); + previewp->mRawSnapshotBufferType = previewp->mSnapshotBufferType; + previewp->mRawSnapshotAspectRatio = previewp->mAspectRatio; + // Mark that the those values do not represent the current snapshot (yet). + previewp->mRawSnapshotWidth = 0; + previewp->mRawSnapshotHeight = 1; // Avoid division by zero when calculation an aspect in LLSnapshotLivePreview::getAspectSizeProblem. + + if (gViewerWindow->rawRawSnapshot( + previewp->mRawSnapshot, + previewp->mWidth, + previewp->mHeight, + previewp->mRawSnapshotAspectRatio, + previewp->mRawSnapshotRenderUI, FALSE, - previewp->mSnapshotBufferType, + previewp->mRawSnapshotBufferType, previewp->getMaxImageSize())) { - previewp->mPreviewImageEncoded->resize( - previewp->mPreviewImage->getWidth(), - previewp->mPreviewImage->getHeight(), - previewp->mPreviewImage->getComponents()); + // On success, cache the size of the raw snapshot. + previewp->mRawSnapshotWidth = previewp->mRawSnapshot->getWidth(); + previewp->mRawSnapshotHeight = previewp->mRawSnapshot->getHeight(); + Dout(dc::snapshot, "Created a new raw snapshot of size " << previewp->mRawSnapshotWidth << "x" << previewp->mRawSnapshotHeight); - if(previewp->getSnapshotType() == SNAPSHOT_TEXTURE) + previewp->mPosTakenGlobal = gAgentCamera.getCameraPositionGlobal(); + EAspectSizeProblem ret = previewp->generateFormattedAndFullscreenPreview(); + // If the required size is too large, we might have to scale up one dimension... So that is ok. + // For example, if the target is 1000x1000 and the aspect is set to 8:1, then the required + // raw snapshot would be 8000x1000, but since 8000 is too large it would end up being only + // 6144x768 (since 6144 is the maximum) and we'll have to stretch the 768 to 1000. + llassert(previewp->mFormattedUpToDate || ret == SIZE_TOO_LARGE || ret == ENCODING_FAILED); + if (!previewp->mFormattedUpToDate && ret == SIZE_TOO_LARGE) { - LLPointer formatted = new LLImageJ2C; - LLPointer scaled = new LLImageRaw( - previewp->mPreviewImage->getData(), - previewp->mPreviewImage->getWidth(), - previewp->mPreviewImage->getHeight(), - previewp->mPreviewImage->getComponents()); - - scaled->biasedScaleToPowerOfTwo(512); - previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; - if (formatted->encode(scaled, 0.f)) - { - previewp->mDataSize = formatted->getDataSize(); - formatted->decode(previewp->mPreviewImageEncoded, 0); - } - } - else - { - // delete any existing image - previewp->mFormattedImage = NULL; - // now create the new one of the appropriate format. - // note: postcards hardcoded to use jpeg always. - LLFloaterSnapshot::ESnapshotFormat format = previewp->getSnapshotType() == SNAPSHOT_POSTCARD - ? LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG : previewp->getSnapshotFormat(); - switch(format) - { - case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG: - previewp->mFormattedImage = new LLImagePNG(); - break; - case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG: - previewp->mFormattedImage = new LLImageJPEG(previewp->mSnapshotQuality); - break; - case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP: - previewp->mFormattedImage = new LLImageBMP(); - break; - } - if (previewp->mFormattedImage->encode(previewp->mPreviewImage, 0)) - { - previewp->mDataSize = previewp->mFormattedImage->getDataSize(); - // special case BMP to copy instead of decode otherwise decode will crash. - if(format == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP) - { - previewp->mPreviewImageEncoded->copy(previewp->mPreviewImage); - } - else - { - previewp->mFormattedImage->decode(previewp->mPreviewImageEncoded, 0); - } - } + // ENCODING_FAILED was already reported. + LLNotificationsUtil::add("ErrorSizeAspectSnapshot"); } + } - LLPointer scaled = new LLImageRaw( - previewp->mPreviewImageEncoded->getData(), - previewp->mPreviewImageEncoded->getWidth(), - previewp->mPreviewImageEncoded->getHeight(), - previewp->mPreviewImageEncoded->getComponents()); - - if(!scaled->isBufferInvalid()) - { - // leave original image dimensions, just scale up texture buffer - if (previewp->mPreviewImageEncoded->getWidth() > 1024 || previewp->mPreviewImageEncoded->getHeight() > 1024) - { - // go ahead and shrink image to appropriate power of 2 for display - scaled->biasedScaleToPowerOfTwo(1024); - previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; - } - else - { - // expand image but keep original image data intact - scaled->expandToPowerOfTwo(1024, FALSE); - } - - previewp->mViewerImage[previewp->mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE); - LLPointer curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex]; - gGL.getTexUnit(0)->bind(curr_preview_image); - if (previewp->getSnapshotType() != SNAPSHOT_TEXTURE) - { - curr_preview_image->setFilteringOption(LLTexUnit::TFO_POINT); - } - else - { - curr_preview_image->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); - } - curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP); - - previewp->mSnapshotUpToDate = TRUE; - //Resize to thumbnail. - { - previewp->mThumbnailUpToDate = TRUE ; - previewp->mThumbnailUpdateLock = TRUE ; - S32 w = get_lower_power_two(scaled->getWidth(), 512) * 2 ; - S32 h = get_lower_power_two(scaled->getHeight(), 512) * 2 ; - scaled->scale(w,h); - previewp->mThumbnailImage = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE); - previewp->mThumbnailUpdateLock = FALSE ; - previewp->setThumbnailImageSize(); - } - - previewp->mPosTakenGlobal = gAgentCamera.getCameraPositionGlobal(); - previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame - } - } previewp->getWindow()->decBusyCount(); - // only show fullscreen preview when in freeze frame mode - previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame")); + + // Only show fullscreen preview when in freeze frame mode. + previewp->setVisible(gSavedSettings.getBOOL("FreezeTime")); previewp->mSnapshotDelayTimer.stop(); previewp->mSnapshotActive = FALSE; - - if(!previewp->getThumbnailUpToDate()) - { - previewp->generateThumbnailImage() ; - } + previewp->generateThumbnailImage(); return TRUE; } +LLSnapshotLivePreview::EAspectSizeProblem LLSnapshotLivePreview::getAspectSizeProblem(S32& width_out, S32& height_out, bool& crop_vertically_out, S32& crop_offset_out) +{ + S32 const window_width = gViewerWindow->getWindowWidthRaw(); + S32 const window_height = gViewerWindow->getWindowHeightRaw(); + + // We need an image with the aspect mAspectRatio (from which mWidth and mHeight were derived). + + // The current aspect ratio of mRawSnapshot is: + F32 const raw_aspect = (F32)mRawSnapshotWidth / mRawSnapshotHeight; + // The smaller dimension might have been rounded up to 0.5 up or down. Calculate upper and lower limits. + F32 lower_raw_aspect; + F32 upper_raw_aspect; + if (mRawSnapshotWidth < mRawSnapshotHeight) + { + lower_raw_aspect = (mRawSnapshotWidth - 0.5) / mRawSnapshotHeight; + upper_raw_aspect = (mRawSnapshotWidth + 0.5) / mRawSnapshotHeight; + } + else + { + lower_raw_aspect = mRawSnapshotWidth / (mRawSnapshotHeight + 0.5); + upper_raw_aspect = mRawSnapshotWidth / (mRawSnapshotHeight - 0.5); + } + // Find out if mRawSnapshot was cropped already. + bool const allow_vertical_crop = window_height * raw_aspect >= window_width; // mRawSnapshot was cropped horizontally. + bool const allow_horizontal_crop = window_width / raw_aspect >= window_height; // mRawSnapshot was cropped vertically. + crop_vertically_out = true; // Prefer this, as it is faster. + crop_offset_out = 0; // The number of columns or rows to cut off on the left or bottom. + // Construct a rectangle size w,h that fits inside mRawSnapshot but has the correct aspect. + width_out = mRawSnapshotWidth; + height_out = mRawSnapshotHeight; + if (mAspectRatio < lower_raw_aspect) + { + width_out = llround(width_out * mAspectRatio / raw_aspect); + if (width_out < mRawSnapshotWidth) + { + // Only set this to false when there is actually something to crop. + crop_vertically_out = false; + if (!allow_horizontal_crop) + { + Dout(dc::snapshot, "NOT up to date: required aspect " << mAspectRatio << + " is less than the (lower) raw aspect " << lower_raw_aspect << " which is already vertically cropped."); + return CANNOT_CROP_HORIZONTALLY; + } + crop_offset_out = (mRawSnapshotWidth - width_out) / 2; + } + } + else if (mAspectRatio > upper_raw_aspect) + { + height_out = llround(height_out * raw_aspect / mAspectRatio); + if (height_out < mRawSnapshotHeight) + { + if (!allow_vertical_crop) + { + Dout(dc::snapshot, "NOT up to date: required aspect " << mAspectRatio << + " is larger than the (upper) raw aspect " << upper_raw_aspect << " which is already horizontally cropped."); + return CANNOT_CROP_VERTICALLY; + } + crop_offset_out = (mRawSnapshotHeight - height_out) / 2; + } + } + // Never allow upscaling of the existing snapshot, of course. + if (mWidth > width_out || mHeight > height_out) + { + Dout(dc::snapshot, "NOT up to date: required target size " << mWidth << "x" << mHeight << + " is larger than (cropped) raw snapshot with size " << width_out << "x" << height_out << "!"); + return SIZE_TOO_LARGE; + } + // Do not allow any resizing for target images that are equal or larger than the current window, when the target is the harddisk. + // If the target size is smaller, than a resize would occur anyway, so in that case we allow resizing whatever we have, + // unless the aspect is different in which case we have to allow resizing in one direction. + if (mSnapshotType == SNAPSHOT_LOCAL && (mWidth >= window_width || mHeight >= window_height) && mWidth != width_out && mHeight != height_out) + { + Dout(dc::snapshot, "NOT up to date: required target size " << mWidth << "x" << mHeight << + " is larger or equal the window size (" << window_width << "x" << window_height << ")" + " but unequal the (cropped) raw snapshot size (" << width_out << "x" << height_out << ")" + " and target is disk!"); + return CANNOT_RESIZE; + } + return ASPECTSIZE_OK; +} + +LLSnapshotLivePreview::EAspectSizeProblem LLSnapshotLivePreview::generateFormattedAndFullscreenPreview(bool delayed) +{ + DoutEntering(dc::snapshot, "LLSnapshotLivePreview::generateFormattedAndFullscreenPreview(" << delayed << ")"); + mFormattedUpToDate = false; + + S32 w, h, crop_offset; + bool crop_vertically; + EAspectSizeProblem ret = getAspectSizeProblem(w, h, crop_vertically, crop_offset); + if (ret != ASPECTSIZE_OK) + { + // Current raw snapshot cannot be used. + return ret; + } + + // Determine the required format. + LLFloaterSnapshot::ESnapshotFormat format; + switch (mSnapshotType) + { + case SNAPSHOT_FEED: + // Feeds hardcoded to always use png. + format = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; + break; + case SNAPSHOT_POSTCARD: + // Postcards hardcoded to always use jpeg. + format = LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG; + break; + case SNAPSHOT_TEXTURE: + format = LLFloaterSnapshot::SNAPSHOT_FORMAT_J2C; + break; + case SNAPSHOT_LOCAL: + format = mSnapshotFormat; + break; + default: + format = mSnapshotFormat; + break; + } + + if (mFormattedImage && + mFormattedWidth == mWidth && + mFormattedHeight == mHeight && + mFormattedRawWidth == w && + mFormattedRawHeight == h && + mFormattedCropOffset == crop_offset && + mFormattedCropVertically == crop_vertically && + mFormattedSnapshotFormat == format && + (mFormattedSnapshotQuality == mSnapshotQuality || + format != LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG)) + { + Dout(dc::snapshot, "Already up to date."); + mFormattedUpToDate = true; + return ret; + } + +#ifdef CWDEBUG + if (!mFormattedImage) + { + Dout(dc::snapshot, "mFormattedImage == NULL!"); + } + else + { + if (mFormattedWidth != mWidth) + Dout(dc::snapshot, "Target width changed from " << mFormattedWidth << " to " << mWidth); + if (mFormattedHeight != mHeight) + Dout(dc::snapshot, "Target height changed from " << mFormattedHeight << " to " << mHeight); + if (mFormattedRawWidth != w) + Dout(dc::snapshot, "Cropped (raw) width changed from " << mFormattedRawWidth << " to " << w); + if (mFormattedRawHeight != h) + Dout(dc::snapshot, "Cropped (raw) height changed from " << mFormattedRawHeight << " to " << h); + if (mFormattedCropOffset != crop_offset) + Dout(dc::snapshot, "Crop offset changed from " << mFormattedCropOffset << " to " << crop_offset); + if (mFormattedCropVertically != crop_vertically) + Dout(dc::snapshot, "Crop direction changed from " << (mFormattedCropVertically ? "vertical" : "horizontal") << " to " << (crop_vertically ? "vertical" : "horizontal")); + if (mFormattedSnapshotFormat != format) + Dout(dc::snapshot, "Format changed from " << mFormattedSnapshotFormat << " to " << format); + if (!(mFormattedSnapshotQuality == mSnapshotQuality || format != LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG)) + Dout(dc::snapshot, "Format is JPEG and quality changed from " << mFormattedSnapshotQuality << " to " << mSnapshotQuality); + } +#endif + + if (delayed) + { + // Just set mFormattedUpToDate. + Dout(dc::snapshot, "NOT up to date, but delayed. Returning."); + return DELAYED; + } + + if (!mRawSnapshot) + { + Dout(dc::snapshot, "No raw snapshot exists."); + return NO_RAW_IMAGE; + } + + Dout(dc::snapshot, "Generating a new formatted image!"); + + mFormattedWidth = mWidth; + mFormattedHeight = mHeight; + mFormattedRawWidth = w; + mFormattedRawHeight = h; + mFormattedCropOffset = crop_offset; + mFormattedCropVertically = crop_vertically; + mFormattedSnapshotFormat = format; + mFormattedSnapshotQuality = mSnapshotQuality; + + // Served, so no need to call this again. + mFormattedDelayTimer.stop(); + + // A cropped copy of raw snapshot is put in 'scaled', which then is + // scaled to the target size (or a close power of two in the case + // of textures) and then encoded to 'formatted' of the same size. + LLPointer scaled = new LLImageRaw(mRawSnapshot, w, h, crop_offset, crop_vertically); + + // Subsequently, 'formatted' is decoded into 'decoded' again, + // to serve the full screen preview. + LLPointer decoded = new LLImageRaw; + + // Scale 'scaled' and allocate the correct image format. + if (mSnapshotType == SNAPSHOT_TEXTURE) + { + // 'scaled' must be a power of two. + scaled->biasedScaleToPowerOfTwo(mWidth, mHeight, 512); + } + else + { + // 'scaled' is just the target size. + scaled->scale(mWidth, mHeight); + } + + bool lossless = false; + switch(format) + { + case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG: + mFormattedImage = new LLImagePNG; + lossless = true; + break; + case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG: + mFormattedImage = new LLImageJPEG(mSnapshotQuality); + break; + case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP: + mFormattedImage = new LLImageBMP; + lossless = true; + break; + case LLFloaterSnapshot::SNAPSHOT_FORMAT_J2C: + mFormattedImage = new LLImageJ2C; + break; + } + + // Encode the scaled snapshot into 'mFormatted' for save/upload. + if (mFormattedImage->encode(scaled, 0)) + { + mFormattedDataSize = mFormattedImage->getDataSize(); + if (!lossless) + { + // decoded must be pre-allocated. + decoded->resize( + mFormattedImage->getWidth(), + mFormattedImage->getHeight(), + mFormattedImage->getComponents()); + mFormattedImage->decode(decoded, 0); + } + } + else + { + // Mark formatted image size as unknown. + mFormattedDataSize = 0; + // Disable upload/save button. + mFormattedImage = NULL; + ret = ENCODING_FAILED; + LLNotificationsUtil::add("ErrorEncodingSnapshot"); + } + + // Generate mFullScreenPreviewTexture + + // Copy 'decoded' into 'scaled'. + if (!lossless) // Otherwise scaled is already "decoded". + { + scaled = NULL; // Free memory before allocating new image. + scaled = new LLImageRaw( + decoded->getData(), + decoded->getWidth(), + decoded->getHeight(), + decoded->getComponents()); + } + + // Generate mFullScreenPreviewTexture from 'scaled'. + if (!scaled->isBufferInvalid()) + { + // Leave original image dimensions, just scale up texture buffer. + if (scaled->getWidth() > 1024 || scaled->getHeight() > 1024) + { + // Go ahead and shrink image to appropriate power of two for display. + scaled->biasedScaleToPowerOfTwo(1024); + mFullScreenPreviewTextureNeedsScaling = FALSE; + } + else + { + // Expand image but keep original image data intact. + scaled->expandToPowerOfTwo(1024, FALSE); + mFullScreenPreviewTextureNeedsScaling = TRUE; + } + mFullScreenPreviewTexture = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE); + LLPointer curr_preview_texture = mFullScreenPreviewTexture; + gGL.getTexUnit(0)->bind(curr_preview_texture); + if (mSnapshotType != SNAPSHOT_TEXTURE) + { + curr_preview_texture->setFilteringOption(LLTexUnit::TFO_POINT); + } + else + { + curr_preview_texture->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); + } + curr_preview_texture->setAddressMode(LLTexUnit::TAM_CLAMP); + + showFreezeFrameSnapshot(TRUE); + + mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame + } + + // Return success if mFormattedImage was succesfully generated. + mFormattedUpToDate = mFormattedImage; + return ret; +} + void LLSnapshotLivePreview::setSize(S32 w, S32 h) { - mWidth[mCurImageIndex] = w; - mHeight[mCurImageIndex] = h; + mWidth = w; + mHeight = h; } void LLSnapshotLivePreview::getSize(S32& w, S32& h) const { - w = mWidth[mCurImageIndex]; - h = mHeight[mCurImageIndex]; + w = mWidth; + h = mHeight; +} + +void LLSnapshotLivePreview::setAspect(F32 a) +{ + mAspectRatio = a; +} + +F32 LLSnapshotLivePreview::getAspect() const +{ + return mAspectRatio; +} + +void LLSnapshotLivePreview::getRawSize(S32& w, S32& h) const +{ + w = mRawSnapshotWidth; + h = mRawSnapshotHeight; +} + +LLFloaterFeed* LLSnapshotLivePreview::getCaptionAndSaveFeed() +{ + if (mCloseCalled) + { + return NULL; + } + + ++mOutstandingCallbacks; + mSaveFailures = 0; + addUsedBy(SNAPSHOT_FEED); + Dout(dc::snapshot, "LLSnapshotLivePreview::getCaptionAndSaveFeed: sSnapshotIndex = " << sSnapshotIndex << "; mOutstandingCallbacks = " << mOutstandingCallbacks << "."); + + if (mFullScreenPreviewTexture.isNull()) + { + // This should never happen! + llwarns << "The snapshot image has not been generated!" << llendl; + saveDone(SNAPSHOT_FEED, false, sSnapshotIndex); + return NULL; + } + + // Calculate and pass in image scale in case image data only uses portion of viewerimage buffer. + F32 uv_width = mFullScreenPreviewTextureNeedsScaling ? llmin((F32)mFormattedWidth / (F32)mFullScreenPreviewTexture->getWidth(), 1.f) : 1.f; + F32 uv_height = mFullScreenPreviewTextureNeedsScaling ? llmin((F32)mFormattedHeight / (F32)mFullScreenPreviewTexture->getHeight(), 1.f) : 1.f; + LLVector2 image_scale(uv_width, uv_height); + + LLImagePNG* png = dynamic_cast(mFormattedImage.get()); + if (!png) + { + llwarns << "Formatted image not a PNG" << llendl; + saveDone(SNAPSHOT_FEED, false, sSnapshotIndex); + return NULL; + } + + LLFloaterFeed* floater = LLFloaterFeed::showFromSnapshot(png, mFullScreenPreviewTexture, image_scale, sSnapshotIndex); + + return floater; } LLFloaterPostcard* LLSnapshotLivePreview::savePostcard() { - if(mViewerImage[mCurImageIndex].isNull()) + if (mCloseCalled) + { + return NULL; + } + + ++mOutstandingCallbacks; + mSaveFailures = 0; + addUsedBy(SNAPSHOT_POSTCARD); + Dout(dc::snapshot, "LLSnapshotLivePreview::savePostcard: sSnapshotIndex = " << sSnapshotIndex << "; mOutstandingCallbacks = " << mOutstandingCallbacks << "."); + + if(mFullScreenPreviewTexture.isNull()) { //this should never happen!! llwarns << "The snapshot image has not been generated!" << llendl ; + saveDone(SNAPSHOT_POSTCARD, false, sSnapshotIndex); return NULL ; } // calculate and pass in image scale in case image data only use portion // of viewerimage buffer - LLVector2 image_scale(1.f, 1.f); - if (!isImageScaled()) - { - image_scale.setVec(llmin(1.f, (F32)mWidth[mCurImageIndex] / (F32)getCurrentImage()->getWidth()), llmin(1.f, (F32)mHeight[mCurImageIndex] / (F32)getCurrentImage()->getHeight())); - } + // calculate UV scale + F32 uv_width = mFullScreenPreviewTextureNeedsScaling ? llmin((F32)mFormattedWidth / (F32)mFullScreenPreviewTexture->getWidth(), 1.f) : 1.f; + F32 uv_height = mFullScreenPreviewTextureNeedsScaling ? llmin((F32)mFormattedHeight / (F32)mFullScreenPreviewTexture->getHeight(), 1.f) : 1.f; + LLVector2 image_scale(uv_width, uv_height); LLImageJPEG* jpg = dynamic_cast(mFormattedImage.get()); if(!jpg) { llwarns << "Formatted image not a JPEG" << llendl; + saveDone(SNAPSHOT_POSTCARD, false, sSnapshotIndex); return NULL; } - LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(jpg, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal); - // relinquish lifetime of jpeg image to postcard floater - mFormattedImage = NULL; - mDataSize = 0; - updateSnapshot(FALSE, FALSE); + LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(jpg, mFullScreenPreviewTexture, image_scale, mPosTakenGlobal, sSnapshotIndex); return floater; } +class saveTextureUserData { +public: + saveTextureUserData(LLSnapshotLivePreview* self, int index, bool temporary) : mSelf(self), mSnapshotIndex(index), mTemporary(temporary) { } + LLSnapshotLivePreview* mSelf; + int mSnapshotIndex; + bool mTemporary; +}; + void LLSnapshotLivePreview::saveTexture() { + if (mCloseCalled) + { + return; + } + + ++mOutstandingCallbacks; + mSaveFailures = 0; + addUsedBy(SNAPSHOT_TEXTURE); + Dout(dc::snapshot, "LLSnapshotLivePreview::saveTexture: sSnapshotIndex = " << sSnapshotIndex << "; mOutstandingCallbacks = " << mOutstandingCallbacks << "."); + saveStart(sSnapshotIndex); + // gen a new uuid for this asset LLTransactionID tid; tid.generate(); LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); - - LLPointer formatted = new LLImageJ2C; - LLPointer scaled = new LLImageRaw(mPreviewImage->getData(), - mPreviewImage->getWidth(), - mPreviewImage->getHeight(), - mPreviewImage->getComponents()); - - scaled->biasedScaleToPowerOfTwo(512); - - if (formatted->encode(scaled, 0.0f)) + LLVFile::writeFile(mFormattedImage->getData(), mFormattedImage->getDataSize(), gVFS, new_asset_id, LLAssetType::AT_TEXTURE); + std::string pos_string; + LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL); + std::string who_took_it; + LLAgentUI::buildFullname(who_took_it); + LLAssetStorage::LLStoreAssetCallback callback = &LLSnapshotLivePreview::saveTextureDone; + S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + saveTextureUserData* user_data = new saveTextureUserData(this, sSnapshotIndex, gSavedSettings.getBOOL("TemporaryUpload")); + if (!upload_new_resource(tid, // tid + LLAssetType::AT_TEXTURE, + "Snapshot : " + pos_string, + "Taken by " + who_took_it + " at " + pos_string, + 0, + LLFolderType::FT_SNAPSHOT_CATEGORY, + LLInventoryType::IT_SNAPSHOT, + PERM_ALL, // Note: Snapshots to inventory is a special case of content upload + LLFloaterPerms::getGroupPerms(), // that is more permissive than other uploads + LLFloaterPerms::getEveryonePerms(), + "Snapshot : " + pos_string, + callback, expected_upload_cost, user_data, &LLSnapshotLivePreview::saveTextureDone2)) { - LLVFile::writeFile(formatted->getData(), formatted->getDataSize(), gVFS, new_asset_id, LLAssetType::AT_TEXTURE); - std::string pos_string; - LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL); - std::string who_took_it; - LLAgentUI::buildFullname(who_took_it); - LLAssetStorage::LLStoreAssetCallback callback = NULL; - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); - void *userdata = NULL; - upload_new_resource(tid, // tid - LLAssetType::AT_TEXTURE, - "Snapshot : " + pos_string, - "Taken by " + who_took_it + " at " + pos_string, - 0, - LLFolderType::FT_SNAPSHOT_CATEGORY, - LLInventoryType::IT_SNAPSHOT, - PERM_ALL, // Note: Snapshots to inventory is a special case of content upload - LLFloaterPerms::getGroupPerms(), // that is more permissive than other uploads - LLFloaterPerms::getEveryonePerms(), - "Snapshot : " + pos_string, - callback, expected_upload_cost, userdata); - gViewerWindow->playSnapshotAnimAndSound(); - } - else - { - LLNotificationsUtil::add("ErrorEncodingSnapshot"); - llwarns << "Error encoding snapshot" << llendl; + // Something went wrong. + delete user_data; + saveDone(SNAPSHOT_TEXTURE, false, sSnapshotIndex); } + gViewerWindow->playSnapshotAnimAndSound(); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT ); - - mDataSize = 0; } void LLSnapshotLivePreview::saveLocal() { - gViewerWindow->saveImageNumbered(mFormattedImage); + if (mCloseCalled) + { + return; + } - // Relinquish image memory. Save button will be disabled as a side-effect. - mFormattedImage = NULL; - mDataSize = 0; - updateSnapshot(FALSE, FALSE); + ++mOutstandingCallbacks; + mSaveFailures = 0; + addUsedBy(SNAPSHOT_LOCAL); + Dout(dc::snapshot, "LLSnapshotLivePreview::saveLocal: sSnapshotIndex = " << sSnapshotIndex << "; mOutstandingCallbacks = " << mOutstandingCallbacks << "."); + saveStart(sSnapshotIndex); + + gViewerWindow->saveImageNumbered(mFormattedImage, sSnapshotIndex); // This calls saveDone() immediately, or later. } -///---------------------------------------------------------------------------- -/// Class LLFloaterSnapshot::Impl -///---------------------------------------------------------------------------- - -class LLFloaterSnapshot::Impl +void LLSnapshotLivePreview::close(LLFloaterSnapshot* view) { -public: - Impl() - : mAvatarPauseHandles(), - mLastToolset(NULL) + DoutEntering(dc::snapshot, "LLSnapshotLivePreview::close(" << (void*)view << ") [mOutstandingCallbacks = " << mOutstandingCallbacks << "]"); + mCloseCalled = view; + if (!mOutstandingCallbacks) { + doCloseAfterSave(); } - ~Impl() + else { - //unpause avatars - mAvatarPauseHandles.clear(); - + view->setVisible(FALSE); + view->setEnabled(FALSE); } - static void onClickDiscard(void* data); - static void onClickKeep(void* data); - static void onCommitSave(LLUICtrl* ctrl, void* data); - static void onClickNewSnapshot(void* data); - static void onClickAutoSnap(LLUICtrl *ctrl, void* data); - //static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data); - static void onClickLess(void* data) ; - static void onClickMore(void* data) ; - static void onClickUICheck(LLUICtrl *ctrl, void* data); - static void onClickHUDCheck(LLUICtrl *ctrl, void* data); - static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data); - static void onClickKeepAspectCheck(LLUICtrl *ctrl, void* data); - static void onCommitQuality(LLUICtrl* ctrl, void* data); - static void onCommitResolution(LLUICtrl* ctrl, void* data) { updateResolution(ctrl, data); } - 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 onCommitSnapshotType(LLUICtrl* ctrl, void* data); - static void onCommitSnapshotFormat(LLUICtrl* ctrl, void* data); - static void onCommitCustomResolution(LLUICtrl *ctrl, void* data); - static void resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) ; - static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); +} - 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 updateResolutionTextEntry(LLFloaterSnapshot* floater); +void LLSnapshotLivePreview::saveStart(int index) +{ + if (index == sSnapshotIndex && gSavedSettings.getBOOL("CloseSnapshotOnKeep") && gSavedSettings.getBOOL("FreezeTime")) + { + // Turn off Freeze Time if we're going to close the floater + // anyway at the *start* of an upload/save attempt. + // + // The disadvantage is that if the upload fails then we lost the Frozen Scene. + // The user can still retry to upload or save the snapshot using the same size + // (or smaller) to disk. + // + // The advantage is that if for some reason the upload takes a long time, then + // the user can immediately continue with using the viewer instead of ending + // up with a frozen (haha) interface. - static LLHandle sPreviewHandle; - static BOOL sAspectRatioCheckOff ; - -private: - static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater); - static ESnapshotFormat getFormatIndex(LLFloaterSnapshot* floater); - 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) ; + LLFloaterSnapshot::Impl::freezeTime(false); + } +} -public: - std::vector mAvatarPauseHandles; +void LLSnapshotLivePreview::saveDone(ESnapshotType type, bool success, int index) +{ + DoutEntering(dc::snapshot, "LLSnapshotLivePreview::saveDone(" << type << ", " << success << ", " << index << ")"); - LLToolset* mLastToolset; -}; + if (sSnapshotIndex != index) + { + Dout(dc::snapshot, "sSnapshotIndex (" << sSnapshotIndex << ") != index (" << index << ")"); + + // The snapshot was already replaced, so this callback has nothing to do with us anymore. + if (!success) + { + llwarns << "Permanent failure to upload or save snapshot" << llendl; + } + return; + } + + --mOutstandingCallbacks; + Dout(dc::snapshot, "sSnapshotIndex = " << sSnapshotIndex << "; mOutstandingCallbacks = " << mOutstandingCallbacks << "."); + if (!success) + { + ++mSaveFailures; + // Enable Upload button. + delUsedBy(type); + LLFloaterSnapshot::updateControls(); + } + if (!mOutstandingCallbacks) + { + doCloseAfterSave(); + } +} + +// This callback is only used for the *legacy* LLViewerAssetStorage::storeAssetData +// (when the cap NewFileAgentInventory is not available) and temporaries. +// See upload_new_resource. +//static +void LLSnapshotLivePreview::saveTextureDone(LLUUID const& asset_id, void* user_data, S32 status, LLExtStat ext_status) +{ + LLResourceData* resource_data = (LLResourceData*)user_data; + + bool success = status == LL_ERR_NOERR; + if (!success) + { + LLSD args; + args["REASON"] = std::string(LLAssetStorage::getErrorString(status)); + LLNotificationsUtil::add("UploadSnapshotFail", args); + } + saveTextureUserData* data = (saveTextureUserData*)resource_data->mUserData; + bool temporary = data->mTemporary; + data->mSelf->saveDone(SNAPSHOT_TEXTURE, success, data->mSnapshotIndex); + delete data; + + // Call the default call back. + LLAssetStorage::LLStoreAssetCallback asset_callback = temporary ? &temp_upload_callback : &upload_done_callback; + (*asset_callback)(asset_id, user_data, status, ext_status); +} + +// This callback used when the capability NewFileAgentInventory is available and it wasn't a temporary. +// See upload_new_resource. +//static +void LLSnapshotLivePreview::saveTextureDone2(bool success, void* user_data) +{ + saveTextureUserData* data = (saveTextureUserData*)user_data; + data->mSelf->saveDone(SNAPSHOT_TEXTURE, success, data->mSnapshotIndex); + delete data; +} + +void LLSnapshotLivePreview::doCloseAfterSave() +{ + if (!mCloseCalled) + { + return; + } + if (!mSaveFailures && gSavedSettings.getBOOL("CloseSnapshotOnKeep")) + { + // Relinquish image memory. + mFormattedImage = NULL; + mFormattedUpToDate = false; + mFormattedDataSize = 0; + updateSnapshot(FALSE, FALSE); + mCloseCalled->close(); + } + else + { + mCloseCalled->setEnabled(TRUE); + mCloseCalled->setVisible(TRUE); + gFloaterView->bringToFront(mCloseCalled); + mCloseCalled = NULL; + } +} + +//---------------------------------------------------------------------------- +// LLFloaterSnapshot::Impl // static LLHandle LLFloaterSnapshot::Impl::sPreviewHandle; -//static -BOOL LLFloaterSnapshot::Impl::sAspectRatioCheckOff = FALSE ; - // static -LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater) +LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(void) { LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)sPreviewHandle.get(); return previewp; @@ -1098,10 +1596,12 @@ LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot // static LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getTypeIndex(LLFloaterSnapshot* floater) { - LLSnapshotLivePreview::ESnapshotType index = LLSnapshotLivePreview::SNAPSHOT_POSTCARD; + LLSnapshotLivePreview::ESnapshotType index = LLSnapshotLivePreview::SNAPSHOT_FEED; LLSD value = floater->childGetValue("snapshot_type_radio"); const std::string id = value.asString(); - if (id == "postcard") + if (id == "feed") + index = LLSnapshotLivePreview::SNAPSHOT_FEED; + else if (id == "postcard") index = LLSnapshotLivePreview::SNAPSHOT_POSTCARD; else if (id == "texture") index = LLSnapshotLivePreview::SNAPSHOT_TEXTURE; @@ -1126,80 +1626,87 @@ LLFloaterSnapshot::ESnapshotFormat LLFloaterSnapshot::Impl::getFormatIndex(LLFlo return index; } - - // static -LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater) +void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const std::string& comboname, bool visible, bool update_controls) { - LLViewerWindow::ESnapshotType type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; - LLSD value = floater->childGetValue("layer_types"); - const std::string id = value.asString(); - if (id == "colors") - type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; - else if (id == "depth") - type = LLViewerWindow::SNAPSHOT_TYPE_DEPTH; - return type; + LLComboBox* combo = floater->getChild(comboname); + combo->setVisible(visible); + updateResolution(combo, floater, update_controls); // to sync spinners with combo } // static -void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const std::string& comboname) +void LLFloaterSnapshot::Impl::setAspect(LLFloaterSnapshot* floater, const std::string& comboname, bool update_controls) { LLComboBox* combo = floater->getChild(comboname); - combo->setVisible(TRUE); - updateResolution(combo, floater, FALSE); // to sync spinners with combo + combo->setVisible(TRUE); + updateAspect(combo, floater, update_controls); // to sync spinner with combo +} + +//static +void LLFloaterSnapshot::Impl::resetFeedAndPostcardAspect(LLFloaterSnapshot* floaterp) +{ + floaterp->getChild("feed_aspect_combo")->setCurrentByIndex(0); // Default + gSavedSettings.setS32("SnapshotFeedLastAspect", 0); + + floaterp->getChild("postcard_aspect_combo")->setCurrentByIndex(0); // Default + gSavedSettings.setS32("SnapshotPostcardLastAspect", 0); } //static void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) { - LLSnapshotLivePreview* previewp = getPreviewView(floaterp); - - S32 delta_height = gSavedSettings.getBOOL("AdvanceSnapshot") ? 0 : floaterp->getUIWinHeightShort() - floaterp->getUIWinHeightLong() ; - - if(!gSavedSettings.getBOOL("AdvanceSnapshot")) //set to original window resolution + S32 delta_height = 0; + if (!gSavedSettings.getBOOL("AdvanceSnapshot")) { - previewp->mKeepAspectRatio = TRUE; + floaterp->getChild("feed_size_combo")->setCurrentByIndex(2); // 500x375 (4:3) + gSavedSettings.setS32("SnapshotFeedLastResolution", 2); - floaterp->getChild("postcard_size_combo")->setCurrentByIndex(0); + floaterp->getChild("postcard_size_combo")->setCurrentByIndex(0); // Current window gSavedSettings.setS32("SnapshotPostcardLastResolution", 0); - floaterp->getChild("texture_size_combo")->setCurrentByIndex(0); + resetFeedAndPostcardAspect(floaterp); + + floaterp->getChild("texture_size_combo")->setCurrentByIndex(0); // 512x512 (most likely result for current window). gSavedSettings.setS32("SnapshotTextureLastResolution", 0); + floaterp->getChild("texture_aspect_combo")->setCurrentByIndex(0); // Current window + gSavedSettings.setS32("SnapshotTextureLastAspect", 0); - floaterp->getChild("local_size_combo")->setCurrentByIndex(0); + floaterp->getChild("local_size_combo")->setCurrentByIndex(0); // Current window gSavedSettings.setS32("SnapshotLocalLastResolution", 0); + floaterp->getChild("local_aspect_combo")->setCurrentByIndex(0); // Current window + gSavedSettings.setS32("SnapshotLocalLastAspect", 0); - LLSnapshotLivePreview* previewp = getPreviewView(floaterp); - previewp->setSize(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); + updateControls(floaterp); + + delta_height = floaterp->getUIWinHeightShort() - floaterp->getUIWinHeightLong(); } + floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height); +} - bool use_freeze_frame = floaterp->childGetValue("freeze_frame_check").asBoolean(); - - if (use_freeze_frame) +//static +void LLFloaterSnapshot::Impl::freezeTime(bool on) +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + if (on) { - // stop all mouse events at fullscreen preview layer - floaterp->getParent()->setMouseOpaque(TRUE); - - // shrink to smaller layout - floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height); + // Stop all mouse events at fullscreen preview layer. + gSnapshotFloaterView->setMouseOpaque(TRUE); // can see and interact with fullscreen preview now if (previewp) { - previewp->setVisible(TRUE); previewp->setEnabled(TRUE); + previewp->setVisible(TRUE); } - //RN: freeze all avatars - LLCharacter* avatarp; + // Freeze all avatars. for (std::vector::iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) { - avatarp = *iter; - sInstance->impl.mAvatarPauseHandles.push_back(avatarp->requestPause()); + sInstance->impl.mAvatarPauseHandles.push_back((*iter)->requestPause()); } - // freeze everything else + // Freeze everything else. gSavedSettings.setBOOL("FreezeTime", TRUE); if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset) @@ -1207,23 +1714,37 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) sInstance->impl.mLastToolset = LLToolMgr::getInstance()->getCurrentToolset(); LLToolMgr::getInstance()->setCurrentToolset(gCameraToolset); } + + // Make sure the floater keeps focus so that pressing ESC stops Freeze Time mode. + sInstance->impl.mPrevDefaultKeyboardFocus = gFocusMgr.getDefaultKeyboardFocus(); + gFocusMgr.setDefaultKeyboardFocus(sInstance); } - else // turning off freeze frame mode + else if (gSavedSettings.getBOOL("FreezeTime")) // turning off freeze frame mode { - floaterp->getParent()->setMouseOpaque(FALSE); - floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height); + // Restore default keyboard focus. + gFocusMgr.setDefaultKeyboardFocus(sInstance->impl.mPrevDefaultKeyboardFocus); + sInstance->impl.mPrevDefaultKeyboardFocus = NULL; + + gSnapshotFloaterView->setMouseOpaque(FALSE); + if (previewp) { previewp->setVisible(FALSE); previewp->setEnabled(FALSE); } - //RN: thaw all avatars - sInstance->impl.mAvatarPauseHandles.clear(); - - // thaw everything else + // Thaw everything except avatars. gSavedSettings.setBOOL("FreezeTime", FALSE); + // Thaw all avatars. + LLVOAvatar* avatarp; + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) + { + avatarp = static_cast(*iter); + avatarp->resetFreezeTime(); + } + sInstance->impl.mAvatarPauseHandles.clear(); + // restore last tool (e.g. pie menu, etc) if (sInstance->impl.mLastToolset) { @@ -1238,15 +1759,21 @@ 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. // static -void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) +void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater, bool delayed_formatted) { + DoutEntering(dc::snapshot, "LLFloaterSnapshot::Impl::updateControls()"); std::string fee = gHippoGridManager->getConnectedGrid()->getUploadFee(); + if (gSavedSettings.getBOOL("TemporaryUpload")) + { + fee = fee.substr(0, fee.find_first_of("0123456789")) + "0"; + } floater->childSetLabelArg("upload_btn", "[UPLOADFEE]", fee); - + + LLSnapshotLivePreview::ESnapshotType shot_type = (LLSnapshotLivePreview::ESnapshotType)gSavedSettings.getS32("LastSnapshotType"); LLRadioGroup* snapshot_type_radio = floater->getChild("snapshot_type_radio"); if (snapshot_type_radio) { - snapshot_type_radio->setSelectedIndex(gSavedSettings.getS32("LastSnapshotType")); + snapshot_type_radio->setSelectedIndex(shot_type); const child_list_t *childs = snapshot_type_radio->getChildList(); if (childs) @@ -1262,122 +1789,128 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) } } } - LLSnapshotLivePreview::ESnapshotType shot_type = getTypeIndex(floater); - ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); //getFormatIndex(floater); LLViewerWindow::ESnapshotType layer_type = getLayerType(floater); - LLViewerWindow::ESnapshotType layer_type = getLayerType(floater); + ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); + floater->childSetVisible("feed_size_combo", FALSE); + floater->childSetVisible("feed_aspect_combo", FALSE); floater->childSetVisible("postcard_size_combo", FALSE); + floater->childSetVisible("postcard_aspect_combo", FALSE); floater->childSetVisible("texture_size_combo", FALSE); + floater->childSetVisible("texture_aspect_combo", FALSE); floater->childSetVisible("local_size_combo", FALSE); + floater->childSetVisible("local_aspect_combo", FALSE); - floater->getChild("postcard_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution")); - floater->getChild("texture_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution")); - floater->getChild("local_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution")); - floater->getChild("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat")); + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) + { + previewp->setSnapshotType(shot_type); + LLViewerWindow::ESnapshotType layer_type = + (shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL) ? + (LLViewerWindow::ESnapshotType)gSavedSettings.getS32("SnapshotLayerType") : + LLViewerWindow::SNAPSHOT_TYPE_COLOR; + // Do this before calling setResolution(). + previewp->setSnapshotBufferType(floater, layer_type); + } + BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot"); + switch(shot_type) + { + case LLSnapshotLivePreview::SNAPSHOT_FEED: + setResolution(floater, "feed_size_combo", is_advance, false); + break; + case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: + setResolution(floater, "postcard_size_combo", is_advance, false); + break; + case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: + setResolution(floater, "texture_size_combo", is_advance, false); + break; + case LLSnapshotLivePreview::SNAPSHOT_LOCAL: + setResolution(floater, "local_size_combo", is_advance, false); + break; + } + floater->getChild("local_format_combo")->selectNthItem(shot_format); floater->childSetVisible("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE); floater->childSetVisible("send_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD); + floater->childSetVisible("feed_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_FEED); floater->childSetVisible("save_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL); - floater->childSetEnabled("keep_aspect_check", shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE && !sAspectRatioCheckOff); floater->childSetEnabled("layer_types", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL); - BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot"); BOOL is_local = shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL; - BOOL show_slider = - shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD - || (is_local && shot_format == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG); + BOOL show_slider = + shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD || + (is_local && shot_format == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG); + floater->getChild(previewp->aspectComboName())->setVisible(is_advance); floater->childSetVisible("more_btn", !is_advance); // the only item hidden in advanced mode floater->childSetVisible("less_btn", is_advance); floater->childSetVisible("type_label2", is_advance); + floater->childSetVisible("type_label3", is_advance); floater->childSetVisible("format_label", is_advance && is_local); - floater->childSetVisible("local_format_combo", is_advance && is_local); + floater->childSetVisible("local_format_combo", is_local); floater->childSetVisible("layer_types", is_advance); floater->childSetVisible("layer_type_label", is_advance); + floater->childSetVisible("aspect_one_label", is_advance); floater->childSetVisible("snapshot_width", is_advance); floater->childSetVisible("snapshot_height", is_advance); - floater->childSetVisible("keep_aspect_check", is_advance); + floater->childSetVisible("aspect_ratio", is_advance); floater->childSetVisible("ui_check", is_advance); floater->childSetVisible("hud_check", is_advance); floater->childSetVisible("keep_open_check", is_advance); - floater->childSetVisible("freeze_frame_check", is_advance); + floater->childSetVisible("freeze_time_check", is_advance); floater->childSetVisible("auto_snapshot_check", is_advance); - floater->childSetVisible("image_quality_slider", is_advance && show_slider); + floater->childSetVisible("image_quality_slider", show_slider); floater->childSetVisible("temp_check", is_advance); - LLSnapshotLivePreview* previewp = getPreviewView(floater); BOOL got_bytes = previewp && previewp->getDataSize() > 0; - BOOL got_snap = previewp->getSnapshotUpToDate(); + BOOL is_texture = shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE; - floater->childSetEnabled("send_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && got_snap && previewp->getDataSize() <= MAX_POSTCARD_DATASIZE); - floater->childSetEnabled("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE && got_snap); - floater->childSetEnabled("save_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL && got_snap); + if (previewp) + { + previewp->setSnapshotFormat(shot_format); + if (previewp->getRawSnapshotUpToDate()) + { + if (delayed_formatted) + { + previewp->mFormattedDelayTimer.start(0.5); + } + previewp->generateFormattedAndFullscreenPreview(delayed_formatted); + } + else + { + previewp->mFormattedDelayTimer.stop(); + } + } LLLocale locale(LLLocale::USER_LOCALE); std::string bytes_string; - LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 ); + if (got_bytes) + { + LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 ); + } + else + { + bytes_string = floater->getString("unknown"); + } S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); floater->childSetLabelArg("texture", "[AMOUNT]", llformat("%d",upload_cost)); floater->childSetLabelArg("upload_btn", "[AMOUNT]", llformat("%d",upload_cost)); - floater->childSetTextArg("file_size_label", "[SIZE]", got_snap ? bytes_string : floater->getString("unknown")); + floater->childSetTextArg("file_size_label", "[SIZE]", bytes_string); floater->childSetColor("file_size_label", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && got_bytes && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLColor4::red : gColors.getColor( "LabelTextColor" )); - switch(shot_type) - { - case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: - layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; - floater->childSetValue("layer_types", "colors"); - if(is_advance) - { - setResolution(floater, "postcard_size_combo"); - } - break; - case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: - layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; - floater->childSetValue("layer_types", "colors"); - if(is_advance) - { - setResolution(floater, "texture_size_combo"); - } - break; - case LLSnapshotLivePreview::SNAPSHOT_LOCAL: - if(is_advance) - { - setResolution(floater, "local_size_combo"); - } - break; - default: - break; - } - - updateResolutionTextEntry(floater); + bool up_to_date = previewp && previewp->getSnapshotUpToDate(); + bool can_upload = up_to_date && !previewp->isUsedBy(shot_type); + floater->childSetEnabled("feed_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_FEED && can_upload); + floater->childSetEnabled("send_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && can_upload && previewp->getDataSize() <= MAX_POSTCARD_DATASIZE); + floater->childSetEnabled("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE && can_upload); + floater->childSetEnabled("save_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL && can_upload); + floater->childSetEnabled("temp_check", is_advance && is_texture); if (previewp) { - previewp->setSnapshotType(shot_type); - previewp->setSnapshotFormat(shot_format); - previewp->setSnapshotBufferType(layer_type); - } -} - -// static -void LLFloaterSnapshot::Impl::updateResolutionTextEntry(LLFloaterSnapshot* floater) -{ - LLSpinCtrl* width_spinner = floater->getChild("snapshot_width"); - LLSpinCtrl* height_spinner = floater->getChild("snapshot_height"); - - if(getTypeIndex(floater) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) - { - width_spinner->setAllowEdit(FALSE); - height_spinner->setAllowEdit(FALSE); - } - else - { - width_spinner->setAllowEdit(TRUE); - height_spinner->setAllowEdit(TRUE); + previewp->showFreezeFrameSnapshot(up_to_date); } } @@ -1392,15 +1925,108 @@ void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, } // static -void LLFloaterSnapshot::Impl::onClickDiscard(void* data) +void LLFloaterSnapshot::Impl::onCommitFeedResolution(LLUICtrl* ctrl, void* data) { - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - if (view) + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotFeedLastResolution", combobox->getCurrentIndex()); + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp && previewp->isUsed()) { - view->close(); + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_FEED); } + updateResolution(ctrl, data); } +// static +void LLFloaterSnapshot::Impl::onCommitPostcardResolution(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotPostcardLastResolution", combobox->getCurrentIndex()); + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_POSTCARD); + } + updateResolution(ctrl, data); +} + +// static +void LLFloaterSnapshot::Impl::onCommitTextureResolution(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotTextureLastResolution", combobox->getCurrentIndex()); + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_TEXTURE); + } + updateResolution(ctrl, data); +} + +// static +void LLFloaterSnapshot::Impl::onCommitLocalResolution(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotLocalLastResolution", combobox->getCurrentIndex()); + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_LOCAL); + } + updateResolution(ctrl, data); +} + +// static +void LLFloaterSnapshot::Impl::onCommitFeedAspect(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotFeedLastAspect", combobox->getCurrentIndex()); + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_FEED); + } + updateAspect(ctrl, data); +} + +// static +void LLFloaterSnapshot::Impl::onCommitPostcardAspect(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotPostcardLastAspect", combobox->getCurrentIndex()); + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_POSTCARD); + } + updateAspect(ctrl, data); +} + +// static +void LLFloaterSnapshot::Impl::onCommitTextureAspect(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotTextureLastAspect", combobox->getCurrentIndex()); + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_TEXTURE); + } + updateAspect(ctrl, data); +} + +// static +void LLFloaterSnapshot::Impl::onCommitLocalAspect(LLUICtrl* ctrl, void* data) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotLocalLastAspect", combobox->getCurrentIndex()); + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp && previewp->isUsed()) + { + previewp->addManualOverride(LLSnapshotLivePreview::SNAPSHOT_LOCAL); + } + updateAspect(ctrl, data); +} // static void LLFloaterSnapshot::Impl::onCommitSave(LLUICtrl* ctrl, void* data) @@ -1412,24 +2038,81 @@ void LLFloaterSnapshot::Impl::onCommitSave(LLUICtrl* ctrl, void* data) onClickKeep(data); } +//static +void LLFloaterSnapshot::saveStart(int index) +{ + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); + if (previewp) + { + previewp->saveStart(index); + } +} + +// Called from LLViewerWindow::saveImageNumbered, LLViewerWindow::saveImageNumbered_continued1 and LLViewerWindow::saveImageNumbered_continued2. +//static +void LLFloaterSnapshot::saveLocalDone(bool success, int index) +{ + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); + if (previewp) + { + previewp->saveDone(LLSnapshotLivePreview::SNAPSHOT_LOCAL, success, index); + } +} + +//static +void LLFloaterSnapshot::saveFeedDone(bool success, int index) +{ + LLUploadDialog::modalUploadFinished(); + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); + if (previewp) + { + previewp->saveDone(LLSnapshotLivePreview::SNAPSHOT_FEED, success, index); + } +} + +//static +void LLFloaterSnapshot::savePostcardDone(bool success, int index) +{ + LLUploadDialog::modalUploadFinished(); + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); + if (previewp) + { + previewp->saveDone(LLSnapshotLivePreview::SNAPSHOT_POSTCARD, success, index); + } +} + // static void LLFloaterSnapshot::Impl::onClickKeep(void* data) { - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLFloaterSnapshot* floater = (LLFloaterSnapshot *)data; + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { - if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD) + if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_FEED) + { + LLFloaterFeed* floater = previewp->getCaptionAndSaveFeed(); + if (floater) + { + // Make sure that the new floater is in front of gSnapshotFloaterView. + // So that the structure is: + // "root" --> + // "Snapshot Floater View" --> + // "floater_snapshot_profile" + // "Snapshot" floater + // ["snapshot_live_preview"] + // and "floater_snapshot_profile" (floater) is a child of "Snapshot Floater View" (gSnapshotFloaterView), + // and therefore in front of "snapshot_live_preview", if it exists. + gSnapshotFloaterView->addChild(floater); + } + } + else if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD) { LLFloaterPostcard* floater = previewp->savePostcard(); - // if still in snapshot mode, put postcard floater in snapshot floaterview - // and link it to snapshot floater - if (floater && !gSavedSettings.getBOOL("CloseSnapshotOnKeep")) + if (floater) { - gFloaterView->removeChild(floater); + // Same as above, but for the "Postcard" floater. gSnapshotFloaterView->addChild(floater); - view->addDependentFloater(floater, FALSE); } } else if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) @@ -1443,38 +2126,57 @@ void LLFloaterSnapshot::Impl::onClickKeep(void* data) if (gSavedSettings.getBOOL("CloseSnapshotOnKeep")) { - view->close(); + previewp->close(floater); } else { checkAutoSnapshot(previewp); } - updateControls(view); + updateControls(floater); } } // static void LLFloaterSnapshot::Impl::onClickNewSnapshot(void* data) { - LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterSnapshot *)data); - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - if (previewp && view) + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) { previewp->updateSnapshot(TRUE); } } +// static +void LLFloaterSnapshot::Impl::onClickFreezeTime(void*) +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) + { + freezeTime(true); + } +} + // static void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data) { LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; gSavedSettings.setBOOL( "AutoSnapshot", check->get() ); + LLFloaterSnapshot* floater = (LLFloaterSnapshot*)data; + if (floater) + { + checkAutoSnapshot(getPreviewView()); + updateControls(floater); + } +} + +// static +void LLFloaterSnapshot::Impl::onClickTemporaryImage(LLUICtrl *ctrl, void* data) +{ LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - checkAutoSnapshot(getPreviewView(view)); updateControls(view); } } @@ -1490,9 +2192,9 @@ void LLFloaterSnapshot::Impl::onClickMore(void* data) view->reshape(view->getRect().getWidth(), view->getUIWinHeightLong()); updateControls(view) ; updateLayout(view) ; - if(getPreviewView(view)) + if (getPreviewView()) { - getPreviewView(view)->setThumbnailImageSize() ; + getPreviewView()->setThumbnailImageSize() ; } } } @@ -1507,9 +2209,9 @@ void LLFloaterSnapshot::Impl::onClickLess(void* data) view->reshape(view->getRect().getWidth(), view->getUIWinHeightShort()); updateControls(view) ; updateLayout(view) ; - if(getPreviewView(view)) + if (getPreviewView()) { - getPreviewView(view)->setThumbnailImageSize() ; + getPreviewView()->setThumbnailImageSize(); } } } @@ -1523,7 +2225,7 @@ void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data) LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - checkAutoSnapshot(getPreviewView(view), TRUE); + checkAutoSnapshot(getPreviewView(), TRUE); updateControls(view); } } @@ -1537,7 +2239,7 @@ void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data) LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - checkAutoSnapshot(getPreviewView(view), TRUE); + checkAutoSnapshot(getPreviewView(), TRUE); updateControls(view); } } @@ -1550,50 +2252,30 @@ void LLFloaterSnapshot::Impl::onClickKeepOpenCheck(LLUICtrl* ctrl, void* data) gSavedSettings.setBOOL( "CloseSnapshotOnKeep", !check->get() ); } -// static -void LLFloaterSnapshot::Impl::onClickKeepAspectCheck(LLUICtrl* ctrl, void* data) -{ - LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; - gSavedSettings.setBOOL( "KeepAspectForSnapshot", check->get() ); - - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - if (view) - { - LLSnapshotLivePreview* previewp = getPreviewView(view) ; - if(previewp) - { - previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; - - S32 w, h ; - previewp->getSize(w, h) ; - if(checkImageSize(previewp, w, h, TRUE, previewp->getMaxImageSize())) - { - resetSnapshotSizeOnUI(view, w, h) ; - } - - previewp->setSize(w, h) ; - previewp->updateSnapshot(FALSE, TRUE); - checkAutoSnapshot(previewp, TRUE); - } - } -} - // static void LLFloaterSnapshot::Impl::onCommitQuality(LLUICtrl* ctrl, void* data) { LLSliderCtrl* slider = (LLSliderCtrl*)ctrl; S32 quality_val = llfloor((F32)slider->getValue().asReal()); - LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterSnapshot *)data); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { previewp->setSnapshotQuality(quality_val); + checkAutoSnapshot(previewp, TRUE); } - checkAutoSnapshot(previewp, TRUE); +} + +//static +void LLFloaterSnapshot::Impl::onQualityMouseUp(void* data) +{ + Dout(dc::snapshot, "Calling LLFloaterSnapshot::Impl::QualityMouseUp()"); + LLFloaterSnapshot* view = (LLFloaterSnapshot *)data; + updateControls(view); } // static -void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data) +void LLFloaterSnapshot::Impl::onCommitFreezeTime(LLUICtrl* ctrl, void* data) { LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; @@ -1603,83 +2285,44 @@ void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data) return; } - gSavedSettings.setBOOL("UseFreezeFrame", check_box->get()); - - updateLayout(view); -} - -// static -void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 index) -{ - LLSnapshotLivePreview *previewp = getPreviewView(view) ; - - // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here -#if 0 - if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == getTypeIndex(view)) - { - previewp->mKeepAspectRatio = FALSE ; - return ; - } -#endif - - if(0 == index) //current window size - { - sAspectRatioCheckOff = TRUE ; - view->childSetEnabled("keep_aspect_check", FALSE) ; - - if(previewp) - { - previewp->mKeepAspectRatio = TRUE ; - } - } - else if(-1 == index) //custom - { - sAspectRatioCheckOff = FALSE ; - //if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE != gSavedSettings.getS32("LastSnapshotType")) - { - view->childSetEnabled("keep_aspect_check", TRUE) ; - - if(previewp) - { - previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; - } - } - } - else - { - sAspectRatioCheckOff = TRUE ; - view->childSetEnabled("keep_aspect_check", FALSE) ; - - if(previewp) - { - previewp->mKeepAspectRatio = FALSE ; - } - } - - return ; + gSavedSettings.setBOOL("SnapshotOpenFreezeTime", check_box->get()); } static std::string lastSnapshotWidthName() { switch(gSavedSettings.getS32("LastSnapshotType")) { + case LLSnapshotLivePreview::SNAPSHOT_FEED: return "LastSnapshotToFeedWidth"; case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: return "LastSnapshotToEmailWidth"; case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: return "LastSnapshotToInventoryWidth"; default: return "LastSnapshotToDiskWidth"; } } + static std::string lastSnapshotHeightName() { switch(gSavedSettings.getS32("LastSnapshotType")) { + case LLSnapshotLivePreview::SNAPSHOT_FEED: return "LastSnapshotToFeedHeight"; case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: return "LastSnapshotToEmailHeight"; case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: return "LastSnapshotToInventoryHeight"; default: return "LastSnapshotToDiskHeight"; } } +static std::string lastSnapshotAspectName() +{ + switch(gSavedSettings.getS32("LastSnapshotType")) + { + case LLSnapshotLivePreview::SNAPSHOT_FEED: return "LastSnapshotToFeedAspect"; + case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: return "LastSnapshotToEmailAspect"; + case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: return "LastSnapshotToInventoryAspect"; + default: return "LastSnapshotToDiskAspect"; + } +} + // static -void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update) +void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, bool update_controls) { LLComboBox* combobox = (LLComboBox*)ctrl; LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; @@ -1689,10 +2332,192 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL return; } - // save off all selected resolution values - gSavedSettings.setS32("SnapshotPostcardLastResolution", view->getChild("postcard_size_combo")->getCurrentIndex()); - gSavedSettings.setS32("SnapshotTextureLastResolution", view->getChild("texture_size_combo")->getCurrentIndex()); - gSavedSettings.setS32("SnapshotLocalLastResolution", view->getChild("local_size_combo")->getCurrentIndex()); + S32 new_width = 0; + S32 new_height = 0; + F32 new_aspect = 0; + LLSnapshotLivePreview* previewp = getPreviewView(); +#if 0 // Broken -- not doing this for now. + LLSnapshotLivePreview::ESnapshotType shot_type = (LLSnapshotLivePreview::ESnapshotType)gSavedSettings.getS32("LastSnapshotType"); + + // Is the snapshot was already used (saved or uploaded) and no manual changes + // have been made since to the current destination type, and the raw snapshot + // is still up to date with regard to visibility of UI, HUD and BufferType etc? + if (previewp && previewp->isUsed() && !previewp->isOverriddenBy(shot_type) && previewp->getRawSnapshotUpToDate()) + { + previewp->getSize(new_width, new_height); + new_aspect = previewp->getAspect(); + S32 const old_width = new_width; + S32 const old_height = new_height; + F32 const old_aspect = new_aspect; + S32 raw_width; + S32 raw_height; + previewp->getRawSize(raw_width, raw_height); + F32 const raw_aspect = (F32)raw_width / raw_height; + bool fixed_crop = false; + bool fixed_size = false; + bool fixed_scale = false; + bool done = false; + bool fail = false; + while (!done) + { + // Attempt to change the size and aspect so the raw snapshot can also be used for this new destination. + S32 w, h, crop_offset; + bool crop_vertically; + previewp->setSize(new_width, new_height); + previewp->setAspect(new_aspect); + LLSnapshotLivePreview::EAspectSizeProblem ret = previewp->getAspectSizeProblem(w, h, crop_vertically, crop_offset); + switch(ret) + { + case LLSnapshotLivePreview::ASPECTSIZE_OK: + done = true; // Don't change anything (else) if the current settings are usable. + break; + case LLSnapshotLivePreview::CANNOT_CROP_HORIZONTALLY: + case LLSnapshotLivePreview::CANNOT_CROP_VERTICALLY: + if (fixed_crop) + { + done = fail = true; + } + else + { + // Set target aspect to aspect of the raw snapshot we have (no reason to crop anything). + new_aspect = raw_aspect; + fixed_crop = true; + } + break; + case LLSnapshotLivePreview::SIZE_TOO_LARGE: + if (fixed_size) + { + done = fail = true; + } + else + { + if (new_width > w) + { + new_width = w; + new_height = llround(new_width / new_aspect); + } + if (new_height > h) + { + new_width = llmin(w, llround(h * new_aspect)); + new_height = llmin(h, llround(new_width / new_aspect)); + } + fixed_size = true; + } + break; + case LLSnapshotLivePreview::CANNOT_RESIZE: + if (fixed_scale) + { + done = fail = true; + } + else + { + F32 ratio = llmin((F32)w / new_width, (F32)h / new_height); + new_width = llround(new_width * ratio); + new_height = llround(new_height * ratio); + fixed_scale = true; + } + break; + } + } + previewp->setAspect(old_aspect); + previewp->setSize(old_width, old_height); + if (fail) + { + new_aspect = 0; + new_width = new_height = 0; + } + else + { + LLComboBox* size_combo_box = NULL; + LLComboBox* aspect_combo_box = NULL; + switch(shot_type) + { + case LLSnapshotLivePreview::SNAPSHOT_FEED: + size_combo_box = view->getChild("feed_size_combo"); + aspect_combo_box = view->getChild("feed_aspect_combo"); + break; + case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: + size_combo_box = view->getChild("postcard_size_combo"); + aspect_combo_box = view->getChild("postcard_aspect_combo"); + break; + case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: + size_combo_box = view->getChild("texture_size_combo"); + aspect_combo_box = view->getChild("texture_aspect_combo"); + break; + case LLSnapshotLivePreview::SNAPSHOT_LOCAL: + size_combo_box = view->getChild("local_size_combo"); + aspect_combo_box = view->getChild("local_aspect_combo"); + break; + } + S32 index = 0; + S32 const size_custom = size_combo_box->getItemCount() - (shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE ? 0 : 1); // Texture does not end on 'Custom'. + while (index < size_custom) + { + size_combo_box->setCurrentByIndex(index); + std::string sdstring = size_combo_box->getSelectedValue(); + LLSD sdres; + std::stringstream sstream(sdstring); + LLSDSerialize::fromNotation(sdres, sstream, sdstring.size()); + S32 width = sdres[0]; + S32 height = sdres[1]; + if (width == 0 || height == 0) + { + width = gViewerWindow->getWindowDisplayWidth(); + height = gViewerWindow->getWindowDisplayHeight(); + } + if (width == new_width && height == new_height) + { + break; + } + ++index; + } + if (index == size_custom && shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE) + { + size_combo_box->setCurrentByIndex(index); + } + index = 0; + S32 const aspect_custom = aspect_combo_box->getItemCount() - 1; + while (index < aspect_custom) + { + aspect_combo_box->setCurrentByIndex(index); + std::string sdstring = aspect_combo_box->getSelectedValue(); + std::stringstream sstream; + sstream << sdstring; + F32 aspect; + sstream >> aspect; + if (aspect == -2) // Default + { + aspect = (F32)new_width / new_height; + } + if (aspect == 0) // Current window + { + aspect = (F32)gViewerWindow->getWindowDisplayWidth() / gViewerWindow->getWindowDisplayHeight(); + } + if (llabs(aspect - new_aspect) < 0.0001) + { + break; + } + ++index; + } + if (index == aspect_custom) + { + aspect_combo_box->setCurrentByIndex(index); + setAspect(view, previewp->aspectComboName(), update_controls); + } + } + } + else +#endif + { + view->getChild("feed_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFeedLastResolution")); + view->getChild("feed_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFeedLastAspect")); + view->getChild("postcard_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution")); + view->getChild("postcard_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastAspect")); + view->getChild("texture_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution")); + view->getChild("texture_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastAspect")); + view->getChild("local_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution")); + view->getChild("local_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastAspect")); + } std::string sdstring = combobox->getSelectedValue(); LLSD sdres; @@ -1702,12 +2527,10 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL S32 width = sdres[0]; S32 height = sdres[1]; - LLSnapshotLivePreview* previewp = getPreviewView(view); if (previewp && combobox->getCurrentIndex() >= 0) { S32 original_width = 0 , original_height = 0 ; previewp->getSize(original_width, original_height) ; - if (width == 0 || height == 0 || gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot")) { // take resolution from current window size @@ -1715,8 +2538,24 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL } else if (width == -1 || height == -1) { - // load last custom value - previewp->setSize(gSavedSettings.getS32(lastSnapshotWidthName()), gSavedSettings.getS32(lastSnapshotHeightName())); + if (previewp->isUsed() && new_width != 0 && new_height != 0) + { + previewp->setSize(new_width, new_height); + } + else + { + // load last custom value + previewp->setSize(gSavedSettings.getS32(lastSnapshotWidthName()), gSavedSettings.getS32(lastSnapshotHeightName())); + } + } + else if (height == -2) + { + // The size is actually the source aspect now, encoded in the width. + F32 source_aspect = width / 630.f; + // Use the size of the current window, cropped to the required aspect. + width = llmin(gViewerWindow->getWindowDisplayWidth(), llround(gViewerWindow->getWindowDisplayHeight() * source_aspect)); + height = llmin(gViewerWindow->getWindowDisplayHeight(), llround(gViewerWindow->getWindowDisplayWidth() / source_aspect)); + previewp->setSize(width, height); } else { @@ -1724,51 +2563,137 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL previewp->setSize(width, height); } - checkAspectRatio(view, width) ; - previewp->getSize(width, height); - if(checkImageSize(previewp, width, height, TRUE, previewp->getMaxImageSize())) - { - resetSnapshotSizeOnUI(view, width, height) ; - } - if(view->childGetValue("snapshot_width").asInteger() != width || view->childGetValue("snapshot_height").asInteger() != height) { view->childSetValue("snapshot_width", width); view->childSetValue("snapshot_height", height); } + } - if(original_width != width || original_height != height) + // Set whether or not the spinners can be changed. + + LLSpinCtrl* width_spinner = view->getChild("snapshot_width"); + LLSpinCtrl* height_spinner = view->getChild("snapshot_height"); + + if (gSavedSettings.getS32("LastSnapshotType") == LLSnapshotLivePreview::SNAPSHOT_TEXTURE || + gSavedSettings.getBOOL("RenderUIInSnapshot") || + gSavedSettings.getBOOL("RenderHUDInSnapshot")) + { + // Disable without making label gray. + width_spinner->setAllowEdit(FALSE); + width_spinner->setIncrement(0); + height_spinner->setAllowEdit(FALSE); + height_spinner->setIncrement(0); + } + else + { + width_spinner->setAllowEdit(TRUE); + width_spinner->setIncrement(32); + height_spinner->setAllowEdit(TRUE); + height_spinner->setIncrement(32); + } + + if (previewp) + { + if (new_aspect == 0) { - previewp->setSize(width, height); - - // hide old preview as the aspect ratio could be wrong - checkAutoSnapshot(previewp, FALSE); - getPreviewView(view)->updateSnapshot(FALSE, TRUE); - if(do_update) - { - updateControls(view); - } + // In case the aspect is 'Default', need to update aspect (which will call updateControls, if necessary). + setAspect(view, previewp->aspectComboName(), update_controls); } + else + { + LLSpinCtrl* aspect_spinner = view->getChild("aspect_ratio"); + aspect_spinner->set(new_aspect); + previewp->setAspect(new_aspect); + } + } +} + +// static +void LLFloaterSnapshot::Impl::updateAspect(LLUICtrl* ctrl, void* data, bool update_controls) +{ + LLComboBox* combobox = (LLComboBox*)ctrl; + LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; + + if (!view || !combobox) + { + return; + } + + LLSnapshotLivePreview* previewp = getPreviewView(); + + view->getChild("feed_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFeedLastAspect")); + view->getChild("postcard_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastAspect")); + view->getChild("texture_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastAspect")); + view->getChild("local_aspect_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastAspect")); + + std::string sdstring = combobox->getSelectedValue(); + std::stringstream sstream; + sstream << sdstring; + F32 aspect; + sstream >> aspect; + + if (aspect == -2) // Default + { + S32 width, height; + previewp->getSize(width, height); + aspect = (F32)width / height; + } + else if (aspect == -1) // Custom + { + aspect = gSavedSettings.getF32(lastSnapshotAspectName()); + } + if (aspect == 0) // Current window + { + aspect = (F32)gViewerWindow->getWindowDisplayWidth() / gViewerWindow->getWindowDisplayHeight(); + } + + LLSpinCtrl* aspect_spinner = view->getChild("aspect_ratio"); + + // Set whether or not the spinners can be changed. + if (gSavedSettings.getBOOL("RenderUIInSnapshot") || + gSavedSettings.getBOOL("RenderHUDInSnapshot")) + { + aspect = (F32)gViewerWindow->getWindowDisplayWidth() / gViewerWindow->getWindowDisplayHeight(); + // Disable without making label gray. + aspect_spinner->setAllowEdit(FALSE); + aspect_spinner->setIncrement(0); + } + else + { + aspect_spinner->setAllowEdit(TRUE); + aspect_spinner->setIncrement(llmax(0.01f, lltrunc(aspect) / 100.0f)); + } + + // Sync the spinner and cache value. + aspect_spinner->set(aspect); + if (previewp) + { + F32 old_aspect = previewp->getAspect(); + previewp->setAspect(aspect); + if (old_aspect != aspect) + { + checkAutoSnapshot(previewp, TRUE); + } + } + if (update_controls) + { + // In case getSnapshotUpToDate() changed. + updateControls(view); } } // static void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data) { - LLComboBox* combobox = (LLComboBox*)ctrl; - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - if (view) { - LLSnapshotLivePreview* previewp = getPreviewView(view); - if (previewp) - { - previewp->setSnapshotBufferType((LLViewerWindow::ESnapshotType)combobox->getCurrentIndex()); - } - checkAutoSnapshot(previewp, TRUE); + LLComboBox* combobox = (LLComboBox*)ctrl; + gSavedSettings.setS32("SnapshotLayerType", combobox->getCurrentIndex()); + updateControls(view); } } @@ -1779,7 +2704,6 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data) if (view) { gSavedSettings.setS32("LastSnapshotType", getTypeIndex(view)); - getPreviewView(view)->updateSnapshot(TRUE); updateControls(view); } } @@ -1792,7 +2716,6 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data) if (view) { gSavedSettings.setS32("SnapshotFormat", getFormatIndex(view)); - getPreviewView(view)->updateSnapshot(TRUE); updateControls(view); } } @@ -1807,110 +2730,34 @@ void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const s combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index - if(comboname == "postcard_size_combo") + if(comboname == "feed_size_combo") + { + gSavedSettings.setS32("SnapshotFeedLastResolution", combo->getCurrentIndex()); + } + else if(comboname == "postcard_size_combo") { gSavedSettings.setS32("SnapshotPostcardLastResolution", combo->getCurrentIndex()); } - else if(comboname == "texture_size_combo") - { - gSavedSettings.setS32("SnapshotTextureLastResolution", combo->getCurrentIndex()); - } else if(comboname == "local_size_combo") { gSavedSettings.setS32("SnapshotLocalLastResolution", combo->getCurrentIndex()); } - - checkAspectRatio(floater, -1); // -1 means custom -} - - - -//static -BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value) -{ - S32 w = width ; - S32 h = height ; - - //if texture, ignore aspect ratio setting, round image size to power of 2. -#if 0 // 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 == gSavedSettings.getS32("LastSnapshotType")) + else if(comboname == "feed_aspect_combo") { - if(width > max_value) - { - width = max_value ; - } - if(height > max_value) - { - height = max_value ; - } - - //round to nearest power of 2 based on the direction of movement - // i.e. higher power of two if increasing texture resolution - if(gSavedSettings.getS32("LastSnapshotToInventoryWidth") < width || - gSavedSettings.getS32("LastSnapshotToInventoryHeight") < height) - { - // Up arrow pressed - width = get_next_power_two(width, MAX_TEXTURE_SIZE) ; - height = get_next_power_two(height, MAX_TEXTURE_SIZE) ; - } - else - { - // Down or no change - width = get_lower_power_two(width, MAX_TEXTURE_SIZE) ; - height = get_lower_power_two(height, MAX_TEXTURE_SIZE) ; - } + gSavedSettings.setS32("SnapshotFeedLastAspect", combo->getCurrentIndex()); } - else -#endif - if(previewp && previewp->mKeepAspectRatio) + else if(comboname == "postcard_aspect_combo") { - if(gViewerWindow->getWindowDisplayWidth() < 1 || gViewerWindow->getWindowDisplayHeight() < 1) - { - return FALSE ; - } - - //aspect ratio of the current window - F32 aspect_ratio = (F32)gViewerWindow->getWindowDisplayWidth() / gViewerWindow->getWindowDisplayHeight() ; - - //change another value proportionally - if(isWidthChanged) - { - height = (S32)(width / aspect_ratio) ; - } - else - { - width = (S32)(height * aspect_ratio) ; - } - - //bound w/h by the max_value - if(width > max_value || height > max_value) - { - if(width > height) - { - width = max_value ; - height = (S32)(width / aspect_ratio) ; - } - else - { - height = max_value ; - width = (S32)(height * aspect_ratio) ; - } - } + gSavedSettings.setS32("SnapshotPostcardLastAspect", combo->getCurrentIndex()); } - else + else if(comboname == "texture_aspect_combo") { + gSavedSettings.setS32("SnapshotTextureLastAspect", combo->getCurrentIndex()); + } + else if(comboname == "local_aspect_combo") + { + gSavedSettings.setS32("SnapshotLocalLastAspect", combo->getCurrentIndex()); } - - return (w != width || h != height) ; -} - -//static -void LLFloaterSnapshot::Impl::resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) -{ - view->getChild("snapshot_width")->forceSetValue(width); - view->getChild("snapshot_height")->forceSetValue(height); - gSavedSettings.setS32(lastSnapshotWidthName(), width); - gSavedSettings.setS32(lastSnapshotHeightName(), height); } //static @@ -1919,10 +2766,10 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - S32 w = llfloor((F32)view->childGetValue("snapshot_width").asReal()); - S32 h = llfloor((F32)view->childGetValue("snapshot_height").asReal()); + S32 w = llround(view->childGetValue("snapshot_width").asReal(), 1.0); + S32 h = llround(view->childGetValue("snapshot_height").asReal(), 1.0); - LLSnapshotLivePreview* previewp = getPreviewView(view); + LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { S32 curw,curh; @@ -1930,43 +2777,12 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat if (w != curw || h != curh) { - BOOL update_ = FALSE ; - //if to upload a snapshot, process spinner input in a special way. -#if 0 // 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 == gSavedSettings.getS32("LastSnapshotType")) - { - S32 spinner_increment = (S32)((LLSpinCtrl*)ctrl)->getIncrement() ; - S32 dw = w - curw ; - S32 dh = h - curh ; - dw = (dw == spinner_increment) ? 1 : ((dw == -spinner_increment) ? -1 : 0) ; - dh = (dh == spinner_increment) ? 1 : ((dh == -spinner_increment) ? -1 : 0) ; - - if(dw) - { - w = (dw > 0) ? curw << dw : curw >> -dw ; - update_ = TRUE ; - } - if(dh) - { - h = (dh > 0) ? curh << dh : curh >> -dh ; - update_ = TRUE ; - } - } -#endif previewp->setMaxImageSize((S32)((LLSpinCtrl *)ctrl)->getMaxValue()) ; - - // Check image size changes the value of height and width - if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize()) - || update_) - { - resetSnapshotSizeOnUI(view, w, h) ; - } - previewp->setSize(w,h); checkAutoSnapshot(previewp, FALSE); previewp->updateSnapshot(FALSE, TRUE); + comboSetCustom(view, "feed_size_combo"); comboSetCustom(view, "postcard_size_combo"); - comboSetCustom(view, "texture_size_combo"); comboSetCustom(view, "local_size_combo"); } } @@ -1974,7 +2790,58 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat gSavedSettings.setS32(lastSnapshotWidthName(), w); gSavedSettings.setS32(lastSnapshotHeightName(), h); - updateControls(view); + updateControls(view, true); + } +} + +char const* LLSnapshotLivePreview::aspectComboName() const +{ + char const* result; + switch(mSnapshotType) + { + case SNAPSHOT_FEED: + result = "feed_aspect_combo"; + break; + case SNAPSHOT_POSTCARD: + result = "postcard_aspect_combo"; + break; + case SNAPSHOT_TEXTURE: + result = "texture_aspect_combo"; + break; + case SNAPSHOT_LOCAL: + result = "local_aspect_combo"; + break; + default: + result= ""; + break; + } + return result; +} + +//static +void LLFloaterSnapshot::Impl::onCommitCustomAspect(LLUICtrl *ctrl, void* data) +{ + LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; + if (view) + { + F32 a = view->childGetValue("aspect_ratio").asReal(); + + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) + { + F32 cura = previewp->getAspect(); + + if (a != cura) + { + previewp->setAspect(a); + previewp->updateSnapshot(FALSE, TRUE); + comboSetCustom(view, previewp->aspectComboName()); + } + } + + gSavedSettings.setF32(lastSnapshotAspectName(), a); + + updateControls(view, true); } } @@ -2017,21 +2884,25 @@ BOOL LLFloaterSnapshot::postBuild() childSetCommitCallback("local_format_combo", Impl::onCommitSnapshotFormat, this); childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this); + childSetAction("freeze_time_btn", Impl::onClickFreezeTime, this); childSetAction("more_btn", Impl::onClickMore, this); childSetAction("less_btn", Impl::onClickLess, this); childSetAction("upload_btn", Impl::onClickKeep, this); childSetAction("send_btn", Impl::onClickKeep, this); + childSetAction("feed_btn", Impl::onClickKeep, this); childSetCommitCallback("save_btn", Impl::onCommitSave, this); - childSetAction("discard_btn", Impl::onClickDiscard, this); childSetCommitCallback("image_quality_slider", Impl::onCommitQuality, this); childSetValue("image_quality_slider", gSavedSettings.getS32("SnapshotQuality")); + impl.mQualityMouseUpConnection = getChild("image_quality_slider")->setSliderMouseUpCallback(boost::bind(&Impl::onQualityMouseUp, this)); childSetCommitCallback("snapshot_width", Impl::onCommitCustomResolution, this); childSetCommitCallback("snapshot_height", Impl::onCommitCustomResolution, this); + childSetCommitCallback("aspect_ratio", Impl::onCommitCustomAspect, this); + childSetCommitCallback("ui_check", Impl::onClickUICheck, this); childSetValue("ui_check", gSavedSettings.getBOOL("RenderUIInSnapshot")); @@ -2041,9 +2912,6 @@ BOOL LLFloaterSnapshot::postBuild() childSetCommitCallback("keep_open_check", Impl::onClickKeepOpenCheck, this); childSetValue("keep_open_check", !gSavedSettings.getBOOL("CloseSnapshotOnKeep")); - childSetCommitCallback("keep_aspect_check", Impl::onClickKeepAspectCheck, this); - childSetValue("keep_aspect_check", gSavedSettings.getBOOL("KeepAspectForSnapshot")); - childSetCommitCallback("layer_types", Impl::onCommitLayerTypes, this); childSetValue("layer_types", "colors"); childSetEnabled("layer_types", FALSE); @@ -2051,39 +2919,54 @@ BOOL LLFloaterSnapshot::postBuild() childSetValue("snapshot_width", gSavedSettings.getS32(lastSnapshotWidthName())); childSetValue("snapshot_height", gSavedSettings.getS32(lastSnapshotHeightName())); - childSetValue("freeze_frame_check", gSavedSettings.getBOOL("UseFreezeFrame")); - childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this); + childSetValue("freeze_time_check", gSavedSettings.getBOOL("SnapshotOpenFreezeTime")); + childSetCommitCallback("freeze_time_check", Impl::onCommitFreezeTime, this); childSetValue("auto_snapshot_check", gSavedSettings.getBOOL("AutoSnapshot")); childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this); + childSetCommitCallback("temp_check", Impl::onClickTemporaryImage, this); - childSetCommitCallback("postcard_size_combo", Impl::onCommitResolution, this); - childSetCommitCallback("texture_size_combo", Impl::onCommitResolution, this); - childSetCommitCallback("local_size_combo", Impl::onCommitResolution, this); + childSetCommitCallback("feed_size_combo", Impl::onCommitFeedResolution, this); + childSetCommitCallback("postcard_size_combo", Impl::onCommitPostcardResolution, this); + childSetCommitCallback("texture_size_combo", Impl::onCommitTextureResolution, this); + childSetCommitCallback("local_size_combo", Impl::onCommitLocalResolution, this); + + childSetCommitCallback("feed_aspect_combo", Impl::onCommitFeedAspect, this); + childSetCommitCallback("postcard_aspect_combo", Impl::onCommitPostcardAspect, this); + childSetCommitCallback("texture_aspect_combo", Impl::onCommitTextureAspect, this); + childSetCommitCallback("local_aspect_combo", Impl::onCommitLocalAspect, this); // create preview window LLRect full_screen_rect = sInstance->getRootView()->getRect(); LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(full_screen_rect); - sInstance->getRootView()->removeChild(gSnapshotFloaterView); - // make sure preview is below snapshot floater - sInstance->getRootView()->addChild(previewp); - sInstance->getRootView()->addChild(gSnapshotFloaterView); + // Make sure preview is below snapshot floater. + // "root" --> (first child is hit first): + // "Snapshot Floater View" + // "snapshot_live_preview" + // ... + sInstance->getRootView()->addChild(previewp); // Note that addChild is actually 'moveChild'. + sInstance->getRootView()->addChild(gSnapshotFloaterView); // The last added child becomes the first child; the one up front. - // gSavedSettings.setBOOL("TemporaryUpload",FALSE); - childSetValue("temp_check",FALSE); - // + childSetValue("temp_check",FALSE); Impl::sPreviewHandle = previewp->getHandle(); impl.updateControls(this); - + impl.freezeTime(gSavedSettings.getBOOL("SnapshotOpenFreezeTime")); + return TRUE; } +LLRect LLFloaterSnapshot::getThumbnailAreaRect() +{ + // getRect() includes shadows and the title bar, therefore the real corners are as follows: + return LLRect(1, getRect().getHeight() - 17, getRect().getWidth() - 1, getRect().getHeight() - 17 - THUMBHEIGHT); +} + void LLFloaterSnapshot::draw() { - LLSnapshotLivePreview* previewp = impl.getPreviewView(this); + LLSnapshotLivePreview* previewp = impl.getPreviewView(); if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock())) { @@ -2097,10 +2980,13 @@ void LLFloaterSnapshot::draw() { if(previewp->getThumbnailImage()) { - S32 offset_x = (getRect().getWidth() - previewp->getThumbnailWidth()) / 2 ; - S32 offset_y = getRect().getHeight() - 205 + (90 - previewp->getThumbnailHeight()) / 2 ; + LLRect const thumb_area = getThumbnailAreaRect(); + // The offset needed to center the thumbnail is: center - thumbnailSize/2 = + S32 offset_x = (thumb_area.mLeft + thumb_area.mRight - previewp->getThumbnailWidth()) / 2; + S32 offset_y = (thumb_area.mBottom + thumb_area.mTop - previewp->getThumbnailHeight()) / 2; gGL.matrixMode(LLRender::MM_MODELVIEW); + gl_rect_2d(thumb_area, LLColor4::grey4, true); gl_draw_scaled_image(offset_x, offset_y, previewp->getThumbnailWidth(), previewp->getThumbnailHeight(), previewp->getThumbnailImage(), LLColor4::white); @@ -2117,10 +3003,11 @@ void LLFloaterSnapshot::onOpen() void LLFloaterSnapshot::onClose(bool app_quitting) { - gSnapshotFloaterView->setEnabled(FALSE); // Set invisible so it doesn't eat tooltips. JC gSnapshotFloaterView->setVisible(FALSE); + gSnapshotFloaterView->setEnabled(FALSE); gSavedSettings.setBOOL("SnapshotBtnState", FALSE); + impl.freezeTime(false); destroy(); } @@ -2130,24 +3017,26 @@ void LLFloaterSnapshot::show(void*) if (!sInstance) { sInstance = new LLFloaterSnapshot(); - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE); - //move snapshot floater to special purpose snapshotfloaterview - gFloaterView->removeChild(sInstance); + LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE); // "Snapshot" floater. + // Make snapshot floater a child of (full screen) gSnapshotFloaterView. + // So that the structure is: + // "root" --> + // "Snapshot Floater View" --> + // "Snapshot" floater + // ["floater_snapshot_profile"] + // ["Postcard"] + // ["snapshot_live_preview"] + // and the "Snapshot" floater (sInstance) is a child of "Snapshot Floater View" (gSnapshotFloaterView), + // and therefore in front of "snapshot_live_preview", if it exists. gSnapshotFloaterView->addChild(sInstance); sInstance->impl.updateLayout(sInstance); } - else // just refresh the snapshot in the existing floater instance (DEV-12255) - { - LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(sInstance); - if(preview) - { - preview->updateSnapshot(TRUE); - } - } sInstance->open(); /* Flawfinder: ignore */ sInstance->focusFirstItem(FALSE); + sInstance->setEnabled(TRUE); + sInstance->setVisible(TRUE); gSnapshotFloaterView->setEnabled(TRUE); gSnapshotFloaterView->setVisible(TRUE); gSnapshotFloaterView->adjustToFitScreen(sInstance, FALSE); @@ -2176,6 +3065,81 @@ void LLFloaterSnapshot::update() } } +//static +void LLFloaterSnapshot::updateControls() +{ + Impl::updateControls(sInstance); +} + +//static +void LLFloaterSnapshot::resetFeedAndPostcardAspect() +{ + Impl::resetFeedAndPostcardAspect(sInstance); +} + +BOOL LLFloaterSnapshot::handleKeyHere(KEY key, MASK mask) +{ + static const LLCachedControl freeze_time("FreezeTime",false); + if (freeze_time && key == KEY_ESCAPE && mask == MASK_NONE) + { + // Ignore trying to defocus the snapshot floater in Freeze Time mode. + // However, if we're showing the fullscreen frozen preview, drop out of it; + // otherwise leave Freeze Time (so the next ESC press DOES defocus + // the floater and only the fourth will finally reset the cam). + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); + if (previewp && previewp->getShowFreezeFrameSnapshot()) + { + previewp->showFreezeFrameSnapshot(false); + } + else + { + impl.freezeTime(false); + } + return TRUE; + } + else if (key == 'Q' && mask == MASK_CONTROL) + { + // Allow users to quit with ctrl-Q. + LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(); + if (previewp && previewp->getShowFreezeFrameSnapshot()) + { + previewp->showFreezeFrameSnapshot(false); + } + impl.freezeTime(false); + gFocusMgr.removeKeyboardFocusWithoutCallback(gFocusMgr.getKeyboardFocus()); + return FALSE; + } + return LLFloater::handleKeyHere(key, mask); +} + +BOOL LLFloaterSnapshot::handleMouseDown(S32 x, S32 y, MASK mask) +{ + if (mask == MASK_NONE) + { + LLRect thumb_area = getThumbnailAreaRect(); + if (thumb_area.pointInRect(x, y)) + { + return TRUE; + } + } + return LLFloater::handleMouseDown(x, y, mask); +} + +BOOL LLFloaterSnapshot::handleMouseUp(S32 x, S32 y, MASK mask) +{ + if (mask == MASK_NONE) + { + // In FreezeTime mode, show preview again (after user pressed ESC) when + // clicking on the thumbnail area. + LLRect thumb_area = getThumbnailAreaRect(); + if (thumb_area.pointInRect(x, y)) + { + impl.updateControls(this); + return TRUE; + } + } + return LLFloater::handleMouseUp(x, y, mask); +} ///---------------------------------------------------------------------------- /// Class LLSnapshotFloaterView @@ -2183,7 +3147,7 @@ void LLFloaterSnapshot::update() LLSnapshotFloaterView::LLSnapshotFloaterView( const std::string& name, const LLRect& rect ) : LLFloaterView(name, rect) { - setMouseOpaque(TRUE); + setMouseOpaque(FALSE); setEnabled(FALSE); } diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index 8fb51c945..3b4f79ced 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -47,16 +47,22 @@ public: { SNAPSHOT_FORMAT_PNG, SNAPSHOT_FORMAT_JPEG, - SNAPSHOT_FORMAT_BMP + SNAPSHOT_FORMAT_BMP, + SNAPSHOT_FORMAT_J2C } ESnapshotFormat; LLFloaterSnapshot(); virtual ~LLFloaterSnapshot(); + LLRect getThumbnailAreaRect(); + /*virtual*/ BOOL postBuild(); /*virtual*/ void draw(); /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void onOpen(); + /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); static void show(void*); static void hide(void*); @@ -66,8 +72,17 @@ public: static S32 getUIWinHeightShort() {return sUIWinHeightShort ;} static S32 getUIWinWidth() {return sUIWinWidth ;} -private: + static void saveStart(int index); + static void saveLocalDone(bool success, int index); + static void saveFeedDone(bool success, int index); + static void savePostcardDone(bool success, int index); + + static void updateControls(); + static void resetFeedAndPostcardAspect(); + class Impl; + +private: Impl& impl; static LLFloaterSnapshot* sInstance; diff --git a/indra/newview/llfloaterteleport.cpp b/indra/newview/llfloaterteleport.cpp index 04ca6d499..dd546c5b0 100644 --- a/indra/newview/llfloaterteleport.cpp +++ b/indra/newview/llfloaterteleport.cpp @@ -63,8 +63,7 @@ extern AIHTTPTimeoutPolicy placeAvatarTeleportResponder_timeout; // OGPX TODO: should this be combined with the Login responder for rez_avatar/place? // OGPX TODO: mResult should not get replaced in result(), instead // should replace individual LLSD fields in mResult. -class LLPlaceAvatarTeleportResponder : - public LLHTTPClient::ResponderWithResult +class LLPlaceAvatarTeleportResponder : public LLHTTPClient::ResponderWithResult { public: LLPlaceAvatarTeleportResponder() @@ -75,7 +74,7 @@ public: { } - void error(U32 statusNum, const std::string& reason) + /*virtual*/ void error(U32 statusNum, const std::string& reason) { LL_INFOS("OGPX") << "LLPlaceAvatarTeleportResponder error in TP " << statusNum << " " << reason << LL_ENDL; @@ -90,7 +89,7 @@ public: } - void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { LLSD result; @@ -221,7 +220,8 @@ public: } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return placeAvatarTeleportResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return placeAvatarTeleportResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLPlaceAvatarTeleportResponder"; } }; // Statics diff --git a/indra/newview/llfloaterteleporthistory.cpp b/indra/newview/llfloaterteleporthistory.cpp index 14ddd9541..6f3d06407 100644 --- a/indra/newview/llfloaterteleporthistory.cpp +++ b/indra/newview/llfloaterteleporthistory.cpp @@ -96,8 +96,8 @@ BOOL LLFloaterTeleportHistory::postBuild() } // setup callbacks for the scroll list - mPlacesList->setDoubleClickCallback(onTeleport); - childSetCommitCallback("places_list", onPlacesSelected, this); + mPlacesList->setDoubleClickCallback(boost::bind(&LLFloaterTeleportHistory::onTeleport,this)); + mPlacesList->setCommitCallback(boost::bind(&LLFloaterTeleportHistory::onPlacesSelected,_1,this)); childSetAction("teleport", onTeleport, this); childSetAction("show_on_map", onShowOnMap, this); childSetAction("copy_slurl", onCopySLURL, this); diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 1219176d6..f52b0960c 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -277,6 +277,8 @@ BOOL LLFloaterTools::postBuild() mComboGridMode = getChild("combobox grid mode"); childSetCommitCallback("combobox grid mode",commit_grid_mode, this); + mCheckShowHighlight = getChild("checkbox show highlight"); + mCheckActualRoot = getChild("checkbox actual root"); // // Create Buttons // @@ -382,6 +384,8 @@ LLFloaterTools::LLFloaterTools() mCheckStretchUniform(NULL), mCheckStretchTexture(NULL), mCheckLimitDrag(NULL), + mCheckShowHighlight(NULL), + mCheckActualRoot(NULL), mBtnRotateLeft(NULL), mBtnRotateReset(NULL), @@ -712,6 +716,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) if (mCheckStretchUniform) mCheckStretchUniform->setVisible( edit_visible ); if (mCheckStretchTexture) mCheckStretchTexture->setVisible( edit_visible ); if (mCheckLimitDrag) mCheckLimitDrag->setVisible( edit_visible ); + if (mCheckShowHighlight) mCheckShowHighlight->setVisible(edit_visible); + if (mCheckActualRoot) mCheckActualRoot->setVisible(edit_visible); // Create buttons BOOL create_visible = (tool == LLToolCompCreate::getInstance()); diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 085a2774e..90cdf83eb 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -143,6 +143,8 @@ public: LLCheckBoxCtrl* mCheckStretchUniform; LLCheckBoxCtrl* mCheckStretchTexture; LLCheckBoxCtrl* mCheckLimitDrag; + LLCheckBoxCtrl* mCheckShowHighlight; + LLCheckBoxCtrl* mCheckActualRoot; LLButton *mBtnRotateLeft; diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 8abbc2d26..e737b3d56 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -92,12 +92,13 @@ LLFloaterTopObjects::~LLFloaterTopObjects() // virtual BOOL LLFloaterTopObjects::postBuild() { - childSetCommitCallback("objects_list", onCommitObjectsList, this); - childSetDoubleClickCallback("objects_list", onDoubleClickObjectsList); - childSetFocus("objects_list"); + LLScrollListCtrl *objects_list = getChild("objects_list"); if (objects_list) { + objects_list->setCommitCallback(boost::bind(&LLFloaterTopObjects::onCommitObjectsList,_1,this)); + objects_list->setDoubleClickCallback(boost::bind(&LLFloaterTopObjects::onDoubleClickObjectsList,this)); + objects_list->setFocus(true); objects_list->setCommitOnSelectionChange(TRUE); } @@ -249,7 +250,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) if (total_count == 0 && list->getItemCount() == 0) { - list->addCommentText(getString("none_descriptor")); + list->setCommentText(getString("none_descriptor")); } else { diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index e5237e8f2..e58b1783e 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -113,13 +113,13 @@ class LLIamHere : public LLHTTPClient::ResponderWithResult mParent = parentIn; }; - virtual void result( const LLSD& content ) + /*virtual*/ void result( const LLSD& content ) { if ( mParent ) mParent->setSiteIsAlive( true ); }; - virtual void error( U32 status, const std::string& reason ) + /*virtual*/ void error( U32 status, const std::string& reason ) { if ( mParent ) { @@ -131,7 +131,8 @@ class LLIamHere : public LLHTTPClient::ResponderWithResult } }; - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return iamHere_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return iamHere_timeout; } + /*virtual*/ char const* getName(void) const { return "LLIamHere"; } }; // this is global and not a class member to keep crud out of the header file diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp index 60d6ad963..122cfd60f 100644 --- a/indra/newview/llfloaterurlentry.cpp +++ b/indra/newview/llfloaterurlentry.cpp @@ -62,7 +62,7 @@ public: LLHandle mParent; - virtual void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { if (200 <= status && status < 300) { @@ -89,7 +89,9 @@ public: floater_url_entry->headerFetchComplete( status, resolved_mime_type ); } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return mediaTypeResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return mediaTypeResponder_timeout; } + + /*virtual*/ char const* getName(void) const { return "LLMediaTypeResponder"; } }; //----------------------------------------------------------------------------- diff --git a/indra/newview/llfloatervfs.cpp b/indra/newview/llfloatervfs.cpp index 86138c0c2..12dc0e08c 100644 --- a/indra/newview/llfloatervfs.cpp +++ b/indra/newview/llfloatervfs.cpp @@ -275,7 +275,7 @@ void LLFloaterVFS::onClickAdd_continued(void* user_data, AIFilePicker* filepicke return; } LLPointer imagep = new LLViewerFetchedTexture(asset_id); - imagep->createGLTexture(0, image_raw, 0, TRUE, LLViewerTexture::BOOST_NONE); + imagep->createGLTexture(0, image_raw, 0, TRUE, LLGLTexture::BOOST_NONE); gTextureList.addImage(imagep); } else diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index d541a93e5..0cd3906fb 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -70,6 +70,7 @@ #include "llviewerregion.h" #include "llviewerstats.h" #include "llworldmap.h" +#include "llworldmapmessage.h" #include "llworldmapview.h" #include "lluictrlfactory.h" #include "llappviewer.h" @@ -88,6 +89,21 @@ //--------------------------------------------------------------------------- static const F32 MAP_ZOOM_TIME = 0.2f; +// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed +// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across +// sessions and doesn't prevent the user to pan the world if it was to grow a lot beyond that limit. +// Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window. +static const S32 MAX_VISIBLE_REGIONS = 512; + +// It would be more logical to have this inside the method where it is used but to compile under gcc this +// struct has to be here. +struct SortRegionNames +{ + inline bool operator ()(std::pair const& _left, std::pair const& _right) + { + return(LLStringUtil::compareInsensitive(_left.second->getName(), _right.second->getName()) < 0); + } +}; enum EPanDirection { PAN_UP, @@ -97,17 +113,10 @@ enum EPanDirection }; // Values in pixels per region -static const F32 ZOOM_MIN = -8.f; // initial value, updated by adjustZoomSlider -static const F32 ZOOM_MAX = 0.f; -static const F32 ZOOM_INC = 0.2f; +static const F32 ZOOM_MAX = 128.f; -static const F32 SIM_COORD_MIN = 0.f; -static const F32 SIM_COORD_MAX = 255.f; static const F32 SIM_COORD_DEFAULT = 128.f; -static const F64 MAX_FLY_DISTANCE = 363.f; // Diagonal size of one sim. -static const F64 MAX_FLY_DISTANCE_SQUARED = MAX_FLY_DISTANCE * MAX_FLY_DISTANCE; - //--------------------------------------------------------------------------- // Globals //--------------------------------------------------------------------------- @@ -166,13 +175,16 @@ LLFloaterWorldMap::LLFloaterWorldMap() mInventory(NULL), mInventoryObserver(NULL), mFriendObserver(NULL), - mCompletingRegionName(""), + mCompletingRegionName(), + mCompletingRegionPos(), mWaitingForTracker(FALSE), - mExactMatch(FALSE), mIsClosing(FALSE), mSetToUserPosition(TRUE), mTrackedLocation(0,0,0), - mTrackedStatus(LLTracker::TRACKING_NOTHING) + mTrackedStatus(LLTracker::TRACKING_NOTHING), + mListFriendCombo(NULL), + mListLandmarkCombo(NULL), + mListSearchResults(NULL) { LLCallbackMap::map_t factory_map; factory_map["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL); @@ -197,54 +209,54 @@ BOOL LLFloaterWorldMap::postBuild() mPanel = getChild("objects_mapview"); - childSetCommitCallback("friend combo", onAvatarComboCommit, this); - LLComboBox *avatar_combo = getChild("friend combo"); - if (avatar_combo) - { - avatar_combo->selectFirstItem(); - avatar_combo->setPrearrangeCallback( onAvatarComboPrearrange ); - avatar_combo->setTextEntryCallback( onComboTextEntry ); - } - - childSetAction("DoSearch", onLocationCommit, this); - + avatar_combo->selectFirstItem(); + avatar_combo->setPrearrangeCallback( onAvatarComboPrearrange ); + avatar_combo->setTextEntryCallback( onComboTextEntry ); + mListFriendCombo = dynamic_cast(avatar_combo); + LLLineEditor *location_editor = getChild("location"); location_editor->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1)); location_editor->setKeystrokeCallback( onSearchTextEntry ); - childSetCommitCallback("search_results", onCommitSearchResult, this); - childSetDoubleClickCallback("search_results", onClickTeleportBtn); - childSetCommitCallback("spin x", onCommitLocation, this); - childSetCommitCallback("spin y", onCommitLocation, this); - childSetCommitCallback("spin z", onCommitLocation, this); - - childSetCommitCallback("landmark combo", onLandmarkComboCommit, this); + LLScrollListCtrl* search_results = getChild("search_results"); + search_results->setDoubleClickCallback(boost::bind(&LLFloaterWorldMap::onClickTeleportBtn,this)); + mListSearchResults = dynamic_cast(search_results); LLComboBox *landmark_combo = getChild( "landmark combo"); - if (landmark_combo) - { - landmark_combo->selectFirstItem(); - landmark_combo->setPrearrangeCallback( onLandmarkComboPrearrange ); - landmark_combo->setTextEntryCallback( onComboTextEntry ); - } - childSetAction("Go Home", onGoHome, this); + landmark_combo->selectFirstItem(); + landmark_combo->setPrearrangeCallback( onLandmarkComboPrearrange ); + landmark_combo->setTextEntryCallback( onComboTextEntry ); + mListLandmarkCombo = dynamic_cast(landmark_combo); + + avatar_combo->setCommitCallback( boost::bind(&LLFloaterWorldMap::onAvatarComboCommit,this) ); + + search_results->setCommitCallback( boost::bind(&LLFloaterWorldMap::onCommitSearchResult,this) ); + + landmark_combo->setCommitCallback( boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit,this) ); + + getChild("spin x")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCoordinatesCommit,this) ); + getChild("spin y")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCoordinatesCommit,this) ); + getChild("spin z")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCoordinatesCommit,this) ); + + getChild("DoSearch")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onLocationCommit,this) ); + getChild("Go Home")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onGoHome,this) ); + getChild("Teleport")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onClickTeleportBtn,this) ); + getChild("Show Destination")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onShowTargetBtn,this) ); + getChild("Show My Location")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onShowAgentBtn,this) ); + getChild("Clear")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onClearBtn,this) ); + getChild("copy_slurl")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCopySLURL,this) ); - childSetAction("Teleport", onClickTeleportBtn, this); - - childSetAction("Show Destination", onShowTargetBtn, this); - childSetAction("Show My Location", onShowAgentBtn, this); - childSetAction("Clear", onClearBtn, this); - childSetAction("copy_slurl", onCopySLURL, this); - - mCurZoomVal = log(LLWorldMapView::sMapScale)/log(2.f); - childSetValue("zoom slider", LLWorldMapView::sMapScale); + mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f); + childSetValue("zoom slider", mCurZoomVal); setDefaultBtn(NULL); mZoomTimer.stop(); - + + onChangeMaturity(); + return TRUE; } @@ -253,13 +265,15 @@ LLFloaterWorldMap::~LLFloaterWorldMap() { // All cleaned up by LLView destructor mPanel = NULL; - + // Inventory deletes all observers on shutdown mInventory = NULL; mInventoryObserver = NULL; - + // avatar tracker will delete this for us. mFriendObserver = NULL; + + gFloaterWorldMap = NULL; } @@ -297,14 +311,8 @@ void LLFloaterWorldMap::show(void*, BOOL center_on_target) } map_panel->updateVisibleBlocks(); - // Reload the agent positions when we show the window - LLWorldMap::getInstance()->eraseItems(); - - // Reload any maps that may have changed - LLWorldMap::getInstance()->clearSimFlags(); - - const bool request_from_sim = true; - LLWorldMap::getInstance()->setCurrentLayer(0, request_from_sim); + // Reload items as they may have changed + LLWorldMap::getInstance()->reloadItems(); // We may already have a bounding box for the regions of the world, // so use that to adjust the view. @@ -338,9 +346,7 @@ void LLFloaterWorldMap::show(void*, BOOL center_on_target) // static void LLFloaterWorldMap::reloadIcons(void*) { - LLWorldMap::getInstance()->eraseItems(); - - LLWorldMap::getInstance()->sendMapLayerRequest(); + LLWorldMap::getInstance()->reloadItems(); } @@ -396,9 +402,7 @@ BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { if (!isMinimized() && isFrontmost()) { - LLRect area; - childGetRect("search_results", area); - if(!area.pointInRect(x, y)) + if(mPanel->pointInView(x, y)) { F32 slider_value = (F32)childGetValue("zoom slider").asReal(); slider_value += ((F32)clicks * -0.3333f); @@ -427,20 +431,6 @@ void LLFloaterWorldMap::reshape( S32 width, S32 height, BOOL called_from_parent // virtual void LLFloaterWorldMap::draw() { - // Hide/Show Mature Events controls - childSetVisible("events_mature_icon", gAgent.canAccessMature()); - childSetVisible("events_mature_label", gAgent.canAccessMature()); - childSetVisible("event_mature_chk", gAgent.canAccessMature()); - - childSetVisible("events_adult_icon", gAgent.canAccessMature()); - childSetVisible("events_adult_label", gAgent.canAccessMature()); - childSetVisible("event_adult_chk", gAgent.canAccessMature()); - bool adult_enabled = gAgent.canAccessAdult(); - if (!adult_enabled) - { - childSetValue("event_adult_chk", FALSE); - } - childSetEnabled("event_adult_chk", adult_enabled); // On orientation island, users don't have a home location yet, so don't // let them teleport "home". It dumps them in an often-crowed welcome @@ -481,7 +471,7 @@ void LLFloaterWorldMap::draw() { F64 seconds = LLTimer::getElapsedSeconds(); double value = fmod(seconds, 2); - value = 0.5 + 0.5*cos(value * 3.14159f); + value = 0.5 + 0.5*cos(value * F_PI); LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0); childSetColor("location_icon", loading_color); } @@ -499,36 +489,30 @@ void LLFloaterWorldMap::draw() childSetEnabled("Teleport", (BOOL)tracking_status); // childSetEnabled("Clear", (BOOL)tracking_status); - childSetEnabled("Show Destination", (BOOL)tracking_status || LLWorldMap::getInstance()->mIsTrackingUnknownLocation); + childSetEnabled("Show Destination", (BOOL)tracking_status || LLWorldMap::getInstance()->isTracking()); childSetEnabled("copy_slurl", (mSLURL.size() > 0) ); setMouseOpaque(TRUE); getDragHandle()->setMouseOpaque(TRUE); - + //RN: snaps to zoom value because interpolation caused jitter in the text rendering - F32 interp = 1.f; - if (!mZoomTimer.getStarted()) + if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild("zoom slider")->getValue().asReal()) { - mCurZoomValInterpolationStart = mCurZoomVal; - if (mCurZoomVal < (F32)childGetValue("zoom slider").asReal()) - { - mZoomTimer.start(); - } + mZoomTimer.start(); } - if (mZoomTimer.getStarted()) - { - interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME; - } - if (interp >= 1.f) + F32 interp = mZoomTimer.getStarted() ? mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME : 1.f; + if (interp > 1.f) { interp = 1.f; mZoomTimer.stop(); } - // Interpolate between mCurZoomValInterpolationStart and "zoom slider". - mCurZoomVal = lerp(mCurZoomValInterpolationStart, (F32)childGetValue("zoom slider").asReal(), interp); + mCurZoomVal = lerp(mCurZoomVal, (F32)getChild("zoom slider")->getValue().asReal(), interp); F32 map_scale = 256.f*pow(2.f, mCurZoomVal); LLWorldMapView::setScale( map_scale ); + onChangeMaturity(); + + LLFloater::draw(); } @@ -632,32 +616,37 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); if (!sim_info) { - LLWorldMap::getInstance()->mIsTrackingUnknownLocation = TRUE; - LLWorldMap::getInstance()->mInvalidLocation = FALSE; - LLWorldMap::getInstance()->mUnknownLocation = pos_global; + // We haven't found a region for that point yet, leave the tracking to the world map + LLWorldMap::getInstance()->setTracking(pos_global); LLTracker::stopTracking(NULL); S32 world_x = S32(pos_global.mdV[0] / 256); S32 world_y = S32(pos_global.mdV[1] / 256); - LLWorldMap::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true); + LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true); setDefaultBtn(""); + + // clicked on a non-region - turn off coord display + enableTeleportCoordsDisplay( false ); + return; } if (sim_info->isDown()) { - // Down sim. Show the blue circle of death! - LLWorldMap::getInstance()->mIsTrackingUnknownLocation = TRUE; - LLWorldMap::getInstance()->mUnknownLocation = pos_global; - LLWorldMap::getInstance()->mInvalidLocation = TRUE; + // Down region. Show the blue circle of death! + // i.e. let the world map that this and tell it it's invalid + LLWorldMap::getInstance()->setTracking(pos_global); + LLWorldMap::getInstance()->setTrackingInvalid(); LLTracker::stopTracking(NULL); setDefaultBtn(""); + + // clicked on a down region - turn off coord display + enableTeleportCoordsDisplay( false ); + return; } - + std::string sim_name = sim_info->getName(); - U32 locX, locY; - from_region_handle(sim_info->getHandle(), &locX, &locY); - F32 region_x = pos_global.mdV[VX] - locX; - F32 region_y = pos_global.mdV[VY] - locY; + F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); + F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); std::string full_name = llformat("%s (%d, %d, %d)", // sim_name.c_str(), // [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-04 (RLVa-1.0.0a) @@ -670,13 +659,43 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) std::string tooltip(""); mTrackedStatus = LLTracker::TRACKING_LOCATION; LLTracker::trackLocation(pos_global, full_name, tooltip); - LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE; - LLWorldMap::getInstance()->mIsTrackingDoubleClick = FALSE; - LLWorldMap::getInstance()->mIsTrackingCommit = FALSE; - + LLWorldMap::getInstance()->cancelTracking(); // The floater is taking over the tracking + + LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal(); + updateTeleportCoordsDisplay( coord_pos ); + + // we have a valid region - turn on coord display + enableTeleportCoordsDisplay( true ); + setDefaultBtn("Teleport"); } + +// enable/disable teleport destination coordinates +void LLFloaterWorldMap::enableTeleportCoordsDisplay( bool enabled ) +{ + childSetEnabled("spin x", enabled ); + childSetEnabled("spin y", enabled ); + childSetEnabled("spin z", enabled ); +} + +// update display of teleport destination coordinates - pos is in global coordinates +void LLFloaterWorldMap::updateTeleportCoordsDisplay( const LLVector3d& pos ) +{ + // if we're going to update their value, we should also enable them + enableTeleportCoordsDisplay( true ); + + // convert global specified position to a local one + F32 region_local_x = (F32)fmod( pos.mdV[VX], (F64)REGION_WIDTH_METERS ); + F32 region_local_y = (F32)fmod( pos.mdV[VY], (F64)REGION_WIDTH_METERS ); + F32 region_local_z = (F32)llclamp( pos.mdV[VZ], 0.0, (F64)REGION_HEIGHT_METERS ); + + // write in the values + childSetValue("spin x", region_local_x ); + childSetValue("spin y", region_local_y ); + childSetValue("spin z", region_local_z ); + } + void LLFloaterWorldMap::updateLocation() { bool gotSimName; @@ -703,19 +722,16 @@ void LLFloaterWorldMap::updateLocation() // Fill out the location field childSetValue("location", agent_sim_name); + // update the coordinate display with location of avatar in region + updateTeleportCoordsDisplay( agentPos ); + + S32 x = llround( (F32)fmod( (F32)agentPos[VX], (F32)REGION_WIDTH_METERS ) ); + S32 y = llround( (F32)fmod( (F32)agentPos[VY], (F32)REGION_WIDTH_METERS ) ); + S32 z = llround( (F32)agentPos[VZ] ); + // Figure out where user is - LLVector3d agentPos = gAgent.getPositionGlobal(); - - S32 agent_x = llround( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) ); - S32 agent_y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) ); - S32 agent_z = llround( (F32)agentPos.mdV[VZ] ); - - childSetValue("spin x", LLSD(agent_x) ); - childSetValue("spin y", LLSD(agent_y) ); - childSetValue("spin z", LLSD(agent_z) ); - // Set the current SLURL - mSLURL = LLURLDispatcher::buildSLURL(agent_sim_name, agent_x, agent_y, agent_z); + mSLURL = LLURLDispatcher::buildSLURL(agent_sim_name, x, y, z); // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) @@ -751,16 +767,18 @@ void LLFloaterWorldMap::updateLocation() childSetValue("location", sim_name); - F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); - F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); - childSetValue("spin x", LLSD(region_x) ); - childSetValue("spin y", LLSD(region_y) ); - childSetValue("spin z", LLSD((F32)pos_global.mdV[VZ]) ); - + // refresh coordinate display to reflect where user clicked. + LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal(); + updateTeleportCoordsDisplay( coord_pos ); + // simNameFromPosGlobal can fail, so don't give the user an invalid SLURL if ( gotSimName ) { - mSLURL = LLURLDispatcher::buildSLURL(sim_name, llround(region_x), llround(region_y), llround((F32)pos_global.mdV[VZ])); + LLVector3d agentPos = gAgent.getPositionGlobal(); + S32 x = llround( (F32)fmod( (F32)agentPos[VX], (F32)REGION_WIDTH_METERS ) ); + S32 y = llround( (F32)fmod( (F32)agentPos[VY], (F32)REGION_WIDTH_METERS ) ); + S32 z = llround( (F32)agentPos[VZ] ); + mSLURL = LLURLDispatcher::buildSLURL(sim_name, x, y, z); } else { // Empty SLURL will disable the "Copy SLURL to clipboard" button @@ -795,15 +813,17 @@ void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S3 { // fill in UI based on URL gFloaterWorldMap->childSetValue("location", region_name); - childSetValue("spin x", LLSD((F32)x_coord)); - childSetValue("spin y", LLSD((F32)y_coord)); - childSetValue("spin z", LLSD((F32)z_coord)); + + // Save local coords to highlight position after region global + // position is returned. + gFloaterWorldMap->mCompletingRegionPos.set( + (F32)x_coord, (F32)y_coord, (F32)z_coord); // pass sim name to combo box gFloaterWorldMap->mCompletingRegionName = region_name; - LLWorldMap::getInstance()->sendNamedRegionRequest(region_name); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name); LLStringUtil::toLower(gFloaterWorldMap->mCompletingRegionName); - LLWorldMap::getInstance()->mIsTrackingCommit = TRUE; + LLWorldMap::getInstance()->setTrackingCommit(); } } @@ -868,9 +888,9 @@ void LLFloaterWorldMap::friendsChanged() // No longer really builds a list. Instead, just updates mAvatarCombo. void LLFloaterWorldMap::buildAvatarIDList() { - LLCtrlListInterface *list = childGetListInterface("friend combo"); + LLCtrlListInterface *list = mListFriendCombo; if (!list) return; - + // Delete all but the "None" entry S32 list_size = list->getItemCount(); if (list_size > 1) @@ -879,12 +899,6 @@ void LLFloaterWorldMap::buildAvatarIDList() list->operateOnSelection(LLCtrlListInterface::OP_DELETE); } - LLSD default_column; - default_column["name"] = "friend name"; - default_column["label"] = "Friend Name"; - default_column["width"] = 500; - list->addColumn(default_column); - // Get all of the calling cards for avatar that are currently online LLCollectMappableBuddies collector; LLAvatarTracker::instance().applyFunctor(collector); @@ -904,12 +918,9 @@ void LLFloaterWorldMap::buildAvatarIDList() void LLFloaterWorldMap::buildLandmarkIDLists() { - LLCtrlListInterface *list = childGetListInterface("landmark combo"); - if (!list) - { - return; - } - + LLCtrlListInterface *list = mListLandmarkCombo; + if (!list) return; + // Delete all but the "None" entry S32 list_size = list->getItemCount(); if (list_size > 1) @@ -969,7 +980,7 @@ F32 LLFloaterWorldMap::getDistanceToDestination(const LLVector3d &destination, void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui) { - LLCtrlListInterface *list = childGetListInterface("search_results"); + LLCtrlListInterface *list = mListSearchResults; if (list) { list->operateOnAll(LLCtrlListInterface::OP_DELETE); @@ -986,9 +997,9 @@ void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui) { childSetValue("spin z", 0); } - LLWorldMap::getInstance()->mIsTrackingCommit = FALSE; + //Singu Note: Don't do this. It basically 'eats' the first click onto void space if the previous tracked target was a valid sim. + //LLWorldMap::getInstance()->cancelTracking(); mCompletingRegionName = ""; - mExactMatch = FALSE; } @@ -996,7 +1007,7 @@ void LLFloaterWorldMap::clearLandmarkSelection(BOOL clear_ui) { if (clear_ui || !childHasKeyboardFocus("landmark combo")) { - LLCtrlListInterface *list = childGetListInterface("landmark combo"); + LLCtrlListInterface *list = mListLandmarkCombo; if (list) { list->selectByValue( "None" ); @@ -1010,7 +1021,7 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui) if (clear_ui || !childHasKeyboardFocus("friend combo")) { mTrackedStatus = LLTracker::TRACKING_NOTHING; - LLCtrlListInterface *list = childGetListInterface("friend combo"); + LLCtrlListInterface *list = mListFriendCombo; if (list) { list->selectByValue( "None" ); @@ -1023,22 +1034,22 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui) // can see the whole world, plus a little. void LLFloaterWorldMap::adjustZoomSliderBounds() { - // World size in regions - S32 world_width_regions = LLWorldMap::getInstance()->getWorldWidth() / REGION_WIDTH_UNITS; - S32 world_height_regions = LLWorldMap::getInstance()->getWorldHeight() / REGION_WIDTH_UNITS; - - // Pad the world size a little bit, so we have a nice border on - // the edge - world_width_regions++; - world_height_regions++; - + // Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed + // width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across + // sessions and doesn't prevent the user to pan the world if it was to grow a lot beyond that limit. + // Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window. + S32 world_width_regions = MAX_VISIBLE_REGIONS; + S32 world_height_regions = MAX_VISIBLE_REGIONS; + // Find how much space we have to display the world - LLRect view_rect = mPanel->getRect(); - + LLWorldMapView* map_panel; + map_panel = (LLWorldMapView*)mPanel; + LLRect view_rect = map_panel->getRect(); + // View size in pixels S32 view_width = view_rect.getWidth(); S32 view_height = view_rect.getHeight(); - + // Pixels per region to display entire width/height F32 width_pixels_per_region = (F32) view_width / (F32) world_width_regions; F32 height_pixels_per_region = (F32) view_height / (F32) world_height_regions; @@ -1052,9 +1063,10 @@ void LLFloaterWorldMap::adjustZoomSliderBounds() // Make sure the zoom slider can be moved at least a little bit. // Likewise, less than the increment pixels per region is just silly. - pixels_per_region = llclamp(pixels_per_region, 1.f, (F32)(pow(2.f, ZOOM_MAX) * 128.f)); - + pixels_per_region = llclamp(pixels_per_region, 1.f, ZOOM_MAX); + F32 min_power = log(pixels_per_region/256.f)/log(2.f); + childSetMinValue("zoom slider", min_power); } @@ -1063,34 +1075,10 @@ void LLFloaterWorldMap::adjustZoomSliderBounds() // User interface widget callbacks //------------------------------------------------------------------------- -// static -void LLFloaterWorldMap::onPanBtn( void* userdata ) -{ - if( !gFloaterWorldMap ) return; - - EPanDirection direction = (EPanDirection)(intptr_t)userdata; - - S32 pan_x = 0; - S32 pan_y = 0; - switch( direction ) - { - case PAN_UP: pan_y = -1; break; - case PAN_DOWN: pan_y = 1; break; - case PAN_LEFT: pan_x = 1; break; - case PAN_RIGHT: pan_x = -1; break; - default: llassert(0); return; - } - - LLWorldMapView* map_panel; - map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; - map_panel->translatePan( pan_x, pan_y ); -} - -// static -void LLFloaterWorldMap::onGoHome(void*) +void LLFloaterWorldMap::onGoHome() { gAgent.teleportHome(); - gFloaterWorldMap->close(); + close(); } @@ -1122,7 +1110,7 @@ void LLFloaterWorldMap::onComboTextEntry( LLLineEditor* ctrl, void* userdata ) // Reset the tracking whenever we start typing into any of the search fields, // so that hitting does an auto-complete versus teleporting us to the // previously selected landmark/friend. - LLTracker::clearFocus(); + LLTracker::stopTracking(NULL); } // static @@ -1133,16 +1121,14 @@ void LLFloaterWorldMap::onSearchTextEntry( LLLineEditor* ctrl, void* userdata ) } // static -void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata ) +void LLFloaterWorldMap::onLandmarkComboCommit() { - LLFloaterWorldMap* self = gFloaterWorldMap; - - if( !self || self->mIsClosing ) + if( mIsClosing ) { return; } - - LLCtrlListInterface *list = gFloaterWorldMap->childGetListInterface("landmark combo"); + + LLCtrlListInterface *list = mListLandmarkCombo; if (!list) return; LLUUID asset_id; @@ -1174,11 +1160,11 @@ void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata ) } } - self->trackLandmark( item_id); - onShowTargetBtn(self); - + trackLandmark( item_id); + onShowTargetBtn(); + // Reset to user postion if nothing is tracked - self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); + mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); } // static @@ -1208,31 +1194,28 @@ void LLFloaterWorldMap::onAvatarComboPrearrange( LLUICtrl* ctrl, void* userdata } } - -// static -void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata ) +void LLFloaterWorldMap::onAvatarComboCommit() { - LLFloaterWorldMap* self = gFloaterWorldMap; - if( !self || self->mIsClosing ) + if( mIsClosing ) { return; } - - LLCtrlListInterface *list = gFloaterWorldMap->childGetListInterface("friend combo"); + + LLCtrlListInterface *list = mListFriendCombo; if (!list) return; - + const LLUUID& new_avatar_id = list->getCurrentID(); if (new_avatar_id.notNull()) { std::string name; - LLComboBox* combo = gFloaterWorldMap->getChild("friend combo"); + LLComboBox* combo = getChild("friend combo"); if (combo) name = combo->getSimple(); - self->trackAvatar(new_avatar_id, name); - onShowTargetBtn(self); + trackAvatar(new_avatar_id, name); + onShowTargetBtn(); } else { // Reset to user postion if nothing is tracked - self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); + mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); } } @@ -1254,105 +1237,99 @@ void LLFloaterWorldMap::updateSearchEnabled() } } -// static -void LLFloaterWorldMap::onLocationCommit( void* userdata ) +void LLFloaterWorldMap::onLocationCommit() { - LLFloaterWorldMap *self = gFloaterWorldMap; - if( !self || self->mIsClosing ) + if( mIsClosing ) { return; } + + clearLocationSelection(FALSE); + mCompletingRegionName = ""; + mLastRegionName = ""; - self->clearLocationSelection(FALSE); - self->mCompletingRegionName = ""; - self->mLastRegionName = ""; - - std::string str = self->childGetValue("location").asString(); + std::string str = childGetValue("location").asString(); // Trim any leading and trailing spaces in the search target std::string saved_str = str; LLStringUtil::trim( str ); if ( str != saved_str ) { // Set the value in the UI if any spaces were removed - self->childSetValue("location", str); + childSetValue("location", str); + } + + // Don't try completing empty name (STORM-1427). + if (str.empty()) + { + return; } LLStringUtil::toLower(str); - gFloaterWorldMap->mCompletingRegionName = str; - LLWorldMap::getInstance()->mIsTrackingCommit = TRUE; - self->mExactMatch = FALSE; + mCompletingRegionName = str; + LLWorldMap::getInstance()->setTrackingCommit(); if (str.length() >= 3) { - LLWorldMap::getInstance()->sendNamedRegionRequest(str); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str); } else { str += "#"; - LLWorldMap::getInstance()->sendNamedRegionRequest(str); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str); } } - -// static -void LLFloaterWorldMap::onClearBtn(void* data) +void LLFloaterWorldMap::onCoordinatesCommit() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->mTrackedStatus = LLTracker::TRACKING_NOTHING; + if( mIsClosing ) + { + return; + } + + S32 x_coord = (S32)childGetValue("spin x").asReal(); + S32 y_coord = (S32)childGetValue("spin y").asReal(); + S32 z_coord = (S32)childGetValue("spin z").asReal(); + + const std::string region_name = childGetValue("location").asString(); + + trackURL( region_name, x_coord, y_coord, z_coord ); +} + +void LLFloaterWorldMap::onClearBtn() +{ + mTrackedStatus = LLTracker::TRACKING_NOTHING; LLTracker::stopTracking((void *)(intptr_t)TRUE); - LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE; - self->mSLURL = ""; // Clear the SLURL since it's invalid - self->mSetToUserPosition = TRUE; // Revert back to the current user position + LLWorldMap::getInstance()->cancelTracking(); + mSLURL = ""; // Clear the SLURL since it's invalid + mSetToUserPosition = TRUE; // Revert back to the current user position } -// static -void LLFloaterWorldMap::onFlyBtn(void* data) +void LLFloaterWorldMap::onShowTargetBtn() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->fly(); + centerOnTarget(TRUE); } -void LLFloaterWorldMap::onShowTargetBtn(void* data) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->centerOnTarget(TRUE); -} - -void LLFloaterWorldMap::onShowAgentBtn(void* data) +void LLFloaterWorldMap::onShowAgentBtn() { LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate - // Set flag so user's location will be displayed if not tracking anything else - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->mSetToUserPosition = TRUE; + mSetToUserPosition = TRUE; } -// static -void LLFloaterWorldMap::onClickTeleportBtn(void* data) +void LLFloaterWorldMap::onClickTeleportBtn() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->teleport(); + teleport(); } -// static -void LLFloaterWorldMap::onCopySLURL(void* data) +void LLFloaterWorldMap::onCopySLURL() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(self->mSLURL)); + getWindow()->copyTextToClipboard(utf8str_to_wstring(mSLURL)); LLSD args; - args["SLURL"] = self->mSLURL; + args["SLURL"] = mSLURL; LLNotificationsUtil::add("CopySLURL", args); } -void LLFloaterWorldMap::onCheckEvents(LLUICtrl*, void* data) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - if(!self) return; - self->childSetEnabled("event_mature_chk", self->childGetValue("event_chk")); - self->childSetEnabled("event_adult_chk", self->childGetValue("event_chk")); -} - // protected void LLFloaterWorldMap::centerOnTarget(BOOL animate) { @@ -1374,9 +1351,12 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate) pos_global = LLTracker::getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal(); } } - else if(LLWorldMap::getInstance()->mIsTrackingUnknownLocation) + else if(LLWorldMap::getInstance()->isTracking()) { - pos_global = LLWorldMap::getInstance()->mUnknownLocation - gAgentCamera.getCameraPositionGlobal();; + pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();; + + + } else { @@ -1472,24 +1452,6 @@ void LLFloaterWorldMap::teleport() } } -// static -void LLFloaterWorldMap::onGoToLandmarkDialog( S32 option, void* userdata ) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; - switch( option ) - { - case 0: - self->teleportToLandmark(); - break; - case 1: - self->flyToLandmark(); - break; - default: - // nothing - break; - } -} - void LLFloaterWorldMap::flyToLandmark() { LLVector3d destination_pos_global; @@ -1570,94 +1532,72 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) LLScrollListCtrl *list = getChild("search_results"); list->operateOnAll(LLCtrlListInterface::OP_DELETE); - - LLSD selected_value = list->getSelectedValue(); - + S32 name_length = mCompletingRegionName.length(); + + LLSD match; - BOOL match_found = FALSE; S32 num_results = 0; - std::map::const_iterator it; - for (it = LLWorldMap::getInstance()->getRegionMap().begin(); it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) + + std::vector > sim_info_vec(LLWorldMap::getInstance()->getRegionMap().begin(), LLWorldMap::getInstance()->getRegionMap().end()); + std::sort(sim_info_vec.begin(), sim_info_vec.end(), SortRegionNames()); + + for (std::vector >::const_iterator it = sim_info_vec.begin(); it != sim_info_vec.end(); ++it) { - LLSimInfo* info = (*it).second; - std::string sim_name = info->getName(); - std::string sim_name_lower = sim_name; + LLSimInfo* info = it->second; + std::string sim_name_lower = info->getName(); LLStringUtil::toLower(sim_name_lower); if (sim_name_lower.substr(0, name_length) == mCompletingRegionName) { - if (LLWorldMap::getInstance()->mIsTrackingCommit) + if (sim_name_lower == mCompletingRegionName) { - if (sim_name_lower == mCompletingRegionName) - { - selected_value = sim_name; - match_found = TRUE; - } + match = info->getName(); } LLSD value; - value["id"] = sim_name; + value["id"] = info->getName(); value["columns"][0]["column"] = "sim_name"; - value["columns"][0]["value"] = sim_name; + value["columns"][0]["value"] = info->getName(); list->addElement(value); num_results++; } } - list->selectByValue(selected_value); - - if (found_null_sim) + if (found_null_sim || match.isDefined()) { mCompletingRegionName = ""; } - - if (match_found) + + if (num_results > 0) { - mExactMatch = TRUE; + // if match found, highlight it and go + if (!match.isUndefined()) + { + list->selectByValue(match); + } + // else select first found item + else + { + list->selectFirstItem(); + } childSetFocus("search_results"); - onCommitSearchResult(NULL, this); - } - else if (!mExactMatch && num_results > 0) - { - list->selectFirstItem(); // select first item by default - childSetFocus("search_results"); - onCommitSearchResult(NULL, this); + onCommitSearchResult(); } else { // if we found nothing, say "none" - list->addCommentText(LLTrans::getString("worldmap_results_none_found")); + list->setCommentText(LLTrans::getString("worldmap_results_none_found")); list->operateOnAll(LLCtrlListInterface::OP_DESELECT); } } -// static -void LLFloaterWorldMap::onCommitLocation(LLUICtrl* ctrl, void* userdata) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; - LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); - if ( LLTracker::TRACKING_LOCATION == tracking_status) - { - LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); - F64 local_x = self->childGetValue("spin x"); - F64 local_y = self->childGetValue("spin y"); - F64 local_z = self->childGetValue("spin z"); - pos_global.mdV[VX] += -fmod(pos_global.mdV[VX], 256.0) + local_x; - pos_global.mdV[VY] += -fmod(pos_global.mdV[VY], 256.0) + local_y; - pos_global.mdV[VZ] = local_z; - self->trackLocation(pos_global); - } -} -// static -void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata) +void LLFloaterWorldMap::onCommitSearchResult() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; - - LLCtrlListInterface *list = self->childGetListInterface("search_results"); + LLCtrlListInterface *list = mListSearchResults; if (!list) return; - + LLSD selected_value = list->getSelectedValue(); std::string sim_name = selected_value.asString(); if (sim_name.empty()) @@ -1674,19 +1614,52 @@ void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata) if (info->isName(sim_name)) { LLVector3d pos_global = info->getGlobalOrigin(); - F64 local_x = self->childGetValue("spin x"); - F64 local_y = self->childGetValue("spin y"); - F64 local_z = self->childGetValue("spin z"); - pos_global.mdV[VX] += local_x; - pos_global.mdV[VY] += local_y; - pos_global.mdV[VZ] = local_z; + + const F64 SIM_COORD_DEFAULT = 128.0; + LLVector3 pos_local(SIM_COORD_DEFAULT, SIM_COORD_DEFAULT, 0.0f); + + // Did this value come from a trackURL() request? + if (!mCompletingRegionPos.isExactlyZero()) + { + pos_local = mCompletingRegionPos; + mCompletingRegionPos.clear(); + } + pos_global.mdV[VX] += (F64)pos_local.mV[VX]; + pos_global.mdV[VY] += (F64)pos_local.mV[VY]; + pos_global.mdV[VZ] = (F64)pos_local.mV[VZ]; - self->childSetValue("location", sim_name); - self->trackLocation(pos_global); - self->setDefaultBtn("Teleport"); + childSetValue("location", sim_name); + trackLocation(pos_global); + setDefaultBtn("Teleport"); break; } } - onShowTargetBtn(self); + onShowTargetBtn(); +} + +void LLFloaterWorldMap::onChangeMaturity() +{ + bool can_access_mature = gAgent.canAccessMature(); + bool can_access_adult = gAgent.canAccessAdult(); + + childSetVisible("events_mature_icon", can_access_mature); + childSetVisible("events_mature_label", can_access_mature); + childSetVisible("event_mature_chk", can_access_mature); + + childSetVisible("events_adult_icon", can_access_adult); + childSetVisible("events_adult_label", can_access_adult); + childSetVisible("event_adult_chk", can_access_adult); + + // disable mature / adult events. + if (!can_access_mature) + { + static LLCachedControl show_mature("MapShowMatureEvents",false); + show_mature = false; + } + if (!can_access_adult) + { + static LLCachedControl show_adult("MapShowAdultEvents",false); + show_adult = false; + } } diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 80cc25abd..53cd425b7 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -111,29 +111,25 @@ public: // teleport to the tracked item, if there is one void teleport(); + void onChangeMaturity(); -protected: - static void onPanBtn( void* userdata ); - - static void onGoHome(void* data); +protected: + void onGoHome(); static void onLandmarkComboPrearrange( LLUICtrl* ctrl, void* data ); - static void onLandmarkComboCommit( LLUICtrl* ctrl, void* data ); + void onLandmarkComboCommit(); static void onAvatarComboPrearrange( LLUICtrl* ctrl, void* data ); - static void onAvatarComboCommit( LLUICtrl* ctrl, void* data ); + void onAvatarComboCommit(); static void onComboTextEntry( LLLineEditor* ctrl, void* data ); static void onSearchTextEntry( LLLineEditor* ctrl, void* data ); - static void onClearBtn(void*); - static void onFlyBtn(void*); - static void onClickTeleportBtn(void*); - static void onShowTargetBtn(void*); - static void onShowAgentBtn(void*); - static void onCopySLURL(void*); - - static void onCheckEvents(LLUICtrl* ctrl, void*); + void onClearBtn(); + void onClickTeleportBtn(); + void onShowTargetBtn(); + void onShowAgentBtn(); + void onCopySLURL(); void centerOnTarget(BOOL animate); void updateLocation(); @@ -142,7 +138,6 @@ protected: void fly(); void buildLandmarkIDLists(); - static void onGoToLandmarkDialog(S32 option,void* userdata); void flyToLandmark(); void teleportToLandmark(); void setLandmarkVisited(); @@ -152,24 +147,28 @@ protected: void teleportToAvatar(); void updateSearchEnabled(); - void onLocationFocusChanged( LLFocusableElement* focus ); - static void onLocationCommit( void* userdata ); - static void onCommitLocation( LLUICtrl* ctrl, void* userdata ); - static void onCommitSearchResult( LLUICtrl* ctrl, void* userdata ); + void onLocationFocusChanged( LLFocusableElement* ctrl ); + void onLocationCommit(); + void onCoordinatesCommit(); + void onCommitSearchResult(); void cacheLandmarkPosition(); -protected: - LLPanel* mPanel; // Panel displaying the map +private: + LLPanel* mPanel; // Panel displaying the map // Sets sMapScale, in pixels per region F32 mCurZoomVal; - F32 mCurZoomValInterpolationStart; // Used during mZoomTimer interpolation. LLFrameTimer mZoomTimer; + // update display of teleport destination coordinates - pos is in global coordinates + void updateTeleportCoordsDisplay( const LLVector3d& pos ); + + // enable/disable teleport destination coordinates + void enableTeleportCoordsDisplay( bool enabled ); + LLDynamicArray mLandmarkAssetIDList; LLDynamicArray mLandmarkItemIDList; - BOOL mHasLandmarkPosition; static const LLUUID sHomeID; @@ -178,9 +177,12 @@ protected: LLFriendObserver* mFriendObserver; std::string mCompletingRegionName; + // Local position from trackURL() request, used to select final + // position once region lookup complete. + LLVector3 mCompletingRegionPos; + std::string mLastRegionName; BOOL mWaitingForTracker; - BOOL mExactMatch; BOOL mIsClosing; BOOL mSetToUserPosition; @@ -190,6 +192,10 @@ protected: std::string mTrackedSimName; std::string mTrackedAvatarName; std::string mSLURL; + + LLCtrlListInterface * mListFriendCombo; + LLCtrlListInterface * mListLandmarkCombo; + LLCtrlListInterface * mListSearchResults; }; extern LLFloaterWorldMap* gFloaterWorldMap; diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h index 3bfbf3611..69060653f 100644 --- a/indra/newview/llfoldervieweventlistener.h +++ b/indra/newview/llfoldervieweventlistener.h @@ -77,7 +77,7 @@ public: virtual BOOL copyToClipboard() const = 0; virtual void cutToClipboard() = 0; virtual BOOL isClipboardPasteable() const = 0; - virtual void pasteFromClipboard() = 0; + virtual void pasteFromClipboard(bool only_copies = false) = 0; virtual void pasteLinkFromClipboard() = 0; virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; virtual BOOL isUpToDate() const = 0; diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 852ad01b8..c0f37fe5f 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -342,7 +342,7 @@ void LLGestureMgr::deactivateGesture(const LLUUID& item_id) gAgent.sendReliableMessage(); - LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id, false); + LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id); notifyObservers(); } @@ -792,7 +792,7 @@ void LLGestureMgr::update() if (gesture->mDoneCallback) { - gesture->mDoneCallback(gesture, gesture->mCallbackData); + gesture->mDoneCallback(gesture); // callback might have deleted gesture, can't // rely on this pointer any more @@ -1299,7 +1299,7 @@ void LLGestureMgr::stopGesture(LLMultiGesture* gesture) if (gesture->mDoneCallback) { - gesture->mDoneCallback(gesture, gesture->mCallbackData); + gesture->mDoneCallback(gesture); // callback might have deleted gesture, can't // rely on this pointer any more diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index be658d131..b40e3d471 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -100,10 +100,10 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) S32 top = llmax(y, mDragStartY); S32 bottom =llmin(y, mDragStartY); - left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]); - right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]); - top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]); - bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]); + left = llround((F32) left * LLUI::getScaleFactor().mV[VX]); + right = llround((F32) right * LLUI::getScaleFactor().mV[VX]); + top = llround((F32) top * LLUI::getScaleFactor().mV[VY]); + bottom = llround((F32) bottom * LLUI::getScaleFactor().mV[VY]); F32 old_far_plane = LLViewerCamera::getInstance()->getFar(); F32 old_near_plane = LLViewerCamera::getInstance()->getNear(); diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index c89c414b5..ea0014b1b 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -36,6 +36,7 @@ #include #include +#include "llappviewer.h" //For gFrameCount #include "llagent.h" #include "llui.h" #include "message.h" @@ -44,6 +45,7 @@ #include "llstatusbar.h" #include "lleconomy.h" #include "llviewercontrol.h" +#include "llviewerregion.h" #include "llviewerwindow.h" #include "llfloaterdirectory.h" #include "llfloatergroupinfo.h" @@ -821,6 +823,7 @@ void LLGroupMgrGroupData::cancelRoleChanges() LLGroupMgr::LLGroupMgr() { + mLastGroupMembersRequestFrame = 0; } LLGroupMgr::~LLGroupMgr() @@ -1885,6 +1888,187 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, } } + +class AIHTTPTimeoutPolicy; +extern AIHTTPTimeoutPolicy groupMemberDataResponder_timeout; + +// Responder class for capability group management +class GroupMemberDataResponder : public LLHTTPClient::ResponderWithResult +{ +public: + GroupMemberDataResponder() {} + virtual ~GroupMemberDataResponder() {} + /*virtual*/ void result(const LLSD& pContent); + /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return groupMemberDataResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "GroupMemberDataResponder"; } +private: + LLSD mMemberData; +}; + +void GroupMemberDataResponder::error(U32 pStatus, const std::string& pReason) +{ + LL_WARNS("GrpMgr") << "Error receiving group member data." << LL_ENDL; +} + +void GroupMemberDataResponder::result(const LLSD& content) +{ + LLGroupMgr::processCapGroupMembersRequest(content); +} + + +// static +void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id) +{ + // Have we requested the information already this frame? + if (mLastGroupMembersRequestFrame == gFrameCount) + return; + + LLViewerRegion* currentRegion = gAgent.getRegion(); + // Thank you FS:Ansariel! + if (!currentRegion) + { + LL_WARNS("GrpMgr") << "Agent does not have a current region. Uh-oh!" << LL_ENDL; + return; + } + + // Check to make sure we have our capabilities + if (!currentRegion->capabilitiesReceived()) + { + LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL; + return; + } + + // Get our capability + std::string cap_url = currentRegion->getCapability("GroupMemberData"); + + // Thank you FS:Ansariel! + if (cap_url.empty()) + { + LL_INFOS("GrpMgr") << "Region has no GroupMemberData capability. Falling back to UDP fetch." << LL_ENDL; + sendGroupMembersRequest(group_id); + return; + } + + // Post to our service. Add a body containing the group_id. + LLSD body = LLSD::emptyMap(); + body["group_id"] = group_id; + + LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder(); + + // This could take a while to finish, timeout after 5 minutes. + LLHTTPClient::post(cap_url, body, grp_data_responder); + + mLastGroupMembersRequestFrame = gFrameCount; +} + +// static +void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) +{ + // Did we get anything in content? + if (!content.size()) + { + LL_DEBUGS("GrpMgr") << "No group member data received." << LL_ENDL; + return; + } + + // If we have no members, there's no reason to do anything else + S32 num_members = content["member_count"]; + if (num_members < 1) + return; + + LLUUID group_id = content["group_id"].asUUID(); + + LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id); + if (!group_datap) + { + LL_WARNS("GrpMgr") << "Received incorrect, possibly stale, group or request id" << LL_ENDL; + return; + } + + group_datap->mMemberCount = num_members; + + LLSD member_list = content["members"]; + LLSD titles = content["titles"]; + LLSD defaults = content["defaults"]; + + std::string online_status; + std::string title; + S32 contribution; + U64 member_powers; + // If this is changed to a bool, make sure to change the LLGroupMemberData constructor + BOOL is_owner; + + // Compute this once, rather than every time. + U64 default_powers = llstrtou64(defaults["default_powers"].asString().c_str(), NULL, 16); + + LLSD::map_const_iterator member_iter_start = member_list.beginMap(); + LLSD::map_const_iterator member_iter_end = member_list.endMap(); + for ( ; member_iter_start != member_iter_end; ++member_iter_start) + { + // Reset defaults + online_status = "unknown"; + title = titles[0].asString(); + contribution = 0; + member_powers = default_powers; + is_owner = false; + + const LLUUID member_id(member_iter_start->first); + LLSD member_info = member_iter_start->second; + + if (member_info.has("last_login")) + { + online_status = member_info["last_login"].asString(); + if (online_status == "Online") + online_status = LLTrans::getString("group_member_status_online"); + else + formatDateString(online_status); + } + + if (member_info.has("title")) + title = titles[member_info["title"].asInteger()].asString(); + + if (member_info.has("powers")) + member_powers = llstrtou64(member_info["powers"].asString().c_str(), NULL, 16); + + if (member_info.has("donated_square_meters")) + contribution = member_info["donated_square_meters"]; + + if (member_info.has("owner")) + is_owner = true; + + LLGroupMemberData* data = new LLGroupMemberData(member_id, + contribution, + member_powers, + title, + online_status, + is_owner); + + group_datap->mMembers[member_id] = data; + } + + // Technically, we have this data, but to prevent completely overhauling + // this entire system (it would be nice, but I don't have the time), + // I'm going to be dumb and just call services I most likely don't need + // with the thought being that the system might need it to be done. + // + // TODO: Refactor to reduce multiple calls for data we already have. + if (group_datap->mTitles.size() < 1) + LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id); + + group_datap->mMemberDataComplete = TRUE; + group_datap->mMemberRequestID.setNull(); + // Make the role-member data request + if (group_datap->mPendingRoleMemberRequest) + { + group_datap->mPendingRoleMemberRequest = FALSE; + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id); + } + + group_datap->mChanged = TRUE; + LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA); +} + void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id) { lldebugs << "LLGroupMgr::sendGroupRoleChanges" << llendl; diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index 225db1735..6a18add68 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -335,6 +335,9 @@ public: static void sendGroupMemberEjects(const LLUUID& group_id, uuid_vec_t& member_ids); + void sendCapGroupMembersRequest(const LLUUID& group_id); + static void processCapGroupMembersRequest(const LLSD& content); + void cancelGroupRoleChanges(const LLUUID& group_id); static void processGroupPropertiesReply(LLMessageSystem* msg, void** data); @@ -370,6 +373,8 @@ private: typedef std::set observer_set_t; typedef std::map observer_map_t; observer_map_t mParticularObservers; + + S32 mLastGroupMembersRequestFrame; }; diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h index c9d098740..9ffffc304 100644 --- a/indra/newview/llhomelocationresponder.h +++ b/indra/newview/llhomelocationresponder.h @@ -44,9 +44,10 @@ extern AIHTTPTimeoutPolicy homeLocationResponder_timeout; /* Typedef, Enum, Class, Struct, etc. */ class LLHomeLocationResponder : public LLHTTPClient::ResponderWithResult { - virtual void result( const LLSD& content ); - virtual void error( U32 status, const std::string& reason ); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return homeLocationResponder_timeout; } + /*virtual*/ void result( const LLSD& content ); + /*virtual*/ void error( U32 status, const std::string& reason ); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return homeLocationResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLHomeLocationResponder"; } }; #endif diff --git a/indra/newview/llhoverview.cpp b/indra/newview/llhoverview.cpp index f6cff6f16..fa922a94b 100644 --- a/indra/newview/llhoverview.cpp +++ b/indra/newview/llhoverview.cpp @@ -262,39 +262,16 @@ void LLHoverView::updateText() else { // [/RLVa:KB] - - // [Ansariel: Display name support] - std::string complete_name = firstname->getString(); - complete_name += " "; - complete_name += lastname->getString(); - - if (LLAvatarNameCache::useDisplayNames()) - { - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(hit_object->getID(), &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - if (phoenix_name_system == 2 || (phoenix_name_system == 1 && avatar_name.mIsDisplayNameDefault)) - { - complete_name = avatar_name.mDisplayName; - } - else - { - complete_name = avatar_name.getCompleteName(); - } - } - } - // [/Ansariel: Display name support] + std::string complete_name; + if (!LLAvatarNameCache::getPNSName(hit_object->getID(), complete_name)) + complete_name = firstname->getString() + std::string(" ") + lastname->getString(); if (title) { line.append(title->getString()); line.append(1, ' '); } - - // [Ansariel: Display name support] line += complete_name; - // [/Ansariel: Display name support] // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) } @@ -347,27 +324,13 @@ void LLHoverView::updateText() std::string name; if (!nodep->mPermissions->isGroupOwned()) { - // [Ansariel: Display name support] - LLAvatarName avatar_name; - // [/Ansariel: Display name support] owner = nodep->mPermissions->getOwner(); if (LLUUID::null == owner) { line.append(LLTrans::getString("TooltipPublic")); } - // [Ansariel: Display name support] - //else if(gCacheName->getFullName(owner, name)) - else if (LLAvatarNameCache::get(owner, &avatar_name)) + else if(LLAvatarNameCache::getPNSName(owner, name)) { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : name = avatar_name.getCompleteName(); break; - case 1 : name = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : name = avatar_name.mDisplayName; break; - default : name = avatar_name.getCompleteName(); break; - } - // [/Ansariel: Display name support] // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) { diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index a06361d99..2a180897b 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -691,7 +691,7 @@ bool LLHUDEffectLookAt::calcTargetPosition() } else { - target_rot = target_av->mRoot.getWorldRotation(); + target_rot = target_av->mRoot->getWorldRotation(); } } else // target obj is not an avatar diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index bd8ec64be..1a2860998 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -199,7 +199,7 @@ public: mAgents = agents_to_invite; } - virtual void error(U32 statusNum, const std::string& reason) + /*virtual*/ void error(U32 statusNum, const std::string& reason) { //try an "old school" way. if ( statusNum == 400 ) @@ -219,7 +219,8 @@ public: //the possible different language translations } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return startConferenceChatResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return startConferenceChatResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLStartConferenceChatResponder"; } private: LLUUID mTempSessionID; @@ -306,9 +307,10 @@ class LLVoiceCallCapResponder : public LLHTTPClient::ResponderWithResult public: LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {}; - virtual void error(U32 status, const std::string& reason); // called with bad status codes - virtual void result(const LLSD& content); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return voiceCallCapResponder_timeout; } + /*virtual*/ void error(U32 status, const std::string& reason); // called with bad status codes + /*virtual*/ void result(const LLSD& content); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return voiceCallCapResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLVoiceCallCapResponder"; } private: LLUUID mSessionID; @@ -1184,40 +1186,43 @@ void LLFloaterIMPanel::init(const std::string& session_label) // [Ansariel: Display name support] mProfileButtonEnabled = FALSE; // [/Ansariel: Display name support] - + + static LLCachedControl concise_im("UseConciseIMButtons"); + static LLCachedControl concise_group("UseConciseGroupChatButtons"); + static LLCachedControl concise_conf("UseConciseConferenceButtons"); std::string xml_filename; switch(mDialog) { case IM_SESSION_GROUP_START: mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); - xml_filename = "floater_instant_message_group.xml"; + xml_filename = concise_group ? "floater_instant_message_group_concisebuttons.xml" : "floater_instant_message_group.xml"; mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel); break; case IM_SESSION_INVITE: mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); if (gAgent.isInGroup(mSessionUUID)) { - xml_filename = "floater_instant_message_group.xml"; + xml_filename = concise_group ? "floater_instant_message_group_concisebuttons.xml" : "floater_instant_message_group.xml"; } else // must be invite to ad hoc IM { - xml_filename = "floater_instant_message_ad_hoc.xml"; + xml_filename = concise_conf ? "floater_instant_message_ad_hoc_concisebuttons.xml" : "floater_instant_message_ad_hoc.xml"; } mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel); break; case IM_SESSION_P2P_INVITE: - xml_filename = "floater_instant_message.xml"; + xml_filename = concise_im ? "floater_instant_message_concisebuttons.xml" : "floater_instant_message.xml"; mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID); break; case IM_SESSION_CONFERENCE_START: mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); - xml_filename = "floater_instant_message_ad_hoc.xml"; + xml_filename = concise_conf ? "floater_instant_message_ad_hoc_concisebuttons.xml" : "floater_instant_message_ad_hoc.xml"; mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel); break; // just received text from another user case IM_NOTHING_SPECIAL: - xml_filename = "floater_instant_message.xml"; + xml_filename = concise_im ? "floater_instant_message_concisebuttons.xml" : "floater_instant_message.xml"; mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionUUID); mProfileButtonEnabled = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionUUID); @@ -1227,7 +1232,7 @@ void LLFloaterIMPanel::init(const std::string& session_label) break; default: llwarns << "Unknown session type" << llendl; - xml_filename = "floater_instant_message.xml"; + xml_filename = concise_im ? "floater_instant_message_concisebuttons.xml" : "floater_instant_message.xml"; break; } @@ -1297,27 +1302,23 @@ void LLFloaterIMPanel::init(const std::string& session_label) } } -// [Ansariel: Display name support] void LLFloaterIMPanel::lookupName() { LLAvatarNameCache::get(mOtherParticipantUUID, boost::bind(&LLFloaterIMPanel::onAvatarNameLookup, _1, _2, this)); } //static -void LLFloaterIMPanel::onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data) +void LLFloaterIMPanel::onAvatarNameLookup(const LLUUID&, const LLAvatarName& avatar_name, void* data) { - LLFloaterIMPanel* self = (LLFloaterIMPanel*)user_data; + LLFloaterIMPanel* self = (LLFloaterIMPanel*)data; if (self && sFloaterIMPanels.count(self) != 0) { - std::string title = avatar_name.getCompleteName(); - if (!title.empty()) - { - self->setTitle(title); - } + std::string title; + LLAvatarNameCache::getPNSName(avatar_name, title); + self->setTitle(title); } } -// [/Ansariel: Display name support] LLFloaterIMPanel::~LLFloaterIMPanel() { @@ -1566,13 +1567,14 @@ public: mSessionID = session_id; } - void error(U32 statusNum, const std::string& reason) + /*virtual*/ void error(U32 statusNum, const std::string& reason) { llinfos << "Error inviting all agents to session" << llendl; //throw something back to the viewer here? } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return sessionInviteResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return sessionInviteResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLSessionInviteResponder"; } private: LLUUID mSessionID; @@ -1676,19 +1678,8 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol else { std::string show_name = name; - LLAvatarName avatar_name; - if (source.notNull() && - LLAvatarNameCache::get(source, &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : show_name = avatar_name.getCompleteName(); break; - case 1 : show_name = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : show_name = avatar_name.mDisplayName; break; - default : show_name = avatar_name.getCompleteName(); break; - } - } + if (source.notNull()) + LLAvatarNameCache::getPNSName(source, show_name); // Convert the name to a hotlink and add to message. const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source); mHistoryEditor->appendStyledText(show_name,false,prepend_newline,source_style); diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 943bd37c1..61d8c01f7 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -196,10 +196,8 @@ public: EInstantMessage dialog); virtual ~LLFloaterIMPanel(); - // [Ansariel: Display name support] void lookupName(); - static void onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data); - // [/Ansariel: Display name support] + static void onAvatarNameLookup(const LLUUID&, const LLAvatarName& avatar_name, void* data); /*virtual*/ BOOL postBuild(); @@ -400,7 +398,6 @@ private: typedef std::map styleMap; static styleMap mStyleMap; - // [Ansariel: Display name support] static std::set sFloaterIMPanels; }; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index d6dabcdae..62f52c759 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -94,8 +94,7 @@ LLIMMgr* gIMMgr = NULL; //{ // return (LLStringUtil::compareDict( a->mName, b->mName ) < 0); //} -class LLViewerChatterBoxInvitationAcceptResponder : - public LLHTTPClient::ResponderWithResult +class LLViewerChatterBoxInvitationAcceptResponder : public LLHTTPClient::ResponderWithResult { public: LLViewerChatterBoxInvitationAcceptResponder( @@ -106,7 +105,7 @@ public: mInvitiationType = invitation_type; } - void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { if ( gIMMgr) { @@ -154,8 +153,8 @@ public: } } - void error(U32 statusNum, const std::string& reason) - { + /*virtual*/ void error(U32 statusNum, const std::string& reason) + { //throw something back to the viewer here? if ( gIMMgr ) { @@ -177,7 +176,8 @@ public: } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return viewerChatterBoxInvitationAcceptResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return viewerChatterBoxInvitationAcceptResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLViewerChatterBoxInvitationAcceptResponder"; } private: LLUUID mSessionID; @@ -483,8 +483,8 @@ void LLIMMgr::addMessage( } //not sure why...but if it is from ourselves we set the target_id - //to be NULL - if( other_participant_id == gAgent.getID() ) + //to be NULL, which seems to be breaking links on group chats, so let's not there. + if (other_participant_id == gAgent.getID() && !gAgent.isInGroup(session_id)) { other_participant_id = LLUUID::null; } @@ -553,7 +553,6 @@ void LLIMMgr::addMessage( // when answering questions. if(gAgent.isGodlike()) { - // *TODO:translate (low priority, god ability) std::ostringstream bonus_info; bonus_info << LLTrans::getString("***")+ " "+ LLTrans::getString("IMParentEstate") + LLTrans::getString(":") + " " << parent_estate_id @@ -574,9 +573,26 @@ void LLIMMgr::addMessage( // now add message to floater bool is_from_system = target_id.isNull() || (from == SYSTEM_FROM); - const LLColor4& color = ( is_from_system ? - gSavedSettings.getColor4("SystemChatColor") : - gSavedSettings.getColor("IMChatColor")); + + static LLCachedControl color_linden_chat("ColorLindenChat"); + bool linden = color_linden_chat && LLMuteList::getInstance()->isLinden(from); + + static LLCachedControl color_friend_chat("ColorFriendChat"); + bool contact = color_friend_chat && LLAvatarTracker::instance().isBuddy(other_participant_id); + + static LLCachedControl color_eo_chat("ColorEstateOwnerChat"); + bool estate_owner = false; + if (color_eo_chat) + { + LLViewerRegion* parent_estate = gAgent.getRegion(); + estate_owner = (parent_estate && parent_estate->isAlive() && other_participant_id == parent_estate->getOwner()); + } + + const LLColor4& color = ( is_from_system ? gSavedSettings.getColor4("SystemChatColor") + : linden ? gSavedSettings.getColor4("AscentLindenColor") + : contact ? gSavedSettings.getColor4("AscentFriendColor") + : estate_owner ? gSavedSettings.getColor4("AscentEstateOwnerColor") + : gSavedSettings.getColor("IMChatColor")); if ( !link_name ) { floater->addHistoryLine(msg,color); // No name to prepend, so just add the message normally @@ -731,7 +747,18 @@ LLUUID LLIMMgr::addSession( { noteMutedUsers(floater, ids); } - LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater); + + static LLCachedControl tear_off("OtherChatsTornOff"); + if(tear_off) + { + // removal sets up relationship for re-attach + LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater); + // reparent to floater view + gFloaterView->addChild(floater); + gFloaterView->bringToFront(floater); + } + else + LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater); } else { @@ -1103,6 +1130,25 @@ LLFloaterIMPanel* LLIMMgr::createFloater( dialog); LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt); + static LLCachedControl tear_off("OtherChatsTornOff"); + if (tear_off) + { + LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater); // removal sets up relationship for re-attach + gFloaterView->addChild(floater); // reparent to floater view + LLFloater* focused_floater = gFloaterView->getFocusedFloater(); // obtain the focused floater + floater->open(); // make the new chat floater appear + static LLCachedControl minimize("OtherChatsTornOffAndMinimized"); + if (focused_floater != NULL) // there was a focused floater + { + floater->setMinimized(minimize); // so minimize this one, for now, if desired + focused_floater->setFocus(true); // and work around focus being removed by focusing on the last + } + else if (minimize) + { + floater->setFocus(false); // work around focus being granted to new floater + floater->setMinimized(true); + } + } mFloaters.insert(floater->getHandle()); return floater; } @@ -1129,6 +1175,25 @@ LLFloaterIMPanel* LLIMMgr::createFloater( dialog); LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt); + static LLCachedControl tear_off("OtherChatsTornOff"); + if (tear_off) + { + LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater); // removal sets up relationship for re-attach + gFloaterView->addChild(floater); // reparent to floater view + LLFloater* focused_floater = gFloaterView->getFocusedFloater(); // obtain the focused floater + floater->open(); // make the new chat floater appear + static LLCachedControl minimize("OtherChatsTornOffAndMinimized"); + if (focused_floater != NULL) // there was a focused floater + { + floater->setMinimized(minimize); // so minimize this one, for now, if desired + focused_floater->setFocus(true); // and work around focus being removed by focusing on the last + } + else if (minimize) + { + floater->setFocus(false); // work around focus being granted to new floater + floater->setMinimized(true); + } + } mFloaters.insert(floater->getHandle()); return floater; } @@ -1153,7 +1218,7 @@ void LLIMMgr::noteOfflineUsers( std::string full_name; if (info && !info->isOnline() - && gCacheName->getFullName(ids.get(i), full_name)) + && LLAvatarNameCache::getPNSName(ids.get(i), full_name)) { LLUIString offline = LLTrans::getString("offline_message"); offline.setArg("[NAME]", full_name); diff --git a/indra/newview/llinventoryactions.cpp b/indra/newview/llinventoryactions.cpp index 372b9bf83..46a92a09d 100644 --- a/indra/newview/llinventoryactions.cpp +++ b/indra/newview/llinventoryactions.cpp @@ -67,6 +67,7 @@ #include "llinventoryclipboard.h" #include "llinventorymodelbackgroundfetch.h" #include "lllineeditor.h" +#include "llmakeoutfitdialog.h" #include "llmenugl.h" #include "llpreviewanim.h" #include "llpreviewgesture.h" @@ -382,6 +383,10 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type, LLInventoryType::IT_GESTURE, PERM_ALL); } + else if ("outfit" == type) + { + new LLMakeOutfitDialog(false); + } else { LLWearableType::EType wear_type = LLWearableType::typeNameToType(type); @@ -671,7 +676,7 @@ class LLAttachObject : public inventory_panel_listener_t else if(item && item->isFinished()) { // must be in library. copy it to our inventory and put it on. - LLPointer cb = new RezAttachmentCallback(attachmentp); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp, false)); copy_inventory_item( gAgent.getID(), item->getPermissions().getOwner(), diff --git a/indra/newview/llinventorybackup.cpp b/indra/newview/llinventorybackup.cpp index b3caf401f..183253b56 100644 --- a/indra/newview/llinventorybackup.cpp +++ b/indra/newview/llinventorybackup.cpp @@ -106,7 +106,7 @@ void LLFloaterInventoryBackupSettings::onClickNext(void* userdata) for( ; item_iter != order->mItems.end(); ) { if(type_remove[(*item_iter)->getType()]) - order->mItems.erase(item_iter); + item_iter = order->mItems.erase(item_iter); else ++item_iter; } @@ -305,7 +305,7 @@ void LLInventoryBackup::download(LLInventoryItem* item, LLFloater* floater, load switch(item->getType()) { case LLAssetType::AT_TEXTURE: - imagep = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID(), MIPMAP_TRUE, LLViewerTexture::BOOST_UI); + imagep = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID(), MIPMAP_TRUE, LLGLTexture::BOOST_UI); imagep->setLoadedCallback( onImage, 0, TRUE, FALSE, userdata, NULL ); // was setLoadedCallbackNoAuth break; case LLAssetType::AT_NOTECARD: @@ -363,7 +363,7 @@ void LLInventoryBackup::imageCallback(BOOL success, } else { - src_vi->setBoostLevel(LLViewerTexture::BOOST_UI); + src_vi->setBoostLevel(LLGLTexture::BOOST_UI); } } @@ -619,11 +619,11 @@ BOOL LLFloaterInventoryBackup::postBuild(void) status_column["column"] = "status"; status_column["value"] = "Pending"; - LLScrollListItem* scroll_itemp = list->addElement(element, ADD_BOTTOM); + /*LLScrollListItem* scroll_itemp = */list->addElement(element, ADD_BOTTOM); //hack to stop crashing - LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(LIST_TYPE); - icon->setClickCallback(NULL, NULL); + //LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(LIST_TYPE); + //icon->setClickCallback(NULL); } // Setup and go! @@ -738,7 +738,7 @@ void LLFloaterInventoryBackup::imageCallback(BOOL success, } else { - src_vi->setBoostLevel(LLViewerTexture::BOOST_UI); + src_vi->setBoostLevel(LLGLTexture::BOOST_UI); } } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 8efcc693d..98ed5cd6d 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -259,7 +259,7 @@ LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory, mInvType(LLInventoryType::IT_NONE), mIsLink(FALSE) { - mInventoryPanel = inventory->getHandle(); + mInventoryPanel = inventory->getInventoryPanelHandle(); const LLInventoryObject* obj = getInventoryObject(); mIsLink = obj && obj->getIsLinkType(); } @@ -612,6 +612,48 @@ BOOL LLInvFVBridge::isClipboardPasteable() const return TRUE; } +bool LLInvFVBridge::isClipboardPasteableAsCopy() const +{ + // In cut mode, we don't paste copies. + if (LLInventoryClipboard::instance().isCutMode()) + { + return false; + } + + LLInventoryModel* model = getInventoryModel(); + if (!model) + { + return false; + } + + // In copy mode, we need to check each element of the clipboard to know if it's a link + LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLDynamicArray objects; + LLInventoryClipboard::instance().retrieve(objects); + const S32 count = objects.count(); + for(S32 i = 0; i < count; i++) + { + const LLUUID &item_id = objects.get(i); + + // Folders may be links + const LLInventoryCategory *cat = model->getCategory(item_id); + if (cat) + { + const LLFolderBridge cat_br(panel, mRoot, item_id); + if (cat_br.isLink()) + return true; + // Skip to the next item in the clipboard + continue; + } + + // May be link item + const LLItemBridge item_br(panel, mRoot, item_id); + if (item_br.isLink()) + return true; + } + return false; +} + BOOL LLInvFVBridge::isClipboardPasteableAsLink() const { if (!InventoryLinksEnabled()) @@ -731,6 +773,20 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, { if (obj->getIsLinkType()) { + // Patch: Inventory-Links tweak, Can copy and cut Inventory Links + items.push_back(std::string("Copy Separator")); + + items.push_back(std::string("Copy")); + if (!isItemCopyable()) + { + disabled_items.push_back(std::string("Copy")); + } + + items.push_back(std::string("Cut")); + if (!isItemMovable() || !isItemRemovable()) + { + disabled_items.push_back(std::string("Cut")); + } items.push_back(std::string("Find Original")); if (isLinkedObjectMissing()) { @@ -798,17 +854,26 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } } + bool paste_as_copy = false; // If Paste As Copy is on the menu, Paste As Link will always show up disabled, so don't bother. // Don't allow items to be pasted directly into the COF or the inbox/outbox if (!isCOFFolder() && !isInboxFolder() && !isOutboxFolder()) { items.push_back(std::string("Paste")); + // Paste as copy if we have links. + if (InventoryLinksEnabled() && isClipboardPasteableAsCopy()) + { + items.push_back(std::string("Paste As Copy")); + paste_as_copy = true; + } } if (!isClipboardPasteable() || ((flags & FIRST_SELECTED_ITEM) == 0)) { disabled_items.push_back(std::string("Paste")); + disabled_items.push_back(std::string("Paste As Copy")); + paste_as_copy = false; } - if(InventoryLinksEnabled()) + if (!paste_as_copy && InventoryLinksEnabled()) { items.push_back(std::string("Paste As Link")); if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) @@ -993,7 +1058,7 @@ LLInventoryObject* LLInvFVBridge::getInventoryObject() const LLInventoryModel* LLInvFVBridge::getInventoryModel() const { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); return panel ? panel->getModel() : NULL; } @@ -1469,6 +1534,18 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) folder_view_itemp->getListener()->pasteFromClipboard(); return; } + else if ("paste_copies" == action) + { + // Single item only + LLInventoryItem* itemp = model->getItem(mUUID); + if (!itemp) return; + + LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID()); + if (!folder_view_itemp) return; + + folder_view_itemp->getListener()->pasteFromClipboard(true); + return; + } else if ("paste_link" == action) { // Single item only @@ -1604,7 +1681,7 @@ LLUIImagePtr LLItemBridge::getIcon() const mIsLink); } - return LLInventoryIcon::getIcon(LLInventoryIcon::ICONNAME_OBJECT); + return LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_OBJECT); } PermissionMask LLItemBridge::getPermissionMask() const @@ -1812,7 +1889,10 @@ BOOL LLItemBridge::removeItem() // we can't do this check because we may have items in a folder somewhere that is // not yet in memory, so we don't want false negatives. (If disabled, then we // know we only have links in the Outfits folder which we explicitly fetch.) - if (!InventoryLinksEnabled()) +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-06-01 (Catznip-2.2.0a) | Added: Catznip-2.0.1a + // Users move folders around and reuse links that way... if we know something has links then it's just bad not to warn them :| +// [/SL:KB] +// if (!InventoryLinksEnabled()) { if (!item->getIsLinkType()) { @@ -1873,13 +1953,26 @@ BOOL LLItemBridge::isItemCopyable() const return FALSE; }*/ - // You can never copy a link. - if (item->getIsLinkType()) +// // You can never copy a link. +// if (item->getIsLinkType()) +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a + // We'll allow copying a link if: + // - its target is available + // - it doesn't point to another link [see LLViewerInventoryItem::getLinkedItem() which returns NULL in that case] + if (item->getIsLinkType() && !item->getLinkedItem()) +// [/SL:KB] { return FALSE; } - return item->getPermissions().allowCopyBy(gAgent.getID()) || InventoryLinksEnabled(); +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a + // User can copy the item if: + // - the item (or its target in the case of a link) is "copy" + // - and/or if the item (or its target in the case of a link) has a linkable asset type + // NOTE: we do *not* want to return TRUE on everything like LL seems to do in SL-2.1.0 because not all types are "linkable" + return (item->getPermissions().allowCopyBy(gAgent.getID())) || (LLAssetType::lookupCanLink(item->getType())); +// [/SL:KB] +// return item->getPermissions().allowCopyBy(gAgent.getID()) || InventoryLinksEnabled(); } return FALSE; } @@ -1952,7 +2045,7 @@ BOOL LLFolderBridge::isItemRemovable() const return FALSE; } - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewFolder* folderp = dynamic_cast(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL); if (folderp) { @@ -2824,6 +2917,11 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) pasteFromClipboard(); return; } + else if ("paste_copies" == action) + { + pasteFromClipboard(true); + return; + } else if ("paste_link" == action) { pasteLinkFromClipboard(); @@ -3062,7 +3160,7 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re return FALSE; } -void LLFolderBridge::pasteFromClipboard() +void LLFolderBridge::pasteFromClipboard(bool only_copies) { LLInventoryModel* model = getInventoryModel(); if(model && isClipboardPasteable()) @@ -3135,7 +3233,7 @@ void LLFolderBridge::pasteFromClipboard() dropToOutfit(item, move_is_into_current_outfit); } } - else if(LLInventoryClipboard::instance().isCutMode()) + else if (!only_copies && LLInventoryClipboard::instance().isCutMode()) { // Do a move to "paste" a "cut" // move_inventory_item() is not enough, as we have to update inventory locally too @@ -3160,6 +3258,11 @@ void LLFolderBridge::pasteFromClipboard() } else { + if (only_copies) + { + item = model->getLinkedItem(item_id); + obj = model->getObject(item->getUUID()); + } // Do a "copy" to "paste" a regular copy clipboard if (LLAssetType::AT_CATEGORY == obj->getType()) { @@ -3170,6 +3273,19 @@ void LLFolderBridge::pasteFromClipboard() copy_inventory_category(model, vicat, parent_id); } } +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a + else if (!only_copies && LLAssetType::lookupIsLinkType(item->getActualType())) + { + link_inventory_item( + gAgent.getID(), + item->getLinkedUUID(), + parent_id, + item->getName(), + item->getDescription(), + item->getActualType(), + LLPointer(NULL)); + } +// [/SL:KB] else { copy_inventory_item( @@ -3322,7 +3438,7 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags) // Not sure what the right thing is to do here. if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT)) { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); if(panel && !panel->getFilterWorn()) if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox or outbox { @@ -3603,7 +3719,7 @@ void LLFolderBridge::createNewCategory(void* user_data) { LLFolderBridge* bridge = (LLFolderBridge*)user_data; if(!bridge) return; - LLInventoryPanel* panel = dynamic_cast(bridge->mInventoryPanel.get()); + LLInventoryPanel* panel = bridge->mInventoryPanel.get(); if (!panel) return; LLInventoryModel* model = panel->getModel(); if(!model) return; @@ -3797,7 +3913,7 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item) // use callback to rearrange favorite landmarks after adding // to have new one placed before target (on which it was dropped). See EXT-4312. LLPointer cb = new AddFavoriteLandmarkCallback(); - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; if (drag_over_item && drag_over_item->getListener()) { @@ -3846,6 +3962,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, if(!isAgentInventory()) return FALSE; // cannot drag into library if (!isAgentAvatarValid()) return FALSE; + LLInventoryPanel* destination_panel = mInventoryPanel.get(); + if (!destination_panel) return false; + const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false); const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); @@ -3977,6 +4096,15 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } } + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + + // Check whether the item being dragged from active inventory panel + if (accept && active_panel) + { + LLFolderView* active_folder_view = active_panel->getRootFolder(); + if (!active_folder_view) return false; + } + if(accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE @@ -3986,14 +4114,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } // If an item is being dragged between windows, unselect everything in the active window // so that we don't follow the selection to its new location (which is very annoying). - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel) + if (active_panel && (destination_panel != active_panel)) { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); - if (active_panel && (panel != active_panel)) - { active_panel->unSelectAll(); - } } // FAVORITES folder @@ -4156,6 +4279,15 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, accept = can_move_to_landmarks(inv_item); } + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + + // Check whether the item being dragged from the library + if (accept && active_panel) + { + LLFolderView* active_folder_view = active_panel->getRootFolder(); + if (!active_folder_view) return false; + } + if (accept && drop) { // FAVORITES folder @@ -4558,7 +4690,7 @@ LLCallingCardBridge::~LLCallingCardBridge() void LLCallingCardBridge::refreshFolderViewItem() { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL; if (itemp) { @@ -5138,7 +5270,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action) else if(item && item->isFinished()) { // must be in library. copy it to our inventory and put it on. - LLPointer cb = new RezAttachmentCallback(0); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0, false)); copy_inventory_item( gAgent.getID(), item->getPermissions().getOwner(), @@ -5155,11 +5287,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action) } else if (isRemoveAction(action)) { - LLInventoryItem* item = gInventory.getItem(mUUID); - if(item) - { - LLVOAvatarSelf::detachAttachmentIntoInventory(item->getLinkedUUID()); - } + LLAppearanceMgr::instance().removeItemFromAvatar(mUUID); } else if ("edit" == action) { @@ -5215,9 +5343,10 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action) void LLObjectBridge::openItem() { + static LLCachedControl add(gSavedSettings, "LiruAddNotReplace"); // object double-click action is to wear/unwear object performAction(getInventoryModel(), - get_is_item_worn(mUUID) ? "detach" : "attach"); + get_is_item_worn(mUUID) ? "detach" : (add ? "wear_add" : "attach")); } std::string LLObjectBridge::getLabelSuffix() const @@ -5563,9 +5692,9 @@ void remove_inventory_category_from_avatar( LLInventoryCategory* category ) if(!category) return; lldebugs << "remove_inventory_category_from_avatar( " << category->getName() << " )" << llendl; - if (gAgentCamera.cameraCustomizeAvatar()) + if (LLFloaterCustomize::instanceExists()) { - gFloaterCustomize->askToSaveIfDirty(boost::bind(&remove_inventory_category_from_avatar_step2,_1,category->getUUID())); + LLFloaterCustomize::getInstance()->askToSaveIfDirty(boost::bind(&remove_inventory_category_from_avatar_step2,_1,category->getUUID())); } else remove_inventory_category_from_avatar_step2(TRUE, category->getUUID() ); @@ -5973,7 +6102,7 @@ void LLWearableBridge::wearAddOnAvatar() } // static -//void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userdata ) +//void LLWearableBridge::onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata ) //{ // LLUUID* item_id = (LLUUID*) userdata; // if(wearable) @@ -5999,7 +6128,7 @@ void LLWearableBridge::wearAddOnAvatar() // static // BAP remove the "add" code path once everything is fully COF-ified. -//void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata ) +//void LLWearableBridge::onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata ) //{ // LLUUID* item_id = (LLUUID*) userdata; // if(wearable) @@ -6080,7 +6209,7 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data) //} // static -//void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable, +//void LLWearableBridge::onRemoveFromAvatarArrived(LLViewerWearable* wearable, // void* userdata) //{ // OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata; @@ -6115,53 +6244,11 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data) // delete on_remove_struct; //} -// static -void LLWearableBridge::removeAllClothesFromAvatar() -{ - // Fetch worn clothes (i.e. the ones in COF). - LLInventoryModel::item_array_t clothing_items; - LLInventoryModel::cat_array_t dummy; - LLIsType is_clothing(LLAssetType::AT_CLOTHING); - gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), - dummy, - clothing_items, - LLInventoryModel::EXCLUDE_TRASH, - is_clothing, - false); - - // Take them off by removing from COF. - for (LLInventoryModel::item_array_t::const_iterator it = clothing_items.begin(); it != clothing_items.end(); ++it) - { -// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g - if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(*it)) ) - continue; -// [/RLVa:KB] - LLAppearanceMgr::instance().removeItemFromAvatar((*it)->getUUID()); - } -} - -// static -void LLWearableBridge::removeItemFromAvatar(LLViewerInventoryItem *item) -{ - if (item) - { -// LLWearableList::instance().getAsset(item->getAssetUUID(), -// item->getName(), -// item->getType(), -// LLWearableBridge::onRemoveFromAvatarArrived, -// new OnRemoveStruct(item->getUUID())); -// [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-3.0.0a) | Added: Catznip-2.1.1d - LLAppearanceMgr::instance().removeItemFromAvatar(item->getUUID()); -// [/SL:KB] - } -} - void LLWearableBridge::removeFromAvatar() { if (get_is_item_worn(mUUID)) { - LLViewerInventoryItem* item = getItem(); - removeItemFromAvatar(item); + LLAppearanceMgr::instance().removeItemFromAvatar(mUUID); } } @@ -6671,10 +6758,14 @@ void LLWearableBridgeAction::wearOnAvatar() { // TODO: investigate wearables may not be loaded at this point EXT-8231 + static LLCachedControl add(gSavedSettings, "LiruAddNotReplace"); LLViewerInventoryItem* item = getItem(); if(item) { - LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true); + if (get_is_item_worn(item)) + LLAppearanceMgr::instance().removeItemFromAvatar(item->getUUID()); + else + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, !add); } } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 8b386710d..0900820cf 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -33,7 +33,7 @@ #include "llinventorymodel.h" #include "llinventoryobserver.h" #include "llviewercontrol.h" -#include "llwearable.h" +#include "llviewerwearable.h" class LLInventoryPanel; class LLInventoryModel; @@ -108,8 +108,9 @@ public: virtual BOOL copyToClipboard() const; virtual void cutToClipboard(); virtual BOOL isClipboardPasteable() const; + bool isClipboardPasteableAsCopy() const; virtual BOOL isClipboardPasteableAsLink() const; - virtual void pasteFromClipboard() {} + virtual void pasteFromClipboard(bool only_copies = false) {} virtual void pasteLinkFromClipboard() {} void getClipboardEntries(bool show_asset_id, menuentry_vec_t &items, menuentry_vec_t &disabled_items, U32 flags); @@ -160,7 +161,7 @@ protected: BOOL restamp); void removeBatchNoCheck(LLDynamicArray& batch); protected: - LLHandle mInventoryPanel; + LLHandle mInventoryPanel; LLFolderView* mRoot; const LLUUID mUUID; // item id LLInventoryType::EType mInvType; @@ -261,7 +262,7 @@ public: BOOL removeSystemFolder(); bool removeItemResponse(const LLSD& notification, const LLSD& response); - virtual void pasteFromClipboard(); + virtual void pasteFromClipboard(bool only_copies = false); virtual void pasteLinkFromClipboard(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); virtual BOOL hasChildren() const; @@ -502,10 +503,10 @@ public: static void onWearOnAvatar( void* userdata ); // Access to wearOnAvatar() from menu static BOOL canWearOnAvatar( void* userdata ); - static void onWearOnAvatarArrived( LLWearable* wearable, void* userdata ); + static void onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata ); void wearOnAvatar(); - static void onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata ); + static void onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata ); void wearAddOnAvatar(); static BOOL canEditOnAvatar( void* userdata ); // Access to editOnAvatar() from menu @@ -513,10 +514,9 @@ public: void editOnAvatar(); static BOOL canRemoveFromAvatar( void* userdata ); - static void onRemoveFromAvatar( void* userdata ); - static void onRemoveFromAvatarArrived( LLWearable* wearable, void* userdata ); - static void removeItemFromAvatar(LLViewerInventoryItem *item); - static void removeAllClothesFromAvatar(); + //static void onRemoveFromAvatar( void* userdata ); + //static void onRemoveFromAvatarArrived( LLViewerWearable* wearable, void* userdata ); + //static void removeAllClothesFromAvatar(); void removeFromAvatar(); protected: LLAssetType::EType mAssetType; diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 9d55023d6..e2b47e687 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -41,7 +41,7 @@ struct IconEntry : public LLDictionaryEntry }; class LLIconDictionary : public LLSingleton, - public LLDictionary + public LLDictionary { public: LLIconDictionary(); @@ -49,48 +49,48 @@ public: LLIconDictionary::LLIconDictionary() { - addEntry(LLInventoryIcon::ICONNAME_TEXTURE, new IconEntry("inv_item_texture.tga")); - addEntry(LLInventoryIcon::ICONNAME_SOUND, new IconEntry("inv_item_sound.tga")); - addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_ONLINE, new IconEntry("inv_item_callingcard_online.tga")); - addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_OFFLINE, new IconEntry("inv_item_callingcard_offline.tga")); - addEntry(LLInventoryIcon::ICONNAME_LANDMARK, new IconEntry("inv_item_landmark.tga")); - addEntry(LLInventoryIcon::ICONNAME_LANDMARK_VISITED, new IconEntry("inv_item_landmark_visited.tga")); - addEntry(LLInventoryIcon::ICONNAME_SCRIPT, new IconEntry("inv_item_script.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING, new IconEntry("inv_item_clothing.tga")); - addEntry(LLInventoryIcon::ICONNAME_OBJECT, new IconEntry("inv_item_object.tga")); - addEntry(LLInventoryIcon::ICONNAME_OBJECT_MULTI, new IconEntry("inv_item_object_multi.tga")); - addEntry(LLInventoryIcon::ICONNAME_NOTECARD, new IconEntry("inv_item_notecard.tga")); - addEntry(LLInventoryIcon::ICONNAME_BODYPART, new IconEntry("inv_item_skin.tga")); - addEntry(LLInventoryIcon::ICONNAME_SNAPSHOT, new IconEntry("inv_item_snapshot.tga")); + addEntry(LLInventoryType::ICONNAME_TEXTURE, new IconEntry("inv_item_texture.tga")); + addEntry(LLInventoryType::ICONNAME_SOUND, new IconEntry("inv_item_sound.tga")); + addEntry(LLInventoryType::ICONNAME_CALLINGCARD_ONLINE, new IconEntry("inv_item_callingcard_online.tga")); + addEntry(LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE, new IconEntry("inv_item_callingcard_offline.tga")); + addEntry(LLInventoryType::ICONNAME_LANDMARK, new IconEntry("inv_item_landmark.tga")); + addEntry(LLInventoryType::ICONNAME_LANDMARK_VISITED, new IconEntry("inv_item_landmark_visited.tga")); + addEntry(LLInventoryType::ICONNAME_SCRIPT, new IconEntry("inv_item_script.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING, new IconEntry("inv_item_clothing.tga")); + addEntry(LLInventoryType::ICONNAME_OBJECT, new IconEntry("inv_item_object.tga")); + addEntry(LLInventoryType::ICONNAME_OBJECT_MULTI, new IconEntry("inv_item_object_multi.tga")); + addEntry(LLInventoryType::ICONNAME_NOTECARD, new IconEntry("inv_item_notecard.tga")); + addEntry(LLInventoryType::ICONNAME_BODYPART, new IconEntry("inv_item_skin.tga")); + addEntry(LLInventoryType::ICONNAME_SNAPSHOT, new IconEntry("inv_item_snapshot.tga")); - addEntry(LLInventoryIcon::ICONNAME_BODYPART_SHAPE, new IconEntry("inv_item_shape.tga")); - addEntry(LLInventoryIcon::ICONNAME_BODYPART_SKIN, new IconEntry("inv_item_skin.tga")); - addEntry(LLInventoryIcon::ICONNAME_BODYPART_HAIR, new IconEntry("inv_item_hair.tga")); - addEntry(LLInventoryIcon::ICONNAME_BODYPART_EYES, new IconEntry("inv_item_eyes.tga")); + addEntry(LLInventoryType::ICONNAME_BODYPART_SHAPE, new IconEntry("inv_item_shape.tga")); + addEntry(LLInventoryType::ICONNAME_BODYPART_SKIN, new IconEntry("inv_item_skin.tga")); + addEntry(LLInventoryType::ICONNAME_BODYPART_HAIR, new IconEntry("inv_item_hair.tga")); + addEntry(LLInventoryType::ICONNAME_BODYPART_EYES, new IconEntry("inv_item_eyes.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, new IconEntry("inv_item_shirt.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PANTS, new IconEntry("inv_item_pants.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHOES, new IconEntry("inv_item_shoes.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, new IconEntry("inv_item_socks.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_JACKET, new IconEntry("inv_item_jacket.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, new IconEntry("inv_item_gloves.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, new IconEntry("inv_item_undershirt.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, new IconEntry("inv_item_underpants.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, new IconEntry("inv_item_skirt.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, new IconEntry("inv_item_alpha.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, new IconEntry("inv_item_tattoo.tga")); - addEntry(LLInventoryIcon::ICONNAME_ANIMATION, new IconEntry("inv_item_animation.tga")); - addEntry(LLInventoryIcon::ICONNAME_GESTURE, new IconEntry("inv_item_gesture.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_SHIRT, new IconEntry("inv_item_shirt.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_PANTS, new IconEntry("inv_item_pants.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_SHOES, new IconEntry("inv_item_shoes.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_SOCKS, new IconEntry("inv_item_socks.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_JACKET, new IconEntry("inv_item_jacket.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_GLOVES, new IconEntry("inv_item_gloves.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, new IconEntry("inv_item_undershirt.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, new IconEntry("inv_item_underpants.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_SKIRT, new IconEntry("inv_item_skirt.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_ALPHA, new IconEntry("inv_item_alpha.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_TATTOO, new IconEntry("inv_item_tattoo.tga")); + addEntry(LLInventoryType::ICONNAME_ANIMATION, new IconEntry("inv_item_animation.tga")); + addEntry(LLInventoryType::ICONNAME_GESTURE, new IconEntry("inv_item_gesture.tga")); - addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, new IconEntry("inv_item_physics.tga")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_PHYSICS, new IconEntry("inv_item_physics.tga")); - addEntry(LLInventoryIcon::ICONNAME_LINKITEM, new IconEntry("inv_link_item.tga")); - addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, new IconEntry("inv_link_folder.tga")); - addEntry(LLInventoryIcon::ICONNAME_MESH, new IconEntry("inv_item_mesh.tga")); + addEntry(LLInventoryType::ICONNAME_LINKITEM, new IconEntry("inv_link_item.tga")); + addEntry(LLInventoryType::ICONNAME_LINKFOLDER, new IconEntry("inv_link_folder.tga")); + addEntry(LLInventoryType::ICONNAME_MESH, new IconEntry("inv_item_mesh.tga")); - addEntry(LLInventoryIcon::ICONNAME_INVALID, new IconEntry("inv_invalid.png")); + addEntry(LLInventoryType::ICONNAME_INVALID, new IconEntry("inv_invalid.png")); - addEntry(LLInventoryIcon::ICONNAME_NONE, new IconEntry("NONE")); + addEntry(LLInventoryType::ICONNAME_NONE, new IconEntry("NONE")); } LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type, @@ -102,7 +102,7 @@ LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type, return LLUI::getUIImage(icon_name); } -LLUIImagePtr LLInventoryIcon::getIcon(EIconName idx) +LLUIImagePtr LLInventoryIcon::getIcon(LLInventoryType::EIconName idx) { return LLUI::getUIImage(getIconName(idx)); } @@ -112,56 +112,56 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type, U32 misc_flag, BOOL item_is_multi) { - EIconName idx = ICONNAME_OBJECT; + LLInventoryType::EIconName idx = LLInventoryType::ICONNAME_OBJECT; if (item_is_multi) { - idx = ICONNAME_OBJECT_MULTI; + idx = LLInventoryType::ICONNAME_OBJECT_MULTI; return getIconName(idx); } switch(asset_type) { case LLAssetType::AT_TEXTURE: - idx = (inventory_type == LLInventoryType::IT_SNAPSHOT) ? ICONNAME_SNAPSHOT : ICONNAME_TEXTURE; + idx = (inventory_type == LLInventoryType::IT_SNAPSHOT) ? LLInventoryType::ICONNAME_SNAPSHOT : LLInventoryType::ICONNAME_TEXTURE; break; case LLAssetType::AT_SOUND: - idx = ICONNAME_SOUND; + idx = LLInventoryType::ICONNAME_SOUND; break; case LLAssetType::AT_CALLINGCARD: - idx = (misc_flag != 0) ? ICONNAME_CALLINGCARD_ONLINE : ICONNAME_CALLINGCARD_OFFLINE; + idx = (misc_flag != 0) ? LLInventoryType::ICONNAME_CALLINGCARD_ONLINE : LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE; break; case LLAssetType::AT_LANDMARK: - idx = (misc_flag != 0) ? ICONNAME_LANDMARK_VISITED : ICONNAME_LANDMARK; + idx = (misc_flag != 0) ? LLInventoryType::ICONNAME_LANDMARK_VISITED : LLInventoryType::ICONNAME_LANDMARK; break; case LLAssetType::AT_SCRIPT: case LLAssetType::AT_LSL_TEXT: case LLAssetType::AT_LSL_BYTECODE: - idx = ICONNAME_SCRIPT; + idx = LLInventoryType::ICONNAME_SCRIPT; break; case LLAssetType::AT_CLOTHING: case LLAssetType::AT_BODYPART: idx = assignWearableIcon(misc_flag); break; case LLAssetType::AT_NOTECARD: - idx = ICONNAME_NOTECARD; + idx = LLInventoryType::ICONNAME_NOTECARD; break; case LLAssetType::AT_ANIMATION: - idx = ICONNAME_ANIMATION; + idx = LLInventoryType::ICONNAME_ANIMATION; break; case LLAssetType::AT_GESTURE: - idx = ICONNAME_GESTURE; + idx = LLInventoryType::ICONNAME_GESTURE; break; case LLAssetType::AT_LINK: - idx = ICONNAME_LINKITEM; + idx = LLInventoryType::ICONNAME_LINKITEM; break; case LLAssetType::AT_LINK_FOLDER: - idx = ICONNAME_LINKFOLDER; + idx = LLInventoryType::ICONNAME_LINKFOLDER; break; case LLAssetType::AT_OBJECT: - idx = ICONNAME_OBJECT; + idx = LLInventoryType::ICONNAME_OBJECT; break; case LLAssetType::AT_MESH: - idx = ICONNAME_MESH; + idx = LLInventoryType::ICONNAME_MESH; default: break; } @@ -170,13 +170,13 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type, } -const std::string& LLInventoryIcon::getIconName(EIconName idx) +const std::string& LLInventoryIcon::getIconName(LLInventoryType::EIconName idx) { const IconEntry *entry = LLIconDictionary::instance().lookup(idx); return entry->mName; } -LLInventoryIcon::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag) +LLInventoryType::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag) { const LLWearableType::EType wearable_type = LLWearableType::EType(LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK & misc_flag); return LLWearableType::getIconName(wearable_type); diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h index c7e2998a2..659448143 100644 --- a/indra/newview/llinventoryicon.h +++ b/indra/newview/llinventoryicon.h @@ -35,66 +35,20 @@ class LLInventoryIcon { public: - enum EIconName - { - ICONNAME_TEXTURE, - ICONNAME_SOUND, - ICONNAME_CALLINGCARD_ONLINE, - ICONNAME_CALLINGCARD_OFFLINE, - ICONNAME_LANDMARK, - ICONNAME_LANDMARK_VISITED, - ICONNAME_SCRIPT, - ICONNAME_CLOTHING, - ICONNAME_OBJECT, - ICONNAME_OBJECT_MULTI, - ICONNAME_NOTECARD, - ICONNAME_BODYPART, - ICONNAME_SNAPSHOT, - - ICONNAME_BODYPART_SHAPE, - ICONNAME_BODYPART_SKIN, - ICONNAME_BODYPART_HAIR, - ICONNAME_BODYPART_EYES, - ICONNAME_CLOTHING_SHIRT, - ICONNAME_CLOTHING_PANTS, - ICONNAME_CLOTHING_SHOES, - ICONNAME_CLOTHING_SOCKS, - ICONNAME_CLOTHING_JACKET, - ICONNAME_CLOTHING_GLOVES, - ICONNAME_CLOTHING_UNDERSHIRT, - ICONNAME_CLOTHING_UNDERPANTS, - ICONNAME_CLOTHING_SKIRT, - ICONNAME_CLOTHING_ALPHA, - ICONNAME_CLOTHING_TATTOO, - - ICONNAME_ANIMATION, - ICONNAME_GESTURE, - - ICONNAME_CLOTHING_PHYSICS, - - ICONNAME_LINKITEM, - ICONNAME_LINKFOLDER, - ICONNAME_MESH, - - ICONNAME_INVALID, - ICONNAME_COUNT, - ICONNAME_NONE = -1 - }; - static const std::string& getIconName(LLAssetType::EType asset_type, LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE, U32 misc_flag = 0, // different meanings depending on item type BOOL item_is_multi = FALSE); - static const std::string& getIconName(EIconName idx); + static const std::string& getIconName(LLInventoryType::EIconName idx); static LLUIImagePtr getIcon(LLAssetType::EType asset_type, LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE, U32 misc_flag = 0, // different meanings depending on item type BOOL item_is_multi = FALSE); - static LLUIImagePtr getIcon(EIconName idx); + static LLUIImagePtr getIcon(LLInventoryType::EIconName idx); protected: - static EIconName assignWearableIcon(U32 misc_flag); + static LLInventoryType::EIconName assignWearableIcon(U32 misc_flag); }; #endif // LL_LLINVENTORYICON_H diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index cacdc559a..c795e6c57 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -483,12 +483,12 @@ public: { } - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { LL_WARNS("InvAPI") << "CreateInventoryCategory failed. status = " << status << ", reasion = \"" << reason << "\"" << LL_ENDL; } - virtual void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { //Server has created folder. @@ -515,7 +515,8 @@ public: } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return createInventoryCategoryResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return createInventoryCategoryResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLCreateInventoryCategoryResponder"; } private: void (*mCallback)(const LLSD&, void*); @@ -891,6 +892,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item) { parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); new_item->setParent(parent_id); + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate new_folder(parent_id, 1); + update.push_back(new_folder); + accountForUpdate(update); + } item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, parent_id); if(item_array) @@ -1425,7 +1431,6 @@ void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content) item_array_t items; update_map_t update; S32 count = content["items"].size(); - bool all_one_folder = true; LLUUID folder_id; // Does this loop ever execute more than once? for(S32 i = 0; i < count; ++i) @@ -1458,10 +1463,6 @@ void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content) { folder_id = titem->getParentUUID(); } - else - { - all_one_folder = false; - } } U32 changes = 0x0; @@ -1560,6 +1561,10 @@ void LLInventoryModel::addCategory(LLViewerInventoryCategory* category) { return; } + + // try to localize default names first. See EXT-8319, EXT-7051. + //category->localizeName(); + // Insert category uniquely into the map mCategoryMap[category->getUUID()] = category; // LLPointer will deref and delete the old one //mInventory[category->getUUID()] = category; @@ -2638,7 +2643,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account) item_array_t items; update_map_t update; S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData); - bool all_one_folder = true; LLUUID folder_id; // Does this loop ever execute more than once? for(S32 i = 0; i < count; ++i) @@ -2670,10 +2674,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account) { folder_id = titem->getParentUUID(); } - else - { - all_one_folder = false; - } } if(account) { diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index b22efb9eb..3f87c2615 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -87,9 +87,10 @@ public: { public: fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; - void result(const LLSD& content); - void error(U32 status, const std::string& reason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchInventoryResponder_timeout; } + /*virtual*/ void result(const LLSD& content); + /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchInventoryResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "fetchInventoryResponder"; } protected: LLSD mRequestSD; }; diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index d1ed71e8b..9e27b1ad4 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -185,16 +185,10 @@ void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *) LLInventoryModelBackgroundFetch::instance().backgroundFetch(); } -//static void LLInventoryModelBackgroundFetch::backgroundFetch() { LLViewerRegion* region = gAgent.getRegion(); - if (!region) - { - return; - } - - if (mBackgroundFetchActive && gAgent.getRegion()) + if (mBackgroundFetchActive && region && region->capabilitiesReceived()) { // If we'll be using the capability, we'll be sending batches and the background thing isn't as important. std::string url = region->getCapability("FetchInventory2"); @@ -376,9 +370,10 @@ class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInvento { public: LLInventoryModelFetchItemResponder(const LLSD& request_sd) : LLInventoryModel::fetchInventoryResponder(request_sd) {}; - void result(const LLSD& content); - void error(U32 status, const std::string& reason); - AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchItemResponder_timeout; } + /*virtual*/ void result(const LLSD& content); + /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchItemResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLInventoryModelFetchItemResponder"; } }; void LLInventoryModelFetchItemResponder::result( const LLSD& content ) @@ -393,7 +388,7 @@ void LLInventoryModelFetchItemResponder::error( U32 status, const std::string& r LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } -class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::ResponderWithResult +class LLInventoryModelFetchDescendentsResponder : public LLHTTPClient::ResponderWithResult { public: LLInventoryModelFetchDescendentsResponder(const LLSD& request_sd, uuid_vec_t recursive_cats) : @@ -401,9 +396,10 @@ class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::ResponderW mRecursiveCatUUIDs(recursive_cats) {}; //LLInventoryModelFetchDescendentsResponder() {}; - void result(const LLSD& content); - void error(U32 status, const std::string& reason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchDescendentsResponder_timeout; } + /*virtual*/ void result(const LLSD& content); + /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchDescendentsResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLInventoryModelFetchDescendentsResponder"; } protected: BOOL getIsRecursive(const LLUUID& cat_id) const; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 2fcdd59f2..1503e9402 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -444,8 +444,6 @@ void LLInventoryPanel::modelChanged(U32 mask) static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh"); LLFastTimer t2(FTM_REFRESH); - bool handled = false; - if (!mViewsInitialized) return; const LLInventoryModel* model = getModel(); @@ -471,7 +469,6 @@ void LLInventoryPanel::modelChanged(U32 mask) // Empty out the display name for relabel. if (mask & LLInventoryObserver::LABEL) { - handled = true; if (view_item) { // Request refresh on this item (also flags for filtering) @@ -490,7 +487,6 @@ void LLInventoryPanel::modelChanged(U32 mask) // Destroy and regenerate the UI. if (mask & LLInventoryObserver::REBUILD) { - handled = true; if (model_item && view_item) { view_item->destroyView(); @@ -530,8 +526,6 @@ void LLInventoryPanel::modelChanged(U32 mask) LLInventoryObserver::ADD | LLInventoryObserver::REMOVE)) { - handled = true; - ////////////////////////////// // ADD Operation // Item exists in memory but a UI element hasn't been created for it. @@ -1021,7 +1015,7 @@ void LLInventoryPanel::createNewItem(const std::string& name, if (inv_type == LLInventoryType::IT_GESTURE) { - LLPointer cb = new CreateGestureCallback(); + LLPointer cb = new LLBoostFuncInventoryCallback(create_gesture_cb); create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type, NOT_WEARABLE, next_owner_perm, cb); diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 330e8d3d2..f1ae05685 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -130,6 +130,8 @@ public: LLScrollableContainerView* getScrollableContainer() { return mScroller; } void onSelectionChange(const std::deque &items, BOOL user_action); + + LLHandle getInventoryPanelHandle() const { return getDerivedHandle(); } // DEBUG ONLY: static void dumpSelectionInformation(void* user_data); diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp index 85a893122..b26d19c7a 100644 --- a/indra/newview/lllandmarklist.cpp +++ b/indra/newview/lllandmarklist.cpp @@ -2,31 +2,25 @@ * @file lllandmarklist.cpp * @brief Landmark asset list class * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,10 +31,11 @@ #include "message.h" #include "llassetstorage.h" +#include "llappviewer.h" #include "llagent.h" -#include "llnotificationsutil.h" #include "llvfile.h" #include "llviewerstats.h" +#include "llnotificationsutil.h" // Globals LLLandmarkList gLandmarkList; @@ -54,23 +49,48 @@ LLLandmarkList::~LLLandmarkList() std::for_each(mList.begin(), mList.end(), DeletePairedPointer()); } -LLLandmark* LLLandmarkList::getAsset( const LLUUID& asset_uuid ) +LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t cb) { LLLandmark* landmark = get_ptr_in_map(mList, asset_uuid); if(landmark) { + LLVector3d dummy; + if(cb && !landmark->getGlobalPos(dummy)) + { + // landmark is not completely loaded yet + loaded_callback_map_t::value_type vt(asset_uuid, cb); + mLoadedCallbackMap.insert(vt); + } return landmark; } else { - if ( gLandmarkList.mBadList.find(asset_uuid) == gLandmarkList.mBadList.end() ) + if ( mBadList.find(asset_uuid) != mBadList.end() ) { - gAssetStorage->getAssetData( - asset_uuid, - LLAssetType::AT_LANDMARK, - LLLandmarkList::processGetAssetReply, - NULL); + return NULL; } + + landmark_requested_list_t::iterator iter = mRequestedList.find(asset_uuid); + if (iter != mRequestedList.end()) + { + const F32 rerequest_time = 30.f; // 30 seconds between requests + if (gFrameTimeSeconds - iter->second < rerequest_time) + { + return NULL; + } + } + + if (cb) + { + loaded_callback_map_t::value_type vt(asset_uuid, cb); + mLoadedCallbackMap.insert(vt); + } + + gAssetStorage->getAssetData(asset_uuid, + LLAssetType::AT_LANDMARK, + LLLandmarkList::processGetAssetReply, + NULL); + mRequestedList[asset_uuid] = gFrameTimeSeconds; } return NULL; } @@ -89,13 +109,16 @@ void LLLandmarkList::processGetAssetReply( LLVFile file(vfs, uuid, type); S32 file_length = file.getSize(); - char* buffer = new char[ file_length + 1 ]; - file.read( (U8*)buffer, file_length); /*Flawfinder: ignore*/ + std::vector buffer(file_length + 1); + file.read( (U8*)&buffer[0], file_length); buffer[ file_length ] = 0; - LLLandmark* landmark = LLLandmark::constructFromString(buffer); + LLLandmark* landmark = LLLandmark::constructFromString(&buffer[0]); if (landmark) { + gLandmarkList.mList[ uuid ] = landmark; + gLandmarkList.mRequestedList.erase(uuid); + LLVector3d pos; if(!landmark->getGlobalPos(pos)) { @@ -106,13 +129,16 @@ void LLLandmarkList::processGetAssetReply( gMessageSystem, gAgent.getRegionHost(), region_id, - NULL); + boost::bind(&LLLandmarkList::onRegionHandle, &gLandmarkList, uuid)); } - } - gLandmarkList.mList[ uuid ] = landmark; - } - delete[] buffer; + // the callback will be called when we get the region handle. + } + else + { + gLandmarkList.makeCallbacks(uuid); + } + } } else { @@ -132,7 +158,54 @@ void LLLandmarkList::processGetAssetReply( } +BOOL LLLandmarkList::isAssetInLoadedCallbackMap(const LLUUID& asset_uuid) +{ + return mLoadedCallbackMap.find(asset_uuid) != mLoadedCallbackMap.end(); +} + BOOL LLLandmarkList::assetExists(const LLUUID& asset_uuid) { return mList.count(asset_uuid) != 0 || mBadList.count(asset_uuid) != 0; } + +void LLLandmarkList::onRegionHandle(const LLUUID& landmark_id) +{ + LLLandmark* landmark = getAsset(landmark_id); + + if (!landmark) + { + llwarns << "Got region handle but the landmark not found." << llendl; + return; + } + + // Calculate landmark global position. + // This should succeed since the region handle is available. + LLVector3d pos; + if (!landmark->getGlobalPos(pos)) + { + llwarns << "Got region handle but the landmark global position is still unknown." << llendl; + return; + } + + makeCallbacks(landmark_id); +} + +void LLLandmarkList::makeCallbacks(const LLUUID& landmark_id) +{ + LLLandmark* landmark = getAsset(landmark_id); + + if (!landmark) + { + llwarns << "Landmark to make callbacks for not found." << llendl; + } + + // make all the callbacks here. + loaded_callback_map_t::iterator it; + while((it = mLoadedCallbackMap.find(landmark_id)) != mLoadedCallbackMap.end()) + { + if (landmark) + (*it).second(landmark); + + mLoadedCallbackMap.erase(it); + } +} diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h index c41ba7a0f..3356f866c 100644 --- a/indra/newview/lllandmarklist.h +++ b/indra/newview/lllandmarklist.h @@ -2,37 +2,32 @@ * @file lllandmarklist.h * @brief Landmark asset list class * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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_LLLANDMARKLIST_H #define LL_LLLANDMARKLIST_H +#include #include #include "lllandmark.h" #include "lluuid.h" @@ -45,6 +40,8 @@ class LLInventoryItem; class LLLandmarkList { public: + typedef boost::function loaded_callback_t; + LLLandmarkList() {} ~LLLandmarkList(); @@ -53,7 +50,7 @@ public: //const LLLandmark* getNext() { return mList.getNextData(); } BOOL assetExists(const LLUUID& asset_uuid); - LLLandmark* getAsset(const LLUUID& asset_uuid); + LLLandmark* getAsset(const LLUUID& asset_uuid, loaded_callback_t cb = NULL); static void processGetAssetReply( LLVFS *vfs, const LLUUID& uuid, @@ -62,12 +59,27 @@ public: S32 status, LLExtStat ext_status ); + // Returns TRUE if loading the landmark with given asset_uuid has been requested + // but is not complete yet. + BOOL isAssetInLoadedCallbackMap(const LLUUID& asset_uuid); + protected: + void onRegionHandle(const LLUUID& landmark_id); + void makeCallbacks(const LLUUID& landmark_id); + typedef std::map landmark_list_t; landmark_list_t mList; typedef std::set landmark_bad_list_t; landmark_bad_list_t mBadList; + + typedef std::map landmark_requested_list_t; + landmark_requested_list_t mRequestedList; + + // *TODO: make the callback multimap a template class and make use of it + // here and in LLLandmark. + typedef std::multimap loaded_callback_map_t; + loaded_callback_map_t mLoadedCallbackMap; }; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index e80032239..192c5f531 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -88,11 +88,18 @@ std::string LLLogChat::timestamp(bool withdate) // it's daylight savings time there. timep = utc_to_pacific_time(utc_time, gPacificDaylightTime); + static LLCachedControl withseconds("SecondsInLog"); std::string text; if (withdate) - text = llformat("[%d/%02d/%02d %02d:%02d] ", (timep->tm_year-100)+2000, timep->tm_mon+1, timep->tm_mday, timep->tm_hour, timep->tm_min); + if (withseconds) + text = llformat("[%d-%02d-%02d %02d:%02d:%02d] ", (timep->tm_year-100)+2000, timep->tm_mon+1, timep->tm_mday, timep->tm_hour, timep->tm_min, timep->tm_sec); + else + text = llformat("[%d/%02d/%02d %02d:%02d] ", (timep->tm_year-100)+2000, timep->tm_mon+1, timep->tm_mday, timep->tm_hour, timep->tm_min); else - text = llformat("[%02d:%02d] ", timep->tm_hour, timep->tm_min); + if (withseconds) + text = llformat("[%02d:%02d:%02d] ", timep->tm_hour, timep->tm_min, timep->tm_sec); + else + text = llformat("[%02d:%02d] ", timep->tm_hour, timep->tm_min); return text; } diff --git a/indra/newview/llmakeoutfitdialog.cpp b/indra/newview/llmakeoutfitdialog.cpp new file mode 100644 index 000000000..be70012d1 --- /dev/null +++ b/indra/newview/llmakeoutfitdialog.cpp @@ -0,0 +1,224 @@ +/** + * @file llmakeoutfitdialog.cpp + * @brief The Make Outfit Dialog, triggered by "Make Outfit" and similar UICtrls. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llmakeoutfitdialog.h" + +#include "llappearancemgr.h" +#include "lluictrlfactory.h" +#include "llvoavatarself.h" +#include "llagent.h" +#include "llviewerregion.h" + +#include "hippogridmanager.h" + +LLMakeOutfitDialog::LLMakeOutfitDialog(bool modal) : LLModalDialog(LLStringUtil::null, 515, 510, modal) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_new_outfit_dialog.xml"); + + setCanClose(!modal); + setCanMinimize(!modal); + + // Build list of check boxes + for (S32 i = 0; i < LLWearableType::WT_COUNT; i++) + { + std::string name = std::string("checkbox_") + LLWearableType::getTypeLabel((LLWearableType::EType)i); + mCheckBoxList.push_back(std::make_pair(name, i)); + // Hide undergarments from teens + if (gAgent.isTeen() && ((LLWearableType::WT_UNDERSHIRT == (LLWearableType::EType)i) || (LLWearableType::WT_UNDERPANTS == (LLWearableType::EType)i))) + { + childSetVisible(name, false); // Lest they know what's beyond their reach. + } + else + { + bool enabled = gAgentWearables.getWearableCount((LLWearableType::EType)i); // TODO: MULTI-WEARABLE + bool selected = enabled && (LLWearableType::WT_SHIRT <= i); // only select clothing by default + childSetEnabled(name, enabled); + childSetValue(name, selected); + } + } + + // NOTE: .xml needs to be updated if attachments are added or their names are changed! + LLVOAvatar* avatar = gAgentAvatarp; + if (avatar) + { + for (LLVOAvatar::attachment_map_t::iterator iter = avatar->mAttachmentPoints.begin(); iter != avatar->mAttachmentPoints.end();) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + S32 attachment_pt = curiter->first; + bool object_attached = (attachment->getNumObjects() > 0); + std::string name = std::string("checkbox_") + attachment->getName(); + mCheckBoxList.push_back(std::make_pair(name, attachment_pt)); + childSetEnabled(name, object_attached); + } + } + + if (!gHippoGridManager->getConnectedGrid()->supportsInvLinks()) + { + childSetEnabled("checkbox_use_links", false); + childSetValue("checkbox_use_links", false); + childSetEnabled("checkbox_use_outfits", false); + childSetValue("checkbox_use_outfits", false); + } + + getChild("Save")->setCommitCallback(boost::bind(&LLMakeOutfitDialog::onSave, this)); + getChild("Cancel")->setCommitCallback(boost::bind(&LLMakeOutfitDialog::close, this, _1)); + getChild("Check All")->setCommitCallback(boost::bind(&LLMakeOutfitDialog::onCheckAll, this, true)); + getChild("Uncheck All")->setCommitCallback(boost::bind(&LLMakeOutfitDialog::onCheckAll, this, false)); + getChild("checkbox_use_outfits")->setCommitCallback(boost::bind(&LLMakeOutfitDialog::refresh, this)); + startModal(); +} + +//virtual +void LLMakeOutfitDialog::draw() +{ + bool one_or_more_items_selected = false; + for (S32 i = 0; i < (S32)mCheckBoxList.size(); i++) + { + if (childGetValue(mCheckBoxList[i].first).asBoolean()) + { + one_or_more_items_selected = true; + break; + } + } + childSetEnabled("Save", one_or_more_items_selected); + + LLModalDialog::draw(); +} + +BOOL LLMakeOutfitDialog::postBuild() +{ + refresh(); + return true; +} + +void LLMakeOutfitDialog::refresh() +{ + bool fUseOutfits = getUseOutfits(); + + for (S32 idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++) + { + LLWearableType::EType wtType = (LLWearableType::EType)idxType; + if (LLAssetType::AT_BODYPART != LLWearableType::getAssetType(wtType)) + continue; + LLUICtrl* pCheckCtrl = getChild(std::string("checkbox_") + LLWearableType::getTypeLabel(wtType)); + if (!pCheckCtrl) + continue; + + pCheckCtrl->setEnabled(!fUseOutfits); + if (fUseOutfits) + pCheckCtrl->setValue(true); + } + childSetEnabled("checkbox_use_links", !fUseOutfits); +} + + +void LLMakeOutfitDialog::setWearableToInclude(S32 wearable, bool enabled, bool selected) +{ + LLWearableType::EType wtType = (LLWearableType::EType)wearable; + if (((0 <= wtType) && (wtType < LLWearableType::WT_COUNT)) && + ((LLAssetType::AT_BODYPART != LLWearableType::getAssetType(wtType)) || !getUseOutfits())) + { + std::string name = std::string("checkbox_") + LLWearableType::getTypeLabel(wtType); + childSetEnabled(name, enabled); + childSetValue(name, selected); + } +} + +void LLMakeOutfitDialog::getIncludedItems(LLInventoryModel::item_array_t& item_list) +{ + LLInventoryModel::cat_array_t *cats; + LLInventoryModel::item_array_t *items; + gInventory.getDirectDescendentsOf(LLAppearanceMgr::instance().getCOF(), cats, items); + for (LLInventoryModel::item_array_t::const_iterator iter = items->begin(); iter != items->end(); ++iter) + { + LLViewerInventoryItem* item = (*iter); + if (!item) + continue; + if (item->isWearableType()) + { + LLWearableType::EType type = item->getWearableType(); + if (type < LLWearableType::WT_COUNT && childGetValue(mCheckBoxList[type].first).asBoolean()) + { + item_list.push_back(item); + } + } + else + { + LLViewerJointAttachment* attachment = gAgentAvatarp->getWornAttachmentPoint(item->getLinkedUUID()); + if (attachment && childGetValue(std::string("checkbox_")+attachment->getName()).asBoolean()) + { + item_list.push_back(item); + } + } + } +} + +void LLMakeOutfitDialog::onSave() +{ + std::string folder_name = childGetValue("name ed").asString(); + LLStringUtil::trim(folder_name); + if (!folder_name.empty()) + { + makeOutfit(folder_name); + close(); // destroys this object + } +} + +void LLMakeOutfitDialog::onCheckAll(bool check) +{ + for (S32 i = 0; i < (S32)(mCheckBoxList.size()); i++) + { + std::string name = mCheckBoxList[i].first; + if (childIsEnabled(name)) childSetValue(name, check); + } +} + +void LLMakeOutfitDialog::makeOutfit(const std::string folder_name) +{ + LLInventoryModel::item_array_t item_list; + getIncludedItems(item_list); + + // MULTI-WEARABLES TODO + if (getUseOutfits()) + LLAppearanceMgr::instance().makeNewOutfitLinks(folder_name, item_list); + else + LLAppearanceMgr::instance().makeNewOutfitLegacy(folder_name, item_list, getUseLinks()); + + if ( gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()) + { + LLAppearanceMgr::instance().requestServerAppearanceUpdate(); + } +} + diff --git a/indra/newview/llmakeoutfitdialog.h b/indra/newview/llmakeoutfitdialog.h new file mode 100644 index 000000000..caed1ceef --- /dev/null +++ b/indra/newview/llmakeoutfitdialog.h @@ -0,0 +1,66 @@ +/** + * @file llmakeoutfitdialog.h + * @brief The Make Outfit Dialog, triggered by "Make Outfit" and similar UICtrls. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLMAKEOUTFITDIALOG_H +#define LLMAKEOUTFITDIALOG_H + + +#include "llinventorymodel.h" +#include "llmodaldialog.h" + +class LLMakeOutfitDialog : public LLModalDialog +{ +private: + std::vector > mCheckBoxList; + +public: + LLMakeOutfitDialog(bool modal = true); + /*virtual*/ void draw(); + BOOL postBuild(); + void refresh(); + + void setWearableToInclude(S32 wearable, bool enabled, bool selected); //TODO: Call this when Wearables are added or removed to update the Dialog in !modal mode. + void onSave(); + void onCheckAll(bool check); + + //Accessors + void getIncludedItems(LLInventoryModel::item_array_t& item_list); + bool getUseOutfits() { return childGetValue("checkbox_use_outfits").asBoolean(); } + bool getUseLinks() { return childGetValue("checkbox_use_links").asBoolean(); } + //bool getRenameClothing() { return childGetValue("rename").asBoolean(); } + +protected: + void makeOutfit(const std::string folder_name); +}; + +#endif //LLMAKEOUTFITDIALOG_H + diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 3ffb93f69..77631c193 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -2,31 +2,25 @@ * @file llmanip.cpp * @brief LLManip class implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/newview/llmanip.h b/indra/newview/llmanip.h index cdf6a3657..6263e4244 100644 --- a/indra/newview/llmanip.h +++ b/indra/newview/llmanip.h @@ -2,31 +2,25 @@ * @file llmanip.h * @brief LLManip class definition * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 304f00e4b..6f014f598 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -2,31 +2,25 @@ * @file llmaniprotate.cpp * @brief LLManipRotate class implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -500,7 +494,6 @@ BOOL LLManipRotate::handleMouseUp(S32 x, S32 y, MASK mask) // Might have missed last update due to timing. LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_ROTATION | UPD_POSITION ); LLSelectMgr::getInstance()->enableSilhouette(TRUE); - //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); LLSelectMgr::getInstance()->updateSelectionCenter(); LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); @@ -945,32 +938,32 @@ void LLManipRotate::renderSnapGuides() { if (i == 0) { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Forward" : "Direction_East"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white); } else if (i == 16) { if (constraint_axis.mV[VZ] > 0.f) { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Left" : "Direction_North"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white); } else { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Right" : "Direction_South"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white); } } else if (i == 32) { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Back" : "Direction_West"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white); } else { if (constraint_axis.mV[VZ] > 0.f) { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Right" : "Direction_South"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white); } else { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Left" : "Direction_North"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white); } } } @@ -978,7 +971,7 @@ void LLManipRotate::renderSnapGuides() { if (i == 0) { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Left" : "Direction_North"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white); } else if (i == 16) { @@ -993,7 +986,7 @@ void LLManipRotate::renderSnapGuides() } else if (i == 32) { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Right" : "Direction_South"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white); } else { @@ -1017,11 +1010,11 @@ void LLManipRotate::renderSnapGuides() { if (constraint_axis.mV[VY] > 0.f) { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Forward" : "Direction_East"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white); } else { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Back" : "Direction_West"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white); } } else if (i == 32) @@ -1032,11 +1025,11 @@ void LLManipRotate::renderSnapGuides() { if (constraint_axis.mV[VY] > 0.f) { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Back" : "Direction_West"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white); } else { - renderTickText(text_point, LLTrans::getString(mObjectSelection->isAttachment() ? "Direction_Forward" : "Direction_East"), LLColor4::white); + renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white); } } } @@ -1381,74 +1374,28 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); projected_mouse -= snap_plane_center; - S32 snap_plane = 0; - - F32 dot = cam_to_snap_plane * constraint_axis; - if (llabs(dot) < 0.01f) - { - // looking at ring edge on, project onto view plane and check if mouse is past ring - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); - projected_mouse -= snap_plane_center; - dot = projected_mouse * constraint_axis; - if (projected_mouse * constraint_axis > 0) - { - snap_plane = 1; - } - projected_mouse -= dot * constraint_axis; - } - else if (dot > 0.f) - { - // look for mouse position outside and in front of snap circle - if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) - { - snap_plane = 1; - } - } - else - { - // look for mouse position inside or in back of snap circle - if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) - { - snap_plane = 1; - } - } - - if (snap_plane == 0) - { - // try other plane - snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f)); - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_to_snap_plane.setVec(1.f, 0.f, 0.f); - } - else - { - cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_to_snap_plane.normVec(); - } - - hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); - projected_mouse -= snap_plane_center; - - dot = cam_to_snap_plane * constraint_axis; + if (gSavedSettings.getBOOL("SnapEnabled")) { + S32 snap_plane = 0; + + F32 dot = cam_to_snap_plane * constraint_axis; if (llabs(dot) < 0.01f) { // looking at ring edge on, project onto view plane and check if mouse is past ring getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); projected_mouse -= snap_plane_center; dot = projected_mouse * constraint_axis; - if (projected_mouse * constraint_axis < 0) + if (projected_mouse * constraint_axis > 0) { - snap_plane = 2; + snap_plane = 1; } projected_mouse -= dot * constraint_axis; } - else if (dot < 0.f) + else if (dot > 0.f) { // look for mouse position outside and in front of snap circle if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) { - snap_plane = 2; + snap_plane = 1; } } else @@ -1456,78 +1403,136 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) // look for mouse position inside or in back of snap circle if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) { - snap_plane = 2; + snap_plane = 1; } } - } - - if (snap_plane > 0) - { - LLVector3 cam_at_axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + + if (snap_plane == 0) { - cam_at_axis.setVec(1.f, 0.f, 0.f); + // try other plane + snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f)); + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_to_snap_plane.setVec(1.f, 0.f, 0.f); + } + else + { + cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_to_snap_plane.normVec(); + } + + hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); + projected_mouse -= snap_plane_center; + + dot = cam_to_snap_plane * constraint_axis; + if (llabs(dot) < 0.01f) + { + // looking at ring edge on, project onto view plane and check if mouse is past ring + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); + projected_mouse -= snap_plane_center; + dot = projected_mouse * constraint_axis; + if (projected_mouse * constraint_axis < 0) + { + snap_plane = 2; + } + projected_mouse -= dot * constraint_axis; + } + else if (dot < 0.f) + { + // look for mouse position outside and in front of snap circle + if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) + { + snap_plane = 2; + } + } + else + { + // look for mouse position inside or in back of snap circle + if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) + { + snap_plane = 2; + } + } } - else - { - cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_at_axis.normVec(); - } - - // first, project mouse onto screen plane at point tangent to rotation radius. - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis); - // project that point onto rotation plane - projected_mouse -= snap_plane_center; - projected_mouse -= projected_vec(projected_mouse, constraint_axis); - - F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec()); - F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; - if (llabs(mouse_lateral_dist) > 0.01f) - { - mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - - (mouse_lateral_dist * mouse_lateral_dist)); - } - LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis); - projected_mouse -= mouse_depth * projected_camera_at; - - if (!mInSnapRegime) - { - mSmoothRotate = TRUE; - } - mInSnapRegime = TRUE; - // 0 to 360 deg - F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); - F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); - //fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f); - - LLVector3 object_axis; - getObjectAxisClosestToMouse(object_axis); - object_axis = object_axis * first_object_node->mSavedRotation; - - // project onto constraint plane - object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); - object_axis.normVec(); - - if (relative_mouse_angle < SNAP_ANGLE_DETENTE) + if (snap_plane > 0) { - F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); - angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + LLVector3 cam_at_axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_at_axis.setVec(1.f, 0.f, 0.f); + } + else + { + cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_at_axis.normVec(); + } + + // first, project mouse onto screen plane at point tangent to rotation radius. + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis); + // project that point onto rotation plane + projected_mouse -= snap_plane_center; + projected_mouse -= projected_vec(projected_mouse, constraint_axis); + + F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec()); + F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; + if (llabs(mouse_lateral_dist) > 0.01f) + { + mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - + (mouse_lateral_dist * mouse_lateral_dist)); + } + LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis); + projected_mouse -= mouse_depth * projected_camera_at; + + if (!mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = TRUE; + // 0 to 360 deg + F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); + + F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); + //fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f); + + LLVector3 object_axis; + getObjectAxisClosestToMouse(object_axis); + object_axis = object_axis * first_object_node->mSavedRotation; + + // project onto constraint plane + object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); + object_axis.normVec(); + + if (relative_mouse_angle < SNAP_ANGLE_DETENTE) + { + F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); + angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + else + { + angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + return LLQuaternion( -angle, constraint_axis ); } else { - angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + if (mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = FALSE; } - return LLQuaternion( -angle, constraint_axis ); } - else - { + else { if (mInSnapRegime) { mSmoothRotate = TRUE; } mInSnapRegime = FALSE; - + } + + if (!mInSnapRegime) + { LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis; up_from_axis.normVec(); LLVector3 cur_intersection; @@ -1694,7 +1699,6 @@ void LLManipRotate::highlightManipulators( S32 x, S32 y ) return; } - LLQuaternion object_rot = first_object->getRenderRotation(); LLVector3 rotation_center = gAgent.getPosAgentFromGlobal(mRotationCenter); LLVector3 mouse_dir_x; LLVector3 mouse_dir_y; diff --git a/indra/newview/llmaniprotate.h b/indra/newview/llmaniprotate.h index bb97f5cc2..e8f1c24c5 100644 --- a/indra/newview/llmaniprotate.h +++ b/indra/newview/llmaniprotate.h @@ -2,31 +2,25 @@ * @file llmaniprotate.h * @brief LLManipRotate class definition * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index e1e6552f9..8cd1abe58 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -2,31 +2,25 @@ * @file llmanipscale.cpp * @brief LLManipScale class implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -385,7 +379,6 @@ BOOL LLManipScale::handleMouseUp(S32 x, S32 y, MASK mask) // Might have missed last update due to UPDATE_DELAY timing LLSelectMgr::getInstance()->sendMultipleUpdate( mLastUpdateFlags ); - //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); } return LLManip::handleMouseUp(x, y, mask); @@ -1186,9 +1179,6 @@ void LLManipScale::dragFace( S32 x, S32 y ) mInSnapRegime = FALSE; } - BOOL send_scale_update = FALSE; - BOOL send_position_update = FALSE; - LLVector3 dir_agent; if( part_dir_local.mV[VX] ) { @@ -1205,8 +1195,6 @@ void LLManipScale::dragFace( S32 x, S32 y ) stretchFace( projected_vec(drag_start_dir_f, dir_agent) + drag_start_center_agent, projected_vec(drag_delta, dir_agent)); - send_position_update = TRUE; - send_scale_update = TRUE; mDragPointGlobal = drag_point_global; } diff --git a/indra/newview/llmanipscale.h b/indra/newview/llmanipscale.h index edfe2257a..521a65e49 100644 --- a/indra/newview/llmanipscale.h +++ b/indra/newview/llmanipscale.h @@ -2,31 +2,25 @@ * @file llmanipscale.h * @brief LLManipScale class definition * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 7c86889a1..c7e31fd45 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -2,31 +2,25 @@ * @file llmaniptranslate.cpp * @brief LLManipTranslate class implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -67,6 +61,7 @@ #include "llworld.h" #include "llui.h" #include "pipeline.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" @@ -502,7 +497,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) } // Throttle updates to 10 per second. - BOOL send_update = FALSE; LLVector3 axis_f; LLVector3d axis_d; @@ -547,6 +541,9 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) { F32 max_drag_distance = gSavedSettings.getF32("MaxDragDistance"); + if (gHippoGridManager->getConnectedGrid()->isAurora()) + max_drag_distance = llmin(10000.f, max_drag_distance); + if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance) { lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (too far)" << llendl; @@ -719,11 +716,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) LLVector3 old_position_local = object->getPosition(); LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation); - // move and clamp root object first, before adjusting children - if (new_position_local != old_position_local) - { - send_update = TRUE; - } //RN: I forget, but we need to do this because of snapping which doesn't often result // in position changes even when the mouse moves object->setPosition(new_position_local); @@ -733,8 +725,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) if (selectNode->mIndividualSelection) { - send_update = FALSE; - // counter-translate child objects if we are moving the root as an individual object->resetChildrenPosition(old_position_local - new_position_local, TRUE) ; } @@ -770,7 +760,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) } // PR: Only update if changed - LLVector3d old_position_global = object->getPositionGlobal(); LLVector3 old_position_agent = object->getPositionAgent(); LLVector3 new_position_agent = gAgent.getPosAgentFromGlobal(new_position_global); if (object->isRootEdit()) @@ -792,11 +781,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) { // counter-translate child objects if we are moving the root as an individual object->resetChildrenPosition(old_position_agent - new_position_agent, TRUE) ; - send_update = FALSE; - } - else if (old_position_global != new_position_global) - { - send_update = TRUE; } } selectNode->mLastPositionLocal = object->getPosition(); @@ -1077,7 +1061,6 @@ BOOL LLManipTranslate::handleMouseUp(S32 x, S32 y, MASK mask) mInSnapRegime = FALSE; LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); - //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); } return LLManip::handleMouseUp(x, y, mask); @@ -1328,7 +1311,6 @@ void LLManipTranslate::renderSnapGuides() // add in off-axis offset tick_start += (mSnapOffsetAxis * mSnapOffsetMeters); - BOOL is_sub_tick = FALSE; F32 tick_scale = 1.f; for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) { @@ -1337,7 +1319,6 @@ void LLManipTranslate::renderSnapGuides() break; } tick_scale *= 0.7f; - is_sub_tick = TRUE; } // S32 num_ticks_to_fade = is_sub_tick ? num_ticks_per_side / 2 : num_ticks_per_side; @@ -1559,7 +1540,6 @@ void LLManipTranslate::renderSnapGuides() float a = line_alpha; - LLColor4 col = gColors.getColor("SilhouetteChildColor"); { //draw grid behind objects LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); diff --git a/indra/newview/llmaniptranslate.h b/indra/newview/llmaniptranslate.h index d20b86b2f..37567c7bd 100644 --- a/indra/newview/llmaniptranslate.h +++ b/indra/newview/llmaniptranslate.h @@ -2,31 +2,25 @@ * @file llmaniptranslate.h * @brief LLManipTranslate class definition * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/newview/llmapresponders.cpp b/indra/newview/llmapresponders.cpp index cf0769bce..eaae3e450 100644 --- a/indra/newview/llmapresponders.cpp +++ b/indra/newview/llmapresponders.cpp @@ -38,6 +38,8 @@ #include "llviewertexturelist.h" #include "llworldmap.h" #include "llagent.h" +#include "llworldmapmessage.h" +#include "llsdserialize.h" //virtual void LLMapLayerResponder::result(const LLSD& result) @@ -45,22 +47,19 @@ void LLMapLayerResponder::result(const LLSD& result) llinfos << "LLMapLayerResponder::result from capabilities" << llendl; S32 agent_flags = result["AgentData"]["Flags"]; - - if (agent_flags != LLWorldMap::getInstance()->mCurrentMap) + U32 layer = flagsToLayer(agent_flags); + + if (layer != SIM_LAYER_COMPOSITE) { llwarns << "Invalid or out of date map image type returned!" << llendl; return; } LLUUID image_id; - //U32 left, right, top, bottom; - LLWorldMap::getInstance()->mMapLayers[agent_flags].clear(); - - bool use_web_map_tiles = LLWorldMap::useWebMapTiles(); + LLWorldMap::getInstance()->mMapLayers.clear(); LLSD::array_const_iterator iter; - BOOL adjust = FALSE; for(iter = result["LayerData"].beginArray(); iter != result["LayerData"].endArray(); ++iter) { const LLSD& layer_data = *iter; @@ -74,146 +73,12 @@ void LLMapLayerResponder::result(const LLSD& result) new_layer.LayerExtents.mTop = layer_data["Top"]; new_layer.LayerImageID = layer_data["ImageID"]; -// if (use_web_map_tiles) -// { -// new_layer.LayerImage = LLWorldMap::loadObjectsTile((U32)new_layer.LayerExtents.mLeft, (U32)new_layer.LayerExtents.mBottom); // no good... Maybe using of level 2 and higher web maps ? -// } -// else -// { - new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID); -// } + new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID); + gGL.getTexUnit(0)->bind(new_layer.LayerImage.get()); new_layer.LayerImage->setAddressMode(LLTexUnit::TAM_CLAMP); - F32 x_meters = F32(new_layer.LayerExtents.mLeft*REGION_WIDTH_UNITS); - F32 y_meters = F32(new_layer.LayerExtents.mBottom*REGION_WIDTH_UNITS); - adjust = LLWorldMap::getInstance()->extendAABB(U32(x_meters), U32(y_meters), - U32(x_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getWidth()), - U32(y_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getHeight())) || adjust; - - LLWorldMap::getInstance()->mMapLayers[agent_flags].push_back(new_layer); + LLWorldMap::getInstance()->mMapLayers.push_back(new_layer); } - - LLWorldMap::getInstance()->mMapLoaded[agent_flags] = TRUE; - if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); - - /* - U32 agent_flags; - msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); - - if (agent_flags < 0 || agent_flags >= MAP_SIM_IMAGE_TYPES) - { - llwarns << "Invalid map image type returned! " << agent_flags << llendl; - return; - } - */ - - bool found_null_sim = false; - - adjust = FALSE; - if (result.has("MapBlocks")) - { - const LLSD& map_blocks = result["MapBlocks"]; - for (iter = map_blocks.beginArray(); iter != map_blocks.endArray(); ++iter) - { - const LLSD& map_block = *iter; - - S32 x_regions = map_block["X"]; - S32 y_regions = map_block["Y"]; - S32 x_size = map_block["SizeX"]; - S32 y_size = map_block["SizeY"]; - std::string name = map_block["Name"]; - S32 access = map_block["Access"]; - S32 region_flags = map_block["RegionFlags"]; - S32 water_height = map_block["WaterHeight"]; - LLUUID image_id = map_block["MapImageID"]; - - U32 x_meters = x_regions * REGION_WIDTH_UNITS; - U32 y_meters = y_regions * REGION_WIDTH_UNITS; - - if (access == 255) - { - // This region doesn't exist - if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) - { - // We were tracking this location, but it doesn't exist - LLWorldMap::getInstance()->mInvalidLocation = TRUE; - } - - found_null_sim = true; - } - else - { - adjust = LLWorldMap::getInstance()->extendAABB(x_meters, - y_meters, - x_meters+REGION_WIDTH_UNITS, - y_meters+REGION_WIDTH_UNITS) || adjust; - U64 handle = to_region_handle(x_meters, y_meters); - - // llinfos << "Map sim " << name << " image layer " << agent_flags << " ID " << image_id.getString() << llendl; - - LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); - if (siminfo == NULL) - { - siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); - } - - siminfo->setName( name ); - siminfo->setAccess( access ); /*Flawfinder: ignore*/ - siminfo->setRegionFlags( region_flags ); - siminfo->setWaterHeight( (F32) water_height ); - siminfo->setMapImageID( image_id, agent_flags ); - siminfo->setSize((U16)x_size, (U16)y_size); - if (use_web_map_tiles) - { - siminfo->mCurrentImage = LLWorldMap::loadObjectsTile((U32)x_regions, (U32)y_regions); - } - else - { - siminfo->mCurrentImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap]); - } - siminfo->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); - gGL.getTexUnit(0)->bind(siminfo->mCurrentImage.get()); - - if (siminfo->mMapImageID[2].notNull()) - { - siminfo->mOverlayImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[2]); - } - else - { - siminfo->mOverlayImage = NULL; - } - - if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) - { - if (siminfo->isDown()) - { - // We were tracking this location, but it doesn't exist - LLWorldMap::getInstance()->mInvalidLocation = true; - } - else - { - // We were tracking this location, and it does exist - bool is_tracking_dbl = LLWorldMap::getInstance()->mIsTrackingDoubleClick == TRUE; - gFloaterWorldMap->trackLocation(LLWorldMap::getInstance()->mUnknownLocation); - if (is_tracking_dbl) - { - LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); - gAgent.teleportViaLocation( pos_global ); - } - } - } - } - } - } - if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); - gFloaterWorldMap->updateSims(found_null_sim); + LLWorldMap::getInstance()->mMapLoaded = true; } diff --git a/indra/newview/llmapresponders.h b/indra/newview/llmapresponders.h index 8b287c9fb..835722348 100644 --- a/indra/newview/llmapresponders.h +++ b/indra/newview/llmapresponders.h @@ -40,8 +40,9 @@ extern AIHTTPTimeoutPolicy mapLayerResponder_timeout; class LLMapLayerResponder : public LLHTTPClient::ResponderWithResult { - virtual void result(const LLSD& content); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return mapLayerResponder_timeout; } + /*virtual*/ void result(const LLSD& content); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return mapLayerResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLMapLayerResponder"; } }; #endif // LL_LLMAPLAYERRESPONDER_H diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 47c8791c9..0b19efde6 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -41,24 +41,53 @@ // Helpers // +static std::string getLoginUriDomain() +{ + LLURI uri(gHippoGridManager->getConnectedGrid()->getLoginUri()); + std::string hostname = uri.hostName(); // Ie, "login..lindenlab.com" + if (hostname.substr(0, 6) == "login.") + { + hostname = hostname.substr(6); // ".lindenlab.com" + } + return hostname; +} + +// Apart from well-known cases, in general this function returns the domain of the loginUri (with the "login." stripped off). +// This should be correct for all SL BETA grids, assuming they have the form of "login..lindenlab.com", in which +// case it returns ".lindenlab.com". +// +// Well-known cases that deviate from this: +// agni --> "secondlife.com" +// damballah --> "secondlife-staging.com" +// static std::string getMarketplaceDomain() { - std::string domain = "secondlife.com"; + std::string domain; if (gHippoGridManager->getCurrentGrid()->isSecondLife()) { - if (!LLViewerLogin::getInstance()->isInProductionGrid()) + if (gHippoGridManager->getConnectedGrid()->isInProductionGrid()) { - domain = "secondlife.aditi.lindenlab.com"; + domain = "secondlife.com"; // agni + } + else + { + // SecondLife(tm) BETA grid. + // Using the login URI is a bit of a kludge, but it's the best we've got at the moment. + domain = utf8str_tolower(getLoginUriDomain()); // .lindenlab.com; ie, "aditi.lindenlab.com". + llassert(domain.length() > 14 && domain.substr(domain.length() - 14) == ".lindenlab.com"); + if (domain == "damballah.lindenlab.com") + { + domain = "secondlife-staging.com"; + } } } else { // TODO: Find out if OpenSim, and Avination adopted any outbox stuffs, if so code HippoGridManager for this // Aurora grid has not. - // For now, reset domain on other grids, so we don't harass LL web services. - domain = ""; //gHippoGridManager->getCurrentGrid()->getMarketPlaceDomain(); + // For now, set domain on other grids to the loginUri domain, so we don't harass LL web services. + domain = getLoginUriDomain(); //gHippoGridManager->getCurrentGrid()->getMarketPlaceDomain(); } - return domain; } @@ -128,9 +157,7 @@ namespace LLMarketplaceImport class LLImportPostResponder : public LLHTTPClient::ResponderWithCompleted { public: - AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return MPImportPostResponder_timeout; } - - void completed(U32 status, const std::string& reason, const LLSD& content) + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) { slmPostTimer.stop(); @@ -160,25 +187,34 @@ namespace LLMarketplaceImport sImportResultStatus = status; sImportId = content; } + + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return MPImportPostResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLImportPostResponder"; } }; class LLImportGetResponder : public LLHTTPClient::ResponderWithCompleted { public: - AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return MPImportGetResponder_timeout; } + /*virtual*/ bool followRedir(void) const { return true; } + /*virtual*/ bool needsHeaders(void) const { return true; } - bool needsHeaders(void) const { return true; } - - void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { - std::string set_cookie_string; - if (headers.getFirstValue("set-cookie", set_cookie_string) && !set_cookie_string.empty()) + if (status == HTTP_OK) { - sMarketplaceCookie = set_cookie_string; + std::string value = get_cookie("_slm_session"); + if (!value.empty()) + { + sMarketplaceCookie = value; + } + else if (sMarketplaceCookie.empty()) + { + llwarns << "No such cookie \"_slm_session\" received!" << llendl; + } } } - void completed(U32 status, const std::string& reason, const LLSD& content) + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) { slmGetTimer.stop(); @@ -196,7 +232,7 @@ namespace LLMarketplaceImport { if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl; + llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout (" << status << " / " << reason << ")." << llendl; } sMarketplaceCookie.clear(); @@ -207,6 +243,9 @@ namespace LLMarketplaceImport sImportResultStatus = status; sImportResults = content; } + + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return MPImportGetResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLImportGetResponder"; } }; // Basic API @@ -342,7 +381,7 @@ namespace LLMarketplaceImport // Interface class // -//static const F32 MARKET_IMPORTER_UPDATE_FREQUENCY = 300.0f; //1.0f; +static const F32 MARKET_IMPORTER_UPDATE_FREQUENCY = 1.0f; //static void LLMarketplaceInventoryImporter::update() @@ -353,7 +392,7 @@ void LLMarketplaceInventoryImporter::update() if (update_timer.hasExpired()) { LLMarketplaceInventoryImporter::instance().updateImport(); - static LLCachedControl MARKET_IMPORTER_UPDATE_FREQUENCY("MarketImporterUpdateFreq", 10.0f); + //static LLCachedControl MARKET_IMPORTER_UPDATE_FREQUENCY("MarketImporterUpdateFreq", 1.0f); update_timer.setTimerExpirySec(MARKET_IMPORTER_UPDATE_FREQUENCY); } } diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index a203559c1..620273289 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -91,9 +91,9 @@ LLMediaCtrl::LLMediaCtrl( const std::string& name, const LLRect& rect ) : if(!getDecoupleTextureSize()) { S32 screen_width = mIgnoreUIScale ? - llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth(); + llround((F32)getRect().getWidth() * LLUI::getScaleFactor().mV[VX]) : getRect().getWidth(); S32 screen_height = mIgnoreUIScale ? - llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight(); + llround((F32)getRect().getHeight() * LLUI::getScaleFactor().mV[VY]) : getRect().getHeight(); setTextureSize(screen_width, screen_height); } @@ -444,8 +444,8 @@ void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) { if(!getDecoupleTextureSize()) { - S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width; - S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height; + S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::getScaleFactor().mV[VX]) : width; + S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::getScaleFactor().mV[VY]) : height; // when floater is minimized, these sizes are negative if ( screen_height > 0 && screen_width > 0 ) @@ -725,8 +725,8 @@ void LLMediaCtrl::draw() gGL.loadIdentity(); // font system stores true screen origin, need to scale this by UI scale factor // to get render origin for this view (with unit scale) - gGL.translatef(floorf(LLFontGL::sCurOrigin.mX * LLUI::sGLScaleFactor.mV[VX]), - floorf(LLFontGL::sCurOrigin.mY * LLUI::sGLScaleFactor.mV[VY]), + gGL.translatef(floorf(LLFontGL::sCurOrigin.mX * LLUI::getScaleFactor().mV[VX]), + floorf(LLFontGL::sCurOrigin.mY * LLUI::getScaleFactor().mV[VY]), LLFontGL::sCurDepth); } @@ -778,10 +778,10 @@ void LLMediaCtrl::draw() if (mIgnoreUIScale) { - x_offset = llround((F32)x_offset * LLUI::sGLScaleFactor.mV[VX]); - y_offset = llround((F32)y_offset * LLUI::sGLScaleFactor.mV[VY]); - width = llround((F32)width * LLUI::sGLScaleFactor.mV[VX]); - height = llround((F32)height * LLUI::sGLScaleFactor.mV[VY]); + x_offset = llround((F32)x_offset * LLUI::getScaleFactor().mV[VX]); + y_offset = llround((F32)y_offset * LLUI::getScaleFactor().mV[VY]); + width = llround((F32)width * LLUI::getScaleFactor().mV[VX]); + height = llround((F32)height * LLUI::getScaleFactor().mV[VY]); } // draw the browser @@ -841,14 +841,14 @@ void LLMediaCtrl::convertInputCoords(S32& x, S32& y) coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL(); } - x = mIgnoreUIScale ? llround((F32)x * LLUI::sGLScaleFactor.mV[VX]) : x; + x = mIgnoreUIScale ? llround((F32)x * LLUI::getScaleFactor().mV[VX]) : x; if ( ! coords_opengl ) { - y = mIgnoreUIScale ? llround((F32)(y) * LLUI::sGLScaleFactor.mV[VY]) : y; + y = mIgnoreUIScale ? llround((F32)(y) * LLUI::getScaleFactor().mV[VY]) : y; } else { - y = mIgnoreUIScale ? llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight() - y; + y = mIgnoreUIScale ? llround((F32)(getRect().getHeight() - y) * LLUI::getScaleFactor().mV[VY]) : getRect().getHeight() - y; }; } diff --git a/indra/newview/llmediaremotectrl.cpp b/indra/newview/llmediaremotectrl.cpp index 50d3276b8..e5fa89e16 100644 --- a/indra/newview/llmediaremotectrl.cpp +++ b/indra/newview/llmediaremotectrl.cpp @@ -35,6 +35,8 @@ #include "llmediaremotectrl.h" #include "llaudioengine.h" +#include "llchat.h" +#include "llfloaterchat.h" #include "lliconctrl.h" #include "llmimetypes.h" #include "lloverlaybar.h" @@ -53,6 +55,7 @@ // static LLRegisterWidget r("media_remote"); +static std::string sLastTooltip; LLMediaRemoteCtrl::LLMediaRemoteCtrl() { @@ -263,10 +266,22 @@ void LLMediaRemoteCtrl::enableMediaButtons() if(artist.isDefined() && title.isDefined()) info_text = artist.asString() + " -- " + title.asString(); else if(title.isDefined()) - info_text = std::string("Title: ") + title.asString(); + info_text = getString("Title") + ": " + title.asString(); else if(artist.isDefined()) - info_text = std::string("Artist: ") + artist.asString(); - music_pause_btn->setToolTip(info_text); + info_text = getString("Artist") + ": " + artist.asString(); + if(music_pause_btn->getToolTip() != info_text) //Has info_text changed since last call? + { + music_pause_btn->setToolTip(info_text); + static LLCachedControl announce_stream_metadata("AnnounceStreamMetadata"); + if(announce_stream_metadata && info_text != sLastTooltip && info_text != "Loading...") //Are we announcing? Don't annoounce what we've last announced. Don't announce Loading. + { + sLastTooltip = info_text; + LLChat chat; + chat.mText = getString("Now_playing") + " " + info_text; + chat.mSourceType = CHAT_SOURCE_SYSTEM; + LLFloaterChat::addChat(chat); + } + } } else music_pause_btn->setToolTip(mCachedPauseTip); diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp new file mode 100644 index 000000000..0dea26fb7 --- /dev/null +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp @@ -0,0 +1,237 @@ +/** +* @file llmenuoptionpathfindingrebakenavmesh.cpp +* @brief Implementation of llmenuoptionpathfindingrebakenavmesh +* @author Prep@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* 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 "llmenuoptionpathfindingrebakenavmesh.h" + +#include +#include + +#include "llagent.h" +#include "llenvmanager.h" +#include "llnotificationsutil.h" +#include "llpathfindingmanager.h" +#include "llpathfindingnavmesh.h" +#include "llpathfindingnavmeshstatus.h" +#include "llviewerregion.h" + +LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh() + : LLSingleton(), + mIsInitialized(false), + mCanRebakeRegion(false), + mRebakeNavMeshMode(kRebakeNavMesh_Default), + mNavMeshSlot(), + mRegionCrossingSlot(), + mAgentStateSlot() +{ +} + +LLMenuOptionPathfindingRebakeNavmesh::~LLMenuOptionPathfindingRebakeNavmesh() +{ + if (mRebakeNavMeshMode == kRebakeNavMesh_RequestSent) + { + LL_WARNS("navmeshRebaking") << "During destruction of the LLMenuOptionPathfindingRebakeNavmesh " + << "singleton, the mode indicates that a request has been sent for which a response has yet " + << "to be received. This could contribute to a crash on exit." << LL_ENDL; + } + + llassert(!mIsInitialized); + if (mIsInitialized) + { + quit(); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::initialize() +{ + if (!mIsInitialized) + { + mIsInitialized = true; + + setMode(kRebakeNavMesh_Default); + + createNavMeshStatusListenerForCurrentRegion(); + + if ( !mRegionCrossingSlot.connected() ) + { + mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this)); + } + + if (!mAgentStateSlot.connected()) + { + mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleAgentState, this, _1)); + } + LLPathfindingManager::getInstance()->requestGetAgentState(); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::quit() +{ + llassert(mIsInitialized); + if (mIsInitialized) + { + if (mNavMeshSlot.connected()) + { + mNavMeshSlot.disconnect(); + } + + if (mRegionCrossingSlot.connected()) + { + mRegionCrossingSlot.disconnect(); + } + + if (mAgentStateSlot.connected()) + { + mAgentStateSlot.disconnect(); + } + + mIsInitialized = false; + } +} + +bool LLMenuOptionPathfindingRebakeNavmesh::canRebakeRegion() const +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the ability to rebake navmesh is being requested." << LL_ENDL; + } + return mCanRebakeRegion; +} + +LLMenuOptionPathfindingRebakeNavmesh::ERebakeNavMeshMode LLMenuOptionPathfindingRebakeNavmesh::getMode() const +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the mode is being requested." << LL_ENDL; + } + return mRebakeNavMeshMode; +} + +void LLMenuOptionPathfindingRebakeNavmesh::sendRequestRebakeNavmesh() +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the request is being made to rebake the navmesh." << LL_ENDL; + } + else + { + if (!canRebakeRegion()) + { + LL_WARNS("navmeshRebaking") << "attempting to rebake navmesh when user does not have permissions " + << "on this region" << LL_ENDL; + } + if (getMode() != kRebakeNavMesh_Available) + { + LL_WARNS("navmeshRebaking") << "attempting to rebake navmesh when mode is not available" + << LL_ENDL; + } + + setMode(kRebakeNavMesh_RequestSent); + LLPathfindingManager::getInstance()->requestRebakeNavMesh(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRebakeNavMeshResponse, this, _1)); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::setMode(ERebakeNavMeshMode pRebakeNavMeshMode) +{ + mRebakeNavMeshMode = pRebakeNavMeshMode; +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleAgentState(BOOL pCanRebakeRegion) +{ + llassert(mIsInitialized); + mCanRebakeRegion = pCanRebakeRegion; +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleRebakeNavMeshResponse(bool pResponseStatus) +{ + llassert(mIsInitialized); + if (getMode() == kRebakeNavMesh_RequestSent) + { + setMode(pResponseStatus ? kRebakeNavMesh_InProgress : kRebakeNavMesh_Default); + } + + if (!pResponseStatus) + { + LLNotificationsUtil::add("PathfindingCannotRebakeNavmesh"); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus) +{ + llassert(mIsInitialized); + ERebakeNavMeshMode rebakeNavMeshMode = kRebakeNavMesh_Default; + if (pNavMeshStatus.isValid()) + { + switch (pNavMeshStatus.getStatus()) + { + case LLPathfindingNavMeshStatus::kPending : + case LLPathfindingNavMeshStatus::kRepending : + rebakeNavMeshMode = kRebakeNavMesh_Available; + break; + case LLPathfindingNavMeshStatus::kBuilding : + rebakeNavMeshMode = kRebakeNavMesh_InProgress; + break; + case LLPathfindingNavMeshStatus::kComplete : + rebakeNavMeshMode = kRebakeNavMesh_NotAvailable; + break; + default : + rebakeNavMeshMode = kRebakeNavMesh_Default; + llassert(0); + break; + } + } + + setMode(rebakeNavMeshMode); +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed() +{ + llassert(mIsInitialized); + createNavMeshStatusListenerForCurrentRegion(); + mCanRebakeRegion = FALSE; + LLPathfindingManager::getInstance()->requestGetAgentState(); +} + +void LLMenuOptionPathfindingRebakeNavmesh::createNavMeshStatusListenerForCurrentRegion() +{ + if (mNavMeshSlot.connected()) + { + mNavMeshSlot.disconnect(); + } + + LLViewerRegion *currentRegion = gAgent.getRegion(); + if (currentRegion != NULL) + { + mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus, this, _2)); + LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true); + } +} diff --git a/indra/newview/llpanelpathfindingrebakenavmesh.h b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h similarity index 63% rename from indra/newview/llpanelpathfindingrebakenavmesh.h rename to indra/newview/llmenuoptionpathfindingrebakenavmesh.h index 5aa1c68d8..7b1d2873b 100644 --- a/indra/newview/llpanelpathfindingrebakenavmesh.h +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h @@ -1,6 +1,6 @@ /** -* @file llpanelpathfindingrebakenavmesh.h -* @brief Header file for llpanelpathfindingrebakenavmesh +* @file llmenuoptionpathfindingrebakenavmesh.h +* @brief Header file for llmenuoptionpathfindingrebakenavmesh * @author Prep@lindenlab.com * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ @@ -24,34 +24,22 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef LL_LLPANELPATHFINDINGREBAKENAVMESH_H -#define LL_LLPANELPATHFINDINGREBAKENAVMESH_H +#ifndef LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H +#define LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H #include -#include "llpanel.h" #include "llpathfindingmanager.h" #include "llpathfindingnavmesh.h" +#include "llsingleton.h" -class LLButton; class LLPathfindingNavMeshStatus; -class LLPanelPathfindingRebakeNavmesh : public LLPanel +class LLMenuOptionPathfindingRebakeNavmesh : public LLSingleton { - - LOG_CLASS(LLPanelPathfindingRebakeNavmesh); + LOG_CLASS(LLMenuOptionPathfindingRebakeNavmesh); public: - static LLPanelPathfindingRebakeNavmesh* getInstance(); - - virtual BOOL postBuild(); - - virtual void draw(); - virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen); - -protected: - -private: typedef enum { kRebakeNavMesh_Available, @@ -61,15 +49,21 @@ private: kRebakeNavMesh_Default = kRebakeNavMesh_NotAvailable } ERebakeNavMeshMode; - LLPanelPathfindingRebakeNavmesh(); - virtual ~LLPanelPathfindingRebakeNavmesh(); + LLMenuOptionPathfindingRebakeNavmesh(); + virtual ~LLMenuOptionPathfindingRebakeNavmesh(); - static LLPanelPathfindingRebakeNavmesh* getPanel(); + void initialize(); + void quit(); - void setMode(ERebakeNavMeshMode pRebakeNavMeshMode); + bool canRebakeRegion() const; ERebakeNavMeshMode getMode() const; - void onNavMeshRebakeClick(); + void sendRequestRebakeNavmesh(); + +protected: + +private: + void setMode(ERebakeNavMeshMode pRebakeNavMeshMode); void handleAgentState(BOOL pCanRebakeRegion); void handleRebakeNavMeshResponse(bool pResponseStatus); @@ -78,19 +72,14 @@ private: void createNavMeshStatusListenerForCurrentRegion(); - bool doDraw() const; - void updatePosition(); + bool mIsInitialized; - BOOL mCanRebakeRegion; + bool mCanRebakeRegion; ERebakeNavMeshMode mRebakeNavMeshMode; - LLButton* mNavMeshRebakeButton; - LLButton* mNavMeshSendingButton; - LLButton* mNavMeshBakingButton; - LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot; boost::signals2::connection mRegionCrossingSlot; LLPathfindingManager::agent_state_slot_t mAgentStateSlot; }; -#endif // LL_LLPANELPATHFINDINGREBAKENAVMESH_H +#endif // LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 74f090532..260c3cc87 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -226,11 +226,12 @@ public: LLMeshRepoThread::sActiveHeaderRequests--; } - virtual void completedRaw(U32 status, const std::string& reason, + /*virtual*/ void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshHeaderResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshHeaderResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLMeshHeaderResponder"; } }; class LLMeshLODResponder : public LLHTTPClient::ResponderWithCompleted @@ -252,11 +253,12 @@ public: LLMeshRepoThread::sActiveLODRequests--; } - virtual void completedRaw(U32 status, const std::string& reason, + /*virtual*/ void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshLODResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshLODResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLMeshLODResponder"; } }; class LLMeshSkinInfoResponder : public LLHTTPClient::ResponderWithCompleted @@ -271,11 +273,12 @@ public: { } - virtual void completedRaw(U32 status, const std::string& reason, + /*virtual*/ void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshSkinInfoResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshSkinInfoResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLMeshSkinInfoResponder"; } }; class LLMeshDecompositionResponder : public LLHTTPClient::ResponderWithCompleted @@ -290,11 +293,12 @@ public: { } - virtual void completedRaw(U32 status, const std::string& reason, + /*virtual*/ void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshDecompositionResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshDecompositionResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLMeshDecompositionResponder"; } }; class LLMeshPhysicsShapeResponder : public LLHTTPClient::ResponderWithCompleted @@ -309,11 +313,12 @@ public: { } - virtual void completedRaw(U32 status, const std::string& reason, + /*virtual*/ void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshPhysicsShapeResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshPhysicsShapeResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLMeshPhysicsShapeResponder"; } }; #if MESH_IMPORT @@ -366,7 +371,7 @@ void log_upload_error(S32 status, const LLSD& content, std::string stage, std::s } } -class LLWholeModelFeeResponder: public LLHTTPClient::ResponderWithCompleted +class LLWholeModelFeeResponder : public LLHTTPClient::ResponderWithCompleted { LLMeshUploadThread* mThread; LLSD mModelData; @@ -378,7 +383,7 @@ public: mObserverHandle(observer_handle) { } - virtual void completed(U32 status, + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) { @@ -417,10 +422,11 @@ public: } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return wholeModelFeeResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return wholeModelFeeResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLWholeModelFeeResponder"; } }; -class LLWholeModelUploadResponder: public LLHTTPClient::ResponderWithCompleted +class LLWholeModelUploadResponder : public LLHTTPClient::ResponderWithCompleted { LLMeshUploadThread* mThread; LLSD mModelData; @@ -433,7 +439,7 @@ public: mObserverHandle(observer_handle) { } - virtual void completed(U32 status, + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) { @@ -475,7 +481,8 @@ public: } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return wholeModelUploadResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return wholeModelUploadResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLWholeModelUploadResponder"; } }; #endif //MESH_IMPORT diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp index 203f5ca0d..0c92db3b6 100644 --- a/indra/newview/llmorphview.cpp +++ b/indra/newview/llmorphview.cpp @@ -2,31 +2,25 @@ * @file llmorphview.cpp * @brief Container for Morph functionality * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -110,8 +104,6 @@ void LLMorphView::initialize() //----------------------------------------------------------------------------- void LLMorphView::shutdown() { - LLVOAvatarSelf::onCustomizeEnd(); - if (isAgentAvatarValid()) { gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE ); @@ -133,14 +125,6 @@ void LLMorphView::setVisible(BOOL visible) if (visible) { - llassert( !gFloaterCustomize ); - gFloaterCustomize = new LLFloaterCustomize(); - gFloaterCustomize->fetchInventory(); - gFloaterCustomize->open(); /*Flawfinder: ignore*/ - - // Must do this _after_ gFloaterView is initialized. - gFloaterCustomize->switchToDefaultSubpart(); - initialize(); // First run dialog @@ -148,16 +132,11 @@ void LLMorphView::setVisible(BOOL visible) } else { - if( gFloaterCustomize ) - { - gFloaterView->removeChild( gFloaterCustomize ); - delete gFloaterCustomize; - gFloaterCustomize = NULL; - } - shutdown(); } } + if(LLFloaterCustomize::instanceExists()) + LLFloaterCustomize::getInstance()->updateVisiblity(); } void LLMorphView::updateCamera() diff --git a/indra/newview/llmorphview.h b/indra/newview/llmorphview.h index 1dd8ef7a5..74c97fa27 100644 --- a/indra/newview/llmorphview.h +++ b/indra/newview/llmorphview.h @@ -2,31 +2,25 @@ * @file llmorphview.h * @brief Container for character morph controls * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -45,7 +39,6 @@ class LLMorphView : public LLView public: LLMorphView(const std::string& name, const LLRect& rect); - void initialize(); void shutdown(); // inherited methods @@ -62,6 +55,8 @@ public: void setCameraDrivenByKeys( BOOL b ); protected: + void initialize(); + LLJoint* mCameraTargetJoint; LLVector3d mCameraOffset; LLVector3d mCameraTargetOffset; diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index efeb7c557..3ce3eb188 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -295,6 +295,23 @@ BOOL LLMuteList::isLinden(const std::string& name) const return last_name == "Linden"; } +static LLVOAvatar* find_avatar(const LLUUID& id) +{ + LLViewerObject *obj = gObjectList.findObject(id); + while (obj && obj->isAttachment()) + { + obj = (LLViewerObject *)obj->getParent(); + } + + if (obj && obj->isAvatar()) + { + return (LLVOAvatar*)obj; + } + else + { + return NULL; + } +} BOOL LLMuteList::add(const LLMute& mute, U32 flags) { @@ -391,6 +408,12 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags) LLViewerPartSim::getInstance()->clearParticlesByOwnerID(localmute.mID); } } + //mute local lights that are attached to the avatar + LLVOAvatar *avatarp = find_avatar(localmute.mID); + if (avatarp) + { + LLPipeline::removeMutedAVsLights(avatarp); + } return TRUE; } } diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 60eafcd4a..52fb33247 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -32,13 +32,16 @@ #include "llviewerprecompiledheaders.h" +#include "llnamelistctrl.h" + #include -#include "llnamelistctrl.h" +#include "llavatarnamecache.h" #include "llcachename.h" #include "llagent.h" #include "llinventory.h" +#include "lltrans.h" static LLRegisterWidget r("name_list"); @@ -51,12 +54,14 @@ LLNameListCtrl::LLNameListCtrl(const std::string& name, void* userdata, BOOL allow_multiple_selection, BOOL draw_border, + bool draw_heading, S32 name_column_index, const std::string& tooltip) : LLScrollListCtrl(name, rect, cb, userdata, allow_multiple_selection, - draw_border), + draw_border,draw_heading), mNameColumnIndex(name_column_index), - mAllowCallingCardDrop(FALSE) + mAllowCallingCardDrop(FALSE), + mShortNames(FALSE) { setToolTip(tooltip); LLNameListCtrl::sInstances.insert(this); @@ -71,19 +76,22 @@ LLNameListCtrl::~LLNameListCtrl() // public -BOOL LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, - BOOL enabled, std::string const& suffix) +LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, + BOOL enabled, const std::string& suffix) { //llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl; - std::string fullname; - BOOL result = gCacheName->getFullName(agent_id, fullname); - - fullname.append(suffix); - - addStringUUIDItem(fullname, agent_id, pos, enabled); - - return result; + LLSD item; + item["id"] = agent_id; + item["enabled"] = enabled; + item["target"] = INDIVIDUAL; + item["suffix"] = suffix; + LLSD& column = item["columns"][0]; + column["value"] = ""; + column["font"] = "SANSSERIF"; + column["column"] = "name"; + + return addNameItemRow(item, pos); } // virtual, public @@ -134,79 +142,99 @@ BOOL LLNameListCtrl::handleDragAndDrop( return handled; } + // public void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos, BOOL enabled) { - //llinfos << "LLNameListCtrl::addGroupNameItem " << group_id << llendl; - std::string group_name; - gCacheName->getGroupName(group_id, group_name); - addStringUUIDItem(group_name, group_id, pos, enabled); + LLSD item; + item["id"] = group_id; + item["enabled"] = enabled; + item["target"] = GROUP; + LLSD& column = item["columns"][0]; + column["value"] = ""; + column["font"] = "SANSSERIF"; + column["column"] = "name"; + + addNameItemRow(item, pos); } // public -void LLNameListCtrl::addGroupNameItem(LLScrollListItem* item, EAddPosition pos) - +void LLNameListCtrl::addGroupNameItem(LLSD& item, EAddPosition pos) { - //llinfos << "LLNameListCtrl::addGroupNameItem " << item->getUUID() << llendl; - - std::string group_name; - gCacheName->getGroupName(item->getUUID(), group_name); - - LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); - ((LLScrollListText*)cell)->setText( std::string(group_name) ); - - addItem(item, pos); + item["target"] = GROUP; + addNameItemRow(item, pos); } -BOOL LLNameListCtrl::addNameItem(LLScrollListItem* item, EAddPosition pos) +LLScrollListItem* LLNameListCtrl::addNameItem(LLSD& item, EAddPosition pos) { - //llinfos << "LLNameListCtrl::addNameItem " << item->getUUID() << llendl; - - std::string fullname; - BOOL result = gCacheName->getFullName(item->getUUID(), fullname); - - LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); - ((LLScrollListText*)cell)->setText( fullname ); - - addItem(item, pos); - - // this column is resizable - LLScrollListColumn* columnp = getColumn(mNameColumnIndex); - if (columnp && columnp->mHeader) - { - columnp->mHeader->setHasResizableElement(TRUE); - } - - return result; + item["target"] = INDIVIDUAL; + return addNameItemRow(item, pos); } LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos, void* userdata) { + return addNameItemRow(value, pos, userdata); +} +LLScrollListItem* LLNameListCtrl::addNameItemRow(const LLSD& value, EAddPosition pos, void* userdata) +{ + LLScrollListItem* item = LLScrollListCtrl::addElement(value, pos, userdata); + if (!item) return NULL; + + LLUUID id = item->getUUID(); // use supplied name by default std::string fullname = value["name"].asString(); - if (value["target"].asString() == "GROUP") + switch(value["target"].asInteger()) { - gCacheName->getGroupName(item->getUUID(), fullname); + case GROUP: + gCacheName->getGroupName(id, fullname); // fullname will be "nobody" if group not found - } - else if (value["target"].asString() == "SPECIAL") - { + break; + case SPECIAL: // just use supplied name - } - else // normal resident + break; + case INDIVIDUAL: { - std::string name; - if (gCacheName->getFullName(item->getUUID(), name)) + LLAvatarName av_name; + if (id.isNull()) { - fullname = name; + fullname = LLTrans::getString("AvatarNameNobody"); } + else if (LLAvatarNameCache::get(id, &av_name)) + { + if (mShortNames) + fullname = av_name.mDisplayName; + else + fullname = av_name.getCompleteName(); + } + else + { + fullname = " ( " + LLTrans::getString("LoadingData") + " ) "; + // ...schedule a callback + LLAvatarNameCache::get(id, + boost::bind(&LLNameListCtrl::onAvatarNameCache, + this, _1, _2, item->getHandle())); + } + break; + } + default: + break; } - LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); - ((LLScrollListText*)cell)->setText( fullname ); + // Append optional suffix. + std::string suffix = value["suffix"]; + if(!suffix.empty()) + { + fullname.append(suffix); + } + + LLScrollListCell* cell = item->getColumn(mNameColumnIndex); + if (cell && !fullname.empty() && cell->getValue().asString().empty()) + { + cell->setValue(fullname); + } dirtyColumns(); @@ -223,54 +251,53 @@ LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos // public void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) { - BOOL item_exists = selectByID( agent_id ); - if(item_exists) + // Find the item specified with agent_id. + S32 idx = -1; + for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++) { - S32 index = getItemIndex(getFirstSelected()); - if(index >= 0) + LLScrollListItem* item = *it; + if (item->getUUID() == agent_id) { - deleteSingleItem(index); + idx = getItemIndex(item); + break; } } + + // Remove it. + if (idx >= 0) + { + selectNthItem(idx); // not sure whether this is needed, taken from previous implementation + deleteSingleItem(idx); + } } -// public -void LLNameListCtrl::refresh(const LLUUID& agent_id, const std::string& full_name) +void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name, + LLHandle item) { - //llinfos << "LLNameListCtrl::refresh " << id << " '" << first << " " - // << last << "'" << llendl; + std::string name; + if (mShortNames) + name = av_name.mDisplayName; + else + name = av_name.getCompleteName(); - - // TODO: scan items for that ID, fix if necessary - item_list::iterator iter; - for (iter = getItemList().begin(); iter != getItemList().end(); iter++) + LLScrollListItem* list_item = item.get(); + if (list_item && list_item->getUUID() == agent_id) { - LLScrollListItem* item = *iter; - if (item->getUUID() == agent_id) + LLScrollListCell* cell = list_item->getColumn(mNameColumnIndex); + if (cell) { - LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); - if (cell) - { - ((LLScrollListText*)cell)->setText( full_name ); - } + cell->setValue(name); + setNeedsSort(); } } dirtyColumns(); } - -// static -void LLNameListCtrl::refreshAll(const LLUUID& id, const std::string& full_name) +void LLNameListCtrl::sortByName(BOOL ascending) { - std::set::iterator it; - for (it = LLNameListCtrl::sInstances.begin(); - it != LLNameListCtrl::sInstances.end(); - ++it) - { - LLNameListCtrl* ctrl = *it; - ctrl->refresh(id, full_name); - } + sortByColumnIndex(mNameColumnIndex,ascending); } // virtual @@ -320,9 +347,9 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto NULL, multi_select, draw_border, - name_column_index); - - name_list->setDisplayHeading(draw_heading); + draw_heading, + name_column_index + ); if (node->hasAttribute("heading_height")) { S32 heading_height; @@ -430,18 +457,7 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto } std::string contents = node->getTextContents(); - - typedef boost::tokenizer > tokenizer; - boost::char_separator sep("\t\n"); - tokenizer tokens(contents, sep); - tokenizer::iterator token_iter = tokens.begin(); - - while(token_iter != tokens.end()) - { - const std::string& line = *token_iter; - name_list->addCommentText(line); - ++token_iter; - } + name_list->setCommentText(contents); return name_list; } diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 0ff74423d..8a4f4141d 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -37,17 +37,26 @@ #include "llscrolllistctrl.h" +class LLAvatarName; class LLNameListCtrl -: public LLScrollListCtrl +: public LLScrollListCtrl, public LLInstanceTracker { public: + typedef enum e_name_type + { + INDIVIDUAL, + GROUP, + SPECIAL + } ENameType; + LLNameListCtrl(const std::string& name, const LLRect& rect, LLUICtrlCallback callback, void* userdata, BOOL allow_multiple_selection, BOOL draw_border = TRUE, + bool draw_heading = false, S32 name_column_index = 0, const std::string& tooltip = LLStringUtil::null); virtual ~LLNameListCtrl(); @@ -57,36 +66,38 @@ public: // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. - BOOL addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, + LLScrollListItem* addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, std::string const& suffix = LLStringUtil::null); - BOOL addNameItem(LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM); + LLScrollListItem* addNameItem(LLSD& item, EAddPosition pos = ADD_BOTTOM); - virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); + /*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); + LLScrollListItem* addNameItemRow(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. void addGroupNameItem(const LLUUID& group_id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); - void addGroupNameItem(LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM); + + void addGroupNameItem(LLSD& item, EAddPosition pos = ADD_BOTTOM); void removeNameItem(const LLUUID& agent_id); - void refresh(const LLUUID& agent_id, const std::string& full_name); - - static void refreshAll(const LLUUID& id, const std::string& full_name); - - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, + // LLView interface + /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg); void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; } + void sortByName(BOOL ascending); private: static std::set sInstances; + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle item); S32 mNameColumnIndex; BOOL mAllowCallingCardDrop; + bool mShortNames; // display name only, no SLID }; #endif diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 86294d46b..724b15c94 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -381,27 +381,29 @@ void LLNetMap::draw() LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); for(U32 i=0; igetFullName(avatar_ids[i], avName); - if(LLMuteList::getInstance()->isMuted(avatar_ids[i])) + gCacheName->getFullName(id, avName); + if(LLMuteList::getInstance()->isMuted(id)) { avColor = muted_color; } - LLViewerRegion* avatar_region = LLWorld::getInstance()->getRegionFromPosGlobal(positions[i]); + LLViewerRegion* avatar_region = LLWorld::getInstance()->getRegionFromPosGlobal(pos); LLUUID estate_owner = avatar_region? avatar_region->getOwner() : LLUUID::null; // MOYMOD Minimap custom av colors. - boost::unordered_map::const_iterator it = mm_MarkerColors.find(avatar_ids[i]); + boost::unordered_map::const_iterator it = mm_MarkerColors.find(id); if(it != mm_MarkerColors.end()) { avColor = it->second; @@ -412,12 +414,12 @@ void LLNetMap::draw() avColor = linden_color; } //check if they are an estate owner at their current position - else if(estate_owner.notNull() && avatar_ids[i] == estate_owner) + else if(estate_owner.notNull() && id == estate_owner) { avColor = em_color; } //without these dots, SL would suck. - else if(is_agent_friend(avatar_ids[i])) + else if(is_agent_friend(id)) { avColor = friend_color; } @@ -432,8 +434,8 @@ void LLNetMap::draw() if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist) { closest_dist = dist_to_cursor; - mClosestAgentToCursor = avatar_ids[i]; - mClosestAgentPosition = positions[i]; + mClosestAgentToCursor = id; + mClosestAgentPosition = pos; } } @@ -627,37 +629,11 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec { msg.assign(""); std::string fullname; - if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname)) + if(mClosestAgentToCursor.notNull() && LLAvatarNameCache::getPNSName(mClosestAgentToCursor, fullname)) { //msg.append(fullname); // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b - // [Ansariel: Display name support] - // msg.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? fullname : RlvStrings::getAnonym(fullname) ); - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - { - msg.append(RlvStrings::getAnonym(fullname)); - } - else - { - if (LLAvatarNameCache::useDisplayNames()) - { - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(mClosestAgentToCursor, &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - if (phoenix_name_system == 2 || (phoenix_name_system == 1 && avatar_name.mIsDisplayNameDefault)) - { - fullname = avatar_name.mDisplayName; - } - else - { - fullname = avatar_name.getCompleteName(true); - } - } - } - msg.append(fullname); - } - // [/Ansariel: Display name support] + msg.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? fullname : RlvStrings::getAnonym(fullname) ); // [/RLVa:KB] msg.append("\n"); diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index 5522f27a4..a834e7812 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -246,19 +246,23 @@ void LLOverlayBar::layoutButtons() if (state_buttons_panel->getVisible()) { - U32 required_width=0; + U32 button_count = 0; const child_list_t& view_list = *(state_buttons_panel->getChildList()); BOOST_FOREACH(LLView* viewp, view_list) { - required_width+=viewp->getRect().getWidth(); + if(!viewp->getEnabled()) + continue; + ++button_count; } + const S32 MAX_BAR_WIDTH = 600; + S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH); - const S32 MAX_BAR_WIDTH = 800; - //const S32 MAX_BUTTON_WIDTH = 150; + // calculate button widths + const S32 MAX_BUTTON_WIDTH = 150; static LLCachedControl status_bar_pad("StatusBarPad",10); - S32 usable_bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH) - (view_list.size()-1) * status_bar_pad; - F32 element_scale = (F32)usable_bar_width / (F32)required_width; + S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_count), 0, MAX_BUTTON_WIDTH); + S32 btn_width = segment_width - status_bar_pad; // Evenly space all buttons, starting from left S32 left = 0; @@ -266,13 +270,14 @@ void LLOverlayBar::layoutButtons() BOOST_REVERSE_FOREACH(LLView* viewp, view_list) { + if(!viewp->getEnabled()) + continue; LLRect r = viewp->getRect(); - S32 new_width = r.getWidth() * element_scale; //if(dynamic_cast(viewp)) // new_width = llclamp(new_width,0,MAX_BUTTON_WIDTH); - r.setOriginAndSize(left, bottom, new_width, r.getHeight()); - viewp->setShape(r,false); - left += viewp->getRect().getWidth() + status_bar_pad; + r.setOriginAndSize(left, bottom, btn_width, r.getHeight()); + viewp->setRect(r); + left += segment_width; } } } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 14709805e..f5792ae86 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -69,7 +69,6 @@ #include "llscrolllistctrl.h" #include "llstatusbar.h" #include "lltabcontainer.h" -#include "lltabcontainervertical.h" #include "llimview.h" #include "lltooldraganddrop.h" #include "lluiconstants.h" @@ -89,6 +88,7 @@ #include +#include @@ -167,21 +167,9 @@ void LLPanelAvatarSecondLife::updatePartnerName() { if (mPartnerID.notNull()) { - // [Ansariel: Display name support] - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(mPartnerID, &avatar_name)) - { - std::string name; - switch (gSavedSettings.getS32("PhoenixNameSystem")) - { - case 0 : name = avatar_name.getLegacyName(); break; - case 1 : name = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : name = avatar_name.mDisplayName; break; - default : name = avatar_name.getLegacyName(); break; - } + std::string name; + if (LLAvatarNameCache::getPNSName(mPartnerID, name)) childSetTextArg("partner_edit", "[NAME]", name); - } - // [/Ansariel: Display name support] childSetEnabled("partner_info", TRUE); } } @@ -202,9 +190,7 @@ void LLPanelAvatarSecondLife::clearControls() childSetValue("born", ""); childSetValue("acct", ""); - // [Ansariel: Display name support] childSetTextArg("partner_edit", "[NAME]", LLStringUtil::null); - // [/Ansariel: Display name support] mPartnerID = LLUUID::null; @@ -283,23 +269,15 @@ void LLPanelAvatarSecondLife::processProperties(void* data, EAvatarProcessorType getChild("img")->setImageAssetID(pAvatarData->image_id); - //Chalice - Show avatar age in days. - int year, month, day; - sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year); - time_t now = time(NULL); - struct tm * timeinfo; - timeinfo=localtime(&now); - timeinfo->tm_mon = --month; - timeinfo->tm_year = year - 1900; - timeinfo->tm_mday = day; - time_t birth = mktime(timeinfo); - std::stringstream NumberString; - NumberString << (difftime(now,birth) / (60*60*24)); - std::string born_on = pAvatarData->born_on; - born_on += " ("; - born_on += NumberString.str(); - born_on += ")"; - childSetValue("born", born_on); + // Show avatar age in days. + { + using namespace boost::gregorian; + int year, month, day; + sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year); + std::ostringstream born_on; + born_on << pAvatarData->born_on << " (" << day_clock::local_day() - date(year, month, day) << ")"; + childSetValue("born", born_on.str()); + } bool allow_publish = (pAvatarData->flags & AVATAR_ALLOW_PUBLISH); childSetValue("allow_publish", allow_publish); @@ -320,7 +298,7 @@ void LLPanelAvatarSecondLife::processProperties(void* data, EAvatarProcessorType // } if (0 == pAvatarGroups->group_list.size()) { - group_list->addCommentText(getString("None")); + group_list->setCommentText(getString("None")); } for(LLAvatarGroups::group_list_t::const_iterator it = pAvatarGroups->group_list.begin(); @@ -406,7 +384,7 @@ void LLPanelAvatarFirstLife::onClickImage(void* data) S32 left, top; gFloaterView->getNewFloaterPosition(&left, &top); LLRect rect = gSavedSettings.getRect("PreviewTextureRect"); - rect.translate( left - rect.mLeft, top - rect.mTop ); + rect.translate( left - rect.mLeft, rect.mTop - top ); // Changed to avoid textures being sunken below the window border. LLPreviewTexture* preview = new LLPreviewTexture("preview task texture", rect, std::string("Profile First Life Picture"), @@ -454,7 +432,7 @@ void LLPanelAvatarSecondLife::onClickImage(void* data) S32 left, top; gFloaterView->getNewFloaterPosition(&left, &top); LLRect rect = gSavedSettings.getRect("PreviewTextureRect"); - rect.translate( left - rect.mLeft, top - rect.mTop ); + rect.translate( left - rect.mLeft, rect.mTop - top ); // Changed to avoid textures being sunken below the window border. LLPreviewTexture* preview = new LLPreviewTexture("preview task texture", rect, std::string("Profile Picture: ") + name_text, @@ -582,11 +560,10 @@ BOOL LLPanelAvatarSecondLife::postBuild(void) childSetAction("Offer Teleport...", LLPanelAvatar::onClickOfferTeleport, getPanelAvatar() ); - childSetDoubleClickCallback("groups", onDoubleClickGroup, this ); + getChild("groups")->setDoubleClickCallback(boost::bind(&LLPanelAvatarSecondLife::onDoubleClickGroup,this)); childSetAction("bigimg", onClickImage, this); - getChild("img")->setFallbackImageName("default_profile_picture.j2c"); return TRUE; diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 1d3e50360..2ec1ac0eb 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -56,7 +56,6 @@ #include "lllineeditor.h" #include "llfloateravatarinfo.h" #include "llfloaterclassified.h" -#include "lltabcontainervertical.h" #include "lltextbox.h" #include "llcombobox.h" #include "llviewertexteditor.h" diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index c92e7c62d..5eda11310 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -85,8 +85,6 @@ BOOL LLPanelContents::postBuild() { - LLRect rect = this->getRect(); - setMouseOpaque(FALSE); childSetAction("button new script",&LLPanelContents::onClickNewScript, this); diff --git a/indra/newview/llpaneldirbrowser.cpp b/indra/newview/llpaneldirbrowser.cpp index 4680780da..5dee332b3 100644 --- a/indra/newview/llpaneldirbrowser.cpp +++ b/indra/newview/llpaneldirbrowser.cpp @@ -212,7 +212,7 @@ void LLPanelDirBrowser::updateResultCount() // add none found response if (list->getItemCount() == 0) { - list->addCommentText(LLTrans::getString("NoneFound")); + list->setCommentText(LLTrans::getString("NoneFound")); list->operateOnAll(LLCtrlListInterface::OP_DESELECT); } } @@ -648,7 +648,7 @@ void LLPanelDirBrowser::processDirPlacesReply(LLMessageSystem* msg, void**) std::string buffer = llformat("%.0f", (F64)dwell); row["columns"][3]["column"] = "dwell"; row["columns"][3]["value"] = buffer; - row["columns"][3]["font"] = "SANSSERIFSMALL"; + row["columns"][3]["font"] = "SANSSERIF_SMALL"; list->addElement(row); self->mResultsContents[parcel_id.asString()] = content; @@ -792,11 +792,11 @@ void LLPanelDirBrowser::processDirEventsReply(LLMessageSystem* msg, void**) row["columns"][2]["column"] = "date"; row["columns"][2]["value"] = date; - row["columns"][2]["font"] = "SANSSERIFSMALL"; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; row["columns"][3]["column"] = "time"; row["columns"][3]["value"] = llformat("%u", unix_time); - row["columns"][3]["font"] = "SANSSERIFSMALL"; + row["columns"][3]["font"] = "SANSSERIF_SMALL"; list->addElement(row, ADD_SORTED); @@ -879,7 +879,7 @@ void LLPanelDirBrowser::processDirGroupsReply(LLMessageSystem* msg, void**) row["columns"][2]["column"] = "members"; row["columns"][2]["value"] = members; - row["columns"][2]["font"] = "SANSSERIFSMALL"; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; row["columns"][3]["column"] = "score"; row["columns"][3]["value"] = search_order; @@ -1069,12 +1069,12 @@ void LLPanelDirBrowser::processDirLandReply(LLMessageSystem *msg, void**) } row["columns"][3]["column"] = "price"; row["columns"][3]["value"] = buffer; - row["columns"][3]["font"] = "SANSSERIFSMALL"; + row["columns"][3]["font"] = "SANSSERIF_SMALL"; buffer = llformat("%d", actual_area); row["columns"][4]["column"] = "area"; row["columns"][4]["value"] = buffer; - row["columns"][4]["font"] = "SANSSERIFSMALL"; + row["columns"][4]["font"] = "SANSSERIF_SMALL"; if (!auction) { @@ -1091,19 +1091,19 @@ void LLPanelDirBrowser::processDirLandReply(LLMessageSystem *msg, void**) buffer = llformat("%.1f", price_per_meter); row["columns"][5]["column"] = "per_meter"; row["columns"][5]["value"] = buffer; - row["columns"][5]["font"] = "SANSSERIFSMALL"; + row["columns"][5]["font"] = "SANSSERIF_SMALL"; } else { // Auctions start at L$1 per meter row["columns"][5]["column"] = "per_meter"; row["columns"][5]["value"] = "1.0"; - row["columns"][5]["font"] = "SANSSERIFSMALL"; + row["columns"][5]["font"] = "SANSSERIF_SMALL"; } row["columns"][6]["column"] = "landtype"; row["columns"][6]["value"] = land_type; - row["columns"][6]["font"] = "SANSSERIFSMALL"; + row["columns"][6]["font"] = "SANSSERIF_SMALL"; list->addElement(row); self->mResultsContents[parcel_id.asString()] = content; @@ -1138,7 +1138,7 @@ void LLPanelDirBrowser::addClassified(LLCtrlListInterface *list, const LLUUID& p row["columns"][2]["column"] = "price"; row["columns"][2]["value"] = price_for_listing; - row["columns"][2]["font"] = "SANSSERIFSMALL"; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; list->addElement(row); } @@ -1222,7 +1222,7 @@ void LLPanelDirBrowser::setupNewSearch() // ready the list for results list->operateOnAll(LLCtrlListInterface::OP_DELETE); - list->addCommentText(LLTrans::getString("Searching")); + list->setCommentText(LLTrans::getString("Searching")); childDisable("results"); mResultsReceived = 0; diff --git a/indra/newview/llpaneldirland.cpp b/indra/newview/llpaneldirland.cpp index c1b4c8ce9..d89c049fa 100644 --- a/indra/newview/llpaneldirland.cpp +++ b/indra/newview/llpaneldirland.cpp @@ -111,7 +111,7 @@ BOOL LLPanelDirLand::postBuild() LLScrollListCtrl* results = getChild("results"); if (results) { - results->setSortChangedCallback(onClickSort); + results->setSortChangedCallback(boost::bind(&LLPanelDirLand::onClickSort,this)); results->sortByColumn(mCurrentSortColumn,mCurrentSortAscending); LLStringUtil::format_map_t args; diff --git a/indra/newview/llpaneldisplay.cpp b/indra/newview/llpaneldisplay.cpp index d2f3bdd01..362675292 100644 --- a/indra/newview/llpaneldisplay.cpp +++ b/indra/newview/llpaneldisplay.cpp @@ -897,10 +897,14 @@ void LLPanelDisplay::apply() LLWindow* window = gViewerWindow->getWindow(); LLCoordScreen size; window->getSize(&size); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); gViewerWindow->changeDisplaySettings(window->getFullscreen(), size, gSavedSettings.getBOOL("DisableVerticalSync"), logged_in); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); } } diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 2156a8120..e28d006a3 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -28,7 +28,7 @@ #include "llpaneleditwearable.h" #include "llpanel.h" -#include "llwearable.h" +#include "llviewerwearable.h" #include "lluictrl.h" #include "llscrollingpanellist.h" #include "llvisualparam.h" @@ -60,6 +60,9 @@ #include "llfloatercustomize.h" #include "llwearablelist.h" +#include "llinventoryicon.h" + +#include // subparts of the UI for focus, camera position, etc. enum ESubpart { @@ -102,7 +105,7 @@ enum ESubpart { SUBPART_PHYSICS_ADVANCED, }; -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines; typedef std::vector subpart_vec_t; @@ -605,21 +608,19 @@ class LLWearableSaveAsDialog : public LLModalDialog { private: std::string mItemName; - void (*mCommitCallback)(LLWearableSaveAsDialog*,void*); - void* mCallbackUserData; + boost::function mSaveCallback; LLPanelEditWearable* mParent; public: - LLWearableSaveAsDialog( const std::string& desc, LLPanelEditWearable* parent, void(*commit_cb)(LLWearableSaveAsDialog*,void*), void* userdata ) + LLWearableSaveAsDialog( const std::string& desc, LLPanelEditWearable* parent, boost::function cb ) : LLModalDialog( LLStringUtil::null, 240, 100 ), - mCommitCallback( commit_cb ), - mCallbackUserData( userdata ), + mSaveCallback( cb ), mParent( parent ) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_wearable_save_as.xml"); - childSetAction("Save", LLWearableSaveAsDialog::onSave, this ); - childSetAction("Cancel", LLWearableSaveAsDialog::onCancel, this ); + childSetAction("Save", boost::bind(&LLWearableSaveAsDialog::onSave, this) ); + childSetAction("Cancel", boost::bind(&LLWearableSaveAsDialog::onCancel, this) ); childSetTextArg("name ed", "[DESC]", desc); } @@ -639,29 +640,27 @@ public: const std::string& getItemName() { return mItemName; } - static void onSave( void* userdata ) + void onSave() { - LLWearableSaveAsDialog* self = (LLWearableSaveAsDialog*) userdata; - self->mItemName = self->childGetValue("name ed").asString(); - LLStringUtil::trim(self->mItemName); - if( !self->mItemName.empty() ) + mItemName = childGetValue("name ed").asString(); + LLStringUtil::trim(mItemName); + if( !mItemName.empty() ) { - if( self->mCommitCallback ) + if( mSaveCallback ) { - self->mCommitCallback( self, self->mCallbackUserData ); + mSaveCallback( this ); } - self->close(); // destroys this object + close(); // destroys this object } } - static void onCancel( void* userdata ) + void onCancel() { - LLWearableSaveAsDialog* self = (LLWearableSaveAsDialog*) userdata; - self->close(); // destroys this object + close(); // destroys this object } }; -LLPanelEditWearable::LLPanelEditWearable( LLWearableType::EType type ) +LLPanelEditWearable::LLPanelEditWearable( LLWearableType::EType type, LLFloaterCustomize* parent ) : LLPanel( LLWearableType::getTypeLabel( type ) ), mType( type ), @@ -669,7 +668,8 @@ LLPanelEditWearable::LLPanelEditWearable( LLWearableType::EType type ) mCurrentIndex( 0 ), mCurrentWearable( NULL ), mPendingWearable( NULL ), - mPendingRefresh( false ) + mPendingRefresh( false ), + mCustomizeFloater( parent ) { } LLPanelEditWearable::~LLPanelEditWearable() @@ -686,63 +686,63 @@ BOOL LLPanelEditWearable::postBuild() childSetValue("icon", icon_name); - childSetAction("Create New", LLPanelEditWearable::onBtnCreateNew, this ); + childSetAction("Create New", boost::bind(&LLPanelEditWearable::onBtnCreateNew, this) ); // If PG, can't take off underclothing or shirt mCanTakeOff = LLWearableType::getAssetType( mType ) == LLAssetType::AT_CLOTHING && !( gAgent.isTeen() && (mType == LLWearableType::WT_UNDERSHIRT || mType == LLWearableType::WT_UNDERPANTS) ); childSetVisible("Take Off", mCanTakeOff); - childSetAction("Take Off", LLPanelEditWearable::onBtnTakeOff, this ); + childSetAction("Take Off", boost::bind(&LLPanelEditWearable::onBtnTakeOff, this) ); LLUICtrl* sex_radio = getChild("sex radio", true, false); if(sex_radio) { - sex_radio->setCommitCallback(boost::bind(&LLPanelEditWearable::onCommitSexChange,this)); + sex_radio->setCommitCallback(boost::bind(&LLPanelEditWearable::onCommitSexChange,this) ); } - childSetAction("Save", &LLPanelEditWearable::onBtnSave, (void*)this ); + childSetAction("Save", boost::bind(&LLPanelEditWearable::saveChanges, this, false, std::string()) ); - childSetAction("Save As", &LLPanelEditWearable::onBtnSaveAs, (void*)this ); + childSetAction("Save As", boost::bind(&LLPanelEditWearable::onBtnSaveAs, this) ); - childSetAction("Revert", &LLPanelEditWearable::onRevertButtonClicked, (void*)this ); + childSetAction("Revert", boost::bind(&LLPanelEditWearable::revertChanges, this) ); - configureAlphaCheckbox(LLVOAvatarDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible"); - configureAlphaCheckbox(LLVOAvatarDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible"); - configureAlphaCheckbox(LLVOAvatarDefines::TEX_HEAD_ALPHA, "head alpha texture invisible"); - configureAlphaCheckbox(LLVOAvatarDefines::TEX_EYES_ALPHA, "eye alpha texture invisible"); - configureAlphaCheckbox(LLVOAvatarDefines::TEX_HAIR_ALPHA, "hair alpha texture invisible"); + configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible"); + configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible"); + configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_HEAD_ALPHA, "head alpha texture invisible"); + configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_EYES_ALPHA, "eye alpha texture invisible"); + configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_HAIR_ALPHA, "hair alpha texture invisible"); - { - const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(mType); - if (!wearable_entry) - { - llwarns << "could not get wearable dictionary entry for wearable of type: " << mType << llendl; - } - U8 num_subparts = wearable_entry->mSubparts.size(); - - for (U8 index = 0; index < num_subparts; ++index) - { - // dive into data structures to get the panel we need - ESubpart subpart_e = wearable_entry->mSubparts[index]; - const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); - - if (!subpart_entry) - { - llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl; - continue; - } - - if(!subpart_entry->mButtonName.empty()) - { - llinfos << "Finding button " << subpart_entry->mButtonName << llendl; - llassert_always(getChild(subpart_entry->mButtonName,true,false)); - childSetAction(subpart_entry->mButtonName, &LLPanelEditWearable::onBtnSubpart, reinterpret_cast(index)); - } - } - // initialize texture and color picker controls - for_each_picker_ctrl_entry (this, mType, boost::bind(init_color_swatch_ctrl, this, _1, _2)); - for_each_picker_ctrl_entry (this, mType, boost::bind(init_texture_ctrl, this, _1, _2)); + { + const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(mType); + if (!wearable_entry) + { + llwarns << "could not get wearable dictionary entry for wearable of type: " << mType << llendl; + } + U8 num_subparts = wearable_entry->mSubparts.size(); + + for (U8 index = 0; index < num_subparts; ++index) + { + // dive into data structures to get the panel we need + ESubpart subpart_e = wearable_entry->mSubparts[index]; + const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); + + if (!subpart_entry) + { + llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl; + continue; + } + + if(!subpart_entry->mButtonName.empty()) + { + llinfos << "Finding button " << subpart_entry->mButtonName << llendl; + llassert_always(getChild(subpart_entry->mButtonName,true,false)); + childSetAction(subpart_entry->mButtonName, boost::bind(&LLPanelEditWearable::changeCamera, this, index)); + } + } + // initialize texture and color picker controls + for_each_picker_ctrl_entry (this, mType, boost::bind(init_color_swatch_ctrl, this, _1, _2)); + for_each_picker_ctrl_entry (this, mType, boost::bind(init_texture_ctrl, this, _1, _2)); } LLTabContainer* tab = getChild("layer_tabs", true, false); @@ -766,18 +766,18 @@ BOOL LLPanelEditWearable::postBuild() BOOL LLPanelEditWearable::isDirty() const { - LLWearable* wearable = getWearable(); + LLViewerWearable* wearable = getWearable(); return wearable && wearable->isDirty(); } void LLPanelEditWearable::draw() { - if( gFloaterCustomize->isMinimized() || !isAgentAvatarValid()) + if( mCustomizeFloater->isMinimized() || !isAgentAvatarValid()) return; refreshWearables(false); - LLWearable* wearable = getWearable(); + LLViewerWearable* wearable = getWearable(); BOOL has_wearable = (wearable != NULL ); BOOL has_any_wearable = has_wearable || gAgentWearables.getWearableCount(mType); BOOL is_dirty = isDirty(); @@ -930,7 +930,7 @@ void LLPanelEditWearable::setWearableIndex(S32 index) tab->selectTab(tab_index); } - LLWearable* wearable = gAgentWearables.getWearable(mType,mCurrentIndex); + LLViewerWearable* wearable = gAgentWearables.getViewerWearable(mType,mCurrentIndex); if(wearable == getWearable()) return; @@ -980,7 +980,7 @@ void LLPanelEditWearable::setWearableIndex(S32 index) { value_map_t sorted_params; getSortedParams(sorted_params, subpart_entry->mEditGroup, ((perm_mask & PERM_MODIFY) && is_complete) ? TRUE : FALSE); - buildParamList(gFloaterCustomize->getScrollingPanelList(), sorted_params); + buildParamList(mCustomizeFloater->getScrollingPanelList(), sorted_params); } if(wearable) @@ -1039,42 +1039,24 @@ void LLPanelEditWearable::wearablesChanged() mPendingRefresh = true; } -// static -void LLPanelEditWearable::onRevertButtonClicked( void* userdata ) +void LLPanelEditWearable::onBtnSaveAs() { - LLPanelEditWearable *panel = (LLPanelEditWearable*) userdata; - panel->revertChanges(); -} - -void LLPanelEditWearable::onBtnSave( void* userdata ) -{ - LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; - self->saveChanges(false); -} - -// static -void LLPanelEditWearable::onBtnSaveAs( void* userdata ) -{ - LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; - if(self->mActiveModal) + if(mActiveModal) return; - LLWearable* wearable = self->getWearable(); + LLViewerWearable* wearable = getWearable(); if( wearable ) { - self->mActiveModal = new LLWearableSaveAsDialog( wearable->getName(), self, onSaveAsCommit, self ); - self->mActiveModal->startModal(); + mActiveModal = new LLWearableSaveAsDialog( wearable->getName(), this, boost::bind(&LLPanelEditWearable::onSaveAsCommit, this, _1)); + mActiveModal->startModal(); // LLWearableSaveAsDialog deletes itself. } } -// static -void LLPanelEditWearable::onSaveAsCommit( LLWearableSaveAsDialog* save_as_dialog, void* userdata ) +void LLPanelEditWearable::onSaveAsCommit( LLWearableSaveAsDialog* save_as_dialog ) { - LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; - self->saveChanges(true, save_as_dialog->getItemName()); + saveChanges(true, save_as_dialog->getItemName()); } -// static void LLPanelEditWearable::onCommitSexChange() { if (!isAgentAvatarValid()) return; @@ -1094,7 +1076,7 @@ void LLPanelEditWearable::onCommitSexChange() } bool is_new_sex_male = (gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE) == SEX_MALE; - LLWearable* wearable = gAgentWearables.getWearable(type, index); + LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, index); if (wearable) { wearable->setVisualParamWeight(param->getID(), is_new_sex_male, FALSE); @@ -1124,13 +1106,10 @@ void LLPanelEditWearable::onCommitSexChange() //self->setSubpart( SUBPART_SHAPE_WHOLE ); } - -// static -void LLPanelEditWearable::onBtnCreateNew( void* userdata ) +void LLPanelEditWearable::onBtnCreateNew() { - LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; LLSD payload; - payload["wearable_type"] = (S32)self->getType(); + payload["wearable_type"] = (S32)getType(); LLNotificationsUtil::add("AutoWearNewClothing", LLSD(), payload, &onSelectAutoWearOption); } @@ -1141,7 +1120,7 @@ bool LLPanelEditWearable::onSelectAutoWearOption(const LLSD& notification, const if(avatar) { // Create a new wearable in the default folder for the wearable's asset type. - LLWearable* wearable = LLWearableList::instance().createNewWearable( (LLWearableType::EType)notification["payload"]["wearable_type"].asInteger() ); + LLViewerWearable* wearable = LLWearableList::instance().createNewWearable( (LLWearableType::EType)notification["payload"]["wearable_type"].asInteger(), avatar ); LLAssetType::EType asset_type = wearable->getAssetType(); LLUUID folder_id; @@ -1150,7 +1129,7 @@ bool LLPanelEditWearable::onSelectAutoWearOption(const LLSD& notification, const // Only auto wear the new item if the AutoWearNewClothing checkbox is selected. LLPointer cb = option == 0 ? - new WearOnAvatarCallback : NULL; + new LLBoostFuncInventoryCallback(boost::bind(&wear_on_avatar_cb,_1,false)) : NULL; create_inventory_item(gAgent.getID(), gAgent.getSessionID(), folder_id, wearable->getTransactionID(), wearable->getName(), wearable->getDescription(), asset_type, LLInventoryType::IT_WEARABLE, wearable->getType(), @@ -1159,7 +1138,7 @@ bool LLPanelEditWearable::onSelectAutoWearOption(const LLSD& notification, const return false; } -LLWearable* LLPanelEditWearable::getWearable() const +LLViewerWearable* LLPanelEditWearable::getWearable() const { return mCurrentWearable;//gAgentWearables.getWearable(mType, mCurrentIndex); // TODO: MULTI-WEARABLE } @@ -1167,72 +1146,72 @@ LLWearable* LLPanelEditWearable::getWearable() const void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl) { - const LLTextureCtrl* texture_ctrl = dynamic_cast(ctrl); - if (!texture_ctrl) - { - llwarns << "got commit signal from not LLTextureCtrl." << llendl; - return; - } - - if (getWearable()) - { - LLWearableType::EType type = getWearable()->getType(); - const PickerControlEntryNamePredicate name_pred(texture_ctrl->getName()); - const LLEditWearableDictionary::PickerControlEntry* entry - = find_picker_ctrl_entry_if(type, name_pred); - if (entry) - { - // Set the new version - LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID()); - if( image->getID() == IMG_DEFAULT ) - { - image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); - } - if (getWearable()) - { - U32 index = gAgentWearables.getWearableIndex(getWearable()); - gAgentAvatarp->setLocalTexture(entry->mTextureIndex, image, FALSE, index); - LLVisualParamHint::requestHintUpdates(); - gAgentAvatarp->wearableUpdated(type, FALSE); - } - if (mType == LLWearableType::WT_ALPHA && image->getID() != IMG_INVISIBLE) - { - mPreviousAlphaTexture[entry->mTextureIndex] = image->getID(); - } - } - else - { - llwarns << "could not get texture picker dictionary entry for wearable of type: " << type << llendl; - } - } + const LLTextureCtrl* texture_ctrl = dynamic_cast(ctrl); + if (!texture_ctrl) + { + llwarns << "got commit signal from not LLTextureCtrl." << llendl; + return; + } + + if (getWearable()) + { + LLWearableType::EType type = getWearable()->getType(); + const PickerControlEntryNamePredicate name_pred(texture_ctrl->getName()); + const LLEditWearableDictionary::PickerControlEntry* entry + = find_picker_ctrl_entry_if(type, name_pred); + if (entry) + { + // Set the new version + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID()); + if( image->getID() == IMG_DEFAULT ) + { + image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); + } + if (getWearable()) + { + U32 index = gAgentWearables.getWearableIndex(getWearable()); + gAgentAvatarp->setLocalTexture(entry->mTextureIndex, image, FALSE, index); + LLVisualParamHint::requestHintUpdates(); + gAgentAvatarp->wearableUpdated(type, FALSE); + } + if (mType == LLWearableType::WT_ALPHA && image->getID() != IMG_INVISIBLE) + { + mPreviousAlphaTexture[entry->mTextureIndex] = image->getID(); + } + } + else + { + llwarns << "could not get texture picker dictionary entry for wearable of type: " << type << llendl; + } + } } void LLPanelEditWearable::onColorSwatchCommit(const LLUICtrl* base_ctrl ) { - LLColorSwatchCtrl* ctrl = (LLColorSwatchCtrl*) base_ctrl; - - if (getWearable()) - { - LLWearableType::EType type = getWearable()->getType(); - const PickerControlEntryNamePredicate name_pred(ctrl->getName()); - const LLEditWearableDictionary::PickerControlEntry* entry - = find_picker_ctrl_entry_if(type, name_pred); - if (entry) - { - const LLColor4& old_color = getWearable()->getClothesColor(entry->mTextureIndex); - const LLColor4& new_color = LLColor4(ctrl->getValue()); - if( old_color != new_color ) - { - getWearable()->setClothesColor(entry->mTextureIndex, new_color, TRUE); - LLVisualParamHint::requestHintUpdates(); - gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE); - } - } - else - { - llwarns << "could not get color swatch dictionary entry for wearable of type: " << type << llendl; - } - } + LLColorSwatchCtrl* ctrl = (LLColorSwatchCtrl*) base_ctrl; + + if (getWearable()) + { + LLWearableType::EType type = getWearable()->getType(); + const PickerControlEntryNamePredicate name_pred(ctrl->getName()); + const LLEditWearableDictionary::PickerControlEntry* entry + = find_picker_ctrl_entry_if(type, name_pred); + if (entry) + { + const LLColor4& old_color = getWearable()->getClothesColor(entry->mTextureIndex); + const LLColor4& new_color = LLColor4(ctrl->getValue()); + if( old_color != new_color ) + { + getWearable()->setClothesColor(entry->mTextureIndex, new_color, TRUE); + LLVisualParamHint::requestHintUpdates(); + gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE); + } + } + else + { + llwarns << "could not get color swatch dictionary entry for wearable of type: " << type << llendl; + } + } } @@ -1240,63 +1219,64 @@ void LLPanelEditWearable::hideTextureControls() { for_each_picker_ctrl_entry (this, mType, boost::bind(set_enabled_texture_ctrl, FALSE, _1, _2)); for_each_picker_ctrl_entry (this, mType, boost::bind(set_enabled_color_swatch_ctrl, FALSE, _1, _2)); - for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); - iter != mAlphaCheckbox2Index.end(); ++iter ) - { - LLCheckBoxCtrl* ctrl = getChild(iter->first, true, false); - if (ctrl) - { - ctrl->setEnabled(FALSE); - ctrl->setVisible(FALSE); - } + for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); + iter != mAlphaCheckbox2Index.end(); ++iter ) + { + LLCheckBoxCtrl* ctrl = getChild(iter->first, true, false); + if (ctrl) + { + ctrl->setEnabled(FALSE); + ctrl->setVisible(FALSE); } + } } void LLPanelEditWearable::saveChanges(bool force_save_as, std::string new_name) { - if (!getWearable() || (!force_save_as && !isDirty())) - { - // do nothing if no unsaved changes - return; - } - - U32 index = gAgentWearables.getWearableIndex(getWearable()); - - if (force_save_as) - { - // the name of the wearable has changed, re-save wearable with new name - LLAppearanceMgr::instance().removeCOFItemLinks(getWearable()->getItemID(),false); - LLWearable* new_wearable = gAgentWearables.saveWearableAs(mType, index, new_name, FALSE); - if(new_wearable) - { - mPendingWearable = new_wearable; - mCurrentWearable = new_wearable; - childSetTextArg("title", "[DESC]", new_wearable->getName()); - childSetTextArg("title_no_modify", "[DESC]", new_wearable->getName()); - } - } - else - { - gAgentWearables.saveWearable(mType, index, TRUE, new_name); - } + if (!getWearable() || (!force_save_as && !isDirty())) + { + // do nothing if no unsaved changes + return; + } + + U32 index = gAgentWearables.getWearableIndex(getWearable()); + + if (force_save_as) + { + // the name of the wearable has changed, re-save wearable with new name + LLAppearanceMgr::instance().removeCOFItemLinks(getWearable()->getItemID()); + LLViewerWearable* new_wearable = gAgentWearables.saveWearableAs(mType, index, new_name, FALSE); + if(new_wearable) + { + mPendingWearable = new_wearable; + mCurrentWearable = new_wearable; + childSetTextArg("title", "[DESC]", new_wearable->getName()); + childSetTextArg("title_no_modify", "[DESC]", new_wearable->getName()); + } + } + else + { + gAgentWearables.saveWearable(mType, index, TRUE, new_name); + } } void LLPanelEditWearable::revertChanges() { - LLWearable* wearable = getWearable(); - if (!wearable || !isDirty()) - { - // no unsaved changes to revert - return; - } + LLViewerWearable* wearable = getWearable(); + if (!wearable || !isDirty()) + { + // no unsaved changes to revert + return; + } + + wearable->revertValues(); + childSetTextArg("title", "[DESC]", wearable->getName() ); + gAgentAvatarp->wearableUpdated(mType, FALSE); - wearable->revertValues(); - childSetTextArg("title", "[DESC]", wearable->getName() ); - gAgentAvatarp->wearableUpdated(mType, FALSE); - if (mType == LLWearableType::WT_ALPHA) - { - updateAlphaCheckboxes(); - } + if (mType == LLWearableType::WT_ALPHA) + { + updateAlphaCheckboxes(); + } } void LLPanelEditWearable::showDefaultSubpart() @@ -1305,8 +1285,6 @@ void LLPanelEditWearable::showDefaultSubpart() changeCamera(0); } - - void LLPanelEditWearable::setUIPermissions(U32 perm_mask, BOOL is_complete) { BOOL is_copyable = (perm_mask & PERM_COPY) ? TRUE : FALSE; @@ -1329,112 +1307,104 @@ void LLPanelEditWearable::setUIPermissions(U32 perm_mask, BOOL is_complete) } } -// static -void LLPanelEditWearable::onBtnSubpart(void* userdata) -{ - LLFloaterCustomize* floater_customize = gFloaterCustomize; - if (!floater_customize) return; - LLPanelEditWearable* self = floater_customize->getCurrentWearablePanel(); - if (!self) return; - self->changeCamera( (S32)(intptr_t)userdata ); -} - void LLPanelEditWearable::changeCamera(U8 subpart) { + const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(mType); + if (!wearable_entry) + { + llinfos << "could not get wearable dictionary entry for wearable type: " << mType << llendl; + return; + } - const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(mType); - if (!wearable_entry) - { - llinfos << "could not get wearable dictionary entry for wearable type: " << mType << llendl; - return; - } - - if (subpart >= wearable_entry->mSubparts.size()) - { - llinfos << "accordion tab expanded for invalid subpart. Wearable type: " << mType << " subpart num: " << subpart << llendl; - return; - } - - ESubpart subpart_e = wearable_entry->mSubparts[subpart]; - const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); - - if (!subpart_entry) - { - llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl; - return; - } - - mCurrentSubpart = subpart_e; - //Update the buttons to reflect the current selected subpart. - for (U8 index = 0; index < wearable_entry->mSubparts.size(); ++index) - { - // dive into data structures to get the panel we need - ESubpart subpart_e = wearable_entry->mSubparts[index]; - const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); - - if (subpart_entry) - { - LLButton* btn = getChild(subpart_entry->mButtonName); - { - btn->setToggleState( subpart == subpart_e ); - } - } - } - - // Update the thumbnails we display - LLWearable* wearable = getWearable(); - LLViewerInventoryItem* item = wearable ? gInventory.getItem(wearable->getItemID()) : NULL; - U32 perm_mask = 0x0; - BOOL is_complete = FALSE; - bool can_export = false; - bool can_import = false; - if(item) - { - perm_mask = item->getPermissions().getMaskOwner(); - is_complete = item->isComplete(); - - if (subpart_e < SUBPART_EYES) // body parts only + if (subpart >= wearable_entry->mSubparts.size()) + { + llinfos << "accordion tab expanded for invalid subpart. Wearable type: " << mType << " subpart num: " << subpart << llendl; + return; + } + + ESubpart subpart_e = wearable_entry->mSubparts[subpart]; + const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); + + if (!subpart_entry) + { + llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl; + return; + } + + mCurrentSubpart = subpart_e; + //Update the buttons to reflect the current selected subpart. + for (U8 index = 0; index < wearable_entry->mSubparts.size(); ++index) + { + // dive into data structures to get the panel we need + ESubpart subpart_e = wearable_entry->mSubparts[index]; + const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); + + if (subpart_entry) + { + LLButton* btn = getChild(subpart_entry->mButtonName); { - can_import = true; - - if (is_complete && - gAgent.getID() == item->getPermissions().getOwner() && - gAgent.getID() == item->getPermissions().getCreator() && - (PERM_ITEM_UNRESTRICTED & - perm_mask) == PERM_ITEM_UNRESTRICTED) - { - can_export = true; - } + btn->setToggleState( subpart == subpart_e ); } } - setUIPermissions(perm_mask, is_complete); - - value_map_t sorted_params; - getSortedParams(sorted_params, subpart_entry->mEditGroup, ((perm_mask & PERM_MODIFY) && is_complete) ? TRUE : FALSE); - buildParamList(gFloaterCustomize->getScrollingPanelList(), sorted_params); - updateScrollingPanelUI(); - gFloaterCustomize->childSetEnabled("Export", can_export); - gFloaterCustomize->childSetEnabled("Import", can_import); - - // Update the camera + } + + // Update the thumbnails we display + LLViewerWearable* wearable = getWearable(); + LLViewerInventoryItem* item = wearable ? gInventory.getItem(wearable->getItemID()) : NULL; + U32 perm_mask = 0x0; + BOOL is_complete = FALSE; + bool can_export = false; + bool can_import = false; + if(item) + { + perm_mask = item->getPermissions().getMaskOwner(); + is_complete = item->isComplete(); + + if (subpart_e < SUBPART_EYES) // body parts only + { + can_import = true; + + if (is_complete && + gAgent.getID() == item->getPermissions().getOwner() && + gAgent.getID() == item->getPermissions().getCreator() && + (PERM_ITEM_UNRESTRICTED & + perm_mask) == PERM_ITEM_UNRESTRICTED) + { + can_export = true; + } + } + } + setUIPermissions(perm_mask, is_complete); + + value_map_t sorted_params; + getSortedParams(sorted_params, subpart_entry->mEditGroup, ((perm_mask & PERM_MODIFY) && is_complete) ? TRUE : FALSE); + buildParamList(mCustomizeFloater->getScrollingPanelList(), sorted_params); + updateScrollingPanelUI(); + mCustomizeFloater->childSetEnabled("Export", can_export); + mCustomizeFloater->childSetEnabled("Import", can_import); + + // Update the camera + if(gMorphView) + { gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ) ); gMorphView->setCameraTargetOffset( subpart_entry->mTargetOffset ); gMorphView->setCameraOffset( subpart_entry->mCameraOffset ); gMorphView->setCameraDistToDefault(); - if (gSavedSettings.getBOOL("AppearanceCameraMovement")) + if (gAgentCamera.cameraCustomizeAvatar()) { gMorphView->updateCamera(); } + } } void LLPanelEditWearable::updateScrollingPanelList() { - updateScrollingPanelUI(); + updateScrollingPanelUI(); } void LLPanelEditWearable::updateScrollingPanelUI() { - LLWearable* wearable = getWearable(); + LLViewerWearable* wearable = getWearable(); // do nothing if we don't have a valid wearable we're editing if(!wearable) { @@ -1450,23 +1420,20 @@ void LLPanelEditWearable::updateScrollingPanelUI() U32 perm_mask = item->getPermissions().getMaskOwner(); BOOL is_complete = item->isComplete(); LLScrollingPanelParam::sUpdateDelayFrames = 0; - gFloaterCustomize->getScrollingPanelList()->updatePanels((perm_mask & PERM_MODIFY) && is_complete); + mCustomizeFloater->getScrollingPanelList()->updatePanels((perm_mask & PERM_MODIFY) && is_complete); } } -// static -void LLPanelEditWearable::onBtnTakeOff( void* userdata ) +void LLPanelEditWearable::onBtnTakeOff() { - LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; - - LLWearable* wearable = self->getWearable(); + LLViewerWearable* wearable = getWearable(); if( !wearable ) { return; } LLAppearanceMgr::instance().removeItemFromAvatar(wearable->getItemID()); - self->refreshWearables(true); + refreshWearables(true); } // static @@ -1474,30 +1441,30 @@ void LLPanelEditWearable::getSortedParams(value_map_t &sorted_params, const std: { if(!getWearable())return; - LLWearable::visual_param_vec_t param_list; - ESex avatar_sex = gAgentAvatarp->getSex(); - - getWearable()->getVisualParams(param_list); - - for (LLWearable::visual_param_vec_t::iterator iter = param_list.begin(); - iter != param_list.end(); - ++iter) - { - LLViewerVisualParam *param = (LLViewerVisualParam*) *iter; - - if (param->getID() == -1 - || !param->isTweakable() - || param->getEditGroup() != edit_group - || !(param->getSex() & avatar_sex)) - { - continue; - } - - // negative getDisplayOrder() to make lowest order the highest priority - value_map_t::value_type vt(-param->getDisplayOrder(), editable_param(editable, param)); - llassert( sorted_params.find(-param->getDisplayOrder()) == sorted_params.end() ); // Check for duplicates - sorted_params.insert(vt); + LLViewerWearable::visual_param_vec_t param_list; + ESex avatar_sex = gAgentAvatarp->getSex(); + + getWearable()->getVisualParams(param_list); + + for (LLViewerWearable::visual_param_vec_t::iterator iter = param_list.begin(); + iter != param_list.end(); + ++iter) + { + LLViewerVisualParam *param = (LLViewerVisualParam*) *iter; + + if (param->getID() == -1 + || !param->isTweakable() + || param->getEditGroup() != edit_group + || !(param->getSex() & avatar_sex)) + { + continue; } + + // negative getDisplayOrder() to make lowest order the highest priority + value_map_t::value_type vt(-param->getDisplayOrder(), editable_param(editable, param)); + llassert( sorted_params.find(-param->getDisplayOrder()) == sorted_params.end() ); // Check for duplicates + sorted_params.insert(vt); + } } void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value_map_t &sorted_params) @@ -1518,7 +1485,7 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value } } -void LLPanelEditWearable::configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name) +void LLPanelEditWearable::configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name) { LLCheckBoxCtrl* checkbox = getChild(name, true, false); if(checkbox) @@ -1529,56 +1496,62 @@ void LLPanelEditWearable::configureAlphaCheckbox(LLVOAvatarDefines::ETextureInde } } -void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLVOAvatarDefines::ETextureIndex te) +void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te) { - if (!checkbox_ctrl) return; - if (!getWearable()) return; + if (!checkbox_ctrl) + return; + if (!getWearable()) + return; + + llinfos << "onInvisibilityCommit, self " << this << " checkbox_ctrl " << checkbox_ctrl << llendl; + + bool new_invis_state = checkbox_ctrl->get(); + if (new_invis_state) + { + LLLocalTextureObject *lto = getWearable()->getLocalTextureObject(te); + mPreviousAlphaTexture[te] = lto->getID(); + + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( IMG_INVISIBLE ); + U32 index = gAgentWearables.getWearableIndex(getWearable()); + gAgentAvatarp->setLocalTexture(te, image, FALSE, index); + gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE); + } + else + { + // Try to restore previous texture, if any. + LLUUID prev_id = mPreviousAlphaTexture[te]; + if (prev_id.isNull() || (prev_id == IMG_INVISIBLE)) + { + prev_id = LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ); + } + if (prev_id.isNull()) + return; + + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(prev_id); - llinfos << "onInvisibilityCommit, self " << this << " checkbox_ctrl " << checkbox_ctrl << llendl; - - bool new_invis_state = checkbox_ctrl->get(); - if (new_invis_state) - { - LLLocalTextureObject *lto = getWearable()->getLocalTextureObject(te); - mPreviousAlphaTexture[te] = lto->getID(); - - LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( IMG_INVISIBLE ); - U32 index = gAgentWearables.getWearableIndex(getWearable()); - gAgentAvatarp->setLocalTexture(te, image, FALSE, index); - gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE); - } - else - { - // Try to restore previous texture, if any. - LLUUID prev_id = mPreviousAlphaTexture[te]; - if (prev_id.isNull() || (prev_id == IMG_INVISIBLE)) - { - prev_id = LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ); - } - if (prev_id.isNull()) return; - - LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(prev_id); - if (!image) return; - - U32 index = gAgentWearables.getWearableIndex(getWearable()); - gAgentAvatarp->setLocalTexture(te, image, FALSE, index); - gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE); - } + if (!image) + return; + + U32 index = gAgentWearables.getWearableIndex(getWearable()); + gAgentAvatarp->setLocalTexture(te, image, FALSE, index); + gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE); + } } void LLPanelEditWearable::updateAlphaCheckboxes() { - if(!getWearable())return; - for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); - iter != mAlphaCheckbox2Index.end(); ++iter ) - { - LLVOAvatarDefines::ETextureIndex te = (LLVOAvatarDefines::ETextureIndex)iter->second; - LLCheckBoxCtrl* ctrl = getChild(iter->first, true, false); - if (ctrl) - { - ctrl->set(!gAgentAvatarp->isTextureVisible(te, getWearable())); - } - } + if(!getWearable()) + return; + for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin(); + iter != mAlphaCheckbox2Index.end(); ++iter ) + { + LLAvatarAppearanceDefines::ETextureIndex te = (LLAvatarAppearanceDefines::ETextureIndex)iter->second; + LLCheckBoxCtrl* ctrl = getChild(iter->first, true, false); + if (ctrl) + { + ctrl->set(!gAgentAvatarp->isTextureVisible(te, getWearable())); + } + } } void LLPanelEditWearable::initPreviousAlphaTextures() @@ -1590,13 +1563,13 @@ void LLPanelEditWearable::initPreviousAlphaTextures() initPreviousAlphaTextureEntry(TEX_LOWER_ALPHA); } -void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te) +void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te) { if(!getWearable()) return; - LLLocalTextureObject *lto = getWearable()->getLocalTextureObject(te); - if (lto) - { - mPreviousAlphaTexture[te] = lto->getID(); - } + LLLocalTextureObject *lto = getWearable()->getLocalTextureObject(te); + if (lto) + { + mPreviousAlphaTexture[te] = lto->getID(); + } } diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index d1877ecaf..0509b8e30 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -30,12 +30,12 @@ #include "llpanel.h" #include "llscrollingpanellist.h" #include "llmodaldialog.h" -#include "llvoavatardefines.h" +#include "llavatarappearancedefines.h" #include "llwearabletype.h" class LLAccordionCtrl; class LLCheckBoxCtrl; -class LLWearable; +class LLViewerWearable; class LLTextBox; class LLViewerInventoryItem; class LLViewerVisualParam; @@ -46,13 +46,14 @@ class LLJoint; class LLLineEditor; class LLSubpart; class LLWearableSaveAsDialog; +class LLFloaterCustomize; -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines; class LLPanelEditWearable : public LLPanel { public: - LLPanelEditWearable( LLWearableType::EType type ); + LLPanelEditWearable( LLWearableType::EType type, LLFloaterCustomize* parent ); virtual ~LLPanelEditWearable(); /*virtual*/ BOOL postBuild(); @@ -64,7 +65,7 @@ public: const std::string& getLabel() { return LLWearableType::getTypeLabel( mType ); } LLWearableType::EType getType() const{ return mType; } - LLWearable* getWearable() const; + LLViewerWearable* getWearable() const; void onTabChanged(LLUICtrl* ctrl); bool onTabPrecommit(); @@ -84,7 +85,6 @@ public: void updateScrollingPanelList(); - static void onRevertButtonClicked( void* userdata ); void onCommitSexChange(); virtual void setVisible( BOOL visible ); @@ -97,40 +97,38 @@ public: void buildParamList(LLScrollingPanelList *panel_list, value_map_t &sorted_params); // Callbacks - static void onBtnSubpart( void* userdata ); - static void onBtnTakeOff( void* userdata ); - static void onBtnSave( void* userdata ); + void onBtnTakeOff(); + void onBtnSave(); - static void onBtnSaveAs( void* userdata ); - static void onSaveAsCommit( LLWearableSaveAsDialog* save_as_dialog, void* userdata ); + void onBtnSaveAs(); + void onSaveAsCommit( LLWearableSaveAsDialog* save_as_dialog ); - static void onBtnTakeOffDialog( S32 option, void* userdata ); - static void onBtnCreateNew( void* userdata ); + void onBtnCreateNew(); static bool onSelectAutoWearOption(const LLSD& notification, const LLSD& response); void onColorSwatchCommit(const LLUICtrl*); void onTexturePickerCommit(const LLUICtrl*); //alpha mask checkboxes - void configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name); - void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLVOAvatarDefines::ETextureIndex te); + void configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name); + void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te); void updateAlphaCheckboxes(); void initPreviousAlphaTextures(); - void initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te); + void initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te); private: - + LLFloaterCustomize* mCustomizeFloater; LLWearableType::EType mType; BOOL mCanTakeOff; - typedef std::map string_texture_index_map_t; + typedef std::map string_texture_index_map_t; string_texture_index_map_t mAlphaCheckbox2Index; - typedef std::map s32_uuid_map_t; + typedef std::map s32_uuid_map_t; s32_uuid_map_t mPreviousAlphaTexture; U32 mCurrentSubpart; U32 mCurrentIndex; - LLWearable* mCurrentWearable; - LLWearable* mPendingWearable; //For SaveAs. There's a period where the old wearable will be removed, but the new one will still be pending, + LLViewerWearable* mCurrentWearable; + LLViewerWearable* mPendingWearable; //For SaveAs. There's a period where the old wearable will be removed, but the new one will still be pending, //so this is needed to retain focus on this wearables tab over the messy transition. bool mPendingRefresh; //LLAgentWearables::setWearableOutfit fires a buttload of remove/wear calls which spams wearablesChanged //a bazillion pointless (and not particularly valid) times. Deferring to draw effectively sorts it all out. diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index d19d14a4b..ca19b2caa 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -544,7 +544,7 @@ void LLPanelFace::getState() bool identical; LLTextureCtrl* texture_ctrl = getChild("texture control"); - + texture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null. // Texture { LLUUID id; @@ -552,8 +552,14 @@ void LLPanelFace::getState() { LLUUID get(LLViewerObject* object, S32 te) { - LLViewerTexture* image = object->getTEImage(te); + //LLViewerTexture* image = object->getTEImage(te); + LLTextureEntry* image = object->getTE(te); //Singu Note: Use this instead of the above. + //The above actually returns LLViewerFetchedTexture::sDefaultImagep when + //the texture id is null, which gives us IMG_DEFAULT, not LLUUID::null + //Such behavior prevents the 'None' button from ever greying out in the face panel. return image ? image->getID() : LLUUID::null; + + } } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); diff --git a/indra/newview/llpanelgeneral.cpp b/indra/newview/llpanelgeneral.cpp index fbd323a09..097f0d8db 100644 --- a/indra/newview/llpanelgeneral.cpp +++ b/indra/newview/llpanelgeneral.cpp @@ -70,8 +70,10 @@ BOOL LLPanelGeneral::postBuild() childSetValue("show_my_name_checkbox", gSavedSettings.getBOOL("RenderNameHideSelf")); childSetValue("small_avatar_names_checkbox", gSavedSettings.getBOOL("SmallAvatarNames")); childSetValue("show_my_title_checkbox", gSavedSettings.getBOOL("RenderHideGroupTitle")); + childSetValue("away_when_idle_checkbox", gSavedSettings.getBOOL("AllowIdleAFK")); childSetValue("afk_timeout_spinner", gSavedSettings.getF32("AFKTimeout")); childSetValue("notify_money_change_checkbox", gSavedSettings.getBOOL("NotifyMoneyChange")); + childSetValue("no_transaction_clutter_checkbox", gSavedSettings.getBOOL("LiruNoTransactionClutter")); @@ -111,6 +113,12 @@ BOOL LLPanelGeneral::postBuild() childSetVisible("maturity_desired_combobox", can_choose); childSetVisible("maturity_desired_textbox", !can_choose); + childSetEnabled("afk_timeout_spinner", gSavedSettings.getBOOL("AllowIdleAFK")); + childSetCommitCallback("away_when_idle_checkbox", &onClickCheckbox, this); + + childSetEnabled("no_transaction_clutter_checkbox", gSavedSettings.getBOOL("NotifyMoneyChange")); + childSetCommitCallback("notify_money_change_checkbox", &onClickCheckbox, this); + childSetAction("clear_settings", &onClickClearSettings, this); return TRUE; @@ -145,8 +153,10 @@ void LLPanelGeneral::apply() gSavedSettings.setBOOL("RenderNameHideSelf", childGetValue("show_my_name_checkbox")); gSavedSettings.setBOOL("SmallAvatarNames", childGetValue("small_avatar_names_checkbox")); gSavedSettings.setBOOL("RenderHideGroupTitle", childGetValue("show_my_title_checkbox")); + gSavedSettings.setBOOL("AllowIdleAFK", childGetValue("away_when_idle_checkbox")); gSavedSettings.setF32("AFKTimeout", childGetValue("afk_timeout_spinner").asReal()); gSavedSettings.setBOOL("NotifyMoneyChange", childGetValue("notify_money_change_checkbox")); + gSavedSettings.setBOOL("LiruNoTransactionClutter", childGetValue("no_transaction_clutter_checkbox")); gSavedSettings.setF32("UIScaleFactor", childGetValue("ui_scale_slider").asReal()); @@ -163,6 +173,17 @@ void LLPanelGeneral::cancel() { } +// static +void LLPanelGeneral::onClickCheckbox(LLUICtrl* ctrl, void* data) +{ + LLPanelGeneral* self = (LLPanelGeneral*)data; + bool enabled = ctrl->getValue().asBoolean(); + if(ctrl->getName() == "away_when_idle_checkbox") + self->childSetEnabled("afk_timeout_spinner", enabled); + else if(ctrl->getName() == "notify_money_change_checkbox") + self->childSetEnabled("no_transaction_clutter_checkbox", enabled); +} + // static void LLPanelGeneral::onClickClearSettings(void*) { diff --git a/indra/newview/llpanelgeneral.h b/indra/newview/llpanelgeneral.h index 1249ec8ca..48c44b15c 100644 --- a/indra/newview/llpanelgeneral.h +++ b/indra/newview/llpanelgeneral.h @@ -47,6 +47,7 @@ public: void apply(); void cancel(); + static void onClickCheckbox(LLUICtrl* ctrl, void* data); static void onClickClearSettings(void*); static void callbackResetAllSettings(const LLSD& notification, const LLSD& response); }; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 5aecdce57..776f7fb9f 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -118,18 +118,16 @@ BOOL LLPanelGroupGeneral::postBuild() mInsignia = getChild("insignia", recurse); if (mInsignia) { - mInsignia->setCommitCallback(onCommitAny); - mInsignia->setCallbackUserData(this); + mInsignia->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); mDefaultIconID = mInsignia->getImageAssetID(); } mEditCharter = getChild("charter", recurse); if(mEditCharter) { - mEditCharter->setCommitCallback(onCommitAny); + mEditCharter->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); mEditCharter->setFocusReceivedCallback(boost::bind(&LLPanelGroupGeneral::onFocusEdit, this)); mEditCharter->setFocusChangedCallback(boost::bind(&LLPanelGroupGeneral::onFocusEdit, this)); - mEditCharter->setCallbackUserData(this); } mBtnJoinGroup = getChild("join_button", recurse); @@ -156,24 +154,21 @@ BOOL LLPanelGroupGeneral::postBuild() mListVisibleMembers = getChild("visible_members", recurse); if (mListVisibleMembers) { - mListVisibleMembers->setDoubleClickCallback(&LLPanelGroupGeneral::openProfile); - mListVisibleMembers->setCallbackUserData(this); + mListVisibleMembers->setDoubleClickCallback(boost::bind(&LLPanelGroupGeneral::openProfile,this)); } // Options mCtrlShowInGroupList = getChild("show_in_group_list", recurse); if (mCtrlShowInGroupList) { - mCtrlShowInGroupList->setCommitCallback(&LLPanelGroupGeneral::onCommitAny); - mCtrlShowInGroupList->setCallbackUserData(this); + mCtrlShowInGroupList->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); } mComboMature = getChild("group_mature_check", recurse); if(mComboMature) { mComboMature->setCurrentByIndex(0); - mComboMature->setCommitCallback(onCommitAny); - mComboMature->setCallbackUserData(this); + mComboMature->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); if (gAgent.isTeen()) { // Teens don't get to set mature flag. JC @@ -184,23 +179,20 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlOpenEnrollment = getChild("open_enrollement", recurse); if (mCtrlOpenEnrollment) { - mCtrlOpenEnrollment->setCommitCallback(onCommitAny); - mCtrlOpenEnrollment->setCallbackUserData(this); + mCtrlOpenEnrollment->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); } mCtrlEnrollmentFee = getChild("check_enrollment_fee", recurse); if (mCtrlEnrollmentFee) { mCtrlEnrollmentFee->setLabelArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); - mCtrlEnrollmentFee->setCommitCallback(onCommitEnrollment); - mCtrlEnrollmentFee->setCallbackUserData(this); + mCtrlEnrollmentFee->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitEnrollment,this)); } mSpinEnrollmentFee = getChild("spin_enrollment_fee", recurse); if (mSpinEnrollmentFee) { - mSpinEnrollmentFee->setCommitCallback(onCommitAny); - mSpinEnrollmentFee->setCallbackUserData(this); + mSpinEnrollmentFee->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); mSpinEnrollmentFee->setPrecision(0); mSpinEnrollmentFee->resetDirty(); } @@ -216,8 +208,7 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlReceiveNotices = getChild("receive_notices", recurse); if (mCtrlReceiveNotices) { - mCtrlReceiveNotices->setCommitCallback(onCommitUserOnly); - mCtrlReceiveNotices->setCallbackUserData(this); + mCtrlReceiveNotices->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitUserOnly,this)); mCtrlReceiveNotices->set(accept_notices); mCtrlReceiveNotices->setEnabled(data.mID.notNull()); mCtrlReceiveNotices->resetDirty(); @@ -226,8 +217,7 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlReceiveChat = getChild("receive_chat", recurse); if (mCtrlReceiveChat) { - mCtrlReceiveChat->setCommitCallback(onCommitUserOnly); - mCtrlReceiveChat->setCallbackUserData(this); + mCtrlReceiveChat->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitUserOnly,this)); mCtrlReceiveChat->set(!gIMMgr->getIgnoreGroup(mGroupID)); mCtrlReceiveChat->setEnabled(mGroupID.notNull()); mCtrlReceiveChat->resetDirty(); @@ -236,8 +226,7 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlListGroup = getChild("list_groups_in_profile", recurse); if (mCtrlListGroup) { - mCtrlListGroup->setCommitCallback(onCommitUserOnly); - mCtrlListGroup->setCallbackUserData(this); + mCtrlListGroup->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitUserOnly,this)); mCtrlListGroup->set(list_in_profile); mCtrlListGroup->setEnabled(data.mID.notNull()); mCtrlListGroup->resetDirty(); @@ -248,8 +237,7 @@ BOOL LLPanelGroupGeneral::postBuild() mComboActiveTitle = getChild("active_title", recurse); if (mComboActiveTitle) { - mComboActiveTitle->setCommitCallback(onCommitTitle); - mComboActiveTitle->setCallbackUserData(this); + mComboActiveTitle->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitTitle,this)); mComboActiveTitle->resetDirty(); } @@ -284,60 +272,54 @@ void LLPanelGroupGeneral::onFocusEdit() notifyObservers(); } -void LLPanelGroupGeneral::onCommitAny(LLUICtrl* ctrl, void* data) +void LLPanelGroupGeneral::onCommitAny() { - LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data; - self->updateChanged(); - self->notifyObservers(); + updateChanged(); + notifyObservers(); } // static -void LLPanelGroupGeneral::onCommitUserOnly(LLUICtrl* ctrl, void* data) +void LLPanelGroupGeneral::onCommitUserOnly() { - LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data; - self->mChanged = TRUE; - self->notifyObservers(); + mChanged = TRUE; + notifyObservers(); } -// static -void LLPanelGroupGeneral::onCommitEnrollment(LLUICtrl* ctrl, void* data) +void LLPanelGroupGeneral::onCommitEnrollment() { - onCommitAny(ctrl, data); + onCommitAny(); - LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data; // Make sure both enrollment related widgets are there. - if (!self->mCtrlEnrollmentFee || !self->mSpinEnrollmentFee) + if (!mCtrlEnrollmentFee || !mSpinEnrollmentFee) { return; } // Make sure the agent can change enrollment info. - if (!gAgent.hasPowerInGroup(self->mGroupID,GP_MEMBER_OPTIONS) - || !self->mAllowEdit) + if (!gAgent.hasPowerInGroup(mGroupID,GP_MEMBER_OPTIONS) + || !mAllowEdit) { return; } - if (self->mCtrlEnrollmentFee->get()) + if (mCtrlEnrollmentFee->get()) { - self->mSpinEnrollmentFee->setEnabled(TRUE); + mSpinEnrollmentFee->setEnabled(TRUE); } else { - self->mSpinEnrollmentFee->setEnabled(FALSE); - self->mSpinEnrollmentFee->set(0); + mSpinEnrollmentFee->setEnabled(FALSE); + mSpinEnrollmentFee->set(0); } } -// static -void LLPanelGroupGeneral::onCommitTitle(LLUICtrl* ctrl, void* data) +void LLPanelGroupGeneral::onCommitTitle() { - LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data; - if (self->mGroupID.isNull() || !self->mAllowEdit) return; - LLGroupMgr::getInstance()->sendGroupTitleUpdate(self->mGroupID,self->mComboActiveTitle->getCurrentID()); - self->update(GC_TITLES); - self->mComboActiveTitle->resetDirty(); + if (mGroupID.isNull() || !mAllowEdit) return; + LLGroupMgr::getInstance()->sendGroupTitleUpdate(mGroupID,mComboActiveTitle->getCurrentID()); + update(GC_TITLES); + mComboActiveTitle->resetDirty(); } // static @@ -433,10 +415,9 @@ void LLPanelGroupGeneral::activate() LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID); LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); - if (!gdatap || !gdatap->isMemberDataComplete() ) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } mFirstUse = FALSE; @@ -872,6 +853,7 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) LLSD row; row["columns"][0]["value"] = pending.str(); + row["columns"][0]["column"] = "name"; mListVisibleMembers->setEnabled(FALSE); mListVisibleMembers->addElement(row); @@ -901,7 +883,7 @@ void LLPanelGroupGeneral::updateMembers() for( ; mMemberProgress != gdatap->mMembers.end() && ifirst << ", " << iter->second->getTitle() << llendl; + lldebugs << "Adding " << mMemberProgress->first << ", " << mMemberProgress->second->getTitle() << llendl; LLGroupMemberData* member = mMemberProgress->second; if (!member) { @@ -936,20 +918,20 @@ void LLPanelGroupGeneral::updateMembers() sSDTime += sd_timer.getElapsedTimeF32(); element_timer.reset(); - mListVisibleMembers->addElement(row);//, ADD_SORTED); + mListVisibleMembers->addNameItem(row); sElementTime += element_timer.getElapsedTimeF32(); } sAllTime += all_timer.getElapsedTimeF32(); - llinfos << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl; + lldebugs << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl; if (mMemberProgress == gdatap->mMembers.end()) { - llinfos << " member list completed." << llendl; + lldebugs << " member list completed." << llendl; mListVisibleMembers->setEnabled(TRUE); - llinfos << "All Time: " << sAllTime << llendl; - llinfos << "SD Time: " << sSDTime << llendl; - llinfos << "Element Time: " << sElementTime << llendl; + lldebugs << "All Time: " << sAllTime << llendl; + lldebugs << "SD Time: " << sSDTime << llendl; + lldebugs << "Element Time: " << sElementTime << llendl; } else { diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index 2eeb901c7..1c275d9aa 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -68,10 +68,10 @@ public: private: void onFocusEdit(); - static void onCommitAny(LLUICtrl* ctrl, void* data); - static void onCommitUserOnly(LLUICtrl* ctrl, void* data); - static void onCommitTitle(LLUICtrl* ctrl, void* data); - static void onCommitEnrollment(LLUICtrl* ctrl, void* data); + void onCommitAny(); + void onCommitUserOnly(); + void onCommitTitle(); + void onCommitEnrollment(); static void onClickJoin(void* userdata); static void onClickInfo(void* userdata); static void onReceiveNotices(LLUICtrl* ctrl, void* data); diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 35f405340..2f44a34bc 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -34,8 +34,10 @@ #include "llpanelgroupinvite.h" #include "llagent.h" +#include "llavatarnamecache.h" #include "llfloateravatarpicker.h" #include "llbutton.h" +#include "llcallingcard.h" #include "llcombobox.h" #include "llgroupmgr.h" #include "llnamelistctrl.h" @@ -54,7 +56,7 @@ public: ~impl(); void addUsers(const std::vector& names, - const std::vector& agent_ids); + const uuid_vec_t& agent_ids); void submitInvitations(); void addRoleNames(LLGroupMgrGroupData* gdatap); void handleRemove(); @@ -65,9 +67,13 @@ public: static void callbackClickAdd(void* userdata); static void callbackClickRemove(void* userdata); static void callbackSelect(LLUICtrl* ctrl, void* userdata); - static void callbackAddUsers(const std::vector& names, - const std::vector& agent_ids, + static void callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data); + + static void onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name, + void* user_data); + bool inviteOwnerCallback(const LLSD& notification, const LLSD& response); public: @@ -80,6 +86,8 @@ public: LLButton *mRemoveButton; LLTextBox *mGroupName; std::string mOwnerWarning; + std::string mAlreadyInGroup; + std::string mTooManySelected; bool mConfirmedOwnerInvite; void (*mCloseCallback)(void* data); @@ -107,7 +115,7 @@ LLPanelGroupInvite::impl::~impl() } void LLPanelGroupInvite::impl::addUsers(const std::vector& names, - const std::vector& agent_ids) + const uuid_vec_t& agent_ids) { std::string name; LLUUID id; @@ -138,9 +146,10 @@ void LLPanelGroupInvite::impl::addUsers(const std::vector& names, //add the name to the names list LLSD row; row["id"] = id; + row["columns"][0]["column"] = "name"; row["columns"][0]["value"] = name; - mInvitees->addElement(row); + mInvitees->addNameItem(row); } } @@ -167,16 +176,40 @@ void LLPanelGroupInvite::impl::submitInvitations() } } + bool already_in_group = false; //loop over the users std::vector items = mInvitees->getAllData(); for (std::vector::iterator iter = items.begin(); iter != items.end(); ++iter) { LLScrollListItem* item = *iter; + if(gdatap->mMembers.find(item->getUUID()) != gdatap->mMembers.end()) + { + already_in_group = true; + continue; + } role_member_pairs[item->getUUID()] = role_id; } + + const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap. + if (role_member_pairs.size() > MAX_GROUP_INVITES) + { + // Fail! + LLSD msg; + msg["MESSAGE"] = mTooManySelected; + LLNotificationsUtil::add("GenericAlert", msg); + (*mCloseCallback)(mCloseCallbackUserData); + return; + } LLGroupMgr::getInstance()->sendGroupMemberInvites(mGroupID, role_member_pairs); + + if(already_in_group) + { + LLSD msg; + msg["MESSAGE"] = mAlreadyInGroup; + LLNotificationsUtil::add("GenericAlert", msg); + } //then close (*mCloseCallback)(mCloseCallbackUserData); @@ -184,7 +217,7 @@ void LLPanelGroupInvite::impl::submitInvitations() bool LLPanelGroupInvite::impl::inviteOwnerCallback(const LLSD& notification, const LLSD& response) { - S32 option = LLNotification::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); switch(option) { @@ -273,12 +306,12 @@ void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata) //Soon the avatar picker will be embedded into this panel //instead of being it's own separate floater. But that is next week. //This will do for now. -jwolk May 10, 2006 - LLFloater* parentp; - - parentp = gFloaterView->getParentFloater(panelp); - parentp->addDependentFloater(LLFloaterAvatarPicker::show(callbackAddUsers, - panelp->mImplementation, - TRUE)); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE); + if (picker) + { + gFloaterView->getParentFloater(panelp)->addDependentFloater(picker); + } } } @@ -342,26 +375,43 @@ void LLPanelGroupInvite::impl::callbackClickOK(void* userdata) if ( selfp ) selfp->submitInvitations(); } + + //static -void LLPanelGroupInvite::impl::callbackAddUsers(const std::vector& names, - const std::vector& ids, - void* user_data) +void LLPanelGroupInvite::impl::callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data) +{ + std::vector names; + for (S32 i = 0; i < (S32)agent_ids.size(); i++) + { + LLAvatarNameCache::get(agent_ids[i], + boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data)); + } + +} + +void LLPanelGroupInvite::impl::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name, + void* user_data) { impl* selfp = (impl*) user_data; - if ( selfp) selfp->addUsers(names, ids); + if (selfp) + { + std::vector names; + uuid_vec_t agent_ids; + agent_ids.push_back(agent_id); + names.push_back(av_name.getCompleteName()); + + selfp->addUsers(names, agent_ids); + } } LLPanelGroupInvite::LLPanelGroupInvite(const std::string& name, const LLUUID& group_id) - : LLPanel(name) + : LLPanel(name), + mImplementation(new impl(group_id)), + mPendingUpdate(FALSE) { - mImplementation = new impl(group_id); - mPendingUpdate = FALSE; - mStoreSelected = LLUUID::null; - - std::string panel_def_file; - // Pass on construction of this panel to the control factory. LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_invite.xml", &getFactoryMap()); } @@ -387,18 +437,72 @@ void LLPanelGroupInvite::clear() mImplementation->mOKButton->setEnabled(FALSE); } -void LLPanelGroupInvite::addUsers(std::vector& agent_ids) +void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) { std::vector names; for (S32 i = 0; i < (S32)agent_ids.size(); i++) { - std::string name; - if(gCacheName->getFullName(agent_ids[i], name)) - names.push_back(name); + std::string fullname; + LLUUID agent_id = agent_ids[i]; + LLViewerObject* dest = gObjectList.findObject(agent_id); + if(dest && dest->isAvatar()) + { + LLNameValue* nvfirst = dest->getNVPair("FirstName"); + LLNameValue* nvlast = dest->getNVPair("LastName"); + if(nvfirst && nvlast) + { + fullname = LLCacheName::buildFullName( + nvfirst->getString(), nvlast->getString()); + + } + if (!fullname.empty()) + { + names.push_back(fullname); + } + else + { + llwarns << "llPanelGroupInvite: Selected avatar has no name: " << dest->getID() << llendl; + names.push_back("(Unknown)"); + } + } + else + { + //looks like user try to invite offline friend + //for offline avatar_id gObjectList.findObject() will return null + //so we need to do this additional search in avatar tracker, see EXT-4732 + if (LLAvatarTracker::instance().isBuddy(agent_id)) + { + LLAvatarName av_name; + if (!LLAvatarNameCache::get(agent_id, &av_name)) + { + // actually it should happen, just in case + LLAvatarNameCache::get(LLUUID(agent_id), boost::bind( + &LLPanelGroupInvite::addUserCallback, this, _1, _2)); + // for this special case! + //when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence + // removed id will be added in callback + agent_ids.erase(agent_ids.begin() + i); + } + else + { + names.push_back(av_name.getLegacyName()); + } + } + } } mImplementation->addUsers(names, agent_ids); } +void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& av_name) +{ + std::vector names; + uuid_vec_t agent_ids; + agent_ids.push_back(id); + names.push_back(av_name.getLegacyName()); + + mImplementation->addUsers(names, agent_ids); +} + void LLPanelGroupInvite::draw() { LLPanel::draw(); @@ -472,8 +576,8 @@ void LLPanelGroupInvite::updateLists() if (!mPendingUpdate) { LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); - LLGroupMgr::getInstance()->sendGroupMembersRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); } mPendingUpdate = TRUE; } @@ -499,9 +603,8 @@ BOOL LLPanelGroupInvite::postBuild() getChild("invitee_list", recurse); if ( mImplementation->mInvitees ) { - mImplementation->mInvitees->setCallbackUserData(mImplementation); mImplementation->mInvitees->setCommitOnSelectionChange(TRUE); - mImplementation->mInvitees->setCommitCallback(impl::callbackSelect); + mImplementation->mInvitees->setCommitCallback(impl::callbackSelect, mImplementation); } LLButton* button = getChild("add_button", recurse); @@ -509,14 +612,14 @@ BOOL LLPanelGroupInvite::postBuild() { // default to opening avatarpicker automatically // (*impl::callbackClickAdd)((void*)this); - button->setClickedCallback(boost::bind(&impl::callbackClickAdd, this)); + button->setClickedCallback(impl::callbackClickAdd, this); } mImplementation->mRemoveButton = getChild("remove_button", recurse); if ( mImplementation->mRemoveButton ) { - mImplementation->mRemoveButton->setClickedCallback(boost::bind(&impl::callbackClickRemove, mImplementation)); + mImplementation->mRemoveButton->setClickedCallback(impl::callbackClickRemove, mImplementation); mImplementation->mRemoveButton->setEnabled(FALSE); } @@ -524,17 +627,19 @@ BOOL LLPanelGroupInvite::postBuild() getChild("ok_button", recurse); if ( mImplementation->mOKButton ) { - mImplementation->mOKButton->setClickedCallback(boost::bind(&impl::callbackClickOK, mImplementation)); + mImplementation->mOKButton->setClickedCallback(impl::callbackClickOK, mImplementation); mImplementation->mOKButton->setEnabled(FALSE); } button = getChild("cancel_button", recurse); if ( button ) { - button->setClickedCallback(boost::bind(&impl::callbackClickCancel,mImplementation)); + button->setClickedCallback(impl::callbackClickCancel, mImplementation); } mImplementation->mOwnerWarning = getString("confirm_invite_owner_str"); + mImplementation->mAlreadyInGroup = getString("already_in_group"); + mImplementation->mTooManySelected = getString("invite_selection_too_large"); update(); diff --git a/indra/newview/llpanelgroupinvite.h b/indra/newview/llpanelgroupinvite.h index 9117b83e7..b296e3dd4 100644 --- a/indra/newview/llpanelgroupinvite.h +++ b/indra/newview/llpanelgroupinvite.h @@ -35,6 +35,7 @@ #include "llpanel.h" #include "lluuid.h" +class LLAvatarName; class LLPanelGroupInvite : public LLPanel { @@ -42,7 +43,11 @@ public: LLPanelGroupInvite(const std::string& name, const LLUUID& group_id); ~LLPanelGroupInvite(); - void addUsers(std::vector& agent_ids); + void addUsers(uuid_vec_t& agent_ids); + /** + * this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers(). + */ + void addUserCallback(const LLUUID& id, const LLAvatarName& av_name); void clear(); void update(); diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 9b7ee5c78..5ad7ad7a1 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -462,19 +462,19 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) row["columns"][0]["column"] = "name"; row["columns"][0]["value"] = name; - row["columns"][0]["font"] = "SANSSERIFSMALL"; + row["columns"][0]["font"] = "SANSSERIF_SMALL"; row["columns"][1]["column"] = "location"; row["columns"][1]["value"] = location; - row["columns"][1]["font"] = "SANSSERIFSMALL"; + row["columns"][1]["font"] = "SANSSERIF_SMALL"; row["columns"][2]["column"] = "area"; row["columns"][2]["value"] = area; - row["columns"][2]["font"] = "SANSSERIFSMALL"; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; row["columns"][3]["column"] = "type"; row["columns"][3]["value"] = land_type; - row["columns"][3]["font"] = "SANSSERIFSMALL"; + row["columns"][3]["font"] = "SANSSERIF_SMALL"; // hidden is always last column row["columns"][4]["column"] = "hidden"; @@ -676,7 +676,7 @@ BOOL LLPanelGroupLandMoney::postBuild() { if ( mImplementationp->mGroupParcelsp ) { - mImplementationp->mGroupParcelsp->addCommentText( + mImplementationp->mGroupParcelsp->setCommentText( mImplementationp->mCantViewParcelsText); mImplementationp->mGroupParcelsp->setEnabled(FALSE); } diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 13786d9e4..ffec84e7d 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -450,7 +450,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) if (1 == count && id.isNull()) { // Only one entry, the dummy entry. - mNoticesList->addCommentText(mNoNoticesStr); + mNoticesList->setCommentText(mNoNoticesStr); mNoticesList->setEnabled(FALSE); return; } @@ -493,7 +493,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) mNoticesList->addElement(row, ADD_BOTTOM); } - mNoticesList->sortItems(); + mNoticesList->updateSort(); } void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data) diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 155ab8dde..b7f09bd69 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -402,7 +402,7 @@ void LLPanelGroupRoles::activate() if (!gdatap || !gdatap->isMemberDataComplete() ) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } // Check role data. @@ -790,7 +790,7 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, row["columns"][column_index]["column"] = "action"; row["columns"][column_index]["value"] = (*ra_it)->mDescription; - row["columns"][column_index]["font"] = "SANSSERIFSMALL"; + row["columns"][column_index]["font"] = "SANSSERIF_SMALL"; LLScrollListItem* item = ctrl->addElement(row, ADD_BOTTOM, (*ra_it)); @@ -890,11 +890,10 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) if (!mMembersList || !mAssignedRolesList || !mAllowedActionsList) return FALSE; // We want to be notified whenever a member is selected. - mMembersList->setCallbackUserData(this); mMembersList->setCommitOnSelectionChange(TRUE); - mMembersList->setCommitCallback(onMemberSelect); + mMembersList->setCommitCallback(boost::bind(&LLPanelGroupMembersSubTab::onMemberSelect,_1,this)); // Show the member's profile on double click. - mMembersList->setDoubleClickCallback(onMemberDoubleClick); + mMembersList->setDoubleClickCallback(boost::bind(&LLPanelGroupMembersSubTab::onMemberDoubleClick,this)); LLButton* button = parent->getChild("member_invite", recurse); if ( button ) @@ -1616,7 +1615,7 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc) retrieved << "Retrieving role member mappings..."; } mMembersList->setEnabled(FALSE); - mMembersList->addCommentText(retrieved.str()); + mMembersList->setCommentText(retrieved.str()); } } @@ -1679,9 +1678,9 @@ void LLPanelGroupMembersSubTab::updateMembers() row["columns"][2]["column"] = "online"; row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus(); - row["columns"][2]["font"] = "SANSSERIFSMALL"; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; - mMembersList->addElement(row);//, ADD_SORTED); + mMembersList->addNameItem(row); mHasMatch = TRUE; } } @@ -1695,7 +1694,7 @@ void LLPanelGroupMembersSubTab::updateMembers() else { mMembersList->setEnabled(FALSE); - mMembersList->addCommentText(std::string("No match.")); + mMembersList->setCommentText(std::string("No match.")); } } else @@ -1980,7 +1979,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) if (!gdatap || !gdatap->isMemberDataComplete()) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } if (!gdatap || !gdatap->isRoleMemberDataComplete()) @@ -2572,7 +2571,7 @@ void LLPanelGroupActionsSubTab::handleActionSelect() } else { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } if (gdatap->isRoleDataComplete()) diff --git a/indra/newview/llpanelgroupvoting.cpp b/indra/newview/llpanelgroupvoting.cpp index 89134c437..0eac7e5ec 100644 --- a/indra/newview/llpanelgroupvoting.cpp +++ b/indra/newview/llpanelgroupvoting.cpp @@ -693,7 +693,7 @@ public: } //If we get back a normal response, handle it here - virtual void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { //Ack'd the proposal initialization, now let's finish up. LLPanelGroupVoting::handleResponse( @@ -702,7 +702,7 @@ public: } //If we get back an error (not found, etc...), handle it here - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { llinfos << "LLPanelGroupVotingResponder::error " << status << ": " << reason << llendl; @@ -710,8 +710,8 @@ public: LLPanelGroupVoting::handleFailure(mGroupID); } - //Return our timeout policy. - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return startGroupVoteResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return startGroupVoteResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLStartGroupVoteResponder"; } private: LLUUID mGroupID; @@ -726,7 +726,7 @@ public: } //If we get back a normal response, handle it here - virtual void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { //Ack'd the proposal initialization, now let's finish up. LLPanelGroupVoting::handleResponse( @@ -736,7 +736,7 @@ public: } //If we get back an error (not found, etc...), handle it here - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { llinfos << "LLPanelGroupVotingResponder::error " << status << ": " << reason << llendl; @@ -745,7 +745,8 @@ public: } //Return out timeout policy. - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return groupProposalBallotResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return groupProposalBallotResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLGroupProposalBallotResponder"; } private: LLUUID mGroupID; @@ -916,19 +917,19 @@ void LLPanelGroupVoting::impl::addPendingActiveScrollListItem(unsigned int curre << current << "\\" << expected << ")"; - mProposals->addCommentText(pending.str()); + mProposals->setCommentText(pending.str()); } void LLPanelGroupVoting::impl::addNoActiveScrollListItem(EAddPosition pos) { // *TODO: translate - mProposals->addCommentText(std::string("There are currently no active proposals"), pos); + mProposals->setCommentText(std::string("There are currently no active proposals")); } void LLPanelGroupVoting::impl::addNoHistoryScrollListItem(EAddPosition pos) { // *TODO: translate - mVotesHistory->addCommentText(std::string("There are currently no archived proposals"), pos); + mVotesHistory->setCommentText(std::string("There are currently no archived proposals")); } void LLPanelGroupVoting::impl::addPendingHistoryScrollListItem(unsigned int current, @@ -941,7 +942,7 @@ void LLPanelGroupVoting::impl::addPendingHistoryScrollListItem(unsigned int curr << current << "\\" << expected << ")"; - mVotesHistory->addCommentText(pending.str()); + mVotesHistory->setCommentText(pending.str()); } @@ -1579,11 +1580,9 @@ BOOL LLPanelGroupVoting::postBuild() //associate callbacks if ( success ) { - mImpl->mProposals->setDoubleClickCallback(impl::onDoubleClickProposal); - mImpl->mProposals->setCallbackUserData(mImpl); + mImpl->mProposals->setDoubleClickCallback(boost::bind(&LLPanelGroupVoting::impl::onDoubleClickProposal,mImpl)); - mImpl->mVotesHistory->setDoubleClickCallback(impl::onDoubleClickHistoryItem); - mImpl->mVotesHistory->setCallbackUserData(mImpl); + mImpl->mVotesHistory->setDoubleClickCallback(boost::bind(&LLPanelGroupVoting::impl::onDoubleClickHistoryItem,mImpl)); mImpl->mBtnAbstain->setClickedCallback(boost::bind(&impl::onClickAbstain,mImpl)); diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp index f3591c0ad..19d1a8d82 100644 --- a/indra/newview/llpanelland.cpp +++ b/indra/newview/llpanelland.cpp @@ -180,7 +180,7 @@ void LLPanelLandInfo::refresh() childSetEnabled("button abandon land",owner_release || manager_releaseable || gAgent.isGodlike()); // only mainland sims are subdividable by owner - if (regionp->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) + if (regionp->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES)) { childSetEnabled("button subdivide land",owner_divide || manager_divideable || gAgent.isGodlike()); } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 019ddd668..99991e769 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -162,10 +162,6 @@ public: LLLoginRefreshHandler gLoginRefreshHandler; -// -std::string gFullName; -// - // helper class that trys to download a URL from a web site and calls a method // on parent class indicating if the web server is working or not class LLIamHereLogin : public LLHTTPClient::ResponderHeadersOnly @@ -196,7 +192,9 @@ class LLIamHereLogin : public LLHTTPClient::ResponderHeadersOnly } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return iamHereLogin_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return iamHereLogin_timeout; } + + /*virtual*/ char const* getName(void) const { return "LLIamHereLogin"; } }; // this is global and not a class member to keep crud out of the header file diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 53eb9b52d..1812b6fc7 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -41,10 +41,6 @@ class LLUIImage; class LLComboBox; -// -extern std::string gFullName; -// - class LLPanelLogin: public LLPanel, public LLViewerMediaObserver @@ -165,8 +161,4 @@ private: std::string load_password_from_disk(void); void save_password_to_disk(const char* hashed_password); -// -extern std::string gFullName; -// - #endif diff --git a/indra/newview/llpanelmediahud.cpp b/indra/newview/llpanelmediahud.cpp index 2fcee26c6..27d1473d6 100644 --- a/indra/newview/llpanelmediahud.cpp +++ b/indra/newview/llpanelmediahud.cpp @@ -78,8 +78,6 @@ LLPanelMediaHUD::LLPanelMediaHUD(viewer_media_t media_impl) mFadeTimer.stop(); mCurrentZoom = ZOOM_NONE; mScrollState = SCROLL_NONE; - - mPanelHandle.bind(this); } LLPanelMediaHUD::~LLPanelMediaHUD() { diff --git a/indra/newview/llpanelmediahud.h b/indra/newview/llpanelmediahud.h index 81d40591e..1d1f5e1be 100644 --- a/indra/newview/llpanelmediahud.h +++ b/indra/newview/llpanelmediahud.h @@ -55,7 +55,8 @@ public: void nextZoomLevel(); void resetZoomLevel() { mCurrentZoom = ZOOM_NONE; } - LLHandle getHandle() const { return mPanelHandle; } + LLHandle getHandle() const { return getDerivedHandle(); } + void setMediaImpl(viewer_media_t media_impl) { mMediaImpl = media_impl; } @@ -105,7 +106,6 @@ private: F32 mMouseInactiveTime; F32 mControlFadeTime; viewer_media_t mMediaImpl; - LLRootHandle mPanelHandle; }; #endif // LL_PANELMEDIAHUD_H diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index b1f702bcd..6af8129ff 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -130,6 +130,10 @@ LLVector3 LLPanelObject::mClipboardPos; LLVector3 LLPanelObject::mClipboardSize; LLVector3 LLPanelObject::mClipboardRot; LLVolumeParams LLPanelObject::mClipboardVolumeParams; +LLFlexibleObjectData* LLPanelObject::mClipboardFlexiParams = NULL; +LLLightParams* LLPanelObject::mClipboardLightParams = NULL; +LLSculptParams* LLPanelObject::mClipboardSculptParams = NULL; +LLLightImageParams* LLPanelObject::mClipboardLightImageParams = NULL; BOOL LLPanelObject::hasParamClipboard = FALSE; BOOL LLPanelObject::postBuild() @@ -594,10 +598,9 @@ void LLPanelObject::getState( ) mBtnCopyParams->setEnabled( single_volume ); mBtnPasteParams->setEnabled( single_volume ); - BOOL owners_identical; LLUUID owner_id; std::string owner_name; - owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); + LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); // BUG? Check for all objects being editable? S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount(); @@ -2493,15 +2496,65 @@ void LLPanelObject::onCopyRot(void* user_data) void LLPanelObject::onCopyParams(void* user_data) { LLPanelObject* self = (LLPanelObject*) user_data; + if (!self) return; + self->getVolumeParams(mClipboardVolumeParams); hasParamClipboard = TRUE; + + LLViewerObject* objp = self->mObject; + + mClipboardFlexiParams = (LLFlexibleObjectData*)objp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); + mClipboardLightParams = (LLLightParams*)objp->getParameterEntry(LLNetworkData::PARAMS_LIGHT); + mClipboardSculptParams = (LLSculptParams*)objp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + if (mClipboardSculptParams) + { + LLUUID id = mClipboardSculptParams->getSculptTexture(); + + // Texture perms check + if (!(id.isNull() || gInventory.isObjectDescendentOf(id, gInventory.getLibraryRootFolderID()) + || id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) + || id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) + || id == LLUUID(std::string("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"))) // alpha + && findItemID(id).isNull()) + { + mClipboardSculptParams->setSculptTexture(LLUUID(SCULPT_DEFAULT_TEXTURE)); + } + } + mClipboardLightImageParams = (LLLightImageParams*)objp->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (mClipboardLightImageParams) + { + LLUUID id = mClipboardLightImageParams->getLightTexture(); + + // Texture perms check + if (!(id.isNull() || gInventory.isObjectDescendentOf(id, gInventory.getLibraryRootFolderID()) + || id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) + || id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) + || id == LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"))) // alpha + { + mClipboardLightImageParams->setLightTexture(findItemID(id)); + } + } } void LLPanelObject::onPasteParams(void* user_data) { + if(!hasParamClipboard) return; + LLPanelObject* self = (LLPanelObject*) user_data; - if(hasParamClipboard) - self->mObject->updateVolume(mClipboardVolumeParams); + if(!self) return; + + LLViewerObject* objp = self->mObject; + + objp->updateVolume(mClipboardVolumeParams); + + if (mClipboardFlexiParams) + objp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, *mClipboardFlexiParams, true); + if (mClipboardLightParams) + objp->setParameterEntry(LLNetworkData::PARAMS_LIGHT, *mClipboardLightParams, true); + if (mClipboardSculptParams) + objp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, *mClipboardSculptParams, true); + if (mClipboardLightImageParams) + objp->setParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE, *mClipboardLightImageParams, true); } void LLPanelObject::onLinkObj(void* user_data) diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index ae2397294..e34d318c6 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -50,6 +50,10 @@ class LLColorSwatchCtrl; class LLTextureCtrl; class LLInventoryItem; class LLUUID; +class LLFlexibleObjectData; +class LLLightParams; +class LLLightImageParams; +class LLSculptParams; class LLPanelObject : public LLPanel { @@ -119,6 +123,10 @@ protected: static LLVector3 mClipboardSize; static LLVector3 mClipboardRot; static LLVolumeParams mClipboardVolumeParams; + static LLFlexibleObjectData* mClipboardFlexiParams; + static LLLightParams* mClipboardLightParams; + static LLSculptParams* mClipboardSculptParams; + static LLLightImageParams* mClipboardLightImageParams; static BOOL hasParamClipboard; S32 mComboMaterialItemCount; diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 8929780d5..41563bfc1 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -48,6 +48,7 @@ #include "llinventorydefines.h" #include "llinventoryfilter.h" #include "llinventoryfunctions.h" +#include "llinventoryicon.h" #include "llpreviewanim.h" #include "llpreviewgesture.h" #include "llpreviewnotecard.h" @@ -131,7 +132,7 @@ public: virtual BOOL copyToClipboard() const; virtual void cutToClipboard(); virtual BOOL isClipboardPasteable() const; - virtual void pasteFromClipboard(); + virtual void pasteFromClipboard(bool only_copies = false); virtual void pasteLinkFromClipboard(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); virtual void performAction(LLInventoryModel* model, std::string action); @@ -604,7 +605,7 @@ BOOL LLTaskInvFVBridge::isClipboardPasteable() const return FALSE; } -void LLTaskInvFVBridge::pasteFromClipboard() +void LLTaskInvFVBridge::pasteFromClipboard(bool only_copies) { } diff --git a/indra/newview/llpanelpathfindingrebakenavmesh.cpp b/indra/newview/llpanelpathfindingrebakenavmesh.cpp deleted file mode 100644 index ca4bcfb67..000000000 --- a/indra/newview/llpanelpathfindingrebakenavmesh.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/** -* @file llpanelpathfindingrebakenavmesh.cpp -* @brief Implementation of llpanelpathfindingrebakenavmesh -* @author Prep@lindenlab.com -* -* $LicenseInfo:firstyear=2012&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2012, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* 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 "llpanelpathfindingrebakenavmesh.h" - -#include -#include - -#include "llagent.h" -#include "llbutton.h" -#include "llenvmanager.h" -#include "llnotificationsutil.h" -#include "llpanel.h" -#include "llpathfindingmanager.h" -#include "llpathfindingnavmesh.h" -#include "llpathfindingnavmeshstatus.h" -#include "lltoolbar.h" -#include "llviewerregion.h" -#include "llviewerwindow.h" -#include "lluictrlfactory.h" - - -LLPanelPathfindingRebakeNavmesh* LLPanelPathfindingRebakeNavmesh::getInstance() -{ - static LLPanelPathfindingRebakeNavmesh* panel = getPanel(); - return panel; -} - -BOOL LLPanelPathfindingRebakeNavmesh::postBuild() -{ - //Rebake button - mNavMeshRebakeButton = getChild("navmesh_btn"); - llassert(mNavMeshRebakeButton != NULL); - mNavMeshRebakeButton->setCommitCallback(boost::bind(&LLPanelPathfindingRebakeNavmesh::onNavMeshRebakeClick, this)); - //LLHints::registerHintTarget("navmesh_btn", mNavMeshRebakeButton->getHandle()); - - //Sending rebake request - mNavMeshSendingButton = findChild("navmesh_btn_sending"); - llassert(mNavMeshSendingButton != NULL); - //LLHints::registerHintTarget("navmesh_btn_sending", mNavMeshSendingButton->getHandle()); - - //rebaking... - mNavMeshBakingButton = findChild("navmesh_btn_baking"); - llassert(mNavMeshBakingButton != NULL); - //LLHints::registerHintTarget("navmesh_btn_baking", mNavMeshBakingButton->getHandle()); - - setMode(kRebakeNavMesh_Default); - - createNavMeshStatusListenerForCurrentRegion(); - - if ( !mRegionCrossingSlot.connected() ) - { - mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this)); - } - - if (!mAgentStateSlot.connected()) - { - mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleAgentState, this, _1)); - } - LLPathfindingManager::getInstance()->requestGetAgentState(); - - return LLPanel::postBuild(); -} - -void LLPanelPathfindingRebakeNavmesh::draw() -{ - if (doDraw()) - { - updatePosition(); - LLPanel::draw(); - } -} - -BOOL LLPanelPathfindingRebakeNavmesh::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) -{ - gViewerWindow->unblockToolTips(); - - if (mNavMeshRebakeButton->getVisible()) - { - msg=mNavMeshRebakeButton->getToolTip(); - //LLToolTipMgr::instance().show(mNavMeshRebakeButton->getToolTip()); - } - else if (mNavMeshSendingButton->getVisible()) - { - msg=mNavMeshSendingButton->getToolTip(); - //LLToolTipMgr::instance().show(mNavMeshSendingButton->getToolTip()); - } - else if (mNavMeshBakingButton->getVisible()) - { - msg=mNavMeshBakingButton->getToolTip(); - //LLToolTipMgr::instance().show(mNavMeshBakingButton->getToolTip()); - } - - // Convert rect local to screen coordinates - localPointToScreen( - 0, 0, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - getRect().getWidth(), getRect().getHeight(), - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); - return true;//LLPanel::handleToolTip(x, y, mask); -} - -LLPanelPathfindingRebakeNavmesh::LLPanelPathfindingRebakeNavmesh() - : LLPanel(), - mCanRebakeRegion(FALSE), - mRebakeNavMeshMode(kRebakeNavMesh_Default), - mNavMeshRebakeButton(NULL), - mNavMeshSendingButton(NULL), - mNavMeshBakingButton(NULL), - mNavMeshSlot(), - mRegionCrossingSlot(), - mAgentStateSlot() -{ - // make sure we have the only instance of this class - static bool b = true; - llassert_always(b); - b=false; -} - -LLPanelPathfindingRebakeNavmesh::~LLPanelPathfindingRebakeNavmesh() -{ -} - -LLPanelPathfindingRebakeNavmesh* LLPanelPathfindingRebakeNavmesh::getPanel() -{ - LLPanelPathfindingRebakeNavmesh* panel = new LLPanelPathfindingRebakeNavmesh(); - LLUICtrlFactory::getInstance()->buildPanel(panel,"panel_navmesh_rebake.xml"); - return panel; -} - -void LLPanelPathfindingRebakeNavmesh::setMode(ERebakeNavMeshMode pRebakeNavMeshMode) -{ - if (pRebakeNavMeshMode == kRebakeNavMesh_Available) - { - LLNotificationsUtil::add("PathfindingRebakeNavmesh"); - } - mNavMeshRebakeButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_Available); - mNavMeshSendingButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_RequestSent); - mNavMeshBakingButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_InProgress); - mRebakeNavMeshMode = pRebakeNavMeshMode; -} - -LLPanelPathfindingRebakeNavmesh::ERebakeNavMeshMode LLPanelPathfindingRebakeNavmesh::getMode() const -{ - return mRebakeNavMeshMode; -} - -void LLPanelPathfindingRebakeNavmesh::onNavMeshRebakeClick() -{ - setMode(kRebakeNavMesh_RequestSent); - LLPathfindingManager::getInstance()->requestRebakeNavMesh(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleRebakeNavMeshResponse, this, _1)); -} - -void LLPanelPathfindingRebakeNavmesh::handleAgentState(BOOL pCanRebakeRegion) -{ - mCanRebakeRegion = pCanRebakeRegion; -} - -void LLPanelPathfindingRebakeNavmesh::handleRebakeNavMeshResponse(bool pResponseStatus) -{ - if (getMode() == kRebakeNavMesh_RequestSent) - { - setMode(pResponseStatus ? kRebakeNavMesh_InProgress : kRebakeNavMesh_Default); - } - - if (!pResponseStatus) - { - LLNotificationsUtil::add("PathfindingCannotRebakeNavmesh"); - } -} - -void LLPanelPathfindingRebakeNavmesh::handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus) -{ - ERebakeNavMeshMode rebakeNavMeshMode = kRebakeNavMesh_Default; - if (pNavMeshStatus.isValid()) - { - switch (pNavMeshStatus.getStatus()) - { - case LLPathfindingNavMeshStatus::kPending : - case LLPathfindingNavMeshStatus::kRepending : - rebakeNavMeshMode = kRebakeNavMesh_Available; - break; - case LLPathfindingNavMeshStatus::kBuilding : - rebakeNavMeshMode = kRebakeNavMesh_InProgress; - break; - case LLPathfindingNavMeshStatus::kComplete : - rebakeNavMeshMode = kRebakeNavMesh_NotAvailable; - break; - default : - rebakeNavMeshMode = kRebakeNavMesh_Default; - llassert(0); - break; - } - } - - setMode(rebakeNavMeshMode); -} - -void LLPanelPathfindingRebakeNavmesh::handleRegionBoundaryCrossed() -{ - createNavMeshStatusListenerForCurrentRegion(); - mCanRebakeRegion = FALSE; - LLPathfindingManager::getInstance()->requestGetAgentState(); -} - -void LLPanelPathfindingRebakeNavmesh::createNavMeshStatusListenerForCurrentRegion() -{ - if (mNavMeshSlot.connected()) - { - mNavMeshSlot.disconnect(); - } - - LLViewerRegion *currentRegion = gAgent.getRegion(); - if (currentRegion != NULL) - { - mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLPanelPathfindingRebakeNavmesh::handleNavMeshStatus, this, _2)); - LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true); - } -} - -bool LLPanelPathfindingRebakeNavmesh::doDraw() const -{ - return (mCanRebakeRegion && (mRebakeNavMeshMode != kRebakeNavMesh_NotAvailable)); -} - -void LLPanelPathfindingRebakeNavmesh::updatePosition() -{ -#if 0 - S32 y_pos = 0; - S32 bottom_tb_center = 0; - - if (LLToolBar* toolbar_bottom = gToolBarView->getChild("toolbar_bottom")) - { - y_pos = toolbar_bottom->getRect().getHeight(); - bottom_tb_center = toolbar_bottom->getRect().getCenterX(); - } - - S32 left_tb_width = 0; - if (LLToolBar* toolbar_left = gToolBarView->getChild("toolbar_left")) - { - left_tb_width = toolbar_left->getRect().getWidth(); - } - - if(LLPanel* panel_ssf_container = getRootView()->getChild("state_management_buttons_container")) - { - panel_ssf_container->setOrigin(0, y_pos); - } - - S32 x_pos = bottom_tb_center-getRect().getWidth()/2 - left_tb_width + 113 /* width of stand/fly button *//* + 10 *//* margin */; - - /*setOrigin( x_pos, 0);*/ -#endif -} diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index c501e9de0..ecc652645 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -343,10 +343,8 @@ void LLPanelPermissions::refresh() // Update creator text field childSetEnabled("Creator:",true); - BOOL creators_identical; std::string creator_name; - creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, - creator_name); + bool creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name); childSetText("Creator Name",creator_name); childSetEnabled("Creator Name",TRUE); @@ -355,9 +353,8 @@ void LLPanelPermissions::refresh() // Update owner text field childSetEnabled("Owner:",true); - BOOL owners_identical; std::string owner_name; - owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_name); + const BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_name); // llinfos << "owners_identical " << (owners_identical ? "TRUE": "FALSE") << llendl; std::string last_owner_name; diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index 7bcb0eb31..da0b9a546 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -47,7 +47,6 @@ #include "llcheckboxctrl.h" #include "llviewercontrol.h" #include "lllineeditor.h" -#include "lltabcontainervertical.h" #include "lltextbox.h" #include "llviewertexteditor.h" #include "lltexturectrl.h" diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp new file mode 100644 index 000000000..2bf44165e --- /dev/null +++ b/indra/newview/llpanelprofile.cpp @@ -0,0 +1,432 @@ +/** +* @file llpanelprofile.cpp +* @brief Profile panel implementation +* +* $LicenseInfo:firstyear=2009&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llpanelprofile.h" + +#ifdef AI_UNUSED +#include "llagent.h" +#include "llavataractions.h" +#include "llfloaterreg.h" +#include "llcommandhandler.h" +#include "llnotificationsutil.h" +#include "llpanelpicks.h" +#include "lltabcontainer.h" +#include "llviewercontrol.h" +#include "llviewernetwork.h" + +static const std::string PANEL_PICKS = "panel_picks"; +#endif // AI_UNUSED + +#include "hippogridmanager.h" +#include "llcontrol.h" +#include "llweb.h" + +std::string getProfileURL(const std::string& agent_name) +{ + std::string url = gSavedSettings.getString("WebProfileURL"); + LLSD subs; + subs["AGENT_NAME"] = agent_name; + url = LLWeb::expandURLSubstitutions(url,subs); + LLStringUtil::toLower(url); + return url; +} + +#ifdef AI_UNUSED +class LLProfileHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLProfileHandler() : LLCommandHandler("profile", UNTRUSTED_THROTTLE) { } + + bool handle(const LLSD& params, const LLSD& query_map, + LLMediaCtrl* web) + { + if (params.size() < 1) return false; + std::string agent_name = params[0]; + llinfos << "Profile, agent_name " << agent_name << llendl; + std::string url = getProfileURL(agent_name); + LLWeb::loadURLInternal(url); + + return true; + } +}; +LLProfileHandler gProfileHandler; + +class LLAgentHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { } + + bool handle(const LLSD& params, const LLSD& query_map, + LLMediaCtrl* web) + { + if (params.size() < 2) return false; + LLUUID avatar_id; + if (!avatar_id.set(params[0], FALSE)) + { + return false; + } + + const std::string verb = params[1].asString(); + if (verb == "about") + { + LLAvatarActions::showProfile(avatar_id); + return true; + } + + if (verb == "inspect") + { + LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", avatar_id)); + return true; + } + + if (verb == "im") + { + LLAvatarActions::startIM(avatar_id); + return true; + } + + if (verb == "pay") + { + if (!LLUI::sSettingGroups["config"]->getBOOL("EnableAvatarPay")) + { + LLNotificationsUtil::add("NoAvatarPay", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); + return true; + } + + LLAvatarActions::pay(avatar_id); + return true; + } + + if (verb == "offerteleport") + { + LLAvatarActions::offerTeleport(avatar_id); + return true; + } + + if (verb == "requestfriend") + { + LLAvatarActions::requestFriendshipDialog(avatar_id); + return true; + } + + if (verb == "mute") + { + if (! LLAvatarActions::isBlocked(avatar_id)) + { + LLAvatarActions::toggleBlock(avatar_id); + } + return true; + } + + if (verb == "unmute") + { + if (LLAvatarActions::isBlocked(avatar_id)) + { + LLAvatarActions::toggleBlock(avatar_id); + } + return true; + } + + return false; + } +}; +LLAgentHandler gAgentHandler; + + +//-- LLPanelProfile::ChildStack begins ---------------------------------------- +LLPanelProfile::ChildStack::ChildStack() +: mParent(NULL) +{ +} + +LLPanelProfile::ChildStack::~ChildStack() +{ + while (mStack.size() != 0) + { + view_list_t& top = mStack.back(); + for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it) + { + LLView* viewp = *it; + if (viewp) + { + viewp->die(); + } + } + mStack.pop_back(); + } +} + +void LLPanelProfile::ChildStack::setParent(LLPanel* parent) +{ + llassert_always(parent != NULL); + mParent = parent; +} + +/// Save current parent's child views and remove them from the child list. +bool LLPanelProfile::ChildStack::push() +{ + view_list_t vlist = *mParent->getChildList(); + + for (view_list_t::const_iterator it = vlist.begin(); it != vlist.end(); ++it) + { + LLView* viewp = *it; + mParent->removeChild(viewp); + } + + mStack.push_back(vlist); + dump(); + return true; +} + +/// Restore saved children (adding them back to the child list). +bool LLPanelProfile::ChildStack::pop() +{ + if (mStack.size() == 0) + { + llwarns << "Empty stack" << llendl; + llassert(mStack.size() == 0); + return false; + } + + view_list_t& top = mStack.back(); + for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it) + { + LLView* viewp = *it; + mParent->addChild(viewp); + } + + mStack.pop_back(); + dump(); + return true; +} + +/// Temporarily add all saved children back. +void LLPanelProfile::ChildStack::preParentReshape() +{ + mSavedStack = mStack; + while(mStack.size() > 0) + { + pop(); + } +} + +/// Add the temporarily saved children back. +void LLPanelProfile::ChildStack::postParentReshape() +{ + mStack = mSavedStack; + mSavedStack = stack_t(); + + for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it) + { + const view_list_t& vlist = (*stack_it); + for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it) + { + LLView* viewp = *list_it; + lldebugs << "removing " << viewp->getName() << llendl; + mParent->removeChild(viewp); + } + } +} + +void LLPanelProfile::ChildStack::dump() +{ + unsigned lvl = 0; + lldebugs << "child stack dump:" << llendl; + for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it, ++lvl) + { + std::ostringstream dbg_line; + dbg_line << "lvl #" << lvl << ":"; + const view_list_t& vlist = (*stack_it); + for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it) + { + dbg_line << " " << (*list_it)->getName(); + } + lldebugs << dbg_line.str() << llendl; + } +} + +//-- LLPanelProfile::ChildStack ends ------------------------------------------ + +LLPanelProfile::LLPanelProfile() + : LLPanel() + , mAvatarId(LLUUID::null) +{ + mChildStack.setParent(this); +} + +BOOL LLPanelProfile::postBuild() +{ + LLPanelPicks* panel_picks = findChild(PANEL_PICKS); + panel_picks->setProfilePanel(this); + + getTabContainer()[PANEL_PICKS] = panel_picks; + + return TRUE; +} + +// virtual +void LLPanelProfile::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + // Temporarily add saved children back and reshape them. + mChildStack.preParentReshape(); + LLPanel::reshape(width, height, called_from_parent); + mChildStack.postParentReshape(); +} + +void LLPanelProfile::onOpen() +{ + getTabContainer()[PANEL_PICKS]->onOpen(getAvatarId()); + + // support commands to open further pieces of UI + if (key.has("show_tab_panel")) + { + std::string panel = key["show_tab_panel"].asString(); + if (panel == "create_classified") + { + LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); + if (picks) + { + picks->createNewClassified(); + } + } + else if (panel == "classified_details") + { + LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); + if (picks) + { + LLSD params = key; + params.erase("show_tab_panel"); + params.erase("open_tab_name"); + picks->openClassifiedInfo(params); + } + } + else if (panel == "edit_classified") + { + LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); + if (picks) + { + LLSD params = key; + params.erase("show_tab_panel"); + params.erase("open_tab_name"); + picks->openClassifiedEdit(params); + } + } + else if (panel == "create_pick") + { + LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); + if (picks) + { + picks->createNewPick(); + } + } + else if (panel == "edit_pick") + { + LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); + if (picks) + { + LLSD params = key; + params.erase("show_tab_panel"); + params.erase("open_tab_name"); + picks->openPickEdit(params); + } + } + } +} + +void LLPanelProfile::onTabSelected(const LLSD& param) +{ + std::string tab_name = param.asString(); + if (NULL != getTabContainer()[tab_name]) + { + getTabContainer()[tab_name]->onOpen(getAvatarId()); + } +} + +void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params) +{ + // Hide currently visible panel (STORM-690). + mChildStack.push(); + + // Add the panel or bring it to front. + if (panel->getParent() != this) + { + addChild(panel); + } + else + { + sendChildToFront(panel); + } + + panel->setVisible(TRUE); + panel->setFocus(TRUE); // prevent losing focus by the floater + panel->onOpen(params); + + LLRect new_rect = getRect(); + panel->reshape(new_rect.getWidth(), new_rect.getHeight()); + new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight()); + panel->setRect(new_rect); +} + +void LLPanelProfile::closePanel(LLPanel* panel) +{ + panel->setVisible(FALSE); + + if (panel->getParent() == this) + { + removeChild(panel); + + // Make the underlying panel visible. + mChildStack.pop(); + + // Prevent losing focus by the floater + const child_list_t* child_list = getChildList(); + if (child_list->size() > 0) + { + child_list->front()->setFocus(TRUE); + } + else + { + llwarns << "No underlying panel to focus." << llendl; + } + } +} + +S32 LLPanelProfile::notifyParent(const LLSD& info) +{ + std::string action = info["action"]; + // lets update Picks list after Pick was saved + if("save_new_pick" == action) + { + onOpen(info); + return 1; + } + + return LLPanel::notifyParent(info); +} +#endif // AI_UNUSED diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h new file mode 100644 index 000000000..05c72cfb5 --- /dev/null +++ b/indra/newview/llpanelprofile.h @@ -0,0 +1,106 @@ +/** +* @file llpanelprofile.h +* @brief Profile panel +* +* $LicenseInfo:firstyear=2009&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLPANELPROFILE_H +#define LL_LLPANELPROFILE_H + +#ifdef AI_UNUSED +#include "llpanel.h" +#include "llpanelavatar.h" + +class LLTabContainer; +#endif // AI_UNUSED + +std::string getProfileURL(const std::string& agent_name); + +#ifdef AI_UNUSED +/** +* Base class for Profile View and My Profile. +*/ +class LLPanelProfile : public LLPanel +{ + LOG_CLASS(LLPanelProfile); + +public: + /*virtual*/ BOOL postBuild(); + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + /*virtual*/ void onOpen(); + + virtual void openPanel(LLPanel* panel, const LLSD& params); + + virtual void closePanel(LLPanel* panel); + + S32 notifyParent(const LLSD& info); + +protected: + + LLPanelProfile(); + + virtual void onTabSelected(const LLSD& param); + + const LLUUID& getAvatarId() { return mAvatarId; } + + void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } + + typedef std::map profile_tabs_t; + + profile_tabs_t& getTabContainer() { return mTabContainer; } + +private: + + //-- ChildStack begins ---------------------------------------------------- + class ChildStack + { + LOG_CLASS(LLPanelProfile::ChildStack); + public: + ChildStack(); + ~ChildStack(); + void setParent(LLPanel* parent); + + bool push(); + bool pop(); + void preParentReshape(); + void postParentReshape(); + + private: + void dump(); + + typedef LLView::child_list_t view_list_t; + typedef std::list stack_t; + + stack_t mStack; + stack_t mSavedStack; + LLPanel* mParent; + }; + //-- ChildStack ends ------------------------------------------------------ + + profile_tabs_t mTabContainer; + ChildStack mChildStack; + LLUUID mAvatarId; +}; +#endif // AI_UNUSED + +#endif //LL_LLPANELPROFILE_H diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index b7ddd2e99..b8d97ef17 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -244,10 +244,9 @@ void LLPanelVolume::getState( ) return; } - BOOL owners_identical; LLUUID owner_id; std::string owner_name; - owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); + LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); // BUG? Check for all objects being editable? BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced(); diff --git a/indra/newview/llpathfindinglinkset.cpp b/indra/newview/llpathfindinglinkset.cpp index fe4daabd8..50b76378f 100644 --- a/indra/newview/llpathfindinglinkset.cpp +++ b/indra/newview/llpathfindinglinkset.cpp @@ -39,6 +39,7 @@ #define LINKSET_MODIFIABLE_FIELD "modifiable" #define LINKSET_CATEGORY_FIELD "navmesh_category" #define LINKSET_CAN_BE_VOLUME "can_be_volume" +#define LINKSET_IS_SCRIPTED_FIELD "is_scripted" #define LINKSET_PHANTOM_FIELD "phantom" #define LINKSET_WALKABILITY_A_FIELD "A" #define LINKSET_WALKABILITY_B_FIELD "B" @@ -62,6 +63,8 @@ LLPathfindingLinkset::LLPathfindingLinkset(const LLSD& pTerrainData) mLandImpact(0U), mIsModifiable(FALSE), mCanBeVolume(FALSE), + mIsScripted(FALSE), + mHasIsScripted(TRUE), mLinksetUse(kUnknown), mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE), mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE), @@ -77,6 +80,8 @@ LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD& mLandImpact(0U), mIsModifiable(TRUE), mCanBeVolume(TRUE), + mIsScripted(FALSE), + mHasIsScripted(FALSE), mLinksetUse(kUnknown), mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE), mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE), @@ -93,6 +98,8 @@ LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& pOther) mLandImpact(pOther.mLandImpact), mIsModifiable(pOther.mIsModifiable), mCanBeVolume(pOther.mCanBeVolume), + mIsScripted(pOther.mIsScripted), + mHasIsScripted(pOther.mHasIsScripted), mLinksetUse(pOther.mLinksetUse), mWalkabilityCoefficientA(pOther.mWalkabilityCoefficientA), mWalkabilityCoefficientB(pOther.mWalkabilityCoefficientB), @@ -113,6 +120,8 @@ LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkse mLandImpact = pOther.mLandImpact; mIsModifiable = pOther.mIsModifiable; mCanBeVolume = pOther.mCanBeVolume; + mIsScripted = pOther.mIsScripted; + mHasIsScripted = pOther.mHasIsScripted; mLinksetUse = pOther.mLinksetUse; mWalkabilityCoefficientA = pOther.mWalkabilityCoefficientA; mWalkabilityCoefficientB = pOther.mWalkabilityCoefficientB; @@ -140,6 +149,11 @@ bool LLPathfindingLinkset::isShowUnmodifiablePhantomWarning(ELinksetUse pLinkset return (!isModifiable() && (isPhantom() != isPhantom(pLinksetUse))); } +bool LLPathfindingLinkset::isShowPhantomToggleWarning(ELinksetUse pLinksetUse) const +{ + return (isModifiable() && (isPhantom() != isPhantom(pLinksetUse))); +} + bool LLPathfindingLinkset::isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const { return (!canBeVolume() && ((pLinksetUse == kMaterialVolume) || (pLinksetUse == kExclusionVolume))); @@ -193,6 +207,13 @@ void LLPathfindingLinkset::parseLinksetData(const LLSD &pLinksetData) llassert(pLinksetData.has(LINKSET_MODIFIABLE_FIELD)); llassert(pLinksetData.get(LINKSET_MODIFIABLE_FIELD).isBoolean()); mIsModifiable = pLinksetData.get(LINKSET_MODIFIABLE_FIELD).asBoolean(); + + mHasIsScripted = pLinksetData.has(LINKSET_IS_SCRIPTED_FIELD); + if (mHasIsScripted) + { + llassert(pLinksetData.get(LINKSET_IS_SCRIPTED_FIELD).isBoolean()); + mIsScripted = pLinksetData.get(LINKSET_IS_SCRIPTED_FIELD).asBoolean(); + } } void LLPathfindingLinkset::parsePathfindingData(const LLSD &pLinksetData) diff --git a/indra/newview/llpathfindinglinkset.h b/indra/newview/llpathfindinglinkset.h index 73b4d6bad..308a3a1e0 100644 --- a/indra/newview/llpathfindinglinkset.h +++ b/indra/newview/llpathfindinglinkset.h @@ -63,12 +63,16 @@ public: inline ELinksetUse getLinksetUse() const {return mLinksetUse;}; + inline BOOL isScripted() const {return mIsScripted;}; + inline BOOL hasIsScripted() const {return mHasIsScripted;}; + inline S32 getWalkabilityCoefficientA() const {return mWalkabilityCoefficientA;}; inline S32 getWalkabilityCoefficientB() const {return mWalkabilityCoefficientB;}; inline S32 getWalkabilityCoefficientC() const {return mWalkabilityCoefficientC;}; inline S32 getWalkabilityCoefficientD() const {return mWalkabilityCoefficientD;}; bool isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const; + bool isShowPhantomToggleWarning(ELinksetUse pLinksetUse) const; bool isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const; LLSD encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; @@ -98,6 +102,8 @@ private: U32 mLandImpact; BOOL mIsModifiable; BOOL mCanBeVolume; + BOOL mIsScripted; + BOOL mHasIsScripted; ELinksetUse mLinksetUse; S32 mWalkabilityCoefficientA; S32 mWalkabilityCoefficientB; diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp index 746fa342a..b886e4676 100644 --- a/indra/newview/llpathfindinglinksetlist.cpp +++ b/indra/newview/llpathfindinglinksetlist.cpp @@ -113,6 +113,20 @@ bool LLPathfindingLinksetList::isShowUnmodifiablePhantomWarning(LLPathfindingLin return isShowWarning; } +bool LLPathfindingLinksetList::isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + bool isShowWarning = false; + + for (const_iterator objectIter = begin(); !isShowWarning && (objectIter != end()); ++objectIter) + { + const LLPathfindingObjectPtr objectPtr = objectIter->second; + const LLPathfindingLinkset *linkset = dynamic_cast(objectPtr.get()); + isShowWarning = linkset->isShowPhantomToggleWarning(pLinksetUse); + } + + return isShowWarning; +} + bool LLPathfindingLinksetList::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const { bool isShowWarning = false; diff --git a/indra/newview/llpathfindinglinksetlist.h b/indra/newview/llpathfindinglinksetlist.h index 77c635864..1d38e4c11 100644 --- a/indra/newview/llpathfindinglinksetlist.h +++ b/indra/newview/llpathfindinglinksetlist.h @@ -43,6 +43,7 @@ public: LLSD encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; bool isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + bool isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; bool isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; void determinePossibleStates(BOOL &pCanBeWalkable, BOOL &pCanBeStaticObstacle, BOOL &pCanBeDynamicObstacle, diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp index 4f23117cc..274180174 100644 --- a/indra/newview/llpathfindingmanager.cpp +++ b/indra/newview/llpathfindingmanager.cpp @@ -116,9 +116,10 @@ public: NavMeshStatusResponder(const std::string &pCapabilityURL, LLViewerRegion *pRegion, bool pIsGetStatusOnly); virtual ~NavMeshStatusResponder(); - virtual void result(const LLSD &pContent); - virtual void error(U32 pStatus, const std::string& pReason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return navMeshStatusResponder_timeout; } + /*virtual*/ void result(const LLSD &pContent); + /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return navMeshStatusResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "NavMeshStatusResponder"; } protected: @@ -139,9 +140,10 @@ public: NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr); virtual ~NavMeshResponder(); - virtual void result(const LLSD &pContent); - virtual void error(U32 pStatus, const std::string& pReason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return navMeshResponder_timeout; } + /*virtual*/ void result(const LLSD &pContent); + /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return navMeshResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "NavMeshResponder"; } protected: @@ -161,9 +163,10 @@ public: AgentStateResponder(const std::string &pCapabilityURL); virtual ~AgentStateResponder(); - virtual void result(const LLSD &pContent); - virtual void error(U32 pStatus, const std::string& pReason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return agentStateResponder_timeout; } + /*virtual*/ void result(const LLSD &pContent); + /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return agentStateResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "AgentStateResponder"; } protected: @@ -181,9 +184,10 @@ public: NavMeshRebakeResponder(const std::string &pCapabilityURL, LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback); virtual ~NavMeshRebakeResponder(); - virtual void result(const LLSD &pContent); - virtual void error(U32 pStatus, const std::string& pReason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return navMeshRebakeResponder_timeout; } + /*virtual*/ void result(const LLSD &pContent); + /*virtual*/ void error(U32 pStatus, const std::string& pReason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return navMeshRebakeResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "NavMeshRebakeResponder"; } protected: @@ -241,9 +245,10 @@ public: ObjectLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr); virtual ~ObjectLinksetsResponder(); - virtual void result(const LLSD &pContent); - virtual void error(U32 pStatus, const std::string &pReason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return objectLinksetsResponder_timeout; } + /*virtual*/ void result(const LLSD &pContent); + /*virtual*/ void error(U32 pStatus, const std::string &pReason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return objectLinksetsResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "ObjectLinksetsResponder"; } protected: @@ -261,9 +266,10 @@ public: TerrainLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr); virtual ~TerrainLinksetsResponder(); - virtual void result(const LLSD &pContent); - virtual void error(U32 pStatus, const std::string &pReason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return terrainLinksetsResponder_timeout; } + /*virtual*/ void result(const LLSD &pContent); + /*virtual*/ void error(U32 pStatus, const std::string &pReason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return terrainLinksetsResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "TerrainLinksetsResponder"; } protected: @@ -281,9 +287,10 @@ public: CharactersResponder(const std::string &pCapabilityURL, LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback); virtual ~CharactersResponder(); - virtual void result(const LLSD &pContent); - virtual void error(U32 pStatus, const std::string &pReason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return charactersResponder_timeout; } + /*virtual*/ void result(const LLSD &pContent); + /*virtual*/ void error(U32 pStatus, const std::string &pReason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return charactersResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "CharactersResponder"; } protected: diff --git a/indra/newview/llpathfindingobject.cpp b/indra/newview/llpathfindingobject.cpp index 916eceb4c..858d3203c 100644 --- a/indra/newview/llpathfindingobject.cpp +++ b/indra/newview/llpathfindingobject.cpp @@ -55,8 +55,10 @@ LLPathfindingObject::LLPathfindingObject() mOwnerUUID(), mHasOwnerName(false), mOwnerName(), + mAvatarNameCacheConnection(), mIsGroupOwned(false), - mLocation() + mLocation(), + mOwnerNameSignal() { } @@ -67,8 +69,10 @@ LLPathfindingObject::LLPathfindingObject(const std::string &pUUID, const LLSD &p mOwnerUUID(), mHasOwnerName(false), mOwnerName(), + mAvatarNameCacheConnection(), mIsGroupOwned(false), - mLocation() + mLocation(), + mOwnerNameSignal() { parseObjectData(pObjectData); } @@ -80,14 +84,17 @@ LLPathfindingObject::LLPathfindingObject(const LLPathfindingObject& pOther) mOwnerUUID(pOther.mOwnerUUID), mHasOwnerName(false), mOwnerName(), + mAvatarNameCacheConnection(), mIsGroupOwned(pOther.mIsGroupOwned), - mLocation(pOther.mLocation) + mLocation(pOther.mLocation), + mOwnerNameSignal() { fetchOwnerName(); } LLPathfindingObject::~LLPathfindingObject() { + disconnectAvatarNameCacheConnection(); } LLPathfindingObject &LLPathfindingObject::operator =(const LLPathfindingObject& pOther) @@ -115,6 +122,23 @@ std::string LLPathfindingObject::getOwnerName() const return ownerName; } +LLPathfindingObject::name_connection_t LLPathfindingObject::registerOwnerNameListener(name_callback_t pOwnerNameCallback) +{ + llassert(hasOwner()); + + name_connection_t connection; + if (hasOwnerName()) + { + pOwnerNameCallback(this); + } + else + { + connection = mOwnerNameSignal.connect(pOwnerNameCallback); + } + + return connection; +} + void LLPathfindingObject::parseObjectData(const LLSD &pObjectData) { llassert(pObjectData.has(PATHFINDING_OBJECT_NAME_FIELD)); @@ -149,7 +173,7 @@ void LLPathfindingObject::fetchOwnerName() mHasOwnerName = LLAvatarNameCache::get(mOwnerUUID, &mOwnerName); if (!mHasOwnerName) { - LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2)); + mAvatarNameCacheConnection = LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2)); } } } @@ -157,6 +181,19 @@ void LLPathfindingObject::fetchOwnerName() void LLPathfindingObject::handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName) { llassert(mOwnerUUID == pOwnerUUID); + mOwnerName = pAvatarName; mHasOwnerName = true; + + disconnectAvatarNameCacheConnection(); + + mOwnerNameSignal(this); +} + +void LLPathfindingObject::disconnectAvatarNameCacheConnection() +{ + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } diff --git a/indra/newview/llpathfindingobject.h b/indra/newview/llpathfindingobject.h index d45cc554f..b8d3ca236 100644 --- a/indra/newview/llpathfindingobject.h +++ b/indra/newview/llpathfindingobject.h @@ -30,8 +30,11 @@ #include #include +#include +#include #include "llavatarname.h" +#include "llavatarnamecache.h" #include "lluuid.h" #include "v3math.h" @@ -59,6 +62,12 @@ public: inline BOOL isGroupOwned() const {return mIsGroupOwned;}; inline const LLVector3& getLocation() const {return mLocation;}; + typedef boost::function name_callback_t; + typedef boost::signals2::signal name_signal_t; + typedef boost::signals2::connection name_connection_t; + + name_connection_t registerOwnerNameListener(name_callback_t pOwnerNameCallback); + protected: private: @@ -66,15 +75,18 @@ private: void fetchOwnerName(); void handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName); + void disconnectAvatarNameCacheConnection(); - LLUUID mUUID; - std::string mName; - std::string mDescription; - LLUUID mOwnerUUID; - bool mHasOwnerName; - LLAvatarName mOwnerName; - BOOL mIsGroupOwned; - LLVector3 mLocation; + LLUUID mUUID; + std::string mName; + std::string mDescription; + LLUUID mOwnerUUID; + bool mHasOwnerName; + LLAvatarName mOwnerName; + LLAvatarNameCache::callback_connection_t mAvatarNameCacheConnection; + BOOL mIsGroupOwned; + LLVector3 mLocation; + name_signal_t mOwnerNameSignal; }; #endif // LL_LLPATHFINDINGOBJECT_H diff --git a/indra/newview/llpathfindingobjectlist.cpp b/indra/newview/llpathfindingobjectlist.cpp index 68a7e736e..f1ecb45fc 100644 --- a/indra/newview/llpathfindingobjectlist.cpp +++ b/indra/newview/llpathfindingobjectlist.cpp @@ -45,6 +45,7 @@ LLPathfindingObjectList::LLPathfindingObjectList() LLPathfindingObjectList::~LLPathfindingObjectList() { + clear(); } bool LLPathfindingObjectList::isEmpty() const @@ -52,6 +53,15 @@ bool LLPathfindingObjectList::isEmpty() const return mObjectMap.empty(); } +void LLPathfindingObjectList::clear() +{ + for (LLPathfindingObjectMap::iterator objectIter = mObjectMap.begin(); objectIter != mObjectMap.end(); ++objectIter) + { + objectIter->second.reset(); + } + mObjectMap.clear(); +} + void LLPathfindingObjectList::update(LLPathfindingObjectPtr pUpdateObjectPtr) { if (pUpdateObjectPtr != NULL) diff --git a/indra/newview/llpathfindingobjectlist.h b/indra/newview/llpathfindingobjectlist.h index 3ad8e8b09..61580582d 100644 --- a/indra/newview/llpathfindingobjectlist.h +++ b/indra/newview/llpathfindingobjectlist.h @@ -47,6 +47,8 @@ public: bool isEmpty() const; + void clear(); + void update(LLPathfindingObjectPtr pUpdateObjectPtr); void update(LLPathfindingObjectListPtr pUpdateObjectListPtr); @@ -56,7 +58,6 @@ public: const_iterator begin() const; const_iterator end() const; - protected: LLPathfindingObjectMap &getObjectMap(); diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 1df29b37e..8d3a249fd 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -172,7 +172,7 @@ protected: } - void setParamValue(LLViewerVisualParam *param, + void setParamValue(const LLViewerVisualParam *param, const F32 new_value_local, F32 behavior_maxeffect); @@ -510,10 +510,9 @@ F32 LLPhysicsMotion::toLocal(const LLVector3 &world) F32 LLPhysicsMotion::calculateVelocity_local() { const F32 world_to_model_scale = 100.0f; - LLJoint *joint = mJointState->getJoint(); - const LLVector3 position_world = joint->getWorldPosition(); - const LLQuaternion rotation_world = joint->getWorldRotation(); - const LLVector3 last_position_world = mPosition_world; + LLJoint *joint = mJointState->getJoint(); + const LLVector3 position_world = joint->getWorldPosition(); + const LLVector3 last_position_world = mPosition_world; const LLVector3 positionchange_world = (position_world-last_position_world) * world_to_model_scale; const LLVector3 velocity_world = positionchange_world; const F32 velocity_local = toLocal(velocity_world); @@ -770,12 +769,10 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) 0, FALSE); } - for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); - iter != driver_param->mDriven.end(); - ++iter) + S32 num_driven = driver_param->getDrivenParamsCount(); + for (S32 i = 0; i < num_driven; ++i) { - LLDrivenEntry &entry = (*iter); - LLViewerVisualParam *driven_param = entry.mParam; + const LLViewerVisualParam *driven_param = driver_param->getDrivenParam(i); setParamValue(driven_param,position_new_local_clamped, behavior_maxeffect); } } @@ -855,7 +852,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) } // Range of new_value_local is assumed to be [0 , 1] normalized. -void LLPhysicsMotion::setParamValue(LLViewerVisualParam *param, +void LLPhysicsMotion::setParamValue(const LLViewerVisualParam *param, F32 new_value_normalized, F32 behavior_maxeffect) { diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index ecb260704..8349b5e03 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -120,70 +120,67 @@ struct SortItemPtrsByName // static LLPreviewGesture* LLPreviewGesture::show(const std::string& title, const LLUUID& item_id, const LLUUID& object_id, BOOL take_focus) { - LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id); - if (previewp) + LLPreviewGesture* preview = (LLPreviewGesture*)LLPreview::find(item_id); + if (preview) { - previewp->open(); /*Flawfinder: ignore*/ - if (take_focus) + preview->open(); /*Flawfinder: ignore*/ + } + else + { + preview = new LLPreviewGesture(); + + // Finish internal construction + preview->init(item_id, object_id); + + // Builds and adds to gFloaterView + LLUICtrlFactory::getInstance()->buildFloater(preview, "floater_preview_gesture.xml"); + preview->setTitle(title); + + // Move window to top-left of screen + LLMultiFloater* hostp = preview->getHost(); + if (hostp == NULL) { - previewp->setFocus(TRUE); + LLRect r = preview->getRect(); + LLRect screen = gFloaterView->getRect(); + r.setLeftTopAndSize(0, screen.getHeight(), r.getWidth(), r.getHeight()); + preview->setRect(r); + } + else + { + // re-add to host to update title + hostp->addFloater(preview, TRUE); } - return previewp; - } - LLPreviewGesture* self = new LLPreviewGesture(); + // Start speculative download of sounds and animations + const LLUUID animation_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_ANIMATION); + LLInventoryModelBackgroundFetch::instance().start(animation_folder_id); - // Finish internal construction - self->init(item_id, object_id); + const LLUUID sound_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SOUND); + LLInventoryModelBackgroundFetch::instance().start(sound_folder_id); - // Builds and adds to gFloaterView - LLUICtrlFactory::getInstance()->buildFloater(self, "floater_preview_gesture.xml"); - self->setTitle(title); - - // Move window to top-left of screen - LLMultiFloater* hostp = self->getHost(); - if (hostp == NULL) - { - LLRect r = self->getRect(); - LLRect screen = gFloaterView->getRect(); - r.setLeftTopAndSize(0, screen.getHeight(), r.getWidth(), r.getHeight()); - self->setRect(r); - } - else - { - // re-add to host to update title - hostp->addFloater(self, TRUE); - } - - // Start speculative download of sounds and animations - LLUUID animation_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_ANIMATION); - LLInventoryModelBackgroundFetch::instance().start(animation_folder_id); - - LLUUID sound_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SOUND); - LLInventoryModelBackgroundFetch::instance().start(sound_folder_id); - - // this will call refresh when we have everything. - LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem(); - if (item && !item->isFinished()) - { - LLInventoryGestureAvailable* observer; - observer = new LLInventoryGestureAvailable(); - observer->watchItem(item_id); - gInventory.addObserver(observer); - item->fetchFromServer(); - } - else - { - // not sure this is necessary. - self->refresh(); + // this will call refresh when we have everything. + LLViewerInventoryItem* item = (LLViewerInventoryItem*)preview->getItem(); + if (item && !item->isFinished()) + { + LLInventoryGestureAvailable* observer; + observer = new LLInventoryGestureAvailable(); + observer->watchItem(item_id); + gInventory.addObserver(observer); + item->fetchFromServer(); + } + else + { + // not sure this is necessary. + preview->refresh(); + } } if (take_focus) { - self->setFocus(TRUE); + preview->setFocus(TRUE); } - return self; + return preview; } void LLPreviewGesture::draw() @@ -334,7 +331,7 @@ bool LLPreviewGesture::handleSaveChangesDialog(const LLSD& notification, const L case 0: // "Yes" LLGestureMgr::instance().stopGesture(mPreviewGesture); mCloseAfterSave = TRUE; - onClickSave(this); + onClickSave(); break; case 1: // "No" @@ -403,9 +400,9 @@ BOOL LLPreviewGesture::postBuild() edit = getChild("trigger_editor"); edit->setKeystrokeCallback(onKeystrokeCommit); - edit->setCommitCallback(onCommitSetDirty); - edit->setCommitOnFocusLost(TRUE); edit->setCallbackUserData(this); + edit->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitSetDirty,this)); + edit->setCommitOnFocusLost(TRUE); edit->setIgnoreTab(TRUE); mTriggerEditor = edit; @@ -416,26 +413,24 @@ BOOL LLPreviewGesture::postBuild() edit = getChild("replace_editor"); edit->setEnabled(FALSE); edit->setKeystrokeCallback(onKeystrokeCommit); - edit->setCommitCallback(onCommitSetDirty); - edit->setCommitOnFocusLost(TRUE); edit->setCallbackUserData(this); + edit->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitSetDirty,this)); + edit->setCommitOnFocusLost(TRUE); + edit->setIgnoreTab(TRUE); mReplaceEditor = edit; combo = getChild( "modifier_combo"); - combo->setCommitCallback(onCommitSetDirty); - combo->setCallbackUserData(this); + combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitSetDirty,this)); mModifierCombo = combo; combo = getChild( "key_combo"); - combo->setCommitCallback(onCommitSetDirty); - combo->setCallbackUserData(this); + combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitSetDirty,this)); mKeyCombo = combo; list = getChild("library_list"); - list->setCommitCallback(onCommitLibrary); - list->setDoubleClickCallback(onClickAdd); - list->setCallbackUserData(this); + list->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitLibrary,this)); + list->setDoubleClickCallback(boost::bind(&LLPreviewGesture::onClickAdd,this)); mLibraryList = list; btn = getChild( "add_btn"); @@ -459,8 +454,7 @@ BOOL LLPreviewGesture::postBuild() mDeleteBtn = btn; list = getChild("step_list"); - list->setCommitCallback(onCommitStep); - list->setCallbackUserData(this); + list->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitStep,this)); mStepList = list; // Options @@ -470,42 +464,38 @@ BOOL LLPreviewGesture::postBuild() combo = getChild( "animation_list"); combo->setVisible(FALSE); - combo->setCommitCallback(onCommitAnimation); - combo->setCallbackUserData(this); + combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitAnimation,this)); mAnimationCombo = combo; LLRadioGroup* group; group = getChild("animation_trigger_type"); group->setVisible(FALSE); - group->setCommitCallback(onCommitAnimationTrigger); - group->setCallbackUserData(this); + group->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitAnimationTrigger,this)); mAnimationRadio = group; combo = getChild( "sound_list"); combo->setVisible(FALSE); - combo->setCommitCallback(onCommitSound); - combo->setCallbackUserData(this); + combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitSound,this)); mSoundCombo = combo; edit = getChild("chat_editor"); edit->setVisible(FALSE); - edit->setCommitCallback(onCommitChat); + edit->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitChat,this)); //edit->setKeystrokeCallback(onKeystrokeCommit); + //edit->setCallbackUserData(this); edit->setCommitOnFocusLost(TRUE); - edit->setCallbackUserData(this); + edit->setIgnoreTab(TRUE); mChatEditor = edit; check = getChild( "wait_anim_check"); check->setVisible(FALSE); - check->setCommitCallback(onCommitWait); - check->setCallbackUserData(this); + check->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitWait,this)); mWaitAnimCheck = check; check = getChild( "wait_time_check"); check->setVisible(FALSE); - check->setCommitCallback(onCommitWait); - check->setCallbackUserData(this); + check->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitWait,this)); mWaitTimeCheck = check; edit = getChild("wait_time_editor"); @@ -513,26 +503,24 @@ BOOL LLPreviewGesture::postBuild() edit->setVisible(FALSE); edit->setPrevalidate(LLLineEditor::prevalidateFloat); // edit->setKeystrokeCallback(onKeystrokeCommit); + //edit->setCallbackUserData(this); edit->setCommitOnFocusLost(TRUE); - edit->setCommitCallback(onCommitWaitTime); - edit->setCallbackUserData(this); + edit->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitWaitTime,this)); + edit->setIgnoreTab(TRUE); mWaitTimeEditor = edit; // Buttons at the bottom check = getChild( "active_check"); - check->setCommitCallback(onCommitActive); - check->setCallbackUserData(this); + check->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitActive,this)); mActiveCheck = check; btn = getChild( "save_btn"); btn->setClickedCallback(boost::bind(&LLPreviewGesture::onClickSave,this)); - btn->setCallbackUserData(this); mSaveBtn = btn; btn = getChild( "preview_btn"); btn->setClickedCallback(boost::bind(&LLPreviewGesture::onClickPreview,this)); - btn->setCallbackUserData(this); mPreviewBtn = btn; @@ -940,13 +928,13 @@ void LLPreviewGesture::onLoadComplete(LLVFS *vfs, LLVFile file(vfs, asset_uuid, type, LLVFile::READ); S32 size = file.getSize(); - char* buffer = new char[size+1]; - file.read((U8*)buffer, size); /*Flawfinder: ignore*/ + std::vector buffer(size+1); + file.read((U8*)&buffer[0], size); buffer[size] = '\0'; LLMultiGesture* gesture = new LLMultiGesture(); - LLDataPackerAsciiBuffer dp(buffer, size+1); + LLDataPackerAsciiBuffer dp(&buffer[0], size+1); BOOL ok = gesture->deserialize(dp); if (ok) @@ -968,9 +956,6 @@ void LLPreviewGesture::onLoadComplete(LLVFS *vfs, delete gesture; gesture = NULL; - delete [] buffer; - buffer = NULL; - self->mAssetStatus = PREVIEW_ASSET_LOADED; } else @@ -1405,47 +1390,35 @@ void LLPreviewGesture::updateLabel(LLScrollListItem* item) text_cell->setText(label); } -// static -void LLPreviewGesture::onCommitSetDirty(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitSetDirty() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } -// static -void LLPreviewGesture::onCommitLibrary(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitLibrary() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* library_item = self->mLibraryList->getFirstSelected(); + LLScrollListItem* library_item = mLibraryList->getFirstSelected(); if (library_item) { - self->mStepList->deselectAllItems(); - self->refresh(); + mStepList->deselectAllItems(); + refresh(); } } -// static -void LLPreviewGesture::onCommitStep(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitStep() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (!step_item) return; - self->mLibraryList->deselectAllItems(); - self->refresh(); + mLibraryList->deselectAllItems(); + refresh(); } - -// static -void LLPreviewGesture::onCommitAnimation(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitAnimation() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (step_item) { LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); @@ -1453,40 +1426,37 @@ void LLPreviewGesture::onCommitAnimation(LLUICtrl* ctrl, void* data) { // Assign the animation name LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - if (self->mAnimationCombo->getCurrentIndex() == 0) + if (mAnimationCombo->getCurrentIndex() == 0) { anim_step->mAnimName.clear(); anim_step->mAnimAssetID.setNull(); } else { - anim_step->mAnimName = self->mAnimationCombo->getSimple(); - anim_step->mAnimAssetID = self->mAnimationCombo->getCurrentID(); + anim_step->mAnimName = mAnimationCombo->getSimple(); + anim_step->mAnimAssetID = mAnimationCombo->getCurrentID(); } //anim_step->mFlags = 0x0; // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } } } -// static -void LLPreviewGesture::onCommitAnimationTrigger(LLUICtrl* ctrl, void *data) +void LLPreviewGesture::onCommitAnimationTrigger() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (step_item) { LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); if (step->getType() == STEP_ANIMATION) { LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - if (self->mAnimationRadio->getSelectedIndex() == 0) + if (mAnimationRadio->getSelectedIndex() == 0) { // start anim_step->mFlags &= ~ANIM_FLAG_STOP; @@ -1499,18 +1469,15 @@ void LLPreviewGesture::onCommitAnimationTrigger(LLUICtrl* ctrl, void *data) // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } } } -// static -void LLPreviewGesture::onCommitSound(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitSound() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (step_item) { LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); @@ -1518,47 +1485,41 @@ void LLPreviewGesture::onCommitSound(LLUICtrl* ctrl, void* data) { // Assign the sound name LLGestureStepSound* sound_step = (LLGestureStepSound*)step; - sound_step->mSoundName = self->mSoundCombo->getSimple(); - sound_step->mSoundAssetID = self->mSoundCombo->getCurrentID(); + sound_step->mSoundName = mSoundCombo->getSimple(); + sound_step->mSoundAssetID = mSoundCombo->getCurrentID(); sound_step->mFlags = 0x0; // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } } } -// static -void LLPreviewGesture::onCommitChat(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitChat() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (!step_item) return; LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); if (step->getType() != STEP_CHAT) return; LLGestureStepChat* chat_step = (LLGestureStepChat*)step; - chat_step->mChatText = self->mChatEditor->getText(); + chat_step->mChatText = mChatEditor->getText(); chat_step->mFlags = 0x0; // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } -// static -void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitWait() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (!step_item) return; LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); @@ -1566,42 +1527,39 @@ void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, void* data) LLGestureStepWait* wait_step = (LLGestureStepWait*)step; U32 flags = 0x0; - if (self->mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM; - if (self->mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME; + if (mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM; + if (mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME; wait_step->mFlags = flags; { LLLocale locale(LLLocale::USER_LOCALE); - F32 wait_seconds = (F32)atof(self->mWaitTimeEditor->getText().c_str()); + F32 wait_seconds = (F32)atof(mWaitTimeEditor->getText().c_str()); if (wait_seconds < 0.f) wait_seconds = 0.f; if (wait_seconds > 3600.f) wait_seconds = 3600.f; wait_step->mWaitSeconds = wait_seconds; } // Enable the input area if necessary - self->mWaitTimeEditor->setEnabled(self->mWaitTimeCheck->get()); + mWaitTimeEditor->setEnabled(mWaitTimeCheck->get()); // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } -// static -void LLPreviewGesture::onCommitWaitTime(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitWaitTime() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (!step_item) return; LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); if (step->getType() != STEP_WAIT) return; - self->mWaitTimeCheck->set(TRUE); - onCommitWait(ctrl, data); + mWaitTimeCheck->set(TRUE); + onCommitWait(); } @@ -1610,18 +1568,15 @@ void LLPreviewGesture::onKeystrokeCommit(LLLineEditor* caller, void* data) { // Just commit every keystroke - onCommitSetDirty(caller, data); + ((LLPreviewGesture*)data)->onCommitSetDirty(); } -// static -void LLPreviewGesture::onClickAdd(void* data) +void LLPreviewGesture::onClickAdd() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* library_item = self->mLibraryList->getFirstSelected(); + LLScrollListItem* library_item = mLibraryList->getFirstSelected(); if (!library_item) return; - S32 library_item_index = self->mLibraryList->getFirstSelectedIndex(); + S32 library_item_index = mLibraryList->getFirstSelectedIndex(); const LLScrollListCell* library_cell = library_item->getColumn(0); const std::string& library_text = library_cell->getValue().asString(); @@ -1632,9 +1587,9 @@ void LLPreviewGesture::onClickAdd(void* data) return; } - self->addStep( (EStepType)library_item_index ); - self->mDirty = TRUE; - self->refresh(); + addStep( (EStepType)library_item_index ); + mDirty = TRUE; + refresh(); } LLScrollListItem* LLPreviewGesture::addStep( const EStepType step_type ) @@ -1734,129 +1689,110 @@ std::string LLPreviewGesture::getLabel(std::vector labels) return result; } -// static -void LLPreviewGesture::onClickUp(void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - S32 selected_index = self->mStepList->getFirstSelectedIndex(); +void LLPreviewGesture::onClickUp() +{ + S32 selected_index = mStepList->getFirstSelectedIndex(); if (selected_index > 0) { - self->mStepList->swapWithPrevious(selected_index); - self->mDirty = TRUE; - self->refresh(); + mStepList->swapWithPrevious(selected_index); + mDirty = TRUE; + refresh(); } } -// static -void LLPreviewGesture::onClickDown(void* data) +void LLPreviewGesture::onClickDown() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - S32 selected_index = self->mStepList->getFirstSelectedIndex(); + S32 selected_index = mStepList->getFirstSelectedIndex(); if (selected_index < 0) return; - S32 count = self->mStepList->getItemCount(); + S32 count = mStepList->getItemCount(); if (selected_index < count-1) { - self->mStepList->swapWithNext(selected_index); - self->mDirty = TRUE; - self->refresh(); + mStepList->swapWithNext(selected_index); + mDirty = TRUE; + refresh(); } } -// static -void LLPreviewGesture::onClickDelete(void* data) +void LLPreviewGesture::onClickDelete() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* item = self->mStepList->getFirstSelected(); - S32 selected_index = self->mStepList->getFirstSelectedIndex(); + LLScrollListItem* item = mStepList->getFirstSelected(); + S32 selected_index = mStepList->getFirstSelectedIndex(); if (item && selected_index >= 0) { LLGestureStep* step = (LLGestureStep*)item->getUserdata(); delete step; - step = NULL; - self->mStepList->deleteSingleItem(selected_index); + mStepList->deleteSingleItem(selected_index); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } } -// static -void LLPreviewGesture::onCommitActive(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitActive() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - if (!LLGestureMgr::instance().isGestureActive(self->mItemUUID)) + if (!LLGestureMgr::instance().isGestureActive(mItemUUID)) { - LLGestureMgr::instance().activateGesture(self->mItemUUID); + LLGestureMgr::instance().activateGesture(mItemUUID); } else { - LLGestureMgr::instance().deactivateGesture(self->mItemUUID); + LLGestureMgr::instance().deactivateGesture(mItemUUID); } // Make sure the (active) label in the inventory gets updated. - LLViewerInventoryItem* item = gInventory.getItem(self->mItemUUID); + LLViewerInventoryItem* item = gInventory.getItem(mItemUUID); if (item) { gInventory.updateItem(item); gInventory.notifyObservers(); } - self->refresh(); + refresh(); } -// static -void LLPreviewGesture::onClickSave(void* data) +void LLPreviewGesture::onClickSave() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - self->saveIfNeeded(); + saveIfNeeded(); } -// static -void LLPreviewGesture::onClickPreview(void* data) +void LLPreviewGesture::onClickPreview() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - if (!self->mPreviewGesture) + if (!mPreviewGesture) { // make temporary gesture - self->mPreviewGesture = self->createGesture(); + mPreviewGesture = createGesture(); // add a callback - self->mPreviewGesture->mDoneCallback = onDonePreview; - self->mPreviewGesture->mCallbackData = self; + mPreviewGesture->mDoneCallback = boost::bind(&LLPreviewGesture::onDonePreview,this,_1); // set the button title - self->mPreviewBtn->setLabel(self->getString("stop_txt")); + mPreviewBtn->setLabel(getString("stop_txt")); // play it, and delete when done - LLGestureMgr::instance().playGesture(self->mPreviewGesture); + LLGestureMgr::instance().playGesture(mPreviewGesture); - self->refresh(); + refresh(); } else { // Will call onDonePreview() below - LLGestureMgr::instance().stopGesture(self->mPreviewGesture); + LLGestureMgr::instance().stopGesture(mPreviewGesture); - self->refresh(); + refresh(); } } // static -void LLPreviewGesture::onDonePreview(LLMultiGesture* gesture, void* data) +void LLPreviewGesture::onDonePreview(LLMultiGesture* gesture) { - LLPreviewGesture* self = (LLPreviewGesture*)data; + mPreviewBtn->setLabel(getString("preview_txt")); - self->mPreviewBtn->setLabel(self->getString("preview_txt")); + delete mPreviewGesture; + mPreviewGesture = NULL; - delete self->mPreviewGesture; - self->mPreviewGesture = NULL; - - self->refresh(); + refresh(); } diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h index 8434a46e5..d4d7228f4 100644 --- a/indra/newview/llpreviewgesture.h +++ b/indra/newview/llpreviewgesture.h @@ -116,30 +116,30 @@ protected: static std::string getLabel(std::vector labels); static void updateLabel(LLScrollListItem* item); - static void onCommitSetDirty(LLUICtrl* ctrl, void* data); - static void onCommitLibrary(LLUICtrl* ctrl, void* data); - static void onCommitStep(LLUICtrl* ctrl, void* data); - static void onCommitAnimation(LLUICtrl* ctrl, void* data); - static void onCommitSound(LLUICtrl* ctrl, void* data); - static void onCommitChat(LLUICtrl* ctrl, void* data); - static void onCommitWait(LLUICtrl* ctrl, void* data); - static void onCommitWaitTime(LLUICtrl* ctrl, void* data); + void onCommitSetDirty(); + void onCommitLibrary(); + void onCommitStep(); + void onCommitAnimation(); + void onCommitSound(); + void onCommitChat(); + void onCommitWait(); + void onCommitWaitTime(); - static void onCommitAnimationTrigger(LLUICtrl* ctrl, void *data); + void onCommitAnimationTrigger(); // Handy function to commit each keystroke static void onKeystrokeCommit(LLLineEditor* caller, void* data); - static void onClickAdd(void* data); - static void onClickUp(void* data); - static void onClickDown(void* data); - static void onClickDelete(void* data); + void onClickAdd(); + void onClickUp(); + void onClickDown(); + void onClickDelete(); - static void onCommitActive(LLUICtrl* ctrl, void* data); - static void onClickSave(void* data); - static void onClickPreview(void* data); + void onCommitActive(); + void onClickSave(); + void onClickPreview(); - static void onDonePreview(LLMultiGesture* gesture, void* data); + void onDonePreview(LLMultiGesture* gesture); virtual const char *getTitleName() const { return "Gesture"; } diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 31e686adb..0e49f95af 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -485,10 +485,7 @@ bool LLScriptEdCore::writeToFile(const std::string& filename) { llwarns << "Unable to write to " << filename << llendl; - LLSD row; - row["columns"][0]["value"] = "Error writing to local file. Is your hard drive full?"; - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - mErrorList->addElement(row); + mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemWriting")); return false; } @@ -653,15 +650,12 @@ void LLScriptEdCore::autoSave() //mAutosaveFilename = llformat("%s.lsl", asfilename.c_str()); } - FILE* fp = LLFile::fopen(mAutosaveFilename.c_str(), "wb"); + LLFILE* fp = LLFile::fopen(mAutosaveFilename.c_str(), "wb"); if(!fp) { llwarns << "Unable to write to " << mAutosaveFilename << llendl; - LLSD row; - row["columns"][0]["value"] = "Error writing to temp file. Is your hard drive full?"; - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - mErrorList->addElement(row); + mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemWriting")); return; } @@ -706,9 +700,7 @@ void LLScriptEdCore::addHelpItemToHistory(const std::string& help_string) // separate history items from full item list if (mLiveHelpHistorySize == 0) { - LLSD row; - row["columns"][0]["type"] = "separator"; - history_combo->addElement(row, ADD_TOP); + history_combo->addSeparator(ADD_TOP); } // delete all history items over history limit while(mLiveHelpHistorySize > MAX_HISTORY_COUNT - 1) @@ -1321,8 +1313,8 @@ LLPreviewLSL::LLPreviewLSL(const std::string& name, const LLRect& rect, void LLPreviewLSL::callbackLSLCompileSucceeded() { llinfos << "LSL Bytecode saved" << llendl; - mScriptEd->mErrorList->addCommentText(LLTrans::getString("CompileSuccessful")); - mScriptEd->mErrorList->addCommentText(LLTrans::getString("SaveComplete")); + mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileSuccessful")); + mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("SaveComplete")); closeIfNeeded(); } @@ -1338,6 +1330,7 @@ void LLPreviewLSL::callbackLSLCompileFailed(const LLSD& compile_errors) LLSD row; std::string error_message = line->asString(); LLStringUtil::stripNonprintable(error_message); + row["columns"][0]["column"] = "default_column"; row["columns"][0]["value"] = error_message; row["columns"][0]["font"] = "OCRA"; mScriptEd->mErrorList->addElement(row); @@ -1480,10 +1473,7 @@ void LLPreviewLSL::saveIfNeeded() { llwarns << "Unable to write to " << filename << llendl; - LLSD row; - row["columns"][0]["value"] = "Error writing to local file. Is your hard drive full?"; - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - mScriptEd->mErrorList->addElement(row); + mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemWriting")); return; } @@ -1506,9 +1496,7 @@ void LLPreviewLSL::saveIfNeeded() else { LLSD row; - row["columns"][0]["value"] = LLTrans::getString("CompileQueueProblemUploading"); - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - mScriptEd->mErrorList->addElement(row); + mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemUploading")); LLFile::remove(filename); } #if 0 //Client side compiling disabled. @@ -1622,7 +1610,6 @@ void LLPreviewLSL::uploadAssetLegacy(const std::string& filename, LLFile::remove(err_filename); LLFile::remove(dst_filename); } -#endif // static void LLPreviewLSL::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) @@ -1710,6 +1697,7 @@ void LLPreviewLSL::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_d } delete instance_uuid; } +#endif // static void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, @@ -1931,8 +1919,8 @@ void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id, bool is_script_running) { lldebugs << "LSL Bytecode saved" << llendl; - mScriptEd->mErrorList->addCommentText(LLTrans::getString("CompileSuccessful")); - mScriptEd->mErrorList->addCommentText(LLTrans::getString("SaveComplete")); + mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileSuccessful")); + mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("SaveComplete")); closeIfNeeded(); } @@ -1947,6 +1935,7 @@ void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors) LLSD row; std::string error_message = line->asString(); LLStringUtil::stripNonprintable(error_message); + row["columns"][0]["column"] = "default_column"; row["columns"][0]["value"] = error_message; row["columns"][0]["font"] = "OCRA"; mScriptEd->mErrorList->addElement(row); @@ -2389,10 +2378,7 @@ void LLLiveLSLEditor::saveIfNeeded() { llwarns << "Unable to write to " << filename << llendl; - LLSD row; - row["columns"][0]["value"] = "Error writing to local file. Is your hard drive full?"; - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - mScriptEd->mErrorList->addElement(row); + mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemWriting")); return; } std::string utf8text = mScriptEd->mEditor->getText(); @@ -2419,10 +2405,7 @@ void LLLiveLSLEditor::saveIfNeeded() } else { - LLSD row; - row["columns"][0]["value"] = LLTrans::getString("CompileQueueProblemUploading"); - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - mScriptEd->mErrorList->addElement(row); + mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemUploading")); LLFile::remove(filename); } #if 0 //Client side compiling disabled. @@ -2518,7 +2501,7 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, else { llinfos << "Compile worked!" << llendl; - mScriptEd->mErrorList->addCommentText(LLTrans::getString("CompileSuccessfulSaving")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessfulSaving")); if(gAssetStorage) { llinfos << "LLLiveLSLEditor::saveAsset " @@ -2548,7 +2531,6 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, runningCheckbox->setLabel(getString("script_running")); runningCheckbox->setEnabled(TRUE); } -#endif void LLLiveLSLEditor::onSaveTextComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) { @@ -2579,7 +2561,6 @@ void LLLiveLSLEditor::onSaveTextComplete(const LLUUID& asset_uuid, void* user_da data = NULL; } - void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) { LLLiveLSLSaveData* data = (LLLiveLSLSaveData*)user_data; @@ -2593,7 +2574,7 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use if(self) { // Tell the user that the compile worked. - self->mScriptEd->mErrorList->addCommentText(LLTrans::getString("SaveComplete")); + self->mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("SaveComplete")); // close the window if this completes both uploads self->getWindow()->decBusyCount(); self->mPendingUploads--; @@ -2627,6 +2608,7 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use LLFile::remove(dst_filename); delete data; } +#endif void LLLiveLSLEditor::open() { diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index f62a8fb5b..9b171763f 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -202,9 +202,11 @@ protected: void uploadAssetViaCaps(const std::string& url, const std::string& filename, const LLUUID& item_id); +#if 0 //Client side compiling disabled. void uploadAssetLegacy(const std::string& filename, const LLUUID& item_id, const LLTransactionID& tid); +#endif // virtual BOOL canSaveAs() const; virtual void saveAs(); @@ -218,8 +220,10 @@ protected: static void onLoadComplete(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status); +#if 0 //Client side compiling disabled. static void onSaveComplete(const LLUUID& uuid, void* user_data, S32 status, LLExtStat ext_status); static void onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status); +#endif public: static LLPreviewLSL* getInstance(const LLUUID& uuid); LLTextEditor* getEditor() { return mScriptEd->mEditor; } @@ -275,10 +279,12 @@ protected: const LLUUID& task_id, const LLUUID& item_id, BOOL is_running); +#if 0 //Client side compiling disabled. void uploadAssetLegacy(const std::string& filename, LLViewerObject* object, const LLTransactionID& tid, BOOL is_running); +#endif // virtual BOOL canSaveAs() const; virtual void saveAs(); @@ -292,8 +298,10 @@ protected: static void onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status); +#if 0 //Client side compiling disabled. static void onSaveTextComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status); static void onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status); +#endif static void onRunningCheckboxClicked(LLUICtrl*, void* userdata); static void onReset(void* userdata); diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index cfb542b2f..8536f4060 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -81,7 +81,7 @@ LLPreviewTexture::LLPreviewTexture(const std::string& name, mLastWidth(0), mAspectRatio(0.f), mImage(NULL), - mImageOldBoostLevel(LLViewerTexture::BOOST_NONE) + mImageOldBoostLevel(LLGLTexture::BOOST_NONE) { const LLInventoryItem *item = getItem(); if(item) @@ -124,8 +124,7 @@ LLPreviewTexture::LLPreviewTexture( const LLRect& rect, const std::string& title, const LLUUID& asset_id, - BOOL copy_to_inv, - BOOL copyable) + BOOL copy_to_inv) : LLPreview( name, @@ -140,7 +139,6 @@ LLPreviewTexture::LLPreviewTexture( mLoadingFullImage( FALSE ), mShowKeepDiscard(FALSE), mCopyToInv(copy_to_inv), - mIsCopyable(copyable), mLastHeight(0), mLastWidth(0), mAspectRatio(0.f), @@ -700,9 +698,9 @@ void LLPreviewTexture::onAspectRatioCommit(LLUICtrl* ctrl, void* userdata) void LLPreviewTexture::loadAsset() { - mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); mImageOldBoostLevel = mImage->getBoostLevel(); - mImage->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); + mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW); mImage->forceToSaveRawImage(0) ; mAssetStatus = PREVIEW_ASSET_LOADING; mUpdateDimensions = TRUE; diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h index bb20af473..02dc4f94e 100644 --- a/indra/newview/llpreviewtexture.h +++ b/indra/newview/llpreviewtexture.h @@ -57,8 +57,7 @@ public: const LLRect& rect, const std::string& title, const LLUUID& asset_id, - BOOL copy_to_inv = FALSE, - BOOL copyable = TRUE); + BOOL copy_to_inv = FALSE); ~LLPreviewTexture(); virtual void draw(); diff --git a/indra/newview/llproductinforequest.cpp b/indra/newview/llproductinforequest.cpp index ff9014deb..27aeea77e 100644 --- a/indra/newview/llproductinforequest.cpp +++ b/indra/newview/llproductinforequest.cpp @@ -46,19 +46,20 @@ class LLProductInfoRequestResponder : public LLHTTPClient::ResponderWithResult { public: //If we get back a normal response, handle it here - virtual void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { LLProductInfoRequestManager::instance().setSkuDescriptions(content); } //If we get back an error (not found, etc...), handle it here - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { llwarns << "LLProductInfoRequest::error(" << status << ": " << reason << ")" << llendl; } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return productInfoRequestResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return productInfoRequestResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLProductInfoRequestResponder"; } }; LLProductInfoRequestManager::LLProductInfoRequestManager() : mSkuDescriptions() diff --git a/indra/newview/llregioninfomodel.cpp b/indra/newview/llregioninfomodel.cpp index 698c4f9bb..590e24648 100644 --- a/indra/newview/llregioninfomodel.cpp +++ b/indra/newview/llregioninfomodel.cpp @@ -119,7 +119,7 @@ void LLRegionInfoModel::sendRegionTerrain(const LLUUID& invoice) const bool LLRegionInfoModel::getUseFixedSun() const { - return mRegionFlags & REGION_FLAGS_SUN_FIXED; + return ((mRegionFlags & REGION_FLAGS_SUN_FIXED) != 0); } void LLRegionInfoModel::setUseFixedSun(bool fixed) @@ -141,7 +141,6 @@ void LLRegionInfoModel::update(LLMessageSystem* msg) msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, mSimName); msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, mEstateID); msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, mParentEstateID); - msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, mRegionFlags); msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, mSimAccess); msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, mAgentLimit); msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, mObjectBonusFactor); @@ -159,6 +158,17 @@ void LLRegionInfoModel::update(LLMessageSystem* msg) msg->getF32(_PREHASH_RegionInfo, _PREHASH_SunHour, mSunHour); LL_DEBUGS("Windlight Sync") << "Got region sun hour: " << mSunHour << LL_ENDL; + if (msg->has(_PREHASH_RegionInfo3)) + { + msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, mRegionFlags); + } + else + { + U32 flags = 0; + msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags); + mRegionFlags = flags; + } + // the only reasonable way to decide if we actually have any data is to // check to see if any of these fields have nonzero sizes if (msg->getSize(_PREHASH_RegionInfo2, _PREHASH_ProductSKU) > 0 || diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h index 1fc8f3e7c..d22a0de46 100644 --- a/indra/newview/llregioninfomodel.h +++ b/indra/newview/llregioninfomodel.h @@ -29,8 +29,7 @@ class LLMessageSystem; -#include "llmemory.h" -#include +#include "llsingleton.h" /** * Contains region info, notifies interested parties of its changes. @@ -53,7 +52,7 @@ public: U8 mSimAccess; U8 mAgentLimit; - U32 mRegionFlags; + U64 mRegionFlags; U32 mEstateID; U32 mParentEstateID; diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h index abc62a10e..6d212e3e4 100644 --- a/indra/newview/llremoteparcelrequest.h +++ b/indra/newview/llremoteparcelrequest.h @@ -46,10 +46,11 @@ class LLRemoteParcelRequestResponder : public LLHTTPClient::ResponderWithResult public: LLRemoteParcelRequestResponder(LLHandle place_panel_handle); //If we get back a normal response, handle it here - virtual void result(const LLSD& content); + /*virtual*/ void result(const LLSD& content); //If we get back an error (not found, etc...), handle it here - virtual void error(U32 status, const std::string& reason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return remoteParcelRequestResponder_timeout; } + /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return remoteParcelRequestResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLRemoteParcelRequestResponder"; } protected: LLHandle mPlacePanelHandle; diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp index 7afcf82c4..c3c48cfd0 100644 --- a/indra/newview/llscrollingpanelparam.cpp +++ b/indra/newview/llscrollingpanelparam.cpp @@ -147,7 +147,7 @@ void LLScrollingPanelParam::setVisible( BOOL visible ) void LLScrollingPanelParam::draw() { - if( !mWearable || gFloaterCustomize->isMinimized() ) + if( !mWearable || !LLFloaterCustomize::instanceExists() || LLFloaterCustomize::getInstance()->isMinimized() ) { return; } @@ -269,7 +269,7 @@ void LLScrollingPanelParam::onHintHeldDown( bool max ) && new_percent < slider->getMaxValue()) { mWearable->setVisualParamWeight(param->getID(), new_weight, FALSE); - mWearable->writeToAvatar(); + mWearable->writeToAvatar(gAgentAvatarp); gAgentAvatarp->updateVisualParams(); slider->setValue( weightToPercent( new_weight ) ); @@ -308,7 +308,7 @@ void LLScrollingPanelParam::onHintMouseUp( bool max ) && new_percent < slider->getMaxValue()) { mWearable->setVisualParamWeight(param->getID(), new_weight, FALSE); - mWearable->writeToAvatar(); + mWearable->writeToAvatar(gAgentAvatarp); slider->setValue( weightToPercent( new_weight ) ); } } diff --git a/indra/newview/llscrollingpanelparambase.cpp b/indra/newview/llscrollingpanelparambase.cpp index 0a83ac44a..672153d04 100644 --- a/indra/newview/llscrollingpanelparambase.cpp +++ b/indra/newview/llscrollingpanelparambase.cpp @@ -120,7 +120,7 @@ void LLScrollingPanelParamBase::onSliderMoved(LLUICtrl* ctrl) if (current_weight != new_weight ) { mWearable->setVisualParamWeight( mParam->getID(), new_weight, FALSE); - mWearable->writeToAvatar(); + mWearable->writeToAvatar(gAgentAvatarp); gAgentAvatarp->updateVisualParams(); } } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 882b96b9c..85d42a6a0 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1593,7 +1593,10 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) // Texture picker defaults aren't inventory items // * Don't need to worry about permissions for them // * Can just apply the texture and be done with it. - objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + //objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + objectp->setTETexture(te, mImageID); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, + // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, + // which we don't want. } return true; } @@ -1756,7 +1759,10 @@ BOOL LLSelectMgr::selectionRevertTextures() } else { - object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + //object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + object->setTETexture(te, id); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, + // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, + // which we don't want. } } } @@ -4649,8 +4655,8 @@ void LLSelectMgr::packObjectName(LLSelectNode* node, void* user_data) void LLSelectMgr::packObjectDescription(LLSelectNode* node, void* user_data) { const std::string* desc = (const std::string*)user_data; - if(!desc->empty()) - { + if(desc) + { // Empty (non-null, but zero length) descriptions are OK gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); gMessageSystem->addStringFast(_PREHASH_Description, *desc); @@ -5191,7 +5197,7 @@ void LLSelectMgr::updateSilhouettes() if (!mSilhouetteImagep) { - mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", TRUE, LLViewerTexture::BOOST_UI); + mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", TRUE, LLGLTexture::BOOST_UI); } mHighlightedObjects->cleanupNodes(); @@ -5944,8 +5950,6 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color) gDebugProgram.bind(); } - static LLCachedControl mode("OutlineMode",0); - gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); @@ -6426,7 +6430,7 @@ LLBBox LLSelectMgr::getBBoxOfSelection() const //----------------------------------------------------------------------------- BOOL LLSelectMgr::canUndo() const { - return const_cast(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG + return const_cast(this)->mSelectedObjects->getFirstMoveableObject() != NULL; // HACK: casting away constness - MG } //----------------------------------------------------------------------------- @@ -6444,7 +6448,7 @@ void LLSelectMgr::undo() //----------------------------------------------------------------------------- BOOL LLSelectMgr::canRedo() const { - return const_cast(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG + return const_cast(this)->mSelectedObjects->getFirstMoveableObject() != NULL; // HACK: casting away constness - MG } //----------------------------------------------------------------------------- diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index dbc2a1961..2a7758bc6 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -73,6 +73,7 @@ const F32 SG_OCCLUSION_FUDGE = 0.25f; #define assert_states_valid(x) #endif +extern bool gShiftFrame; static U32 sZombieGroups = 0; U32 LLSpatialGroup::sNodeCount = 0; @@ -82,6 +83,7 @@ U32 LLSpatialGroup::sNodeCount = 0; std::set LLSpatialGroup::sPendingQueries; U32 gOctreeMaxCapacity; +U32 gOctreeReserveCapacity; BOOL LLSpatialGroup::sNoDelete = FALSE; @@ -98,7 +100,7 @@ public: protected: - std::list mAvailableName; + std::queue mAvailableName; //Use queue, because this usage is FIFO, which queue is desgined for GLuint mCurQuery; virtual GLuint allocateName() @@ -108,7 +110,7 @@ protected: if (!mAvailableName.empty()) { ret = mAvailableName.front(); - mAvailableName.pop_front(); + mAvailableName.pop(); } else { @@ -123,8 +125,8 @@ protected: #if LL_TRACK_PENDING_OCCLUSION_QUERIES LLSpatialGroup::sPendingQueries.erase(name); #endif - llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); - mAvailableName.push_back(name); + //llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); + mAvailableName.push(name); } }; @@ -412,6 +414,7 @@ void LLSpatialGroup::setVisible() void LLSpatialGroup::validate() { + ll_assert_aligned(this,64); #if LL_OCTREE_PARANOIA_CHECK sg_assert(!isState(DIRTY)); @@ -805,7 +808,10 @@ void LLSpatialGroup::shift(const LLVector4a &offset) mObjectExtents[0].add(offset); mObjectExtents[1].add(offset); - if (!mSpatialPartition->mRenderByGroup) + if (!mSpatialPartition->mRenderByGroup && + mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE && + mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && + mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) { setState(GEOM_DIRTY); gPipeline.markRebuild(this, TRUE); @@ -1075,6 +1081,8 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mLastUpdateDistance(-1.f), mLastUpdateTime(gFrameTimeSeconds) { + ll_assert_aligned(this,16); + sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -1118,6 +1126,11 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) return; } + if (gShiftFrame) + { + return; + } + #if !LL_RELEASE_FOR_DOWNLOAD if (isState(LLSpatialGroup::OBJECT_DIRTY)) { @@ -1554,7 +1567,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) // Don't cull hole/edge water, unless RenderWaterVoidCulling is set and we have the GL_ARB_depth_clamp extension. //if ((mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER && !gGLManager.mHasDepthClamp) || // earlyFail(camera, this)) - if (earlyFail(camera, this)) + if (earlyFail(camera, this)) //Returns true if camera is inside this spatial group. { LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL); setOcclusionState(LLSpatialGroup::DISCARD_QUERY); @@ -1609,9 +1622,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) llassert(shader); shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr()); - shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE, - mBounds[1][1]+SG_OCCLUSION_FUDGE, - mBounds[1][2]+SG_OCCLUSION_FUDGE); + //static LLVector4a fudge(SG_OCCLUSION_FUDGE); + static LLCachedControl vel("SHOcclusionFudge",SG_OCCLUSION_FUDGE); + LLVector4a fudge(SG_OCCLUSION_FUDGE); + static LLVector4a bounds; + bounds.setAdd(fudge,mBounds[1]); + shader->uniform3fv(LLShaderMgr::BOX_SIZE, 1, bounds.getF32ptr()); if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) { @@ -1732,6 +1748,8 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) drawablep->setSpatialGroup(NULL); } + drawablep->setSpatialGroup(NULL); + assert_octree_valid(mOctree); return TRUE; @@ -2308,12 +2326,11 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) return FALSE; } - const F32 vel = SG_OCCLUSION_FUDGE*2.f; - LLVector4a fudge; - fudge.splat(vel); + static LLCachedControl vel("SHOcclusionFudge",SG_OCCLUSION_FUDGE); + LLVector4a fudge(vel*2.f); const LLVector4a& c = group->mBounds[0]; - LLVector4a r; + static LLVector4a r; r.setAdd(group->mBounds[1], fudge); /*if (r.magVecSquared() > 1024.0*1024.0) @@ -3029,6 +3046,8 @@ void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLCo void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color, const LLColor4& line_color) { + if(mesh.mPositions.empty() || mesh.mNormals.empty()) + return; gGL.diffuseColor4fv(color.mV); LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals); LLGLEnable offset(GL_POLYGON_OFFSET_LINE); @@ -3390,6 +3409,8 @@ void renderPhysicsShapes(LLSpatialGroup* group) LLViewerObject* object = drawable->getVObj(); if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) { + gGL.pushMatrix(); + gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix); //push face vertices for terrain for (S32 i = 0; i < drawable->getNumFaces(); ++i) { @@ -3411,6 +3432,7 @@ void renderPhysicsShapes(LLSpatialGroup* group) } } } + gGL.popMatrix(); } } } @@ -3463,9 +3485,9 @@ void renderTexturePriority(LLDrawable* drawable) drawBox(center, size); /*S32 boost = imagep->getBoostLevel(); - if (boost>LLViewerTexture::BOOST_NONE) + if (boost>LLGLTexture::BOOST_NONE) { - F32 t = (F32) boost / (F32) (LLViewerTexture::BOOST_MAX_LEVEL-1); + F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1); LLVector4 col = lerp(boost_cold, boost_hot, t); LLGLEnable blend_on(GL_BLEND); gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); @@ -3812,7 +3834,7 @@ void renderAgentTarget(LLVOAvatar* avatar) { renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f)); renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f)); - renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f)); + renderCrossHairs(avatar->mRoot->getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f)); renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f)); } } @@ -3877,9 +3899,6 @@ public: return; } - LLVector4a nodeCenter = group->mBounds[0]; - LLVector4a octCenter = group->mOctreeNode->getCenter(); - group->rebuildGeom(); group->rebuildMesh(); @@ -4399,6 +4418,10 @@ public: } } + else if (avatar->isLangolier()) + { + skip_check = true; + } } if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) @@ -4489,251 +4512,27 @@ LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) return new LLVertexBuffer(type_mask, usage); } -LLCullResult::LLCullResult() -{ - mVisibleGroupsAllocated = 0; - mAlphaGroupsAllocated = 0; - mOcclusionGroupsAllocated = 0; - mDrawableGroupsAllocated = 0; - mVisibleListAllocated = 0; - mVisibleBridgeAllocated = 0; - - mVisibleGroups = NULL; - mVisibleGroupsEnd = NULL; - mAlphaGroups = NULL; - mAlphaGroupsEnd = NULL; - mOcclusionGroups = NULL; - mOcclusionGroupsEnd = NULL; - mDrawableGroups = NULL; - mDrawableGroupsEnd = NULL; - mVisibleList = NULL; - mVisibleListEnd = NULL; - mVisibleBridge = NULL; - mVisibleBridgeEnd = NULL; - - for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) - { - mRenderMap[i] = NULL; - mRenderMapEnd[i] = NULL; - mRenderMapAllocated[i] = 0; - } - - clear(); -} - -void LLCullResult::pushBack(void**& head, U32& count, void* val) -{ - count++; - head = (void**) realloc((void*) head, sizeof(void*) * count); - head[count-1] = val; -} void LLCullResult::clear() { - mVisibleGroupsSize = 0; - mVisibleGroupsEnd = mVisibleGroups; - - mAlphaGroupsSize = 0; - mAlphaGroupsEnd = mAlphaGroups; - - mOcclusionGroupsSize = 0; - mOcclusionGroupsEnd = mOcclusionGroups; - - mDrawableGroupsSize = 0; - mDrawableGroupsEnd = mDrawableGroups; - - mVisibleListSize = 0; - mVisibleListEnd = mVisibleList; - - mVisibleBridgeSize = 0; - mVisibleBridgeEnd = mVisibleBridge; - + mVisibleGroups.clear(); + mAlphaGroups.clear(); + mOcclusionGroups.clear(); + mDrawableGroups.clear(); + mVisibleList.clear(); + mVisibleBridge.clear(); for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) { - for (U32 j = 0; j < mRenderMapSize[i]; j++) - { - mRenderMap[i][j] = 0; - } - mRenderMapSize[i] = 0; - mRenderMapEnd[i] = mRenderMap[i]; + mRenderMap[i].clear(); } } -LLCullResult::sg_iterator LLCullResult::beginVisibleGroups() -{ - return mVisibleGroups; -} - -LLCullResult::sg_iterator LLCullResult::endVisibleGroups() -{ - return mVisibleGroupsEnd; -} - -LLCullResult::sg_iterator LLCullResult::beginAlphaGroups() -{ - return mAlphaGroups; -} - -LLCullResult::sg_iterator LLCullResult::endAlphaGroups() -{ - return mAlphaGroupsEnd; -} - -LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups() -{ - return mOcclusionGroups; -} - -LLCullResult::sg_iterator LLCullResult::endOcclusionGroups() -{ - return mOcclusionGroupsEnd; -} - -LLCullResult::sg_iterator LLCullResult::beginDrawableGroups() -{ - return mDrawableGroups; -} - -LLCullResult::sg_iterator LLCullResult::endDrawableGroups() -{ - return mDrawableGroupsEnd; -} - -LLCullResult::drawable_iterator LLCullResult::beginVisibleList() -{ - return mVisibleList; -} - -LLCullResult::drawable_iterator LLCullResult::endVisibleList() -{ - return mVisibleListEnd; -} - -LLCullResult::bridge_iterator LLCullResult::beginVisibleBridge() -{ - return mVisibleBridge; -} - -LLCullResult::bridge_iterator LLCullResult::endVisibleBridge() -{ - return mVisibleBridgeEnd; -} - -LLCullResult::drawinfo_iterator LLCullResult::beginRenderMap(U32 type) -{ - return mRenderMap[type]; -} - -LLCullResult::drawinfo_iterator LLCullResult::endRenderMap(U32 type) -{ - return mRenderMapEnd[type]; -} - -void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) -{ - if (mVisibleGroupsSize < mVisibleGroupsAllocated) - { - mVisibleGroups[mVisibleGroupsSize] = group; - } - else - { - pushBack((void**&) mVisibleGroups, mVisibleGroupsAllocated, (void*) group); - } - ++mVisibleGroupsSize; - mVisibleGroupsEnd = mVisibleGroups+mVisibleGroupsSize; -} - -void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) -{ - if (mAlphaGroupsSize < mAlphaGroupsAllocated) - { - mAlphaGroups[mAlphaGroupsSize] = group; - } - else - { - pushBack((void**&) mAlphaGroups, mAlphaGroupsAllocated, (void*) group); - } - ++mAlphaGroupsSize; - mAlphaGroupsEnd = mAlphaGroups+mAlphaGroupsSize; -} - -void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) -{ - if (mOcclusionGroupsSize < mOcclusionGroupsAllocated) - { - mOcclusionGroups[mOcclusionGroupsSize] = group; - } - else - { - pushBack((void**&) mOcclusionGroups, mOcclusionGroupsAllocated, (void*) group); - } - ++mOcclusionGroupsSize; - mOcclusionGroupsEnd = mOcclusionGroups+mOcclusionGroupsSize; -} - -void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) -{ - if (mDrawableGroupsSize < mDrawableGroupsAllocated) - { - mDrawableGroups[mDrawableGroupsSize] = group; - } - else - { - pushBack((void**&) mDrawableGroups, mDrawableGroupsAllocated, (void*) group); - } - ++mDrawableGroupsSize; - mDrawableGroupsEnd = mDrawableGroups+mDrawableGroupsSize; -} - -void LLCullResult::pushDrawable(LLDrawable* drawable) -{ - if (mVisibleListSize < mVisibleListAllocated) - { - mVisibleList[mVisibleListSize] = drawable; - } - else - { - pushBack((void**&) mVisibleList, mVisibleListAllocated, (void*) drawable); - } - ++mVisibleListSize; - mVisibleListEnd = mVisibleList+mVisibleListSize; -} - -void LLCullResult::pushBridge(LLSpatialBridge* bridge) -{ - if (mVisibleBridgeSize < mVisibleBridgeAllocated) - { - mVisibleBridge[mVisibleBridgeSize] = bridge; - } - else - { - pushBack((void**&) mVisibleBridge, mVisibleBridgeAllocated, (void*) bridge); - } - ++mVisibleBridgeSize; - mVisibleBridgeEnd = mVisibleBridge+mVisibleBridgeSize; -} - -void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) -{ - if (mRenderMapSize[type] < mRenderMapAllocated[type]) - { - mRenderMap[type][mRenderMapSize[type]] = draw_info; - } - else - { - pushBack((void**&) mRenderMap[type], mRenderMapAllocated[type], (void*) draw_info); - } - ++mRenderMapSize[type]; - mRenderMapEnd[type] = mRenderMap[type] + mRenderMapSize[type]; -} - - void LLCullResult::assertDrawMapsEmpty() { for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) { - if (mRenderMapSize[i] != 0) + if (hasRenderMap(i)) { llerrs << "Stale LLDrawInfo's in LLCullResult!" << llendl; } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index e6b018087..9a00bc1e6 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -73,6 +73,16 @@ protected: ~LLDrawInfo(); public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLDrawInfo(const LLDrawInfo& rhs) { @@ -111,7 +121,7 @@ public: F32 mPartSize; F32 mVSize; LLSpatialGroup* mGroup; - LLFace* mFace; //associated face + LL_ALIGN_16(LLFace* mFace); //associated face F32 mDistance; U32 mDrawMode; @@ -186,7 +196,7 @@ public: }; }; -LL_ALIGN_PREFIX(64) +LL_ALIGN_PREFIX(16) class LLSpatialGroup : public LLOctreeListener { friend class LLSpatialPartition; @@ -198,6 +208,16 @@ public: *this = rhs; } + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + const LLSpatialGroup& operator=(const LLSpatialGroup& rhs) { llerrs << "Illegal operation!" << llendl; @@ -332,9 +352,10 @@ public: void dirtyMesh() { setState(MESH_DIRTY); } //octree wrappers to make code more readable - //element_list& getData() { return mOctreeNode->getData(); } + //element_list& getData() { return mOctreeNode->getData(); } //unused element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } + bool hasElement(LLDrawable* drawablep) { return std::find(mOctreeNode->getDataBegin(), mOctreeNode->getDataEnd(), drawablep) != mOctreeNode->getDataEnd(); } U32 getElementCount() const { return mOctreeNode->getElementCount(); } bool isEmpty() const { return mOctreeNode->isEmpty(); } @@ -359,12 +380,12 @@ public: V4_COUNT = 10 } eV4Index; - LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector4a mExtents[2]; // extents (min, max) of this node and all its children - LLVector4a mObjectExtents[2]; // extents (min, max) of objects in this node - LLVector4a mObjectBounds[2]; // bounding box (center, size) of objects in this node - LLVector4a mViewAngle; - LLVector4a mLastUpdateViewAngle; + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node + LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node + LL_ALIGN_16(LLVector4a mViewAngle); + LL_ALIGN_16(LLVector4a mLastUpdateViewAngle); F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3() @@ -525,95 +546,63 @@ public: class LLCullResult { public: - LLCullResult(); + LLCullResult() {} - typedef LLSpatialGroup** sg_list_t; - typedef LLDrawable** drawable_list_t; - typedef LLSpatialBridge** bridge_list_t; - typedef LLDrawInfo** drawinfo_list_t; + typedef std::vector sg_list_t; + typedef std::vector drawable_list_t; + typedef std::vector bridge_list_t; + typedef std::vector drawinfo_list_t; - typedef LLSpatialGroup** sg_iterator; - typedef LLSpatialBridge** bridge_iterator; - typedef LLDrawInfo** drawinfo_iterator; - typedef LLDrawable** drawable_iterator; + typedef sg_list_t::const_iterator sg_iterator; + typedef bridge_list_t::const_iterator bridge_iterator; + typedef drawinfo_list_t::const_iterator drawinfo_iterator; + typedef drawable_list_t::const_iterator drawable_iterator; void clear(); - sg_iterator beginVisibleGroups(); - sg_iterator endVisibleGroups(); + const sg_iterator beginVisibleGroups() const { return mVisibleGroups.begin(); } + const sg_iterator endVisibleGroups() const { return mVisibleGroups.end(); } - sg_iterator beginAlphaGroups(); - sg_iterator endAlphaGroups(); + const sg_iterator beginAlphaGroups() const { return mAlphaGroups.begin(); } + const sg_iterator endAlphaGroups() const { return mAlphaGroups.end(); } + const sg_list_t::iterator beginAlphaGroups() { return mAlphaGroups.begin(); } + const sg_list_t::iterator endAlphaGroups() { return mAlphaGroups.end(); } - bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; } - sg_iterator beginOcclusionGroups(); - sg_iterator endOcclusionGroups(); + bool hasOcclusionGroups() const { return !mOcclusionGroups.empty(); } + const sg_iterator beginOcclusionGroups() const { return mOcclusionGroups.begin(); } + const sg_iterator endOcclusionGroups() const { return mOcclusionGroups.end(); } - sg_iterator beginDrawableGroups(); - sg_iterator endDrawableGroups(); + const sg_iterator beginDrawableGroups() const { return mDrawableGroups.begin(); } + const sg_iterator endDrawableGroups() const { return mDrawableGroups.end(); } - drawable_iterator beginVisibleList(); - drawable_iterator endVisibleList(); + const drawable_iterator beginVisibleList() const { return mVisibleList.begin(); } + const drawable_iterator endVisibleList() const { return mVisibleList.end(); } - bridge_iterator beginVisibleBridge(); - bridge_iterator endVisibleBridge(); + const bridge_iterator beginVisibleBridge() const { return mVisibleBridge.begin(); } + const bridge_iterator endVisibleBridge() const { return mVisibleBridge.end(); } - drawinfo_iterator beginRenderMap(U32 type); - drawinfo_iterator endRenderMap(U32 type); + bool hasRenderMap(U32 type) const { return !mRenderMap[type].empty(); } + const drawinfo_iterator beginRenderMap(U32 type)const { return mRenderMap[type].begin(); } + const drawinfo_iterator endRenderMap(U32 type) const { return mRenderMap[type].end(); } - void pushVisibleGroup(LLSpatialGroup* group); - void pushAlphaGroup(LLSpatialGroup* group); - void pushOcclusionGroup(LLSpatialGroup* group); - void pushDrawableGroup(LLSpatialGroup* group); - void pushDrawable(LLDrawable* drawable); - void pushBridge(LLSpatialBridge* bridge); - void pushDrawInfo(U32 type, LLDrawInfo* draw_info); - - U32 getVisibleGroupsSize() { return mVisibleGroupsSize; } - U32 getAlphaGroupsSize() { return mAlphaGroupsSize; } - U32 getDrawableGroupsSize() { return mDrawableGroupsSize; } - U32 getVisibleListSize() { return mVisibleListSize; } - U32 getVisibleBridgeSize() { return mVisibleBridgeSize; } - U32 getRenderMapSize(U32 type) { return mRenderMapSize[type]; } + void pushVisibleGroup(LLSpatialGroup* group) { mVisibleGroups.push_back(group); } + void pushAlphaGroup(LLSpatialGroup* group) { mAlphaGroups.push_back(group); } + void pushOcclusionGroup(LLSpatialGroup* group) { mOcclusionGroups.push_back(group); } + void pushDrawableGroup(LLSpatialGroup* group) { mDrawableGroups.push_back(group); } + void pushDrawable(LLDrawable* drawable) { mVisibleList.push_back(drawable); } + void pushBridge(LLSpatialBridge* bridge) { mVisibleBridge.push_back(bridge); } + void pushDrawInfo(U32 type, LLDrawInfo* draw_info) { mRenderMap[type].push_back(draw_info); } void assertDrawMapsEmpty(); private: - - void pushBack(void** &head, U32& count, void* val); - - U32 mVisibleGroupsSize; - U32 mAlphaGroupsSize; - U32 mOcclusionGroupsSize; - U32 mDrawableGroupsSize; - U32 mVisibleListSize; - U32 mVisibleBridgeSize; - - U32 mVisibleGroupsAllocated; - U32 mAlphaGroupsAllocated; - U32 mOcclusionGroupsAllocated; - U32 mDrawableGroupsAllocated; - U32 mVisibleListAllocated; - U32 mVisibleBridgeAllocated; - - U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES]; - sg_list_t mVisibleGroups; - sg_iterator mVisibleGroupsEnd; sg_list_t mAlphaGroups; - sg_iterator mAlphaGroupsEnd; sg_list_t mOcclusionGroups; - sg_iterator mOcclusionGroupsEnd; sg_list_t mDrawableGroups; - sg_iterator mDrawableGroupsEnd; drawable_list_t mVisibleList; - drawable_iterator mVisibleListEnd; bridge_list_t mVisibleBridge; - bridge_iterator mVisibleBridgeEnd; drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; - U32 mRenderMapAllocated[LLRenderPass::NUM_RENDER_TYPES]; - drawinfo_iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES]; - }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 21f4738f8..521c5e4f0 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -191,6 +191,7 @@ #include "llwind.h" #include "llworld.h" #include "llworldmap.h" +#include "llworldmapmessage.h" #include "llxfermanager.h" #include "pipeline.h" #include "llappviewer.h" @@ -306,7 +307,6 @@ bool process_login_success_response(std::string &password); void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is_group) { - LLNameListCtrl::refreshAll(id, full_name); LLNameBox::refreshAll(id, full_name, is_group); LLNameEditor::refreshAll(id, full_name, is_group); @@ -757,9 +757,6 @@ bool idle_startup() // We have at least some login information on a SLURL firstname = gLoginHandler.getFirstName(); lastname = gLoginHandler.getLastName(); - // - gFullName = utf8str_tolower(firstname + " " + lastname); - // web_login_key = gLoginHandler.getWebLoginKey(); // Show the login screen if we don't have everything @@ -771,9 +768,6 @@ bool idle_startup() LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo"); firstname = cmd_line_login[0].asString(); lastname = cmd_line_login[1].asString(); - // - gFullName = utf8str_tolower(firstname + " " + lastname); - // LLMD5 pass((unsigned char*)cmd_line_login[2].asString().c_str()); char md5pass[33]; /* Flawfinder: ignore */ @@ -791,9 +785,6 @@ bool idle_startup() { firstname = gSavedSettings.getString("FirstName"); lastname = gSavedSettings.getString("LastName"); - // - gFullName = utf8str_tolower(firstname + " " + lastname); - // password = LLStartUp::loadPasswordFromDisk(); gSavedSettings.setBOOL("RememberPassword", TRUE); @@ -809,9 +800,6 @@ bool idle_startup() // a valid grid is selected firstname = gSavedSettings.getString("FirstName"); lastname = gSavedSettings.getString("LastName"); - // - gFullName = utf8str_tolower(firstname + " " + lastname); - // password = LLStartUp::loadPasswordFromDisk(); show_connect_box = true; } @@ -895,9 +883,6 @@ bool idle_startup() else { LLPanelLogin::setFields(firstname, lastname, password); - // - gFullName = utf8str_tolower(firstname + " " + lastname); - // LLPanelLogin::giveFocus(); } display_startup(); @@ -969,9 +954,6 @@ bool idle_startup() { firstname = gLoginHandler.getFirstName(); lastname = gLoginHandler.getLastName(); - // - gFullName = utf8str_tolower(firstname + " " + lastname); - // web_login_key = gLoginHandler.getWebLoginKey(); } @@ -990,15 +972,21 @@ bool idle_startup() { gSavedSettings.setString("FirstName", firstname); gSavedSettings.setString("LastName", lastname); - // - gFullName = utf8str_tolower(firstname + " " + lastname); - // if (!gSavedSettings.controlExists("RememberLogin")) gSavedSettings.declareBOOL("RememberLogin", false, "Remember login", false); gSavedSettings.setBOOL("RememberLogin", LLPanelLogin::getRememberLogin()); LL_INFOS("AppInit") << "Attempting login as: " << firstname << " " << lastname << LL_ENDL; gDebugInfo["LoginName"] = firstname + " " + lastname; } + else + { + // User tried to login on a non-SecondLife grid with an empty lastname. + LLSD subs; + subs["GRIDNAME"] = gHippoGridManager->getConnectedGrid()->getGridName(); + LLNotificationsUtil::add(firstname.empty() ? "EmptyFirstNameMessage" : "EmptyLastNameMessage", subs); + LLStartUp::setStartupState(STATE_LOGIN_SHOW); + return FALSE; + } LLScriptEdCore::parseFunctions("lsl_functions_sl.xml"); //Singu Note: This parsing function essentially replaces the entirety of the lscript_library library @@ -1076,7 +1064,7 @@ bool idle_startup() gSavedSettings.getControl("_NACL_AntiSpamAmount")->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamAmountChanged, _2)); // NaCl End - //good as place as any to create user windlight directories + //good a place as any to create user windlight directories std::string user_windlight_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", "")); LLFile::mkdir(user_windlight_path_name.c_str()); @@ -1432,7 +1420,6 @@ bool idle_startup() LL_DEBUGS("AppInit") << "downloading..." << LL_ENDL; return FALSE; } - Debug(if (gCurlIo) dc::curlio.off()); // Login succeeded: restore dc::curlio to original state. LLStartUp::setStartupState( STATE_LOGIN_PROCESS_RESPONSE ); progress += 0.01f; set_startup_status(progress, LLTrans::getString("LoginProcessingResponse"), auth_message); @@ -1469,6 +1456,7 @@ bool idle_startup() { // Yay, login! successful_login = true; + Debug(if (gCurlIo) dc::curlio.off()); // Login succeeded: restore dc::curlio to original state. } else { @@ -1548,13 +1536,12 @@ bool idle_startup() } } break; - case LLUserAuth::E_COULDNT_RESOLVE_HOST: - case LLUserAuth::E_SSL_PEER_CERTIFICATE: - case LLUserAuth::E_UNHANDLED_ERROR: - case LLUserAuth::E_SSL_CACERT: - case LLUserAuth::E_SSL_CONNECT_ERROR: default: - if (LLViewerLogin::getInstance()->tryNextURI()) + { + static int http_failures = 0; + http_failures = (error == LLUserAuth::E_HTTP_SERVER_ERROR) ? http_failures + 1 : 0; + if ((error == LLUserAuth::E_HTTP_SERVER_ERROR && http_failures <= 3) || + LLViewerLogin::getInstance()->tryNextURI()) { static int login_attempt_number = 0; std::ostringstream s; @@ -1569,6 +1556,7 @@ bool idle_startup() emsg << "Unable to connect to " << gHippoGridManager->getCurrentGrid()->getGridName() << ".\n"; emsg << LLUserAuth::getInstance()->errorMessage(); } + } break; } @@ -1684,9 +1672,13 @@ bool idle_startup() display_startup(); // init the shader managers - //LLDayCycleManager::initClass(); + + LLAvatarAppearance::initClass(); display_startup(); + //LLDayCycleManager::initClass(); + //display_startup(); + // RN: don't initialize VO classes in drone mode, they are too closely tied to rendering LLViewerObject::initVOClasses(); display_startup(); @@ -3394,8 +3386,8 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("AvatarPickerReply", LLFloaterAvatarPicker::processAvatarPickerReply); msg->setHandlerFunc("MapLayerReply", LLWorldMap::processMapLayerReply); - msg->setHandlerFunc("MapBlockReply", LLWorldMap::processMapBlockReply); - msg->setHandlerFunc("MapItemReply", LLWorldMap::processMapItemReply); + msg->setHandlerFunc("MapBlockReply", LLWorldMapMessage::processMapBlockReply); + msg->setHandlerFunc("MapItemReply", LLWorldMapMessage::processMapItemReply); msg->setHandlerFunc("EventInfoReply", LLPanelEvent::processEventInfoReply); msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply); @@ -4099,9 +4091,6 @@ bool process_login_success_response(std::string& password) if(!text.empty()) lastname.assign(text); gSavedSettings.setString("FirstName", firstname); gSavedSettings.setString("LastName", lastname); - // - gFullName = utf8str_tolower(firstname + " " + lastname); - // if (gSavedSettings.getBOOL("RememberPassword")) { @@ -4281,6 +4270,18 @@ bool process_login_success_response(std::string& password) gSavedSettings.setString("MapServerURL", map_server_url); LLWorldMap::gotMapServerURL(true); } + + if(gHippoGridManager->getConnectedGrid()->isOpenSimulator()) + { + std::string web_profile_url = response["web_profile_url"]; + if(!web_profile_url.empty()) + gSavedSettings.setString("WebProfileURL", web_profile_url); + } + else if(!gHippoGridManager->getConnectedGrid()->isInProductionGrid()) + { + gSavedSettings.setString("WebProfileURL", "https://my-demo.secondlife.com/[AGENT_NAME]"); + } + // Initial outfit for the user. LLSD initial_outfit = response["initial-outfit"][0]; if(initial_outfit.size()) @@ -4325,6 +4326,13 @@ bool process_login_success_response(std::string& password) gCloudTextureID = id; } #endif + // set the location of the Agent Appearance service, from which we can request + // avatar baked textures if they are supported by the current region + std::string agent_appearance_url = response["agent_appearance_service"]; + if (!agent_appearance_url.empty()) + { + gSavedSettings.setString("AgentAppearanceServiceURL", agent_appearance_url); + } } // Override grid info with anything sent in the login response diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index f9af3a2a9..c8581aa69 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -401,8 +401,8 @@ void LLStatusBar::refresh() BOOL no_scripts = FALSE; if((region - && ((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) - || (region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS))) + && (region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS) + || region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS))) || (parcel && !parcel->getAllowOtherScripts())) { no_scripts = TRUE; @@ -725,11 +725,9 @@ void LLStatusBar::setHealth(S32 health) { if (mHealth > (health + gSavedSettings.getF32("UISndHealthReductionThreshold"))) { - LLVOAvatar *me; - - if ((me = gAgentAvatarp)) + if (isAgentAvatarValid()) { - if (me->getSex() == SEX_FEMALE) + if (gAgentAvatarp->getSex() == SEX_FEMALE) { make_ui_sound("UISndHealthReductionF"); } @@ -841,11 +839,11 @@ static void onClickSeeAV(void*) static void onClickScripts(void*) { LLViewerRegion* region = gAgent.getRegion(); - if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) + if(region && region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS)) { LLNotificationsUtil::add("ScriptsStopped"); } - else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) + else if(region && region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS)) { LLNotificationsUtil::add("ScriptsNotRunning"); } diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index de0562b7f..bd1b99911 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -2,31 +2,25 @@ * @file llsurface.cpp * @brief Implementation of LLSurface class * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,6 +42,7 @@ #include "llappviewer.h" #include "llworld.h" #include "llviewercontrol.h" +#include "llviewertexture.h" #include "llsurfacepatch.h" #include "llvosurfacepatch.h" #include "llvowater.h" @@ -61,6 +56,7 @@ #include "lldrawable.h" extern LLPipeline gPipeline; +extern bool gShiftFrame; LLColor4U MAX_WATER_COLOR(0, 48, 96, 240); @@ -351,13 +347,21 @@ void LLSurface::getNeighboringRegions( std::vector& uniqueRegio } } + +void LLSurface::getNeighboringRegionsStatus( std::vector& regions ) +{ + S32 i; + for (i = 0; i < 8; i++) + { + if ( mNeighbors[i] != NULL ) + { + regions.push_back( i ); + } + } +} + void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) { - if (gNoRender) - { - return; - } - S32 i; LLSurfacePatch *patchp, *neighbor_patchp; @@ -618,6 +622,11 @@ void LLSurface::moveZ(const S32 x, const S32 y, const F32 delta) void LLSurface::updatePatchVisibilities(LLAgent &agent) { + if (gShiftFrame) + { + return; + } + LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal()); LLSurfacePatch *patchp; diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 127bec465..a693f6943 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -2,31 +2,25 @@ * @file llsurface.h * @brief Description of LLSurface class * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -148,6 +142,7 @@ public: friend std::ostream& operator<<(std::ostream &s, const LLSurface &S); void getNeighboringRegions( std::vector& uniqueRegions ); + void getNeighboringRegionsStatus( std::vector& regions ); public: // Number of grid points on one side of a region, including +1 buffer for diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 770f6579a..3ebea883c 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -2,31 +2,25 @@ * @file llsurfacepatch.cpp * @brief LLSurfacePatch class implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -49,6 +43,7 @@ #include "lldrawpool.h" #include "noise.h" +extern bool gShiftFrame; extern U64 gFrameTime; extern LLPipeline gPipeline; @@ -224,7 +219,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid(); pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid(); pos_agent.mV[VZ] = *(mDataZ + point_offset); - *vertex = pos_agent; + *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent(); LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); LLVector3 tex_pos = rel_pos * (1.f/surface_stride); @@ -372,10 +367,13 @@ void LLSurfacePatch::updateCameraDistanceRegion(const LLVector3 &pos_region) { if (LLPipeline::sDynamicLOD) { - LLVector3 dv = pos_region; - dv -= mCenterRegion; - mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/ - llmax(LLVOSurfacePatch::sLODFactor, 0.1f); + if (!gShiftFrame) + { + LLVector3 dv = pos_region; + dv -= mCenterRegion; + mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/ + llmax(LLVOSurfacePatch::sLODFactor, 0.1f); + } } else { diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 085f01688..051c3e4c8 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -873,7 +873,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id) //static const S32 MAX_REASONABLE_FILE_SIZE = 512*1024*1024; // 512 MB -F32 LLTextureCache::sHeaderCacheVersion = 1.7f; +F32 LLTextureCache::sHeaderCacheVersion = 1.8f; U32 LLTextureCache::sCacheMaxEntries = MAX_REASONABLE_FILE_SIZE / TEXTURE_CACHE_ENTRY_SIZE; S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit const char* entries_filename = "texture.entries"; diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index c1814874d..ac6ac0227 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -24,7 +24,7 @@ * $/LicenseInfo$ */ -#ifndef LL_LLTEXTURECACHE_ +#ifndef LL_LLTEXTURECACHE_H #define LL_LLTEXTURECACHE_H #include "lldir.h" diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 18493bd7c..6c84bdddd 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -161,18 +161,19 @@ public: static void onBtnSetToDefault( void* userdata ); static void onBtnSelect( void* userdata ); static void onBtnCancel( void* userdata ); - static void onBtnPipette( void* userdata ); + void onBtnPipette( ); static void onBtnUUID( void* userdata ); //static void onBtnRevert( void* userdata ); static void onBtnWhite( void* userdata ); + static void onBtnNone( void* userdata ); static void onBtnInvisible( void* userdata ); static void onBtnAlpha( void* userdata ); static void onBtnClear( void* userdata ); - static void onSelectionChange(const std::deque &items, BOOL user_action, void* data); + void onSelectionChange(const std::deque &items, BOOL user_action); static void onShowFolders(LLUICtrl* ctrl, void* userdata); static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata); static void onSearchEdit(const std::string& search_string, void* user_data ); - static void onTextureSelect( const LLTextureEntry& te, void *data ); + void onTextureSelect( const LLTextureEntry& te ); // tag: vaa emerald local_asset_browser [begin] // static void onBtnLocal( void* userdata ); @@ -216,6 +217,7 @@ protected: BOOL mNoCopyTextureSelected; F32 mContextConeOpacity; LLSaveFolderState mSavedFolderState; + BOOL mSelectedItemPinned; LLScrollListCtrl* mLocalScrollCtrl; // tag: vaa emerald local_asset_browser }; @@ -248,83 +250,12 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mSearchEdit(NULL), mImmediateFilterPermMask(immediate_filter_perm_mask), mNonImmediateFilterPermMask(non_immediate_filter_perm_mask), - mContextConeOpacity(0.f) + mContextConeOpacity(0.f), + mSelectedItemPinned(FALSE) { + mCanApplyImmediately = can_apply_immediately; LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml"); - mTentativeLabel = getChild("Multiple"); - - mResolutionLabel = getChild("unknown"); - - - childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this); - childSetAction("Alpha", LLFloaterTexturePicker::onBtnAlpha,this); - childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this); - childSetAction("Invisible", LLFloaterTexturePicker::onBtnInvisible,this); - - // tag: vaa emerald local_asset_browser [begin] -// childSetAction("Local", LLFloaterTexturePicker::onBtnLocal, this); -// childSetAction("Server", LLFloaterTexturePicker::onBtnServer, this); - childSetAction("Add", LLFloaterTexturePicker::onBtnAdd, this); - childSetAction("Remove", LLFloaterTexturePicker::onBtnRemove, this); - childSetAction("Browser", LLFloaterTexturePicker::onBtnBrowser, this); - - mLocalScrollCtrl = getChild("local_name_list"); - mLocalScrollCtrl->setCallbackUserData(this); - mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit); - LocalAssetBrowser::UpdateTextureCtrlList( mLocalScrollCtrl ); - // tag: vaa emerald local_asset_browser [end] - - childSetCommitCallback("show_folders_check", onShowFolders, this); - childSetVisible("show_folders_check", FALSE); - - mSearchEdit = getChild("inventory search editor"); - mSearchEdit->setSearchCallback(onSearchEdit, this); - - mInventoryPanel = getChild("inventory panel"); - - if(mInventoryPanel) - { - U32 filter_types = 0x0; - filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; - filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; - - mInventoryPanel->setFilterTypes(filter_types); - //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss. - mInventoryPanel->setFilterPermMask(immediate_filter_perm_mask); - mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, _1, _2, (void*)this)); - mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - mInventoryPanel->setAllowMultiSelect(FALSE); - - // store this filter as the default one - mInventoryPanel->getRootFolder()->getFilter()->markDefault(); - - // Commented out to stop opening all folders with textures - // mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_TEXTURE); - - // don't put keyboard focus on selected item, because the selection callback - // will assume that this was user input - mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); - } - - mCanApplyImmediately = can_apply_immediately; - mNoCopyTextureSelected = FALSE; - - childSetValue("apply_immediate_check", gSavedSettings.getBOOL("ApplyTextureImmediately")); - childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this); - - if (!can_apply_immediately) - { - childSetEnabled("show_folders_check", FALSE); - } - - childSetAction("Pipette", LLFloaterTexturePicker::onBtnPipette,this); - childSetAction("ApplyUUID", LLFloaterTexturePicker::onBtnUUID,this); - childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this); - childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this); - - // update permission filter once UI is fully initialized - updateFilterPermMask(); setCanMinimize(FALSE); @@ -532,7 +463,85 @@ BOOL LLFloaterTexturePicker::postBuild() setTitle(pick + mLabel); } + mTentativeLabel = getChild("Multiple"); + mResolutionLabel = getChild("unknown"); + + + childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this); + childSetAction("None", LLFloaterTexturePicker::onBtnNone,this); + childSetAction("Alpha", LLFloaterTexturePicker::onBtnAlpha,this); + childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this); + childSetAction("Invisible", LLFloaterTexturePicker::onBtnInvisible,this); + + // tag: vaa emerald local_asset_browser [begin] +// childSetAction("Local", LLFloaterTexturePicker::onBtnLocal, this); +// childSetAction("Server", LLFloaterTexturePicker::onBtnServer, this); + childSetAction("Add", LLFloaterTexturePicker::onBtnAdd, this); + childSetAction("Remove", LLFloaterTexturePicker::onBtnRemove, this); + childSetAction("Browser", LLFloaterTexturePicker::onBtnBrowser, this); + + mLocalScrollCtrl = getChild("local_name_list"); + mLocalScrollCtrl->setCallbackUserData(this); + mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit); + LocalAssetBrowser::UpdateTextureCtrlList( mLocalScrollCtrl ); + // tag: vaa emerald local_asset_browser [end] + + childSetCommitCallback("show_folders_check", onShowFolders, this); + childSetVisible("show_folders_check", FALSE); + + mSearchEdit = getChild("inventory search editor"); + mSearchEdit->setSearchCallback(onSearchEdit, this); + + mInventoryPanel = getChild("inventory panel"); + + if(mInventoryPanel) + { + U32 filter_types = 0x0; + filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; + filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; + + mInventoryPanel->setFilterTypes(filter_types); + //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss. + mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask); + mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2)); + mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + mInventoryPanel->setAllowMultiSelect(FALSE); + + // Disable auto selecting first filtered item because it takes away + // selection from the item set by LLTextureCtrl owning this floater. + mInventoryPanel->getRootFolder()->setAutoSelectOverride(TRUE); + + // Commented out to scroll to currently selected texture. See EXT-5403. + // // store this filter as the default one + // mInventoryPanel->getRootFolder()->getFilter()->markDefault(); + + // Commented out to stop opening all folders with textures + // mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_TEXTURE); + + // don't put keyboard focus on selected item, because the selection callback + // will assume that this was user input + mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); + } + + mNoCopyTextureSelected = FALSE; + + childSetValue("apply_immediate_check", gSavedSettings.getBOOL("ApplyTextureImmediately")); + childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this); + + if (!mCanApplyImmediately) + { + childSetEnabled("show_folders_check", FALSE); + } + + getChild("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this)); + childSetAction("ApplyUUID", LLFloaterTexturePicker::onBtnUUID,this); + childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this); + childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this); + + // update permission filter once UI is fully initialized + updateFilterPermMask(); + LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1)); return TRUE; } @@ -610,11 +619,11 @@ void LLFloaterTexturePicker::draw() mTexturep = NULL; if(mImageAssetID.notNull()) { - mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES, LLViewerTexture::BOOST_PREVIEW); + mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES, LLGLTexture::BOOST_PREVIEW); } else if (!mFallbackImageName.empty()) { - mTexturep = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, MIPMAP_YES, LLViewerTexture::BOOST_PREVIEW); + mTexturep = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, MIPMAP_YES, LLGLTexture::BOOST_PREVIEW); } if (mTentativeLabel) @@ -624,6 +633,7 @@ void LLFloaterTexturePicker::draw() childSetEnabled("Default", mImageAssetID != mOwner->getDefaultImageAssetID()); childSetEnabled("Blank", mImageAssetID != mWhiteImageAssetID ); + childSetEnabled("None", mOwner->getAllowNoTexture() && !mImageAssetID.isNull() ); childSetEnabled("Invisible", mOwner->getAllowInvisibleTexture() && mImageAssetID != mInvisibleImageAssetID ); childSetEnabled("Alpha", mImageAssetID != mAlphaImageAssetID ); @@ -672,6 +682,31 @@ void LLFloaterTexturePicker::draw() // Draw X gl_draw_x(interior, LLColor4::black ); } + + if (mSelectedItemPinned) return; + + LLFolderView* folder_view = mInventoryPanel->getRootFolder(); + if (!folder_view) return; + + LLInventoryFilter* filter = folder_view->getFilter(); + if (!filter) return; + + bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() && + filter->isNotDefault(); + + // After inventory panel filter is applied we have to update + // constraint rect for the selected item because of folder view + // AutoSelectOverride set to TRUE. We force PinningSelectedItem + // flag to FALSE state and setting filter "dirty" to update + // scroll container to show selected item (see LLFolderView::doIdle()). + if (!is_filter_active && !mSelectedItemPinned) + { + folder_view->setPinningSelectedItem(mSelectedItemPinned); + folder_view->dirtyFilter(); + folder_view->arrangeFromRoot(); + + mSelectedItemPinned = TRUE; + } } } @@ -758,6 +793,13 @@ void LLFloaterTexturePicker::onBtnWhite(void* userdata) self->commitIfImmediateSet(); } +// static +void LLFloaterTexturePicker::onBtnNone(void* userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setImageID( LLUUID::null ); + self->commitIfImmediateSet(); +} // static void LLFloaterTexturePicker::onBtnInvisible(void* userdata) @@ -876,26 +918,18 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl *ctrl, void *userdata) // tag: vaa emerald local_asset_browser [end] -// static -void LLFloaterTexturePicker::onBtnPipette( void* userdata ) +void LLFloaterTexturePicker::onBtnPipette() { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - - if ( self) + BOOL pipette_active = getChild("Pipette")->getValue().asBoolean(); + pipette_active = !pipette_active; + if (pipette_active) { - BOOL pipette_active = self->childGetValue("Pipette").asBoolean(); - pipette_active = !pipette_active; - if (pipette_active) - { - LLToolPipette::getInstance()->setSelectCallback(onTextureSelect, self); - LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); - } - else - { - LLToolMgr::getInstance()->clearTransientTool(); - } + LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); + } + else + { + LLToolMgr::getInstance()->clearTransientTool(); } - } // static @@ -916,33 +950,32 @@ void LLFloaterTexturePicker::onBtnUUID( void* userdata ) } // static -void LLFloaterTexturePicker::onSelectionChange(const std::deque &items, BOOL user_action, void* data) +void LLFloaterTexturePicker::onSelectionChange(const std::deque &items, BOOL user_action) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data; if (items.size()) { LLFolderViewItem* first_item = items.front(); LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID()); - self->mNoCopyTextureSelected = FALSE; + mNoCopyTextureSelected = FALSE; if (itemp) { // if (itemp->getPermissions().getMaskOwner() & PERM_ALL) - self->childSetValue("texture_uuid", self->mImageAssetID); + childSetValue("texture_uuid", mImageAssetID); else - self->childSetValue("texture_uuid", LLUUID::null.asString()); + childSetValue("texture_uuid", LLUUID::null.asString()); // if (!itemp->getPermissions().allowCopyBy(gAgent.getID())) { - self->mNoCopyTextureSelected = TRUE; + mNoCopyTextureSelected = TRUE; } - self->mImageAssetID = itemp->getAssetUUID(); - self->mIsDirty = TRUE; + mImageAssetID = itemp->getAssetUUID(); + mIsDirty = TRUE; if (user_action) { // only commit intentional selections, not implicit ones - self->commitIfImmediateSet(); + commitIfImmediateSet(); } } } @@ -1017,32 +1050,28 @@ void LLFloaterTexturePicker::onSearchEdit(const std::string& search_string, void picker->mInventoryPanel->setFilterSubString(upper_case_search_string); } -//static -void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te, void *data ) +void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data; - - LLUUID inventory_item_id = self->findItemID(te.getID(), TRUE); - if (self && inventory_item_id.notNull()) + LLUUID inventory_item_id = findItemID(te.getID(), TRUE); + if (inventory_item_id.notNull()) { LLToolPipette::getInstance()->setResult(TRUE, ""); - self->setImageID(te.getID()); - - self->mNoCopyTextureSelected = FALSE; + setImageID(te.getID()); + mNoCopyTextureSelected = FALSE; LLInventoryItem* itemp = gInventory.getItem(inventory_item_id); if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) { // no copy texture - self->mNoCopyTextureSelected = TRUE; + mNoCopyTextureSelected = TRUE; } else { - self->childSetValue("texture_uuid", inventory_item_id.asString()); + childSetValue("texture_uuid", inventory_item_id.asString()); } - self->commitIfImmediateSet(); + commitIfImmediateSet(); } else { @@ -1506,13 +1535,13 @@ void LLTextureCtrl::draw() } else if (!mImageAssetID.isNull()) { - mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES,LLViewerTexture::BOOST_PREVIEW, LLViewerTexture::LOD_TEXTURE); + mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES,LLGLTexture::BOOST_PREVIEW, LLViewerTexture::LOD_TEXTURE); mTexturep->forceToSaveRawImage(0) ; } else if (!mFallbackImageName.empty()) { // Show fallback image. - mTexturep = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, MIPMAP_YES,LLViewerTexture::BOOST_PREVIEW, LLViewerTexture::LOD_TEXTURE); + mTexturep = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, MIPMAP_YES,LLGLTexture::BOOST_PREVIEW, LLViewerTexture::LOD_TEXTURE); } else // mImageAssetID == LLUUID::null { diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 5d4894948..1d8207238 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -312,8 +312,6 @@ public: { } - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return HTTPGetResponder_timeout; } - #if 0 //Apparently, SL never sends content-range and instead sends transfer-encoding: chunked, so disabling for now /*virtual*/ bool needsHeaders(void) const { return true; } @@ -408,11 +406,14 @@ public: } } - virtual bool followRedir() + /*virtual*/ bool followRedir() const { return mFollowRedir; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return HTTPGetResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "HTTPGetResponder"; } + private: LLTextureFetch* mFetcher; LLUUID mID; @@ -1282,7 +1283,7 @@ bool LLTextureFetchWorker::doWork(S32 param) { //NOTE: //control the number of the http requests issued for: - //1, not openning too many file descriptors at the same time; + //1, not opening too many file descriptors at the same time; //2, control the traffic of http so udp gets bandwidth. // static const LLCachedControl max_http_requests("HTTPMaxRequests", 32); @@ -2223,27 +2224,21 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) { lockQueue() ; LLTextureFetchWorker* worker = getWorkerAfterLock(id); - if (worker) - { - size_t erased_1 = mRequestMap.erase(worker->mID); - unlockQueue() ; - llassert_always(erased_1 > 0) ; - - removeFromNetworkQueue(worker, cancel); - llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; - - worker->scheduleDelete(); - } - else - { - unlockQueue() ; - } + removeRequest(worker, cancel, false); } -void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) +void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel, bool bNeedsLock) { - lockQueue() ; + if(!worker) + { + if(!bNeedsLock) + unlockQueue() ; + return; + } + if(bNeedsLock) + lockQueue() ; + size_t erased_1 = mRequestMap.erase(worker->mID); unlockQueue() ; @@ -2254,6 +2249,23 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) worker->scheduleDelete(); } +void LLTextureFetch::deleteAllRequests() +{ + while(1) + { + lockQueue(); + if(mRequestMap.empty()) + { + unlockQueue() ; + break; + } + + LLTextureFetchWorker* worker = mRequestMap.begin()->second; + + removeRequest(worker, true, false); + } +} + S32 LLTextureFetch::getNumRequests() { lockQueue() ; @@ -3096,8 +3108,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) mFetcher->decrCurlPOSTCount(); } - // virtual - void error(U32 status_num, const std::string & reason) + /*virtual*/ void error(U32 status_num, const std::string & reason) { if (mLiveSequence == mExpectedSequence) { @@ -3107,8 +3118,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) << reason << LL_ENDL; } - // virtual - void result(const LLSD & content) + /*virtual*/ void result(const LLSD & content) { if (mLiveSequence == mExpectedSequence) { @@ -3116,7 +3126,8 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) mReportingStarted = true; } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return lcl_responder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return lcl_responder_timeout; } + /*virtual*/ char const* getName(void) const { return "lcl_responder"; } private: LLTextureFetch * mFetcher; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index b0caf2619..ea72f4582 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -69,6 +69,7 @@ public: bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http); void deleteRequest(const LLUUID& id, bool cancel); + void deleteAllRequests(); bool getRequestFinished(const LLUUID& id, S32& discard_level, LLPointer& raw, LLPointer& aux); bool updateRequestPriority(const LLUUID& id, F32 priority); @@ -118,7 +119,7 @@ protected: void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); void addToHTTPQueue(const LLUUID& id); void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0); - void removeRequest(LLTextureFetchWorker* worker, bool cancel); + void removeRequest(LLTextureFetchWorker* worker, bool cancel, bool bNeedsLock = true); // Overrides from the LLThread tree bool runCondition(); diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index a524cd098..e4a407290 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -39,7 +39,7 @@ #include "llappviewer.h" #include "llselectmgr.h" -#include "lltexlayer.h" +#include "llviewertexlayer.h" #include "lltexturecache.h" #include "lltexturefetch.h" #include "llviewercontrol.h" @@ -163,7 +163,7 @@ void LLTextureBar::draw() { color = LLColor4::green4; } - else if (mImagep->getBoostLevel() > LLViewerTexture::BOOST_NONE) + else if (mImagep->getBoostLevel() > LLGLTexture::BOOST_NONE) { color = LLColor4::magenta; } @@ -417,14 +417,14 @@ void LLAvatarTexBar::draw() LLColor4 color; U32 line_num = 1; - for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); + for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin(); + baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end(); ++baked_iter) { - const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first; - const LLTexLayerSet *layerset = avatarp->debugGetLayerSet(baked_index); + const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first; + const LLViewerTexLayerSet *layerset = dynamic_cast(avatarp->debugGetLayerSet(baked_index)); if (!layerset) continue; - const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite(); + const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite(); if (!layerset_buffer) continue; LLColor4 text_color = LLColor4::white; diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index f668f5bfc..01d2e26d6 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -69,6 +69,7 @@ #include "llfloatermute.h" #include "llimpanel.h" #include "llscrolllistctrl.h" +#include "llfloatercustomize.h" // [RLVa:KB] #include "rlvhandler.h" @@ -481,7 +482,7 @@ void LLToolBar::onClickAppearance(void*) { if (gAgentWearables.areWearablesLoaded()) { - gAgentCamera.changeCameraToCustomizeAvatar(); + LLFloaterCustomize::show(); } } diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp index 7dc0860e5..c3f2593c4 100644 --- a/indra/newview/lltoolbrush.cpp +++ b/indra/newview/lltoolbrush.cpp @@ -664,7 +664,7 @@ bool LLToolBrushLand::canTerraform(LLViewerRegion* regionp) const { if (!regionp) return false; if (regionp->canManageEstate()) return true; - return !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_TERRAFORM); + return !regionp->getRegionFlag(REGION_FLAGS_BLOCK_TERRAFORM); } // static diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index d39061bb4..159717515 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1089,14 +1089,17 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, { return; } - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); + //LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); S32 num_faces = hit_obj->getNumTEs(); for( S32 face = 0; face < num_faces; face++ ) { // update viewer side image in anticipation of update from simulator - hit_obj->setTEImage(face, image); + //hit_obj->setTEImage(face, image); + hit_obj->setTETexture(face, asset_id); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, + // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, + // which we don't want. dialog_refresh_all(); } // send the update to the simulator @@ -1157,9 +1160,12 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, return; } // update viewer side image in anticipation of update from simulator - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); + //LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); - hit_obj->setTEImage(hit_face, image); + //hit_obj->setTEImage(hit_face, image); + hit_obj->setTETexture(hit_face, asset_id); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, + // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, + // which we don't want. dialog_refresh_all(); // send the update to the simulator @@ -1258,7 +1264,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, if (!item || !item->isFinished()) return; if (regionp - && (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX)) + && regionp->getRegionFlag(REGION_FLAGS_SANDBOX)) { LLFirstUse::useSandbox(); } @@ -1732,7 +1738,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( // LLPointer cb = new RezAttachmentCallback(0); // [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a // Make this behave consistent with dad3dWearItem - LLPointer cb = new RezAttachmentCallback(0, !(mask & MASK_CONTROL)); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&rez_attachment_cb, _1, (LLViewerJointAttachment*)0, !(mask & MASK_CONTROL))); // [/SL:KB] copy_inventory_item( gAgent.getID(), @@ -2137,7 +2143,7 @@ EAcceptance LLToolDragAndDrop::dad3dActivateGesture( { // create item based on that one, and put it on if that // was a success. - LLPointer cb = new ActivateGestureCallback(); + LLPointer cb = new LLBoostFuncInventoryCallback(activate_gesture_cb); copy_inventory_item( gAgent.getID(), item->getPermissions().getOwner(), diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index 5f0bf0ff6..b98b6092f 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -315,9 +315,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask) { S32 dx = gViewerWindow->getCurrentMouseDX(); S32 dy = gViewerWindow->getCurrentMouseDY(); - - BOOL moved_outside_slop = FALSE; - + if (hasMouseCapture() && mValidClickPoint) { mAccumX += llabs(dx); @@ -325,19 +323,11 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask) if (mAccumX >= SLOP_RANGE) { - if (!mOutsideSlopX) - { - moved_outside_slop = TRUE; - } mOutsideSlopX = TRUE; } if (mAccumY >= SLOP_RANGE) { - if (!mOutsideSlopY) - { - moved_outside_slop = TRUE; - } mOutsideSlopY = TRUE; } } diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index 6765f87bb..6170b7aca 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -983,8 +983,6 @@ BOOL LLToolGrab::handleMouseUp(S32 x, S32 y, MASK mask) gGrabTransientTool = NULL; } - //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); - return TRUE; } diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index efeb6bc2f..716edd7dd 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -272,7 +272,8 @@ void LLToolMgr::updateToolStatus() bool LLToolMgr::inEdit() { - return mBaseTool != LLToolPie::getInstance() && mBaseTool != gToolNull; + static const LLCachedControl freeze_time("FreezeTime",false); + return mBaseTool != LLToolPie::getInstance() && mBaseTool != gToolNull && (mCurrentToolset != gCameraToolset || !freeze_time); } bool LLToolMgr::canEdit() diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 867ec94ec..24a9a9d56 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -2,31 +2,25 @@ * @file lltoolmorph.cpp * @brief A tool to manipulate faces.. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,6 +34,7 @@ #include "llaudioengine.h" #include "llviewercontrol.h" #include "llfontgl.h" +#include "llwearable.h" #include "sound_ids.h" #include "v3math.h" #include "v3color.h" @@ -201,19 +196,19 @@ BOOL LLVisualParamHint::render() mNeedsUpdate = FALSE; mIsVisible = TRUE; - LLViewerJointMesh* cam_target_joint = NULL; + LLJoint* cam_target_joint = NULL; const std::string& cam_target_mesh_name = mVisualParam->getCameraTargetName(); if( !cam_target_mesh_name.empty() ) { - cam_target_joint = (LLViewerJointMesh*)gAgentAvatarp->getJoint( cam_target_mesh_name ); + cam_target_joint = gAgentAvatarp->getJoint( cam_target_mesh_name ); } if( !cam_target_joint ) { - cam_target_joint = (LLViewerJointMesh*)gMorphView->getCameraTargetJoint(); + cam_target_joint = gMorphView->getCameraTargetJoint();; } if( !cam_target_joint ) { - cam_target_joint = (LLViewerJointMesh*)gAgentAvatarp->getJoint("mHead"); + cam_target_joint = gAgentAvatarp->getJoint("mHead");; } LLQuaternion avatar_rotation; @@ -239,9 +234,9 @@ BOOL LLVisualParamHint::render() LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / (F32)mFullHeight); LLViewerCamera::getInstance()->setOriginAndLookAt( - camera_pos, // camera + camera_pos, // camera LLVector3::z_axis, // up - target_pos ); // point of interest + target_pos ); // point of interest LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); diff --git a/indra/newview/lltoolpipette.cpp b/indra/newview/lltoolpipette.cpp index 9d95ccc06..878ed0f9a 100644 --- a/indra/newview/lltoolpipette.cpp +++ b/indra/newview/lltoolpipette.cpp @@ -55,8 +55,6 @@ LLToolPipette::LLToolPipette() : LLTool(std::string("Pipette")), mSuccess(TRUE) { - mSelectCallback = NULL; - mUserData = NULL; } @@ -106,6 +104,15 @@ BOOL LLToolPipette::handleToolTip(S32 x, S32 y, std::string& msg, LLRect *sticky return TRUE; } +void LLToolPipette::setTextureEntry(const LLTextureEntry* entry) +{ + if (entry) + { + mTextureEntry = *entry; + mSignal(mTextureEntry); + } +} + void LLToolPipette::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); @@ -118,20 +125,11 @@ void LLToolPipette::pickCallback(const LLPickInfo& pick_info) { //TODO: this should highlight the selected face only LLSelectMgr::getInstance()->highlightObjectOnly(hit_obj); - LLToolPipette::getInstance()->mTextureEntry = *hit_obj->getTE(pick_info.mObjectFace); - if (LLToolPipette::getInstance()->mSelectCallback) - { - LLToolPipette::getInstance()->mSelectCallback(LLToolPipette::getInstance()->mTextureEntry, LLToolPipette::getInstance()->mUserData); - } + const LLTextureEntry* entry = hit_obj->getTE(pick_info.mObjectFace); + LLToolPipette::getInstance()->setTextureEntry(entry); } } -void LLToolPipette::setSelectCallback(select_callback callback, void* user_data) -{ - mSelectCallback = callback; - mUserData = user_data; -} - void LLToolPipette::setResult(BOOL success, const std::string& msg) { mTooltipMsg = msg; diff --git a/indra/newview/lltoolpipette.h b/indra/newview/lltoolpipette.h index 54c24e946..b9d53623f 100644 --- a/indra/newview/lltoolpipette.h +++ b/indra/newview/lltoolpipette.h @@ -56,18 +56,19 @@ public: virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect *sticky_rect_screen); - typedef void (*select_callback)(const LLTextureEntry& te, void *data); - void setSelectCallback(select_callback callback, void* user_data); + // Note: Don't return connection; use boost::bind + boost::signals2::trackable to disconnect slots + typedef boost::signals2::signal signal_t; + void setToolSelectCallback(const signal_t::slot_type& cb) { mSignal.connect(cb); } void setResult(BOOL success, const std::string& msg); - + + void setTextureEntry(const LLTextureEntry* entry); static void pickCallback(const LLPickInfo& pick_info); protected: LLTextureEntry mTextureEntry; - select_callback mSelectCallback; + signal_t mSignal; BOOL mSuccess; std::string mTooltipMsg; - void* mUserData; }; #endif //LL_LLTOOLPIPETTE_H diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index 9e3062db4..8d6982695 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -217,7 +217,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) return FALSE; } - if (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX) + if (regionp->getRegionFlag(REGION_FLAGS_SANDBOX)) { LLFirstUse::useSandbox(); } @@ -553,7 +553,7 @@ BOOL LLToolPlacer::addDuplicate(S32 x, S32 y) FALSE); // select copy if (regionp - && (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX)) + && regionp->getRegionFlag(REGION_FLAGS_SANDBOX)) { LLFirstUse::useSandbox(); } diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index 403113e50..39cd470f3 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -88,7 +88,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi } // [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c - if (rlv_handler_t::isEnabled()) + if ( (object) && (rlv_handler_t::isEnabled()) ) { if (!gRlvHandler.canEdit(object)) { @@ -109,7 +109,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi } } - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (object) && ((!object->isAttachment()) || (!object->permYouOwner())) && + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!object->isAttachment()) || (!object->permYouOwner())) && (dist_vec_squared(gAgent.getPositionAgent(), object->getPositionRegion()) > 1.5f * 1.5f) ) { // NOTE-RLVa: see behaviour notes for a rather lengthy explanation of why we're doing things this way diff --git a/indra/newview/lltracker.h b/indra/newview/lltracker.h index 285036527..c727c29d5 100644 --- a/indra/newview/lltracker.h +++ b/indra/newview/lltracker.h @@ -81,7 +81,7 @@ public: // 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 (BOOL) instance()->mTrackingStatus; } + static BOOL isTracking(void*) { return instance()->mTrackingStatus != TRACKING_NOTHING; } static void stopTracking(void*); static void clearFocus(); diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index 7540dd72c..769afc378 100644 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -43,7 +43,7 @@ extern AIHTTPTimeoutPolicy translationReceiver_timeout; class LLTranslate { public : - class TranslationReceiver: public LLHTTPClient::ResponderWithResult + class TranslationReceiver : public LLHTTPClient::ResponderWithResult { protected: TranslationReceiver(const std::string &fromLang, const std::string &toLang) @@ -60,15 +60,13 @@ public : { } - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { LL_WARNS("Translate") << "URL Request error: " << reason << LL_ENDL; handleFailure(); } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return translationReceiver_timeout; } - - virtual void completedRaw( + /*virtual*/ void completedRaw( U32 status, const std::string& reason, const LLChannelDescriptors& channels, @@ -100,6 +98,8 @@ public : handleResponse(translation, detectedLanguage); } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return translationReceiver_timeout; } + protected: const std::string m_toLang; const std::string m_fromLang; diff --git a/indra/newview/lluploaddialog.cpp b/indra/newview/lluploaddialog.cpp index a860e5303..a4f758ff8 100644 --- a/indra/newview/lluploaddialog.cpp +++ b/indra/newview/lluploaddialog.cpp @@ -75,7 +75,7 @@ LLUploadDialog::LLUploadDialog( const std::string& msg) } LLUploadDialog::sDialog = this; - const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF ); + const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_BIG ); LLRect msg_rect; for (int line_num=0; line_num<16; ++line_num) { @@ -91,7 +91,10 @@ LLUploadDialog::LLUploadDialog( const std::string& msg) void LLUploadDialog::setMessage( const std::string& msg) { - const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF ); + S32 const min_width = gViewerWindow->getWindowWidthRaw() / 10; + S32 const min_height = gViewerWindow->getWindowHeightRaw() / 10; + + const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_BIG ); const S32 VPAD = 16; const S32 HPAD = 25; @@ -127,14 +130,14 @@ void LLUploadDialog::setMessage( const std::string& msg) S32 line_height = S32( font->getLineHeight() + 0.99f ); - S32 dialog_width = max_msg_width + 2 * HPAD; - S32 dialog_height = line_height * msg_lines.size() + 2 * VPAD; + S32 dialog_width = llmax(max_msg_width + 2 * HPAD, min_width); + S32 dialog_height = llmax(line_height * (S32)msg_lines.size() + 2 * VPAD, min_height); reshape( dialog_width, dialog_height, FALSE ); // Message S32 msg_x = (getRect().getWidth() - max_msg_width) / 2; - S32 msg_y = getRect().getHeight() - VPAD - line_height; + S32 msg_y = (getRect().getHeight() + line_height * msg_lines.size()) / 2 - line_height; int line_num; for (line_num=0; line_num<16; ++line_num) { diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h index 85cc7b86a..0ddba6735 100644 --- a/indra/newview/lluploadfloaterobservers.h +++ b/indra/newview/lluploadfloaterobservers.h @@ -104,11 +104,10 @@ public: LLUploadModelPremissionsResponder(const LLHandle& observer); - void error(U32 status, const std::string& reason); - - void result(const LLSD& content); - - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return uploadModelPremissionsResponder_timeout; } + /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ void result(const LLSD& content); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return uploadModelPremissionsResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLUploadModelPremissionsResponder"; } private: LLHandle mObserverHandle; diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 1144c5827..a9971abbd 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -45,6 +45,7 @@ #include "llurlsimstring.h" #include "llweb.h" #include "llworldmap.h" +#include "llworldmapmessage.h" // library includes #include "llsd.h" @@ -243,7 +244,7 @@ bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mous url_displayp->setName(region_name); // Request a region handle by name - LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, LLURLDispatcherImpl::regionNameCallback, url, false); // don't teleport @@ -282,7 +283,7 @@ void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const std::strin LLVector3d global_pos = from_region_handle(region_handle) + LLVector3d(local_pos); U64 new_region_handle = to_region_handle(global_pos); - LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle, + LLWorldMapMessage::getInstance()->sendHandleRegionRequest(new_region_handle, LLURLDispatcherImpl::regionHandleCallback, url, teleport); } @@ -401,7 +402,7 @@ public: { url += tokens[i].asString() + "/"; } - LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, LLURLDispatcherImpl::regionHandleCallback, url, true); // teleport diff --git a/indra/newview/lluserauth.cpp b/indra/newview/lluserauth.cpp index a692f9575..a0791989e 100644 --- a/indra/newview/lluserauth.cpp +++ b/indra/newview/lluserauth.cpp @@ -323,7 +323,16 @@ LLUserAuth::UserAuthcode LLUserAuth::parseResponse() // will all be string => string pairs. UserAuthcode rv = E_UNHANDLED_ERROR; XMLRPC_REQUEST response = mResponder->response(); - if(!response) return rv; + if(!response) + { + U32 status = mResponder->http_status(); + // Is it an HTTP error? + if (!(200 <= status && status < 400)) + { + rv = E_HTTP_SERVER_ERROR; + } + return rv; + } // clear out any old parsing mResponses.clear(); diff --git a/indra/newview/lluserauth.h b/indra/newview/lluserauth.h index 847b1e8b5..1bc76cb84 100644 --- a/indra/newview/lluserauth.h +++ b/indra/newview/lluserauth.h @@ -88,6 +88,7 @@ public: E_SSL_PEER_CERTIFICATE, E_SSL_CACERT, E_SSL_CONNECT_ERROR, + E_HTTP_SERVER_ERROR, E_UNHANDLED_ERROR, E_LAST // never use! } UserAuthcode; diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 958f4f0e6..7df652c41 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -253,8 +253,11 @@ void audio_update_wind(bool force_update) // which is sufficient to completely turn off or turn on wind noise volume_delta = 1.f; } - // mute wind entirely when the user asked - if (gSavedSettings.getBOOL("MuteWind")) + + static LLCachedControl MuteWind("MuteWind"); + static LLCachedControl ContinueFlying("LiruContinueFlyingOnUnsit"); + // mute wind entirely when the user asked or when the user is seated, but flying + if (MuteWind || (ContinueFlying && gAgentAvatarp&& gAgentAvatarp->isSitting())) { // volume decreases by itself gAudiop->mMaxWindGain = 0.f; diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 7e3ca1883..4d357433e 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -137,9 +137,6 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, mLastPointOfInterest = point_of_interest; - // constrain to max distance from avatar - LLVector3 camera_offset = center - gAgent.getPositionAgent(); - LLViewerRegion * regp = gAgent.getRegion(); F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f; @@ -319,7 +316,7 @@ void LLViewerCamera::setPerspective(BOOL for_selection, { F32 fov_y, aspect; fov_y = RAD_TO_DEG * getView(); - BOOL z_default_near, z_default_far = FALSE; + BOOL z_default_far = FALSE; if (z_far <= 0) { z_default_far = TRUE; @@ -327,7 +324,6 @@ void LLViewerCamera::setPerspective(BOOL for_selection, } if (z_near <= 0) { - z_default_near = TRUE; z_near = getNear(); } aspect = getAspect(); diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index a4a05fca8..82d88bc3d 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -52,9 +52,20 @@ const F32 OGL_TO_CFR_ROTATION[16] = { 0.f, 0.f, -1.f, 0.f, // -Z becomes X const BOOL FOR_SELECTION = TRUE; const BOOL NOT_FOR_SELECTION = FALSE; + +LL_ALIGN_PREFIX(16) class LLViewerCamera : public LLCamera, public LLSingleton { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } typedef enum { @@ -138,6 +149,7 @@ protected: S16 mZoomSubregion; public: -}; +} LL_ALIGN_POSTFIX(16); + #endif // LL_LLVIEWERCAMERA_H diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 4e1ad8645..9a7c114f5 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -157,6 +157,43 @@ static bool handleSetShaderChanged(const LLSD& newvalue) return true; } +static bool handleRenderPerfTestChanged(const LLSD& newvalue) +{ + bool status = !newvalue.asBoolean(); + if (!status) + { + gPipeline.clearRenderTypeMask(LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_GRASS, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_PASS_GRASS, + LLPipeline::RENDER_TYPE_HUD, + LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, + LLPipeline::RENDER_TYPE_HUD_PARTICLES, + LLPipeline::END_RENDER_TYPES); + gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_FEATURE_UI, false); + } + else + { + gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_GRASS, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_PASS_GRASS, + LLPipeline::RENDER_TYPE_HUD, + LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, + LLPipeline::RENDER_TYPE_HUD_PARTICLES, + LLPipeline::END_RENDER_TYPES); + gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_FEATURE_UI, true); + } + + return true; +} + static bool handleAvatarBoobMassChanged(const LLSD& newvalue) { LLVOAvatar::sBoobConfig.mass = EmeraldBoobUtils::convertMass((F32) newvalue.asReal()); @@ -206,6 +243,11 @@ static bool handleSetSelfInvisible( const LLSD& newvalue) return true; } +bool handleRenderAvatarComplexityLimitChanged(const LLSD& newvalue) +{ + return true; +} + bool handleRenderTransparentWaterChanged(const LLSD& newvalue) { LLWorld::getInstance()->updateWaterObjects(); @@ -437,6 +479,7 @@ static bool handleRepartition(const LLSD&) if (gPipeline.isInit()) { gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); + gOctreeReserveCapacity = llmin(gSavedSettings.getU32("OctreeReserveNodeCapacity"),U32(512)); gObjectList.repartitionObjects(); } return true; @@ -638,6 +681,7 @@ void settings_setup_listeners() gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("OctreeReserveNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); @@ -659,6 +703,7 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderAvatarMaxVisible")->getSignal()->connect(boost::bind(&handleAvatarMaxVisibleChanged, _2)); gSavedSettings.getControl("RenderAvatarInvisible")->getSignal()->connect(boost::bind(&handleSetSelfInvisible, _2)); + gSavedSettings.getControl("RenderAvatarComplexityLimit")->getSignal()->connect(boost::bind(&handleRenderAvatarComplexityLimitChanged, _2)); gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2)); gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2)); gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2)); @@ -689,6 +734,7 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); + gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2)); gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2)); gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2)); gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 8c932285b..1a8129bb3 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -51,6 +51,7 @@ #include "llhudmanager.h" #include "llimagebmp.h" #include "llimagegl.h" +#include "lloctree.h" #include "llselectmgr.h" #include "llsky.h" #include "llstartup.h" @@ -90,6 +91,8 @@ #include "rlvlocks.h" // [/RLVa:KB] +extern bool gShiftFrame; + LLPointer gDisconnectedImagep = NULL; // used to toggle renderer back on after teleport @@ -185,7 +188,8 @@ void display_update_camera(bool tiling=false) // Cut draw distance in half when customizing avatar, // but on the viewer only. F32 final_far = gAgentCamera.mDrawDistance; - if(tiling) //Don't animate clouds and water if tiling! + static const LLCachedControl freeze_time("FreezeTime",false); + if(freeze_time || tiling) //Don't animate clouds and water if tiling! { LLViewerCamera::getInstance()->setFar(final_far); gViewerWindow->setup3DRender(); @@ -223,6 +227,9 @@ void display_stats() F32 fps = gRecentFrameCount / fps_log_freq; llinfos << llformat("FPS: %.02f", fps) << llendl; llinfos << llformat("VBO: %d glVBO: %d", LLVertexBuffer::sCount, LLVertexBuffer::sGLCount) << llendl; +#ifdef LL_OCTREE_STATS + OctreeStats::getInstance()->dump(); +#endif gRecentFrameCount = 0; gRecentFPSTime.reset(); } @@ -318,6 +325,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo } gViewerWindow->checkSettings(); + + if(gWindowResized) //Singu Note: gViewerWindow->checkSettings() can call LLViewerWindow::reshape(). If it has then skip this frame. + { + return; + } { LLFastTimer ftm(FTM_PICK); @@ -411,18 +423,30 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo gAgent.setTeleportMessage(std::string()); } + static const LLCachedControl hide_tp_screen("AscentDisableTeleportScreens",false); const std::string& message = gAgent.getTeleportMessage(); switch( gAgent.getTeleportState() ) { + case LLAgent::TELEPORT_PENDING: + gTeleportDisplayTimer.reset(); + if(!hide_tp_screen) + gViewerWindow->setShowProgress(TRUE); + gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); + gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["pending"]); + gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["pending"]); + break; + case LLAgent::TELEPORT_START: // Transition to REQUESTED. Viewer has sent some kind // of TeleportRequest to the source simulator gTeleportDisplayTimer.reset(); - if(!gSavedSettings.getBOOL("AscentDisableTeleportScreens"))gViewerWindow->setShowProgress(TRUE); - gViewerWindow->setProgressPercent(0); + if(!hide_tp_screen) + gViewerWindow->setShowProgress(TRUE); + gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["requesting"]); + gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["requesting"]); break; case LLAgent::TELEPORT_REQUESTED: @@ -446,14 +470,15 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); gTextureList.mForceResetTextureStats = TRUE; - if(!gSavedSettings.getBOOL("AscentDisableTeleportScreens"))gAgentCamera.resetView(TRUE, TRUE); + if(!hide_tp_screen) + gAgentCamera.resetView(TRUE, TRUE); break; case LLAgent::TELEPORT_ARRIVING: // Make the user wait while content "pre-caches" { F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY); - if( arrival_fraction > 1.f || gSavedSettings.getBOOL("AscentDisableTeleportScreens")) + if( arrival_fraction > 1.f || hide_tp_screen) { arrival_fraction = 1.f; LLFirstUse::useTeleport(); @@ -1109,6 +1134,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo display_stats(); LLAppViewer::instance()->pingMainloopTimeout("Display:Done"); + + gShiftFrame = false; } void render_hud_attachments() @@ -1144,7 +1171,7 @@ void render_hud_attachments() gPipeline.pushRenderTypeMask(); // turn off everything - gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES); + gPipeline.clearAllRenderTypes(); // turn on HUD gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); // turn on HUD particles @@ -1526,7 +1553,7 @@ void render_ui_2d() gGL.pushMatrix(); S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2); S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2); - gGL.scalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f); + gGL.scalef(LLUI::getScaleFactor().mV[0], LLUI::getScaleFactor().mV[1], 1.f); gGL.translatef((F32)half_width, (F32)half_height, 0.f); F32 zoom = gAgentCamera.mHUDCurZoom; gGL.scalef(zoom,zoom,1.f); diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp index 0c917ef4e..ea38be2cb 100644 --- a/indra/newview/llviewerdisplayname.cpp +++ b/indra/newview/llviewerdisplayname.cpp @@ -68,7 +68,8 @@ public: LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots(); } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return setDisplayNameResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return setDisplayNameResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLSetDisplayNameResponder"; } }; void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot) diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index c932de258..0063c9073 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -63,6 +63,10 @@ #include "llfloatercustomize.h" // #include "llappviewer.h" // System Folders + +// Two do-nothing ops for use in callbacks. +void no_op_inventory_func(const LLUUID&) {} +void no_op() {} // ///---------------------------------------------------------------------------- @@ -786,7 +790,10 @@ void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id) } } -void WearOnAvatarCallback::fire(const LLUUID& inv_item) +//void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp) +// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a +void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp, bool replace) +// [/SL:KB] { if (inv_item.isNull()) return; @@ -794,58 +801,14 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item) LLViewerInventoryItem *item = gInventory.getItem(inv_item); if (item) { - LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, mReplace); - } -} - -void ModifiedCOFCallback::fire(const LLUUID& inv_item) -{ - LLAppearanceMgr::instance().updateAppearanceFromCOF(); - - // Start editing the item if previously requested. - gAgentWearables.editWearableIfRequested(inv_item); - - // TODO: camera mode may not be changed if a debug setting is tweaked - if( gAgentCamera.cameraCustomizeAvatar() ) - { - // If we're in appearance editing mode, the current tab may need to be refreshed - /*LLSidepanelAppearance *panel = dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance")); - if (panel) - { - panel->showDefaultSubpart(); - }*/ - gFloaterCustomize->switchToDefaultSubpart(); - } -} - -//RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp) +// rez_attachment(item, attachmentp); // [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a -RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp, bool replace) - : mAttach(attachmentp), mReplace(replace) -// [/SL:KB] -{ -// mAttach = attachmentp; -} -RezAttachmentCallback::~RezAttachmentCallback() -{ -} - -void RezAttachmentCallback::fire(const LLUUID& inv_item) -{ - if (inv_item.isNull()) - return; - - LLViewerInventoryItem *item = gInventory.getItem(inv_item); - if (item) - { -// rez_attachment(item, mAttach); -// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a - rez_attachment(item, mAttach, mReplace); + rez_attachment(item, attachmentp, replace); // [/SL:KB] } } -void ActivateGestureCallback::fire(const LLUUID& inv_item) +void activate_gesture_cb(const LLUUID& inv_item) { if (inv_item.isNull()) return; @@ -858,7 +821,7 @@ void ActivateGestureCallback::fire(const LLUUID& inv_item) LLGestureMgr::instance().activateGesture(inv_item); } -void CreateGestureCallback::fire(const LLUUID& inv_item) +void create_gesture_cb(const LLUUID& inv_item) { if (inv_item.isNull()) return; @@ -1117,7 +1080,7 @@ void create_new_item(const std::string& name, if (inv_type == LLInventoryType::IT_GESTURE) { - LLPointer cb = new CreateGestureCallback(); + LLPointer cb = new LLBoostFuncInventoryCallback(create_gesture_cb); create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type, NOT_WEARABLE, next_owner_perm, cb); diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 2eb67cc62..7c9e0652f 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -241,53 +241,16 @@ public: virtual void fire(const LLUUID& inv_item) = 0; }; -class WearOnAvatarCallback : public LLInventoryCallback -{ -public: - WearOnAvatarCallback(bool do_replace = false) : mReplace(do_replace) {} - - void fire(const LLUUID& inv_item); - -protected: - bool mReplace; -}; - -class ModifiedCOFCallback : public LLInventoryCallback -{ - void fire(const LLUUID& inv_item); -}; class LLViewerJointAttachment; -class RezAttachmentCallback : public LLInventoryCallback -{ -public: -// RezAttachmentCallback(LLViewerJointAttachment *attachmentp); +//void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp); // [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a - RezAttachmentCallback(LLViewerJointAttachment *attachmentp, bool replace = false); +void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp, bool replace); // [/SL:KB] - void fire(const LLUUID& inv_item); -protected: - ~RezAttachmentCallback(); +void activate_gesture_cb(const LLUUID& inv_item); -private: - LLViewerJointAttachment* mAttach; -// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a - bool mReplace; -// [/SL:KB] -}; - -class ActivateGestureCallback : public LLInventoryCallback -{ -public: - void fire(const LLUUID& inv_item); -}; - -class CreateGestureCallback : public LLInventoryCallback -{ -public: - void fire(const LLUUID& inv_item); -}; +void create_gesture_cb(const LLUUID& inv_item); class AddFavoriteLandmarkCallback : public LLInventoryCallback { @@ -301,6 +264,42 @@ private: LLUUID mTargetLandmarkId; }; +typedef boost::function inventory_func_type; +void no_op_inventory_func(const LLUUID&); // A do-nothing inventory_func + +typedef boost::function nullary_func_type; +void no_op(); // A do-nothing nullary func. + +// Shim between inventory callback and boost function/callable +class LLBoostFuncInventoryCallback: public LLInventoryCallback +{ +public: + + LLBoostFuncInventoryCallback(inventory_func_type fire_func, + nullary_func_type destroy_func = no_op): + mFireFunc(fire_func), + mDestroyFunc(destroy_func) + { + } + + // virtual + void fire(const LLUUID& item_id) + { + mFireFunc(item_id); + } + + // virtual + ~LLBoostFuncInventoryCallback() + { + mDestroyFunc(); + } + + +private: + inventory_func_type mFireFunc; + nullary_func_type mDestroyFunc; +}; + // misc functions //void inventory_reliable_callback(void**, S32 status); diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index a907f102f..e46299f9d 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -35,50 +35,26 @@ #include "llrender.h" #include "llmath.h" #include "llglheaders.h" -#include "llrendersphere.h" #include "llvoavatar.h" #include "pipeline.h" -#define DEFAULT_LOD 0.0f - -const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64; - -//----------------------------------------------------------------------------- -// Static Data -//----------------------------------------------------------------------------- -BOOL LLViewerJoint::sDisableLOD = FALSE; +static const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64; //----------------------------------------------------------------------------- // LLViewerJoint() -// Class Constructor +// Class Constructors //----------------------------------------------------------------------------- -LLViewerJoint::LLViewerJoint() - : LLJoint() -{ - init(); -} +LLViewerJoint::LLViewerJoint() : + LLAvatarJoint() +{ } +LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) : + LLAvatarJoint(name, parent) +{ } -//----------------------------------------------------------------------------- -// LLViewerJoint() -// Class Constructor -//----------------------------------------------------------------------------- -LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) - : LLJoint(name, parent) -{ - init(); -} - - -void LLViewerJoint::init() -{ - mValid = FALSE; - mComponents = SC_JOINT | SC_BONE | SC_AXES; - mMinPixelArea = DEFAULT_LOD; - mPickName = PN_DEFAULT; - mVisible = TRUE; - mMeshID = 0; -} +LLViewerJoint::LLViewerJoint(S32 joint_num) : + LLAvatarJoint(joint_num) +{ } //----------------------------------------------------------------------------- @@ -89,154 +65,6 @@ LLViewerJoint::~LLViewerJoint() { } - -//-------------------------------------------------------------------- -// setValid() -//-------------------------------------------------------------------- -void LLViewerJoint::setValid( BOOL valid, BOOL recursive ) -{ - //---------------------------------------------------------------- - // set visibility for this joint - //---------------------------------------------------------------- - mValid = valid; - - //---------------------------------------------------------------- - // set visibility for children - //---------------------------------------------------------------- - if (recursive) - { - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - joint->setValid(valid, TRUE); - } - } - -} - -//-------------------------------------------------------------------- -// renderSkeleton() -// DEBUG (UNUSED) -//-------------------------------------------------------------------- -// void LLViewerJoint::renderSkeleton(BOOL recursive) -// { -// F32 nc = 0.57735f; - -// //---------------------------------------------------------------- -// // push matrix stack -// //---------------------------------------------------------------- -// gGL.pushMatrix(); - -// //---------------------------------------------------------------- -// // render the bone to my parent -// //---------------------------------------------------------------- -// if (mComponents & SC_BONE) -// { -// drawBone(); -// } - -// //---------------------------------------------------------------- -// // offset to joint position and -// // rotate to our orientation -// //---------------------------------------------------------------- -// gGL.loadIdentity(); -// gGL.multMatrix( &getWorldMatrix().mMatrix[0][0] ); - -// //---------------------------------------------------------------- -// // render joint axes -// //---------------------------------------------------------------- -// if (mComponents & SC_AXES) -// { -// gGL.begin(LLRender::LINES); -// gGL.color3f( 1.0f, 0.0f, 0.0f ); -// gGL.vertex3f( 0.0f, 0.0f, 0.0f ); -// gGL.vertex3f( 0.1f, 0.0f, 0.0f ); - -// gGL.color3f( 0.0f, 1.0f, 0.0f ); -// gGL.vertex3f( 0.0f, 0.0f, 0.0f ); -// gGL.vertex3f( 0.0f, 0.1f, 0.0f ); - -// gGL.color3f( 0.0f, 0.0f, 1.0f ); -// gGL.vertex3f( 0.0f, 0.0f, 0.0f ); -// gGL.vertex3f( 0.0f, 0.0f, 0.1f ); -// gGL.end(); -// } - -// //---------------------------------------------------------------- -// // render the joint graphic -// //---------------------------------------------------------------- -// if (mComponents & SC_JOINT) -// { -// gGL.color3f( 1.0f, 1.0f, 0.0f ); - -// gGL.begin(LLRender::TRIANGLES); - -// // joint top half -// glNormal3f(nc, nc, nc); -// gGL.vertex3f(0.0f, 0.0f, 0.05f); -// gGL.vertex3f(0.05f, 0.0f, 0.0f); -// gGL.vertex3f(0.0f, 0.05f, 0.0f); - -// glNormal3f(-nc, nc, nc); -// gGL.vertex3f(0.0f, 0.0f, 0.05f); -// gGL.vertex3f(0.0f, 0.05f, 0.0f); -// gGL.vertex3f(-0.05f, 0.0f, 0.0f); - -// glNormal3f(-nc, -nc, nc); -// gGL.vertex3f(0.0f, 0.0f, 0.05f); -// gGL.vertex3f(-0.05f, 0.0f, 0.0f); -// gGL.vertex3f(0.0f, -0.05f, 0.0f); - -// glNormal3f(nc, -nc, nc); -// gGL.vertex3f(0.0f, 0.0f, 0.05f); -// gGL.vertex3f(0.0f, -0.05f, 0.0f); -// gGL.vertex3f(0.05f, 0.0f, 0.0f); - -// // joint bottom half -// glNormal3f(nc, nc, -nc); -// gGL.vertex3f(0.0f, 0.0f, -0.05f); -// gGL.vertex3f(0.0f, 0.05f, 0.0f); -// gGL.vertex3f(0.05f, 0.0f, 0.0f); - -// glNormal3f(-nc, nc, -nc); -// gGL.vertex3f(0.0f, 0.0f, -0.05f); -// gGL.vertex3f(-0.05f, 0.0f, 0.0f); -// gGL.vertex3f(0.0f, 0.05f, 0.0f); - -// glNormal3f(-nc, -nc, -nc); -// gGL.vertex3f(0.0f, 0.0f, -0.05f); -// gGL.vertex3f(0.0f, -0.05f, 0.0f); -// gGL.vertex3f(-0.05f, 0.0f, 0.0f); - -// glNormal3f(nc, -nc, -nc); -// gGL.vertex3f(0.0f, 0.0f, -0.05f); -// gGL.vertex3f(0.05f, 0.0f, 0.0f); -// gGL.vertex3f(0.0f, -0.05f, 0.0f); - -// gGL.end(); -// } - -// //---------------------------------------------------------------- -// // render children -// //---------------------------------------------------------------- -// if (recursive) -// { -// for (child_list_t::iterator iter = mChildren.begin(); -// iter != mChildren.end(); ++iter) -// { -// LLViewerJoint* joint = (LLViewerJoint*)(*iter); -// joint->renderSkeleton(); -// } -// } - -// //---------------------------------------------------------------- -// // pop matrix stack -// //---------------------------------------------------------------- -// gGL.popMatrix(); -// } - - //-------------------------------------------------------------------- // render() //-------------------------------------------------------------------- @@ -317,13 +145,13 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy ) for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); ++iter) { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); + LLAvatarJoint* joint = dynamic_cast(*iter); F32 jointLOD = joint->getLOD(); if (pixelArea >= jointLOD || sDisableLOD) { triangle_count += joint->render( pixelArea, TRUE, is_dummy ); - if (jointLOD != DEFAULT_LOD) + if (jointLOD != DEFAULT_AVATAR_JOINT_LOD) { break; } @@ -333,72 +161,6 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy ) return triangle_count; } - -//-------------------------------------------------------------------- -// drawBone() -// DEBUG (UNUSED) -//-------------------------------------------------------------------- -// void LLViewerJoint::drawBone() -// { -// if ( mParent == NULL ) -// return; - -// F32 boneSize = 0.02f; - -// // rotate to point to child (bone direction) -// gGL.pushMatrix(); - -// LLVector3 boneX = getPosition(); -// F32 length = boneX.normVec(); - -// LLVector3 boneZ(1.0f, 0.0f, 1.0f); - -// LLVector3 boneY = boneZ % boneX; -// boneY.normVec(); - -// boneZ = boneX % boneY; - -// LLMatrix4 rotateMat; -// rotateMat.setFwdRow( boneX ); -// rotateMat.setLeftRow( boneY ); -// rotateMat.setUpRow( boneZ ); -// gGL.multMatrix( &rotateMat.mMatrix[0][0] ); - -// // render the bone -// gGL.color3f( 0.5f, 0.5f, 0.0f ); - -// gGL.begin(LLRender::TRIANGLES); - -// gGL.vertex3f( length, 0.0f, 0.0f); -// gGL.vertex3f( 0.0f, boneSize, 0.0f); -// gGL.vertex3f( 0.0f, 0.0f, boneSize); - -// gGL.vertex3f( length, 0.0f, 0.0f); -// gGL.vertex3f( 0.0f, 0.0f, -boneSize); -// gGL.vertex3f( 0.0f, boneSize, 0.0f); - -// gGL.vertex3f( length, 0.0f, 0.0f); -// gGL.vertex3f( 0.0f, -boneSize, 0.0f); -// gGL.vertex3f( 0.0f, 0.0f, -boneSize); - -// gGL.vertex3f( length, 0.0f, 0.0f); -// gGL.vertex3f( 0.0f, 0.0f, boneSize); -// gGL.vertex3f( 0.0f, -boneSize, 0.0f); - -// gGL.end(); - -// // restore matrix -// gGL.popMatrix(); -// } - -//-------------------------------------------------------------------- -// isTransparent() -//-------------------------------------------------------------------- -BOOL LLViewerJoint::isTransparent() -{ - return FALSE; -} - //-------------------------------------------------------------------- // drawShape() //-------------------------------------------------------------------- @@ -407,213 +169,4 @@ U32 LLViewerJoint::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy ) return 0; } -//-------------------------------------------------------------------- -// setSkeletonComponents() -//-------------------------------------------------------------------- -void LLViewerJoint::setSkeletonComponents( U32 comp, BOOL recursive ) -{ - mComponents = comp; - if (recursive) - { - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - joint->setSkeletonComponents(comp, recursive); - } - } -} - -void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area) -{ - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - joint->updateFaceSizes(num_vertices, num_indices, pixel_area); - } -} - -void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update) -{ - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - joint->updateFaceData(face, pixel_area, damp_wind, terse_update); - } -} - -void LLViewerJoint::updateJointGeometry() -{ - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - joint->updateJointGeometry(); - } -} - - -BOOL LLViewerJoint::updateLOD(F32 pixel_area, BOOL activate) -{ - BOOL lod_changed = FALSE; - BOOL found_lod = FALSE; - - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - F32 jointLOD = joint->getLOD(); - - if (found_lod || jointLOD == DEFAULT_LOD) - { - // we've already found a joint to enable, so enable the rest as alternatives - lod_changed |= joint->updateLOD(pixel_area, TRUE); - } - else - { - if (pixel_area >= jointLOD || sDisableLOD) - { - lod_changed |= joint->updateLOD(pixel_area, TRUE); - found_lod = TRUE; - } - else - { - lod_changed |= joint->updateLOD(pixel_area, FALSE); - } - } - } - return lod_changed; -} - -void LLViewerJoint::dump() -{ - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - joint->dump(); - } -} - -void LLViewerJoint::setVisible(BOOL visible, BOOL recursive) -{ - mVisible = visible; - - if (recursive) - { - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - joint->setVisible(visible, recursive); - } - } -} - - -void LLViewerJoint::setMeshesToChildren() -{ - removeAllChildren(); - for (std::vector::iterator iter = mMeshParts.begin(); - iter != mMeshParts.end(); iter++) - { - addChild((LLViewerJointMesh *) *iter); - } -} -//----------------------------------------------------------------------------- -// LLViewerJointCollisionVolume() -//----------------------------------------------------------------------------- - -LLViewerJointCollisionVolume::LLViewerJointCollisionVolume() -{ - mUpdateXform = FALSE; -} - -LLViewerJointCollisionVolume::LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent) : LLViewerJoint(name, parent) -{ - -} - -void LLViewerJointCollisionVolume::renderCollision() -{ - updateWorldMatrix(); - - gGL.pushMatrix(); - gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] ); - - gGL.diffuseColor3f( 0.f, 0.f, 1.f ); - - gGL.begin(LLRender::LINES); - - LLVector3 v[] = - { - LLVector3(1,0,0), - LLVector3(-1,0,0), - LLVector3(0,1,0), - LLVector3(0,-1,0), - - LLVector3(0,0,-1), - LLVector3(0,0,1), - }; - - //sides - gGL.vertex3fv(v[0].mV); - gGL.vertex3fv(v[2].mV); - - gGL.vertex3fv(v[0].mV); - gGL.vertex3fv(v[3].mV); - - gGL.vertex3fv(v[1].mV); - gGL.vertex3fv(v[2].mV); - - gGL.vertex3fv(v[1].mV); - gGL.vertex3fv(v[3].mV); - - - //top - gGL.vertex3fv(v[0].mV); - gGL.vertex3fv(v[4].mV); - - gGL.vertex3fv(v[1].mV); - gGL.vertex3fv(v[4].mV); - - gGL.vertex3fv(v[2].mV); - gGL.vertex3fv(v[4].mV); - - gGL.vertex3fv(v[3].mV); - gGL.vertex3fv(v[4].mV); - - - //bottom - gGL.vertex3fv(v[0].mV); - gGL.vertex3fv(v[5].mV); - - gGL.vertex3fv(v[1].mV); - gGL.vertex3fv(v[5].mV); - - gGL.vertex3fv(v[2].mV); - gGL.vertex3fv(v[5].mV); - - gGL.vertex3fv(v[3].mV); - gGL.vertex3fv(v[5].mV); - - gGL.end(); - - gGL.popMatrix(); -} - -LLVector3 LLViewerJointCollisionVolume::getVolumePos(LLVector3 &offset) -{ - mUpdateXform = TRUE; - - LLVector3 result = offset; - result.scaleVec(getScale()); - result.rotVec(getWorldRotation()); - result += getWorldPosition(); - - return result; -} - // End diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h index 76e3833ac..fd262b6e8 100644 --- a/indra/newview/llviewerjoint.h +++ b/indra/newview/llviewerjoint.h @@ -30,7 +30,8 @@ //----------------------------------------------------------------------------- // Header Files //----------------------------------------------------------------------------- -#include "lljoint.h" +#include "llavatarjoint.h" +#include "lljointpickname.h" class LLFace; class LLViewerJointMesh; @@ -39,124 +40,25 @@ class LLViewerJointMesh; // class LLViewerJoint //----------------------------------------------------------------------------- class LLViewerJoint : - public LLJoint + public virtual LLAvatarJoint { public: LLViewerJoint(); + LLViewerJoint(S32 joint_num); + // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform* LLViewerJoint(const std::string &name, LLJoint *parent = NULL); virtual ~LLViewerJoint(); - // Gets the validity of this joint - BOOL getValid() { return mValid; } - - // Sets the validity of this joint - virtual void setValid( BOOL valid, BOOL recursive=FALSE ); - - // Primarily for debugging and character setup - // Derived classes may add text/graphic output. - // Draw skeleton graphic for debugging and character setup - void renderSkeleton(BOOL recursive=TRUE); // debug only (unused) - - // Draws a bone graphic to the parent joint. - // Derived classes may add text/graphic output. - // Called by renderSkeleton(). - void drawBone(); // debug only (unused) - // Render character hierarchy. // Traverses the entire joint hierarchy, setting up // transforms and calling the drawShape(). // Derived classes may add text/graphic output. virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ); // Returns triangle count - // Returns true if this object is transparent. - // This is used to determine in which order to draw objects. - virtual BOOL isTransparent(); - - // Returns true if this object should inherit scale modifiers from its immediate parent - virtual BOOL inheritScale() { return FALSE; } - // Draws the shape attached to a joint. // Called by render(). virtual U32 drawShape( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ); virtual void drawNormals() {} - - enum Components - { - SC_BONE = 1, - SC_JOINT = 2, - SC_AXES = 4 - }; - - // Selects which skeleton components to draw - void setSkeletonComponents( U32 comp, BOOL recursive = TRUE ); - - // Returns which skeleton components are enables for drawing - U32 getSkeletonComponents() { return mComponents; } - - // Sets the level of detail for this node as a minimum - // pixel area threshold. If the current pixel area for this - // object is less than the specified threshold, the node is - // not traversed. In addition, if a value is specified (not - // default of 0.0), and the pixel area is larger than the - // specified minimum, the node is rendered, but no other siblings - // of this node under the same parent will be. - F32 getLOD() { return mMinPixelArea; } - void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; } - - // Sets the OpenGL selection stack name that is pushed and popped - // with this joint state. The default value indicates that no name - // should be pushed/popped. - enum PickName - { - PN_DEFAULT = -1, - PN_0 = 0, - PN_1 = 1, - PN_2 = 2, - PN_3 = 3, - PN_4 = 4, - PN_5 = 5 - }; - void setPickName(PickName name) { mPickName = name; } - PickName getPickName() { return mPickName; } - - virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area); - virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false); - virtual BOOL updateLOD(F32 pixel_area, BOOL activate); - virtual void updateJointGeometry(); - virtual void dump(); - - void setVisible( BOOL visible, BOOL recursive ); - - // Takes meshes in mMeshParts and sets each one as a child joint - void setMeshesToChildren(); - -public: - static BOOL sDisableLOD; - std::vector mMeshParts; - void setMeshID( S32 id ) {mMeshID = id;} - -protected: - void init(); - - BOOL mValid; - U32 mComponents; - F32 mMinPixelArea; - PickName mPickName; - BOOL mVisible; - S32 mMeshID; -}; - -class LLViewerJointCollisionVolume : public LLViewerJoint -{ -public: - LLViewerJointCollisionVolume(); - LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent = NULL); - virtual ~LLViewerJointCollisionVolume() {}; - - virtual BOOL inheritScale() { return TRUE; } - - void renderCollision(); - LLVector3 getVolumePos(LLVector3 &offset); }; #endif // LL_LLVIEWERJOINT_H diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index d9e9499ce..1184cf73c 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -42,7 +42,7 @@ #include "llface.h" #include "llgldbg.h" #include "llglheaders.h" -#include "lltexlayer.h" +#include "llviewertexlayer.h" #include "llviewercamera.h" #include "llviewercontrol.h" #include "llviewertexturelist.h" @@ -67,101 +67,20 @@ static const U32 sRenderMask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLViewerJointMesh::LLSkinJoint -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// LLSkinJoint -//----------------------------------------------------------------------------- -LLSkinJoint::LLSkinJoint() -{ - mJoint = NULL; -} - -//----------------------------------------------------------------------------- -// ~LLSkinJoint -//----------------------------------------------------------------------------- -LLSkinJoint::~LLSkinJoint() -{ - mJoint = NULL; -} - - -//----------------------------------------------------------------------------- -// LLSkinJoint::setupSkinJoint() -//----------------------------------------------------------------------------- -BOOL LLSkinJoint::setupSkinJoint( LLViewerJoint *joint) -{ - // find the named joint - mJoint = joint; - if ( !mJoint ) - { - llinfos << "Can't find joint" << llendl; - } - - // compute the inverse root skin matrix - mRootToJointSkinOffset.clearVec(); - - LLVector3 rootSkinOffset; - while (joint) - { - rootSkinOffset += joint->getSkinOffset(); - joint = (LLViewerJoint*)joint->getParent(); - } - - mRootToJointSkinOffset = -rootSkinOffset; - mRootToParentJointSkinOffset = mRootToJointSkinOffset; - mRootToParentJointSkinOffset += mJoint->getSkinOffset(); - - return TRUE; -} - - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // LLViewerJointMesh //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -BOOL LLViewerJointMesh::sPipelineRender = FALSE; -EAvatarRenderPass LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; -U32 LLViewerJointMesh::sClothingMaskImageName = 0; -LLColor4 LLViewerJointMesh::sClothingInnerColor; //----------------------------------------------------------------------------- // LLViewerJointMesh() //----------------------------------------------------------------------------- LLViewerJointMesh::LLViewerJointMesh() : - mTexture( NULL ), - mLayerSet( NULL ), - mTestImageName( 0 ), - mFaceIndexCount(0), - mIsTransparent(FALSE) + LLAvatarJointMesh() { - - mColor[0] = 1.0f; - mColor[1] = 1.0f; - mColor[2] = 1.0f; - mColor[3] = 1.0f; - mShiny = 0.0f; - mCullBackFaces = TRUE; - - mMesh = NULL; - - mNumSkinJoints = 0; - mSkinJoints = NULL; - - mFace = NULL; - - mMeshID = 0; - mUpdateXform = FALSE; - - mValid = FALSE; } @@ -171,199 +90,6 @@ LLViewerJointMesh::LLViewerJointMesh() //----------------------------------------------------------------------------- LLViewerJointMesh::~LLViewerJointMesh() { - mMesh = NULL; - mTexture = NULL; - freeSkinData(); -} - - -//----------------------------------------------------------------------------- -// LLViewerJointMesh::allocateSkinData() -//----------------------------------------------------------------------------- -BOOL LLViewerJointMesh::allocateSkinData( U32 numSkinJoints ) -{ - mSkinJoints = new LLSkinJoint[ numSkinJoints ]; - mNumSkinJoints = numSkinJoints; - return TRUE; -} - -//----------------------------------------------------------------------------- -// LLViewerJointMesh::freeSkinData() -//----------------------------------------------------------------------------- -void LLViewerJointMesh::freeSkinData() -{ - mNumSkinJoints = 0; - delete [] mSkinJoints; - mSkinJoints = NULL; -} - -//-------------------------------------------------------------------- -// LLViewerJointMesh::getColor() -//-------------------------------------------------------------------- -void LLViewerJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha ) -{ - *red = mColor[0]; - *green = mColor[1]; - *blue = mColor[2]; - *alpha = mColor[3]; -} - -//-------------------------------------------------------------------- -// LLViewerJointMesh::setColor() -//-------------------------------------------------------------------- -void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha ) -{ - mColor[0] = red; - mColor[1] = green; - mColor[2] = blue; - mColor[3] = alpha; -} - - -//-------------------------------------------------------------------- -// LLViewerJointMesh::getTexture() -//-------------------------------------------------------------------- -//LLViewerTexture *LLViewerJointMesh::getTexture() -//{ -// return mTexture; -//} - -//-------------------------------------------------------------------- -// LLViewerJointMesh::setTexture() -//-------------------------------------------------------------------- -void LLViewerJointMesh::setTexture( LLViewerTexture *texture ) -{ - mTexture = texture; - - // texture and dynamic_texture are mutually exclusive - if( texture ) - { - mLayerSet = NULL; - //texture->bindTexture(0); - //texture->setClamp(TRUE, TRUE); - } -} - -//-------------------------------------------------------------------- -// LLViewerJointMesh::setLayerSet() -// Sets the shape texture (takes precedence over normal texture) -//-------------------------------------------------------------------- -void LLViewerJointMesh::setLayerSet( LLTexLayerSet* layer_set ) -{ - mLayerSet = layer_set; - - // texture and dynamic_texture are mutually exclusive - if( layer_set ) - { - mTexture = NULL; - } -} - - - -//-------------------------------------------------------------------- -// LLViewerJointMesh::getMesh() -//-------------------------------------------------------------------- -LLPolyMesh *LLViewerJointMesh::getMesh() -{ - return mMesh; -} - -//----------------------------------------------------------------------------- -// LLViewerJointMesh::setMesh() -//----------------------------------------------------------------------------- -void LLViewerJointMesh::setMesh( LLPolyMesh *mesh ) -{ - // set the mesh pointer - mMesh = mesh; - - // release any existing skin joints - freeSkinData(); - - if ( mMesh == NULL ) - { - return; - } - - // acquire the transform from the mesh object - setPosition( mMesh->getPosition() ); - setRotation( mMesh->getRotation() ); - setScale( mMesh->getScale() ); - - // create skin joints if necessary - if ( mMesh->hasWeights() && !mMesh->isLOD()) - { - U32 numJointNames = mMesh->getNumJointNames(); - - allocateSkinData( numJointNames ); - std::string *jointNames = mMesh->getJointNames(); - - U32 jn; - for (jn = 0; jn < numJointNames; jn++) - { - //llinfos << "Setting up joint " << jointNames[jn] << llendl; - LLViewerJoint* joint = (LLViewerJoint*)(getRoot()->findJoint(jointNames[jn]) ); - mSkinJoints[jn].setupSkinJoint( joint ); - } - } - - // setup joint array - if (!mMesh->isLOD()) - { - setupJoint((LLViewerJoint*)getRoot()); - } - -// llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl; -} - -//----------------------------------------------------------------------------- -// setupJoint() -//----------------------------------------------------------------------------- -void LLViewerJointMesh::setupJoint(LLViewerJoint* current_joint) -{ -// llinfos << "Mesh: " << getName() << llendl; - -// S32 joint_count = 0; - U32 sj; - for (sj=0; sjmJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == ¤t_joint->getParent()->getWorldMatrix()) - { - // ...then just add ourselves - LLViewerJoint* jointp = js.mJoint; - mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js)); -// llinfos << "joint " << joint_count << js.mJoint->getName() << llendl; -// joint_count++; - } - // otherwise add our parent and ourselves - else - { - mMesh->mJointRenderData.put(new LLJointRenderData(¤t_joint->getParent()->getWorldMatrix(), NULL)); -// llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl; -// joint_count++; - mMesh->mJointRenderData.put(new LLJointRenderData(¤t_joint->getWorldMatrix(), &js)); -// llinfos << "joint " << joint_count << current_joint->getName() << llendl; -// joint_count++; - } - } - - // depth-first traversal - for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin(); - iter != current_joint->mChildren.end(); ++iter) - { - LLViewerJoint* child_joint = (LLViewerJoint*)(*iter); - setupJoint(child_joint); - } } const S32 NUM_AXES = 3; @@ -474,21 +200,6 @@ void LLViewerJointMesh::uploadJointMatrices() } } -//-------------------------------------------------------------------- -// LLViewerJointMesh::drawBone() -//-------------------------------------------------------------------- -void LLViewerJointMesh::drawBone() -{ -} - -//-------------------------------------------------------------------- -// LLViewerJointMesh::isTransparent() -//-------------------------------------------------------------------- -BOOL LLViewerJointMesh::isTransparent() -{ - return mIsTransparent; -} - //-------------------------------------------------------------------- // DrawElementsBLEND and utility code //-------------------------------------------------------------------- @@ -544,6 +255,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) llassert( !(mTexture.notNull() && mLayerSet) ); // mutually exclusive LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP; + LLViewerTexLayerSet *layerset = dynamic_cast(mLayerSet); if (mTestImageName) { gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName); @@ -558,18 +270,18 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); } } - else if( !is_dummy && mLayerSet ) + else if( !is_dummy && layerset ) { - if( mLayerSet->hasComposite() ) + if( layerset->hasComposite() ) { - gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getComposite()); + gGL.getTexUnit(diffuse_channel)->bind(layerset->getViewerComposite()); } else { // This warning will always trigger if you've hacked the avatar to show as incomplete. // Ignore the warning if that's the case. - static const LLCachedControl rener_unloaded_avatar("RenderUnloadedAvatar"); - if (!rener_unloaded_avatar) + static const LLCachedControl render_unloaded_avatar("RenderUnloadedAvatar", false); + if (!render_unloaded_avatar) { llwarns << "Layerset without composite" << llendl; } @@ -736,8 +448,10 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w F32* vw = (F32*) vertex_weightsp.get(); F32* cw = (F32*) clothing_weightsp.get(); - LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), num_verts*2*sizeof(F32)); - LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), num_verts*sizeof(F32)); + S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size); + S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size); LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32)); } diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index dd5dae1dc..c5b872ede 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -29,64 +29,20 @@ #include "llviewerjoint.h" #include "llviewertexture.h" +#include "llavatarjointmesh.h" #include "llpolymesh.h" #include "v4color.h" class LLDrawable; class LLFace; class LLCharacter; -class LLTexLayerSet; - -typedef enum e_avatar_render_pass -{ - AVATAR_RENDER_PASS_SINGLE, - AVATAR_RENDER_PASS_CLOTHING_INNER, - AVATAR_RENDER_PASS_CLOTHING_OUTER -} EAvatarRenderPass; - -class LLSkinJoint -{ -public: - LLSkinJoint(); - ~LLSkinJoint(); - BOOL setupSkinJoint( LLViewerJoint *joint); - - LLViewerJoint *mJoint; - LLVector3 mRootToJointSkinOffset; - LLVector3 mRootToParentJointSkinOffset; -}; +class LLViewerTexLayerSet; //----------------------------------------------------------------------------- // class LLViewerJointMesh //----------------------------------------------------------------------------- -class LLViewerJointMesh : public LLViewerJoint +class LLViewerJointMesh : public LLAvatarJointMesh, public LLViewerJoint { - friend class LLVOAvatar; -protected: - LLColor4 mColor; // color value -// LLColor4 mSpecular; // specular color (always white for now) - F32 mShiny; // shiny value - LLPointer mTexture; // ptr to a global texture - LLTexLayerSet* mLayerSet; // ptr to a layer set owned by the avatar - U32 mTestImageName; // handle to a temporary texture for previewing uploads - LLPolyMesh* mMesh; // ptr to a global polymesh - BOOL mCullBackFaces; // true by default - LLFace* mFace; // ptr to a face w/ AGP copy of mesh - - U32 mFaceIndexCount; - BOOL mIsTransparent; - - U32 mNumSkinJoints; - LLSkinJoint* mSkinJoints; - S32 mMeshID; - -public: - static BOOL sPipelineRender; - //RN: this is here for testing purposes - static U32 sClothingMaskImageName; - static EAvatarRenderPass sRenderPass; - static LLColor4 sClothingInnerColor; - public: // Constructor LLViewerJointMesh(); @@ -94,67 +50,28 @@ public: // Destructor virtual ~LLViewerJointMesh(); - // Gets the shape color - void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha ); - - // Sets the shape color - void setColor( F32 red, F32 green, F32 blue, F32 alpha ); - - // Sets the shininess - void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; }; - - // Sets the shape texture - void setTexture( LLViewerTexture *texture ); - - void setTestTexture( U32 name ) { mTestImageName = name; } - - // Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture) - void setLayerSet( LLTexLayerSet* layer_set ); - - // Gets the poly mesh - LLPolyMesh *getMesh(); - - // Sets the poly mesh - void setMesh( LLPolyMesh *mesh ); - - // Sets up joint matrix data for rendering - void setupJoint(LLViewerJoint* current_joint); - // Render time method to upload batches of joint matrices void uploadJointMatrices(); - // Sets ID for picking - void setMeshID( S32 id ) {mMeshID = id;} - - // Gets ID for picking - S32 getMeshID() { return mMeshID; } - // overloaded from base class - /*virtual*/ void drawBone(); - /*virtual*/ BOOL isTransparent(); /*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy ); + // necessary because MS's compiler warns on function inheritance via dominance in the diamond inheritance here. + // warns even though LLViewerJoint holds the only non virtual implementation. + /*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) { return LLViewerJoint::render(pixelArea,first_pass,is_dummy);} + /*virtual*/ void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area); /*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false); /*virtual*/ BOOL updateLOD(F32 pixel_area, BOOL activate); /*virtual*/ void updateJointGeometry(); /*virtual*/ void dump(); - void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; } - /*virtual*/ BOOL isAnimatable() const { return FALSE; } - + private: //copy mesh into given face's vertex buffer, applying current animation pose static void updateGeometry(LLFace* face, LLPolyMesh* mesh); - -private: - // Allocate skin data - BOOL allocateSkinData( U32 numSkinJoints ); - - // Free skin data - void freeSkinData(); }; #endif // LL_LLVIEWERJOINTMESH_H diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 94b05c958..3e8b49b98 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -55,6 +55,7 @@ #include "llwindow.h" #include "llvieweraudio.h" #include "llweb.h" +#include "llwebprofile.h" #include "llfloateravatarinfo.h" // for getProfileURL() function //#include "viewerversion.h" @@ -75,14 +76,15 @@ class LLMimeDiscoveryResponder : public LLHTTPClient::ResponderHeadersOnly { LOG_CLASS(LLMimeDiscoveryResponder); public: - LLMimeDiscoveryResponder( viewer_media_t media_impl) + LLMimeDiscoveryResponder(viewer_media_t media_impl, std::string const& default_mime_type) : mMediaImpl(media_impl), + mDefaultMimeType(default_mime_type), mInitialized(false) {} /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { - if (200 <= status && status < 300) + if (200 <= status && status < 300 || status == 405) // Using HEAD may result in a 405 METHOD NOT ALLOWED, but still have the right Content-TYpe header. { std::string media_type; if (headers.getFirstValue("content-type", media_type)) @@ -92,9 +94,13 @@ public: completeAny(status, mime_type); return; } - llwarns << "LLMimeDiscoveryResponder::completedHeaders: OK HTTP status (" << status << ") but no Content-Type! Received headers: " << headers << llendl; + if (200 <= status && status < 300) + { + llwarns << "LLMimeDiscoveryResponder::completedHeaders: OK HTTP status (" << status << ") but no Content-Type! Received headers: " << headers << llendl; + } } - completeAny(status, "none/none"); + llwarns << "LLMimeDiscoveryResponder::completedHeaders: Got status " << status << ". Using default mime-type: " << mDefaultMimeType << llendl; + completeAny(status, mDefaultMimeType); } void completeAny(U32 status, const std::string& mime_type) @@ -111,8 +117,11 @@ public: /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return mimeDiscoveryResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLMimeDiscoveryResponder"; } + public: viewer_media_t mMediaImpl; + std::string mDefaultMimeType; bool mInitialized; }; @@ -128,21 +137,16 @@ public: { } - /* virtual */ bool needsHeaders(void) const { return true; } + /*virtual*/ bool needsHeaders(void) const { return true; } - /* virtual */ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { LL_DEBUGS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL; LL_DEBUGS("MediaAuth") << headers << LL_ENDL; - AIHTTPReceivedHeaders::range_type cookies; - if (headers.getValues("set-cookie", cookies)) - { - for (AIHTTPReceivedHeaders::iterator_type cookie = cookies.first; cookie != cookies.second; ++cookie) - LLViewerMedia::openIDCookieResponse(cookie->second); - } + LLViewerMedia::openIDCookieResponse(get_cookie("agni_sl_session_id")); } - /* virtual */ void completedRaw( + /*virtual*/ void completedRaw( U32 status, const std::string& reason, const LLChannelDescriptors& channels, @@ -152,38 +156,52 @@ public: // We don't care about the content of the response, only the set-cookie header. } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return viewerMediaOpenIDResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return viewerMediaOpenIDResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLViewerMediaOpenIDResponder"; } }; class LLViewerMediaWebProfileResponder : public LLHTTPClient::ResponderWithCompleted { LOG_CLASS(LLViewerMediaWebProfileResponder); public: - LLViewerMediaWebProfileResponder(std::string host) - { - mHost = host; - } + LLViewerMediaWebProfileResponder(std::string host) : mHost(host) { } + ~LLViewerMediaWebProfileResponder() { } - ~LLViewerMediaWebProfileResponder() - { - } + /*virtual*/ bool followRedir(void) const { return true; } + /*virtual*/ bool needsHeaders(void) const { return true; } - /* virtual */ bool needsHeaders(void) const { return true; } - - /* virtual */ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { LL_INFOS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL; LL_INFOS("MediaAuth") << headers << LL_ENDL; + bool found = false; AIHTTPReceivedHeaders::range_type cookies; if (headers.getValues("set-cookie", cookies)) { for (AIHTTPReceivedHeaders::iterator_type cookie = cookies.first; cookie != cookies.second; ++cookie) + { LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie->second, mHost); + + std::string key = cookie->second.substr(0, cookie->second.find('=')); + if (key == "_my_secondlife_session") + { + // Set cookie for snapshot publishing. + std::string auth_cookie = cookie->second.substr(0, cookie->second.find(";")); // strip path + LL_INFOS("MediaAuth") << "Setting openID auth cookie \"" << auth_cookie << "\"." << LL_ENDL; + LLWebProfile::setAuthCookie(auth_cookie); + found = true; + break; + } + } + } + if (!found) + { + llwarns << "LLViewerMediaWebProfileResponder did not receive a session ID cookie \"_my_secondlife_session\"! OpenID authentications will fail!" << llendl; } } - void completedRaw( + /*virtual*/ void completedRaw( U32 status, const std::string& reason, const LLChannelDescriptors& channels, @@ -193,8 +211,10 @@ public: // We don't care about the content of the response, only the set-cookie header. } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return viewerMediaWebProfileResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return viewerMediaWebProfileResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLViewerMediaWebProfileResponder"; } +private: std::string mHost; }; @@ -1312,7 +1332,7 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi { if(mime_type.empty()) { - LLHTTPClient::getHeaderOnly( url, new LLMimeDiscoveryResponder(this)); + LLHTTPClient::getHeaderOnly(url, new LLMimeDiscoveryResponder(this, "text/html")); } else if(initializeMedia(mime_type) && (plugin = getMediaPlugin())) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9d93b6970..af189265e 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -178,14 +178,16 @@ #include "llinventorypanel.h" #include "llinventorybridge.h" #include "llkeyboard.h" -#include "llpanellogin.h" +#include "llmakeoutfitdialog.h" #include "llmenucommands.h" #include "llmenugl.h" #include "llmimetypes.h" #include "llmorphview.h" +#include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmoveview.h" #include "llmutelist.h" #include "llnotify.h" +#include "llpanellogin.h" #include "llpanelobject.h" #include "llparcel.h" @@ -264,10 +266,14 @@ #include "llagentui.h" #include "llpathfindingmanager.h" +#include "lltexturecache.h" +#include "llvovolume.h" +#include + #include "hippogridmanager.h" using namespace LLOldEvents; -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines; void init_client_menu(LLMenuGL* menu); void init_server_menu(LLMenuGL* menu); @@ -612,6 +618,9 @@ BOOL enable_region_owner(void*); void menu_toggle_attached_lights(void* user_data); void menu_toggle_attached_particles(void* user_data); +BOOL enable_dump_archetype_xm(void*); +void handle_dump_archetype_xml(void *); + class LLMenuParcelObserver : public LLParcelObserver { public: @@ -813,11 +822,6 @@ void init_menus() NULL, &menu_check_control, (void*)"Nimble")); - menu->addChild(new LLMenuItemCheckGL( "ReSit", - &menu_toggle_control, - NULL, - &menu_check_control, - (void*)"ReSit")); menu->addSeparator(); menu->addChild(new LLMenuItemCallGL( "Object Area Search", &handle_area_search, NULL)); @@ -854,6 +858,7 @@ void init_menus() menu->setCanTearOff(TRUE); init_client_menu(menu); gMenuBarView->addChild( menu ); + rlvMenuToggleVisible(); menu = new LLMenuGL(SERVER_MENU_NAME); menu->setCanTearOff(TRUE); @@ -874,7 +879,7 @@ void init_menus() menu = new LLMenuGL(CLIENT_MENU_NAME); menu->setCanTearOff(FALSE); - menu->addChild(new LLMenuItemCallGL("Debug Settings...", LLFloaterSettingsDebug::show, NULL, NULL)); + menu->addChild(new LLMenuItemCallGL("Debug Settings...", handle_singleton_toggle, NULL, NULL)); gLoginMenuBarView->addChild(menu); menu->updateParent(LLMenuGL::sMenuContainer); @@ -1058,15 +1063,13 @@ void init_client_menu(LLMenuGL* menu) // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1b | OK #ifdef RLV_ADVANCED_MENU - if (rlv_handler_t::isEnabled()) - { - sub_menu = new LLMenuGL("RLVa"); - sub_menu->setCanTearOff(TRUE); - init_debug_rlva_menu(sub_menu); - menu->addChild(sub_menu); - sub_menu->setVisible(rlv_handler_t::isEnabled()); - sub_menu->setEnabled(rlv_handler_t::isEnabled()); - } + sub_menu = new LLMenuGL("RLVa Embedded"); + init_debug_rlva_menu(sub_menu); + menu->addChild(sub_menu); + // Top Level Menu as well + sub_menu = new LLMenuGL("RLVa Main"); + init_debug_rlva_menu(sub_menu); + gMenuBarView->addChild(sub_menu); #endif // RLV_ADVANCED_MENU // [/RLVa:KB] @@ -1217,7 +1220,7 @@ void init_client_menu(LLMenuGL* menu) &menu_check_control, (void*)"SaveMinidump")); - menu->addChild(new LLMenuItemCallGL("Debug Settings...", LLFloaterSettingsDebug::show, NULL, NULL)); + menu->addChild(new LLMenuItemCallGL("Debug Settings...", handle_singleton_toggle, NULL, NULL)); menu->addChild(new LLMenuItemCheckGL("View Admin Options", &handle_admin_override_toggle, NULL, &check_admin_override, NULL, 'V', MASK_CONTROL | MASK_ALT)); menu->addChild(new LLMenuItemCallGL("Request Admin Status", @@ -1622,7 +1625,7 @@ void init_debug_avatar_menu(LLMenuGL* menu) &gAllowIdleAFK)); sub_menu->addChild(new LLMenuItemCallGL("Appearance To XML", - &LLVOAvatar::dumpArchetypeXML)); + &handle_dump_archetype_xml,&enable_dump_archetype_xm)); // HACK for easy testing of avatar geometry sub_menu->addChild(new LLMenuItemCallGL( "Toggle Character Geometry", @@ -1691,6 +1694,9 @@ void init_debug_avatar_menu(LLMenuGL* menu) // [RLVa:KB] - Checked: 2009-11-17 (RLVa-1.1.0d) | Modified: RLVa-1.1.0d | OK void init_debug_rlva_menu(LLMenuGL* menu) { + menu->setLabel(std::string("RLVa")); // Same menu, same label + menu->setCanTearOff(true); + // Debug options { LLMenuGL* pDbgMenu = new LLMenuGL("Debug"); @@ -2056,7 +2062,8 @@ class LLViewCommunicate : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if (LLFloaterChatterBox::getInstance()->getFloaterCount() == 0) + static LLCachedControl only_comm("CommunicateSpecificShortcut"); + if (!only_comm && LLFloaterChatterBox::getInstance()->getFloaterCount() == 0) { LLFloaterMyFriends::toggleInstance(); } @@ -2265,6 +2272,105 @@ class LLObjectDerender : public view_listener_t } }; +class LLTextureReloader +{ +public: + ~LLTextureReloader() + { + for(std::set< LLViewerFetchedTexture*>::iterator it=mTextures.begin();it!=mTextures.end();++it) + { + LLViewerFetchedTexture* img = *it; + const LLUUID& id = img->getID(); + if(id.notNull() && id != IMG_DEFAULT && id != IMG_DEFAULT_AVATAR && img != LLViewerFetchedTexture::sDefaultImagep) + { + LLAppViewer::getTextureCache()->removeFromCache(id); + img->forceRefetch(); + for (S32 i = 0; i < img->getNumVolumes(); ++i) + { + LLVOVolume* volume = (*(img->getVolumeList()))[i]; + if (volume && volume->isSculpted() && !volume->isMesh()) + volume->notifyMeshLoaded(); + } + } + } + } + void addTexture(LLViewerTexture* texture) + { + if(!texture) + return; + const LLUUID& id = texture->getID(); + if(id.notNull() && id != IMG_DEFAULT && id != IMG_DEFAULT_AVATAR && texture != LLViewerFetchedTexture::sDefaultImagep) + { + LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(texture); + if(img) + mTextures.insert(img); + } + } + +private: + std::set< LLViewerFetchedTexture*> mTextures; +}; +class LLAvatarReloadTextures : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar) + { + LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(avatar->getID()); + LLTextureReloader texture_list; + for (U32 i = 0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i) + { + if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i)) + { + if(avatar->isSelf()) + { + LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)i); + U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); + for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++) + { + texture_list.addTexture(((LLVOAvatarSelf*)avatar)->getLocalTextureGL((ETextureIndex)i,wearable_index)); + } + } + } + else + { + texture_list.addTexture(avatar->getTEImage((ETextureIndex)i)); + } + } + } + return true; + } +}; +class LLObjectReloadTextures : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLTextureReloader texture_list; + for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin(); + iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++) + { + LLViewerObject* object = (*iter)->getObject(); + + for (U8 i = 0; i < object->getNumTEs(); i++) + { + if((*iter)->isTESelected(i)) + { + texture_list.addTexture(object->getTEImage(i)); + } + if(object->isSculpted() && !object->isMesh()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + if(sculpt_params) + { + texture_list.addTexture(LLViewerTextureManager::getFetchedTexture(sculpt_params->getSculptTexture())); + } + } + } + } + return true; + } +}; //--------------------------------------------------------------------------- // Land pie menu @@ -2390,7 +2496,7 @@ class LLSelfRemoveAllAttachments : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAgentWearables::userRemoveAllAttachments(); + LLAppearanceMgr::instance().removeAllAttachmentsFromAvatar(); return true; } }; @@ -3599,7 +3705,6 @@ void set_god_level(U8 god_level) // God mode changes region visibility LLWorldMap::getInstance()->reset(); - LLWorldMap::getInstance()->setCurrentLayer(0); // inventory in items may change in god mode gObjectList.dirtyAllObjectInventory(); @@ -3933,11 +4038,6 @@ bool handle_sit_or_stand() gRlvHandler.setSitSource(gAgent.getPositionGlobal()); } // [/RLVa:KB] - - // - gReSitTargetID = object->mID; - gReSitOffset = pick.mObjectOffset; - // gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); @@ -4125,14 +4225,14 @@ void handle_show_newest_map(void*) // // Major mode switching // -void reset_view_final( BOOL proceed ); +void reset_view_final( BOOL proceed); void handle_reset_view() { - if( (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode()) && gFloaterCustomize ) + if(gAgentCamera.cameraCustomizeAvatar() && LLFloaterCustomize::instanceExists()) { // Show dialog box if needed. - gFloaterCustomize->askToSaveIfDirty( boost::bind(&reset_view_final, _1) ); + LLFloaterCustomize::getInstance()->askToSaveIfDirty( boost::bind(&reset_view_final, _1) ); } else { @@ -4150,7 +4250,7 @@ class LLViewResetView : public view_listener_t }; // Note: extra parameters allow this function to be called from dialog. -void reset_view_final( BOOL proceed ) +void reset_view_final( BOOL proceed) { if( !proceed ) { @@ -4160,6 +4260,10 @@ void reset_view_final( BOOL proceed ) gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW); gAgentCamera.resetView(TRUE, TRUE); gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); + + if(gAgentCamera.cameraCustomizeAvatar() && LLFloaterCustomize::instanceExists()) + LLFloaterCustomize::getInstance()->close(); + } class LLViewLookAtLastChatter : public view_listener_t @@ -4449,6 +4553,22 @@ void handle_god_request_havok(void *) // } //} +BOOL enable_dump_archetype_xm(void*) +{ + return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"); +} + +void handle_dump_archetype_xml(void *) +{ + std::string emptyname; + LLVOAvatar* avatar = + find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if (!avatar) + { + avatar = gAgentAvatarp; + } + avatar->dumpArchetypeXML(emptyname); +}; // HACK for easily testing new avatar geometry void handle_god_request_avatar_geometry(void *) @@ -5225,6 +5345,39 @@ class LLToolsEnablePathfindingView : public view_listener_t } }; +class LLToolsDoPathfindingRebakeRegion : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool hasPathfinding = (LLPathfindingManager::getInstance() != NULL); + + if (hasPathfinding) + { + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh(); + } + + return hasPathfinding; + } +}; + +class LLToolsEnablePathfindingRebakeRegion : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool returnValue = false; + + if (LLPathfindingManager::getInstance() != NULL) + { + LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance(); + returnValue = (rebakeInstance->canRebakeRegion() && + (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available)); + + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(returnValue); + return returnValue; + } +}; + // Round the position of all root objects to the grid class LLToolsSnapObjectXY : public view_listener_t { @@ -6385,9 +6538,13 @@ class LLShowFloater : public view_listener_t { if (gAgentWearables.areWearablesLoaded()) { - gAgentCamera.changeCameraToCustomizeAvatar(); + LLFloaterCustomize::show(); } } + else if (floater_name == "outfit") + { + new LLMakeOutfitDialog(false); + } // Phoenix: Wolfspirit: Enabled Show Floater out of viewer menu else if (floater_name == "displayname") { @@ -7014,6 +7171,7 @@ class LLAttachmentDrop : public view_listener_t // called from avatar pie menu void handle_detach_from_avatar(void* user_data) { + uuid_vec_t ids_to_remove; const LLViewerJointAttachment *attachment = (LLViewerJointAttachment*)user_data; // if (attachment->getNumObjects() > 0) @@ -7021,11 +7179,6 @@ void handle_detach_from_avatar(void* user_data) if ( (attachment->getNumObjects() > 0) && ((!rlv_handler_t::isEnabled()) || (gRlvAttachmentLocks.canDetach(attachment))) ) // [/RLVa:KB] { - gMessageSystem->newMessage("ObjectDetach"); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator iter = attachment->mAttachedObjects.begin(); iter != attachment->mAttachedObjects.end(); iter++) @@ -7035,12 +7188,14 @@ void handle_detach_from_avatar(void* user_data) if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.isLockedAttachment(attached_object)) ) continue; // [/RLVa:KB] - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); + ids_to_remove.push_back(attached_object->getAttachmentItemID()); + } + if (!ids_to_remove.empty()) + { + LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove); } - gMessageSystem->sendReliable( gAgent.getRegionHost() ); } -} +}; void attach_label(std::string& label, void* user_data) { @@ -7138,17 +7293,8 @@ class LLAttachmentDetach : public view_listener_t } // [/RLVa:KB] - // The sendDetach() method works on the list of selected - // objects. Thus we need to clear the list, make sure it only - // contains the object the user clicked, send the message, - // then clear the list. - // We use deselectAll to update the simulator's notion of what's - // selected, and removeAll just to change things locally. - //RN: I thought it was more useful to detach everything that was selected - if (LLSelectMgr::getInstance()->getSelection()->isAttachment()) - { - LLSelectMgr::getInstance()->sendDetach(); - } + LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID()); + return true; } }; @@ -8287,18 +8433,18 @@ void init_meshes_and_morphs_menu() menu->addChild(new LLMenuItemCallGL("Dump Avatar Mesh Info", &LLPolyMesh::dumpDiagInfo)); menu->addSeparator(); - LLVOAvatar::mesh_info_t mesh_info; - LLVOAvatar::getMeshInfo(&mesh_info); + LLAvatarAppearance::mesh_info_t mesh_info; + LLAvatarAppearance::getMeshInfo(&mesh_info); - for(LLVOAvatarSelf::mesh_info_t::iterator info_iter = mesh_info.begin(); + for(LLAvatarAppearance::mesh_info_t::iterator info_iter = mesh_info.begin(); info_iter != mesh_info.end(); ++info_iter) { const std::string& type = info_iter->first; - LLVOAvatar::lod_mesh_map_t& lod_mesh = info_iter->second; + LLAvatarAppearance::lod_mesh_map_t& lod_mesh = info_iter->second; LLMenuGL* type_menu = new LLMenuGL(type); - for(LLVOAvatar::lod_mesh_map_t::iterator lod_iter = lod_mesh.begin(); + for(LLAvatarAppearance::lod_mesh_map_t::iterator lod_iter = lod_mesh.begin(); lod_iter != lod_mesh.end(); ++lod_iter) { S32 lod = lod_iter->first; @@ -8929,6 +9075,10 @@ void handle_rebake_textures(void*) // Slam pending upload count to "unstick" things bool slam_for_debug = true; gAgentAvatarp->forceBakeAllTextures(slam_for_debug); + if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()) + { + LLAppearanceMgr::instance().requestServerAppearanceUpdate(); + } } void toggle_visibility(void* user_data) @@ -9066,7 +9216,7 @@ class LLEditTakeOff : public view_listener_t { std::string clothing = userdata.asString(); if (clothing == "all") - LLWearableBridge::removeAllClothesFromAvatar(); + LLAppearanceMgr::instance().removeAllClothesFromAvatar(); else { LLWearableType::EType type = LLWearableType::typeNameToType(clothing); @@ -9083,7 +9233,7 @@ class LLEditTakeOff : public view_listener_t // We'll use the first wearable we come across that can be removed (moving from top to bottom) for (; wearable_index >= 0; wearable_index--) { - const LLWearable* pWearable = gAgentWearables.getWearable(type, wearable_index); + const LLViewerWearable* pWearable = gAgentWearables.getViewerWearable(type, wearable_index); if (!gRlvWearableLocks.isLockedWearable(pWearable)) break; } @@ -9091,9 +9241,8 @@ class LLEditTakeOff : public view_listener_t return true; // No wearable found that can be removed } // [/RLVa:KB] - - LLViewerInventoryItem *item = dynamic_cast(gAgentWearables.getWearableInventoryItem(type,wearable_index)); - LLWearableBridge::removeItemFromAvatar(item); + LLUUID item_id = gAgentWearables.getWearableItemID(type,wearable_index); + LLAppearanceMgr::instance().removeItemFromAvatar(item_id); } } return true; @@ -9409,7 +9558,8 @@ void initialize_menus() addMenu(new LLToolsEnablePathfinding(), "Tools.EnablePathfinding"); addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView"); - + addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion"); + addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion"); /*addMenu(new LLToolsVisibleBuyObject(), "Tools.VisibleBuyObject"); addMenu(new LLToolsVisibleTakeObject(), "Tools.VisibleTakeObject");*/ @@ -9469,6 +9619,8 @@ void initialize_menus() addMenu(new LLObjectInspect(), "Object.Inspect"); // Visual mute, originally by Phox. addMenu(new LLObjectDerender(), "Object.DERENDER"); + addMenu(new LLAvatarReloadTextures(), "Avatar.ReloadTextures"); + addMenu(new LLObjectReloadTextures(), "Object.ReloadTextures"); addMenu(new LLObjectExport(), "Object.Export"); addMenu(new LLObjectImport(), "Object.Import"); addMenu(new LLObjectImportUpload(), "Object.ImportUpload"); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index fc795f8fb..b5a4863d3 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -527,6 +527,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t S32 width = gViewerWindow->getWindowDisplayWidth(); S32 height = gViewerWindow->getWindowDisplayHeight(); + F32 ratio = (F32)width / height; F32 supersample = 1.f; if (gSavedSettings.getBOOL("HighResSnapshot")) @@ -546,8 +547,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t if (gViewerWindow->rawSnapshot(raw, width, height, - TRUE, - FALSE, + ratio, gSavedSettings.getBOOL("RenderUIInSnapshot"), FALSE, LLViewerWindow::SNAPSHOT_TYPE_COLOR, @@ -574,7 +574,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t formatted->enableOverSize() ; formatted->encode(raw, 0); formatted->disableOverSize(); - gViewerWindow->saveImageNumbered(formatted); + gViewerWindow->saveImageNumbered(formatted, -1); } return true; } @@ -1155,7 +1155,7 @@ LLSD generate_new_resource_upload_capability_body(LLAssetType::EType asset_type, return body; } -void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, +bool upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, std::string name, std::string desc, S32 compression_info, LLFolderType::EType destination_folder_type, @@ -1166,11 +1166,12 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, - void *userdata) + void *userdata, + void (*callback2)(bool, void*)) { if(gDisconnected) { - return ; + return false; } @@ -1207,7 +1208,7 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty body["expected_upload_cost"] = LLSD::Integer(expected_upload_cost); LLHTTPClient::post(url, body, - new LLNewAgentInventoryResponder(body, uuid, asset_type)); + new LLNewAgentInventoryResponder(body, uuid, asset_type, callback2, userdata)); } else { @@ -1230,7 +1231,7 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol(); args["[AMOUNT]"] = llformat("%d", expected_upload_cost); LLFloaterBuyCurrency::buyCurrency( LLTrans::getString("UploadingCosts", args), expected_upload_cost ); - return; + return false; } } } @@ -1260,6 +1261,9 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty TRUE, temporary); } + + // Return true when a call to a callback function will follow. + return true; } LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid) diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 85bd7e166..426a5a4bf 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -66,7 +66,8 @@ void upload_new_resource(const std::string& src_filename, S32 expected_upload_cost, void *userdata); -void upload_new_resource(const LLTransactionID &tid, +// Return false if no upload attempt was done (and the callback will not be called). +bool upload_new_resource(const LLTransactionID &tid, LLAssetType::EType type, std::string name, std::string desc, @@ -79,7 +80,13 @@ void upload_new_resource(const LLTransactionID &tid, const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, - void *userdata); + void *userdata, + void (*callback2)(bool, void*) = NULL); + +// The default callback functions, called when 'callback' == NULL (for normal and temporary uploads). +// user_data must be a LLResourceData allocated with new (or NULL). +void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status); +void temp_upload_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status); LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index e3a98c636..b0dee6a7a 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -208,10 +208,12 @@ static const U32 LLREQUEST_PERMISSION_THROTTLE_LIMIT = 5; // requests static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL = 10.0f; // seconds extern BOOL gDebugClicks; +extern bool gShiftFrame; // function prototypes bool check_offer_throttle(const std::string& from_name, bool check_only); void callbackCacheEstateOwnerName(const LLUUID& id, const std::string& full_name, bool is_group); +static void process_money_balance_reply_extended(LLMessageSystem* msg); //inventory offer throttle globals LLFrameTimer gThrottleTimer; @@ -676,7 +678,6 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain) bool join_group_response(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - BOOL delete_context_data = TRUE; bool accept_invite = false; LLUUID group_id = notification["payload"]["group_id"].asUUID(); @@ -705,7 +706,6 @@ bool join_group_response(const LLSD& notification, const LLSD& response) } else { - delete_context_data = FALSE; LLSD args; args["NAME"] = name; args["INVITE"] = message; @@ -719,7 +719,6 @@ bool join_group_response(const LLSD& notification, const LLSD& response) // sure the user is sure they want to join. if (fee > 0) { - delete_context_data = FALSE; LLSD args; args["COST"] = llformat("%d", fee); // Set the fee for next time to 0, so that we don't keep @@ -2009,7 +2008,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // BOOL is_busy = gAgent.getBusy(); - BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat); + BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat) + // object IMs contain sender object id in session_id (STORM-1209) + || dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id); BOOL is_linden = LLMuteList::getInstance()->isLinden(name); BOOL is_owned_by_me = FALSE; @@ -2507,7 +2508,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType)); std::string from_name; - from_name += "A group member named "; + from_name += LLTrans::getString("AGroupMemberNamed") + " "; from_name += name; info->mFromName = from_name; @@ -3305,6 +3306,8 @@ protected: delete m_chat; } + /*virtual*/ char const* getName(void) const { return "ChatTranslationReceiver"; } + private: LLChat *m_chat; const BOOL m_history; @@ -3369,6 +3372,7 @@ protected: } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return authHandler_timeout; } + /*virtual*/ char const* getName(void) const { return "AuthHandler"; } }; void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) @@ -3632,29 +3636,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } } - - // [Ansariel/Henri: Display name support] if (chatter && chatter->isAvatar()) { - if (LLAvatarNameCache::useDisplayNames()) - { - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(from_id, &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - if (phoenix_name_system == 2 || (phoenix_name_system == 1 && avatar_name.mIsDisplayNameDefault)) - { - from_name = avatar_name.mDisplayName; - } - else - { - from_name = avatar_name.getCompleteName(); - } - } + if (LLAvatarNameCache::getPNSName(from_id, from_name)) chat.mFromName = from_name; - } } - // [/Ansariel/Henri: Display name support] BOOL visible_in_chat_bubble = FALSE; std::string verb; @@ -4221,6 +4207,7 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**) void process_agent_movement_complete(LLMessageSystem* msg, void**) { + gShiftFrame = true; gAgentMovementCompleted = true; LLUUID agent_id; @@ -5226,9 +5213,19 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) // Various hacks that aren't statistics, but are being handled here. // U32 max_tasks_per_region; - U32 region_flags; + U64 region_flags; msg->getU32("Region", "ObjectCapacity", max_tasks_per_region); - msg->getU32("Region", "RegionFlags", region_flags); + + if (msg->has(_PREHASH_RegionInfo)) + { + msg->getU64("RegionInfo", "RegionFlagsExtended", region_flags); + } + else + { + U32 flags = 0; + msg->getU32("Region", "RegionFlags", flags); + region_flags = flags; + } LLViewerRegion* regionp = gAgent.getRegion(); if (regionp) @@ -5400,7 +5397,10 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data) gAgentCamera.setForceMouselook(force_mouselook); // Forcing turning off flying here to prevent flying after pressing "Stand" // to stand up from an object. See EXT-1655. - gAgent.setFlying(FALSE); + // Unless the user wants to. + static LLCachedControl ContinueFlying("LiruContinueFlyingOnUnsit"); + if (!ContinueFlying) + gAgent.setFlying(FALSE); LLViewerObject* object = gObjectList.findObject(sitObjectID); if (object) @@ -5704,20 +5704,20 @@ void process_money_balance_reply( LLMessageSystem* msg, void** ) gStatusBar->setLandCredit(credit); gStatusBar->setLandCommitted(committed); } - static std::deque recent; - if(!desc.empty() && gSavedSettings.getBOOL("NotifyMoneyChange") - && (std::find(recent.rbegin(), recent.rend(), tid) == recent.rend())) - { - // Make the user confirm the transaction, since they might - // have missed something during an event. - // *TODO:translate - LLSD args; - args["MESSAGE"] = desc; - LLNotificationsUtil::add("SystemMessage", args); - // Also send notification to chat -- MC - LLChat chat(desc); - LLFloaterChat::addChat(desc); + if (desc.empty() + || !gSavedSettings.getBOOL("NotifyMoneyChange")) + { + // ...nothing to display + return; + } + + // Suppress duplicate messages about the same transaction + static std::deque recent; + if (std::find(recent.rbegin(), recent.rend(), tid) != recent.rend()) + { + return; + } // Once the 'recent' container gets large enough, chop some // off the beginning. @@ -5730,20 +5730,247 @@ void process_money_balance_reply( LLMessageSystem* msg, void** ) } //LL_DEBUGS("Messaging") << "Pushing back transaction " << tid << LL_ENDL; recent.push_back(tid); + + if (msg->has("TransactionInfo")) + { + // ...message has extended info for localization + process_money_balance_reply_extended(msg); + } + else + { + // Only old dev grids will not supply the TransactionInfo block, + // so we can just use the hard-coded English string. + LLSD args; + args["MESSAGE"] = desc; + LLNotificationsUtil::add("SystemMessage", args); + + // Also send notification to chat -- MC + LLChat chat(desc); + LLFloaterChat::addChat(desc); } } -bool handle_special_notification_callback(const LLSD& notification, const LLSD& response) +static std::string reason_from_transaction_type(S32 transaction_type, + const std::string& item_desc) +{ + // *NOTE: The keys for the reason strings are unusual because + // an earlier version of the code used English language strings + // extracted from hard-coded server English descriptions. + // Keeping them so we don't have to re-localize them. + switch (transaction_type) + { + case TRANS_OBJECT_SALE: + { + LLStringUtil::format_map_t arg; + arg["ITEM"] = item_desc; + return LLTrans::getString("for item", arg); + } + case TRANS_LAND_SALE: + return LLTrans::getString("for a parcel of land"); + + case TRANS_LAND_PASS_SALE: + return LLTrans::getString("for a land access pass"); + + case TRANS_GROUP_LAND_DEED: + return LLTrans::getString("for deeding land"); + + case TRANS_GROUP_CREATE: + return LLTrans::getString("to create a group"); + + case TRANS_GROUP_JOIN: + return LLTrans::getString("to join a group"); + + case TRANS_UPLOAD_CHARGE: + return LLTrans::getString("to upload"); + + case TRANS_CLASSIFIED_CHARGE: + return LLTrans::getString("to publish a classified ad"); + + // 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(); + + default: + llwarns << "Unknown transaction type " + << transaction_type << llendl; + return std::string(); + } +} + +static void process_money_balance_reply_extended(LLMessageSystem* msg) +{ + // Added in server 1.40 and viewer 2.1, support for localization + // and agent ids for name lookup. + S32 transaction_type = 0; + LLUUID source_id; + BOOL is_source_group = false; + LLUUID dest_id; + BOOL is_dest_group = false; + S32 amount = 0; + std::string item_description; + BOOL success = false; + + msg->getS32("TransactionInfo", "TransactionType", transaction_type); + msg->getUUID("TransactionInfo", "SourceID", source_id); + msg->getBOOL("TransactionInfo", "IsSourceGroup", is_source_group); + msg->getUUID("TransactionInfo", "DestID", dest_id); + msg->getBOOL("TransactionInfo", "IsDestGroup", is_dest_group); + msg->getS32("TransactionInfo", "Amount", amount); + msg->getString("TransactionInfo", "ItemDescription", item_description); + msg->getBOOL("MoneyData", "TransactionSuccess", success); + LL_INFOS("Money") << "MoneyBalanceReply source " << source_id + << " dest " << dest_id + << " type " << transaction_type + << " item " << item_description << LL_ENDL; + + if (source_id.isNull() && dest_id.isNull()) + { + // this is a pure balance update, no notification required + return; + } + + std::string source_slurl; + if (is_source_group) + { + gCacheName->getGroupName(source_id, source_slurl); + } + else + { + LLAvatarNameCache::getPNSName(source_id, source_slurl); + } + + std::string dest_slurl; + if (is_dest_group) + { + gCacheName->getGroupName(dest_id, dest_slurl); + } + else + { + LLAvatarNameCache::getPNSName(dest_id, dest_slurl); + } + + std::string reason = + reason_from_transaction_type(transaction_type, item_description); + + LLStringUtil::format_map_t args; + args["REASON"] = reason; // could be empty + args["AMOUNT"] = llformat("%d", amount); + + // Need to delay until name looked up, so need to know whether or not + // is group + bool is_name_group = false; + LLUUID name_id; + std::string message; + static LLCachedControl no_transaction_clutter("LiruNoTransactionClutter", false); + std::string notification = no_transaction_clutter ? "Payment" : "SystemMessage"; + LLSD final_args; + LLSD payload; + + bool you_paid_someone = (source_id == gAgentID); + if (you_paid_someone) + { + args["NAME"] = dest_slurl; + is_name_group = is_dest_group; + name_id = dest_id; + if (!reason.empty()) + { + if (dest_id.notNull()) + { + message = success ? LLTrans::getString("you_paid_ldollars", args) : + LLTrans::getString("you_paid_failure_ldollars", args); + } + else + { + // transaction fee to the system, eg, to create a group + message = success ? LLTrans::getString("you_paid_ldollars_no_name", args) : + LLTrans::getString("you_paid_failure_ldollars_no_name", args); + } + } + else + { + if (dest_id.notNull()) + { + message = success ? LLTrans::getString("you_paid_ldollars_no_reason", args) : + LLTrans::getString("you_paid_failure_ldollars_no_reason", args); + } + else + { + // no target, no reason, you just paid money + message = success ? LLTrans::getString("you_paid_ldollars_no_info", args) : + LLTrans::getString("you_paid_failure_ldollars_no_info", args); + } + } + final_args["MESSAGE"] = message; + } + else + { + // ...someone paid you + args["NAME"] = source_slurl; + is_name_group = is_source_group; + name_id = source_id; + if (!reason.empty()) + { + message = LLTrans::getString("paid_you_ldollars", args); + } + else + { + message = LLTrans::getString("paid_you_ldollars_no_reason", args); + } + final_args["MESSAGE"] = message; + + // make notification loggable + payload["from_id"] = source_id; + } + + // Despite using SLURLs, wait until the name is available before + // showing the notification, otherwise the UI layout is strange and + // the user sees a "Loading..." message + if (is_name_group) + { + gCacheName->getGroup(name_id, + boost::bind(&LLNotificationsUtil::add, + notification, final_args, payload)); + } + else + { + LLAvatarNameCache::get(name_id, + boost::bind(&LLNotificationsUtil::add, + notification, final_args, payload)); + } +} + +bool handle_prompt_for_maturity_level_change_callback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) { // set the preference to the maturity of the region we're calling - int preferredMaturity = notification["payload"]["_region_access"].asInteger(); - gSavedSettings.setU32("PreferredMaturity", preferredMaturity); - gAgent.sendMaturityPreferenceToServer(preferredMaturity); + U8 preferredMaturity = static_cast(notification["payload"]["_region_access"].asInteger()); + gSavedSettings.setU32("PreferredMaturity", static_cast(preferredMaturity)); + } + + return false; +} +bool handle_prompt_for_maturity_level_change_and_reteleport_callback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + if (0 == option) + { + // set the preference to the maturity of the region we're calling + U8 preferredMaturity = static_cast(notification["payload"]["_region_access"].asInteger()); + gSavedSettings.setU32("PreferredMaturity", static_cast(preferredMaturity)); + gAgent.setMaturityRatingChangeDuringTeleport(preferredMaturity); + gAgent.restartFailedTeleportRequest(); + } + else + { + gAgent.clearTeleportRequest(); } return false; @@ -5752,39 +5979,148 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD& // some of the server notifications need special handling. This is where we do that. bool handle_special_notification(std::string notificationID, LLSD& llsdBlock) { - int regionAccess = llsdBlock["_region_access"].asInteger(); - llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess); - - // we're going to throw the LLSD in there in case anyone ever wants to use it - LLNotificationsUtil::add(notificationID+"_Notify", llsdBlock); + U8 regionAccess = static_cast(llsdBlock["_region_access"].asInteger()); + std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); + LLStringUtil::toLower(regionMaturity); + llsdBlock["REGIONMATURITY"] = regionMaturity; + bool returnValue = false; + LLNotificationPtr maturityLevelNotification; + std::string notifySuffix = "_Notify"; if (regionAccess == SIM_ACCESS_MATURE) { if (gAgent.isTeen()) { - LLNotificationsUtil::add(notificationID+"_KB", llsdBlock); - return true; + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; } else if (gAgent.prefersPG()) { - LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback); - return true; + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock); + returnValue = true; } } else if (regionAccess == SIM_ACCESS_ADULT) { if (!gAgent.isAdult()) { - LLNotificationsUtil::add(notificationID+"_KB", llsdBlock); - return true; + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; } else if (gAgent.prefersPG() || gAgent.prefersMature()) { - LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback); - return true; + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock); + returnValue = true; } } - return false; + + if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) + { + // Given a simple notification if no maturityLevelNotification is set or it is ignore + LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock); + } + + return returnValue; +} + +// some of the server notifications need special handling. This is where we do that. +bool handle_teleport_access_blocked(LLSD& llsdBlock) +{ + std::string notificationID("TeleportEntryAccessBlocked"); + U8 regionAccess = static_cast(llsdBlock["_region_access"].asInteger()); + std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); + LLStringUtil::toLower(regionMaturity); + llsdBlock["REGIONMATURITY"] = regionMaturity; + + bool returnValue = false; + LLNotificationPtr maturityLevelNotification; + std::string notifySuffix = "_Notify"; + if (regionAccess == SIM_ACCESS_MATURE) + { + if (gAgent.isTeen()) + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; + } + else if (gAgent.prefersPG()) + { + if (gAgent.hasRestartableFailedTeleportRequest()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + returnValue = true; + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + else if (regionAccess == SIM_ACCESS_ADULT) + { + if (!gAgent.isAdult()) + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; + } + else if (gAgent.prefersPG() || gAgent.prefersMature()) + { + if (gAgent.hasRestartableFailedTeleportRequest()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + returnValue = true; + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + + if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) + { + // Given a simple notification if no maturityLevelNotification is set or it is ignore + LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock); + } + + return returnValue; } bool attempt_standard_notification(LLMessageSystem* msgsystem) @@ -5828,16 +6164,20 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) RegionEntryAccessBlocked RegionEntryAccessBlocked_Notify + RegionEntryAccessBlocked_NotifyAdultsOnly RegionEntryAccessBlocked_Change - RegionEntryAccessBlocked_KB + RegionEntryAccessBlocked_AdultsOnlyContent + RegionEntryAccessBlocked_ChangeAndReTeleport LandClaimAccessBlocked LandClaimAccessBlocked_Notify + LandClaimAccessBlocked_NotifyAdultsOnly LandClaimAccessBlocked_Change - LandClaimAccessBlocked_KB + LandClaimAccessBlocked_AdultsOnlyContent LandBuyAccessBlocked LandBuyAccessBlocked_Notify + LandBuyAccessBlocked_NotifyAdultsOnly LandBuyAccessBlocked_Change - LandBuyAccessBlocked_KB + LandBuyAccessBlocked_AdultsOnlyContent -----------------------------------------------------------------------*/ if (handle_special_notification(notificationID, llsdBlock)) @@ -5889,6 +6229,30 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data) } } +bool handle_not_age_verified_alert(const std::string &pAlertName) +{ + LLNotificationPtr notification = LLNotificationsUtil::add(pAlertName); + if ((notification == NULL) || notification->isIgnored()) + { + LLNotificationsUtil::add(pAlertName + "_Notify"); + } + + return true; +} + +bool handle_special_alerts(const std::string &pAlertName) +{ + bool isHandled = false; + + if (LLStringUtil::compareStrings(pAlertName, "NotAgeVerified") == 0) + { + + isHandled = handle_not_age_verified_alert(pAlertName); + } + + return isHandled; +} + void process_alert_core(const std::string& message, BOOL modal) { // HACK -- handle callbacks for specific alerts @@ -5912,7 +6276,10 @@ void process_alert_core(const std::string& message, BOOL modal) // Allow the server to spawn a named alert so that server alerts can be // translated out of English. std::string alert_name(message.substr(ALERT_PREFIX.length())); - LLNotificationsUtil::add(alert_name); + if (!handle_special_alerts(alert_name)) + { + LLNotificationsUtil::add(alert_name); + } } else if (message.find(NOTIFY_PREFIX) == 0) { @@ -6213,6 +6580,7 @@ bool script_question_cb(const LLSD& notification, const LLSD& response) // ...with description on top LLNotificationsUtil::add("DebitPermissionDetails"); + return false; } // check whether permissions were granted or denied @@ -6581,7 +6949,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**) else { // change notification name in this special case - if (handle_special_notification("RegionEntryAccessBlocked", llsd_block)) + if (handle_teleport_access_blocked(llsd_block)) { if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) { @@ -6650,8 +7018,9 @@ void process_teleport_local(LLMessageSystem *msg,void**) } } + static LLCachedControl fly_after_tp(gSavedSettings, "LiruFlyAfterTeleport"); // Sim tells us whether the new position is off the ground - if (teleport_flags & TELEPORT_FLAGS_IS_FLYING) + if (fly_after_tp || (teleport_flags & TELEPORT_FLAGS_IS_FLYING)) { gAgent.setFlying(TRUE); } @@ -7044,40 +7413,35 @@ void process_script_dialog(LLMessageSystem* msg, void**) } else { - for (i = 1; i < button_count; i++) - { - std::string tdesc; - msg->getString("Buttons", "ButtonLabel", tdesc, i); - form.addElement("button", std::string(tdesc)); - } + for (i = 1; i < button_count; i++) + { + std::string tdesc; + msg->getString("Buttons", "ButtonLabel", tdesc, i); + form.addElement("button", std::string(tdesc)); + } } LLSD args; args["TITLE"] = object_name; args["MESSAGE"] = message; - // args["CHANNEL"] = chat_channel; - // LLNotificationPtr notification; - if (!first_name.empty()) + bool const is_group = first_name.empty(); + char const* name = (is_group && !is_text_box) ? "GROUPNAME" : "NAME"; + args[name] = is_group ? last_name : LLCacheName::buildFullName(first_name, last_name); + if (is_text_box) + { + args["DEFAULT"] = default_text; + payload["textbox"] = "true"; + LLNotificationsUtil::add("ScriptTextBoxDialog", args, payload, callback_script_dialog); + } + else if (!first_name.empty()) { - args["NAME"] = LLCacheName::buildFullName(first_name, last_name); - - if (is_text_box) - { - args["DEFAULT"] = default_text; - payload["textbox"] = "true"; - LLNotificationsUtil::add("ScriptTextBoxDialog", args, payload, callback_script_dialog); - } - else - { notification = LLNotifications::instance().add( LLNotification::Params("ScriptDialog").substitutions(args).payload(payload).form_elements(form.asLLSD())); } - } else { - args["GROUPNAME"] = last_name; notification = LLNotifications::instance().add( LLNotification::Params("ScriptDialogGroup").substitutions(args).payload(payload).form_elements(form.asLLSD())); } diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index a2625495c..dde9a9d47 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -77,6 +77,7 @@ bool LLViewerLogin::isSecondLife() bool LLViewerLogin::isInProductionGrid() { - return true; + // Return true (as before) on opensim grids, but return the real thing (agni or not) on SL. + return !gHippoGridManager->getConnectedGrid()->isSecondLife() || gHippoGridManager->getConnectedGrid()->isInProductionGrid(); } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e917727d1..0bdee81c3 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -205,6 +205,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mID(id), mLocalID(0), mTotalCRC(0), + mListIndex(-1), mTEImages(NULL), mGLName(0), mbCanSelect(TRUE), @@ -242,6 +243,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mTimeDilation(1.f), mRotTime(0.f), mAngularVelocityRot(), + mPreviousRotation(), mState(0), mMedia(NULL), mClickAction(0), @@ -271,7 +273,12 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe { mPositionAgent = mRegionp->getOriginAgent(); } - resetRot(); + + static const LLCachedControl use_new_target_omega ("UseNewTargetOmegaCode", true); + if (use_new_target_omega) + { + resetRot(); + } LLViewerObject::sNumObjects++; } @@ -809,6 +816,12 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp) } LLDrawable* old_parent = mDrawable->mParent; mDrawable->mParent = parentp; + + if (parentp && mDrawable->isActive()) + { + parentp->makeActive(); + parentp->setState(LLDrawable::ACTIVE_CHILD); + } gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); if( (old_parent != parentp && old_parent) @@ -1258,11 +1271,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, mText->setString(mHudTextString); } - if (mDrawable.notNull()) - { - setChanged(MOVED | SILHOUETTE); - gPipeline.markMoved(mDrawable, FALSE); // undamped - } + setChanged(MOVED | SILHOUETTE); } else if (mText.notNull()) { @@ -1435,9 +1444,10 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #else val = (U16 *) &data[count]; #endif - setAngularVelocity( U16_to_F32(val[VX], -size, size), + new_angv.set(U16_to_F32(val[VX], -size, size), U16_to_F32(val[VY], -size, size), U16_to_F32(val[VZ], -size, size)); + setAngularVelocity(new_angv); break; case 16: @@ -2104,17 +2114,49 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, } } - if (new_rot != getRotation() - || new_angv != old_angv) - { - if (new_angv != old_angv) + static const LLCachedControl use_new_target_omega ("UseNewTargetOmegaCode", true); + if (use_new_target_omega) + { // New, experimental code + if ((new_rot != getRotation()) || (new_angv != old_angv)) { + if (new_rot != mPreviousRotation) + { + resetRot(); + } + else if (new_angv != old_angv) + { + if (flagUsePhysics()) + { + resetRot(); + } + else + { + mRotTime = 0.0f; + } + } + + // Remember the last rotation value + mPreviousRotation = new_rot; + + // Set the rotation of the object followed by adjusting for the accumulated angular velocity (llSetTargetOmega) + setRotation(new_rot * mAngularVelocityRot); + setChanged(ROTATED | SILHOUETTE); + } + } + else + { // Old code + if (new_rot != mPreviousRotation || new_angv != old_angv) + { + if (new_rot != mPreviousRotation) + { + mPreviousRotation = new_rot; + setRotation(new_rot); + } + + setChanged(ROTATED | SILHOUETTE); + resetRot(); } - - // Set the rotation of the object followed by adjusting for the accumulated angular velocity (llSetTargetOmega) - setRotation(new_rot * mAngularVelocityRot); - setChanged(ROTATED | SILHOUETTE); } @@ -2132,9 +2174,15 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, gPipeline.addDebugBlip(getPositionAgent(), color); } - if ((0.0f == vel_mag_sq) && - (0.0f == accel_mag_sq) && - (0.0f == getAngularVelocity().magVecSquared())) + const F32 MAG_CUTOFF = F_APPROXIMATELY_ZERO; + + llassert(vel_mag_sq >= 0.f); + llassert(accel_mag_sq >= 0.f); + llassert(getAngularVelocity().magVecSquared() >= 0.f); + + if ((MAG_CUTOFF >= vel_mag_sq) && + (MAG_CUTOFF >= accel_mag_sq) && + (MAG_CUTOFF >= getAngularVelocity().magVecSquared())) { mStatic = TRUE; // This object doesn't move! } @@ -2208,17 +2256,15 @@ BOOL LLViewerObject::isActive() const return TRUE; } -BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) + + +void LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { //static LLFastTimer::DeclareTimer ftm("Viewer Object"); //LLFastTimer t(ftm); - if (mDead) + if (!mDead) { - // It's dead. Don't update it. - return TRUE; - } - // CRO - don't velocity interp linked objects! // Leviathan - but DO velocity interp joints if (!mStatic && sVelocityInterpolate && !isSelected()) @@ -2227,12 +2273,12 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) F32 dt_raw = (F32)(time - mLastInterpUpdateSecs); F32 dt = mTimeDilation * dt_raw; - applyAngularVelocity(dt); + applyAngularVelocity(dt); - if (isAttachment()) - { - mLastInterpUpdateSecs = time; - return TRUE; + if (isAttachment()) + { + mLastInterpUpdateSecs = time; + return; } else { // Move object based on it's velocity and rotation @@ -2241,8 +2287,7 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } updateDrawable(FALSE); - - return TRUE; +} } @@ -3342,14 +3387,14 @@ void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */) S32 tex_count = getNumTEs(); for (i = 0; i < tex_count; i++) { - getTEImage(i)->setBoostLevel(LLViewerTexture::BOOST_SELECTED); + getTEImage(i)->setBoostLevel(LLGLTexture::BOOST_SELECTED); } if (isSculpted() && !isMesh()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); LLUUID sculpt_id = sculpt_params->getSculptTexture(); - LLViewerTextureManager::getFetchedTexture(sculpt_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLViewerTexture::BOOST_SELECTED); + LLViewerTextureManager::getFetchedTexture(sculpt_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED); } if (boost_children) @@ -4112,7 +4157,7 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) // if (mDrawable.notNull() && mDrawable->isVisible()) // { const LLUUID& image_id = getTE(te)->getID(); - mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); // } } @@ -4131,6 +4176,23 @@ void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) } +S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, const std::string &url ) +{ + S32 retval = 0; + if (uuid != getTE(te)->getID() || + uuid == LLUUID::null) + { + retval = LLPrimitive::setTETexture(te, uuid); + mTEImages[te] = LLViewerTextureManager::getFetchedTextureFromUrl (url, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid); + setChanged(TEXTURE); + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + } + } + return retval; +} + S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host) { S32 retval = 0; @@ -4138,7 +4200,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos uuid == LLUUID::null) { retval = LLPrimitive::setTETexture(te, uuid); - mTEImages[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); + mTEImages[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); setChanged(TEXTURE); if (mDrawable.notNull()) { @@ -5450,9 +5512,12 @@ BOOL LLViewerObject::setFlagsWithoutUpdate(U32 flags, BOOL state) void LLViewerObject::setPhysicsShapeType(U8 type) { mPhysicsShapeUnknown = false; + if (type != mPhysicsShapeType) + { mPhysicsShapeType = type; mCostStale = true; } +} void LLViewerObject::setPhysicsGravity(F32 gravity) { @@ -5478,7 +5543,6 @@ U8 LLViewerObject::getPhysicsShapeType() const { if (mPhysicsShapeUnknown) { - mPhysicsShapeUnknown = false; gObjectList.updatePhysicsFlags(this); } @@ -5503,8 +5567,12 @@ void LLViewerObject::applyAngularVelocity(F32 dt) // calculate the delta increment based on the object's angular velocity dQ.setQuat(angle, ang_vel); - // accumulate the angular velocity rotations to re-apply in the case of an object update - mAngularVelocityRot *= dQ; + static const LLCachedControl use_new_target_omega ("UseNewTargetOmegaCode", true); + if (use_new_target_omega) + { + // accumulate the angular velocity rotations to re-apply in the case of an object update + mAngularVelocityRot *= dQ; + } // Just apply the delta increment to the current rotation setRotation(getRotation()*dQ); @@ -5516,8 +5584,28 @@ void LLViewerObject::resetRot() { mRotTime = 0.0f; - // Reset the accumulated angular velocity rotation - mAngularVelocityRot.loadIdentity(); + static const LLCachedControl use_new_target_omega ("UseNewTargetOmegaCode", true); + if(use_new_target_omega) + { + // Reset the accumulated angular velocity rotation + mAngularVelocityRot.loadIdentity(); + } +} + +//virtual +void LLViewerObject::setSelected(BOOL sel) +{ + mUserSelected = sel; + + static const LLCachedControl use_new_target_omega ("UseNewTargetOmegaCode", true); + if(use_new_target_omega) + { + resetRot(); + } + else + { + mRotTime = 0.f; + } } U32 LLViewerObject::getPartitionType() const diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 791393533..f2c90c36c 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -150,7 +150,7 @@ public: LLNameValue* getNVPair(const std::string& name) const; // null if no name value pair by that name // Object create and update functions - virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Types of media we can associate enum { MEDIA_NONE = 0, MEDIA_SET = 1 }; @@ -214,11 +214,13 @@ public: LLViewerRegion* getRegion() const { return mRegionp; } BOOL isSelected() const { return mUserSelected; } - virtual void setSelected(BOOL sel) { mUserSelected = sel; mRotTime = 0.f;} + void setSelected(BOOL sel); const LLUUID &getID() const { return mID; } U32 getLocalID() const { return mLocalID; } U32 getCRC() const { return mTotalCRC; } + S32 getListIndex() const { return mListIndex; } + void setListIndex(S32 idx) { mListIndex = idx; } virtual BOOL isFlexible() const { return FALSE; } virtual BOOL isSculpted() const { return FALSE; } @@ -306,6 +308,7 @@ public: /*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry); /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid); S32 setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host); + S32 setTETextureCore(const U8 te, const LLUUID& uuid, const std::string &url ); /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color); /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color); /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t); @@ -603,6 +606,9 @@ public: // Last total CRC received from sim, used for caching U32 mTotalCRC; + // index into LLViewerObjectList::mActiveObjects or -1 if not in list + S32 mListIndex; + LLPointer *mTEImages; // Selection, picking and rendering variables @@ -737,6 +743,7 @@ protected: F32 mTimeDilation; // Time dilation sent with the object. F32 mRotTime; // Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega) LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations + LLQuaternion mPreviousRotation; U8 mState; // legacy LLViewerObjectMedia* mMedia; // NULL if no media associated diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp index e08968f42..5edd111f2 100644 --- a/indra/newview/llviewerobjectbackup.cpp +++ b/indra/newview/llviewerobjectbackup.cpp @@ -111,7 +111,7 @@ void setDefaultTextures() } } -class importResponder: public LLNewAgentInventoryResponder +class importResponder : public LLNewAgentInventoryResponder { public: @@ -191,6 +191,8 @@ public: LLObjectBackup::getInstance()->updateMap(content["new_asset"].asUUID()); LLObjectBackup::getInstance()->uploadNextAsset(); } + + /*virtual*/ char const* getName(void) const { return "importResponder"; } }; class CacheReadResponder : public LLTextureCache::ReadResponder @@ -775,10 +777,10 @@ void LLObjectBackup::exportNextTexture() S32 cur_discard = imagep->getDiscardLevel(); if (cur_discard > 0) { - if (imagep->getBoostLevel() != LLViewerTexture::BOOST_PREVIEW) + if (imagep->getBoostLevel() != LLGLTexture::BOOST_PREVIEW) { // we want to force discard 0: this one does this. - imagep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); + imagep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); } } else diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index a53805fe8..ae919f7f7 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -56,6 +56,8 @@ #include "llstring.h" #include "llhudnametag.h" #include "lldrawable.h" +#include "llflexibleobject.h" +#include "llviewertextureanim.h" #include "xform.h" #include "llsky.h" #include "llviewercamera.h" @@ -90,6 +92,8 @@ extern BOOL gAnimateTextures; #include "importtracker.h" extern ImportTracker gImportTracker; +#define MAX_CONCURRENT_PHYSICS_REQUESTS 256 + void dialog_refresh_all(); class AIHTTPTimeoutPolicy; @@ -331,9 +335,12 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, // have to transform to absolute coordinates. num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); + // I don't think this case is ever hit. TODO* Test this. if (!cached && !compressed && update_type != OUT_FULL) { + //llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl; gTerseObjectUpdates += num_objects; + /* S32 size; if (mesgsys->getReceiveCompressedSize()) { @@ -343,10 +350,12 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, { size = mesgsys->getReceiveSize(); } - // llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl; + llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl; + */ } else { + /* S32 size; if (mesgsys->getReceiveCompressedSize()) { @@ -357,7 +366,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, size = mesgsys->getReceiveSize(); } - // llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl; + llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl; + */ gFullObjectUpdates += num_objects; } @@ -710,7 +720,7 @@ public: } } - void error(U32 statusNum, const std::string& reason) + /*virtual*/ void error(U32 statusNum, const std::string& reason) { llwarns << "Transport error requesting object cost " @@ -722,7 +732,7 @@ public: clear_object_list_pending_requests(); } - void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { if ( !content.isMap() || content.has("error") ) { @@ -772,7 +782,8 @@ public: } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return objectCostResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return objectCostResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLObjectCostResponder"; } private: LLSD mObjectIDs; @@ -800,7 +811,7 @@ public: } } - void error(U32 statusNum, const std::string& reason) + /*virtual*/ void error(U32 statusNum, const std::string& reason) { llwarns << "Transport error requesting object physics flags " @@ -812,7 +823,7 @@ public: clear_object_list_pending_requests(); } - void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { if ( !content.isMap() || content.has("error") ) { @@ -869,7 +880,8 @@ public: } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return physicsFlagsResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return physicsFlagsResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLPhysicsFlagsResponder"; } private: LLSD mObjectIDs; @@ -924,26 +936,35 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) const F64 frame_time = LLFrameTimer::getElapsedSeconds(); - std::vector kill_list; - S32 num_active_objects = 0; LLViewerObject *objectp = NULL; // Make a copy of the list in case something in idleUpdate() messes with it - std::vector idle_list; - + static std::vector idle_list; + if(mActiveObjects.size() > idle_list.capacity()) + idle_list.reserve( mActiveObjects.size() ); + + U32 idle_count = 0; + static LLFastTimer::DeclareTimer idle_copy("Idle Copy"); { LLFastTimer t(idle_copy); - idle_list.reserve( mActiveObjects.size() ); - for (std::set >::iterator active_iter = mActiveObjects.begin(); + for (std::vector >::iterator active_iter = mActiveObjects.begin(); active_iter != mActiveObjects.end(); active_iter++) { objectp = *active_iter; if (objectp) { - idle_list.push_back( objectp ); + if (idle_count >= idle_list.size()) + { + idle_list.push_back( objectp ); + } + else + { + idle_list[idle_count] = objectp; + } + ++idle_count; } else { // There shouldn't be any NULL pointers in the list, but they have caused @@ -952,12 +973,14 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) } } } + + std::vector::iterator idle_end = idle_list.begin()+idle_count; static const LLCachedControl freeze_time("FreezeTime",0); if (freeze_time) { for (std::vector::iterator iter = idle_list.begin(); - iter != idle_list.end(); iter++) + iter != idle_end; iter++) { objectp = *iter; if ( @@ -973,27 +996,23 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) else { for (std::vector::iterator idle_iter = idle_list.begin(); - idle_iter != idle_list.end(); idle_iter++) + idle_iter != idle_end; idle_iter++) { objectp = *idle_iter; - if (!objectp->idleUpdate(agent, world, frame_time)) - { - // If Idle Update returns false, kill object! - kill_list.push_back(objectp); - } - else - { - num_active_objects++; - } - } - for (std::vector::iterator kill_iter = kill_list.begin(); - kill_iter != kill_list.end(); kill_iter++) - { - objectp = *kill_iter; - killObject(objectp); + llassert(objectp->isActive()); + objectp->idleUpdate(agent, world, frame_time); + } + + //update flexible objects + LLVolumeImplFlexible::updateClass(); + + //update animated textures + LLViewerTextureAnim::updateClass(); } + + fetchObjectCosts(); fetchPhysicsFlags(); @@ -1060,7 +1079,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) */ LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size() - mNumDeadObjects); - LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(num_active_objects); + LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count); LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled); LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled); } @@ -1081,8 +1100,6 @@ void LLViewerObjectList::fetchObjectCosts() LLSD id_list; U32 object_index = 0; - U32 count = 0; - for ( std::set::iterator iter = mStaleObjectCost.begin(); iter != mStaleObjectCost.end(); @@ -1099,7 +1116,7 @@ void LLViewerObjectList::fetchObjectCosts() mStaleObjectCost.erase(iter++); - if (count++ >= 450) + if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS) { break; } @@ -1144,7 +1161,7 @@ void LLViewerObjectList::fetchPhysicsFlags() for ( std::set::iterator iter = mStalePhysicsFlags.begin(); iter != mStalePhysicsFlags.end(); - ++iter) + ) { // Check to see if a request for this object // has already been made. @@ -1154,12 +1171,14 @@ void LLViewerObjectList::fetchPhysicsFlags() mPendingPhysicsFlags.insert(*iter); id_list[object_index++] = *iter; } - } - // id_list should now contain all - // requests in mStalePhysicsFlags before, so clear - // it now - mStalePhysicsFlags.clear(); + mStalePhysicsFlags.erase(iter++); + + if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS) + { + break; + } + } if ( id_list.size() > 0 ) { @@ -1226,7 +1245,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) { //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list in cleanupReferences." << llendl; objectp->setOnActiveList(FALSE); - mActiveObjects.erase(objectp); + removeFromActiveList(objectp); } if (objectp->isOnMap()) @@ -1329,7 +1348,7 @@ void LLViewerObjectList::killAllObjects() killObject(objectp); // Object must be dead, or it's the LLVOAvatarSelf which never dies. - llassert((objectp == gAgentAvatarp) || objectp->isDead()); + llassert((objectp == gAgentAvatarp) || objectp->isDead() || (objectp->asAvatar() && objectp->asAvatar()->isFrozenDead())); } cleanDeadObjects(FALSE); @@ -1416,6 +1435,27 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) mNumDeadObjects = 0; } +void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) +{ + S32 idx = objectp->getListIndex(); + if (idx != -1) + { //remove by moving last element to this object's position + llassert(mActiveObjects[idx] == objectp); + + objectp->setListIndex(-1); + + S32 last_index = mActiveObjects.size()-1; + + if (idx != last_index) + { + mActiveObjects[idx] = mActiveObjects[last_index]; + mActiveObjects[idx]->setListIndex(idx); + } + + mActiveObjects.pop_back(); + } +} + void LLViewerObjectList::updateActive(LLViewerObject *objectp) { LLMemType mt(LLMemType::MTYPE_OBJECT); @@ -1430,16 +1470,35 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) if (active) { //llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl; - mActiveObjects.insert(objectp); - objectp->setOnActiveList(TRUE); + S32 idx = objectp->getListIndex(); + if (idx <= -1) + { + mActiveObjects.push_back(objectp); + objectp->setListIndex(mActiveObjects.size()-1); + objectp->setOnActiveList(TRUE); + } + else + { + llassert(idx < (S32)mActiveObjects.size()); + llassert(mActiveObjects[idx] == objectp); + + if (idx >= (S32)mActiveObjects.size() || + mActiveObjects[idx] != objectp) + { + llwarns << "Invalid object list index detected!" << llendl; + } + } } else { //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list." << llendl; - mActiveObjects.erase(objectp); + removeFromActiveList(objectp); objectp->setOnActiveList(FALSE); } } + + llassert(objectp->isActive() || objectp->getListIndex() == -1); + } void LLViewerObjectList::updateObjectCost(LLViewerObject* object) diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 9266dcf2d..5a48656b7 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -128,7 +128,9 @@ public: void dirtyAllObjectInventory(); + void removeFromActiveList(LLViewerObject* objectp); void updateActive(LLViewerObject *objectp); + void updateAvatarVisibility(); // Selection related stuff @@ -206,7 +208,7 @@ public: typedef std::vector > vobj_list_t; vobj_list_t mObjects; - std::set > mActiveObjects; + std::vector > mActiveObjects; vobj_list_t mMapObjects; diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 49cd7a1a3..b95a96ad3 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -106,7 +106,6 @@ void LLViewerParcelMedia::update(LLParcel* parcel) } // we're in a parcel - bool new_parcel = false; S32 parcelid = parcel->getLocalID(); LLUUID regionid = gAgent.getRegion()->getRegionID(); @@ -115,7 +114,6 @@ void LLViewerParcelMedia::update(LLParcel* parcel) LL_DEBUGS("Media") << "New parcel, parcel id = " << parcelid << ", region id = " << regionid << LL_ENDL; sMediaParcelLocalID = parcelid; sMediaRegionID = regionid; - new_parcel = true; } std::string mediaUrl = std::string ( parcel->getMediaURL () ); diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 9ed016d71..2a42b7661 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -120,7 +120,7 @@ LLViewerParcelMgr::LLViewerParcelMgr() mRequestResult(0), mWestSouth(), mEastNorth(), - mSelectedDwell(0.f), + mSelectedDwell(DWELL_NAN), mAgentParcelSequenceID(-1), mHoverRequestResult(0), mHoverWestSouth(), @@ -244,7 +244,7 @@ void LLViewerParcelMgr::getDisplayInfo(S32* area_out, S32* claim_out, S32 price = 0; S32 rent = 0; BOOL for_sale = FALSE; - F32 dwell = 0.f; + F32 dwell = DWELL_NAN; if (mSelected) { @@ -590,7 +590,7 @@ void LLViewerParcelMgr::deselectLand() mCurrentParcel->mBanList.clear(); //mCurrentParcel->mRenterList.reset(); - mSelectedDwell = 0.f; + mSelectedDwell = DWELL_NAN; // invalidate parcel selection so that existing users of this selection can clean up mCurrentParcelSelection->setParcel(NULL); @@ -710,8 +710,8 @@ bool LLViewerParcelMgr::allowAgentScripts(const LLViewerRegion* region, const LL // This mirrors the traditional menu bar parcel icon code, but is not // technically correct. return region - && !(region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) - && !(region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) + && !region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS) + && !region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS) && parcel && parcel->getAllowOtherScripts(); } @@ -1679,7 +1679,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use parcel_mgr.sendParcelAccessListRequest(AL_ACCESS | AL_BAN); // Request dwell for this land, if it's not public land. - parcel_mgr.mSelectedDwell = 0.f; + parcel_mgr.mSelectedDwell = DWELL_NAN; if (0 != local_id) { parcel_mgr.sendParcelDwellRequest(); @@ -2080,7 +2080,7 @@ void LLViewerParcelMgr::startReleaseLand() return; } /* - if ((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) + if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL) && !gAgent.isGodlike()) { LLSD args; @@ -2324,7 +2324,7 @@ void LLViewerParcelMgr::startDeedLandToGroup() /* if(!gAgent.isGodlike()) { - if((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) + if(region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL) && (mCurrentParcel->getOwnerID() != region->getOwner())) { LLSD args; diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 49571f80a..5ae44e2d0 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -46,6 +46,8 @@ class LLParcel; class LLViewerTexture; class LLViewerRegion; +const F32 DWELL_NAN = -1.0f; // A dwell having this value will be displayed as Loading... + // Constants for sendLandOwner //const U32 NO_NEIGHBOR_JOIN = 0x0; //const U32 ALL_NEIGHBOR_JOIN = U32( NORTH_MASK diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 94a2968b4..6a8de2595 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -710,7 +710,9 @@ void LLViewerPartSim::updateSimulation() if (mViewerPartSources[i]->isDead()) { - mViewerPartSources.erase(mViewerPartSources.begin() + i); + mViewerPartSources[i] = mViewerPartSources.back(); + mViewerPartSources.pop_back(); + //mViewerPartSources.erase(mViewerPartSources.begin() + i); count--; i+=deldir; } @@ -727,7 +729,7 @@ void LLViewerPartSim::updateSimulation() LLViewerObject* vobj = mViewerPartGroups[i]->mVOPartGroupp; S32 visirate = 1; - if (vobj) + if (vobj && vobj->mDrawable.notNull()) { LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup(); if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY)) @@ -738,7 +740,7 @@ void LLViewerPartSim::updateSimulation() if ((LLDrawable::getCurrentFrame()+mViewerPartGroups[i]->mID)%visirate == 0) { - if (vobj) + if (vobj && vobj->mDrawable.notNull()) { gPipeline.markRebuild(vobj->mDrawable, LLDrawable::REBUILD_ALL, TRUE); } @@ -747,7 +749,9 @@ void LLViewerPartSim::updateSimulation() if (!mViewerPartGroups[i]->getCount()) { delete mViewerPartGroups[i]; - mViewerPartGroups.erase(mViewerPartGroups.begin() + i); + mViewerPartGroups[i] = mViewerPartGroups.back(); + mViewerPartGroups.pop_back(); + //mViewerPartGroups.erase(mViewerPartGroups.begin() + i); i--; count--; } @@ -831,14 +835,16 @@ void LLViewerPartSim::removeLastCreatedSource() void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) { LLMemType mt(LLMemType::MTYPE_PARTICLES); - for (group_list_t::iterator i = mViewerPartGroups.begin(); i != mViewerPartGroups.end(); ) - { - group_list_t::iterator iter = i++; - if ((*iter)->getRegion() == regionp) + group_list_t& vec = mViewerPartGroups; + for (group_list_t::size_type i = 0;igetRegion() == regionp) { - delete *iter; - i = mViewerPartGroups.erase(iter); + delete vec[i]; + vec[i--] = vec.back(); + vec.pop_back(); + //i = mViewerPartGroups.erase(iter); } } } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 7df9352f6..0aeaf9878 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -219,7 +219,7 @@ public: virtual ~BaseCapabilitiesComplete() { } - void error(U32 statusNum, const std::string& reason) + /*virtual*/ void error(U32 statusNum, const std::string& reason) { LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL; LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); @@ -229,7 +229,7 @@ public: } } - void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); if(!regionp) //region was removed @@ -265,7 +265,8 @@ public: } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return baseCapabilitiesComplete_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return baseCapabilitiesComplete_timeout; } + /*virtual*/ char const* getName(void) const { return "BaseCapabilitiesComplete"; } static boost::intrusive_ptr build( U64 region_handle, S32 id ) { @@ -291,9 +292,11 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mZoning(""), mIsEstateManager(FALSE), mRegionFlags( REGION_FLAGS_DEFAULT ), + mRegionProtocols( 0 ), mSimAccess( SIM_ACCESS_MIN ), mBillableFactor(1.0), mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT), + mCentralBakeVersion(0), mClassID(0), mCPURatio(0), mColoName("unknown"), @@ -472,18 +475,6 @@ void LLViewerRegion::sendReliableMessage() gMessageSystem->sendReliable(mImpl->mHost); } -void LLViewerRegion::setFlags(BOOL b, U32 flags) -{ - if (b) - { - mRegionFlags |= flags; - } - else - { - mRegionFlags &= ~flags; - } -} - void LLViewerRegion::setWaterHeight(F32 water_level) { mImpl->mLandp->setWaterHeight(water_level); @@ -496,10 +487,10 @@ F32 LLViewerRegion::getWaterHeight() const BOOL LLViewerRegion::isVoiceEnabled() const { - return (getRegionFlags() & REGION_FLAGS_ALLOW_VOICE); + return getRegionFlag(REGION_FLAGS_ALLOW_VOICE); } -void LLViewerRegion::setRegionFlags(U32 flags) +void LLViewerRegion::setRegionFlags(U64 flags) { mRegionFlags = flags; } @@ -595,7 +586,7 @@ std::string LLViewerRegion::getLocalizedSimProductName() const } // static -std::string LLViewerRegion::regionFlagsToString(U32 flags) +std::string LLViewerRegion::regionFlagsToString(U64 flags) { std::string result; @@ -720,6 +711,31 @@ std::string LLViewerRegion::accessToShortString(U8 sim_access) } } +// static +U8 LLViewerRegion::shortStringToAccess(const std::string &sim_access) +{ + U8 accessValue; + + if (LLStringUtil::compareStrings(sim_access, "PG") == 0) + { + accessValue = SIM_ACCESS_PG; + } + else if (LLStringUtil::compareStrings(sim_access, "M") == 0) + { + accessValue = SIM_ACCESS_MATURE; + } + else if (LLStringUtil::compareStrings(sim_access, "A") == 0) + { + accessValue = SIM_ACCESS_ADULT; + } + else + { + accessValue = SIM_ACCESS_MIN; + } + + return accessValue; +} + // static void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**) { @@ -1444,7 +1460,8 @@ void LLViewerRegion::unpackRegionHandshake() { LLMessageSystem *msg = gMessageSystem; - U32 region_flags; + U64 region_flags = 0; + U64 region_protocols = 0; U8 sim_access; std::string sim_name; LLUUID sim_owner; @@ -1453,7 +1470,6 @@ void LLViewerRegion::unpackRegionHandshake() F32 billable_factor; LLUUID cache_id; - msg->getU32 ("RegionInfo", "RegionFlags", region_flags); msg->getU8 ("RegionInfo", "SimAccess", sim_access); msg->getString ("RegionInfo", "SimName", sim_name); msg->getUUID ("RegionInfo", "SimOwner", sim_owner); @@ -1462,7 +1478,20 @@ void LLViewerRegion::unpackRegionHandshake() msg->getF32 ("RegionInfo", "BillableFactor", billable_factor); msg->getUUID ("RegionInfo", "CacheID", cache_id ); + if (msg->has(_PREHASH_RegionInfo4)) + { + msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionFlagsExtended, region_flags); + msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionProtocols, region_protocols); + } + else + { + U32 flags = 0; + msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags); + region_flags = flags; + } + setRegionFlags(region_flags); + setRegionProtocols(region_protocols); setSimAccess(sim_access); setRegionNameAndZone(sim_name); setOwner(sim_owner); @@ -1501,6 +1530,8 @@ void LLViewerRegion::unpackRegionHandshake() mProductName = productName; } + + mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking"); LLVLComposition *compp = getComposition(); if (compp) { @@ -1538,7 +1569,8 @@ void LLViewerRegion::unpackRegionHandshake() // all of our terrain stuff, by if (compp->getParamsReady()) { - getLand().dirtyAllPatches(); + //this line creates frame stalls on region crossing and removing it appears to have no effect + //getLand().dirtyAllPatches(); } else { @@ -1564,7 +1596,6 @@ void LLViewerRegion::unpackRegionHandshake() msg->sendReliable(host); } - void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) { capabilityNames.append("AgentState"); @@ -1575,11 +1606,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("CopyInventoryFromNotecard"); capabilityNames.append("CreateInventoryCategory"); capabilityNames.append("DispatchRegionInfo"); + capabilityNames.append("EnvironmentSettings"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); - capabilityNames.append("EnvironmentSettings"); - /*capabilityNames.append("ObjectMedia"); - capabilityNames.append("ObjectMediaNavigate");*/ if (gSavedSettings.getBOOL("UseHTTPInventory")) //Caps suffixed with 2 by LL. Don't update until rest of fetch system is updated first. { @@ -1590,12 +1619,12 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) } capabilityNames.append("GetDisplayNames"); - capabilityNames.append("GetTexture"); capabilityNames.append("GetMesh"); capabilityNames.append("GetObjectCost"); capabilityNames.append("GetObjectPhysicsData"); + capabilityNames.append("GetTexture"); + capabilityNames.append("GroupMemberData"); capabilityNames.append("GroupProposalBallot"); - capabilityNames.append("HomeLocation"); //capabilityNames.append("LandResources"); //Script limits (llfloaterscriptlimits.cpp) capabilityNames.append("MapLayer"); @@ -1605,9 +1634,11 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) #endif //MESH_IMPORT capabilityNames.append("NavMeshGenerationStatus"); capabilityNames.append("NewFileAgentInventory"); + /*capabilityNames.append("ObjectMedia"); + capabilityNames.append("ObjectMediaNavigate");*/ capabilityNames.append("ObjectNavMeshProperties"); + capabilityNames.append("ParcelNavigateMedia"); //Singu Note: Removed by Baker, do we need this? capabilityNames.append("ParcelPropertiesUpdate"); - capabilityNames.append("ParcelNavigateMedia"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); @@ -1621,21 +1652,22 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("SendUserReport"); capabilityNames.append("SendUserReportWithScreenshot"); capabilityNames.append("ServerReleaseNotes"); - capabilityNames.append("SimConsole"); - capabilityNames.append("SimulatorFeatures"); capabilityNames.append("SetDisplayName"); + capabilityNames.append("SimConsole"); //Singu Note: Removed by Baker, sim console won't work without this. capabilityNames.append("SimConsoleAsync"); + capabilityNames.append("SimulatorFeatures"); capabilityNames.append("StartGroupProposal"); capabilityNames.append("TerrainNavMeshProperties"); capabilityNames.append("TextureStats"); capabilityNames.append("UntrustedSimulatorMessage"); capabilityNames.append("UpdateAgentInformation"); capabilityNames.append("UpdateAgentLanguage"); + capabilityNames.append("UpdateAvatarAppearance"); capabilityNames.append("UpdateGestureAgentInventory"); - capabilityNames.append("UpdateNotecardAgentInventory"); - capabilityNames.append("UpdateScriptAgent"); capabilityNames.append("UpdateGestureTaskInventory"); + capabilityNames.append("UpdateNotecardAgentInventory"); capabilityNames.append("UpdateNotecardTaskInventory"); + capabilityNames.append("UpdateScriptAgent"); capabilityNames.append("UpdateScriptTask"); capabilityNames.append("UploadBakedTexture"); //capabilityNames.append("ViewerMetrics"); @@ -1721,13 +1753,13 @@ public: { } - void error(U32 statusNum, const std::string& reason) + /*virtual*/ void error(U32 statusNum, const std::string& reason) { LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL; retry(); } - void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); if(!regionp) //region is removed or responder is not created. @@ -1739,7 +1771,8 @@ public: regionp->setSimulatorFeatures(content); } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return simulatorFeaturesReceived_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return simulatorFeaturesReceived_timeout; } + /*virtual*/ char const* getName(void) const { return "SimulatorFeaturesReceived"; } private: void retry() @@ -1793,6 +1826,11 @@ bool LLViewerRegion::isSpecialCapabilityName(const std::string &name) std::string LLViewerRegion::getCapability(const std::string& name) const { + if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia"))) + { + llwarns << "getCapability called before caps received" << llendl; + } + CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name); if(iter == mImpl->mCapabilities.end()) { @@ -1852,7 +1890,7 @@ LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type) // the viewer can not yet distinquish between normal- and estate-owned objects // so we collapse these two bits and enable the UI if either are set -const U32 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT +const U64 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT | REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT; bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector& boxes) const @@ -1860,7 +1898,7 @@ bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector< return (mParcelOverlay != NULL) && (mParcelOverlay->isOwnedSelf(pos) || mParcelOverlay->isOwnedGroup(pos) - || ((mRegionFlags & ALLOW_RETURN_ENCROACHING_OBJECT) + || (getRegionFlag(ALLOW_RETURN_ENCROACHING_OBJECT) && mParcelOverlay->encroachesOwned(boxes)) ); } @@ -1880,7 +1918,10 @@ void LLViewerRegion::getNeighboringRegions( std::vector& unique { mImpl->mLandp->getNeighboringRegions( uniqueRegions ); } - +void LLViewerRegion::getNeighboringRegionsStatus( std::vector& regions ) +{ + mImpl->mLandp->getNeighboringRegionsStatus( regions ); +} void LLViewerRegion::showReleaseNotes() { std::string url = this->getCapability("ServerReleaseNotes"); @@ -1927,3 +1968,9 @@ bool LLViewerRegion::meshRezEnabled() const } } +bool LLViewerRegion::dynamicPathfindingEnabled() const +{ + return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") && + mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean()); +} + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b7fd43602..a97a07228 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -36,6 +36,7 @@ // A ViewerRegion is a class that contains a bunch of objects and surfaces // that are in to a particular region. #include +#include #include "lldarray.h" #include "llwind.h" @@ -67,6 +68,7 @@ class LLVOCache; class LLVOCacheEntry; class LLSpatialPartition; class LLEventPump; +class LLCapabilityListener; class LLDataPacker; class LLDataPackerBinaryBuffer; class LLHost; @@ -117,13 +119,13 @@ public: //void setAgentOffset(const LLVector3d &offset); void updateRenderMatrix(); - void setAllowDamage(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DAMAGE); } - void setAllowLandmark(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_LANDMARK); } - void setAllowSetHome(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_SET_HOME); } - void setResetHomeOnTeleport(BOOL b) { setFlags(b, REGION_FLAGS_RESET_HOME_ON_TELEPORT); } - void setSunFixed(BOOL b) { setFlags(b, REGION_FLAGS_SUN_FIXED); } - void setBlockFly(BOOL b) { setFlags(b, REGION_FLAGS_BLOCK_FLY); } - void setAllowDirectTeleport(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DIRECT_TELEPORT); } + void setAllowDamage(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DAMAGE, b); } + void setAllowLandmark(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_LANDMARK, b); } + void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); } + void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); } + void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); } + void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } + void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); } inline BOOL getAllowDamage() const; @@ -164,8 +166,15 @@ public: LLViewerParcelOverlay *getParcelOverlay() const { return mParcelOverlay; } - void setRegionFlags(U32 flags); - U32 getRegionFlags() const { return mRegionFlags; } + inline void setRegionFlag(U64 flag, BOOL on); + inline BOOL getRegionFlag(U64 flag) const; + void setRegionFlags(U64 flags); + U64 getRegionFlags() const { return mRegionFlags; } + + inline void setRegionProtocol(U64 protocol, BOOL on); + BOOL getRegionProtocol(U64 protocol) const; + void setRegionProtocols(U64 protocols) { mRegionProtocols = protocols; } + U64 getRegionProtocols() const { return mRegionProtocols; } void setTimeDilation(F32 time_dilation); F32 getTimeDilation() const { return mTimeDilation; } @@ -203,13 +212,14 @@ public: std::string getLocalizedSimProductName() const; // Returns "Sandbox", "Expensive", etc. - static std::string regionFlagsToString(U32 flags); + static std::string regionFlagsToString(U64 flags); // Returns translated version of "Mature", "PG", "Adult", etc. static std::string accessToString(U8 sim_access); // Returns "M", "PG", "A" etc. static std::string accessToShortString(U8 sim_access); + static U8 shortStringToAccess(const std::string &sim_access); // Return access icon name static std::string getAccessIcon(U8 sim_access); @@ -285,6 +295,8 @@ public: F32 getLandHeightRegion(const LLVector3& region_pos); + U8 getCentralBakeVersion() { return mCentralBakeVersion; } + void getInfo(LLSD& info); bool meshRezEnabled() const; @@ -293,6 +305,9 @@ public: void getSimulatorFeatures(LLSD& info); void setSimulatorFeatures(const LLSD& info); + + bool dynamicPathfindingEnabled() const; + typedef enum { CACHE_MISS_TYPE_FULL = 0, @@ -337,7 +352,8 @@ public: bool objectsCrossParcel(const std::vector& boxes) const; void getNeighboringRegions( std::vector& uniqueRegions ); - + void getNeighboringRegionsStatus( std::vector& regions ); + public: struct CompareDistance { @@ -352,7 +368,6 @@ public: protected: void disconnectAllNeighbors(); void initStats(); - void setFlags(BOOL b, U32 flags); public: LLWind mWind; @@ -400,11 +415,13 @@ private: U32 mPingDelay; F32 mDeltaTime; // Time since last measurement of lastPackets, Bits, etc - U32 mRegionFlags; // includes damage flags + U64 mRegionFlags; // includes damage flags + U64 mRegionProtocols; // protocols supported by this region U8 mSimAccess; F32 mBillableFactor; U32 mMaxTasks; // max prim count F32 mCameraDistanceSquared; // updated once per frame + U8 mCentralBakeVersion; // Information for Homestead / CR-53 S32 mClassID; @@ -433,6 +450,40 @@ private: LLSD mSimulatorFeatures; }; +inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const +{ + return ((mRegionProtocols & protocol) != 0); +} + +inline void LLViewerRegion::setRegionProtocol(U64 protocol, BOOL on) +{ + if (on) + { + mRegionProtocols |= protocol; + } + else + { + mRegionProtocols &= ~protocol; + } +} + +inline BOOL LLViewerRegion::getRegionFlag(U64 flag) const +{ + return ((mRegionFlags & flag) != 0); +} + +inline void LLViewerRegion::setRegionFlag(U64 flag, BOOL on) +{ + if (on) + { + mRegionFlags |= flag; + } + else + { + mRegionFlags &= ~flag; + } +} + inline BOOL LLViewerRegion::getAllowDamage() const { return ((mRegionFlags & REGION_FLAGS_ALLOW_DAMAGE) !=0); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 25014b640..313673721 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -32,7 +32,6 @@ #include "llviewerprecompiledheaders.h" -#include //First, because glh_linear #defines equivalent.. which boost uses internally #include "llfeaturemanager.h" #include "llviewershadermgr.h" @@ -172,7 +171,8 @@ LLGLSLShader gPostNightVisionProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not LLGLSLShader gPostGaussianBlurProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList LLGLSLShader gPostPosterizeProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList LLGLSLShader gPostMotionBlurProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList - +LLGLSLShader gPostVignetteProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList + // Deferred rendering shaders LLGLSLShader gDeferredImpostorProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredWaterProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calculatesAtmospherics @@ -307,18 +307,6 @@ void LLViewerShaderMgr::setShaders() return; } - { - const std::string dumpdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"shader_dump")+gDirUtilp->getDirDelimiter(); - try - { - boost::filesystem::remove_all(dumpdir); - } - catch(const boost::filesystem::filesystem_error& e) - { - llinfos << "boost::filesystem::remove_all(\""+dumpdir+"\") failed: '" + e.code().message() + "'" << llendl; - } - } - LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")), 1); static const LLCachedControl no_texture_indexing("ShyotlUseLegacyTextureBatching",false); if(no_texture_indexing) @@ -482,6 +470,12 @@ void LLViewerShaderMgr::setShaders() if (loaded) { loaded = loadTransformShaders(); + if(!loaded) //Failed to load. Just wipe all transformfeedback shaders and continue like nothing happened. + { + mVertexShaderLevel[SHADER_TRANSFORM] = 0; + unloadShaderClass(SHADER_TRANSFORM); + loaded = true; + } } if (loaded) @@ -908,7 +902,6 @@ BOOL LLViewerShaderMgr::loadShadersEffects() shaderUniforms.push_back("contrast"); shaderUniforms.push_back("contrastBase"); shaderUniforms.push_back("saturation"); - shaderUniforms.push_back("lumWeights"); gPostColorFilterProgram.mName = "Color Filter Shader (Post)"; gPostColorFilterProgram.mShaderFiles.clear(); @@ -929,7 +922,6 @@ BOOL LLViewerShaderMgr::loadShadersEffects() shaderUniforms.reserve(3); shaderUniforms.push_back("brightMult"); shaderUniforms.push_back("noiseStrength"); - shaderUniforms.push_back("lumWeights"); gPostNightVisionProgram.mName = "Night Vision Shader (Post)"; gPostNightVisionProgram.mShaderFiles.clear(); @@ -998,6 +990,26 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gPostMotionBlurProgram.uniform1i("tex1", 1); } } + + { + vector shaderUniforms; + shaderUniforms.reserve(3); + shaderUniforms.push_back("vignette_darkness"); + shaderUniforms.push_back("vignette_radius"); + shaderUniforms.push_back("screen_res"); + + gPostVignetteProgram.mName = "Vignette Shader (Post)"; + gPostVignetteProgram.mShaderFiles.clear(); + gPostVignetteProgram.mShaderFiles.push_back(make_pair("effects/VignetteF.glsl", GL_FRAGMENT_SHADER_ARB)); + gPostVignetteProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB)); + gPostVignetteProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; + if(gPostVignetteProgram.createShader(NULL, &shaderUniforms)) + { + gPostVignetteProgram.bind(); + gPostVignetteProgram.uniform1i("tex0", 0); + } + } + #endif return success; @@ -1293,7 +1305,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { // load water shader gDeferredWaterProgram.mName = "Deferred Water Shader"; + gDeferredWaterProgram.mFeatures.atmosphericHelpers = true; gDeferredWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredWaterProgram.mFeatures.hasAtmospherics = true; gDeferredWaterProgram.mFeatures.hasGamma = true; gDeferredWaterProgram.mFeatures.hasTransport = true; gDeferredWaterProgram.mShaderFiles.clear(); @@ -1493,12 +1507,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredStarProgram.mName = "Deferred Star Program"; + vector shaderUniforms(mWLUniforms); + shaderUniforms.push_back("custom_alpha"); gDeferredStarProgram.mShaderFiles.clear(); gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredStarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gDeferredStarProgram.createShader(NULL, &mWLUniforms); + success = gDeferredStarProgram.createShader(NULL, &shaderUniforms); } if (success) @@ -2396,7 +2412,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() if (success) { - gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; + /*gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; gAvatarEyeballProgram.mFeatures.calculatesLighting = true; gAvatarEyeballProgram.mFeatures.isSpecular = true; gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true; @@ -2409,7 +2425,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB)); gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB)); gAvatarEyeballProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; - success = gAvatarEyeballProgram.createShader(NULL, NULL); + success = gAvatarEyeballProgram.createShader(NULL, NULL);*/ } if( !success ) diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 6013a47f2..eeb96dfa6 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -62,6 +62,7 @@ #include "llviewernetwork.h" #include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived #include "sgmemstat.h" +#include "llviewertexlayer.h" class AIHTTPTimeoutPolicy; extern AIHTTPTimeoutPolicy viewerStatsResponder_timeout; @@ -525,7 +526,7 @@ void output_statistics(void*) llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl; LLTexLayerStaticImageList::getInstance()->dumpByteCount(); LLVOAvatarSelf::dumpScratchTextureByteCount(); - LLTexLayerSetBuffer::dumpTotalByteCount(); + LLViewerTexLayerSetBuffer::dumpTotalByteCount(); LLVOAvatarSelf::dumpTotalLocalTextureByteCount(); LLTexLayerParamAlpha::dumpCacheByteCount(); LLVOAvatar::dumpBakedStatus(); @@ -703,18 +704,19 @@ class ViewerStatsResponder : public LLHTTPClient::ResponderWithResult public: ViewerStatsResponder() { } - void error(U32 statusNum, const std::string& reason) + /*virtual*/ void error(U32 statusNum, const std::string& reason) { llinfos << "ViewerStatsResponder::error " << statusNum << " " << reason << llendl; } - void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { llinfos << "ViewerStatsResponder::result" << llendl; } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return viewerStatsResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return viewerStatsResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "ViewerStatsResponder"; } }; /* @@ -873,7 +875,7 @@ void send_stats() llinfos << "Misc Stats: int_1: " << misc["int_1"] << " int_2: " << misc["int_2"] << llendl; llinfos << "Misc Stats: string_1: " << misc["string_1"] << " string_2: " << misc["string_2"] << llendl; - body["DisplayNamesEnabled"] = gSavedSettings.getS32("PhoenixNameSystem") > 0; + body["DisplayNamesEnabled"] = gSavedSettings.getS32("PhoenixNameSystem") == 1 || gSavedSettings.getS32("PhoenixNameSystem") == 2; body["DisplayNamesShowUsername"] = gSavedSettings.getS32("PhoenixNameSystem") == 1; body["MinimalSkin"] = false; diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp new file mode 100644 index 000000000..cbf32eb43 --- /dev/null +++ b/indra/newview/llviewertexlayer.cpp @@ -0,0 +1,748 @@ +/** + * @file lltexlayer.cpp + * @brief A texture layer. Used for avatars. + * + * $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 "lltexlayer.h" +#include "llviewertexlayer.h" + +#include "llagent.h" +#include "llimagej2c.h" +#include "llnotificationsutil.h" +#include "llvfile.h" +#include "llvfs.h" +#include "llviewerregion.h" +#include "llglslshader.h" +#include "llvoavatarself.h" +#include "pipeline.h" +#include "llassetuploadresponders.h" +#include "llviewercontrol.h" +#include "llviewerstats.h" + +static const S32 BAKE_UPLOAD_ATTEMPTS = 7; +static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt + +// runway consolidate +extern std::string self_av_string(); + + +//----------------------------------------------------------------------------- +// LLBakedUploadData() +//----------------------------------------------------------------------------- +LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar, + LLViewerTexLayerSet* layerset, + const LLUUID& id, + bool highest_res) : + mAvatar(avatar), + mTexLayerSet(layerset), + mID(id), + mStartTime(LLFrameTimer::getTotalTime()), // Record starting time + mIsHighestRes(highest_res) +{ +} + +//----------------------------------------------------------------------------- +// LLViewerTexLayerSetBuffer +// The composite image that a LLViewerTexLayerSet writes to. Each LLViewerTexLayerSet has one. +//----------------------------------------------------------------------------- + +// static +S32 LLViewerTexLayerSetBuffer::sGLByteCount = 0; + +LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, + S32 width, S32 height) : + // ORDER_LAST => must render these after the hints are created. + LLTexLayerSetBuffer(owner), + LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), + mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates + mNeedsUpload(FALSE), + mNumLowresUploads(0), + mUploadFailCount(0), + mNeedsUpdate(TRUE), + mNumLowresUpdates(0) +{ + LLViewerTexLayerSetBuffer::sGLByteCount += getSize(); + mNeedsUploadTimer.start(); + mNeedsUpdateTimer.start(); +} + +LLViewerTexLayerSetBuffer::~LLViewerTexLayerSetBuffer() +{ + LLViewerTexLayerSetBuffer::sGLByteCount -= getSize(); + destroyGLTexture(); + for( S32 order = 0; order < ORDER_COUNT; order++ ) + { + LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. + } +} + +//virtual +S8 LLViewerTexLayerSetBuffer::getType() const +{ + return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ; +} + +//virtual +void LLViewerTexLayerSetBuffer::restoreGLTexture() +{ + LLViewerDynamicTexture::restoreGLTexture() ; +} + +//virtual +void LLViewerTexLayerSetBuffer::destroyGLTexture() +{ + LLViewerDynamicTexture::destroyGLTexture() ; +} + +// static +void LLViewerTexLayerSetBuffer::dumpTotalByteCount() +{ + llinfos << "Composite System GL Buffers: " << (LLViewerTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl; +} + +void LLViewerTexLayerSetBuffer::requestUpdate() +{ + restartUpdateTimer(); + mNeedsUpdate = TRUE; + mNumLowresUpdates = 0; + // If we're in the middle of uploading a baked texture, we don't care about it any more. + // When it's downloaded, ignore it. + mUploadID.setNull(); +} + +void LLViewerTexLayerSetBuffer::requestUpload() +{ + conditionalRestartUploadTimer(); + mNeedsUpload = TRUE; + mNumLowresUploads = 0; + mUploadPending = TRUE; +} + +void LLViewerTexLayerSetBuffer::conditionalRestartUploadTimer() +{ + // If we requested a new upload but haven't even uploaded + // a low res version of our last upload request, then + // keep the timer ticking instead of resetting it. + if (mNeedsUpload && (mNumLowresUploads == 0)) + { + mNeedsUploadTimer.unpause(); + } + else + { + mNeedsUploadTimer.unpause(); //Isn't always unpaused before this, although it should be.. + mNeedsUploadTimer.reset(); + mNeedsUploadTimer.start(); + } +} + +void LLViewerTexLayerSetBuffer::restartUpdateTimer() +{ + mNeedsUpdateTimer.reset(); + mNeedsUpdateTimer.start(); +} + +void LLViewerTexLayerSetBuffer::cancelUpload() +{ + mNeedsUpload = FALSE; + mUploadPending = FALSE; + mNeedsUploadTimer.pause(); + mUploadRetryTimer.reset(); +} + +// virtual +BOOL LLViewerTexLayerSetBuffer::needsRender() +{ + llassert(mTexLayerSet->getAvatarAppearance() == gAgentAvatarp); + if (!isAgentAvatarValid()) return FALSE; + + const BOOL upload_now = mNeedsUpload && isReadyToUpload(); + const BOOL update_now = mNeedsUpdate && isReadyToUpdate(); + + // Don't render if we don't want to (or aren't ready to) upload or update. + if (!(update_now || upload_now)) + { + return FALSE; + } + + // Don't render if we're animating our appearance. + if (gAgentAvatarp->getIsAppearanceAnimating()) + { + return FALSE; + } + + // Don't render if we are trying to create a shirt texture but aren't wearing a skirt. + if (gAgentAvatarp->getBakedTE(getViewerTexLayerSet()) == LLAvatarAppearanceDefines::TEX_SKIRT_BAKED && + !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT)) + { + cancelUpload(); + return FALSE; + } + + // Render if we have at least minimal level of detail for each local texture. + return getViewerTexLayerSet()->isLocalTextureDataAvailable(); +} + +// virtual +void LLViewerTexLayerSetBuffer::preRenderTexLayerSet() +{ + LLTexLayerSetBuffer::preRenderTexLayerSet(); + + // keep depth buffer, we don't need to clear it + LLViewerDynamicTexture::preRender(FALSE); +} + +// virtual +void LLViewerTexLayerSetBuffer::postRenderTexLayerSet(BOOL success) +{ + + LLTexLayerSetBuffer::postRenderTexLayerSet(success); + LLViewerDynamicTexture::postRender(success); +} + +// virtual +void LLViewerTexLayerSetBuffer::midRenderTexLayerSet(BOOL success) +{ + // do we need to upload, and do we have sufficient data to create an uploadable composite? + // TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero? + const BOOL upload_now = mNeedsUpload && isReadyToUpload(); + const BOOL update_now = mNeedsUpdate && isReadyToUpdate(); + + if(upload_now) + { + if (!success) + { + llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegionName() << llendl; + mUploadPending = FALSE; + } + else + { + LLViewerTexLayerSet* layer_set = getViewerTexLayerSet(); + if (layer_set->isVisible()) + { + layer_set->getAvatar()->debugBakedTextureUpload(layer_set->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish. + doUpload(); + } + else + { + mUploadPending = FALSE; + mNeedsUpload = FALSE; + mNeedsUploadTimer.pause(); + layer_set->getAvatar()->setNewBakedTexture(layer_set->getBakedTexIndex(),IMG_INVISIBLE); + } + } + } + + if (update_now) + { + doUpdate(); + } + + // *TODO: Old logic does not check success before setGLTextureCreated + // we have valid texture data now + mGLTexturep->setGLTextureCreated(true); +} + +BOOL LLViewerTexLayerSetBuffer::isInitialized(void) const +{ + return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated(); +} + +BOOL LLViewerTexLayerSetBuffer::uploadPending() const +{ + return mUploadPending; +} + +BOOL LLViewerTexLayerSetBuffer::uploadNeeded() const +{ + return mNeedsUpload; +} + +BOOL LLViewerTexLayerSetBuffer::uploadInProgress() const +{ + return !mUploadID.isNull(); +} + +BOOL LLViewerTexLayerSetBuffer::isReadyToUpload() const +{ + if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries. + if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance()) return FALSE; // Don't upload if avatar is being edited. + + BOOL ready = FALSE; + if (getViewerTexLayerSet()->isLocalTextureDataFinal()) + { + // If we requested an upload and have the final LOD ready, upload (or wait a while if this is a retry) + if (mUploadFailCount == 0) + { + ready = TRUE; + } + else + { + ready = mUploadRetryTimer.getElapsedTimeF32() >= BAKE_UPLOAD_RETRY_DELAY * (1 << (mUploadFailCount - 1)); + } + } + else + { + // Upload if we've hit a timeout. Upload is a pretty expensive process so we need to make sure + // we aren't doing uploads too frequently. + const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout"); + if (texture_timeout != 0) + { + // The timeout period increases exponentially between every lowres upload in order to prevent + // spamming the server with frequent uploads. + const U32 texture_timeout_threshold = texture_timeout*(1 << mNumLowresUploads); + + // If we hit our timeout and have textures available at even lower resolution, then upload. + const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold; + const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable(); + ready = has_lower_lod && is_upload_textures_timeout; + } + } + + return ready; +} + +BOOL LLViewerTexLayerSetBuffer::isReadyToUpdate() const +{ + // If we requested an update and have the final LOD ready, then update. + if (getViewerTexLayerSet()->isLocalTextureDataFinal()) return TRUE; + + // If we haven't done an update yet, then just do one now regardless of state of textures. + if (mNumLowresUpdates == 0) return TRUE; + + // Update if we've hit a timeout. Unlike for uploads, we can make this timeout fairly small + // since render unnecessarily doesn't cost much. + const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout"); + if (texture_timeout != 0) + { + // If we hit our timeout and have textures available at even lower resolution, then update. + const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout; + const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable(); + if (has_lower_lod && is_update_textures_timeout) return TRUE; + } + + return FALSE; +} + +BOOL LLViewerTexLayerSetBuffer::requestUpdateImmediate() +{ + mNeedsUpdate = TRUE; + BOOL result = FALSE; + + if (needsRender()) + { + preRender(FALSE); + result = render(); + postRender(result); + } + + return result; +} + +// Create the baked texture, send it out to the server, then wait for it to come +// back so we can switch to using it. +void LLViewerTexLayerSetBuffer::doUpload() +{ + LLViewerTexLayerSet* layer_set = getViewerTexLayerSet(); + llinfos << "Uploading baked " << layer_set->getBodyRegionName() << llendl; + LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES); + + // Don't need caches since we're baked now. (note: we won't *really* be baked + // until this image is sent to the server and the Avatar Appearance message is received.) + layer_set->deleteCaches(); + + // Get the COLOR information from our texture + U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ]; + glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data ); + stop_glerror(); + + // Get the MASK information from our texture + LLGLSUIDefault gls_ui; + LLPointer baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 ); + U8* baked_mask_data = baked_mask_image->getData(); + layer_set->gatherMorphMaskAlpha(baked_mask_data, + mOrigin.mX, mOrigin.mY, + mFullWidth, mFullHeight); + + + // Create the baked image from our color and mask information + const S32 baked_image_components = 5; // red green blue [bump] clothing + LLPointer baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components ); + U8* baked_image_data = baked_image->getData(); + S32 i = 0; + for (S32 u=0; u < mFullWidth; u++) + { + for (S32 v=0; v < mFullHeight; v++) + { + baked_image_data[5*i + 0] = baked_color_data[4*i + 0]; + baked_image_data[5*i + 1] = baked_color_data[4*i + 1]; + baked_image_data[5*i + 2] = baked_color_data[4*i + 2]; + baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes. + baked_image_data[5*i + 4] = baked_mask_data[i]; + i++; + } + } + + LLPointer compressedImage = new LLImageJ2C; + const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask) + if (compressedImage->encode(baked_image, comment_text)) + { + LLTransactionID tid; + tid.generate(); + const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(), + gVFS, asset_id, LLAssetType::AT_TEXTURE)) + { + // Read back the file and validate. + BOOL valid = FALSE; + LLPointer integrity_test = new LLImageJ2C; + S32 file_size = 0; + U8* data = LLVFile::readFile(gVFS, LLImageBase::getPrivatePool(), asset_id, LLAssetType::AT_TEXTURE, &file_size); + if (data) + { + valid = integrity_test->validate(data, file_size); // integrity_test will delete 'data' + } + else + { + integrity_test->setLastError("Unable to read entire file"); + } + + if (valid) + { + const bool highest_lod = layer_set->isLocalTextureDataFinal(); + // Baked_upload_data is owned by the responder and deleted after the request completes. + LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, + layer_set, + asset_id, + highest_lod); + // upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit. + mUploadID = asset_id; + + // Upload the image + const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture"); + if(!url.empty() + && !LLPipeline::sForceOldBakedUpload // toggle debug setting UploadBakedTexOld to change between the new caps method and old method + && (mUploadFailCount < (BAKE_UPLOAD_ATTEMPTS - 1))) // Try last ditch attempt via asset store if cap upload is failing. + { + LLSD body = LLSD::emptyMap(); + // The responder will call LLViewerTexLayerSetBuffer::onTextureUploadComplete() + LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data)); + llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl; + } + else + { + gAssetStorage->storeAssetData(tid, + LLAssetType::AT_TEXTURE, + LLViewerTexLayerSetBuffer::onTextureUploadComplete, + baked_upload_data, + TRUE, // temp_file + TRUE, // is_priority + TRUE); // store_local + llinfos << "Baked texture upload via Asset Store." << llendl; + } + + if (highest_lod) + { + // Sending the final LOD for the baked texture. All done, pause + // the upload timer so we know how long it took. + mNeedsUpload = FALSE; + mNeedsUploadTimer.pause(); + } + else + { + // Sending a lower level LOD for the baked texture. Restart the upload timer. + mNumLowresUploads++; + mNeedsUploadTimer.unpause(); + mNeedsUploadTimer.reset(); + } + + // Print out notification that we uploaded this texture. + if (gSavedSettings.getBOOL("DebugAvatarRezTime")) + { + const std::string lod_str = highest_lod ? "HighRes" : "LowRes"; + LLSD args; + args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32()); + args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32()); + args["BODYREGION"] = layer_set->getBodyRegionName(); + args["RESOLUTION"] = lod_str; + LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args); + LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL; + } + } + else + { + // The read back and validate operation failed. Remove the uploaded file. + mUploadPending = FALSE; + LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE); + file.remove(); + llinfos << "Unable to create baked upload file (reason: corrupted)." << llendl; + } + } + } + else + { + // The VFS write file operation failed. + mUploadPending = FALSE; + llinfos << "Unable to create baked upload file (reason: failed to write file)" << llendl; + } + + delete [] baked_color_data; +} + +// Mostly bookkeeping; don't need to actually "do" anything since +// render() will actually do the update. +void LLViewerTexLayerSetBuffer::doUpdate() +{ + LLViewerTexLayerSet* layer_set = getViewerTexLayerSet(); + const BOOL highest_lod = layer_set->isLocalTextureDataFinal(); + if (highest_lod) + { + mNeedsUpdate = FALSE; + } + else + { + mNumLowresUpdates++; + } + + restartUpdateTimer(); + + // need to switch to using this layerset if this is the first update + // after getting the lowest LOD + layer_set->getAvatar()->updateMeshTextures(); + + // Print out notification that we updated this texture. + if (gSavedSettings.getBOOL("DebugAvatarRezTime")) + { + const BOOL highest_lod = layer_set->isLocalTextureDataFinal(); + const std::string lod_str = highest_lod ? "HighRes" : "LowRes"; + LLSD args; + args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32()); + args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32()); + args["BODYREGION"] = layer_set->getBodyRegionName(); + args["RESOLUTION"] = lod_str; + LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args); + LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL; + } +} + +// static +void LLViewerTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, + void* userdata, + S32 result, + LLExtStat ext_status) // StoreAssetData callback (not fixed) +{ + LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata; + + if (isAgentAvatarValid() && + !gAgentAvatarp->isDead() && + (baked_upload_data->mAvatar == gAgentAvatarp) && // Sanity check: only the user's avatar should be uploading textures. + (baked_upload_data->mTexLayerSet->hasComposite())) + { + LLViewerTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getViewerComposite(); + S32 failures = layerset_buffer->mUploadFailCount; + layerset_buffer->mUploadFailCount = 0; + + if (layerset_buffer->mUploadID.isNull()) + { + // The upload got canceled, we should be in the + // process of baking a new texture so request an + // upload with the new data + + // BAP: does this really belong in this callback, as + // opposed to where the cancellation takes place? + // suspect this does nothing. + layerset_buffer->requestUpload(); + } + else if (baked_upload_data->mID == layerset_buffer->mUploadID) + { + // This is the upload we're currently waiting for. + layerset_buffer->mUploadID.setNull(); + const std::string name(baked_upload_data->mTexLayerSet->getBodyRegionName()); + const std::string resolution = baked_upload_data->mIsHighestRes ? " full res " : " low res "; + if (result >= 0) + { + layerset_buffer->mUploadPending = FALSE; // Allows sending of AgentSetAppearance later + LLAvatarAppearanceDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->getViewerTexLayerSet()); + // Update baked texture info with the new UUID + U64 now = LLFrameTimer::getTotalTime(); // Record starting time + llinfos << "Baked" << resolution << "texture upload for " << name << " took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl; + gAgentAvatarp->setNewBakedTexture(baked_te, uuid); + } + else + { + ++failures; + S32 max_attempts = baked_upload_data->mIsHighestRes ? BAKE_UPLOAD_ATTEMPTS : 1; // only retry final bakes + llwarns << "Baked" << resolution << "texture upload for " << name << " failed (attempt " << failures << "/" << max_attempts << ")" << llendl; + if (failures < max_attempts) + { + layerset_buffer->mUploadFailCount = failures; + layerset_buffer->mUploadRetryTimer.start(); + layerset_buffer->requestUpload(); + } + } + } + else + { + llinfos << "Received baked texture out of date, ignored." << llendl; + } + + gAgentAvatarp->dirtyMesh(); + } + else + { + // Baked texture failed to upload (in which case since we + // didn't set the new baked texture, it means that they'll try + // and rebake it at some point in the future (after login?)), + // or this response to upload is out of date, in which case a + // current response should be on the way or already processed. + llwarns << "Baked upload failed" << llendl; + } + + delete baked_upload_data; +} + +//----------------------------------------------------------------------------- +// LLViewerTexLayerSet +// An ordered set of texture layers that get composited into a single texture. +//----------------------------------------------------------------------------- + +LLViewerTexLayerSet::LLViewerTexLayerSet(LLAvatarAppearance* const appearance) : + LLTexLayerSet(appearance), + mUpdatesEnabled( FALSE ) +{ +} + +// virtual +LLViewerTexLayerSet::~LLViewerTexLayerSet() +{ +} + +// Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on. +BOOL LLViewerTexLayerSet::isLocalTextureDataAvailable() const +{ + if (!mAvatarAppearance->isSelf()) return FALSE; + return getAvatar()->isLocalTextureDataAvailable(this); +} + + +// Returns TRUE if all of the data for the textures that this layerset depends on have arrived. +BOOL LLViewerTexLayerSet::isLocalTextureDataFinal() const +{ + if (!mAvatarAppearance->isSelf()) return FALSE; + return getAvatar()->isLocalTextureDataFinal(this); +} + + +void LLViewerTexLayerSet::requestUpdate() +{ + if( mUpdatesEnabled ) + { + createComposite(); + getViewerComposite()->requestUpdate(); + } +} + +void LLViewerTexLayerSet::requestUpload() +{ + createComposite(); + getViewerComposite()->requestUpload(); +} + +void LLViewerTexLayerSet::cancelUpload() +{ + if(mComposite) + { + getViewerComposite()->cancelUpload(); + } +} + +void LLViewerTexLayerSet::updateComposite() +{ + createComposite(); + getViewerComposite()->requestUpdateImmediate(); +} + +// virtual +void LLViewerTexLayerSet::createComposite() +{ + if(!mComposite) + { + S32 width = mInfo->getWidth(); + S32 height = mInfo->getHeight(); + // Composite other avatars at reduced resolution + if( !mAvatarAppearance->isSelf() ) + { + llerrs << "composites should not be created for non-self avatars!" << llendl; + } + mComposite = new LLViewerTexLayerSetBuffer( this, width, height ); + } +} + +void LLViewerTexLayerSet::setUpdatesEnabled( BOOL b ) +{ + mUpdatesEnabled = b; +} + +LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() +{ + return dynamic_cast (mAvatarAppearance); +} + +const LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() const +{ + return dynamic_cast (mAvatarAppearance); +} + +LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() +{ + return dynamic_cast (getComposite()); +} + +const LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() const +{ + return dynamic_cast (getComposite()); +} + + +const std::string LLViewerTexLayerSetBuffer::dumpTextureInfo() const +{ + if (!isAgentAvatarValid()) return ""; + + const BOOL is_high_res = !mNeedsUpload; + const U32 num_low_res = mNumLowresUploads; + const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32(); + const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(getViewerTexLayerSet()); + + std::string status = "CREATING "; + if (!uploadNeeded()) status = "DONE "; + if (uploadInProgress()) status = "UPLOADING"; + + std::string text = llformat("[%s] [HiRes:%d LoRes:%d] [Elapsed:%d] %s", + status.c_str(), + is_high_res, num_low_res, + upload_time, + local_texture_info.c_str()); + return text; +} diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h new file mode 100644 index 000000000..959c883da --- /dev/null +++ b/indra/newview/llviewertexlayer.h @@ -0,0 +1,180 @@ +/** + * @file llviewertexlayer.h + * @brief Viewer Texture layer classes. Used for avatars. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_VIEWER_TEXLAYER_H +#define LL_VIEWER_TEXLAYER_H + +#include "lldynamictexture.h" +#include "llextendedstatus.h" +#include "lltexlayer.h" + +class LLVOAvatarSelf; +class LLViewerTexLayerSetBuffer; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLViewerTexLayerSet +// +// An ordered set of texture layers that gets composited into a single texture. +// Only exists for llavatarappearanceself. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLViewerTexLayerSet : public LLTexLayerSet +{ +public: + LLViewerTexLayerSet(LLAvatarAppearance* const appearance); + virtual ~LLViewerTexLayerSet(); + + /*virtual*/void requestUpdate(); + void requestUpload(); + void cancelUpload(); + BOOL isLocalTextureDataAvailable() const; + BOOL isLocalTextureDataFinal() const; + void updateComposite(); + /*virtual*/void createComposite(); + void setUpdatesEnabled(BOOL b); + BOOL getUpdatesEnabled() const { return mUpdatesEnabled; } + + LLVOAvatarSelf* getAvatar(); + const LLVOAvatarSelf* getAvatar() const; + LLViewerTexLayerSetBuffer* getViewerComposite(); + const LLViewerTexLayerSetBuffer* getViewerComposite() const; + +private: + BOOL mUpdatesEnabled; + +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLViewerTexLayerSetBuffer +// +// The composite image that a LLViewerTexLayerSet writes to. Each LLViewerTexLayerSet has one. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLViewerTexLayerSetBuffer : public LLTexLayerSetBuffer, public LLViewerDynamicTexture +{ + LOG_CLASS(LLViewerTexLayerSetBuffer); + +public: + LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height); + virtual ~LLViewerTexLayerSetBuffer(); + +public: + /*virtual*/ S8 getType() const; + BOOL isInitialized(void) const; + static void dumpTotalByteCount(); + const std::string dumpTextureInfo() const; + virtual void restoreGLTexture(); + virtual void destroyGLTexture(); +private: + LLViewerTexLayerSet* getViewerTexLayerSet() + { return dynamic_cast (mTexLayerSet); } + const LLViewerTexLayerSet* getViewerTexLayerSet() const + { return dynamic_cast (mTexLayerSet); } + static S32 sGLByteCount; + + //-------------------------------------------------------------------- + // Tex Layer Render + //-------------------------------------------------------------------- + virtual void preRenderTexLayerSet(); + virtual void midRenderTexLayerSet(BOOL success); + virtual void postRenderTexLayerSet(BOOL success); + virtual S32 getCompositeOriginX() const { return getOriginX(); } + virtual S32 getCompositeOriginY() const { return getOriginY(); } + virtual S32 getCompositeWidth() const { return getFullWidth(); } + virtual S32 getCompositeHeight() const { return getFullHeight(); } + + //-------------------------------------------------------------------- + // Dynamic Texture Interface + //-------------------------------------------------------------------- +public: + /*virtual*/ BOOL needsRender(); +protected: + // Pass these along for tex layer rendering. + virtual void preRender(BOOL clear_depth) { preRenderTexLayerSet(); } + virtual void postRender(BOOL success) { postRenderTexLayerSet(success); } + virtual BOOL render() { return renderTexLayerSet(); } + + //-------------------------------------------------------------------- + // Uploads + //-------------------------------------------------------------------- +public: + void requestUpload(); + void cancelUpload(); + BOOL uploadNeeded() const; // We need to upload a new texture + BOOL uploadInProgress() const; // We have started uploading a new texture and are awaiting the result + BOOL uploadPending() const; // We are expecting a new texture to be uploaded at some point + static void onTextureUploadComplete(const LLUUID& uuid, + void* userdata, + S32 result, LLExtStat ext_status); +protected: + BOOL isReadyToUpload() const; + void doUpload(); // Does a read back and upload. + void conditionalRestartUploadTimer(); +private: + BOOL mNeedsUpload; // Whether we need to send our baked textures to the server + U32 mNumLowresUploads; // Number of times we've sent a lowres version of our baked textures to the server + BOOL mUploadPending; // Whether we have received back the new baked textures + LLUUID mUploadID; // The current upload process (null if none). + LLFrameTimer mNeedsUploadTimer; // Tracks time since upload was requested and performed. + S32 mUploadFailCount; // Number of consecutive upload failures + LLFrameTimer mUploadRetryTimer; // Tracks time since last upload failure. + + //-------------------------------------------------------------------- + // Updates + //-------------------------------------------------------------------- +public: + void requestUpdate(); + BOOL requestUpdateImmediate(); +protected: + BOOL isReadyToUpdate() const; + void doUpdate(); + void restartUpdateTimer(); +private: + BOOL mNeedsUpdate; // Whether we need to locally update our baked textures + U32 mNumLowresUpdates; // Number of times we've locally updated with lowres version of our baked textures + LLFrameTimer mNeedsUpdateTimer; // Tracks time since update was requested and performed. +}; + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLBakedUploadData +// +// Used by LLTexLayerSetBuffer for a callback. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +struct LLBakedUploadData +{ + LLBakedUploadData(const LLVOAvatarSelf* avatar, + LLViewerTexLayerSet* layerset, + const LLUUID& id, + bool highest_res); + ~LLBakedUploadData() {} + const LLUUID mID; + const LLVOAvatarSelf* mAvatar; // note: backlink only; don't LLPointer + LLViewerTexLayerSet* mTexLayerSet; + const U64 mStartTime; // for measuring baked texture upload time + const bool mIsHighestRes; // whether this is a "final" bake, or intermediate low res +}; + +#endif // LL_VIEWER_TEXLAYER_H + diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index cf54a6ce8..c4ad62fb2 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -59,6 +59,7 @@ //#include "lltextureatlas.h" //#include "lltextureatlasmanager.h" #include "lltextureentry.h" +#include "lltexturemanagerbridge.h" #if NEW_MEDIA_TEXTURE #include "llmediaentry.h" #endif //NEW_MEDIA_TEXTURE @@ -242,7 +243,7 @@ LLPointer LLViewerTextureManager::getLocalTexture(BOOL usemipma if(generate_gl_tex) { tex->generateGLTexture() ; - tex->setCategory(LLViewerTexture::LOCAL) ; + tex->setCategory(LLGLTexture::LOCAL) ; } return tex ; } @@ -252,14 +253,14 @@ LLPointer LLViewerTextureManager::getLocalTexture(const LLUUID& if(generate_gl_tex) { tex->generateGLTexture() ; - tex->setCategory(LLViewerTexture::LOCAL) ; + tex->setCategory(LLGLTexture::LOCAL) ; } return tex ; } LLPointer LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) { LLPointer tex = new LLViewerTexture(raw, usemipmaps) ; - tex->setCategory(LLViewerTexture::LOCAL) ; + tex->setCategory(LLGLTexture::LOCAL) ; return tex ; } LLPointer LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex) @@ -268,7 +269,7 @@ LLPointer LLViewerTextureManager::getLocalTexture(const U32 wid if(generate_gl_tex) { tex->generateGLTexture() ; - tex->setCategory(LLViewerTexture::LOCAL) ; + tex->setCategory(LLGLTexture::LOCAL) ; } return tex ; } @@ -315,6 +316,26 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const return gTextureList.getImageFromHost(image_id, host) ; } +// Create a bridge to the viewer texture manager. +class LLViewerTextureManagerBridge : public LLTextureManagerBridge +{ + /*virtual*/ LLPointer getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) + { + return LLViewerTextureManager::getLocalTexture(usemipmaps, generate_gl_tex); + } + + /*virtual*/ LLPointer getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) + { + return LLViewerTextureManager::getLocalTexture(width, height, components, usemipmaps, generate_gl_tex); + } + + /*virtual*/ LLGLTexture* getFetchedTexture(const LLUUID &image_id) + { + return LLViewerTextureManager::getFetchedTexture(image_id); + } +}; + + void LLViewerTextureManager::init() { { @@ -360,16 +381,19 @@ void LLViewerTextureManager::init() imagep->setCachedRawImage(0, image_raw) ; image_raw = NULL; #else - LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI); + LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI); #endif LLViewerFetchedTexture::sDefaultImagep->dontDiscard(); - LLViewerFetchedTexture::sDefaultImagep->setCategory(LLViewerTexture::OTHER) ; + LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER) ; - LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI); + LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLGLTexture::BOOST_UI); LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ; LLViewerTexture::initClass() ; + // Create a texture manager bridge. + gTextureManagerBridgep = new LLViewerTextureManagerBridge(); + #if 0 if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) { @@ -387,6 +411,7 @@ void LLViewerTextureManager::cleanup() { stop_glerror(); + delete gTextureManagerBridgep; LLImageGL::sDefaultGLTexture = NULL ; LLViewerTexture::sNullImagep = NULL; LLViewerTexture::sBlackImagep = NULL; @@ -415,25 +440,6 @@ void LLViewerTexture::initClass() } } -// static -S32 LLViewerTexture::getTotalNumOfCategories() -{ - return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ; -} - -// static -//index starts from zero. -S32 LLViewerTexture::getIndexFromCategory(S32 category) -{ - return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ; -} - -//static -S32 LLViewerTexture::getCategoryFromIndex(S32 index) -{ - return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ; -} - // tuning params const F32 discard_bias_delta = .25f; const F32 discard_delta_time = 0.5f; @@ -574,45 +580,38 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity //------------------------------------------------------------------------------------------- const U32 LLViewerTexture::sCurrentFileVersion = 1; -LLViewerTexture::LLViewerTexture(BOOL usemipmaps) +LLViewerTexture::LLViewerTexture(BOOL usemipmaps) : + LLGLTexture(usemipmaps) { init(true); - mUseMipMaps = usemipmaps ; mID.generate(); sImageCount++; } -LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps) - : mID(id) +LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps) : + LLGLTexture(usemipmaps), + mID(id) { init(true); - mUseMipMaps = usemipmaps ; sImageCount++; } -LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) +LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) : + LLGLTexture(width, height, components, usemipmaps) { init(true); - mFullWidth = width ; - mFullHeight = height ; - mUseMipMaps = usemipmaps ; - mComponents = components ; - setTexelsPerImage(); - mID.generate(); sImageCount++; } -LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) +LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) : + LLGLTexture(raw, usemipmaps) { init(true); - mUseMipMaps = usemipmaps ; - mGLTexturep = new LLImageGL(raw, usemipmaps) ; - // Create an empty image of the specified size and width mID.generate(); sImageCount++; } @@ -623,18 +622,9 @@ LLViewerTexture::~LLViewerTexture() sImageCount--; } +// virtual void LLViewerTexture::init(bool firstinit) { - mBoostLevel = LLViewerTexture::BOOST_NONE; - - mFullWidth = 0; - mFullHeight = 0; - mTexelsPerImage = 0 ; - mUseMipMaps = FALSE ; - mComponents = 0 ; - - mTextureState = NO_DELETE ; - mDontDiscard = FALSE; mMaxVirtualSize = 0.f; mNeedsGLTexture = FALSE ; mMaxVirtualSizeResetInterval = 1; @@ -645,7 +635,6 @@ void LLViewerTexture::init(bool firstinit) mNumVolumes = 0; mFaceList.clear() ; mVolumeList.clear(); - #if !NEW_MEDIA_TEXTURE mIsMediaTexture = false; #endif //!NEW_MEDIA_TEXTURE @@ -661,42 +650,17 @@ void LLViewerTexture::cleanup() { mFaceList.clear() ; mVolumeList.clear(); - if(mGLTexturep) - { - mGLTexturep->cleanup(); - } } -// virtual void LLViewerTexture::dump() { - if(mGLTexturep) - { - mGLTexturep->dump(); - } + LLGLTexture::dump(); llinfos << "LLViewerTexture" << " mID " << mID << llendl; } -void LLViewerTexture::setBoostLevel(S32 level) -{ - if(mBoostLevel != level) - { - mBoostLevel = level ; - if(mBoostLevel != LLViewerTexture::BOOST_NONE) - { - setNoDelete() ; - } - if(gAuditTexture) - { - setCategory(mBoostLevel); - } - } -} - - bool LLViewerTexture::bindDefaultImage(S32 stage) { if (stage < 0) return false; @@ -899,66 +863,6 @@ void LLViewerTexture::switchToCachedImage() //nothing here. } -void LLViewerTexture::forceActive() -{ - mTextureState = ACTIVE ; -} - -void LLViewerTexture::setActive() -{ - if(mTextureState != NO_DELETE) - { - mTextureState = ACTIVE ; - } -} - -//set the texture to stay in memory -void LLViewerTexture::setNoDelete() -{ - mTextureState = NO_DELETE ; -} - -void LLViewerTexture::generateGLTexture() -{ - if(mGLTexturep.isNull()) - { - mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ; - } -} - -LLImageGL* LLViewerTexture::getGLTexture() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep ; -} - -BOOL LLViewerTexture::createGLTexture() -{ - if(mGLTexturep.isNull()) - { - generateGLTexture() ; - } - - return mGLTexturep->createGLTexture() ; -} - -BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category) -{ - llassert(mGLTexturep.notNull()) ; - - BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ; - - if(ret) - { - mFullWidth = mGLTexturep->getCurrentWidth() ; - mFullHeight = mGLTexturep->getCurrentHeight() ; - mComponents = mGLTexturep->getComponents() ; - setTexelsPerImage(); - } - - return ret ; -} //virtual void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) @@ -966,219 +870,6 @@ void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) //nothing here. } -void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) -{ - llassert(mGLTexturep.notNull()) ; - - mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ; -} -void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode) -{ - llassert(mGLTexturep.notNull()) ; - mGLTexturep->setAddressMode(mode) ; -} -void LLViewerTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option) -{ - llassert(mGLTexturep.notNull()) ; - mGLTexturep->setFilteringOption(option) ; -} - -//virtual -S32 LLViewerTexture::getWidth(S32 discard_level) const -{ - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getWidth(discard_level) ; -} - -//virtual -S32 LLViewerTexture::getHeight(S32 discard_level) const -{ - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getHeight(discard_level) ; -} - -S32 LLViewerTexture::getMaxDiscardLevel() const -{ - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getMaxDiscardLevel() ; -} -S32 LLViewerTexture::getDiscardLevel() const -{ - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getDiscardLevel() ; -} -S8 LLViewerTexture::getComponents() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getComponents() ; -} - -LLGLuint LLViewerTexture::getTexName() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getTexName() ; -} - -BOOL LLViewerTexture::hasGLTexture() const -{ - if(mGLTexturep.notNull()) - { - return mGLTexturep->getHasGLTexture() ; - } - return FALSE ; -} - -BOOL LLViewerTexture::getBoundRecently() const -{ - if(mGLTexturep.notNull()) - { - return mGLTexturep->getBoundRecently() ; - } - return FALSE ; -} - -LLTexUnit::eTextureType LLViewerTexture::getTarget(void) const -{ - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTarget() ; -} - -BOOL LLViewerTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, bool fast_update) -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, fast_update) ; -} - -BOOL LLViewerTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool fast_update) -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height, fast_update) ; -} - -void LLViewerTexture::setGLTextureCreated (bool initialized) -{ - llassert(mGLTexturep.notNull()) ; - - mGLTexturep->setGLTextureCreated (initialized) ; -} - -void LLViewerTexture::setCategory(S32 category) -{ - llassert(mGLTexturep.notNull()) ; - - mGLTexturep->setCategory(category) ; -} - -LLTexUnit::eTextureAddressMode LLViewerTexture::getAddressMode(void) const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getAddressMode() ; -} - -S32 LLViewerTexture::getTextureMemory() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->mTextureMemory ; -} - -LLGLenum LLViewerTexture::getPrimaryFormat() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getPrimaryFormat() ; -} - -BOOL LLViewerTexture::getIsAlphaMask() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getIsAlphaMask() ; -} - -BOOL LLViewerTexture::getMask(const LLVector2 &tc) -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getMask(tc) ; -} - -F32 LLViewerTexture::getTimePassedSinceLastBound() -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getTimePassedSinceLastBound() ; -} -BOOL LLViewerTexture::getMissed() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getMissed() ; -} - -BOOL LLViewerTexture::isJustBound() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->isJustBound() ; -} - -void LLViewerTexture::forceUpdateBindStats(void) const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->forceUpdateBindStats() ; -} - -/*U32 LLViewerTexture::getTexelsInAtlas() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getTexelsInAtlas() ; -} - -U32 LLViewerTexture::getTexelsInGLTexture() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getTexelsInGLTexture() ; -} - -BOOL LLViewerTexture::isGLTextureCreated() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->isGLTextureCreated() ; -} - -S32 LLViewerTexture::getDiscardLevelInAtlas() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getDiscardLevelInAtlas() ; -}*/ - -void LLViewerTexture::destroyGLTexture() -{ - if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) - { - mGLTexturep->destroyGLTexture() ; - mTextureState = DELETED ; - } -} - -void LLViewerTexture::setTexelsPerImage() -{ - S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT); - S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT); - mTexelsPerImage = (F32)fullwidth * fullheight; -} - BOOL LLViewerTexture::isLargeImage() { return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize ; @@ -1330,6 +1021,31 @@ void LLViewerFetchedTexture::cleanup() mCachedRawDiscardLevel = -1 ; mCachedRawImageReady = FALSE ; mSavedRawImage = NULL ; + mSavedRawDiscardLevel = -1; +} + +void LLViewerFetchedTexture::forceRefetch() +{ + bool needs_aux = mNeedsAux; + bool save_raw = mForceToSaveRawImage; + S32 raw_discard = mDesiredSavedRawDiscardLevel; + F32 raw_time = mKeptSavedRawImageTime; + callback_list_t callback_list = mLoadedCallbackList; + mLoadedCallbackList.clear(); + LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); + if(mGLTexturep) + mGLTexturep->forceToInvalidateGLTexture(); + init(false); + mRawImage = NULL; + mAuxRawImage = NULL; + if(save_raw) + forceToSaveRawImage(raw_discard,raw_time); + for(callback_list_t::iterator iter = callback_list.begin(); + iter != callback_list.end(); ++iter) + { + LLLoadedCallbackEntry *entryp = *iter; + setLoadedCallback(entryp->mCallback,entryp->mDesiredDiscard,entryp->mNeedsImageRaw,needs_aux,entryp->mUserData,entryp->mSourceCallbackList,entryp->mPaused); + } } void LLViewerFetchedTexture::setForSculpt() @@ -1337,9 +1053,10 @@ void LLViewerFetchedTexture::setForSculpt() static const S32 MAX_INTERVAL = 8 ; //frames mForSculpt = TRUE ; - if(isForSculptOnly() && !getBoundRecently()) + if(isForSculptOnly() && hasGLTexture() && !getBoundRecently()) { destroyGLTexture() ; //sculpt image does not need gl texture. + mTextureState = ACTIVE; } checkCachedRawSculptImage() ; setMaxVirtualSizeResetInterval(MAX_INTERVAL) ; @@ -1446,7 +1163,11 @@ void LLViewerFetchedTexture::addToCreateTexture() for(U32 i = 0 ; i < mNumFaces ; i++) { - mFaceList[i]->dirtyTexture() ; + LLFace* facep = mFaceList[i]; + if(facep) + { + facep->dirtyTexture() ; + } } //discard the cached raw image and the saved raw image @@ -1735,7 +1456,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority() // Don't decode anything we don't need priority = -4.0f; } - else if ((mBoostLevel == LLViewerTexture::BOOST_UI || mBoostLevel == LLViewerTexture::BOOST_ICON) && !have_all_data) + else if ((mBoostLevel == LLGLTexture::BOOST_UI || mBoostLevel == LLGLTexture::BOOST_ICON) && !have_all_data) { priority = 1.f; } @@ -2096,7 +1817,7 @@ bool LLViewerFetchedTexture::updateFetch() if(make_request) { //load the texture progressively. - S32 delta_level = (mBoostLevel > LLViewerTexture::BOOST_NONE) ? 2 : 1 ; + S32 delta_level = (mBoostLevel > LLGLTexture::BOOST_NONE) ? 2 : 1 ; if (current_discard < 0) { desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level); @@ -2320,7 +2041,7 @@ void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::so destroySavedRawImage() ; } } - else if(needsToSaveRawImage() && mBoostLevel != LLViewerTexture::BOOST_PREVIEW) + else if(needsToSaveRawImage() && mBoostLevel != LLGLTexture::BOOST_PREVIEW) { if(desired_raw_discard != INVALID_DISCARD_LEVEL) { @@ -2782,7 +2503,7 @@ void LLViewerFetchedTexture::setCachedRawImage() S32 h = mRawImage->getHeight() ; S32 max_size = MAX_CACHED_RAW_IMAGE_AREA ; - if(LLViewerTexture::BOOST_TERRAIN == mBoostLevel) + if(LLGLTexture::BOOST_TERRAIN == mBoostLevel) { max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA ; } @@ -3171,7 +2892,7 @@ void LLViewerLODTexture::processTextureStats() if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 } - else if (mBoostLevel < LLViewerTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f) + else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f) { // If the image has not been significantly visible in a while, we don't want it mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1)); @@ -3221,7 +2942,7 @@ void LLViewerLODTexture::processTextureStats() mCalculatedDiscardLevel = discard_level; } } - if (mBoostLevel < LLViewerTexture::BOOST_SCULPTED) + if (mBoostLevel < LLGLTexture::BOOST_SCULPTED) { discard_level += sDesiredDiscardBias; discard_level *= sDesiredDiscardScale; // scale @@ -3247,7 +2968,7 @@ void LLViewerLODTexture::processTextureStats() // S32 current_discard = getDiscardLevel(); - if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLViewerTexture::BOOST_SCULPTED && current_discard >= 0) + if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLGLTexture::BOOST_SCULPTED && current_discard >= 0) { // SH-2516 fix. if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage) diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 85a6b4915..0cbe896a6 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -2,39 +2,32 @@ * @file llviewertexture.h * @brief Object for managing images and their textures * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ - * */ #ifndef LL_LLVIEWERTEXTURE_H #define LL_LLVIEWERTEXTURE_H -#include "lltexture.h" +#include "llgltexture.h" #include "lltimer.h" #include "llframetimer.h" #include "llhost.h" @@ -97,14 +90,9 @@ public: class LLTextureBar; -class LLViewerTexture : public LLTexture +class LLViewerTexture : public LLGLTexture { public: - enum - { - MAX_IMAGE_SIZE_DEFAULT = 1024, - INVALID_DISCARD_LEVEL = 0x7fff - }; enum { LOCAL_TEXTURE, @@ -116,42 +104,6 @@ public: INVALID_TEXTURE_TYPE }; - enum EBoostLevel - { - BOOST_NONE = 0, - BOOST_AVATAR_BAKED , - BOOST_AVATAR , - BOOST_CLOUDS , - BOOST_SCULPTED , - - BOOST_HIGH = 10, - BOOST_BUMP , - BOOST_TERRAIN , // has to be high priority for minimap / low detail - BOOST_SELECTED , - BOOST_AVATAR_BAKED_SELF , - BOOST_AVATAR_SELF , // needed for baking avatar - BOOST_SUPER_HIGH , //textures higher than this need to be downloaded at the required resolution without delay. - BOOST_HUD , - BOOST_ICON , - BOOST_UI , - BOOST_PREVIEW , - BOOST_MAP , - BOOST_MAP_VISIBLE , - BOOST_MAX_LEVEL, - - //other texture Categories - LOCAL = BOOST_MAX_LEVEL, - AVATAR_SCRATCH_TEX, - DYNAMIC_TEX, - MEDIA, - //ATLAS, - OTHER, - MAX_GL_IMAGE_CATEGORY - }; - static S32 getTotalNumOfCategories() ; - static S32 getIndexFromCategory(S32 category) ; - static S32 getCategoryFromIndex(S32 index) ; - typedef std::vector ll_face_list_t; typedef std::vector ll_volume_list_t; @@ -177,9 +129,8 @@ public: /*virtual*/ bool bindDefaultImage(const S32 stage = 0) ; /*virtual*/ void forceImmediateUpdate() ; - const LLUUID& getID() const { return mID; } - - void setBoostLevel(S32 level); + /*virtual*/ const LLUUID& getID() const { return mID; } + //void setBoostLevel(S32 level); S32 getBoostLevel() { return mBoostLevel; } void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const; @@ -191,8 +142,6 @@ public: LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} - S32 getFullWidth() const { return mFullWidth; } - S32 getFullHeight() const { return mFullHeight; } /*virtual*/ void setKnownDrawSize(S32 width, S32 height); virtual void addFace(LLFace* facep) ; @@ -205,60 +154,8 @@ public: S32 getNumVolumes() const; const ll_volume_list_t* getVolumeList() const { return &mVolumeList; } - void generateGLTexture() ; - void destroyGLTexture() ; - //--------------------------------------------------------------------------------------------- - //functions to access LLImageGL - //--------------------------------------------------------------------------------------------- - /*virtual*/S32 getWidth(S32 discard_level = -1) const; - /*virtual*/S32 getHeight(S32 discard_level = -1) const; - - BOOL hasGLTexture() const ; - LLGLuint getTexName() const ; - BOOL createGLTexture() ; - BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLViewerTexture::OTHER); virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; - - void setFilteringOption(LLTexUnit::eTextureFilterOptions option); - void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); - void setAddressMode(LLTexUnit::eTextureAddressMode mode); - BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, bool fast_update = false); - BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool fast_update = false); - void setGLTextureCreated (bool initialized); - void setCategory(S32 category) ; - - LLTexUnit::eTextureAddressMode getAddressMode(void) const ; - S32 getMaxDiscardLevel() const; - S32 getDiscardLevel() const; - S8 getComponents() const ; - BOOL getBoundRecently() const; - S32 getTextureMemory() const ; - LLGLenum getPrimaryFormat() const; - BOOL getIsAlphaMask() const ; - LLTexUnit::eTextureType getTarget(void) const ; - BOOL getMask(const LLVector2 &tc); - F32 getTimePassedSinceLastBound(); - BOOL getMissed() const ; - BOOL isJustBound()const ; - void forceUpdateBindStats(void) const; - - /*U32 getTexelsInAtlas() const ; - U32 getTexelsInGLTexture() const ; - BOOL isGLTextureCreated() const ; - S32 getDiscardLevelInAtlas() const ;*/ - //--------------------------------------------------------------------------------------------- - //end of functions to access LLImageGL - //--------------------------------------------------------------------------------------------- - - //----------------- - /*virtual*/ void setActive() ; - void forceActive() ; - void setNoDelete() ; - void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; } - BOOL getDontDiscard() const { return mDontDiscard; } - //----------------- - BOOL isLargeImage() ; void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;} @@ -271,35 +168,23 @@ protected: void init(bool firstinit) ; void reorganizeFaceList() ; void reorganizeVolumeList() ; - void setTexelsPerImage(); private: friend class LLBumpImageList; friend class LLUIImageList; //note: do not make this function public. - /*virtual*/ LLImageGL* getGLTexture() const ; virtual void switchToCachedImage(); static bool isMemoryForTextureLow() ; protected: LLUUID mID; - S32 mBoostLevel; // enum describing priority level - S32 mFullWidth; - S32 mFullHeight; - BOOL mUseMipMaps ; - S8 mComponents; - F32 mTexelsPerImage; // Texels per image. - mutable S8 mNeedsGLTexture; + mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need? mutable S32 mMaxVirtualSizeResetCounter ; mutable S32 mMaxVirtualSizeResetInterval; mutable F32 mAdditionalDecodePriority; // priority add to mDecodePriority. LLFrameTimer mLastReferencedTimer; - //GL texture - LLPointer mGLTexturep ; - S8 mDontDiscard; // Keep full res version of this image (for UI, etc) - ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture U32 mNumFaces ; LLFrameTimer mLastFaceListUpdateTimer ; @@ -311,17 +196,6 @@ protected: //do not use LLPointer here. LLViewerMediaTexture* mParcelMedia ; -protected: - typedef enum - { - DELETED = 0, //removed from memory - DELETION_CANDIDATE, //ready to be removed from memory - INACTIVE, //not be used for the last certain period (i.e., 30 seconds). - ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). - NO_DELETE = 99 //stay in memory, can not be removed. - } LLGLTextureState; - LLGLTextureState mTextureState ; - static F32 sTexelPixelRatio; public: static const U32 sCurrentFileVersion; @@ -504,6 +378,8 @@ public: void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} void forceToDeleteRequest(); + void forceRefetch(); + protected: /*virtual*/ void switchToCachedImage(); S32 getCurrentDiscardLevelForFetching() ; @@ -742,7 +618,7 @@ public: static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id, BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, // Get the requested level immediately upon creation. + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, @@ -751,7 +627,7 @@ public: static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename, BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, @@ -760,7 +636,7 @@ public: static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url, BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, diff --git a/indra/newview/llviewertextureanim.cpp b/indra/newview/llviewertextureanim.cpp index 9f1ac7c49..2b364851a 100644 --- a/indra/newview/llviewertextureanim.cpp +++ b/indra/newview/llviewertextureanim.cpp @@ -27,21 +27,37 @@ #include "llviewerprecompiledheaders.h" #include "llviewertextureanim.h" +#include "llvovolume.h" #include "llmath.h" #include "llerror.h" -LLViewerTextureAnim::LLViewerTextureAnim() : LLTextureAnim() +std::vector LLViewerTextureAnim::sInstanceList; + +LLViewerTextureAnim::LLViewerTextureAnim(LLVOVolume* vobj) : LLTextureAnim() { + mVObj = vobj; mLastFrame = -1.f; // Force an update initially mLastTime = 0.f; mOffS = mOffT = 0; mScaleS = mScaleT = 1; mRot = 0; + + mInstanceIndex = sInstanceList.size(); + sInstanceList.push_back(this); } LLViewerTextureAnim::~LLViewerTextureAnim() { + S32 end_idx = sInstanceList.size()-1; + + if (end_idx != mInstanceIndex) + { + sInstanceList[mInstanceIndex] = sInstanceList[end_idx]; + sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex; + } + + sInstanceList.pop_back(); } void LLViewerTextureAnim::reset() @@ -50,6 +66,14 @@ void LLViewerTextureAnim::reset() mTimer.reset(); } +//static +void LLViewerTextureAnim::updateClass() +{ + for (std::vector::iterator iter = sInstanceList.begin(); iter != sInstanceList.end(); ++iter) + { + (*iter)->mVObj->animateTextures(); + } +} S32 LLViewerTextureAnim::animateTextures(F32 &off_s, F32 &off_t, F32 &scale_s, F32 &scale_t, diff --git a/indra/newview/llviewertextureanim.h b/indra/newview/llviewertextureanim.h index dd7bd0cb9..abbfabceb 100644 --- a/indra/newview/llviewertextureanim.h +++ b/indra/newview/llviewertextureanim.h @@ -30,10 +30,18 @@ #include "lltextureanim.h" #include "llframetimer.h" +class LLVOVolume; + class LLViewerTextureAnim : public LLTextureAnim { +private: + static std::vector sInstanceList; + S32 mInstanceIndex; + public: - LLViewerTextureAnim(); + static void updateClass(); + + LLViewerTextureAnim(LLVOVolume* vobj); virtual ~LLViewerTextureAnim(); /*virtual*/ void reset(); @@ -51,6 +59,7 @@ public: F32 mRot; protected: + LLVOVolume* mVObj; LLFrameTimer mTimer; F64 mLastTime; F32 mLastFrame; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 937f79701..981421b99 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -65,6 +65,8 @@ #include "pipeline.h" #include "llappviewer.h" #include "llagent.h" +#include "llviewerdisplay.h" +#include "llflexibleobject.h" //////////////////////////////////////////////////////////////////////////// @@ -215,7 +217,7 @@ void LLViewerTextureList::doPrefetchImages() if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type) { - LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, MIPMAP_TRUE, LLViewerTexture::BOOST_NONE, texture_type); + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type); if (image) { image->addTextureStats((F32)pixel_area); @@ -245,7 +247,9 @@ void LLViewerTextureList::shutdown() if (!image->hasGLTexture() || !image->getUseDiscard() || image->needsAux() || - image->getTargetHost() != LLHost::invalid) + image->getTargetHost() != LLHost::invalid || + !image->getUrl().empty() + ) { continue; // avoid UI, baked, and other special images } @@ -355,7 +359,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& if (full_path.empty()) { llwarns << "Failed to find local image file: " << filename << llendl; - return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI); + return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI); } std::string url = "file://" + full_path; @@ -380,7 +384,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& { // Never mind that this ignores image_set_id; // getImage() will handle that later. - return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI); + return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI); } // generate UUID based on hash of filename @@ -453,7 +457,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, if ((&image_id == NULL) || image_id.isNull()) { - return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI)); + return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI)); } LLPointer imagep = findImage(image_id); @@ -623,11 +627,30 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MEDIA("Media"); void LLViewerTextureList::updateImages(F32 max_time) { - if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) + static BOOL cleared = FALSE; + static const LLCachedControl hide_tp_screen("AscentDisableTeleportScreens",false); + + //Can't check gTeleportDisplay due to a process_teleport_local(), which sets it to true for local teleports... so: + // Do this case if IS teleporting but NOT local teleporting, AND either the TP screen is set to appear OR we just entered the sim (TELEPORT_START_ARRIVAL) + LLAgent::ETeleportState state = gAgent.getTeleportState(); + if(state != LLAgent::TELEPORT_NONE && state != LLAgent::TELEPORT_LOCAL && state != LLAgent::TELEPORT_PENDING && + (!hide_tp_screen || state == LLAgent::TELEPORT_START_ARRIVAL || state == LLAgent::TELEPORT_ARRIVING)) { - clearFetchingRequests(); + if(!cleared) + { + llinfos << "Flushing upon teleport." << llendl; + clearFetchingRequests(); + //gPipeline.clearRebuildGroups() really doesn't belong here... but since it is here, do a few other needed things too. + gPipeline.clearRebuildGroups(); + gPipeline.resetVertexBuffers(); + LLVolumeImplFlexible::resetTimers(); + cleared = TRUE; + } return; } + cleared = FALSE; + + LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); S32 global_raw_memory; { @@ -705,14 +728,13 @@ void LLViewerTextureList::clearFetchingRequests() return; } + LLAppViewer::getTextureFetch()->deleteAllRequests(); + for (image_priority_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ++iter) { - LLViewerFetchedTexture* image = *iter; - if(image->hasFetcher()) - { - image->forceToDeleteRequest() ; - } + LLViewerFetchedTexture* imagep = *iter; + imagep->forceToDeleteRequest() ; } } @@ -720,10 +742,11 @@ void LLViewerTextureList::updateImagesDecodePriorities() { // Update the decode priority for N images each frame { - const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second - S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10); + static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32 + const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds) + 1, MAX_PRIO_UPDATES); + S32 update_counter = llmin(max_update_count, mUUIDMap.size()); uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); - while(update_counter > 0 && !mUUIDMap.empty()) + while ((update_counter-- > 0) && !mUUIDMap.empty()) { if (iter == mUUIDMap.end()) { @@ -787,6 +810,10 @@ void LLViewerTextureList::updateImagesDecodePriorities() } } + if (!imagep->isInImageList()) + { + continue; + } imagep->processTextureStats(); F32 old_priority = imagep->getDecodePriority(); F32 old_priority_test = llmax(old_priority, 0.0f); @@ -800,7 +827,6 @@ void LLViewerTextureList::updateImagesDecodePriorities() imagep->setDecodePriority(decode_priority); addImageToList(imagep); } - update_counter--; } } } @@ -884,15 +910,26 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) { LLTimer image_op_timer; - // Update the decode priority for N images each frame - // Make a list with 32 high priority entries + 256 cycled entries - const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32); - const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256); + // Update fetch for N images each frame + static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority"); // default: 32 + static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority"); // default: 256 + static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority"); // default: 32 + static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0 + static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false + + size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT); + //Old: size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*40.f*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT); + max_priority_count = llmin(max_priority_count, mImageList.size()); - // 32 high priority entries + size_t total_update_count = mUUIDMap.size(); + size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT); + //Old: size_t max_priority_count = llmin((S32) (MAX_UPDATE_COUNT*40.f*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT); + max_update_count = llmin(max_update_count, total_update_count); + + // MAX_HIGH_PRIO_COUNT high priority entries typedef std::vector entries_list_t; entries_list_t entries; - size_t update_counter = llmin(max_priority_count, mImageList.size()); + size_t update_counter = max_priority_count; image_priority_list_t::iterator iter1 = mImageList.begin(); while(update_counter > 0) { @@ -902,43 +939,46 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) update_counter--; } - // 256 cycled entries - update_counter = llmin(max_update_count, mUUIDMap.size()); + // MAX_UPDATE_COUNT cycled entries + update_counter = max_update_count; if(update_counter > 0) { uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID); - uuid_map_t::iterator iter2p = iter2; - while(update_counter > 0) + while ((update_counter > 0) && (total_update_count > 0)) { if (iter2 == mUUIDMap.end()) { iter2 = mUUIDMap.begin(); } - entries.push_back(iter2->second); - iter2p = iter2++; - update_counter--; - } + LLViewerFetchedTexture* imagep = iter2->second; + // Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set. + if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher()))) + { + entries.push_back(imagep); + update_counter--; + } - mLastFetchUUID = iter2p->first; + iter2++; + total_update_count--; + } } S32 fetch_count = 0; - S32 min_count = max_priority_count + max_update_count/4; + size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); + S32 min_count = max_priority_count + min_update_count; for (entries_list_t::iterator iter3 = entries.begin(); iter3 != entries.end(); ) { LLViewerFetchedTexture* imagep = *iter3++; - - bool fetching = imagep->updateFetch(); - if (fetching) + fetch_count += (imagep->updateFetch() ? 1 : 0); + if (min_count <= (S32)min_update_count) { - fetch_count++; + mLastFetchUUID = imagep->getID(); } - if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time) + if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time)) { break; } - min_count--; } //if (fetch_count == 0) //{ @@ -1304,7 +1344,7 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d U8 *data = new U8[data_size]; msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); - LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); if (!image) { delete [] data; @@ -1377,7 +1417,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d U8 *data = new U8[data_size]; msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); - LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); if (!image) { delete [] data; @@ -1477,9 +1517,9 @@ LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priori LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority ) { - if (boost_priority == LLViewerTexture::BOOST_NONE) + if (boost_priority == LLGLTexture::BOOST_NONE) { - boost_priority = LLViewerTexture::BOOST_UI; + boost_priority = LLGLTexture::BOOST_UI; } LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, MIPMAP_NO, boost_priority); return loadUIImage(imagep, name, use_mips, scale_rect, clip_rect); @@ -1488,9 +1528,9 @@ LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority) { - if (boost_priority == LLViewerTexture::BOOST_NONE) + if (boost_priority == LLGLTexture::BOOST_NONE) { - boost_priority = LLViewerTexture::BOOST_UI; + boost_priority = LLGLTexture::BOOST_UI; } LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, MIPMAP_NO, boost_priority); return loadUIImage(imagep, id.asString(), use_mips, scale_rect, clip_rect); @@ -1515,7 +1555,7 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st //Note: //Some other textures such as ICON also through this flow to be fetched. //But only UI textures need to set this callback. - if(imagep->getBoostLevel() == LLViewerTexture::BOOST_UI) + if(imagep->getBoostLevel() == LLGLTexture::BOOST_UI) { LLUIImageLoadData* datap = new LLUIImageLoadData; datap->mImageName = name; diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 043a48cbd..57d6bc91d 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -131,7 +131,7 @@ private: LLViewerFetchedTexture * getImage(const LLUUID &image_id, BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, // Get the requested level immediately upon creation. + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, @@ -140,7 +140,7 @@ private: LLViewerFetchedTexture * getImageFromFile(const std::string& filename, BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, // Get the requested level immediately upon creation. + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, @@ -149,7 +149,7 @@ private: LLViewerFetchedTexture* getImageFromUrl(const std::string& url, BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, // Get the requested level immediately upon creation. + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, @@ -158,7 +158,7 @@ private: LLViewerFetchedTexture* createImage(const LLUUID &image_id, BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, // Get the requested level immediately upon creation. + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, LLGLenum primary_format = 0, @@ -168,7 +168,7 @@ private: // Request image from a specific host, used for baked avatar textures. // Implemented in header in case someone changes default params above. JC LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host) - { return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } + { return getImage(image_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } public: typedef std::set > image_list_t; @@ -225,11 +225,11 @@ private: LLPointer loadUIImageByName(const std::string& name, const std::string& filename, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null, - LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI); + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI); LLPointer loadUIImageByID(const LLUUID& id, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null, - LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI); + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI); LLPointer loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null); diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp new file mode 100644 index 000000000..2c4c87caf --- /dev/null +++ b/indra/newview/llviewerwearable.cpp @@ -0,0 +1,698 @@ +/** + * @file llviewerwearable.cpp + * @brief LLViewerWearable class implementation + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llagent.h" +#include "llagentcamera.h" +#include "llagentwearables.h" +#include "llfloatercustomize.h" +#include "llnotificationsutil.h" +#include "lltextureentry.h" +#include "llviewertexlayer.h" +#include "llvoavatarself.h" +#include "llavatarappearancedefines.h" +#include "llviewerwearable.h" +#include "llviewercontrol.h" +#include "llviewerregion.h" +#include "llinventoryobserver.h" + +using namespace LLAvatarAppearanceDefines; + +// support class - remove for 2.1 (hackity hack hack) +class LLOverrideBakedTextureUpdate +{ +public: + LLOverrideBakedTextureUpdate(bool temp_state) + { + U32 num_bakes = (U32) LLAvatarAppearanceDefines::BAKED_NUM_INDICES; + for( U32 index = 0; index < num_bakes; ++index ) + { + composite_enabled[index] = gAgentAvatarp->isCompositeUpdateEnabled(index); + } + gAgentAvatarp->setCompositeUpdatesEnabled(temp_state); + } + + ~LLOverrideBakedTextureUpdate() + { + U32 num_bakes = (U32)LLAvatarAppearanceDefines::BAKED_NUM_INDICES; + for( U32 index = 0; index < num_bakes; ++index ) + { + gAgentAvatarp->setCompositeUpdatesEnabled(index, composite_enabled[index]); + } + } +private: + bool composite_enabled[LLAvatarAppearanceDefines::BAKED_NUM_INDICES]; +}; + +// Private local functions +static std::string asset_id_to_filename(const LLUUID &asset_id); + +LLViewerWearable::LLViewerWearable(const LLTransactionID& transaction_id) : + LLWearable() +{ + mTransactionID = transaction_id; + mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID()); +} + +LLViewerWearable::LLViewerWearable(const LLAssetID& asset_id) : + LLWearable() +{ + mAssetID = asset_id; + mTransactionID.setNull(); +} + +// virtual +LLViewerWearable::~LLViewerWearable() +{ +} + +// virtual +LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp ) +{ + // suppress texlayerset updates while wearables are being imported. Layersets will be updated + // when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed. + LLOverrideBakedTextureUpdate stop_bakes(false); + + LLWearable::EImportResult result = LLWearable::importStream(input_stream, avatarp); + if (LLWearable::FAILURE == result) return result; + if (LLWearable::BAD_HEADER == result) + { + // Shouldn't really log the asset id for security reasons, but + // we need it in this case. + llwarns << "Bad Wearable asset header: " << mAssetID << llendl; + //gVFS->dumpMap(); + return result; + } + + LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN ); + LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN ); + + te_map_t::const_iterator iter = mTEMap.begin(); + te_map_t::const_iterator end = mTEMap.end(); + for (; iter != end; ++iter) + { + S32 te = iter->first; + LLLocalTextureObject* lto = iter->second; + LLUUID textureid = LLUUID::null; + if (lto) + { + textureid = lto->getID(); + } + + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( textureid ); + if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) + { + image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(textureid, (LLAvatarAppearanceDefines::ETextureIndex)te), NULL); + } + } + + return result; +} + + +// Avatar parameter and texture definitions can change over time. +// This function returns true if parameters or textures have been added or removed +// since this wearable was created. +BOOL LLViewerWearable::isOldVersion() const +{ + if (!isAgentAvatarValid()) return FALSE; + + if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion ) + { + llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl; + llassert(0); + } + + if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion ) + { + return TRUE; + } + + S32 param_count = 0; + for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); + param; + param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() ) + { + if( (param->getWearableType() == mType) && (param->isTweakable() ) ) + { + param_count++; + if( !is_in_map(mVisualParamIndexMap, param->getID() ) ) + { + return TRUE; + } + } + } + if( param_count != mVisualParamIndexMap.size() ) + { + return TRUE; + } + + + S32 te_count = 0; + for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) + { + if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType) + { + te_count++; + if( !is_in_map(mTEMap, te ) ) + { + return TRUE; + } + } + } + if( te_count != mTEMap.size() ) + { + return TRUE; + } + + return FALSE; +} + +// Avatar parameter and texture definitions can change over time. +// * If parameters or textures have been REMOVED since the wearable was created, +// they're just ignored, so we consider the wearable clean even though isOldVersion() +// will return true. +// * If parameters or textures have been ADDED since the wearable was created, +// they are taken to have default values, so we consider the wearable clean +// only if those values are the same as the defaults. +BOOL LLViewerWearable::isDirty() const +{ + if (!isAgentAvatarValid()) return FALSE; + + for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); + param; + param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() ) + { + if( (param->getWearableType() == mType) + && (param->isTweakable() ) + && !param->getCrossWearable()) + { + F32 current_weight = getVisualParamWeight(param->getID()); + current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() ); + F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight()); + saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() ); + + U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() ); + U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() ); + + if( a != b ) + { + //llwarns << "param ID " << param->getID() << " was changed." << llendl; + return TRUE; + } + } + } + + for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) + { + if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType) + { + te_map_t::const_iterator current_iter = mTEMap.find(te); + if(current_iter != mTEMap.end()) + { + const LLUUID& current_image_id = current_iter->second->getID(); + te_map_t::const_iterator saved_iter = mSavedTEMap.find(te); + if(saved_iter != mSavedTEMap.end()) + { + const LLUUID& saved_image_id = saved_iter->second->getID(); + if (saved_image_id != current_image_id) + { + // saved vs current images are different, wearable is dirty + return TRUE; + } + } + else + { + // image found in current image list but not saved image list + return TRUE; + } + } + } + } + + return FALSE; +} + + +void LLViewerWearable::setParamsToDefaults() +{ + if (!isAgentAvatarValid()) return; + + for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() ) + { + if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->isTweakable() ) ) + { + setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE); + } + } +} + +void LLViewerWearable::setTexturesToDefaults() +{ + for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) + { + if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType) + { + LLUUID id = getDefaultTextureImageID((ETextureIndex) te); + LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id ); + if( mTEMap.find(te) == mTEMap.end() ) + { + mTEMap[te] = new LLLocalTextureObject(image, id); + createLayers(te, gAgentAvatarp); + } + else + { + // Local Texture Object already created, just set image and UUID + LLLocalTextureObject *lto = mTEMap[te]; + lto->setID(id); + lto->setImage(image); + } + } + } +} + + +// virtual +const LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const +{ + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index); + const std::string &default_image_name = texture_dict->mDefaultImageName; + if (default_image_name == "") + { + return IMG_DEFAULT_AVATAR; + } + else + { + return LLUUID(gSavedSettings.getString(default_image_name)); + } +} + + +// Updates the user's avatar's appearance +//virtual +void LLViewerWearable::writeToAvatar(LLAvatarAppearance *avatarp) +{ + LLVOAvatarSelf* viewer_avatar = dynamic_cast(avatarp); + + if (!avatarp || !viewer_avatar) return; + + if (!viewer_avatar->isValid()) return; + +#if 0 + // FIXME DRANO - kludgy way to avoid overwriting avatar state from wearables. + // Ideally would avoid calling this func in the first place. + if (viewer_avatar->isUsingServerBakes() && + !viewer_avatar->isUsingLocalAppearance()) + { + return; + } +#endif + + ESex old_sex = avatarp->getSex(); + + LLWearable::writeToAvatar(avatarp); + + + // Pull texture entries + for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) + { + if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType) + { + te_map_t::const_iterator iter = mTEMap.find(te); + LLUUID image_id; + if(iter != mTEMap.end()) + { + image_id = iter->second->getID(); + } + else + { + image_id = getDefaultTextureImageID((ETextureIndex) te); + } + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE ); + // MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this. + viewer_avatar->setLocalTextureTE(te, image, 0); + } + } + + ESex new_sex = avatarp->getSex(); + if( old_sex != new_sex ) + { + viewer_avatar->updateSexDependentLayerSets( FALSE ); + } +} + + +// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values. +// static +void LLViewerWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake ) +{ + if (!isAgentAvatarValid()) return; + + // You can't just remove body parts. + if( (type == LLWearableType::WT_SHAPE) || + (type == LLWearableType::WT_SKIN) || + (type == LLWearableType::WT_HAIR) || + (type == LLWearableType::WT_EYES) ) + { + return; + } + + // Pull params + for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() ) + { + if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->isTweakable()) ) + { + S32 param_id = param->getID(); + gAgentAvatarp->setVisualParamWeight( param_id, param->getDefaultWeight(), upload_bake ); + } + } + + if(isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance() && LLFloaterCustomize::instanceExists()) + { + LLFloaterCustomize::getInstance()->wearablesChanged(type); + } + + gAgentAvatarp->updateVisualParams(); + gAgentAvatarp->wearableUpdated(type, FALSE); + +// if( upload_bake ) +// { +// gAgent.sendAgentSetAppearance(); +// } +} + +// Does not copy mAssetID. +// Definition version is current: removes obsolete enties and creates default values for new ones. +void LLViewerWearable::copyDataFrom(const LLViewerWearable* src) +{ + if (!isAgentAvatarValid()) return; + + mDefinitionVersion = LLWearable::sCurrentDefinitionVersion; + + mName = src->mName; + mDescription = src->mDescription; + mPermissions = src->mPermissions; + mSaleInfo = src->mSaleInfo; + + setType(src->mType, gAgentAvatarp); + + mSavedVisualParamMap.clear(); + // Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed) + for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); + param; + param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() ) + { + if( (param->getWearableType() == mType) ) + { + S32 id = param->getID(); + F32 weight = src->getVisualParamWeight(id); + mSavedVisualParamMap[id] = weight; + } + } + + destroyTextures(); + // Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed) + for (S32 te = 0; te < TEX_NUM_INDICES; te++) + { + if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType) + { + te_map_t::const_iterator iter = src->mTEMap.find(te); + LLUUID image_id; + LLViewerFetchedTexture *image = NULL; + if(iter != src->mTEMap.end()) + { + image = dynamic_cast (src->getLocalTextureObject(te)->getImage()); + image_id = src->getLocalTextureObject(te)->getID(); + mTEMap[te] = new LLLocalTextureObject(image, image_id); + mSavedTEMap[te] = new LLLocalTextureObject(image, image_id); + mTEMap[te]->setBakedReady(src->getLocalTextureObject(te)->getBakedReady()); + mTEMap[te]->setDiscard(src->getLocalTextureObject(te)->getDiscard()); + } + else + { + image_id = getDefaultTextureImageID((ETextureIndex) te); + image = LLViewerTextureManager::getFetchedTexture( image_id ); + mTEMap[te] = new LLLocalTextureObject(image, image_id); + mSavedTEMap[te] = new LLLocalTextureObject(image, image_id); + } + createLayers(te, gAgentAvatarp); + } + } + + // 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(); +} + +void LLViewerWearable::setItemID(const LLUUID& item_id) +{ + mItemID = item_id; +} + +void LLViewerWearable::revertValues() +{ +#if 0 + // DRANO avoid overwrite when not in local appearance + if (isAgentAvatarValid() && gAgentAvatarp->isUsingServerBakes() && !gAgentAvatarp->isUsingLocalAppearance()) + { + return; + } +#endif + LLWearable::revertValues(); + + + /*LLSidepanelAppearance *panel = dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance")); + if( panel ) + { + panel->updateScrollingPanelList(); + }*/ + if( LLFloaterCustomize::instanceExists() && gAgentWearables.getWearableIndex(this)==0 ) + LLFloaterCustomize::getInstance()->updateScrollingPanelList(); + +} + +void LLViewerWearable::saveValues() +{ + LLWearable::saveValues(); + + /*LLSidepanelAppearance *panel = dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance")); + if( panel ) + { + panel->updateScrollingPanelList(); + }*/ + + if( LLFloaterCustomize::instanceExists() && gAgentWearables.getWearableIndex(this)==0) + LLFloaterCustomize::getInstance()->updateScrollingPanelList(); +} + +/*void LLViewerWearable::readFromAvatar() +{ + LLVOAvatar* avatar = gAgentAvatarp; + llassert( avatar ); + if( !avatar ) + { + return; + } + + mDefinitionVersion = LLViewerWearable::sCurrentDefinitionVersion; + + mVisualParamMap.clear(); + for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) + { + if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->isTweakable()) ) + { + mVisualParamMap[param->getID()] = param->getWeight(); + } + } + + mTEMap.clear(); + for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) + { + if( LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te ) == mType ) + { + LLViewerTexture* image = avatar->getTEImage( te ); + if( image ) + { + mTEMap[te] = image->getID(); + } + } + } + + //if( gFloaterCustomize ) + //{ + // mDescription = gFloaterCustomize->getWearableDescription( mType ); + //} +}*/ + +// virtual +void LLViewerWearable::setUpdated() const +{ + gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID()); +} + +void LLViewerWearable::refreshName() +{ + LLUUID item_id = getItemID(); + LLInventoryItem* item = gInventory.getItem(item_id); + if( item ) + { + mName = item->getName(); + } +} + +// virtual +void LLViewerWearable::addToBakedTextureHash(LLMD5& hash) const +{ + LLUUID asset_id = getAssetID(); + hash.update((const unsigned char*)asset_id.mData, UUID_BYTES); +} + +struct LLWearableSaveData +{ + LLWearableType::EType mType; +}; + +void LLViewerWearable::saveNewAsset() const +{ +// llinfos << "LLViewerWearable::saveNewAsset() type: " << getTypeName() << llendl; + //llinfos << *this << llendl; + + const std::string filename = asset_id_to_filename(mAssetID); + LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */ + BOOL successful_save = FALSE; + if(fp && exportFile(fp)) + { + successful_save = TRUE; + } + if(fp) + { + fclose(fp); + fp = NULL; + } + if(!successful_save) + { + std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str()); + llwarns << buffer << llendl; + + LLSD args; + args["NAME"] = mName; + LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args); + return; + } + + // save it out to database + if( gAssetStorage ) + { + /* + std::string url = gAgent.getRegion()->getCapability("NewAgentInventory"); + if (!url.empty()) + { + llinfos << "Update Agent Inventory via capability" << llendl; + LLSD body; + body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetToFolderType(getAssetType())); + body["asset_type"] = LLAssetType::lookup(getAssetType()); + body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE); + body["name"] = getName(); + body["description"] = getDescription(); + LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename)); + } + else + { + } + */ + LLWearableSaveData* data = new LLWearableSaveData; + data->mType = mType; + gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(), + &LLViewerWearable::onSaveNewAssetComplete, + (void*)data); + } +} + +// static +void LLViewerWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) +{ + LLWearableSaveData* data = (LLWearableSaveData*)userdata; + const std::string& type_name = LLWearableType::getTypeName(data->mType); + if(0 == status) + { + // Success + llinfos << "Saved wearable " << type_name << llendl; + } + else + { + std::string buffer = llformat("Unable to save %s to central asset store.", type_name.c_str()); + llwarns << buffer << " Status: " << status << llendl; + LLSD args; + args["NAME"] = type_name; + LLNotificationsUtil::add("CannotSaveToAssetStore", args); + } + + // Delete temp file + const std::string src_filename = asset_id_to_filename(new_asset_id); + LLFile::remove(src_filename); + + // delete the context data + delete data; + +} + +std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w) +{ + s << "wearable " << LLWearableType::getTypeName(w.mType) << "\n"; + s << " Name: " << w.mName << "\n"; + s << " Desc: " << w.mDescription << "\n"; + //w.mPermissions + //w.mSaleInfo + + s << " Params:" << "\n"; + for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin(); + iter != w.mVisualParamIndexMap.end(); ++iter) + { + S32 param_id = iter->first; + LLVisualParam *wearable_param = iter->second; + F32 param_weight = wearable_param->getWeight(); + s << " " << param_id << " " << param_weight << "\n"; + } + + s << " Textures:" << "\n"; + for (LLViewerWearable::te_map_t::const_iterator iter = w.mTEMap.begin(); + iter != w.mTEMap.end(); ++iter) + { + S32 te = iter->first; + const LLUUID& image_id = iter->second->getID(); + s << " " << te << " " << image_id << "\n"; + } + return s; +} + +std::string asset_id_to_filename(const LLUUID &asset_id) +{ + std::string asset_id_string; + asset_id.toString(asset_id_string); + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl"; + return filename; +} diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h new file mode 100644 index 000000000..85d4faaf6 --- /dev/null +++ b/indra/newview/llviewerwearable.h @@ -0,0 +1,103 @@ +/** + * @file llviewerwearable.h + * @brief LLViewerWearable class header file + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_VIEWER_WEARABLE_H +#define LL_VIEWER_WEARABLE_H + +#include "llwearable.h" +#include "llavatarappearancedefines.h" + +class LLVOAvatar; + +class LLViewerWearable : public LLWearable +{ + friend class LLWearableList; + + //-------------------------------------------------------------------- + // Constructors and destructors + //-------------------------------------------------------------------- +private: + // Private constructors used by LLWearableList + LLViewerWearable(const LLTransactionID& transactionID); + LLViewerWearable(const LLAssetID& assetID); +public: + virtual ~LLViewerWearable(); + + //-------------------------------------------------------------------- + // Accessors + //-------------------------------------------------------------------- +public: + const LLUUID& getItemID() const { return mItemID; } + const LLAssetID& getAssetID() const { return mAssetID; } + const LLTransactionID& getTransactionID() const { return mTransactionID; } + void setItemID(const LLUUID& item_id); + +public: + + BOOL isDirty() const; + BOOL isOldVersion() const; + + /*virtual*/ void writeToAvatar(LLAvatarAppearance *avatarp); + void removeFromAvatar( BOOL upload_bake ) { LLViewerWearable::removeFromAvatar( mType, upload_bake ); } + static void removeFromAvatar( LLWearableType::EType type, BOOL upload_bake ); + + /*virtual*/ EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp ); + + void setParamsToDefaults(); + void setTexturesToDefaults(); + + /*virtual*/ const LLUUID getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const; + + + void saveNewAsset() const; + static void onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status ); + + void copyDataFrom(const LLViewerWearable* src); + + friend std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w); + + /*virtual*/ void revertValues(); + /*virtual*/ void saveValues(); + + // Something happened that requires the wearable's label to be updated (e.g. worn/unworn). + void setUpdated() const; + + // the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem, + // not the wearable asset itself. + void refreshName(); + + // Update the baked texture hash. + /*virtual*/void addToBakedTextureHash(LLMD5& hash) const; + +protected: + LLAssetID mAssetID; + LLTransactionID mTransactionID; + + LLUUID mItemID; // ID of the inventory item in the agent's inventory +}; + + +#endif // LL_VIEWER_WEARABLE_H diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1c4bdfcff..c5f44f342 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -128,10 +128,10 @@ #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" +#include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmodaldialog.h" #include "llmorphview.h" #include "llmoveview.h" -#include "llpanelpathfindingrebakenavmesh.h" #include "llnotify.h" #include "lloverlaybar.h" #include "llpreviewtexture.h" @@ -366,7 +366,7 @@ public: if (isAgentAvatarValid()) { - tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition()); + tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition()); agent_root_center_text = llformat("AgentRootCenter %f %f %f", (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); } @@ -1467,7 +1467,7 @@ LLViewerWindow::LLViewerWindow( mIgnoreActivate( FALSE ), mHoverPick(), mResDirty(false), - mStatesDirty(false), + //mStatesDirty(false), //Singu Note: No longer needed. State update is now in restoreGL. mIsFullscreenChecked(false), mCurrResolutionIndex(0) { @@ -1959,10 +1959,11 @@ void LLViewerWindow::initWorldUI() // put behind everything else in the UI mRootView->addChildInBack(gHUDView); } - + LLPanel* panel_ssf_container = getRootView()->getChild("state_management_buttons_container"); - LLPanelPathfindingRebakeNavmesh *panel_rebake_navmesh = LLPanelPathfindingRebakeNavmesh::getInstance(); - panel_ssf_container->addChild(panel_rebake_navmesh); + panel_ssf_container->setVisible(TRUE); + + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize(); } // initWorldUI that wasn't before logging in. Some of this may require the access the 'LindenUserDir'. @@ -2041,6 +2042,9 @@ void LLViewerWindow::shutdownViews() // Delete all child views. delete mRootView; mRootView = NULL; + llinfos << "RootView deleted." << llendl ; + + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit(); // Automatically deleted as children of mRootView. Fix the globals. gFloaterTools = NULL; @@ -2203,7 +2207,7 @@ void LLViewerWindow::reshape(S32 width, S32 height) mWindowRectRaw.mTop = mWindowRectRaw.mBottom + height; calcDisplayScale(); - BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor; + BOOL display_scale_changed = mDisplayScale != LLUI::getScaleFactor(); LLUI::setScaleFactor(mDisplayScale); // update our window rectangle @@ -2382,7 +2386,7 @@ void LLViewerWindow::draw() // scale view by UI global scale factor and aspect ratio correction factor gGL.scalef(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); - LLVector2 old_scale_factor = LLUI::sGLScaleFactor; + LLVector2 old_scale_factor = LLUI::getScaleFactor(); // apply camera zoom transform (for high res screenshots) F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion(); @@ -2396,7 +2400,7 @@ void LLViewerWindow::draw() (F32)getWindowHeightScaled() * -(F32)pos_y, 0.f); gGL.scalef(zoom_factor, zoom_factor, 1.f); - LLUI::sGLScaleFactor *= zoom_factor; + LLUI::getScaleFactor() *= zoom_factor; } // Draw tool specific overlay on world @@ -2464,7 +2468,7 @@ void LLViewerWindow::draw() LLFontGL::HCENTER, LLFontGL::TOP); } - LLUI::sGLScaleFactor = old_scale_factor; + LLUI::setScaleFactor(old_scale_factor); } gGL.popMatrix(); @@ -3236,8 +3240,8 @@ void LLViewerWindow::hoverPickCallback(const LLPickInfo& pick_info) void LLViewerWindow::updateMouseDelta() { - S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]); - S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]); + S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]); + S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]); //RN: fix for asynchronous notification of mouse leaving window not working LLCoordWindow mouse_pos; @@ -3986,10 +3990,11 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d } // Saves an image to the harddrive as "SnapshotX" where X >= 1. -void LLViewerWindow::saveImageNumbered(LLPointer image) +void LLViewerWindow::saveImageNumbered(LLPointer image, int index) { if (!image) { + LLFloaterSnapshot::saveLocalDone(false, index); return; } @@ -4018,15 +4023,15 @@ void LLViewerWindow::saveImageNumbered(LLPointer image) // pick a directory in which to save AIFilePicker* filepicker = AIFilePicker::create(); // Deleted in LLViewerWindow::saveImageNumbered_continued1 filepicker->open(proposed_name, pick_type, "", "snapshot"); - filepicker->run(boost::bind(&LLViewerWindow::saveImageNumbered_continued1, this, image, extension, filepicker)); + filepicker->run(boost::bind(&LLViewerWindow::saveImageNumbered_continued1, this, image, extension, filepicker, index)); return; } // LLViewerWindow::sSnapshotBaseName and LLViewerWindow::sSnapshotDir already known. Go straight to saveImageNumbered_continued2. - saveImageNumbered_continued2(image, extension); + saveImageNumbered_continued2(image, extension, index); } -void LLViewerWindow::saveImageNumbered_continued1(LLPointer image, std::string const& extension, AIFilePicker* filepicker) +void LLViewerWindow::saveImageNumbered_continued1(LLPointer image, std::string const& extension, AIFilePicker* filepicker, int index) { if (filepicker->hasFilename()) { @@ -4036,11 +4041,15 @@ void LLViewerWindow::saveImageNumbered_continued1(LLPointer im LLViewerWindow::sSnapshotBaseName = gDirUtilp->getBaseFileName(filepath, true); LLViewerWindow::sSnapshotDir = gDirUtilp->getDirName(filepath); - saveImageNumbered_continued2(image, extension); + saveImageNumbered_continued2(image, extension, index); + } + else + { + LLFloaterSnapshot::saveLocalDone(false, index); } } -void LLViewerWindow::saveImageNumbered_continued2(LLPointer image, std::string const& extension) +void LLViewerWindow::saveImageNumbered_continued2(LLPointer image, std::string const& extension, int index) { // Look for an unused file name std::string filepath; @@ -4064,6 +4073,11 @@ void LLViewerWindow::saveImageNumbered_continued2(LLPointer im if (image->save(filepath)) { playSnapshotAnimAndSound(); + LLFloaterSnapshot::saveLocalDone(true, index); + } + else + { + LLFloaterSnapshot::saveLocalDone(false, index); } } @@ -4093,10 +4107,14 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height) BOOL disable_sync = gSavedSettings.getBOOL("DisableVerticalSync"); if (gViewerWindow->mWindow->getFullscreen()) { + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); gViewerWindow->changeDisplaySettings(FALSE, new_size, disable_sync, TRUE); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); } else { @@ -4110,7 +4128,7 @@ BOOL LLViewerWindow::saveSnapshot( const std::string& filepath, S32 image_width, llinfos << "Saving snapshot to: " << filepath << llendl; LLPointer raw = new LLImageRaw; - BOOL success = rawSnapshot(raw, image_width, image_height, TRUE, FALSE, show_ui, do_rebuild); + BOOL success = rawSnapshot(raw, image_width, image_height, (F32)image_width / image_height, show_ui, do_rebuild); if (success) { @@ -4146,7 +4164,7 @@ void LLViewerWindow::playSnapshotAnimAndSound() BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) { - return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type); + return rawSnapshot(raw, preview_width, preview_height, (F32)gViewerWindow->getWindowWidthRaw() / gViewerWindow->getWindowHeightRaw(), show_ui, do_rebuild, type); // *TODO below code was broken in deferred pipeline /* @@ -4285,25 +4303,29 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p return TRUE;*/ } -// Saves the image from the screen to the specified filename and path. -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, F32 supersample) +// Saves the image from the screen to the image pointed to by raw. +// This function does NOT yet scale the snapshot down to the requested size +// if that is smaller than the current window (scale_factor < 1) or if +// the aspect of the snapshot is unequal to the aspect of requested image. +bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw, + S32 image_width, S32 image_height, F32 snapshot_aspect, BOOL show_ui, + BOOL do_rebuild, ESnapshotType type, S32 max_size, F32 supersample) { if (!raw) { - return FALSE; + return false; } //check if there is enough memory for the snapshot image if(LLPipeline::sMemAllocationThrottled) { - return FALSE ; //snapshot taking is disabled due to memory restriction. + return false; //snapshot taking is disabled due to memory restriction. } if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K { if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3)) { llwarns << "No enough memory to take the snapshot with size (w : h): " << image_width << " : " << image_height << llendl ; - return FALSE ; //there is no enough memory for taking this snapshot. + return false; //there is no enough memory for taking this snapshot. } } @@ -4327,27 +4349,13 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei LLPipeline::sShowHUDAttachments = FALSE; } - // Copy screen to a buffer - // crop sides or top and bottom, if taking a snapshot of different aspect ratio - // from window - LLRect window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw(); - S32 snapshot_width = window_rect.getWidth(); - S32 snapshot_height = window_rect.getHeight(); + LLRect const window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw(); + S32 const window_width = window_rect.getWidth(); + S32 const window_height = window_rect.getHeight(); + // SNAPSHOT - S32 window_width = snapshot_width; - S32 window_height = snapshot_height; - - - F32 scale_factor = 1.0f ; - - bool is_tiling = false; - - //fbo method no longer supported. Good riddance - /*LLRenderTarget target; - bool use_fbo = false; - static const LLCachedControl force_tile("SHHighResSnapshotForceTile",false);*/ #if 1//SHY_MOD // screenshot improvement F32 internal_scale = llmin(llmax(supersample,1.f),3.f); @@ -4371,86 +4379,79 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei } } - if(!keep_window_aspect) //image cropping - { - F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; - snapshot_width = (S32)(ratio * image_width) ; - snapshot_height = (S32)(ratio * image_height) ; - scale_factor = llmax(1.0f, 1.0f / ratio) ; - } - else //the scene(window) proportion needs to be maintained. + S32 buffer_x_offset = 0; + S32 buffer_y_offset = 0; + F32 scale_factor; + S32 image_buffer_x; + S32 image_buffer_y; + + F32 const window_aspect = (F32)window_width / window_height; + // snapshot fits precisely inside window, it is the portion of the window with the correct aspect. + F32 snapshot_width = (snapshot_aspect > window_aspect) ? (F32)window_width : window_height * snapshot_aspect; + F32 snapshot_height = (snapshot_aspect < window_aspect) ? (F32)window_height : window_width / snapshot_aspect; + // ratio is the ratio snapshot/image', where image' is a rectangle with aspect snapshot_aspect that precisely contains image. + // Thus image_width' / image_height' == aspect ==> snapshot_width / image_width' == snapshot_height / image_height'. + // Since image' precisely contains image, one of them is equal (ie, image_height' = image_height) and the other is larger + // (or equal) (ie, image_width' >= image_width), and therefore one of snapshot_width / image_width and + // snapshot_height / image_height is correct, and the other is larger. Therefore, the smallest value of the + // following equals the ratio we're looking for. + F32 ratio = llmin(snapshot_width / image_width, snapshot_height / image_height); + // buffer equals the largest of image' and snapshot. This is because in the first case we need the higher + // resolution because of the size of the target image, and in the second case there is no reason to go + // smaller because it takes the same amount of time (and a slightly better quality should result after + // the final scaling). Thus, if ratio < 1 then buffer equals image', otherwise it equals snapshot. + // scale_factor is the ratio buffer/snapshot, and is initiallly equal to the ratio between buffer + // and snapshot (which have the same aspect). + for(scale_factor = llmax(1.0f, 1.0f / ratio);; // Initial attempt. + // However, if the buffer turns out to be too large, then clamp it to max_size. + scale_factor = llmin(max_size / snapshot_width, max_size / snapshot_height)) // Clamp { - if(image_width > window_width || image_height > window_height) //need to enlarge the scene + image_buffer_x = llround(snapshot_width * scale_factor); + image_buffer_y = llround(snapshot_height * scale_factor); + if (llmax(image_buffer_x, image_buffer_y) > max_size && // Boundary check to avoid memory overflow. + internal_scale <= 1.f) // SHY_MOD: If supersampling... Don't care about max_size. { - //Unsupported - /*if (!force_tile && gGLManager.mHasFramebufferObject && !show_ui) - { - GLint max_size = 0; - glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size); - - if (image_width <= max_size && image_height <= max_size) //re-project the scene - { - use_fbo = TRUE; - - snapshot_width = image_width; - snapshot_height = image_height; - target.allocate(snapshot_width, snapshot_height, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, TRUE); - window_width = snapshot_width; - window_height = snapshot_height; - scale_factor = 1.f; - mWindowRectRaw.set(0, snapshot_height, snapshot_width, 0); - target.bindTarget(); - } - } - - if(!use_fbo) //no re-projection, so tiling the scene*/ - { - F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; - snapshot_width = (S32)(ratio * image_width) ; - snapshot_height = (S32)(ratio * image_height) ; - scale_factor = llmax(1.0f, 1.0f / ratio) ; - is_tiling = true; - } + // Too big, clamp. + continue; } - //else: keep the current scene scale, re-scale it if necessary after reading out. + // Done. + break; } - - S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f); - S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f); + // Center the buffer. + buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f); + buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f); + Dout(dc::snapshot, "rawRawSnapshot(" << image_width << ", " << image_height << ", " << snapshot_aspect << "): image_buffer_x = " << image_buffer_x << "; image_buffer_y = " << image_buffer_y); - S32 image_buffer_x = llfloor(snapshot_width*scale_factor) ; - S32 image_buffer_y = llfloor(snapshot_height*scale_factor) ; -#if 1//SHY_MOD // screenshot improvement - if(internal_scale <= 1.f) //If supersampling... Don't care about max_size. -#endif //shy_mod - if(image_buffer_x > max_size || image_buffer_y > max_size) //boundary check to avoid memory overflow + bool error = !(image_buffer_x > 0 && image_buffer_y > 0); + if (!error) { - scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ; - image_buffer_x = llfloor(snapshot_width*scale_factor) ; - image_buffer_y = llfloor(snapshot_height *scale_factor) ; + raw->resize(image_buffer_x, image_buffer_y, 3); + error = raw->isBufferInvalid(); } - if (image_buffer_x > 0 && image_buffer_y > 0) + if (error) { - raw->resize(image_buffer_x, image_buffer_y, 3); - } - else - { - return FALSE ; - } - if(raw->isBufferInvalid()) - { - return FALSE ; + if (prev_draw_ui != gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); + } + if (hide_hud) + { + LLPipeline::sShowHUDAttachments = TRUE; + } + setCursor(UI_CURSOR_ARROW); + return false; } - BOOL high_res = scale_factor > 1.f; - if (high_res) + BOOL is_tiling = scale_factor > 1.f; + if (is_tiling) { + Dout(dc::warning, "USING TILING FOR SNAPSHOT!"); send_agent_pause(); if (show_ui || !hide_hud) { - //rescale fonts - initFonts(scale_factor); - LLHUDObject::reshapeAll(); + //rescale fonts + initFonts(scale_factor); + LLHUDObject::reshapeAll(); } } @@ -4463,7 +4464,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y) { - S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height);; + S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height); // handle fractional columns U32 read_height = llmax(0, (window_height - subimage_y_offset) - llmax(0, (window_height * (subimage_y + 1)) - (buffer_y_offset + raw->getHeight()))); @@ -4505,7 +4506,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei // Ping the watchdog thread every 100 lines to keep us alive (arbitrary number, feel free to change) if (out_y % 100 == 0) { - LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot"); + LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawRawSnapshot"); } if (type == SNAPSHOT_TYPE_COLOR) @@ -4548,12 +4549,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei output_buffer_offset_y += subimage_y_offset; } - /*if (use_fbo) - { - mWindowRect = window_rect; - target.flush(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - }*/ gDisplaySwapBuffers = FALSE; gDepthDirty = TRUE; @@ -4568,36 +4563,12 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei LLPipeline::sShowHUDAttachments = TRUE; } - if (high_res && (show_ui || !hide_hud)) + if (is_tiling && (show_ui || !hide_hud)) { initFonts(1.f); LLHUDObject::reshapeAll(); } - // Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding) - // Note: this formula depends on the number of components being 3. Not obvious, but it's correct. - image_width += (image_width * 3) % 4; - - BOOL ret = TRUE ; - // Resize image - if(llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4) - { - ret = raw->scale( image_width, image_height ); - } - else if(image_width != image_buffer_x || image_height != image_buffer_y) - { - ret = raw->scale( image_width, image_height, FALSE ); - } - -#if 1//SHY_MOD // screenshot improvement - if(raw->isBufferInvalid()) //Just checking! - return FALSE; - if(internal_scale != 1.f) //Scale down our render to the desired dimensions. - raw->scale( image_width/internal_scale, image_height/internal_scale ); - if(raw->isBufferInvalid()) //Just checking! - return FALSE; -#endif //shy_mod - setCursor(UI_CURSOR_ARROW); if (do_rebuild) @@ -4610,11 +4581,50 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei gPipeline.resetDrawOrders(); } - if (high_res) + if (is_tiling) { send_agent_resume(); } + return true; +} + +// Same as the above, but does the resizing. +bool LLViewerWindow::rawSnapshot(LLImageRaw *raw, + S32 image_width, S32 image_height, F32 snapshot_aspect, BOOL show_ui, + BOOL do_rebuild, ESnapshotType type, S32 max_size, F32 supersample) +{ + bool ret = rawRawSnapshot(raw, image_width, image_height, snapshot_aspect, show_ui, do_rebuild, type, max_size, supersample); + +#if 1 + + if (ret && !raw->scale(image_width, image_height)) + { + ret = false; // Failure. + } + +#else // This was the old behavior.. but I don't think this is needed here. + + if (ret) + { + // Pad image width such that the line length is a multiple of 4 bytes (for BMP encoding). + int n = 4; + for (int c = raw->getComponents(); c % 2 == 0 && n > 1; c /= 2) { n /= 2; } // n /= gcd(n, components) + image_width += (image_width * (n - 1)) % n; // Now n divides image_width, and thus four divides image_width * components, the line length. + + // Resize image + if (llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4) + { + ret = raw->scale( image_width, image_height ); + } + else if (image_width != image_buffer_x || image_height != image_buffer_y) + { + ret = raw->scale( image_width, image_height, FALSE ); + } + } + +#endif + return ret; } @@ -4879,6 +4889,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) gGLManager.mIsDisabled = FALSE; initGLDefaults(); + gGL.refreshState(); //Singu Note: Call immediately. Cached states may have prevented initGLDefaults from actually applying changes. LLGLState::restoreGL(); gTextureList.restoreGL(); @@ -4899,7 +4910,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) gResizeScreenTexture = TRUE; gWindowResized = TRUE; - if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) + if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance()) { LLVisualParamHint::requestHintUpdates(); } @@ -4974,12 +4985,15 @@ void LLViewerWindow::requestResolutionUpdate(bool fullscreen_checked) BOOL LLViewerWindow::checkSettings() { - if (mStatesDirty) + //Singu Note: Don't do the following. + //setShaders is already called in restoreGL(), and gGL.refreshState() is too as to maintain blend states. + //This maintaining of blend states is needed for LLGLState::checkStates() to not error out. + /*if (mStatesDirty) { gGL.refreshState(); LLViewerShaderMgr::instance()->setShaders(); mStatesDirty = false; - } + }*/ // We want to update the resolution AFTER the states getting refreshed not before. if (mResDirty) @@ -5026,10 +5040,8 @@ BOOL LLViewerWindow::checkSettings() desired_screen_size, gSavedSettings.getBOOL("DisableVerticalSync"), mShowFullscreenProgress); - LLGLState::checkStates(); LLGLState::checkTextureChannels(); - mStatesDirty = true; return TRUE; } } @@ -5038,12 +5050,15 @@ BOOL LLViewerWindow::checkSettings() if(is_fullscreen) { // Changing to windowed mode. + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); changeDisplaySettings(FALSE, LLCoordScreen(gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight")), TRUE, mShowFullscreenProgress); - mStatesDirty = true; + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); return TRUE; } } @@ -5111,24 +5126,33 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, mIgnoreActivate = TRUE; LLCoordScreen old_size; LLCoordScreen old_pos; + LLCoordScreen new_pos; mWindow->getSize(&old_size); BOOL got_position = mWindow->getPosition(&old_pos); - if (!old_fullscreen && fullscreen && got_position) + //Singu Note: ALWAYS Save old values if we can. + if(!old_fullscreen && !mWindow->getMaximized() && got_position) { - // switching from windowed to fullscreen, so save window position + //Always save the current position if we can gSavedSettings.setS32("WindowX", old_pos.mX); gSavedSettings.setS32("WindowY", old_pos.mY); } + + //Singu Note: Try to feed switchcontext a posp pointer right off the bat. Looks less clunky on systems that implemented it. + if (!fullscreen && !mWindow->getMaximized()) + { + new_pos.mX = gSavedSettings.getS32("WindowX"); + new_pos.mY = gSavedSettings.getS32("WindowY"); + } mWindow->setFSAASamples(fsaa); - result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync); + result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync, &new_pos); if (!result_first_try) { // try to switch back mWindow->setFSAASamples(old_fsaa); - result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync); + result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync, &new_pos); if (!result_second_try) { @@ -5181,10 +5205,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, } else { - S32 windowX = gSavedSettings.getS32("WindowX"); - S32 windowY = gSavedSettings.getS32("WindowY"); - - mWindow->setPosition(LLCoordScreen ( windowX, windowY ) ); + mWindow->setPosition(new_pos); } } @@ -5193,6 +5214,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, mWantFullscreen = mWindow->getFullscreen(); mShowFullscreenProgress = FALSE; + //mStatesDirty = true; //Singu Note: No longer needed. State update is now in restoreGL. return success; } diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 30848b386..42c8b4cf2 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -308,17 +308,21 @@ public: enum ESnapshotType { SNAPSHOT_TYPE_COLOR, - SNAPSHOT_TYPE_DEPTH, + SNAPSHOT_TYPE_DEPTH }; 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 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, F32 supersample = 1.f ); + bool rawRawSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, F32 aspect, + BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, + S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE, F32 supersample = 1.f); + bool rawSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, F32 aspect, + BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, + S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE, F32 supersample = 1.f); BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ; BOOL isSnapshotLocSet() const { return ! sSnapshotDir.empty(); } void resetSnapshotLoc() const { sSnapshotDir.clear(); } - void saveImageNumbered(LLPointer image); - void saveImageNumbered_continued1(LLPointer image, std::string const& extension, AIFilePicker* filepicker); - void saveImageNumbered_continued2(LLPointer image, std::string const& extension); + void saveImageNumbered(LLPointer image, int index); + void saveImageNumbered_continued1(LLPointer image, std::string const& extension, AIFilePicker* filepicker, int index); + void saveImageNumbered_continued2(LLPointer image, std::string const& extension, int index); // Reset the directory where snapshots are saved. // Client will open directory picker on next snapshot save. @@ -449,7 +453,7 @@ protected: class LLDebugText* mDebugText; // Internal class for debug text bool mResDirty; - bool mStatesDirty; + //bool mStatesDirty; //Singu Note: No longer needed. State update is now in restoreGL. bool mIsFullscreenChecked; // Did the user check the fullscreen checkbox in the display settings U32 mCurrResolutionIndex; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 6e5a370d3..8954a2da2 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -232,7 +232,7 @@ BOOL LLVLComposition::generateComposition() { if (mDetailTextures[i]->getDiscardLevel() < 0) { - mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail + mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); return FALSE; } @@ -249,7 +249,7 @@ BOOL LLVLComposition::generateComposition() ddiscard++; min_dim /= 2; } - mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail + mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail mDetailTextures[i]->setMinDiscardLevel(ddiscard); return FALSE; } @@ -385,9 +385,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, LLPointer raw = new LLImageRaw(tex_width, tex_height, tex_comps); U8 *rawp = raw->getData(); - F32 tex_width_inv = 1.f/tex_width; - F32 tex_height_inv = 1.f/tex_height; - F32 st_x_stride, st_y_stride; st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width); st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height); @@ -422,11 +419,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, tex1 = tex0 + 1; tex1 = llclamp(tex1, 0, 3); - F32 xy_int_i, xy_int_j; - - xy_int_i = i * tex_width_inv; - xy_int_j = j * tex_height_inv; - st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps; for (U32 k = 0; k < tex_comps; k++) { @@ -472,7 +464,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, for (S32 i = 0; i < 4; i++) { // Un-boost detatil textures (will get re-boosted if rendering in high detail) - mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_NONE); + mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE); mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1); } diff --git a/indra/newview/llvlmanager.cpp b/indra/newview/llvlmanager.cpp index b586ab673..88afc9cc3 100644 --- a/indra/newview/llvlmanager.cpp +++ b/indra/newview/llvlmanager.cpp @@ -44,6 +44,11 @@ LLVLManager gVLManager; +// Extended land layer for Aurora Sim +const char AURORA_LAND_LAYER_CODE = 'M'; +const char AURORA_WIND_LAYER_CODE = '9'; +const char AURORA_CLOUD_LAYER_CODE = ':'; + LLVLManager::~LLVLManager() { S32 i; @@ -56,15 +61,15 @@ LLVLManager::~LLVLManager() void LLVLManager::addLayerData(LLVLData *vl_datap, const S32 mesg_size) { - if (LAND_LAYER_CODE == vl_datap->mType) + if (LAND_LAYER_CODE == vl_datap->mType || AURORA_LAND_LAYER_CODE == vl_datap->mType) { mLandBits += mesg_size * 8; } - else if (WIND_LAYER_CODE == vl_datap->mType) + else if (WIND_LAYER_CODE == vl_datap->mType || AURORA_WIND_LAYER_CODE == vl_datap->mType) { mWindBits += mesg_size * 8; } - else if (CLOUD_LAYER_CODE == vl_datap->mType) + else if (CLOUD_LAYER_CODE == vl_datap->mType || AURORA_CLOUD_LAYER_CODE == vl_datap->mType) { mCloudBits += mesg_size * 8; } @@ -93,12 +98,16 @@ void LLVLManager::unpackData(const S32 num_packets) { datap->mRegionp->getLand().decompressDCTPatch(bit_pack, &goph, FALSE); } - else if (WIND_LAYER_CODE == datap->mType) + else if (AURORA_LAND_LAYER_CODE == datap->mType) + { + datap->mRegionp->getLand().decompressDCTPatch(bit_pack, &goph, TRUE); + } + else if (WIND_LAYER_CODE == datap->mType || AURORA_WIND_LAYER_CODE == datap->mType) { datap->mRegionp->mWind.decompress(bit_pack, &goph); } - else if (CLOUD_LAYER_CODE == datap->mType) + else if (CLOUD_LAYER_CODE == datap->mType || AURORA_CLOUD_LAYER_CODE == datap->mType) { #if ENABLE_CLASSIC_CLOUDS datap->mRegionp->mCloudLayer.decompress(bit_pack, &goph); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 19bd366b4..8108d2bd3 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -51,6 +51,7 @@ #include "llviewercontrol.h" #include "lldrawpoolavatar.h" #include "lldriverparam.h" +#include "llpolyskeletaldistortion.h" #include "lleditingmotion.h" #include "llemote.h" #include "llfirstuse.h" @@ -77,11 +78,11 @@ #include "llselectmgr.h" #include "llsprite.h" #include "lltargetingmotion.h" -#include "lltexlayer.h" #include "lltoolmorph.h" #include "llviewercamera.h" #include "llviewergenericmessage.h" //for Auto Deruth #include "llviewercontrol.h" +#include "llviewertexlayer.h" #include "llviewertexturelist.h" #include "llviewermedia.h" #include "llviewermenu.h" @@ -89,6 +90,7 @@ #include "llviewerparcelmgr.h" #include "llviewershadermgr.h" #include "llviewerstats.h" +#include "llviewerwearable.h" #include "llvoavatarself.h" #include "llvovolume.h" #include "llworld.h" @@ -126,7 +128,7 @@ #include -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines; //----------------------------------------------------------------------------- // Global constants @@ -147,7 +149,6 @@ const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df44 //----------------------------------------------------------------------------- // Constants //----------------------------------------------------------------------------- -const std::string AVATAR_DEFAULT_CHAR = "avatar"; const S32 MIN_PIXEL_AREA_FOR_COMPOSITE = 1024; const F32 SHADOW_OFFSET_AMT = 0.03f; @@ -208,8 +209,6 @@ const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f; const U32 EMERALD_BOOB_SIZE_PARAM = 105; const U32 EMERALD_BOOB_GRAVITY_PARAM = 507; -const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0); - //Singu note: FADE and ALWAYS are swapped around from LL's source to match our preference panel. // Changing the "RenderName" order would cause confusion when 'always' setting suddenly gets // interpreted as 'fade', and vice versa. @@ -220,6 +219,11 @@ enum ERenderName RENDER_NAME_ALWAYS }; + +// Utility func - FIXME move out of avatar. +std::string get_sequential_numbered_file_name(const std::string& prefix, + const std::string& suffix); + //----------------------------------------------------------------------------- // Callback data //----------------------------------------------------------------------------- @@ -240,58 +244,6 @@ struct LLTextureMaskData ** **/ -//------------------------------------------------------------------------ -// LLVOBoneInfo -// Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton. -//------------------------------------------------------------------------ -class LLVOAvatarBoneInfo -{ - friend class LLVOAvatar; - friend class LLVOAvatarSkeletonInfo; -public: - LLVOAvatarBoneInfo() : mIsJoint(FALSE) {} - ~LLVOAvatarBoneInfo() - { - std::for_each(mChildList.begin(), mChildList.end(), DeletePointer()); - } - BOOL parseXml(LLXmlTreeNode* node); - -private: - std::string mName; - BOOL mIsJoint; - LLVector3 mPos; - LLVector3 mRot; - LLVector3 mScale; - LLVector3 mPivot; - typedef std::vector child_list_t; - child_list_t mChildList; -}; - -//------------------------------------------------------------------------ -// LLVOAvatarSkeletonInfo -// Overall avatar skeleton -//------------------------------------------------------------------------ -class LLVOAvatarSkeletonInfo -{ - friend class LLVOAvatar; -public: - LLVOAvatarSkeletonInfo() : - mNumBones(0), mNumCollisionVolumes(0) {} - ~LLVOAvatarSkeletonInfo() - { - std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer()); - } - BOOL parseXml(LLXmlTreeNode* node); - S32 getNumBones() const { return mNumBones; } - S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; } - -private: - S32 mNumBones; - S32 mNumCollisionVolumes; - typedef std::vector bone_info_list_t; - bone_info_list_t mBoneInfoList; -}; - //----------------------------------------------------------------------------- // class LLBodyNoiseMotion //----------------------------------------------------------------------------- @@ -782,7 +734,7 @@ const LLSD SHClientTagMgr::generateClientTag(const LLVOAvatar* pAvatar) const { for(S32 te = TEX_UPPER_SHIRT; te <= TEX_SKIRT; ++te) //Don't iterate past skirt. The sim doesn't even send those TEs (Those TEs assume TEX_HAIR_BAKED's uuid) { - LLWearableType::EType wearable = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)te); + LLWearableType::EType wearable = LLAvatarAppearanceDictionary::getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)te); if( wearable != LLWearableType::WT_INVALID && wearable != LLWearableType::WT_ALPHA && wearable != LLWearableType::WT_TATTOO && @@ -937,11 +889,7 @@ void SHClientTagMgr::clearAvatarTag(const LLVOAvatar* pAvatar) //----------------------------------------------------------------------------- // Static Data //----------------------------------------------------------------------------- -LLXmlTree LLVOAvatar::sXMLTree; -LLXmlTree LLVOAvatar::sSkeletonXMLTree; -LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL; -LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL; -LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL; +LLAvatarAppearanceDictionary *LLVOAvatar::sAvatarDictionary = NULL; S32 LLVOAvatar::sFreezeCounter = 0; U32 LLVOAvatar::sMaxVisible = 50; @@ -999,15 +947,15 @@ static U32 calc_shame(LLVOVolume* volume, std::set &textures); LLVOAvatar::LLVOAvatar(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp) : + LLAvatarAppearance(&gAgentWearables), LLViewerObject(id, pcode, regionp), - mIsDummy(FALSE), mSpecialRenderMode(0), mAttachmentGeometryBytes(0), mAttachmentSurfaceArea(0.f), mTurning(FALSE), - mPelvisToFoot(0.f), + mFreezeTimeLangolier(false), + mFreezeTimeDead(false), mLastSkeletonSerialNum( 0 ), - mHeadOffset(), mIsSitting(FALSE), mTimeVisible(), mTyping(FALSE), @@ -1032,9 +980,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mFirstAppearanceMessageReceived( FALSE ), mCulled( FALSE ), mVisibilityRank(0), - mTexSkinColor( NULL ), - mTexHairColor( NULL ), - mTexEyeColor( NULL ), mNeedsSkin(FALSE), mLastSkinTime(0.f), mUpdatePeriod(1), @@ -1045,8 +990,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mSupportsAlphaLayers(FALSE), mLoadedCallbacksPaused(FALSE), mHasPelvisOffset( FALSE ), - mRenderUnloadedAvatar(LLCachedControl(gSavedSettings, "RenderUnloadedAvatar")), mLastRezzedStatus(-1), + mIsEditingAppearance(FALSE), + mUseLocalAppearance(FALSE), + mUseServerBakes(FALSE), // FIXME DRANO consider using boost::optional, defaulting to unknown. mFirstSetActualBoobGravRan( false ), mSupportsPhysics( false ), // @@ -1054,6 +1001,9 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mCCSChatTextOverride(false) // { + static LLCachedControl const freeze_time("FreezeTime", false); + mFreezeTimeLangolier = freeze_time; + LLMemType mt(LLMemType::MTYPE_AVATAR); //VTResume(); // VTune @@ -1065,28 +1015,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mPelvisp = NULL; - mBakedTextureDatas.resize(BAKED_NUM_INDICES); - for (U32 i = 0; i < mBakedTextureDatas.size(); i++ ) - { - mBakedTextureDatas[i].mLastTextureIndex = IMG_DEFAULT_AVATAR; - mBakedTextureDatas[i].mTexLayerSet = NULL; - mBakedTextureDatas[i].mIsLoaded = false; - mBakedTextureDatas[i].mIsUsed = false; - mBakedTextureDatas[i].mMaskTexName = 0; - mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i); - } - mDirtyMesh = 2; // Dirty geometry, need to regenerate. mMeshTexturesDirty = FALSE; mHeadp = NULL; - mIsBuilt = FALSE; - - mNumJoints = 0; - mSkeleton = NULL; - - mNumCollisionVolumes = 0; - mCollisionVolumes = NULL; // set up animation variables mSpeed = 0.f; @@ -1175,47 +1107,8 @@ LLVOAvatar::~LLVOAvatar() } lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl; - mRoot.removeAllChildren(); - mJointMap.clear(); - - deleteAndClearArray(mSkeleton); - deleteAndClearArray(mCollisionVolumes); - - mNumJoints = 0; - - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - deleteAndClear(mBakedTextureDatas[i].mTexLayerSet); - mBakedTextureDatas[i].mMeshes.clear(); - - for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin(); - iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++) - { - LLMaskedMorph* masked_morph = (*iter2); - delete masked_morph; - } - } - std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer()); mAttachmentPoints.clear(); - - deleteAndClear(mTexSkinColor); - deleteAndClear(mTexHairColor); - deleteAndClear(mTexEyeColor); - - std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer()); - mMeshes.clear(); - - for (std::vector::iterator jointIter = mMeshLOD.begin(); - jointIter != mMeshLOD.end(); - ++jointIter) - { - LLViewerJoint* joint = (LLViewerJoint *) *jointIter; - std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer()); - joint->mMeshParts.clear(); - } - std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer()); - mMeshLOD.clear(); mDead = TRUE; @@ -1229,6 +1122,13 @@ LLVOAvatar::~LLVOAvatar() void LLVOAvatar::markDead() { + static const LLCachedControl freeze_time("FreezeTime", false); + if (freeze_time && !mFreezeTimeLangolier) + { + // Delay the call to this function until FreezeTime is reset, otherwise avatars disappear from the frozen scene. + mFreezeTimeDead = true; + return; + } if (mNameText) { mNameText->markDead(); @@ -1261,7 +1161,7 @@ BOOL LLVOAvatar::isFullyTextured() const { for (U32 i = 0; i < (U32)mMeshLOD.size(); i++) { - LLViewerJoint* joint = (LLViewerJoint*) mMeshLOD[i]; + LLAvatarJoint* joint = mMeshLOD[i]; if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT)) { continue; // don't care about skirt textures if we're not wearing one. @@ -1270,19 +1170,19 @@ BOOL LLVOAvatar::isFullyTextured() const { continue; // nonexistent LOD OK. } - std::vector::iterator meshIter = joint->mMeshParts.begin(); + avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin(); if (meshIter != joint->mMeshParts.end()) { - LLViewerJointMesh *mesh = (LLViewerJointMesh *) *meshIter; + LLAvatarJointMesh *mesh = (*meshIter); if (!mesh) { continue; // nonexistent mesh OK } - if (mesh->mTexture.notNull() && mesh->mTexture->hasGLTexture()) + if (mesh->hasGLTexture()) { continue; // Mesh exists and has a baked texture. } - if (mesh->mLayerSet && mesh->mLayerSet->hasComposite()) + if (mesh->hasComposite()) { continue; // Mesh exists and has a composite texture. } @@ -1377,46 +1277,6 @@ std::string LLVOAvatar::rezStatusToString(S32 rez_status) return "unknown"; } -// static -void LLVOAvatar::getMeshInfo (mesh_info_t* mesh_info) -{ - if (!mesh_info) return; - - LLVOAvatarXmlInfo::mesh_info_list_t::iterator iter = sAvatarXmlInfo->mMeshInfoList.begin(); - LLVOAvatarXmlInfo::mesh_info_list_t::iterator end = sAvatarXmlInfo->mMeshInfoList.end(); - - for (; iter != end; ++iter) - { - LLVOAvatarXmlInfo::LLVOAvatarMeshInfo* avatar_info = (*iter); - std::string type = avatar_info->mType; - S32 lod = avatar_info->mLOD; - std::string file = avatar_info->mMeshFileName; - - mesh_info_t::iterator iter_info = mesh_info->find(type); - if(iter_info == mesh_info->end()) - { - lod_mesh_map_t lod_mesh; - lod_mesh.insert(std::pair(lod, file)); - mesh_info->insert(std::pair(type, lod_mesh)); - } - else - { - lod_mesh_map_t& lod_mesh = iter_info->second; - lod_mesh_map_t::iterator iter_lod = lod_mesh.find(lod); - if (iter_lod == lod_mesh.end()) - { - lod_mesh.insert(std::pair(lod, file)); - } - else - { - // Should never happen - llwarns << "Duplicate mesh LOD " << type << " " << lod << " " << file << llendl; - } - } - } - return; -} - // static void LLVOAvatar::dumpBakedStatus() { @@ -1475,15 +1335,15 @@ void LLVOAvatar::dumpBakedStatus() { llcont << " Unbaked ("; - for (LLVOAvatarDictionary::BakedTextures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end(); ++iter) { - const LLVOAvatarDictionary::BakedEntry *baked_dict = iter->second; + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = iter->second; const ETextureIndex index = baked_dict->mTextureIndex; if (!inst->isTextureDefined(index)) { - llcont << " " << LLVOAvatarDictionary::getInstance()->getTexture(index)->mName; + llcont << " " << LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mName; } } llcont << " ) " << inst->getUnbakedPixelAreaRank(); @@ -1504,7 +1364,7 @@ void LLVOAvatar::restoreGL() gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); for (U32 i = 0; i < gAgentAvatarp->mBakedTextureDatas.size(); i++) { - gAgentAvatarp->invalidateComposite(gAgentAvatarp->mBakedTextureDatas[i].mTexLayerSet, FALSE); + gAgentAvatarp->invalidateComposite(gAgentAvatarp->getTexLayerSet(i), FALSE); } gAgentAvatarp->updateMeshTextures(); } @@ -1531,7 +1391,7 @@ void LLVOAvatar::resetImpostors() // static void LLVOAvatar::deleteCachedImages(bool clearAll) { - if (LLTexLayerSet::sHasCaches) + if (LLViewerTexLayerSet::sHasCaches) { lldebugs << "Deleting layer set caches" << llendl; for (std::vector::iterator iter = LLCharacter::sInstances.begin(); @@ -1540,7 +1400,7 @@ void LLVOAvatar::deleteCachedImages(bool clearAll) LLVOAvatar* inst = (LLVOAvatar*) *iter; inst->deleteLayerSetCaches(clearAll); } - LLTexLayerSet::sHasCaches = FALSE; + LLViewerTexLayerSet::sHasCaches = FALSE; } LLVOAvatarSelf::deleteScratchTextures(); LLTexLayerStaticImageList::getInstance()->deleteCachedImages(); @@ -1553,108 +1413,17 @@ void LLVOAvatar::deleteCachedImages(bool clearAll) //------------------------------------------------------------------------ void LLVOAvatar::initClass() { - std::string xmlFile; - - xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml"; - BOOL success = sXMLTree.parseFile( xmlFile, FALSE ); - if (!success) - { - llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl; - } - - // now sanity check xml file - LLXmlTreeNode* root = sXMLTree.getRoot(); - if (!root) - { - llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl; - return; - } - - //------------------------------------------------------------------------- - // (root) - //------------------------------------------------------------------------- - if( !root->hasName( "linden_avatar" ) ) - { - llerrs << "Invalid avatar file header: " << xmlFile << llendl; - } - - std::string version; - static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); - if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) - { - llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl; - } - - S32 wearable_def_version = 1; - static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version"); - root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version ); - LLWearable::setCurrentDefinitionVersion( wearable_def_version ); - - std::string mesh_file_name; - - LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" ); - if (!skeleton_node) - { - llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl; - 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)) - { - llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl; - } - - std::string skeleton_path; - skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name); - if (!parseSkeletonFile(skeleton_path)) - { - llerrs << "Error parsing skeleton file: " << skeleton_path << llendl; - } - - // Process XML data - - // avatar_skeleton.xml - if (sAvatarSkeletonInfo) - { //this can happen if a login attempt failed - delete sAvatarSkeletonInfo; - } - sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo; - if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot())) - { - llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl; - } - // parse avatar_lad.xml - if (sAvatarXmlInfo) - { //this can happen if a login attempt failed - deleteAndClear(sAvatarXmlInfo); - } - sAvatarXmlInfo = new LLVOAvatarXmlInfo; - if (!sAvatarXmlInfo->parseXmlSkeletonNode(root)) - { - llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; - } - if (!sAvatarXmlInfo->parseXmlMeshNodes(root)) - { - llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; - } - if (!sAvatarXmlInfo->parseXmlColorNodes(root)) - { - llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; - } - if (!sAvatarXmlInfo->parseXmlLayerNodes(root)) - { - llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; - } - if (!sAvatarXmlInfo->parseXmlDriverNodes(root)) - { - llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; - } - if (!sAvatarXmlInfo->parseXmlMorphNodes(root)) - { - llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; - } + gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise"); + gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot"); + gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion"); + gAnimLibrary.animStateSetString(ANIM_AGENT_EDITING,"editing"); + gAnimLibrary.animStateSetString(ANIM_AGENT_EYE,"eye"); + gAnimLibrary.animStateSetString(ANIM_AGENT_FLY_ADJUST,"fly_adjust"); + gAnimLibrary.animStateSetString(ANIM_AGENT_HAND_MOTION,"hand_motion"); + gAnimLibrary.animStateSetString(ANIM_AGENT_HEAD_ROT,"head_rot"); + gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX,"pelvis_fix"); + gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET,"target"); + gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST,"walk_adjust"); SHClientTagMgr::instance(); //Instantiate. Parse. Will fetch a new tag file if AscentUpdateTagsOnLoad is true. } @@ -1662,85 +1431,11 @@ void LLVOAvatar::initClass() void LLVOAvatar::cleanupClass() { - deleteAndClear(sAvatarXmlInfo); - deleteAndClear(sAvatarSkeletonInfo); - sSkeletonXMLTree.cleanup(); - sXMLTree.cleanup(); } +// virtual void LLVOAvatar::initInstance(void) { - //------------------------------------------------------------------------- - // initialize joint, mesh and shape members - //------------------------------------------------------------------------- - mRoot.setName( "mRoot" ); - - for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin(); - iter != LLVOAvatarDictionary::getInstance()->getMeshes().end(); - ++iter) - { - const EMeshIndex mesh_index = iter->first; - const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second; - LLViewerJoint* joint = new LLViewerJoint(); - joint->setName(mesh_dict->mName); - joint->setMeshID(mesh_index); - mMeshLOD.push_back(joint); - - /* mHairLOD.setName("mHairLOD"); - mHairMesh0.setName("mHairMesh0"); - mHairMesh0.setMeshID(MESH_ID_HAIR); - mHairMesh1.setName("mHairMesh1"); */ - for (U32 lod = 0; lod < mesh_dict->mLOD; lod++) - { - LLViewerJointMesh* mesh = new LLViewerJointMesh(); - std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast(lod); - // We pre-pended an m - need to capitalize first character for camelCase - mesh_name[1] = toupper(mesh_name[1]); - mesh->setName(mesh_name); - mesh->setMeshID(mesh_index); - mesh->setPickName(mesh_dict->mPickName); - mesh->setIsTransparent(FALSE); - switch((int)mesh_index) - { - case MESH_ID_HAIR: - mesh->setIsTransparent(TRUE); - break; - case MESH_ID_SKIRT: - mesh->setIsTransparent(TRUE); - break; - case MESH_ID_EYEBALL_LEFT: - case MESH_ID_EYEBALL_RIGHT: - mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); - break; - } - - joint->mMeshParts.push_back(mesh); - } - } - - //------------------------------------------------------------------------- - // associate baked textures with meshes - //------------------------------------------------------------------------- - for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin(); - iter != LLVOAvatarDictionary::getInstance()->getMeshes().end(); - ++iter) - { - const EMeshIndex mesh_index = iter->first; - const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second; - const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID; - // Skip it if there's no associated baked texture. - if (baked_texture_index == BAKED_NUM_INDICES) continue; - - for (std::vector::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin(); - iter != mMeshLOD[mesh_index]->mMeshParts.end(); - ++iter) - { - LLViewerJointMesh* mesh = (LLViewerJointMesh*) *iter; - mBakedTextureDatas[(int)baked_texture_index].mMeshes.push_back(mesh); - } - } - - //------------------------------------------------------------------------- // register motions //------------------------------------------------------------------------- @@ -1801,6 +1496,8 @@ void LLVOAvatar::initInstance(void) } + LLAvatarAppearance::initInstance(); + // grab the boob savedparams (prob a better place for this) sBoobConfig.mass = EmeraldBoobUtils::convertMass(gSavedSettings.getF32("EmeraldBoobMass")); sBoobConfig.hardness = EmeraldBoobUtils::convertHardness(gSavedSettings.getF32("EmeraldBoobHardness")); @@ -1814,7 +1511,6 @@ void LLVOAvatar::initInstance(void) { return; } - buildCharacter(); // preload specific motions here createMotion( ANIM_AGENT_CUSTOMIZE); @@ -1825,6 +1521,30 @@ void LLVOAvatar::initInstance(void) mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) ); } +// virtual +LLAvatarJoint* LLVOAvatar::createAvatarJoint() +{ + return new LLViewerJoint(); +} + +// virtual +LLAvatarJoint* LLVOAvatar::createAvatarJoint(S32 joint_num) +{ + return new LLViewerJoint(joint_num); +} + +// virtual +LLAvatarJointMesh* LLVOAvatar::createAvatarJointMesh() +{ + return new LLViewerJointMesh(); +} + +// virtual +LLTexLayerSet* LLVOAvatar::createTexLayerSet() +{ + return new LLViewerTexLayerSet(this); +} + const LLVector3 LLVOAvatar::getRenderPosition() const { if (mDrawable.isNull() || mDrawable->getGeneration() < 0) @@ -1861,8 +1581,6 @@ void LLVOAvatar::onShift(const LLVector4a& shift_vector) const LLVector3& shift = reinterpret_cast(shift_vector); mLastAnimExtents[0] += shift; mLastAnimExtents[1] += shift; - mNeedsImpostorUpdate = TRUE; - mNeedsAnimUpdate = TRUE; } void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) @@ -1899,7 +1617,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) float max_attachment_span = DEFAULT_MAX_PRIM_SCALE * 5.0f; //stretch bounding box by joint positions - for (polymesh_map_t::iterator i = mMeshes.begin(); i != mMeshes.end(); ++i) + for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) { LLPolyMesh* mesh = i->second; for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++) @@ -2138,163 +1856,6 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector return hit; } -//----------------------------------------------------------------------------- -// parseSkeletonFile() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename) -{ - LLMemType mt(LLMemType::MTYPE_AVATAR); - - //------------------------------------------------------------------------- - // parse the file - //------------------------------------------------------------------------- - BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE ); - - if (!parsesuccess) - { - llerrs << "Can't parse skeleton file: " << filename << llendl; - return FALSE; - } - - // now sanity check xml file - LLXmlTreeNode* root = sSkeletonXMLTree.getRoot(); - if (!root) - { - llerrs << "No root node found in avatar skeleton file: " << filename << llendl; - return FALSE; - } - - if( !root->hasName( "linden_skeleton" ) ) - { - llerrs << "Invalid avatar skeleton file header: " << filename << llendl; - return FALSE; - } - - std::string version; - static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); - if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) - { - llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl; - return FALSE; - } - - return TRUE; -} - -//----------------------------------------------------------------------------- -// setupBone() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num) -{ - LLMemType mt(LLMemType::MTYPE_AVATAR); - - LLViewerJoint* joint = NULL; - - if (info->mIsJoint) - { - joint = (LLViewerJoint*)getCharacterJoint(joint_num); - if (!joint) - { - llwarns << "Too many bones" << llendl; - return FALSE; - } - joint->setName( info->mName ); - } - else // collision volume - { - if (volume_num >= (S32)mNumCollisionVolumes) - { - llwarns << "Too many bones" << llendl; - return FALSE; - } - joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]); - joint->setName( info->mName ); - } - - // add to parent - if (parent) - { - parent->addChild( joint ); - } - - joint->setPosition(info->mPos); - joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY], - info->mRot.mV[VZ], LLQuaternion::XYZ)); - joint->setScale(info->mScale); - - joint->setDefaultFromCurrentXform(); - - if (info->mIsJoint) - { - joint->setSkinOffset( info->mPivot ); - joint_num++; - } - else // collision volume - { - volume_num++; - } - - // setup children - LLVOAvatarBoneInfo::child_list_t::const_iterator iter; - for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter) - { - LLVOAvatarBoneInfo *child_info = *iter; - if (!setupBone(child_info, joint, volume_num, joint_num)) - { - return FALSE; - } - } - - return TRUE; -} - -//----------------------------------------------------------------------------- -// buildSkeleton() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info) -{ - LLMemType mt(LLMemType::MTYPE_AVATAR); - - - if (!info) - return FALSE; - //------------------------------------------------------------------------- - // allocate joints - //------------------------------------------------------------------------- - if (!allocateCharacterJoints(info->mNumBones)) - { - llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl; - return FALSE; - } - - //------------------------------------------------------------------------- - // allocate volumes - //------------------------------------------------------------------------- - if (info->mNumCollisionVolumes) - { - if (!allocateCollisionVolumes(info->mNumCollisionVolumes)) - { - llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl; - return FALSE; - } - } - - S32 current_joint_num = 0; - S32 current_volume_num = 0; - LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter; - for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter) - { - LLVOAvatarBoneInfo *info = *iter; - if (!setupBone(info, NULL, current_volume_num, current_joint_num)) - { - llerrs << "Error parsing bone in skeleton file" << llendl; - return FALSE; - } - } - - return TRUE; -} - LLVOAvatar* LLVOAvatar::asAvatar() { return this; @@ -2326,121 +1887,14 @@ void LLVOAvatar::startDefaultMotions() // LLVOAvatar::buildCharacter() // Deferred initialization and rebuild of the avatar. //----------------------------------------------------------------------------- +// virtual void LLVOAvatar::buildCharacter() { - LLMemType mt(LLMemType::MTYPE_AVATAR); - - //------------------------------------------------------------------------- - // remove all references to our existing skeleton - // so we can rebuild it - //------------------------------------------------------------------------- - flushAllMotions(); + LLAvatarAppearance::buildCharacter(); - //------------------------------------------------------------------------- - // remove all of mRoot's children - //------------------------------------------------------------------------- - mRoot.removeAllChildren(); - mJointMap.clear(); + // Not done building yet; more to do. mIsBuilt = FALSE; - //------------------------------------------------------------------------- - // clear mesh data - //------------------------------------------------------------------------- - for (std::vector::iterator jointIter = mMeshLOD.begin(); - jointIter != mMeshLOD.end(); ++jointIter) - { - LLViewerJoint* joint = (LLViewerJoint*) *jointIter; - for (std::vector::iterator meshIter = joint->mMeshParts.begin(); - meshIter != joint->mMeshParts.end(); ++meshIter) - { - LLViewerJointMesh * mesh = (LLViewerJointMesh *) *meshIter; - mesh->setMesh(NULL); - } - } - - //------------------------------------------------------------------------- - // (re)load our skeleton and meshes - //------------------------------------------------------------------------- - LLTimer timer; - - BOOL status = loadAvatar(); - stop_glerror(); - - if (gNoRender) - { - // Still want to load the avatar skeleton so visual parameters work. - return; - } - -// gPrintMessagesThisFrame = TRUE; - lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl; - - if (!status) - { - if (isSelf()) - { - llerrs << "Unable to load user's avatar" << llendl; - } - else - { - llwarns << "Unable to load other's avatar" << llendl; - } - return; - } - - //------------------------------------------------------------------------- - // initialize "well known" joint pointers - //------------------------------------------------------------------------- - mPelvisp = (LLViewerJoint*)mRoot.findJoint("mPelvis"); - mTorsop = (LLViewerJoint*)mRoot.findJoint("mTorso"); - mChestp = (LLViewerJoint*)mRoot.findJoint("mChest"); - mNeckp = (LLViewerJoint*)mRoot.findJoint("mNeck"); - mHeadp = (LLViewerJoint*)mRoot.findJoint("mHead"); - mSkullp = (LLViewerJoint*)mRoot.findJoint("mSkull"); - mHipLeftp = (LLViewerJoint*)mRoot.findJoint("mHipLeft"); - mHipRightp = (LLViewerJoint*)mRoot.findJoint("mHipRight"); - mKneeLeftp = (LLViewerJoint*)mRoot.findJoint("mKneeLeft"); - mKneeRightp = (LLViewerJoint*)mRoot.findJoint("mKneeRight"); - mAnkleLeftp = (LLViewerJoint*)mRoot.findJoint("mAnkleLeft"); - mAnkleRightp = (LLViewerJoint*)mRoot.findJoint("mAnkleRight"); - mFootLeftp = (LLViewerJoint*)mRoot.findJoint("mFootLeft"); - mFootRightp = (LLViewerJoint*)mRoot.findJoint("mFootRight"); - mWristLeftp = (LLViewerJoint*)mRoot.findJoint("mWristLeft"); - mWristRightp = (LLViewerJoint*)mRoot.findJoint("mWristRight"); - mEyeLeftp = (LLViewerJoint*)mRoot.findJoint("mEyeLeft"); - mEyeRightp = (LLViewerJoint*)mRoot.findJoint("mEyeRight"); - - //------------------------------------------------------------------------- - // Make sure "well known" pointers exist - //------------------------------------------------------------------------- - if (!(mPelvisp && - mTorsop && - mChestp && - mNeckp && - mHeadp && - mSkullp && - mHipLeftp && - mHipRightp && - mKneeLeftp && - mKneeRightp && - mAnkleLeftp && - mAnkleRightp && - mFootLeftp && - mFootRightp && - mWristLeftp && - mWristRightp && - mEyeLeftp && - mEyeRightp)) - { - llerrs << "Failed to create avatar." << llendl; - return; - } - - //------------------------------------------------------------------------- - // initialize the pelvis - //------------------------------------------------------------------------- - mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) ); - //------------------------------------------------------------------------- // set head offset from pelvis //------------------------------------------------------------------------- @@ -2495,11 +1949,11 @@ void LLVOAvatar::releaseMeshData() //llinfos << "Releasing" << llendl; // cleanup mesh data - for (std::vector::iterator iter = mMeshLOD.begin(); + for (avatar_joint_list_t::iterator iter = mMeshLOD.begin(); iter != mMeshLOD.end(); ++iter) { - LLViewerJoint* joint = (LLViewerJoint*) *iter; + LLAvatarJoint* joint = (*iter); joint->setValid(FALSE, TRUE); } @@ -2589,7 +2043,11 @@ void LLVOAvatar::updateMeshData() last_v_num = num_vertices ; last_i_num = num_indices ; - mMeshLOD[part_index++]->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); + LLViewerJoint* part_mesh = getViewerJoint(part_index++); + if (part_mesh) + { + part_mesh->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); + } } if(num_vertices < 1)//skip empty meshes { @@ -2663,7 +2121,11 @@ void LLVOAvatar::updateMeshData() rigid = true; } - mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid); + LLViewerJoint* mesh = getViewerJoint(k); + if (mesh) + { + mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid); + } } stop_glerror(); @@ -2683,83 +2145,16 @@ void LLVOAvatar::updateMeshData() //------------------------------------------------------------------------ -//------------------------------------------------------------------------ -// The viewer can only suggest a good size for the agent, -// the simulator will keep it inside a reasonable range. -void LLVOAvatar::computeBodySize() -{ - LLVector3 pelvis_scale = mPelvisp->getScale(); - - // some of the joints have not been cached - LLVector3 skull = mSkullp->getPosition(); - LLVector3 skull_scale = mSkullp->getScale(); - - LLVector3 neck = mNeckp->getPosition(); - LLVector3 neck_scale = mNeckp->getScale(); - - LLVector3 chest = mChestp->getPosition(); - LLVector3 chest_scale = mChestp->getScale(); - - // the rest of the joints have been cached - LLVector3 head = mHeadp->getPosition(); - LLVector3 head_scale = mHeadp->getScale(); - - LLVector3 torso = mTorsop->getPosition(); - LLVector3 torso_scale = mTorsop->getScale(); - - LLVector3 hip = mHipLeftp->getPosition(); - LLVector3 hip_scale = mHipLeftp->getScale(); - - LLVector3 knee = mKneeLeftp->getPosition(); - LLVector3 knee_scale = mKneeLeftp->getScale(); - - LLVector3 ankle = mAnkleLeftp->getPosition(); - LLVector3 ankle_scale = mAnkleLeftp->getScale(); - - LLVector3 foot = mFootLeftp->getPosition(); - - mPelvisToFoot = 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]; - - LLVector3 new_body_size; - new_body_size.mV[VZ] = mPelvisToFoot + - // 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; - - if (new_body_size != mBodySize) - { - mBodySize = new_body_size; - - if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF()) - { // notify simulator of change in size - // but not if we are in the middle of updating appearance - gAgent.sendAgentSetAppearance(); - } - } -} - //------------------------------------------------------------------------ // LLVOAvatar::processUpdateMessage() //------------------------------------------------------------------------ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, - void **user_data, - U32 block_num, const EObjectUpdateType update_type, + void **user_data, + U32 block_num, const EObjectUpdateType update_type, LLDataPacker *dp) { LLMemType mt(LLMemType::MTYPE_AVATAR); - LLVector3 old_vel = getVelocity(); const BOOL has_name = !getNVPair("FirstName"); // Do base class updates... @@ -2781,28 +2176,6 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, } } - //llinfos << getRotation() << llendl; - //llinfos << getPosition() << llendl; - // - if (update_type == OUT_FULL ) - { - - if(isSelf()) - { - if(gSavedSettings.getBOOL("ReSit")) - { - gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_TargetObject); - gMessageSystem->addUUIDFast(_PREHASH_TargetID, gReSitTargetID); - gMessageSystem->addVector3Fast(_PREHASH_Offset, gReSitOffset); - gAgent.getRegion()->sendReliableMessage(); - } - } - } - // return retval; } @@ -2813,6 +2186,13 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) // to redirect certain avatar texture requests to different sims. if (isIndexBakedTexture((ETextureIndex)te)) { + const std::string url = getImageURL(te,uuid); + if (!url.empty()) + { + llinfos << "texture URL " << url << llendl; + return setTETextureCore(te, uuid, url); + } + LLHost target_host = getObjectHost(); return setTETextureCore(te, uuid, target_host); } @@ -2822,7 +2202,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) } } -static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Update Avatar"); +static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Avatar Update"); static LLFastTimer::DeclareTimer FTM_JOINT_UPDATE("Update Joints"); //------------------------------------------------------------------------ @@ -2855,7 +2235,7 @@ void LLVOAvatar::dumpAnimationState() //------------------------------------------------------------------------ // idleUpdate() //------------------------------------------------------------------------ -BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { LLMemType mt(LLMemType::MTYPE_AVATAR); LLFastTimer t(FTM_AVATAR_UPDATE); @@ -2863,12 +2243,12 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) if (isDead()) { llinfos << "Warning! Idle on dead avatar" << llendl; - return TRUE; - } + return; + } if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) { - return TRUE; + return; } checkTextureLoading() ; @@ -2931,13 +2311,13 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) // animate the character // store off last frame's root position to be consistent with camera position - LLVector3 root_pos_last = mRoot.getWorldPosition(); + LLVector3 root_pos_last = mRoot->getWorldPosition(); bool detailed_update = updateCharacter(agent); bool voice_enabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel(); if (gNoRender) { - return TRUE; + return; } idleUpdateVoiceVisualizer( voice_enabled ); @@ -2954,8 +2334,6 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) idleUpdateNameTag( root_pos_last ); idleUpdateRenderCost(); - - return TRUE; } void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) @@ -3056,11 +2434,11 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) if ( mIsSitting ) { LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] ); - mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset ); + mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot->getWorldPosition() + headOffset ); } else { - LLVector3 tagPos = mRoot.getWorldPosition(); + LLVector3 tagPos = mRoot->getWorldPosition(); tagPos[VZ] -= mPelvisToFoot; tagPos[VZ] += ( mBodySize[VZ] + 0.125f ); mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos ); @@ -3135,7 +2513,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (isImpostor() && !mNeedsImpostorUpdate) { - LLVector4a ext[2]; + LL_ALIGN_16(LLVector4a ext[2]); F32 distance; LLVector3 angle; @@ -3394,7 +2772,10 @@ void LLVOAvatar::idleUpdateLoadingEffect() LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK | LLPartData::LL_PART_TARGET_POS_MASK ); - setParticleSource(particle_parameters, getID()); + if (!isTooComplex()) // do not generate particles for overly-complex avatars + { + setParticleSource(particle_parameters, getID()); + } } } } @@ -3666,6 +3047,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) } bool is_friend = LLAvatarTracker::instance().isBuddy(getID()); bool is_cloud = getIsCloud(); + bool is_langolier = isLangolier(); if (is_appearance != mNameAppearance) { @@ -3691,7 +3073,8 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) || is_muted != mNameMute || is_appearance != mNameAppearance || is_friend != mNameFriend - || is_cloud != mNameCloud) + || is_cloud != mNameCloud + || is_langolier != mNameLangolier) { LLColor4 name_tag_color = getNameTagColor(is_friend); @@ -3701,7 +3084,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) std::string firstnameText; std::string lastnameText; - if (is_away || is_muted || is_busy || is_appearance || !idle_string.empty()) + if (is_away || is_muted || is_busy || is_appearance || is_langolier || !idle_string.empty()) { std::string line; if (is_away) @@ -3724,7 +3107,12 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) line += LLTrans::getString("AvatarEditingAppearance"); //"(Editing Appearance)" line += ", "; } - if (is_cloud) + if (is_langolier) + { + line += LLTrans::getString("AvatarLangolier"); //"Langolier" + line += ", "; + } + else if (is_cloud) { line += LLTrans::getString("LoadingData"); //"Loading..." line += ", "; @@ -3755,8 +3143,8 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - bool show_display_names = phoenix_name_system > 0; - bool show_usernames = phoenix_name_system < 2; + bool show_display_names = phoenix_name_system == 1 || phoenix_name_system == 2; + bool show_usernames = phoenix_name_system != 2; if (show_display_names && LLAvatarNameCache::useDisplayNames()) { LLAvatarName av_name; @@ -3851,6 +3239,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) mNameAppearance = is_appearance; mNameFriend = is_friend; mNameCloud = is_cloud; + mNameLangolier = is_langolier; mTitle = title ? title->getString() : ""; LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); new_name = TRUE; @@ -3990,7 +3379,7 @@ void LLVOAvatar::invalidateNameTags() // Compute name tag position during idle update LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) { - LLQuaternion root_rot = mRoot.getWorldRotation(); + LLQuaternion root_rot = mRoot->getWorldRotation(); LLVector3 pixel_right_vec; LLVector3 pixel_up_vec; LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec); @@ -4004,7 +3393,7 @@ LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) local_camera_up.scaleVec(mBodySize * 0.5f); local_camera_at.scaleVec(mBodySize * 0.5f); - LLVector3 name_position = mRoot.getWorldPosition(); + LLVector3 name_position = mRoot->getWorldPosition(); name_position[VZ] -= mPelvisToFoot; name_position[VZ] += (mBodySize[VZ]* 0.55f); name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av)); @@ -4071,13 +3460,13 @@ void LLVOAvatar::idleUpdateBelowWater() void LLVOAvatar::slamPosition() { gAgent.setPositionAgent(getPositionAgent()); - mRoot.setWorldPosition(getPositionAgent()); // teleport + mRoot->setWorldPosition(getPositionAgent()); // teleport setChanged(TRANSLATED); if (mDrawable.notNull()) { gPipeline.updateMoveNormalAsync(mDrawable); } - mRoot.updateWorldMatrixChildren(); + mRoot->updateWorldMatrixChildren(); } bool LLVOAvatar::isVisuallyMuted() const @@ -4088,7 +3477,18 @@ bool LLVOAvatar::isVisuallyMuted() const return LLMuteList::getInstance()->isMuted(getID()) || (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) || - (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f); + (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f) || + isLangolier(); +} + +void LLVOAvatar::resetFreezeTime() +{ + bool dead = mFreezeTimeDead; + mFreezeTimeLangolier = mFreezeTimeDead = false; + if (dead) + { + markDead(); + } } //------------------------------------------------------------------------ @@ -4099,8 +3499,33 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) { LLMemType mt(LLMemType::MTYPE_AVATAR); + // Frozen! + if (areAnimationsPaused()) + { + updateMotions(LLCharacter::NORMAL_UPDATE); // This is necessary to get unpaused again. + return FALSE; + } + // clear debug text mDebugText.clear(); + + if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) + { + S32 central_bake_version = -1; + if (getRegion()) + { + central_bake_version = getRegion()->getCentralBakeVersion(); + } + addDebugText(llformat("mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d", + mUseLocalAppearance, mIsEditingAppearance, + mUseServerBakes, central_bake_version)); + } + if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) + { + if (!mBakedTextureDebugText.empty()) + addDebugText(mBakedTextureDebugText); + } + if (LLVOAvatar::sShowAnimationDebug) { for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); @@ -4249,8 +3674,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) xyVel.mV[VZ] = 0.0f; speed = xyVel.length(); - BOOL throttle = TRUE; - if (!(mIsSitting && getParent())) { //-------------------------------------------------------------------- @@ -4261,11 +3684,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) if (mTimeLast == 0.0f) { mTimeLast = animation_time; - throttle = FALSE; // put the pelvis at slaved position/mRotation - mRoot.setWorldPosition( getPositionAgent() ); // first frame - mRoot.setWorldRotation( getRotation() ); + mRoot->setWorldPosition( getPositionAgent() ); // first frame + mRoot->setWorldRotation( getRotation() ); } //-------------------------------------------------------------------- @@ -4308,10 +3730,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos); - if (newPosition != mRoot.getXform()->getWorldPosition()) + if (newPosition != mRoot->getXform()->getWorldPosition()) { - mRoot.touch(); - mRoot.setWorldPosition(newPosition ); // regular update + mRoot->touch(); + mRoot->setWorldPosition(newPosition ); // regular update } @@ -4339,7 +3761,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } LLVector3 velDir = getVelocity(); velDir.normalize(); - if ( mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end()) + static LLCachedControl TurnAround("TurnAroundWhenWalkingBackwards"); + if (!TurnAround && (mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end())) { F32 vpD = velDir * primDir; if (vpD < -0.5f) @@ -4372,7 +3795,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } - LLQuaternion root_rotation = mRoot.getWorldMatrix().quaternion(); + LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion(); F32 root_roll, root_pitch, root_yaw; root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw); @@ -4389,8 +3812,12 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) // and head turn. Once in motion, it must conform however. BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook(); - LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV ); - F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, PELVIS_ROT_THRESHOLD_SLOW, PELVIS_ROT_THRESHOLD_FAST); + LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV ); + + static const LLCachedControl s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow"); + static const LLCachedControl s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast"); + + F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast); if (self_in_mouselook) { @@ -4471,14 +3898,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) F32 u = llclamp((deltaTime / pelvis_lag_time), 0.0f, 1.0f); - mRoot.setWorldRotation( slerp(u, mRoot.getWorldRotation(), wQv) ); + mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) ); } } else if (mDrawable.notNull()) { - mRoot.setPosition(mDrawable->getPosition()); - mRoot.setRotation(mDrawable->getRotation()); + mRoot->setPosition(mDrawable->getPosition()); + mRoot->setRotation(mDrawable->getRotation()); } //------------------------------------------------------------------------- @@ -4578,7 +4005,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } } - mRoot.updateWorldMatrixChildren(); + mRoot->updateWorldMatrixChildren(); if (!mDebugText.size() && mText.notNull()) { @@ -4595,7 +4022,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) return TRUE; } - //----------------------------------------------------------------------------- // updateHeadOffset() //----------------------------------------------------------------------------- @@ -4603,7 +4029,7 @@ void LLVOAvatar::updateHeadOffset() { // since we only care about Z, just grab one of the eyes LLVector3 midEyePt = mEyeLeftp->getWorldPosition(); - midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot.getWorldPosition(); + midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition(); midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]); if (mDrawable.notNull()) @@ -4641,8 +4067,8 @@ void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount, void LLVOAvatar::postPelvisSetRecalc( void ) { computeBodySize(); - mRoot.touch(); - mRoot.updateWorldMatrixChildren(); + mRoot->touch(); + mRoot->updateWorldMatrixChildren(); dirtyMesh(); updateHeadOffset(); } @@ -4836,19 +4262,44 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) if (mNeedsSkin) { //generate animated mesh - mMeshLOD[MESH_ID_LOWER_BODY]->updateJointGeometry(); - mMeshLOD[MESH_ID_UPPER_BODY]->updateJointGeometry(); + LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); + LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); + LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT); + LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH); + LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); + LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); + + if(upper_mesh) + { + upper_mesh->updateJointGeometry(); + } + if (lower_mesh) + { + lower_mesh->updateJointGeometry(); + } if( isWearingWearableType( LLWearableType::WT_SKIRT ) ) { - mMeshLOD[MESH_ID_SKIRT]->updateJointGeometry(); + if(skirt_mesh) + { + skirt_mesh->updateJointGeometry(); + } } if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) { - mMeshLOD[MESH_ID_EYELASH]->updateJointGeometry(); - mMeshLOD[MESH_ID_HEAD]->updateJointGeometry(); - mMeshLOD[MESH_ID_HAIR]->updateJointGeometry(); + if(eyelash_mesh) + { + eyelash_mesh->updateJointGeometry(); + } + if(head_mesh) + { + head_mesh->updateJointGeometry(); + } + if(hair_mesh) + { + hair_mesh->updateJointGeometry(); + } } mNeedsSkin = FALSE; mLastSkinTime = gFrameTimeSeconds; @@ -4965,19 +4416,31 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) { if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy) { - num_indices += mMeshLOD[MESH_ID_HEAD]->render(mAdjustedPixelArea, TRUE, mIsDummy || is_muted); + LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); + if (head_mesh) + { + num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy); + } first_pass = FALSE; } } if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy) { - num_indices += mMeshLOD[MESH_ID_UPPER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy || is_muted); + LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); + if (upper_mesh) + { + num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } first_pass = FALSE; } if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy) { - num_indices += mMeshLOD[MESH_ID_LOWER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy || is_muted); + LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); + if (lower_mesh) + { + num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } first_pass = FALSE; } } @@ -5010,7 +4473,11 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (mIsDummy || isTextureVisible(TEX_SKIRT_BAKED)) ) { gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f); - num_indices += mMeshLOD[MESH_ID_SKIRT]->render(mAdjustedPixelArea, FALSE); + LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT); + if (skirt_mesh) + { + num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE); + } first_pass = FALSE; gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } @@ -5024,14 +4491,23 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) if (isTextureVisible(TEX_HEAD_BAKED)) { - num_indices += mMeshLOD[MESH_ID_EYELASH]->render(mAdjustedPixelArea, first_pass, mIsDummy); + LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH); + if (eyelash_mesh) + { + num_indices += eyelash_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } first_pass = FALSE; } // Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair) // TODO: 1.25 will be able to switch this logic back to calling isTextureVisible(); - if (getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha) + if ( getImage(TEX_HAIR_BAKED, 0) && + getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha) { - num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass, mIsDummy); + LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); + if (hair_mesh) + { + num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } first_pass = FALSE; } if (LLPipeline::sImpostorRender) @@ -5073,10 +4549,18 @@ U32 LLVOAvatar::renderRigid() gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); } - if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy) + if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy) { - num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea, TRUE, mIsDummy); - num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy); + LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT); + LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT); + if (eyeball_left) + { + num_indices += eyeball_left->render(mAdjustedPixelArea, TRUE, mIsDummy); + } + if(eyeball_right) + { + num_indices += eyeball_right->render(mAdjustedPixelArea, TRUE, mIsDummy); + } } if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) @@ -5242,17 +4726,30 @@ void LLVOAvatar::updateTextures() mHasGrey = FALSE; // debug for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) { - LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture_index); + LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index); U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); const LLTextureEntry *te = getTE(texture_index); - const F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + + // getTE can return 0. + // Not sure yet why it does, but of course it crashes when te->mScale? gets used. + // Put safeguard in place so this corner case get better handling and does not result in a crash. + F32 texel_area_ratio = 1.0f; + if( te ) + { + texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + } + else + { + llwarns << "getTE( " << texture_index << " ) returned 0" <getTexture((ETextureIndex)texture_index); + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index); const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; if (texture_dict->mIsLocalTexture) { @@ -5268,6 +4765,7 @@ void LLVOAvatar::updateTextures() if (isIndexBakedTexture((ETextureIndex)texture_index) && imagep->getID() != IMG_DEFAULT_AVATAR && imagep->getID() != IMG_INVISIBLE + && !isUsingServerBakes() && !imagep->getTargetHost().isOk()) { LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture " @@ -5362,7 +4860,10 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel //the texture pipeline will stop fetching this texture. imagep->resetTextureStats(); - imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures. + // TODO: currently default to HTTP texture and fall back to UDP if cannot be found there. + // Once server messaging is in place, we should call setCanUseHTTP(false) for old style + // appearance requests + imagep->setCanUseHTTP(true); imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); imagep->resetMaxVirtualSizeResetCounter() ; @@ -5370,8 +4871,8 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel mMinPixelArea = llmin(pixel_area, mMinPixelArea); imagep->addTextureStats(pixel_area / texel_area_ratio); imagep->setBoostLevel(boost_level); - - if(boost_level != LLViewerTexture::BOOST_AVATAR_BAKED_SELF) + + if(boost_level != LLGLTexture::BOOST_AVATAR_BAKED_SELF) { imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ; } @@ -5404,6 +4905,28 @@ void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te) setTE(index, te); } +const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid) +{ + std::string url = ""; + if (isUsingServerBakes()) + { + if (gSavedSettings.getString("AgentAppearanceServiceURL").empty()) + { + // Probably a server-side issue if we get here: + llwarns << "AgentAppearanceServiceURL not set - Baked texture requests will fail" << llendl; + return url; + } + + const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te); + if (texture_entry != NULL) + { + url = gSavedSettings.getString("AgentAppearanceServiceURL") + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString(); + //llinfos << "baked texture url: " << url << llendl; + } + } + return url; +} + //----------------------------------------------------------------------------- // resolveHeight() //----------------------------------------------------------------------------- @@ -5596,7 +5119,9 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL if ( start ) // start animation { - if (anim_id == ANIM_AGENT_TYPE && gSavedSettings.getBOOL("PlayTypingSound")) + static LLCachedControl play_typing_sound("PlayTypingSound"); + static LLCachedControl announce_snapshots("AnnounceSnapshots"); + if (anim_id == ANIM_AGENT_TYPE && play_typing_sound) { if (gAudiop) { @@ -5622,6 +5147,17 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL { sitDown(TRUE); } + else if(anim_id == ANIM_AGENT_SNAPSHOT && announce_snapshots) + { + std::string name; + LLAvatarNameCache::getPNSName(mID, name); + LLChat chat; + chat.mFromName = name; + chat.mText = name + " " + LLTrans::getString("took_a_snapshot") + "."; + chat.mURL = llformat("secondlife:///app/agent/%s/about",mID.asString().c_str()); + chat.mSourceType = CHAT_SOURCE_SYSTEM; + LLFloaterChat::addChat(chat); + } if (startMotion(anim_id)) @@ -5815,56 +5351,6 @@ void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id) { } -//----------------------------------------------------------------------------- -// getVolumePos() -//----------------------------------------------------------------------------- -LLVector3 LLVOAvatar::getVolumePos(S32 joint_index, LLVector3& volume_offset) -{ - if(joint_index < 0) - { - return LLVector3::zero; - } - - if (joint_index > mNumCollisionVolumes) - { - return LLVector3::zero; - } - - return mCollisionVolumes[joint_index].getVolumePos(volume_offset); -} - -//----------------------------------------------------------------------------- -// findCollisionVolume() -//----------------------------------------------------------------------------- -LLJoint* LLVOAvatar::findCollisionVolume(U32 volume_id) -{ - //SNOW-488: As mNumCollisionVolumes is a S32 and we are casting from a U32 to a S32 - //to compare we also need to be sure of the wrap around case producing (S32) <0 - //or in terms of the U32 an out of bounds index in the array. - if ((S32)volume_id > mNumCollisionVolumes || (S32)volume_id<0) - { - return NULL; - } - - return &mCollisionVolumes[volume_id]; -} - -//----------------------------------------------------------------------------- -// findCollisionVolume() -//----------------------------------------------------------------------------- -S32 LLVOAvatar::getCollisionVolumeID(std::string &name) -{ - for (S32 i = 0; i < mNumCollisionVolumes; i++) - { - if (mCollisionVolumes[i].getName() == name) - { - return i; - } - } - - return -1; -} - //----------------------------------------------------------------------------- // addDebugText() //----------------------------------------------------------------------------- @@ -5894,7 +5380,7 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) if (iter == mJointMap.end() || iter->second == NULL) { //search for joint and cache found joint in lookup table - jointp = mRoot.findJoint(name); + jointp = mRoot->findJoint(name); mJointMap[name] = jointp; } else @@ -5905,25 +5391,12 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) return jointp; } -//----------------------------------------------------------------------------- -// resetJointPositions -//----------------------------------------------------------------------------- -void LLVOAvatar::resetJointPositions( void ) -{ - for(S32 i = 0; i < (S32)mNumJoints; ++i) - { - mSkeleton[i].restoreOldXform(); - mSkeleton[i].setId( LLUUID::null ); - } - mHasPelvisOffset = false; - mPelvisFixup = mLastPelvisFixup; -} //----------------------------------------------------------------------------- // resetSpecificJointPosition //----------------------------------------------------------------------------- void LLVOAvatar::resetSpecificJointPosition( const std::string& name ) { - LLJoint* pJoint = mRoot.findJoint( name ); + LLJoint* pJoint = mRoot->findJoint( name ); if ( pJoint && pJoint->doesJointNeedToBeReset() ) { @@ -5945,16 +5418,17 @@ void LLVOAvatar::resetSpecificJointPosition( const std::string& name ) //----------------------------------------------------------------------------- void LLVOAvatar::resetJointPositionsToDefault( void ) { - //Subsequent joints are relative to pelvis - for( S32 i = 0; i < (S32)mNumJoints; ++i ) + avatar_joint_list_t::iterator iter = mSkeleton.begin(); + avatar_joint_list_t::iterator end = mSkeleton.end(); + for (; iter != end; ++iter) { - LLJoint* pJoint = (LLJoint*)&mSkeleton[i]; + LLJoint* pJoint = (*iter); if ( pJoint->doesJointNeedToBeReset() ) { - pJoint->setId( LLUUID::null ); //restore joints to default positions, however skip over the pelvis + // *TODO: How does this pointer check skip over pelvis? if ( pJoint ) { pJoint->restoreOldXform(); @@ -6053,23 +5527,6 @@ F32 LLVOAvatar::getPixelArea() const } -//----------------------------------------------------------------------------- -// LLVOAvatar::getHeadMesh() -//----------------------------------------------------------------------------- -LLPolyMesh* LLVOAvatar::getHeadMesh() -{ - return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh(); -} - - -//----------------------------------------------------------------------------- -// LLVOAvatar::getUpperBodyMesh() -//----------------------------------------------------------------------------- -LLPolyMesh* LLVOAvatar::getUpperBodyMesh() -{ - return mMeshLOD[MESH_ID_UPPER_BODY]->mMeshParts[0]->getMesh(); -} - //----------------------------------------------------------------------------- // LLVOAvatar::getPosGlobalFromAgent() @@ -6087,61 +5544,6 @@ LLVector3 LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position) return gAgent.getPosAgentFromGlobal(position); } -//----------------------------------------------------------------------------- -// allocateCharacterJoints() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::allocateCharacterJoints( U32 num ) -{ - deleteAndClearArray(mSkeleton); - mNumJoints = 0; - - mSkeleton = new LLViewerJoint[num]; - - for(S32 joint_num = 0; joint_num < (S32)num; joint_num++) - { - mSkeleton[joint_num].setJointNum(joint_num); - } - - if (!mSkeleton) - { - return FALSE; - } - - mNumJoints = num; - return TRUE; -} - -//----------------------------------------------------------------------------- -// allocateCollisionVolumes() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::allocateCollisionVolumes( U32 num ) -{ - deleteAndClearArray(mCollisionVolumes); - mNumCollisionVolumes = 0; - - mCollisionVolumes = new LLViewerJointCollisionVolume[num]; - if (!mCollisionVolumes) - { - return FALSE; - } - - mNumCollisionVolumes = num; - return TRUE; -} - - -//----------------------------------------------------------------------------- -// getCharacterJoint() -//----------------------------------------------------------------------------- -LLJoint *LLVOAvatar::getCharacterJoint( U32 num ) -{ - if ((S32)num >= mNumJoints - || (S32)num < 0) - { - return NULL; - } - return (LLJoint*)&mSkeleton[num]; -} //----------------------------------------------------------------------------- // requestStopMotion() @@ -6152,216 +5554,25 @@ void LLVOAvatar::requestStopMotion( LLMotion* motion ) // Only agent avatars should handle the stop motion notifications. } -//----------------------------------------------------------------------------- -// loadAvatar() -//----------------------------------------------------------------------------- -static LLFastTimer::DeclareTimer FTM_LOAD_AVATAR("Load Avatar"); - -BOOL LLVOAvatar::loadAvatar() -{ -// LLFastTimer t(FTM_LOAD_AVATAR); - - // avatar_skeleton.xml - if( !buildSkeleton(sAvatarSkeletonInfo) ) - { - llwarns << "avatar file: buildSkeleton() failed" << llendl; - return FALSE; - } - - // avatar_lad.xml : - if( !loadSkeletonNode() ) - { - llwarns << "avatar file: loadNodeSkeleton() failed" << llendl; - return FALSE; - } - - // avatar_lad.xml : - if( !loadMeshNodes() ) - { - llwarns << "avatar file: loadNodeMesh() failed" << llendl; - return FALSE; - } - - // avatar_lad.xml : - if( sAvatarXmlInfo->mTexSkinColorInfo ) - { - mTexSkinColor = new LLTexGlobalColor( this ); - if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) ) - { - llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl; - return FALSE; - } - } - else - { - llwarns << " name=\"skin_color\" not found" << llendl; - return FALSE; - } - if( sAvatarXmlInfo->mTexHairColorInfo ) - { - mTexHairColor = new LLTexGlobalColor( this ); - if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) ) - { - llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl; - return FALSE; - } - } - else - { - llwarns << " name=\"hair_color\" not found" << llendl; - return FALSE; - } - if( sAvatarXmlInfo->mTexEyeColorInfo ) - { - mTexEyeColor = new LLTexGlobalColor( this ); - if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) ) - { - llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl; - return FALSE; - } - } - else - { - llwarns << " name=\"eye_color\" not found" << llendl; - return FALSE; - } - - // avatar_lad.xml : - if (sAvatarXmlInfo->mLayerInfoList.empty()) - { - llwarns << "avatar file: missing node" << llendl; - return FALSE; - } - - if (sAvatarXmlInfo->mMorphMaskInfoList.empty()) - { - llwarns << "avatar file: missing node" << llendl; - return FALSE; - } - - // avatar_lad.xml : - for (LLVOAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin(); - iter != sAvatarXmlInfo->mMorphMaskInfoList.end(); - ++iter) - { - LLVOAvatarXmlInfo::LLVOAvatarMorphInfo *info = *iter; - - EBakedTextureIndex baked = LLVOAvatarDictionary::findBakedByRegionName(info->mRegion); - if (baked != BAKED_NUM_INDICES) - { - LLPolyMorphTarget *morph_param; - const std::string *name = &info->mName; - morph_param = (LLPolyMorphTarget *)(getVisualParam(name->c_str())); - if (morph_param) - { - BOOL invert = info->mInvert; - addMaskedMorph(baked, morph_param, invert, info->mLayer); - } - } - - } - - loadLayersets(); - - // avatar_lad.xml : - for (LLVOAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin(); - iter != sAvatarXmlInfo->mDriverInfoList.end(); - ++iter) - { - LLDriverParamInfo *info = *iter; - LLDriverParam* driver_param = new LLDriverParam( this ); - if (driver_param->setInfo(info)) - { - addVisualParam( driver_param ); - LLVisualParam*(LLVOAvatar::*avatar_function)(S32)const = &LLVOAvatar::getVisualParam; - if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLVOAvatar*)this,_1 ), false)) - { - llwarns << "could not link driven params for avatar " << this->getFullname() << " id: " << driver_param->getID() << llendl; - continue; - } - } - else - { - delete driver_param; - llwarns << "avatar file: driver_param->parseData() failed" << llendl; - return FALSE; - } - } - - - return TRUE; -} - //----------------------------------------------------------------------------- // loadSkeletonNode(): loads node from XML tree //----------------------------------------------------------------------------- +//virtual BOOL LLVOAvatar::loadSkeletonNode () { - mRoot.addChild( &mSkeleton[0] ); - - for (std::vector::iterator iter = mMeshLOD.begin(); - iter != mMeshLOD.end(); - ++iter) + if (!LLAvatarAppearance::loadSkeletonNode()) { - LLViewerJoint *joint = (LLViewerJoint *) *iter; - joint->mUpdateXform = FALSE; - joint->setMeshesToChildren(); + return FALSE; } - mRoot.addChild(mMeshLOD[MESH_ID_HEAD]); - mRoot.addChild(mMeshLOD[MESH_ID_EYELASH]); - mRoot.addChild(mMeshLOD[MESH_ID_UPPER_BODY]); - mRoot.addChild(mMeshLOD[MESH_ID_LOWER_BODY]); - mRoot.addChild(mMeshLOD[MESH_ID_SKIRT]); - mRoot.addChild(mMeshLOD[MESH_ID_HEAD]); - - LLViewerJoint *skull = (LLViewerJoint*)mRoot.findJoint("mSkull"); - if (skull) - { - skull->addChild(mMeshLOD[MESH_ID_HAIR] ); - } - - LLViewerJoint *eyeL = (LLViewerJoint*)mRoot.findJoint("mEyeLeft"); - if (eyeL) - { - eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] ); - } - - LLViewerJoint *eyeR = (LLViewerJoint*)mRoot.findJoint("mEyeRight"); - if (eyeR) - { - eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] ); - } - - // SKELETAL DISTORTIONS - { - LLVOAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter; - for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin(); - iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); - ++iter) - { - LLPolySkeletalDistortionInfo *info = *iter; - LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this); - if (!param->setInfo(info)) - { - delete param; - return FALSE; - } - else - { - addVisualParam(param); - } - } - } - // ATTACHMENTS { - LLVOAvatarXmlInfo::attachment_info_list_t::iterator iter; + LLAvatarXmlInfo::attachment_info_list_t::iterator iter; for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin(); iter != sAvatarXmlInfo->mAttachmentInfoList.end(); ++iter) { - LLVOAvatarXmlInfo::LLVOAvatarAttachmentInfo *info = *iter; + LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter; if (!isSelf() && info->mJointName == "mScreen") { //don't process screen joint for other avatars continue; @@ -6433,144 +5644,6 @@ BOOL LLVOAvatar::loadSkeletonNode () return TRUE; } -//----------------------------------------------------------------------------- -// loadMeshNodes(): loads nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::loadMeshNodes() -{ - for (LLVOAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin(); - meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end(); - ++meshinfo_iter) - { - const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo *info = *meshinfo_iter; - const std::string &type = info->mType; - S32 lod = info->mLOD; - - LLViewerJointMesh* mesh = NULL; - U8 mesh_id = 0; - BOOL found_mesh_id = FALSE; - - /* if (type == "hairMesh") - switch(lod) - case 0: - mesh = &mHairMesh0; */ - for (LLVOAvatarDictionary::Meshes::const_iterator mesh_iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin(); - mesh_iter != LLVOAvatarDictionary::getInstance()->getMeshes().end(); - ++mesh_iter) - { - const EMeshIndex mesh_index = mesh_iter->first; - const LLVOAvatarDictionary::MeshEntry *mesh_dict = mesh_iter->second; - if (type.compare(mesh_dict->mName) == 0) - { - mesh_id = mesh_index; - found_mesh_id = TRUE; - break; - } - } - - if (found_mesh_id) - { - if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size()) - { - mesh = mMeshLOD[mesh_id]->mMeshParts[lod]; - } - else - { - llwarns << "Avatar file: has invalid lod setting " << lod << llendl; - return FALSE; - } - } - else - { - llwarns << "Ignoring unrecognized mesh type: " << type << llendl; - return FALSE; - } - - // llinfos << "Parsing mesh data for " << type << "..." << llendl; - - // If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings. - // Do not touch!!! - mesh->setColor( 1.0f, 1.0f, 1.0f, 1.0f ); - - LLPolyMesh *poly_mesh = NULL; - - if (!info->mReferenceMeshName.empty()) - { - polymesh_map_t::const_iterator polymesh_iter = mMeshes.find(info->mReferenceMeshName); - if (polymesh_iter != mMeshes.end()) - { - poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second); - poly_mesh->setAvatar(this); - } - else - { - // This should never happen - LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL; - } - } - else - { - poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName); - poly_mesh->setAvatar(this); - } - - if( !poly_mesh ) - { - llwarns << "Failed to load mesh of type " << type << llendl; - return FALSE; - } - - // Multimap insert - mMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh)); - - mesh->setMesh( poly_mesh ); - mesh->setLOD( info->mMinPixelArea ); - - for (LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin(); - xmlinfo_iter != info->mPolyMorphTargetInfoList.end(); - ++xmlinfo_iter) - { - const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter); - LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh()); - if (!param->setInfo(info_pair->first)) - { - delete param; - return FALSE; - } - else - { - if (info_pair->second) - { - addSharedVisualParam(param); - } - else - { - addVisualParam(param); - } - } - } - } - - return TRUE; -} - -//----------------------------------------------------------------------------- -// loadLayerSets() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::loadLayersets() -{ - BOOL success = TRUE; - for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin(); - layerset_iter != sAvatarXmlInfo->mLayerInfoList.end(); - ++layerset_iter) - { - // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such. - LLTexLayerSetInfo *layerset_info = *layerset_iter; - layerset_info->createVisualParams(this); - } - return success; -} - //----------------------------------------------------------------------------- // updateVisualParams() //----------------------------------------------------------------------------- @@ -6589,7 +5662,7 @@ void LLVOAvatar::updateVisualParams() { computeBodySize(); mLastSkeletonSerialNum = mSkeletonSerialNum; - mRoot.updateWorldMatrixChildren(); + mRoot->updateWorldMatrixChildren(); } dirtyMesh(); @@ -6679,7 +5752,12 @@ BOOL LLVOAvatar::updateJointLODs() } // now select meshes to render based on adjusted pixel area - BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE); + LLViewerJoint* root = dynamic_cast(mRoot); + BOOL res = FALSE; + if (root) + { + res = root->updateLOD(mAdjustedPixelArea, TRUE); + } if (res) { sNumLODChangesThisFrame++; @@ -6769,6 +5847,15 @@ void LLVOAvatar::dirtyMesh(S32 priority) { mDirtyMesh = llmax(mDirtyMesh, priority); } + +//----------------------------------------------------------------------------- +// getViewerJoint() +//----------------------------------------------------------------------------- +LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx) +{ + return dynamic_cast(mMeshLOD[idx]); +} + //----------------------------------------------------------------------------- // hideSkirt() //----------------------------------------------------------------------------- @@ -6777,22 +5864,6 @@ void LLVOAvatar::hideSkirt() mMeshLOD[MESH_ID_SKIRT]->setVisible(FALSE, TRUE); } -//----------------------------------------------------------------------------- -// getMesh( LLPolyMeshSharedData *shared_data ) -//----------------------------------------------------------------------------- -LLPolyMesh* LLVOAvatar::getMesh( LLPolyMeshSharedData *shared_data ) -{ - for (polymesh_map_t::iterator i = mMeshes.begin(); i != mMeshes.end(); ++i) - { - LLPolyMesh* mesh = i->second; - if (mesh->getSharedData() == shared_data) - { - return mesh; - } - } - return NULL; -} - BOOL LLVOAvatar::setParent(LLViewerObject* parent) { BOOL ret ; @@ -7200,9 +6271,9 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) // Notice that removing sitDown() from here causes avatars sitting on // objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655. sitDown(TRUE); - mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject - mRoot.setPosition(getPosition()); - mRoot.updateWorldMatrixChildren(); + mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject + mRoot->setPosition(getPosition()); + mRoot->updateWorldMatrixChildren(); stopMotion(ANIM_AGENT_BODY_NOISE); @@ -7248,10 +6319,10 @@ void LLVOAvatar::getOffObject() sitDown(FALSE); - mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject - mRoot.setPosition(cur_position_world); - mRoot.setRotation(cur_rotation_world); - mRoot.getXform()->update(); + mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject + mRoot->setPosition(cur_position_world); + mRoot->setRotation(cur_rotation_world); + mRoot->getXform()->update(); startMotion(ANIM_AGENT_BODY_NOISE); @@ -7315,6 +6386,52 @@ S32 LLVOAvatar::getAttachmentCount() return count; } +BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const +{ + if (mIsDummy) return TRUE; + + if (isSelf()) + { + return LLAvatarAppearance::isWearingWearableType(type); + } + + switch(type) + { + case LLWearableType::WT_SHAPE: + case LLWearableType::WT_SKIN: + case LLWearableType::WT_HAIR: + case LLWearableType::WT_EYES: + return TRUE; // everyone has all bodyparts + default: + break; // Do nothing + } + + /* switch(type) + case LLWearableType::WT_SHIRT: + indicator_te = TEX_UPPER_SHIRT; */ + for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); + ++tex_iter) + { + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second; + if (texture_dict->mWearableType == type) + { + // If you're checking another avatar's clothing, you don't have component textures. + // Thus, you must check to see if the corresponding baked texture is defined. + // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing + // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that + // gets baked into a texture that always exists (upper or lower). + if (texture_dict->mIsUsedByBakedTexture) + { + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex); + } + return FALSE; + } + } + return FALSE; +} + //----------------------------------------------------------------------------- // isWearingAttachment() //----------------------------------------------------------------------------- @@ -7383,40 +6500,6 @@ const std::string LLVOAvatar::getAttachedPointName(const LLUUID& inv_item_id) return LLStringUtil::null; } - - - - - - - - - - - - -LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const -{ - if (color_name=="skin_color" && mTexSkinColor) - { - return mTexSkinColor->getColor(); - } - else if(color_name=="hair_color" && mTexHairColor) - { - return mTexHairColor->getColor(); - } - if(color_name=="eye_color" && mTexEyeColor) - { - return mTexEyeColor->getColor(); - } - else - { -// return LLColor4( .5f, .5f, .5f, .5f ); - return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color - } -} - - void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result ) { } @@ -7425,6 +6508,7 @@ void LLVOAvatar::invalidateAll() { } +// virtual void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake ) { if (global_color == mTexSkinColor) @@ -7443,9 +6527,15 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL if (!isTextureDefined(mBakedTextureDatas[BAKED_HAIR].mTextureIndex)) { LLColor4 color = mTexHairColor->getColor(); - for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++) + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end(); + for (; iter != end; ++iter) { - mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setColor( color ); + } } } } @@ -7479,10 +6569,10 @@ BOOL LLVOAvatar::getIsCloud() const return TRUE; } - /*if (isTooComplex()) + if (isTooComplex()) { return TRUE; - }*/ + } return FALSE; } @@ -7598,15 +6688,28 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) BOOL LLVOAvatar::isFullyLoaded() const { + static LLCachedControl const render_unloaded_avatar("RenderUnloadedAvatar", false); + // [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a // Changes to LLAppearanceMgr::updateAppearanceFromCOF() expect this function to actually return mFullyLoaded for gAgentAvatarp - if ( (!isSelf()) && (mRenderUnloadedAvatar) ) + if ( (!isSelf()) && render_unloaded_avatar ) return TRUE; else return mFullyLoaded; // [/SL:KB] } +bool LLVOAvatar::isTooComplex() const +{ + static const LLCachedControl render_avatar_complexity_limit("RenderAvatarComplexityLimit",0); + if (render_avatar_complexity_limit > 0 && mVisualComplexity >= render_avatar_complexity_limit) + { + return true; + } + + return false; +} + //----------------------------------------------------------------------------- // findMotion() @@ -7616,12 +6719,32 @@ LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const return mMotionController.findMotion(id); } +void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color) +{ + if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) + { + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); + for (; iter != end; ++iter) + { + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + { + mesh->setColor(color); + } + } + } + } +} //----------------------------------------------------------------------------- // updateMeshTextures() // Uses the current TE values to set the meshes' and layersets' textures. //----------------------------------------------------------------------------- +// virtual void LLVOAvatar::updateMeshTextures() { + mBakedTextureDebugText.clear(); // llinfos << "updateMeshTextures" << llendl; if (gNoRender) return; // if user has never specified a texture, assign the default @@ -7630,18 +6753,19 @@ void LLVOAvatar::updateMeshTextures() const LLViewerTexture* te_image = getImage(i, 0); if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT)) { - setImage(i, LLViewerTextureManager::getFetchedTexture(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR), 0); // IMG_DEFAULT_AVATAR = a special texture that's never rendered. + // IMG_DEFAULT_AVATAR = a special texture that's never rendered. + const LLUUID& image_id = (i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR); + setImage(i, LLViewerTextureManager::getFetchedTexture(image_id), 0); } } - const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures const BOOL other_culled = !isSelf() && mCulled; LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ; BOOL paused = FALSE; if(!isSelf()) { src_callback_list = &mCallbackTextureList ; - paused = mLoadedCallbacksPaused ; + paused = !isVisible(); } std::vector is_layer_baked; @@ -7650,71 +6774,117 @@ void LLVOAvatar::updateMeshTextures() std::vector use_lkg_baked_layer; // lkg = "last known good" use_lkg_baked_layer.resize(mBakedTextureDatas.size(), false); + mBakedTextureDebugText += "indx layerset linvld ltda ilb ulkg ltid\n"; for (U32 i=0; i < mBakedTextureDatas.size(); i++) { is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex); - + LLViewerTexLayerSet* layerset = NULL; + bool layerset_invalid = false; if (!other_culled) { // When an avatar is changing clothes and not in Appearance mode, - // use the last-known good baked texture until it finish the first + // use the last-known good baked texture until it finishes the first // render of the new layerset. - const BOOL layerset_invalid = mBakedTextureDatas[i].mTexLayerSet - && ( !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized() - || !mBakedTextureDatas[i].mTexLayerSet->isLocalTextureDataAvailable() ); + layerset = getTexLayerSet(i); + layerset_invalid = layerset && ( !layerset->getViewerComposite()->isInitialized() + || !layerset->isLocalTextureDataAvailable() ); use_lkg_baked_layer[i] = (!is_layer_baked[i] - && (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) + && (mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR) && layerset_invalid); if (use_lkg_baked_layer[i]) { - mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE); + layerset->setUpdatesEnabled(TRUE); } } else { use_lkg_baked_layer[i] = (!is_layer_baked[i] - && mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR); - if (mBakedTextureDatas[i].mTexLayerSet) - { - mBakedTextureDatas[i].mTexLayerSet->destroyComposite(); - } + && mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR); } + std::string last_id_string; + if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT_AVATAR) + last_id_string = "A"; + else if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT) + last_id_string = "D"; + else + last_id_string = "*"; + bool is_ltda = layerset + && layerset->getViewerComposite()->isInitialized() + && layerset->isLocalTextureDataAvailable(); + mBakedTextureDebugText += llformat("%4d %4s %4d %4d %4d %4d %4s\n", + i, + (layerset?"*":"0"), + layerset_invalid, + is_ltda, + is_layer_baked[i], + use_lkg_baked_layer[i], + last_id_string.c_str()); } - // Turn on alpha masking correctly for yourself and other avatars on 1.23+ mSupportsAlphaLayers = isSelf() || is_layer_baked[BAKED_HAIR]; - // Baked textures should be requested from the sim this avatar is on. JC - const LLHost target_host = getObjectHost(); - if (!target_host.isOk()) - { - llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl; - } - for (U32 i=0; i < mBakedTextureDatas.size(); i++) { - if (use_lkg_baked_layer[i] && !self_customizing ) + debugColorizeSubMeshes(i, LLColor4::white); + + LLViewerTexLayerSet* layerset = getTexLayerSet(i); + if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() ) { - LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host ); - mBakedTextureDatas[i].mIsUsed = TRUE; - for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++) + LLViewerFetchedTexture* baked_img; +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLViewerFetchedTexture* existing_baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID); +#endif + const std::string url = getImageURL(i, mBakedTextureDatas[i].mLastTextureID); + if (!url.empty()) { - mBakedTextureDatas[i].mMeshes[k]->setTexture( baked_img ); + baked_img = LLViewerTextureManager::getFetchedTextureFromUrl(url, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, mBakedTextureDatas[i].mLastTextureID); + } + else + { + // Baked textures should be requested from the sim this avatar is on. JC + const LLHost target_host = getObjectHost(); + if (!target_host.isOk()) + { + llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl; + } + + baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureID, target_host ); + } + llassert(baked_img == existing_baked_img); + + mBakedTextureDatas[i].mIsUsed = TRUE; + + debugColorizeSubMeshes(i,LLColor4::red); + + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); + for (; iter != end; ++iter) + { + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setTexture( baked_img ); + } } } - else if (!self_customizing && is_layer_baked[i]) + else if (!isUsingLocalAppearance() && is_layer_baked[i]) { - LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ; - if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureIndex ) + LLViewerFetchedTexture* baked_img = + LLViewerTextureManager::staticCastToFetchedTexture( + getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ; + if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureID ) { - // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). + // Even though the file may not be finished loading, + // we'll consider it loaded and use it (rather than + // doing compositing). useBakedTexture( baked_img->getID() ); } else { mBakedTextureDatas[i].mIsLoaded = FALSE; - if ( (baked_img->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) ) + if ( (baked_img->getID() != IMG_INVISIBLE) && + ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) ) { baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ), src_callback_list, paused); @@ -7723,40 +6893,59 @@ void LLVOAvatar::updateMeshTextures() src_callback_list, paused ); } } - else if (mBakedTextureDatas[i].mTexLayerSet - && !other_culled) + else if (layerset && isUsingLocalAppearance()) { - mBakedTextureDatas[i].mTexLayerSet->createComposite(); - mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( TRUE ); + debugColorizeSubMeshes(i,LLColor4::yellow ); + + layerset->createComposite(); + layerset->setUpdatesEnabled( TRUE ); mBakedTextureDatas[i].mIsUsed = FALSE; - for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++) + + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); + for (; iter != end; ++iter) { - mBakedTextureDatas[i].mMeshes[k]->setLayerSet( mBakedTextureDatas[i].mTexLayerSet ); + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setLayerSet( layerset ); + } } } + else + { + debugColorizeSubMeshes(i,LLColor4::blue); + } } // set texture and color of hair manually if we are not using a baked image. // This can happen while loading hair for yourself, or for clients that did not // bake a hair texture. Still needed for yourself after 1.22 is depricated. - if (!is_layer_baked[BAKED_HAIR] || self_customizing) + if (!is_layer_baked[BAKED_HAIR] || isEditingAppearance()) { const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1); LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 ); - for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++) + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end(); + for (; iter != end; ++iter) { - mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); - mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setTexture( hair_img ); + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setColor( color ); + mesh->setTexture( hair_img ); + } } } - for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = + LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin(); + baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end(); ++baked_iter) { const EBakedTextureIndex baked_index = baked_iter->first; - const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); local_tex_iter != baked_dict->mLocalTextures.end(); @@ -7784,7 +6973,7 @@ void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, B } //virtual -void LLVOAvatar::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index) +void LLVOAvatar::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index) { // invalid for anyone but self llassert(0); @@ -7835,18 +7024,30 @@ void LLVOAvatar::clearChat() mChats.clear(); } -// adds a morph mask to the appropriate baked texture structure -void LLVOAvatar::addMaskedMorph(EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer) + +void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index) { - if (index < BAKED_NUM_INDICES) + if (index >= BAKED_NUM_INDICES) { - LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer); - mBakedTextureDatas[index].mMaskedMorphs.push_front(morph); + llwarns << "invalid baked texture index passed to applyMorphMask" << llendl; + return; + } + + for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin(); + iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter) + { + const LLMaskedMorph* maskedMorph = (*iter); + LLPolyMorphTarget* morph_target = dynamic_cast(maskedMorph->mMorphTarget); + if (morph_target) + { + morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert); + } } } + // returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise -BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index) +BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index) { if (index >= BAKED_NUM_INDICES) { @@ -7857,7 +7058,7 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex inde { if (isSelf()) { - LLTexLayerSet *layer_set = mBakedTextureDatas[index].mTexLayerSet; + LLViewerTexLayerSet *layer_set = getTexLayerSet(index); if (layer_set) { return !layer_set->isMorphValid(); @@ -7872,23 +7073,6 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex inde return FALSE; } -void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index) -{ - if (index >= BAKED_NUM_INDICES) - { - llwarns << "invalid baked texture index passed to applyMorphMask" << llendl; - return; - } - - for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin(); - iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter) - { - const LLMaskedMorph* maskedMorph = (*iter); - maskedMorph->mMorphTarget->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert); - } -} - - //----------------------------------------------------------------------------- // releaseComponentTextures() // release any component texture UUIDs for which we have a baked texture @@ -7911,7 +7095,7 @@ void LLVOAvatar::releaseComponentTextures() for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { - const LLVOAvatarDictionary::BakedEntry * bakedDicEntry = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); + const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); // skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID if (!isTextureDefined(bakedDicEntry->mTextureIndex) && ( (baked_index != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) )) @@ -7927,120 +7111,14 @@ void LLVOAvatar::releaseComponentTextures() } } -//static -BOOL LLVOAvatar::teToColorParams( ETextureIndex te, U32 *param_name ) -{ - switch( te ) - { - case TEX_UPPER_SHIRT: - param_name[0] = 803; //"shirt_red"; - param_name[1] = 804; //"shirt_green"; - param_name[2] = 805; //"shirt_blue"; - break; - - case TEX_LOWER_PANTS: - param_name[0] = 806; //"pants_red"; - param_name[1] = 807; //"pants_green"; - param_name[2] = 808; //"pants_blue"; - break; - - case TEX_LOWER_SHOES: - param_name[0] = 812; //"shoes_red"; - param_name[1] = 813; //"shoes_green"; - param_name[2] = 817; //"shoes_blue"; - break; - - case TEX_LOWER_SOCKS: - param_name[0] = 818; //"socks_red"; - param_name[1] = 819; //"socks_green"; - param_name[2] = 820; //"socks_blue"; - break; - - case TEX_UPPER_JACKET: - case TEX_LOWER_JACKET: - param_name[0] = 834; //"jacket_red"; - param_name[1] = 835; //"jacket_green"; - param_name[2] = 836; //"jacket_blue"; - break; - - case TEX_UPPER_GLOVES: - param_name[0] = 827; //"gloves_red"; - param_name[1] = 829; //"gloves_green"; - param_name[2] = 830; //"gloves_blue"; - break; - - case TEX_UPPER_UNDERSHIRT: - param_name[0] = 821; //"undershirt_red"; - param_name[1] = 822; //"undershirt_green"; - param_name[2] = 823; //"undershirt_blue"; - break; - - case TEX_LOWER_UNDERPANTS: - param_name[0] = 824; //"underpants_red"; - param_name[1] = 825; //"underpants_green"; - param_name[2] = 826; //"underpants_blue"; - break; - - case TEX_SKIRT: - param_name[0] = 921; //"skirt_red"; - param_name[1] = 922; //"skirt_green"; - param_name[2] = 923; //"skirt_blue"; - break; - - case TEX_HEAD_TATTOO: - case TEX_LOWER_TATTOO: - case TEX_UPPER_TATTOO: - param_name[0] = 1071; //"tattoo_red"; - param_name[1] = 1072; //"tattoo_green"; - param_name[2] = 1073; //"tattoo_blue"; - break; - - default: - llassert(0); - return FALSE; - } - - return TRUE; -} - -void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake ) -{ - U32 param_name[3]; - if( teToColorParams( te, param_name ) ) - { - setVisualParamWeight( param_name[0], new_color.mV[VX], upload_bake ); - setVisualParamWeight( param_name[1], new_color.mV[VY], upload_bake ); - setVisualParamWeight( param_name[2], new_color.mV[VZ], upload_bake ); - } -} - -LLColor4 LLVOAvatar::getClothesColor( ETextureIndex te ) -{ - LLColor4 color; - U32 param_name[3]; - if( teToColorParams( te, param_name ) ) - { - color.mV[VX] = getVisualParamWeight( param_name[0] ); - color.mV[VY] = getVisualParamWeight( param_name[1] ); - color.mV[VZ] = getVisualParamWeight( param_name[2] ); - } - return color; -} - -// static -LLColor4 LLVOAvatar::getDummyColor() -{ - return DUMMY_COLOR; -} - void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const { LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL; - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); ++iter) { - const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; // TODO: MULTI-WEARABLE: handle multiple textures for self const LLViewerTexture* te_image = getImage(iter->first,0); if( !te_image ) @@ -8070,48 +7148,6 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const } } -// Unlike most wearable functions, this works for both self and other. -BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const -{ - if (mIsDummy) return TRUE; - - switch(type) - { - case LLWearableType::WT_SHAPE: - case LLWearableType::WT_SKIN: - case LLWearableType::WT_HAIR: - case LLWearableType::WT_EYES: - return TRUE; // everyone has all bodyparts - default: - break; // Do nothing - } - - /* switch(type) - case LLWearableType::WT_SHIRT: - indicator_te = TEX_UPPER_SHIRT; */ - for (LLVOAvatarDictionary::Textures::const_iterator tex_iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - tex_iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); - ++tex_iter) - { - const LLVOAvatarDictionary::TextureEntry *texture_dict = tex_iter->second; - if (texture_dict->mWearableType == type) - { - // If you're checking another avatar's clothing, you don't have component textures. - // Thus, you must check to see if the corresponding baked texture is defined. - // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing - // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that - // gets baked into a texture that always exists (upper or lower). - if (texture_dict->mIsUsedByBakedTexture) - { - const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - return isTextureDefined(LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex); - } - return FALSE; - } - } - return FALSE; -} - //----------------------------------------------------------------------------- // clampAttachmentPositions() //----------------------------------------------------------------------------- @@ -8206,7 +7242,7 @@ void LLVOAvatar::onFirstTEMessageReceived() if(!isSelf()) { src_callback_list = &mCallbackTextureList ; - paused = mLoadedCallbacksPaused ; + paused = !isVisible(); } for (U32 i = 0; i < mBakedTextureDatas.size(); i++) @@ -8218,7 +7254,7 @@ void LLVOAvatar::onFirstTEMessageReceived() if (layer_baked) { LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ; - mBakedTextureDatas[i].mLastTextureIndex = image->getID(); + mBakedTextureDatas[i].mLastTextureID = image->getID(); // If we have more than one texture for the other baked layers, we'll want to call this for them too. if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) ) { @@ -8270,18 +7306,87 @@ bool LLVOAvatar::visualParamWeightsAreDefault() return rtn; } +void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value) +{ + std::string type_string = "unknown"; + if (dynamic_cast(viewer_param)) + type_string = "param_alpha"; + if (dynamic_cast(viewer_param)) + type_string = "param_color"; + if (dynamic_cast(viewer_param)) + type_string = "param_driver"; + if (dynamic_cast(viewer_param)) + type_string = "param_morph"; + if (dynamic_cast(viewer_param)) + type_string = "param_skeleton"; + S32 wtype = -1; + LLViewerVisualParam *vparam = dynamic_cast(viewer_param); + if (vparam) + { + wtype = vparam->getWearableType(); + } + S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight()); + apr_file_printf(file, "\t\t\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() + ); +} + + +void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, + const std::vector& params_for_dump, + const LLTEContents& tec) +{ + std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml"); + + LLAPRFile outfile; + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); + outfile.open(fullpath, LL_APR_WB ); + apr_file_t* file = outfile.getFileHandle(); + if (!file) + { + return; + } + else + { + llinfos << "xmlfile write handle obtained : " << fullpath << llendl; + } + + + LLVisualParam* param = getFirstVisualParam(); + for (S32 i = 0; i < (S32)params_for_dump.size(); i++) + { + while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT + { + param = getNextVisualParam(); + } + LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; + F32 value = params_for_dump[i]; + dump_visual_param(file, viewer_param, value); + param = getNextVisualParam(); + } + for (U32 i = 0; i < tec.face_count; i++) + { + std::string uuid_str; + ((LLUUID*)tec.image_data)[i].toString(uuid_str); + apr_file_printf( file, "\t\t\n", i, uuid_str.c_str()); + } +} //----------------------------------------------------------------------------- // processAvatarAppearance() //----------------------------------------------------------------------------- void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) { + bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"); + std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_"; + if (enable_verbose_dumps) { dumpArchetypeXML(dump_prefix + "process_start"); } if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages")) { llwarns << "Blocking AvatarAppearance message" << llendl; return; } - LLMemType mt(LLMemType::MTYPE_AVATAR); BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; @@ -8291,12 +7396,38 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; + ESex old_sex = getSex(); + + LLTEContents tec; + parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, tec); + + U8 appearance_version = 0; + S32 this_update_cof_version = LLViewerInventoryCategory::VERSION_UNKNOWN; + S32 last_update_request_cof_version = LLAppearanceMgr::instance().mLastUpdateRequestCOFVersion; + // For future use: + //U32 appearance_flags = 0; + + if (mesgsys->has(_PREHASH_AppearanceData)) + { + mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, appearance_version, 0); + mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, this_update_cof_version, 0); + // For future use: + //mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0); + } + + // Only now that we have result of appearance_version can we decide whether to bail out. if( isSelf() ) { - llwarns << avString() << "Received AvatarAppearance for self" << llendl; - if( mFirstTEMessageReceived ) + LL_DEBUGS("Avatar") << "this_update_cof_version " << this_update_cof_version + << " last_update_request_cof_version " << last_update_request_cof_version + << " my_cof_version " << LLAppearanceMgr::instance().getCOFVersion() << llendl; + + if (getRegion() && (getRegion()->getCentralBakeVersion()==0)) + { + llwarns << avString() << "Received AvatarAppearance message for self in non-server-bake region" << llendl; + } + if( mFirstTEMessageReceived && (appearance_version == 0)) { -// llinfos << "processAvatarAppearance end " << mID << llendl; return; } } @@ -8306,11 +7437,26 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) return; } - ESex old_sex = getSex(); + // Check for stale update. + if (isSelf() + && (appearance_version>0) + && (this_update_cof_version < last_update_request_cof_version)) + { + llwarns << "Stale appearance update, wanted version " << last_update_request_cof_version + << ", got " << this_update_cof_version << llendl; + return; + } + + if (isSelf() && isEditingAppearance()) + { + llinfos << "ignoring appearance message while in appearance edit" << llendl; + return; + } + + mUseServerBakes = (appearance_version > 0); + + applyParsedTEMessage(tec); -// llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl; -// dumpAvatarTEs( "PRE processAvatarAppearance()" ); - unpackTEMessage(mesgsys, _PREHASH_ObjectData); SHClientTagMgr::instance().updateAvatarTag(this); // dumpAvatarTEs( "POST processAvatarAppearance()" ); @@ -8319,11 +7465,11 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++) { if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex) - && mBakedTextureDatas[baked_index].mLastTextureIndex != IMG_DEFAULT + && mBakedTextureDatas[baked_index].mLastTextureID != IMG_DEFAULT && baked_index != BAKED_SKIRT) { setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, - LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureID, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); } } @@ -8342,21 +7488,14 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } setCompositeUpdatesEnabled( FALSE ); - mMeshTexturesDirty = TRUE; gPipeline.markGLRebuild(this); - // ! BACKWARDS COMPATIBILITY ! - // Non-self avatars will no longer have component textures - if (!isSelf()) - { - releaseComponentTextures(); - } - mSupportsPhysics = false; // parse visual params S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); - if( num_blocks > 1 ) + 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; BOOL params_changed = FALSE; @@ -8370,6 +7509,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } else { + std::vector params_for_dump; for( S32 i = 0; i < num_blocks; i++ ) { while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT @@ -8395,6 +7535,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) { setActualBoobGrav(newWeight); } + + params_for_dump.push_back(newWeight); if (is_first_appearance_message || (param->getWeight() != newWeight)) { @@ -8412,8 +7554,12 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } param = getNextVisualParam(); } + if (enable_verbose_dumps) + dumpAppearanceMsgParams(dump_prefix + "appearance_msg", params_for_dump, tec); } + if (enable_verbose_dumps) { dumpArchetypeXML(dump_prefix + "process_post_set_weights"); } + const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT if (num_blocks != expected_tweakable_count) { @@ -8446,7 +7592,16 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } else { - llwarns << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl; + // AvatarAppearance message arrived without visual params + LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL; + if (drop_visual_params_debug) + { + llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << llendl; + } + else + { + llinfos << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl; + } const F32 LOADING_TIMEOUT_SECONDS = 60.f; // this isn't really a problem if we already have a non-default shape @@ -8469,6 +7624,14 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // If all of the avatars are completely baked, release the global image caches to conserve memory. LLVOAvatar::cullAvatarsByPixelArea(); + if (isSelf()) + { + mUseLocalAppearance = false; + } + + updateMeshTextures(); + + if (enable_verbose_dumps) dumpArchetypeXML(dump_prefix + "process_end"); // llinfos << "processAvatarAppearance end " << mID << llendl; } @@ -8543,12 +7706,12 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); maskData->mLastDiscardLevel = discard_level; */ BOOL found_texture_id = false; - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); ++iter) { - const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; if (texture_dict->mIsUsedByBakedTexture) { const ETextureIndex texture_index = iter->first; @@ -8644,11 +7807,7 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, // Called when baked texture is loaded and also when we start up with a baked texture void LLVOAvatar::useBakedTexture( const LLUUID& id ) { - /* if(id == head_baked->getID()) - mHeadBakedLoaded = TRUE; - mLastHeadBakedID = id; - mHeadMesh0.setTexture( head_baked ); - mHeadMesh1.setTexture( head_baked ); */ + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 ); @@ -8656,17 +7815,31 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) { LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL; mBakedTextureDatas[i].mIsLoaded = true; - mBakedTextureDatas[i].mLastTextureIndex = id; + mBakedTextureDatas[i].mLastTextureID = id; mBakedTextureDatas[i].mIsUsed = true; - for (U32 k = 0; k < mBakedTextureDatas[i].mMeshes.size(); k++) + + if (isUsingLocalAppearance()) { - mBakedTextureDatas[i].mMeshes[k]->setTexture( image_baked ); + llinfos << "not changing to baked texture while isUsingLocalAppearance" << llendl; } - if (mBakedTextureDatas[i].mTexLayerSet) + else { - //mBakedTextureDatas[i].mTexLayerSet->destroyComposite(); + debugColorizeSubMeshes(i,LLColor4::green); + + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); + for (; iter != end; ++iter) + { + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setTexture( image_baked ); + } + } } - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); + + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = + LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); local_tex_iter != baked_dict->mLocalTextures.end(); ++local_tex_iter) @@ -8679,9 +7852,15 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) // This is paired with similar code in updateMeshTextures that sets hair mesh color. if (i == BAKED_HAIR) { - for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++) + avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); + avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); + for (; iter != end; ++iter) { - mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f ); + LLAvatarJointMesh* mesh = (*iter); + if (mesh) + { + mesh->setColor( LLColor4::white ); + } } } } @@ -8690,43 +7869,100 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) dirtyMesh(); } -// static -void LLVOAvatar::dumpArchetypeXML( void* ) +std::string get_sequential_numbered_file_name(const std::string& prefix, + const std::string& suffix) { - LLAPRFile outfile(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER, "new archetype.xml"), LL_APR_WB); - apr_file_t* file = outfile.getFileHandle() ; + typedef std::map file_num_type; + static file_num_type file_nums; + file_num_type::iterator it = file_nums.find(prefix); + S32 num = 0; + if (it != file_nums.end()) + { + num = it->second; + } + file_nums[prefix] = num+1; + std::string outfilename = prefix + " " + llformat("%04d",num) + ".xml"; + std::replace(outfilename.begin(),outfilename.end(),' ','_'); + return outfilename; +} + +void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables ) +{ + std::string outprefix(prefix); + if (outprefix.empty()) + { + outprefix = getFullname() + (isSelf()?"_s":"_o"); + } + if (outprefix.empty()) + { + outprefix = std::string("new_archetype"); + } + std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml"); + + LLAPRFile outfile; + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); + outfile.open(fullpath, LL_APR_WB ); + apr_file_t* file = outfile.getFileHandle(); if (!file) { return; } + else + { + llinfos << "xmlfile write handle obtained : " << fullpath << llendl; + } apr_file_printf( file, "\n" ); apr_file_printf( file, "\n" ); apr_file_printf( file, "\n\t\n" ); - // only body parts, not clothing. - for (S32 type = LLWearableType::WT_SHAPE; type <= LLWearableType::WT_EYES; type++) + if (group_by_wearables) { - const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); - apr_file_printf( file, "\n\t\t\n", wearable_name.c_str() ); + for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++) + { + const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); + apr_file_printf( file, "\n\t\t\n", wearable_name.c_str() ); - for (LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam()) + for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) + { + LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; + if( (viewer_param->getWearableType() == type) && + (viewer_param->isTweakable() ) ) + { + dump_visual_param(file, viewer_param, viewer_param->getWeight()); + } + } + + for (U8 te = 0; te < TEX_NUM_INDICES; te++) + { + if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type) + { + // MULTIPLE_WEARABLES: extend to multiple wearables? + LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); + if( te_image ) + { + std::string uuid_str; + te_image->getID().toString( uuid_str ); + apr_file_printf( file, "\t\t\n", te, uuid_str.c_str()); + } + } + } + } + } + else + { + // Just dump all params sequentially. + for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) { LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - if( (viewer_param->getWearableType() == type) && - (viewer_param->isTweakable() ) ) - { - apr_file_printf(file, "\t\t\n", - viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight()); - } + dump_visual_param(file, viewer_param, viewer_param->getWeight()); } for (U8 te = 0; te < TEX_NUM_INDICES; te++) { - if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te) == type) { // MULTIPLE_WEARABLES: extend to multiple wearables? - LLViewerTexture* te_image = ((LLVOAvatar *)(gAgentAvatarp))->getImage((ETextureIndex)te, 0); + LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); if( te_image ) { std::string uuid_str; @@ -8735,14 +7971,18 @@ void LLVOAvatar::dumpArchetypeXML( void* ) } } } + } apr_file_printf( file, "\t\n" ); apr_file_printf( file, "\n\n" ); - //explictly close the file if it is still open which it should be - if (file) + + bool ultra_verbose = false; + if (isSelf() && ultra_verbose) { - outfile.close(); + // show the cloned params inside the wearables as well. + gAgentAvatarp->dumpWearableInfo(outfile); } + // File will close when handle goes out of scope } @@ -8824,12 +8064,9 @@ void LLVOAvatar::cullAvatarsByPixelArea() } } + // runway - this doesn't really detect gray/grey state. S32 grey_avatars = 0; - if (LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars)) - { - LLVOAvatar::deleteCachedImages(false); - } - else + if (!LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars)) { if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame { @@ -8857,503 +8094,26 @@ void LLVOAvatar::startAppearanceAnimation() } } +//virtual +void LLVOAvatar::bodySizeChanged() +{ + if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF()) + { // notify simulator of change in size + // but not if we are in the middle of updating appearance + gAgent.sendAgentSetAppearance(); + } +} + +void LLVOAvatar::setIsUsingServerBakes(BOOL newval) +{ + mUseServerBakes = newval; +} + // virtual void LLVOAvatar::removeMissingBakedTextures() { } -//----------------------------------------------------------------------------- -// LLVOAvatarXmlInfo -//----------------------------------------------------------------------------- - -LLVOAvatar::LLVOAvatarXmlInfo::LLVOAvatarXmlInfo() - : mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0) -{ -} - -LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo() -{ - std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer()); - std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer()); - std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer()); - deleteAndClear(mTexSkinColorInfo); - deleteAndClear(mTexHairColorInfo); - deleteAndClear(mTexEyeColorInfo); - std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer()); - std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer()); - std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer()); -} - -//----------------------------------------------------------------------------- -// LLVOAvatarBoneInfo::parseXml() -//----------------------------------------------------------------------------- -BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node) -{ - if (node->hasName("bone")) - { - mIsJoint = TRUE; - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - if (!node->getFastAttributeString(name_string, mName)) - { - llwarns << "Bone without name" << llendl; - return FALSE; - } - } - else if (node->hasName("collision_volume")) - { - mIsJoint = FALSE; - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - if (!node->getFastAttributeString(name_string, mName)) - { - mName = "Collision Volume"; - } - } - else - { - llwarns << "Invalid node " << node->getName() << llendl; - return FALSE; - } - - static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); - if (!node->getFastAttributeVector3(pos_string, mPos)) - { - llwarns << "Bone without position" << llendl; - return FALSE; - } - - static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot"); - if (!node->getFastAttributeVector3(rot_string, mRot)) - { - llwarns << "Bone without rotation" << llendl; - return FALSE; - } - - static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); - if (!node->getFastAttributeVector3(scale_string, mScale)) - { - llwarns << "Bone without scale" << llendl; - return FALSE; - } - - if (mIsJoint) - { - static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); - if (!node->getFastAttributeVector3(pivot_string, mPivot)) - { - llwarns << "Bone without pivot" << llendl; - return FALSE; - } - } - - // parse children - LLXmlTreeNode* child; - for( child = node->getFirstChild(); child; child = node->getNextChild() ) - { - LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo; - if (!child_info->parseXml(child)) - { - delete child_info; - return FALSE; - } - mChildList.push_back(child_info); - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// LLVOAvatarSkeletonInfo::parseXml() -//----------------------------------------------------------------------------- -BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) -{ - static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones"); - if (!node->getFastAttributeS32(num_bones_string, mNumBones)) - { - llwarns << "Couldn't find number of bones." << llendl; - return FALSE; - } - - static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes"); - node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes); - - LLXmlTreeNode* child; - for( child = node->getFirstChild(); child; child = node->getNextChild() ) - { - LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo; - if (!info->parseXml(child)) - { - delete info; - llwarns << "Error parsing bone in skeleton file" << llendl; - return FALSE; - } - mBoneInfoList.push_back(info); - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlSkeletonNode(): parses nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root) -{ - LLXmlTreeNode* node = root->getChildByName( "skeleton" ); - if( !node ) - { - llwarns << "avatar file: missing " << llendl; - return FALSE; - } - - LLXmlTreeNode* child; - - // SKELETON DISTORTIONS - for (child = node->getChildByName( "param" ); - child; - child = node->getNextNamedChild()) - { - if (!child->getChildByName("param_skeleton")) - { - if (child->getChildByName("param_morph")) - { - llwarns << "Can't specify morph param in skeleton definition." << llendl; - } - else - { - llwarns << "Unknown param type." << llendl; - } - continue; - } - - LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo; - if (!info->parseXml(child)) - { - delete info; - return FALSE; - } - - mSkeletalDistortionInfoList.push_back(info); - } - - // ATTACHMENT POINTS - for (child = node->getChildByName( "attachment_point" ); - child; - child = node->getNextNamedChild()) - { - LLVOAvatarAttachmentInfo* info = new LLVOAvatarAttachmentInfo(); - - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - if (!child->getFastAttributeString(name_string, info->mName)) - { - llwarns << "No name supplied for attachment point." << llendl; - delete info; - continue; - } - - static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint"); - if (!child->getFastAttributeString(joint_string, info->mJointName)) - { - llwarns << "No bone declared in attachment point " << info->mName << llendl; - delete info; - continue; - } - - static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position"); - if (child->getFastAttributeVector3(position_string, info->mPosition)) - { - info->mHasPosition = TRUE; - } - - static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation"); - if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler)) - { - info->mHasRotation = TRUE; - } - static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group"); - if (child->getFastAttributeS32(group_string, info->mGroup)) - { - if (info->mGroup == -1) - info->mGroup = -1111; // -1 = none parsed, < -1 = bad value - } - - static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id"); - if (!child->getFastAttributeS32(id_string, info->mAttachmentID)) - { - llwarns << "No id supplied for attachment point " << info->mName << llendl; - delete info; - continue; - } - - static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice"); - child->getFastAttributeS32(slot_string, info->mPieMenuSlice); - - static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person"); - child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson); - - static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud"); - child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment); - - mAttachmentInfoList.push_back(info); - } - - return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlMeshNodes(): parses nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root) -{ - for (LLXmlTreeNode* node = root->getChildByName( "mesh" ); - node; - node = root->getNextNamedChild()) - { - LLVOAvatarMeshInfo *info = new LLVOAvatarMeshInfo; - - // attribute: type - static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type"); - if( !node->getFastAttributeString( type_string, info->mType ) ) - { - llwarns << "Avatar file: is missing type attribute. Ignoring element. " << llendl; - delete info; - return FALSE; // Ignore this element - } - - static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod"); - if (!node->getFastAttributeS32( lod_string, info->mLOD )) - { - llwarns << "Avatar file: is missing lod attribute. Ignoring element. " << llendl; - delete info; - return FALSE; // Ignore this element - } - - static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); - if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) ) - { - llwarns << "Avatar file: is missing file_name attribute. Ignoring: " << info->mType << llendl; - delete info; - return FALSE; // Ignore this element - } - - static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference"); - node->getFastAttributeString( reference_string, info->mReferenceMeshName ); - - // attribute: min_pixel_area - static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area"); - static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width"); - if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea )) - { - F32 min_pixel_area = 0.1f; - if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area )) - { - // this is square root of pixel area (sensible to use linear space in defining lods) - min_pixel_area = min_pixel_area * min_pixel_area; - } - info->mMinPixelArea = min_pixel_area; - } - - // Parse visual params for this node only if we haven't already - for (LLXmlTreeNode* child = node->getChildByName( "param" ); - child; - child = node->getNextNamedChild()) - { - if (!child->getChildByName("param_morph")) - { - if (child->getChildByName("param_skeleton")) - { - llwarns << "Can't specify skeleton param in a mesh definition." << llendl; - } - else - { - llwarns << "Unknown param type." << llendl; - } - continue; - } - - LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo(); - if (!morphinfo->parseXml(child)) - { - delete morphinfo; - delete info; - return -1; - } - BOOL shared = FALSE; - static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared"); - child->getFastAttributeBOOL(shared_string, shared); - - info->mPolyMorphTargetInfoList.push_back(LLVOAvatarMeshInfo::morph_info_pair_t(morphinfo, shared)); - } - - mMeshInfoList.push_back(info); - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlColorNodes(): parses nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root) -{ - for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" ); - color_node; - color_node = root->getNextNamedChild()) - { - std::string global_color_name; - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - if (color_node->getFastAttributeString( name_string, global_color_name ) ) - { - if( global_color_name == "skin_color" ) - { - if (mTexSkinColorInfo) - { - llwarns << "avatar file: multiple instances of skin_color" << llendl; - return FALSE; - } - mTexSkinColorInfo = new LLTexGlobalColorInfo; - if( !mTexSkinColorInfo->parseXml( color_node ) ) - { - deleteAndClear(mTexSkinColorInfo); - llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl; - return FALSE; - } - } - else if( global_color_name == "hair_color" ) - { - if (mTexHairColorInfo) - { - llwarns << "avatar file: multiple instances of hair_color" << llendl; - return FALSE; - } - mTexHairColorInfo = new LLTexGlobalColorInfo; - if( !mTexHairColorInfo->parseXml( color_node ) ) - { - deleteAndClear(mTexHairColorInfo); - llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl; - return FALSE; - } - } - else if( global_color_name == "eye_color" ) - { - if (mTexEyeColorInfo) - { - llwarns << "avatar file: multiple instances of eye_color" << llendl; - return FALSE; - } - mTexEyeColorInfo = new LLTexGlobalColorInfo; - if( !mTexEyeColorInfo->parseXml( color_node ) ) - { - llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl; - return FALSE; - } - } - } - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlLayerNodes(): parses nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root) -{ - for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" ); - layer_node; - layer_node = root->getNextNamedChild()) - { - LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo(); - if( layer_info->parseXml( layer_node ) ) - { - mLayerInfoList.push_back(layer_info); - } - else - { - delete layer_info; - llwarns << "avatar file: layer_set->parseXml() failed" << llendl; - return FALSE; - } - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlDriverNodes(): parses nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root) -{ - LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" ); - if( driver ) - { - for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" ); - grand_child; - grand_child = driver->getNextNamedChild()) - { - if( grand_child->getChildByName( "param_driver" ) ) - { - LLDriverParamInfo* driver_info = new LLDriverParamInfo(); - if( driver_info->parseXml( grand_child ) ) - { - mDriverInfoList.push_back(driver_info); - } - else - { - delete driver_info; - llwarns << "avatar file: driver_param->parseXml() failed" << llendl; - return FALSE; - } - } - } - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlDriverNodes(): parses nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root) -{ - LLXmlTreeNode* masks = root->getChildByName( "morph_masks" ); - if( !masks ) - { - return FALSE; - } - - for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" ); - grand_child; - grand_child = masks->getNextNamedChild()) - { - LLVOAvatarMorphInfo* info = new LLVOAvatarMorphInfo(); - - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name"); - if (!grand_child->getFastAttributeString(name_string, info->mName)) - { - llwarns << "No name supplied for morph mask." << llendl; - delete info; - continue; - } - - static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region"); - if (!grand_child->getFastAttributeString(region_string, info->mRegion)) - { - llwarns << "No region supplied for morph mask." << llendl; - delete info; - continue; - } - - static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer"); - if (!grand_child->getFastAttributeString(layer_string, info->mLayer)) - { - llwarns << "No layer supplied for morph mask." << llendl; - delete info; - continue; - } - - // optional parameter. don't throw a warning if not present. - static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert"); - grand_child->getFastAttributeBOOL(invert_string, info->mInvert); - - mMorphMaskInfoList.push_back(info); - } - - return TRUE; -} - //virtual void LLVOAvatar::updateRegion(LLViewerRegion *regionp) { @@ -9571,7 +8331,7 @@ void LLVOAvatar::idleUpdateRenderCost() for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); ETextureIndex tex_index = baked_dict->mTextureIndex; if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT))) { @@ -9651,11 +8411,11 @@ void LLVOAvatar::idleUpdateRenderCost() } // print any avatar textures we didn't already know about - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); ++iter) { - const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; // TODO: MULTI-WEARABLE: handle multiple textures for self const LLViewerTexture* te_image = getImage(iter->first,0); if (!te_image) @@ -9685,26 +8445,26 @@ void LLVOAvatar::idleUpdateRenderCost() BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index) { if (index < 0 || index >= TEX_NUM_INDICES) return false; - return LLVOAvatarDictionary::getInstance()->getTexture(index)->mIsLocalTexture; + return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsLocalTexture; } // static BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index) { if (index < 0 || index >= TEX_NUM_INDICES) return false; - return LLVOAvatarDictionary::getInstance()->getTexture(index)->mIsBakedTexture; + return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsBakedTexture; } const std::string LLVOAvatar::getBakedStatusForPrintout() const { std::string line; - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); ++iter) { const ETextureIndex index = iter->first; - const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; if (texture_dict->mIsBakedTexture) { line += texture_dict->mName; @@ -9736,28 +8496,25 @@ F32 calc_bouncy_animation(F32 x) } //virtual -BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index ) const +BOOL LLVOAvatar::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index ) const { if (isIndexLocalTexture(te)) { return FALSE; } - LLViewerTexture* img = getImage(te, index); - if(img) + if( !getImage( te, index ) ) { - return (img->getID() != IMG_DEFAULT_AVATAR && - img->getID() != IMG_DEFAULT); - } - else - { - llwarns << "Image doesn't exist" << llendl; + llwarns << "getImage( " << te << ", " << index << " ) returned 0" << llendl; return FALSE; } + + return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR && + getImage(te, index)->getID() != IMG_DEFAULT); } //virtual -BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index) const +BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const { if (isIndexLocalTexture(type)) { @@ -9773,7 +8530,7 @@ BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 ind } //virtual -BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const +BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const { // non-self avatars don't have wearables return FALSE; @@ -9882,3 +8639,4 @@ U32 calc_shame(LLVOVolume* volume, std::set &textures) return shame; } + diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 81529a2f3..cf9643373 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -1,38 +1,32 @@ /** * @file llvoavatar.h - * @brief Declaration of LLVOAvatar class which is a derivation fo + * @brief Declaration of LLVOAvatar class which is a derivation of * LLViewerObject * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * 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_LLVOAVATAR_H -#define LL_LLVOAVATAR_H +#ifndef LL_VOAVATAR_H +#define LL_VOAVATAR_H #include #include @@ -42,6 +36,7 @@ #include #include "imageids.h" // IMG_INVISIBLE +#include "llavatarappearance.h" #include "llchat.h" #include "lldrawpoolalpha.h" #include "llviewerobject.h" @@ -50,9 +45,10 @@ #include "llviewerjointmesh.h" #include "llviewerjointattachment.h" #include "llrendertarget.h" -#include "llvoavatardefines.h" +#include "llavatarappearancedefines.h" #include "lltexglobalcolor.h" #include "lldriverparam.h" +#include "llviewertexlayer.h" #include "material_codes.h" // LL_MCODE_END #include "emeraldboobutils.h" @@ -70,13 +66,12 @@ extern const LLUUID ANIM_AGENT_PELVIS_FIX; extern const LLUUID ANIM_AGENT_TARGET; extern const LLUUID ANIM_AGENT_WALK_ADJUST; -class LLTexLayerSet; +class LLViewerWearable; class LLVoiceVisualizer; class LLHUDNameTag; class LLHUDEffectSpiral; class LLTexGlobalColor; -class LLVOAvatarBoneInfo; -class LLVOAvatarSkeletonInfo; +class LLViewerJoint; class SHClientTagMgr : public LLSingleton, public boost::signals2::trackable { @@ -122,17 +117,14 @@ private: // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLVOAvatar : + public LLAvatarAppearance, public LLViewerObject, - public LLCharacter, public boost::signals2::trackable { LOG_CLASS(LLVOAvatar); public: friend class LLVOAvatarSelf; -protected: - struct LLVOAvatarXmlInfo; - struct LLMaskedMorph; /******************************************************************************** ** ** @@ -140,6 +132,16 @@ protected: **/ public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual void markDead(); static void initClass(); // Initialize data that's only init'd once per class. @@ -147,9 +149,6 @@ public: virtual void initInstance(); // Called after construction to initialize the class. protected: virtual ~LLVOAvatar(); - BOOL loadSkeletonNode(); - BOOL loadMeshNodes(); - virtual BOOL loadLayersets(); /** Initialization ** ** @@ -164,31 +163,31 @@ protected: // LLViewerObject interface and related //-------------------------------------------------------------------- public: - virtual void updateGL(); - virtual LLVOAvatar* asAvatar(); + /*virtual*/ void updateGL(); + /*virtual*/ LLVOAvatar* asAvatar(); virtual U32 processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, U32 block_num, const EObjectUpdateType update_type, LLDataPacker *dp); - virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - virtual BOOL updateLOD(); + virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ BOOL updateLOD(); BOOL updateJointLODs(); void updateLODRiggedAttachments( void ); - virtual BOOL isActive() const; // Whether this object needs to do an idleUpdate. - virtual void updateTextures(); - virtual S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim. - virtual void onShift(const LLVector4a& shift_vector); - virtual U32 getPartitionType() const; - virtual const LLVector3 getRenderPosition() const; - virtual void updateDrawable(BOOL force_damped); - virtual LLDrawable* createDrawable(LLPipeline *pipeline); - virtual BOOL updateGeometry(LLDrawable *drawable); - virtual void setPixelAreaAndAngle(LLAgent &agent); - virtual void updateRegion(LLViewerRegion *regionp); - virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax); - virtual void getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); - virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. + /*virtual*/ void updateTextures(); + /*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim. + /*virtual*/ void onShift(const LLVector4a& shift_vector); + /*virtual*/ U32 getPartitionType() const; + /*virtual*/ const LLVector3 getRenderPosition() const; + /*virtual*/ void updateDrawable(BOOL force_damped); + /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); + /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); + /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); + /*virtual*/ void updateRegion(LLViewerRegion *regionp); + /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax); + /*virtual*/ void getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); + /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, S32* face_hit = NULL, // which face was hit @@ -209,16 +208,14 @@ public: // LLCharacter interface and related //-------------------------------------------------------------------- public: - virtual LLVector3 getCharacterPosition(); - virtual LLQuaternion getCharacterRotation(); - virtual LLVector3 getCharacterVelocity(); - virtual LLVector3 getCharacterAngularVelocity(); - virtual LLJoint* getCharacterJoint(U32 num); - virtual BOOL allocateCharacterJoints(U32 num); + /*virtual*/ LLVector3 getCharacterPosition(); + /*virtual*/ LLQuaternion getCharacterRotation(); + /*virtual*/ LLVector3 getCharacterVelocity(); + /*virtual*/ LLVector3 getCharacterAngularVelocity(); - virtual LLUUID remapMotionID(const LLUUID& id); - virtual BOOL startMotion(const LLUUID& id, F32 time_offset = 0.f); - virtual BOOL stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE); + /*virtual*/ LLUUID remapMotionID(const LLUUID& id); + /*virtual*/ BOOL startMotion(const LLUUID& id, F32 time_offset = 0.f); + /*virtual*/ BOOL stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE); virtual void stopMotionFromSource(const LLUUID& source_id); virtual void requestStopMotion(LLMotion* motion); LLMotion* findMotion(const LLUUID& id) const; @@ -226,24 +223,17 @@ public: void dumpAnimationState(); virtual LLJoint* getJoint(const std::string &name); - virtual LLJoint* getRootJoint() { return &mRoot; } - - void resetJointPositions( void ); + void resetJointPositionsToDefault( void ); void resetSpecificJointPosition( const std::string& name ); - virtual const char* getAnimationPrefix() { return "avatar"; } - virtual const LLUUID& getID() const; - virtual LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset); - virtual LLJoint* findCollisionVolume(U32 volume_id); - virtual S32 getCollisionVolumeID(std::string &name); - virtual void addDebugText(const std::string& text); - virtual F32 getTimeDilation(); - virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm); - virtual F32 getPixelArea() const; - virtual LLPolyMesh* getHeadMesh(); - virtual LLPolyMesh* getUpperBodyMesh(); - virtual LLVector3d getPosGlobalFromAgent(const LLVector3 &position); - virtual LLVector3 getPosAgentFromGlobal(const LLVector3d &position); + + /*virtual*/ const LLUUID& getID() const; + /*virtual*/ void addDebugText(const std::string& text); + /*virtual*/ F32 getTimeDilation(); + /*virtual*/ void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm); + /*virtual*/ F32 getPixelArea() const; + /*virtual*/ LLVector3d getPosGlobalFromAgent(const LLVector3 &position); + /*virtual*/ LLVector3 getPosAgentFromGlobal(const LLVector3d &position); virtual void updateVisualParams(); @@ -258,10 +248,9 @@ public: public: virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent - bool isBuilt() const { return mIsBuilt; } private: //aligned members - LLVector4a mImpostorExtents[2]; + LL_ALIGN_16(LLVector4a mImpostorExtents[2]); private: BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients @@ -290,9 +279,7 @@ public: void idleUpdateRenderCost(); void idleUpdateBelowWater(); void idleUpdateBoobEffect(); //Emerald - - //-------------------------------------------------------------------- // Static preferences (controlled by user settings/menus) //-------------------------------------------------------------------- @@ -325,18 +312,20 @@ public: //-------------------------------------------------------------------- public: BOOL isFullyLoaded() const; - bool visualParamWeightsAreDefault(); + bool isTooComplex() const; + bool visualParamWeightsAreDefault(); virtual BOOL getIsCloud() const; BOOL isFullyTextured() const; BOOL hasGray() const; S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = fully textured. void updateRezzedStatusTimers(); + bool isLangolier() const { return mFreezeTimeLangolier; } + bool isFrozenDead() const { return mFreezeTimeDead; } S32 mLastRezzedStatus; protected: BOOL updateIsFullyLoaded(); BOOL processFullyLoadedChange(bool loading); - void updateRuthTimer(bool loading); F32 calcMorphAmount(); private: @@ -348,88 +337,41 @@ private: S32 mVisualComplexity; LLFrameTimer mFullyLoadedTimer; LLFrameTimer mRuthTimer; + bool mFreezeTimeLangolier; // True when this avatar was created during snapshot FreezeTime mode, and that mode is still active. + bool mFreezeTimeDead; // True when the avatar was marked dead (ie, TP-ed away) while in FreezeTime mode. protected: LLFrameTimer mInvisibleTimer; /** State ** ** *******************************************************************************/ - /******************************************************************************** ** ** ** SKELETON **/ +protected: + /*virtual*/ LLAvatarJoint* createAvatarJoint(); // Returns LLViewerJoint + /*virtual*/ LLAvatarJoint* createAvatarJoint(S32 joint_num); // Returns LLViewerJoint + /*virtual*/ LLAvatarJointMesh* createAvatarJointMesh(); // Returns LLViewerJointMesh public: void updateHeadOffset(); - F32 getPelvisToFoot() const { return mPelvisToFoot; } void setPelvisOffset( bool hasOffset, const LLVector3& translation, F32 offset ) ; bool hasPelvisOffset( void ) { return mHasPelvisOffset; } void postPelvisSetRecalc( void ); void setPelvisOffset( F32 pelvixFixupAmount ); + /*virtual*/ BOOL loadSkeletonNode(); + /*virtual*/ void buildCharacter(); + bool mHasPelvisOffset; LLVector3 mPelvisOffset; F32 mLastPelvisToFoot; F32 mPelvisFixup; F32 mLastPelvisFixup; - LLVector3 mHeadOffset; // current head position - LLViewerJoint mRoot; - - typedef std::map joint_map_t; - joint_map_t mJointMap; - -protected: - static BOOL parseSkeletonFile(const std::string& filename); - void buildCharacter(); - virtual BOOL loadAvatar(); - - BOOL setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num); - BOOL buildSkeleton(const LLVOAvatarSkeletonInfo *info); -private: - BOOL mIsBuilt; // state of deferred character building - S32 mNumJoints; - LLViewerJoint* mSkeleton; - - //-------------------------------------------------------------------- - // Pelvis height adjustment members. - //-------------------------------------------------------------------- -public: - LLVector3 mBodySize; S32 mLastSkeletonSerialNum; -private: - F32 mPelvisToFoot; - //-------------------------------------------------------------------- - // Cached pointers to well known joints - //-------------------------------------------------------------------- -public: - LLViewerJoint* mPelvisp; - LLViewerJoint* mTorsop; - LLViewerJoint* mChestp; - LLViewerJoint* mNeckp; - LLViewerJoint* mHeadp; - LLViewerJoint* mSkullp; - LLViewerJoint* mEyeLeftp; - LLViewerJoint* mEyeRightp; - LLViewerJoint* mHipLeftp; - LLViewerJoint* mHipRightp; - LLViewerJoint* mKneeLeftp; - LLViewerJoint* mKneeRightp; - LLViewerJoint* mAnkleLeftp; - LLViewerJoint* mAnkleRightp; - LLViewerJoint* mFootLeftp; - LLViewerJoint* mFootRightp; - LLViewerJoint* mWristLeftp; - LLViewerJoint* mWristRightp; - - //-------------------------------------------------------------------- - // XML parse tree - //-------------------------------------------------------------------- -private: - static LLXmlTree sXMLTree; // avatar config file - static LLXmlTree sSkeletonXMLTree; // avatar skeleton file /** Skeleton ** ** @@ -443,6 +385,7 @@ private: public: U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0); bool isVisuallyMuted() const; + void resetFreezeTime(); U32 renderRigid(); U32 renderSkinned(EAvatarRenderPass pass); @@ -453,7 +396,6 @@ public: static void deleteCachedImages(bool clearAll=true); static void destroyGL(); static void restoreGL(); - BOOL mIsDummy; // for special views S32 mSpecialRenderMode; // special lighting U32 mAttachmentGeometryBytes; //number of bytes in attached geometry F32 mAttachmentSurfaceArea; //estimated surface area of attachments @@ -471,9 +413,15 @@ private: // Morph masks //-------------------------------------------------------------------- public: - BOOL morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES); - void addMaskedMorph(LLVOAvatarDefines::EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer); - void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES); + /*virtual*/ void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES); + BOOL morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES); + + + //-------------------------------------------------------------------- + // Global colors + //-------------------------------------------------------------------- +public: + /*virtual*/void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake); //-------------------------------------------------------------------- // Visibility @@ -518,8 +466,6 @@ private: F32 mImpostorDistance; F32 mImpostorPixelArea; LLVector3 mLastAnimExtents[2]; - - LLCachedControl mRenderUnloadedAvatar; //-------------------------------------------------------------------- // Wind rippling in clothes @@ -556,10 +502,10 @@ private: // Constants //-------------------------------------------------------------------- public: - virtual LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR; } - virtual LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED; } + virtual LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLGLTexture::BOOST_AVATAR; } + virtual LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLGLTexture::BOOST_AVATAR_BAKED; } virtual S32 getTexImageSize() const; - virtual S32 getTexImageArea() const { return getTexImageSize()*getTexImageSize(); } + /*virtual*/ S32 getTexImageArea() const { return getTexImageSize()*getTexImageSize(); } /** Rendering ** ** @@ -574,9 +520,9 @@ public: // Loading status //-------------------------------------------------------------------- public: - virtual BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; - virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; - virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const; + virtual BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const; + virtual BOOL isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const; + virtual BOOL isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const; BOOL isFullyBaked(); static BOOL areAllNearbyInstancesBaked(S32& grey_avatars); @@ -587,6 +533,7 @@ public: // Baked textures //-------------------------------------------------------------------- public: + /*virtual*/ LLTexLayerSet* createTexLayerSet(); // Return LLViewerTexLayerSet void releaseComponentTextures(); // ! BACKWARDS COMPATIBILITY ! protected: static void onBakedTextureMasksLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); @@ -594,32 +541,19 @@ protected: static void onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); virtual void removeMissingBakedTextures(); void useBakedTexture(const LLUUID& id); + LLViewerTexLayerSet* getTexLayerSet(const U32 index) const { return dynamic_cast(mBakedTextureDatas[index].mTexLayerSet); } + - typedef std::deque morph_list_t; - struct BakedTextureData - { - LLUUID mLastTextureIndex; - LLTexLayerSet* mTexLayerSet; // Only exists for self - bool mIsLoaded; - bool mIsUsed; - LLVOAvatarDefines::ETextureIndex mTextureIndex; - U32 mMaskTexName; - // Stores pointers to the joint meshes that this baked texture deals with - std::vector< LLViewerJointMesh * > mMeshes; // std::vector mJoints[i]->mMeshParts - morph_list_t mMaskedMorphs; - }; - typedef std::vector bakedtexturedata_vec_t; - bakedtexturedata_vec_t mBakedTextureDatas; LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ; BOOL mLoadedCallbacksPaused; //-------------------------------------------------------------------- // Local Textures //-------------------------------------------------------------------- protected: - virtual void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0); - virtual void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); + virtual void setLocalTexture(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0); + virtual void addLocalTextureStats(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); // MULTI-WEARABLE: make self-only? - virtual void setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index = 0); + virtual void setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index = 0); //-------------------------------------------------------------------- // Texture accessors @@ -627,6 +561,7 @@ protected: private: virtual void setImage(const U8 te, LLViewerTexture *imagep, const U32 index); virtual LLViewerTexture* getImage(const U8 te, const U32 index) const; + const std::string getImageURL(const U8 te, const LLUUID &uuid); virtual const LLTextureEntry* getTexEntry(const U8 te_num) const; virtual void setTexEntry(const U8 index, const LLTextureEntry &te); @@ -653,13 +588,11 @@ public: // Static texture/mesh/baked dictionary //-------------------------------------------------------------------- public: - static BOOL isIndexLocalTexture(LLVOAvatarDefines::ETextureIndex i); - static BOOL isIndexBakedTexture(LLVOAvatarDefines::ETextureIndex i); + static BOOL isIndexLocalTexture(LLAvatarAppearanceDefines::ETextureIndex i); + static BOOL isIndexBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i); private: - static const LLVOAvatarDefines::LLVOAvatarDictionary *getDictionary() { return sAvatarDictionary; } - static LLVOAvatarDefines::LLVOAvatarDictionary* sAvatarDictionary; - static LLVOAvatarSkeletonInfo* sAvatarSkeletonInfo; - static LLVOAvatarXmlInfo* sAvatarXmlInfo; + static const LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary *getDictionary() { return sAvatarDictionary; } + static LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* sAvatarDictionary; //-------------------------------------------------------------------- // Messaging @@ -680,22 +613,20 @@ private: **/ public: - void updateMeshTextures(); + void debugColorizeSubMeshes(U32 i, const LLColor4& color); + virtual void updateMeshTextures(); void updateSexDependentLayerSets(BOOL upload_bake); - void dirtyMesh(); // Dirty the avatar mesh + virtual void dirtyMesh(); // Dirty the avatar mesh void updateMeshData(); protected: void releaseMeshData(); - virtual void restoreMeshData(); + virtual void restoreMeshData(); private: - void dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority + virtual void dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority + LLViewerJoint* getViewerJoint(S32 idx); S32 mDirtyMesh; // 0 -- not dirty, 1 -- morphed, 2 -- LOD BOOL mMeshTexturesDirty; - typedef std::multimap polymesh_map_t; - polymesh_map_t mMeshes; - std::vector mMeshLOD; - //-------------------------------------------------------------------- // Destroy invisible mesh //-------------------------------------------------------------------- @@ -716,42 +647,38 @@ public: void processAvatarAppearance(LLMessageSystem* mesgsys); void hideSkirt(); void startAppearanceAnimation(); - LLPolyMesh* getMesh(LLPolyMeshSharedData* shared_data); + /*virtual*/ void bodySizeChanged(); //-------------------------------------------------------------------- // Appearance morphing //-------------------------------------------------------------------- public: BOOL getIsAppearanceAnimating() const { return mAppearanceAnimating; } + + // True if we are computing our appearance via local compositing + // instead of baked textures, as for example during wearable + // editing or when waiting for a subsequent server rebake. + /*virtual*/ BOOL isUsingLocalAppearance() const { return mUseLocalAppearance; } + + // True if this avatar should fetch its baked textures via the new + // appearance mechanism. + /*virtual*/ BOOL isUsingServerBakes() const { return mUseServerBakes; } + void setIsUsingServerBakes(BOOL newval); + + + // True if we are currently in appearance editing mode. Often but + // not always the same as isUsingLocalAppearance(). + /*virtual*/ BOOL isEditingAppearance() const { return mIsEditingAppearance; } + + // FIXME review isUsingLocalAppearance uses, some should be isEditing instead. + private: BOOL mAppearanceAnimating; LLFrameTimer mAppearanceMorphTimer; F32 mLastAppearanceBlendTime; - -public: - typedef std::map lod_mesh_map_t; - typedef std::map mesh_info_t; - - static void getMeshInfo(mesh_info_t* mesh_info); - - //-------------------------------------------------------------------- - // Clothing colors (convenience functions to access visual parameters) - //-------------------------------------------------------------------- -public: - void setClothesColor(LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake); - LLColor4 getClothesColor(LLVOAvatarDefines::ETextureIndex te); - static BOOL teToColorParams(LLVOAvatarDefines::ETextureIndex te, U32 *param_name); - - //-------------------------------------------------------------------- - // Global colors - //-------------------------------------------------------------------- -public: - LLColor4 getGlobalColor(const std::string& color_name ) const; - void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake); -private: - LLTexGlobalColor* mTexSkinColor; - LLTexGlobalColor* mTexHairColor; - LLTexGlobalColor* mTexEyeColor; + BOOL mIsEditingAppearance; // flag for if we're actively in appearance editing mode + BOOL mUseLocalAppearance; // flag for if we're using a local composite + BOOL mUseServerBakes; // flag for if baked textures should be fetched from baking service (false if they're temporary uploads) //-------------------------------------------------------------------- // Visibility @@ -761,7 +688,6 @@ public: void setVisibilityRank(U32 rank); U32 getVisibilityRank() const { return mVisibilityRank; } // unused static S32 sNumVisibleAvatars; // Number of instances of this class - static LLColor4 getDummyColor(); /** Appearance ** ** *******************************************************************************/ @@ -771,9 +697,6 @@ public: ** WEARABLES **/ -public: - virtual BOOL isWearingWearableType(LLWearableType::EType type ) const; - //-------------------------------------------------------------------- // Attachments //-------------------------------------------------------------------- @@ -783,6 +706,7 @@ public: virtual BOOL detachObject(LLViewerObject *viewer_object); void cleanupAttachedMesh( LLViewerObject* pVO ); static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); + /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const; protected: LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object); void lazyAttach(); @@ -795,7 +719,7 @@ public: S32 getAttachmentCount(); // Warning: order(N) not order(1) // currently used only by -self typedef std::map attachment_map_t; attachment_map_t mAttachmentPoints; - std::vector > mPendingAttachment; + std::vector > mPendingAttachment; //-------------------------------------------------------------------- // HUD functions @@ -900,15 +824,6 @@ private: BOOL mTurning; // controls hysteresis on avatar rotation F32 mSpeed; // misc. animation repeated state - //-------------------------------------------------------------------- - // Collision volumes - //-------------------------------------------------------------------- -public: - S32 mNumCollisionVolumes; - LLViewerJointCollisionVolume* mCollisionVolumes; -protected: - BOOL allocateCollisionVolumes(U32 num); - //-------------------------------------------------------------------- // Dimensions //-------------------------------------------------------------------- @@ -918,7 +833,6 @@ public: void resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm); void slamPosition(); // Slam position to transmitted position (for teleport); protected: - void computeBodySize(); //-------------------------------------------------------------------- // Material being stepped on @@ -962,9 +876,9 @@ private: **/ public: - virtual BOOL setParent(LLViewerObject* parent); - virtual void addChild(LLViewerObject *childp); - virtual void removeChild(LLViewerObject *childp); + /*virtual*/ BOOL setParent(LLViewerObject* parent); + /*virtual*/ void addChild(LLViewerObject *childp); + /*virtual*/ void removeChild(LLViewerObject *childp); //-------------------------------------------------------------------- // Sitting @@ -988,7 +902,7 @@ private: **/ public: - std::string getFullname() const; // Returns "FirstName LastName" + /*virtual*/ std::string getFullname() const; // Returns "FirstName LastName" std::string avString() const; // Frequently used string in log messages "Avatar '* labels); @@ -1002,6 +916,7 @@ private: bool mNameAppearance; bool mNameFriend; bool mNameCloud; + bool mNameLangolier; F32 mNameAlpha; BOOL mRenderGroupTitles; @@ -1070,7 +985,10 @@ private: // General //-------------------------------------------------------------------- public: - static void dumpArchetypeXML(void*); + void dumpArchetypeXML(const std::string& prefix, bool group_by_wearables = false); + void dumpAppearanceMsgParams( const std::string& dump_prefix, + const std::vector& paramsForDump, + const LLTEContents& tec); static void dumpBakedStatus(); const std::string getBakedStatusForPrintout() const; void dumpAvatarTEs(const std::string& context) const; @@ -1087,6 +1005,7 @@ private: F32 mMaxPixelArea; F32 mAdjustedPixelArea; std::string mDebugText; + std::string mBakedTextureDebugText; //-------------------------------------------------------------------- @@ -1111,105 +1030,6 @@ protected: protected: // Shared with LLVOAvatarSelf - struct LLVOAvatarXmlInfo - { - LLVOAvatarXmlInfo(); - ~LLVOAvatarXmlInfo(); - - BOOL parseXmlSkeletonNode(LLXmlTreeNode* root); - BOOL parseXmlMeshNodes(LLXmlTreeNode* root); - BOOL parseXmlColorNodes(LLXmlTreeNode* root); - BOOL parseXmlLayerNodes(LLXmlTreeNode* root); - BOOL parseXmlDriverNodes(LLXmlTreeNode* root); - BOOL parseXmlMorphNodes(LLXmlTreeNode* root); - - struct LLVOAvatarMeshInfo - { - typedef std::pair morph_info_pair_t; - typedef std::vector morph_info_list_t; - - LLVOAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {} - ~LLVOAvatarMeshInfo() - { - morph_info_list_t::iterator iter; - for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++) - { - delete iter->first; - } - mPolyMorphTargetInfoList.clear(); - } - - std::string mType; - S32 mLOD; - std::string mMeshFileName; - std::string mReferenceMeshName; - F32 mMinPixelArea; - morph_info_list_t mPolyMorphTargetInfoList; - }; - typedef std::vector mesh_info_list_t; - mesh_info_list_t mMeshInfoList; - - typedef std::vector skeletal_distortion_info_list_t; - skeletal_distortion_info_list_t mSkeletalDistortionInfoList; - - struct LLVOAvatarAttachmentInfo - { - LLVOAvatarAttachmentInfo() - : mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE), - mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {} - std::string mName; - std::string mJointName; - LLVector3 mPosition; - LLVector3 mRotationEuler; - S32 mGroup; - S32 mAttachmentID; - S32 mPieMenuSlice; - BOOL mVisibleFirstPerson; - BOOL mIsHUDAttachment; - BOOL mHasPosition; - BOOL mHasRotation; - }; - typedef std::vector attachment_info_list_t; - attachment_info_list_t mAttachmentInfoList; - - LLTexGlobalColorInfo *mTexSkinColorInfo; - LLTexGlobalColorInfo *mTexHairColorInfo; - LLTexGlobalColorInfo *mTexEyeColorInfo; - - typedef std::vector layer_info_list_t; - layer_info_list_t mLayerInfoList; - - typedef std::vector driver_info_list_t; - driver_info_list_t mDriverInfoList; - - struct LLVOAvatarMorphInfo - { - LLVOAvatarMorphInfo() - : mInvert(FALSE) {} - std::string mName; - std::string mRegion; - std::string mLayer; - BOOL mInvert; - }; - - typedef std::vector morph_info_list_t; - morph_info_list_t mMorphMaskInfoList; - }; - - struct LLMaskedMorph - { - LLMaskedMorph(LLPolyMorphTarget *morph_target, BOOL invert, std::string layer) : - mMorphTarget(morph_target), - mInvert(invert), - mLayer(layer) - { - morph_target->addPendingMorphMask(); - } - - LLPolyMorphTarget *mMorphTarget; - BOOL mInvert; - std::string mLayer; - }; /** Support classes ** ** @@ -1243,4 +1063,4 @@ extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL; extern const U32 EMERALD_BOOB_SIZE_PARAM; //"Breast Size" extern const U32 EMERALD_BOOB_GRAVITY_PARAM; //"Breast_Gravity" -#endif // LL_VO_AVATAR_H +#endif // LL_VOAVATAR_H diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 2d8010c70..78daf033c 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -56,6 +56,8 @@ #include "llviewerobjectlist.h" #include "llviewerstats.h" #include "llviewerregion.h" +#include "llviewertexlayer.h" +#include "llviewerwearable.h" #include "llappearancemgr.h" #include "llmeshrepository.h" #include "llvovolume.h" @@ -80,7 +82,7 @@ BOOL isAgentAvatarValid() (!gAgentAvatarp->isDead())); } -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines; /********************************************************************************* ** ** @@ -161,7 +163,7 @@ void LLVOAvatarSelf::initInstance() llinfos << "Self avatar object created. Starting timer." << llendl; mDebugSelfLoadTimer.reset(); // clear all times to -1 for debugging - for (U32 i =0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i) + for (U32 i =0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i) { for (U32 j = 0; j <= MAX_DISCARD_LEVEL; ++j) { @@ -169,7 +171,7 @@ void LLVOAvatarSelf::initInstance() } } - for (U32 i =0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i) + for (U32 i =0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i) { mDebugBakedTextureTimes[i][0] = -1.0f; mDebugBakedTextureTimes[i][1] = -1.0f; @@ -226,13 +228,11 @@ BOOL LLVOAvatarSelf::loadAvatarSelf() llwarns << "avatar file: buildSkeleton() failed" << llendl; return FALSE; } - // TODO: make loadLayersets() called only by self. - //success &= loadLayersets(); return success; } -BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info) +BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info) { LLMemType mt(LLMemType::MTYPE_AVATAR); @@ -487,70 +487,6 @@ LLVOAvatarSelf::~LLVOAvatarSelf() ** ** *********************************************************************************/ -//virtual -BOOL LLVOAvatarSelf::loadLayersets() -{ - BOOL success = TRUE; - for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator iter = sAvatarXmlInfo->mLayerInfoList.begin(); - iter != sAvatarXmlInfo->mLayerInfoList.end(); - ++iter) - { - // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such. - const LLTexLayerSetInfo *info = *iter; - LLTexLayerSet* layer_set = new LLTexLayerSet( this ); - - if (!layer_set->setInfo(info)) - { - stop_glerror(); - delete layer_set; - llwarns << "avatar file: layer_set->parseData() failed" << llendl; - return FALSE; - } - - // scan baked textures and associate the layerset with the appropriate one - EBakedTextureIndex baked_index = BAKED_NUM_INDICES; - for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); - ++baked_iter) - { - const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; - if (layer_set->isBodyRegion(baked_dict->mName)) - { - baked_index = baked_iter->first; - // ensure both structures are aware of each other - mBakedTextureDatas[baked_index].mTexLayerSet = layer_set; - layer_set->setBakedTexIndex(baked_index); - break; - } - } - // if no baked texture was found, warn and cleanup - if (baked_index == BAKED_NUM_INDICES) - { - llwarns << " has invalid body_region attribute" << llendl; - delete layer_set; - return FALSE; - } - - // scan morph masks and let any affected layers know they have an associated morph - for (LLVOAvatar::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin(); - morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end(); - ++morph_iter) - { - LLMaskedMorph *morph = *morph_iter; - LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer); - if (layer) - { - layer->setHasMorph(TRUE); - } - else - { - llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl; - success = FALSE; - } - } - } - return success; -} // virtual BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent) { @@ -570,25 +506,20 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent) } // virtual -BOOL LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +BOOL LLVOAvatarSelf::isValid() const { - if (!isAgentAvatarValid()) + return ((getRegion() != NULL) && !isDead()); +} + +// virtual +void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +{ + if (isValid()) { - return TRUE; + LLVOAvatar::idleUpdate(agent, world, time); + if(!gNoRender) + idleUpdateTractorBeam(); } - /*if(!gNoRender) - { - //Emerald performs some force-bakes stuff here. Added it in because we noticed slow responses with client tag ident. -HgB - for(U8 i=0;iforceActive(); - } - }*/ - LLVOAvatar::idleUpdate(agent,world,time); - if(!gNoRender) - idleUpdateTractorBeam(); - return TRUE; } // virtual @@ -601,13 +532,8 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) } return LLVOAvatar::getJoint(name); } -//virtual -void LLVOAvatarSelf::resetJointPositions( void ) -{ - return LLVOAvatar::resetJointPositions(); -} // virtual -BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake ) +BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake ) { if (!which_param) { @@ -635,20 +561,28 @@ BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight, BOOL upload_bak return setParamWeight(param,weight,upload_bake); } -BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake ) +BOOL LLVOAvatarSelf::setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake ) { if (!param) { return FALSE; } +#if 0 + // FIXME DRANO - kludgy way to avoid overwriting avatar state from wearables. + if (isUsingServerBakes() && !isUsingLocalAppearance()) + { + return FALSE; + } +#endif + if (param->getCrossWearable()) { LLWearableType::EType type = (LLWearableType::EType)param->getWearableType(); U32 size = gAgentWearables.getWearableCount(type); for (U32 count = 0; count < size; ++count) { - LLWearable *wearable = gAgentWearables.getWearable(type,count); + LLViewerWearable *wearable = gAgentWearables.getViewerWearable(type,count); if (wearable) { wearable->setVisualParamWeight(param->getID(), weight, upload_bake); @@ -682,7 +616,7 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation() LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type); if (wearable) { - wearable->writeToAvatar(); + wearable->writeToAvatar(this); } } @@ -725,7 +659,10 @@ U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys, { U32 retval = LLVOAvatar::processUpdateMessage(mesgsys,user_data,block_num,update_type,dp); - if (mInitialBakesLoaded == false && retval == 0x0) + // FIXME DRANO - skipping in the case of !mFirstAppearanceMessageReceived prevents us from trying to + // load textures before we know where they come from (ie, from baking service or not); + // unknown impact on performance. + if (mInitialBakesLoaded == false && retval == 0x0 && mFirstAppearanceMessageReceived) { // call update textures to force the images to be created updateMeshTextures(); @@ -736,7 +673,7 @@ U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys, // need to trigger a few operations to get the avatar to use the new bakes for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - const LLVOAvatarDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex; + const LLAvatarAppearanceDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex; LLUUID texture_id = getTEImage(te)->getID(); setNewBakedTexture(te, texture_id); mInitialBakeIDs[i] = texture_id; @@ -799,11 +736,15 @@ void LLVOAvatarSelf::removeMissingBakedTextures() { for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE); - invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, FALSE); + LLViewerTexLayerSet *layerset = getTexLayerSet(i); + layerset->setUpdatesEnabled(TRUE); + invalidateComposite(layerset, FALSE); } updateMeshTextures(); - requestLayerSetUploads(); + if (getRegion() && !getRegion()->getCentralBakeVersion()) + { + requestLayerSetUploads(); + } } } @@ -881,7 +822,7 @@ void LLVOAvatarSelf::idleUpdateTractorBeam() } // This is only done for yourself (maybe it should be in the agent?) - if (!needsRenderBeam() || !mIsBuilt) + if (!needsRenderBeam() || !isBuilt()) { mBeam = NULL; } @@ -995,11 +936,6 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode) } } -/*virtual*/ BOOL LLVOAvatarSelf::isWearingWearableType(LLWearableType::EType type ) const -{ - return gAgentWearables.getWearableCount(type) > 0; -} - //----------------------------------------------------------------------------- // updatedWearable( LLWearableType::EType type ) // forces an update to any baked textures relevant to type. @@ -1007,26 +943,27 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode) //----------------------------------------------------------------------------- void LLVOAvatarSelf::wearableUpdated( LLWearableType::EType type, BOOL upload_result ) { - for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin(); + baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end(); ++baked_iter) { - const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; - const LLVOAvatarDefines::EBakedTextureIndex index = baked_iter->first; + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; + const LLAvatarAppearanceDefines::EBakedTextureIndex index = baked_iter->first; if (baked_dict) { - for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin(); + for (LLAvatarAppearanceDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin(); type_iter != baked_dict->mWearables.end(); ++type_iter) { const LLWearableType::EType comp_type = *type_iter; if (comp_type == type) { - if (mBakedTextureDatas[index].mTexLayerSet) + LLViewerTexLayerSet *layerset = getLayerSet(index); + if (layerset) { - mBakedTextureDatas[index].mTexLayerSet->setUpdatesEnabled(true); - invalidateComposite(mBakedTextureDatas[index].mTexLayerSet, upload_result); + layerset->setUpdatesEnabled(true); + invalidateComposite(layerset, upload_result); } break; } @@ -1240,7 +1177,7 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) // Make sure the inventory is in sync with the avatar. // Update COF contents, don't trigger appearance update. - if (!isAgentAvatarValid()) + if (!isValid()) { llinfos << "removeItemLinks skipped, avatar is under destruction" << llendl; } @@ -1289,7 +1226,7 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id) const LLViewerObject *attached_obj = gAgentAvatarp->getWornAttachment(item_id); if (!attached_obj) { - LLAppearanceMgr::instance().removeCOFItemLinks(item_id, false); + LLAppearanceMgr::instance().removeCOFItemLinks(item_id); } } return TRUE; @@ -1297,9 +1234,9 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id) return FALSE; } -U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const +U32 LLVOAvatarSelf::getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const { - LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i); + LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i); return gAgentWearables.getWearableCount(type); } @@ -1330,11 +1267,8 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr discard_level < local_tex_obj->getDiscard()) { local_tex_obj->setDiscard(discard_level); - if (isUsingBakedTextures()) - { - requestLayerSetUpdate(index); - } - else + requestLayerSetUpdate(index); + if (isEditingAppearance()) { LLVisualParamHint::requestHintUpdates(); } @@ -1368,11 +1302,11 @@ BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex { return FALSE; } - *tex_pp = local_tex_obj->getImage(); + *tex_pp = dynamic_cast (local_tex_obj->getImage()); return TRUE; } -LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const +LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const { if (!isIndexLocalTexture(type)) { @@ -1388,7 +1322,7 @@ LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLVOAvatarDefines::ETe { return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); } - return local_tex_obj->getImage(); + return dynamic_cast (local_tex_obj->getImage()); } const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) const @@ -1409,29 +1343,30 @@ const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) c // Returns true if at least the lowest quality discard level exists for every texture // in the layerset. //----------------------------------------------------------------------------- -BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const +BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* layerset) const { /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet) return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */ - for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin(); + baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end(); ++baked_iter) { const EBakedTextureIndex baked_index = baked_iter->first; if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet) { - BOOL ret = true; - const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; + bool ret = true; + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); local_tex_iter != baked_dict->mLocalTextures.end(); ++local_tex_iter) { const ETextureIndex tex_index = *local_tex_iter; - const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index); + const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index); const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) { - ret &= (getLocalDiscardLevel(tex_index, wearable_index) >= 0); + bool tex_avail = (getLocalDiscardLevel(tex_index, wearable_index) >= 0); + ret &= tex_avail; } } return ret; @@ -1447,7 +1382,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset) // Returns true if the highest quality discard level exists for every texture // in the layerset. //----------------------------------------------------------------------------- -BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) const +BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset) const { const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); // const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels. @@ -1456,13 +1391,13 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons { if (layerset == mBakedTextureDatas[i].mTexLayerSet) { - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); local_tex_iter != baked_dict->mLocalTextures.end(); ++local_tex_iter) { const ETextureIndex tex_index = *local_tex_iter; - const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index); + const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index); const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) { @@ -1486,13 +1421,13 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); local_tex_iter != baked_dict->mLocalTextures.end(); ++local_tex_iter) { const ETextureIndex tex_index = *local_tex_iter; - const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index); + const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index); const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) { @@ -1506,22 +1441,22 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const return TRUE; } -BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const +BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLAvatarAppearanceDefines::EBakedTextureIndex index) const { - const LLTexLayerSet *layerset = mBakedTextureDatas[index].mTexLayerSet; + const LLViewerTexLayerSet *layerset = getLayerSet(index); if (!layerset) return FALSE; - const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite(); + const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite(); if (!layerset_buffer) return FALSE; return !layerset_buffer->uploadNeeded(); } -BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const +BOOL LLVOAvatarSelf::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const { LLUUID id; BOOL isDefined = TRUE; if (isIndexLocalTexture(type)) { - const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(type); + const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(type); const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); if (index >= wearable_count) { @@ -1548,7 +1483,7 @@ BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 } //virtual -BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index) const +BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const { if (isIndexBakedTexture(type)) { @@ -1561,7 +1496,7 @@ BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 } //virtual -BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const +BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const { if (isIndexBakedTexture(type)) { @@ -1584,13 +1519,14 @@ void LLVOAvatarSelf::requestLayerSetUploads() } } -void LLVOAvatarSelf::requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i) +void LLVOAvatarSelf::requestLayerSetUpload(LLAvatarAppearanceDefines::EBakedTextureIndex i) { ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex; const BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index)); - if (!layer_baked && mBakedTextureDatas[i].mTexLayerSet) + LLViewerTexLayerSet *layerset = getLayerSet(i); + if (!layer_baked && layerset) { - mBakedTextureDatas[i].mTexLayerSet->requestUpload(); + layerset->requestUpload(); } } @@ -1604,8 +1540,8 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const { for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - LLTexLayerSet* layerset = mBakedTextureDatas[i].mTexLayerSet; - if (layerset && layerset->getComposite() && layerset->getComposite()->uploadPending()) + LLViewerTexLayerSet* layerset = getTexLayerSet(i); + if (layerset && layerset->getViewerComposite() && layerset->getViewerComposite()->uploadPending()) { return true; } @@ -1615,22 +1551,23 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result ) { - if( !layerset || !layerset->getUpdatesEnabled() ) + LLViewerTexLayerSet *layer_set = dynamic_cast(layerset); + if( !layer_set || !layer_set->getUpdatesEnabled() ) { return; } // llinfos << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegionName() << llendl; - layerset->requestUpdate(); - layerset->invalidateMorphMasks(); + layer_set->requestUpdate(); + layer_set->invalidateMorphMasks(); - if( upload_result ) + if( upload_result && (getRegion() && !getRegion()->getCentralBakeVersion())) { llassert(isSelf()); - ETextureIndex baked_te = getBakedTE( layerset ); + ETextureIndex baked_te = getBakedTE( layer_set ); setTEImage( baked_te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR) ); - layerset->requestUpload(); + layer_set->requestUpload(); updateMeshTextures(); } } @@ -1639,7 +1576,8 @@ void LLVOAvatarSelf::invalidateAll() { for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, TRUE); + LLViewerTexLayerSet *layerset = getTexLayerSet(i); + invalidateComposite(layerset, TRUE); } //mDebugSelfLoadTimer.reset(); } @@ -1657,17 +1595,19 @@ void LLVOAvatarSelf::setCompositeUpdatesEnabled( bool b ) void LLVOAvatarSelf::setCompositeUpdatesEnabled(U32 index, bool b) { - if (mBakedTextureDatas[index].mTexLayerSet ) + LLViewerTexLayerSet *layerset = getTexLayerSet(index); + if (layerset ) { - mBakedTextureDatas[index].mTexLayerSet->setUpdatesEnabled( b ); + layerset->setUpdatesEnabled( b ); } } bool LLVOAvatarSelf::isCompositeUpdateEnabled(U32 index) { - if (mBakedTextureDatas[index].mTexLayerSet) + LLViewerTexLayerSet *layerset = getTexLayerSet(index); + if (layerset) { - return mBakedTextureDatas[index].mTexLayerSet->getUpdatesEnabled(); + return layerset->getUpdatesEnabled(); } return false; } @@ -1678,9 +1618,10 @@ void LLVOAvatarSelf::setupComposites() { ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex; BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index)); - if (mBakedTextureDatas[i].mTexLayerSet) + LLViewerTexLayerSet *layerset = getTexLayerSet(i); + if (layerset) { - mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(!layer_baked); + layerset->setUpdatesEnabled(!layer_baked); } } } @@ -1689,10 +1630,11 @@ void LLVOAvatarSelf::updateComposites() { for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - if (mBakedTextureDatas[i].mTexLayerSet + LLViewerTexLayerSet *layerset = getTexLayerSet(i); + if (layerset && ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT))) { - mBakedTextureDatas[i].mTexLayerSet->updateComposite(); + layerset->updateComposite(); } } } @@ -1705,11 +1647,12 @@ S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 wearable_index) const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, wearable_index); if (local_tex_obj) { + const LLViewerFetchedTexture* image = dynamic_cast( local_tex_obj->getImage() ); if (type >= 0 && local_tex_obj->getID() != IMG_DEFAULT_AVATAR - && !local_tex_obj->getImage()->isMissingAsset()) + && !image->isMissingAsset()) { - return local_tex_obj->getImage()->getDiscardLevel(); + return image->getDiscardLevel(); } else { @@ -1734,7 +1677,7 @@ void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num); if (local_tex_obj) { - const LLViewerFetchedTexture* image_gl = local_tex_obj->getImage(); + const LLViewerFetchedTexture* image_gl = dynamic_cast( local_tex_obj->getImage() ); if (image_gl) { S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); @@ -1769,8 +1712,8 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te llerrs << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << llendl; return; } - LLWearableType::EType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType(type); - if (!gAgentWearables.getWearable(wearable_type,index)) + LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(type); + if (!gAgentWearables.getViewerWearable(wearable_type,index)) { // no wearable is loaded, cannot set the texture. return; @@ -1783,10 +1726,10 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te return; } - LLTexLayerSet *layer_set = getLayerSet(type); + LLViewerTexLayerSet *layer_set = getLayerSet(type); if (layer_set) { - layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getWearable(wearable_type,index)); + layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getViewerWearable(wearable_type,index)); } } @@ -1805,16 +1748,13 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te { local_tex_obj->setDiscard(tex_discard); if (isSelf()) - { - if (gAgentAvatarp->isUsingBakedTextures()) { requestLayerSetUpdate(type); + if (isEditingAppearance()) + { + LLVisualParamHint::requestHintUpdates(); + } } - else - { - LLVisualParamHint::requestHintUpdates(); - } - } } else { @@ -1828,8 +1768,9 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te local_tex_obj->setID(tex->getID()); setBakedReady(type,baked_version_ready,index); } + //virtual -void LLVOAvatarSelf::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index) +void LLVOAvatarSelf::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index) { if (!isIndexLocalTexture(type)) return; LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index); @@ -1848,16 +1789,16 @@ void LLVOAvatarSelf::dumpLocalTextures() const /* ETextureIndex baked_equiv[] = { TEX_UPPER_BAKED, if (isTextureDefined(baked_equiv[i])) */ - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); ++iter) { - const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture) continue; const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex; + const ETextureIndex baked_equiv = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex; const std::string &name = texture_dict->mName; const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0); @@ -1880,7 +1821,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const } else { - const LLViewerFetchedTexture* image = local_tex_obj->getImage(); + const LLViewerFetchedTexture* image = dynamic_cast( local_tex_obj->getImage() ); llinfos << "LocTex " << name << ": " << "Discard " << image->getDiscardLevel() << ", " @@ -1975,14 +1916,14 @@ BOOL LLVOAvatarSelf::getIsCloud() const if (!mPreviousFullyLoaded) { - if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet) && + if (!isLocalTextureDataAvailable(getLayerSet(BAKED_LOWER)) && (!isTextureDefined(TEX_LOWER_BAKED, 0))) { lldebugs << "Lower textures not baked" << llendl; return TRUE; } - if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_UPPER].mTexLayerSet) && + if (!isLocalTextureDataAvailable(getLayerSet(BAKED_UPPER)) && (!isTextureDefined(TEX_UPPER_BAKED, 0))) { lldebugs << "Upper textures not baked" << llendl; @@ -2053,7 +1994,7 @@ void LLVOAvatarSelf::debugBakedTextureUpload(EBakedTextureIndex index, BOOL fini mDebugBakedTextureTimes[index][done] = mDebugSelfLoadTimer.getElapsedTimeF32(); } -const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const +const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const { std::string text=""; @@ -2061,21 +2002,21 @@ const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLTexLayer /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet) return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */ - for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); + for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin(); + baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end(); ++baked_iter) { const EBakedTextureIndex baked_index = baked_iter->first; if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet) { - const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; text += llformat("%d-%s ( ",baked_index, baked_dict->mName.c_str()); for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); local_tex_iter != baked_dict->mLocalTextures.end(); ++local_tex_iter) { const ETextureIndex tex_index = *local_tex_iter; - const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index); + const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index); const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); if (wearable_count > 0) { @@ -2102,14 +2043,14 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); BOOL is_texture_final = TRUE; for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); local_tex_iter != baked_dict->mLocalTextures.end(); ++local_tex_iter) { const ETextureIndex tex_index = *local_tex_iter; - const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index); + const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index); const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) { @@ -2125,7 +2066,7 @@ const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) c { if (canGrabBakedTexture(baked_index)) { - ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index); + ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index); if (tex_index == TEX_NUM_INDICES) { return LLUUID::null; @@ -2137,7 +2078,7 @@ const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) c BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const { - ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index); + ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index); if (tex_index == TEX_NUM_INDICES) { return FALSE; @@ -2156,19 +2097,19 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const // baked texture. We don't want people copying people's // work via baked textures. - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index); + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index); for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin(); iter != baked_dict->mLocalTextures.end(); ++iter) { const ETextureIndex t_index = (*iter); - LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(t_index); + LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(t_index); U32 count = gAgentWearables.getWearableCount(wearable_type); lldebugs << "Checking index " << (U32) t_index << " count: " << count << llendl; for (U32 wearable_index = 0; wearable_index < count; ++wearable_index) { - LLWearable *wearable = gAgentWearables.getWearable(wearable_type, wearable_index); + LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, wearable_index); if (wearable) { const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index); @@ -2214,36 +2155,36 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe { if (!isIndexLocalTexture(type)) return; - if (!covered_by_baked) + if (getLocalTextureID(type, index) != IMG_DEFAULT_AVATAR && imagep->getDiscardLevel() != 0) { - if (getLocalTextureID(type, index) != IMG_DEFAULT_AVATAR && imagep->getDiscardLevel() != 0) - { - F32 desired_pixels; - desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); - imagep->setBoostLevel(getAvatarBoostLevel()); + F32 desired_pixels; + desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); - imagep->resetTextureStats(); - imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); - imagep->addTextureStats( desired_pixels / texel_area_ratio ); - imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ; - imagep->forceUpdateBindStats() ; - if (imagep->getDiscardLevel() < 0) - { - mHasGrey = TRUE; // for statistics gathering - } - } - else + if (isUsingLocalAppearance()) + { + imagep->setBoostLevel(getAvatarBoostLevel()); + imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ; + } + imagep->resetTextureStats(); + imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); + imagep->addTextureStats( desired_pixels / texel_area_ratio ); + imagep->forceUpdateBindStats() ; + if (imagep->getDiscardLevel() < 0) { - // texture asset is missing mHasGrey = TRUE; // for statistics gathering } } + else + { + // texture asset is missing + mHasGrey = TRUE; // for statistics gathering + } } -LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 wearable_index) const +LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 wearable_index) const { - LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i); - LLWearable* wearable = gAgentWearables.getWearable(type, wearable_index); + LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i); + LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index); if (wearable) { return wearable->getLocalTextureObject(i); @@ -2256,7 +2197,7 @@ LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::E // getBakedTE() // Used by the LayerSet. (Layer sets don't in general know what textures depend on them.) //----------------------------------------------------------------------------- -ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const +ETextureIndex LLVOAvatarSelf::getBakedTE( const LLViewerTexLayerSet* layerset ) const { for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { @@ -2270,9 +2211,9 @@ ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const } -void LLVOAvatarSelf::setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid) +void LLVOAvatarSelf::setNewBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex i, const LLUUID &uuid) { - ETextureIndex index = LLVOAvatarDictionary::bakedToLocalTextureIndex(i); + ETextureIndex index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(i); setNewBakedTexture(index, uuid); } @@ -2294,7 +2235,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) /* switch(te) case TEX_HEAD_BAKED: llinfos << "New baked texture: HEAD" << llendl; */ - const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(te); + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(te); if (texture_dict->mIsBakedTexture) { debugBakedTextureUpload(texture_dict->mBakedTextureIndex, TRUE); // FALSE for start of upload, TRUE for finish. @@ -2319,11 +2260,25 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) if (isAllLocalTextureDataFinal()) { LLNotificationsUtil::add("AvatarRezSelfBakedDoneNotification",args); + LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32() + << " Notification " << "AvatarRezSelfBakedDoneNotification" + << llendl; } else { args["STATUS"] = debugDumpAllLocalTextureDataInfo(); LLNotificationsUtil::add("AvatarRezSelfBakedUpdateNotification",args); + LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32() + << " Notification " << "AvatarRezSelfBakedUpdateNotification" + << llendl; } } @@ -2331,6 +2286,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) } } +// FIXME: This is not called consistently. Something may be broken. void LLVOAvatarSelf::outputRezDiagnostics() const { if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) @@ -2339,12 +2295,12 @@ void LLVOAvatarSelf::outputRezDiagnostics() const } const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32(); - llinfos << "REZTIME: Myself rez stats:" << llendl; - llinfos << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl; - llinfos << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl; - llinfos << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl; - llinfos << "\t Load time for each texture: " << llendl; - for (U32 i = 0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i) + LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl; + LL_DEBUGS("Avatar") << "\t Load time for each texture: " << llendl; + for (U32 i = 0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i) { std::stringstream out; out << "\t\t (" << i << ") "; @@ -2367,32 +2323,35 @@ void LLVOAvatarSelf::outputRezDiagnostics() const // Don't print out non-existent textures. if (j != 0) - llinfos << out.str() << llendl; + { + LL_DEBUGS("Avatar") << out.str() << LL_ENDL; + } } - llinfos << "\t Time points for each upload (start / finish)" << llendl; - for (U32 i = 0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i) + LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << llendl; + for (U32 i = 0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i) { - llinfos << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl; + LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl; } - for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); + for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin(); + baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end(); ++baked_iter) { - const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first; - const LLTexLayerSet *layerset = debugGetLayerSet(baked_index); + const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first; + const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index); if (!layerset) continue; - const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite(); + const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite(); if (!layerset_buffer) continue; - llinfos << layerset_buffer->dumpTextureInfo() << llendl; + LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl; } } void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const { - LL_DEBUGS("Avatar Rez") + LL_INFOS("Avatar") + << avString() << llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32()) - << llendl; + << LL_ENDL; } void LLVOAvatarSelf::reportAvatarRezTime() const @@ -2414,7 +2373,8 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid mHeadLayerSet->cancelUpload(); */ for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet) + LLViewerTexLayerSet *layerset = getTexLayerSet(i); + if ( mBakedTextureDatas[i].mTextureIndex == te && layerset) { if (mInitialBakeIDs[i] != LLUUID::null) { @@ -2428,7 +2388,7 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid } mInitialBakeIDs[i] = LLUUID::null; } - mBakedTextureDatas[i].mTexLayerSet->cancelUpload(); + layerset->cancelUpload(); } } } @@ -2447,17 +2407,17 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**) /* ETextureIndex baked_texture_indices[BAKED_NUM_INDICES] = TEX_HEAD_BAKED, TEX_UPPER_BAKED, */ - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); ++iter) { const ETextureIndex index = iter->first; - const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; if (texture_dict->mIsBakedTexture) { if (texture_id == gAgentAvatarp->getTEImage(index)->getID()) { - LLTexLayerSet* layer_set = gAgentAvatarp->getLayerSet(index); + LLViewerTexLayerSet* layer_set = gAgentAvatarp->getLayerSet(index); if (layer_set) { llinfos << "TAT: rebake - matched entry " << (S32)index << llendl; @@ -2481,15 +2441,6 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**) } } -BOOL LLVOAvatarSelf::isUsingBakedTextures() const -{ - // Composite textures are used during appearance mode. - if (gAgentCamera.cameraCustomizeAvatar()) - return FALSE; - - return TRUE; -} - void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug) { @@ -2498,7 +2449,7 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug) for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex; - LLTexLayerSet* layer_set = getLayerSet(baked_index); + LLViewerTexLayerSet* layer_set = getLayerSet(baked_index); if (layer_set) { if (slam_for_debug) @@ -2530,7 +2481,7 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index ) case LOCTEX_UPPER_SHIRT: if( mUpperBodyLayerSet ) mUpperBodyLayerSet->requestUpdate(); */ - const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index); if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture) return; const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; @@ -2540,22 +2491,22 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index ) } } -LLTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const +LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const { - /* switch(index) - case TEX_HEAD_BAKED: - case TEX_HEAD_BODYPAINT: - return mHeadLayerSet; */ - const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); - if (texture_dict->mIsUsedByBakedTexture) - { - const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - return mBakedTextureDatas[baked_index].mTexLayerSet; - } - return NULL; + /* switch(index) + case TEX_HEAD_BAKED: + case TEX_HEAD_BODYPAINT: + return mHeadLayerSet; */ + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index); + if (texture_dict->mIsUsedByBakedTexture) + { + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + return getLayerSet(baked_index); + } + return NULL; } -LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const +LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const { /* switch(index) case TEX_HEAD_BAKED: @@ -2563,26 +2514,59 @@ LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const return mHeadLayerSet; */ if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES) { - return mBakedTextureDatas[baked_index].mTexLayerSet; + return getTexLayerSet(baked_index); } return NULL; } -// static -void LLVOAvatarSelf::onCustomizeStart() -{ - // We're no longer doing any baking or invalidating on entering - // appearance editing mode. Leaving function in place in case - // further changes require us to do something at this point - Nyx -} + // static -void LLVOAvatarSelf::onCustomizeEnd() +void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch) { if (isAgentAvatarValid()) { + gAgentAvatarp->mIsEditingAppearance = true; + gAgentAvatarp->mUseLocalAppearance = true; + + if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) + { + gAgentCamera.changeCameraToCustomizeAvatar(); + } + +#if 0 + gAgentAvatarp->clearVisualParamWeights(); + gAgentAvatarp->idleUpdateAppearanceAnimation(); +#endif + gAgentAvatarp->invalidateAll(); + gAgentAvatarp->updateMeshTextures(); + } +} + +// static +void LLVOAvatarSelf::onCustomizeEnd(bool disable_camera_switch) +{ + + if (isAgentAvatarValid()) + { + gAgentAvatarp->mIsEditingAppearance = false; + if (gAgentAvatarp->getRegion() && !gAgentAvatarp->getRegion()->getCentralBakeVersion()) + { + // FIXME DRANO - move to sendAgentSetAppearance, make conditional on upload complete. + gAgentAvatarp->mUseLocalAppearance = false; + } + + gAgentAvatarp->invalidateAll(); + + if (gAgentCamera.cameraCustomizeAvatar()) //If in customize cam, break out of it, always. + { + gAgentCamera.changeCameraToDefault(); + gAgentCamera.resetView(); + } + + LLAppearanceMgr::instance().updateAppearanceFromCOF(); } } @@ -2595,12 +2579,12 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const { LLUUID texture_id[TEX_NUM_INDICES]; // pack away current TEs to make sure we don't send them out - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); ++iter) { const ETextureIndex index = iter->first; - const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; if (!texture_dict->mIsBakedTexture) { LLTextureEntry* entry = getTE((U8) index); @@ -2615,12 +2599,12 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const bool success = packTEMessage(mesgsys); // unpack TEs to make sure we don't re-trigger a bake - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); ++iter) { const ETextureIndex index = iter->first; - const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; if (!texture_dict->mIsBakedTexture) { LLTextureEntry* entry = getTE((U8) index); @@ -2723,6 +2707,41 @@ void LLVOAvatarSelf::dumpScratchTextureByteCount() llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl; } +void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value); + +void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile) +{ + apr_file_t* file = outfile.getFileHandle(); + if (!file) + { + return; + } + + + apr_file_printf( file, "\n\n" ); + + LLWearableData *wd = getWearableData(); + for (S32 type = 0; type < LLWearableType::WT_COUNT; type++) + { + const std::string& type_name = LLWearableType::getTypeName((LLWearableType::EType)type); + for (U32 j=0; j< wd->getWearableCount((LLWearableType::EType)type); j++) + { + LLViewerWearable *wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)type,j); + apr_file_printf( file, "\n\t \n", + type_name.c_str(), wearable->getName().c_str() ); + LLWearable::visual_param_vec_t v_params; + wearable->getVisualParams(v_params); + for (LLWearable::visual_param_vec_t::iterator it = v_params.begin(); + it != v_params.end(); ++it) + { + LLVisualParam *param = *it; + dump_visual_param(file, param, param->getWeight()); + } + } + } + apr_file_printf( file, "\n\n" ); +} + // static void LLVOAvatarSelf::onChangeSelfInvisible(bool invisible) { diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 0105315ff..1cb09086e 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -49,6 +49,16 @@ class LLVOAvatarSelf : **/ public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVOAvatarSelf(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual ~LLVOAvatarSelf(); virtual void markDead(); @@ -57,9 +67,8 @@ public: protected: /*virtual*/ BOOL loadAvatar(); BOOL loadAvatarSelf(); - BOOL buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info); + BOOL buildSkeletonSelf(const LLAvatarSkeletonInfo *info); BOOL buildMenus(); - /*virtual*/ BOOL loadLayersets(); /** Initialization ** ** @@ -75,7 +84,7 @@ protected: //-------------------------------------------------------------------- public: /*virtual*/ void updateRegion(LLViewerRegion *regionp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); //-------------------------------------------------------------------- // LLCharacter interface and related @@ -85,9 +94,7 @@ public: /*virtual*/ void requestStopMotion(LLMotion* motion); /*virtual*/ LLJoint* getJoint(const std::string &name); - void resetJointPositions( void ); - - /*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE ); + /*virtual*/ BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE ); /*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE ); /*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE ); /*virtual*/ void updateVisualParams(); @@ -101,7 +108,7 @@ public: private: // helper function. Passed in param is assumed to be in avatar's parameter list. - BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE ); + BOOL setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE ); @@ -121,6 +128,7 @@ private: public: /*virtual*/ bool isSelf() const { return true; } + /*virtual*/ BOOL isValid() const; //-------------------------------------------------------------------- // Updates @@ -167,8 +175,8 @@ private: // LLVOAvatar Constants //-------------------------------------------------------------------- public: - /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_SELF; } - /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED_SELF; } + /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLGLTexture::BOOST_AVATAR_SELF; } + /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLGLTexture::BOOST_AVATAR_BAKED_SELF; } /*virtual*/ S32 getTexImageSize() const { return LLVOAvatar::getTexImageSize()*4; } /** Rendering @@ -185,32 +193,32 @@ public: //-------------------------------------------------------------------- public: /*virtual*/ bool hasPendingBakedUploads() const; - S32 getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex type, U32 index) const; + S32 getLocalDiscardLevel(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const; bool areTexturesCurrent() const; - BOOL isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const; - BOOL isLocalTextureDataFinal(const LLTexLayerSet* layerset) const; - BOOL isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const; + BOOL isLocalTextureDataAvailable(const LLViewerTexLayerSet* layerset) const; + BOOL isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset) const; + BOOL isBakedTextureFinal(const LLAvatarAppearanceDefines::EBakedTextureIndex index) const; // If you want to check all textures of a given type, pass gAgentWearables.getWearableCount() for index - /*virtual*/ BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const; - /*virtual*/ BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; - /*virtual*/ BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const; + /*virtual*/ BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const; + /*virtual*/ BOOL isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const; + /*virtual*/ BOOL isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const; //-------------------------------------------------------------------- // Local Textures //-------------------------------------------------------------------- public: - BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const; - LLViewerFetchedTexture* getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const; - const LLUUID& getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index) const; + BOOL getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const; + LLViewerFetchedTexture* getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const; + const LLUUID& getLocalTextureID(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const; void setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index); - /*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index); + /*virtual*/ void setLocalTexture(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index); protected: - /*virtual*/ void setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index); + /*virtual*/ void setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index); void localTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); void getLocalTextureByteCount(S32* gl_byte_count) const; - /*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index); - LLLocalTextureObject* getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 index) const; + /*virtual*/ void addLocalTextureStats(LLAvatarAppearanceDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index); + LLLocalTextureObject* getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 index) const; private: static void onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); @@ -223,13 +231,12 @@ private: // Baked textures //-------------------------------------------------------------------- public: - LLVOAvatarDefines::ETextureIndex getBakedTE(const LLTexLayerSet* layerset ) const; - void setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid); - void setNewBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid); - void setCachedBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid); + LLAvatarAppearanceDefines::ETextureIndex getBakedTE(const LLViewerTexLayerSet* layerset ) const; + void setNewBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex i, const LLUUID &uuid); + void setNewBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i, const LLUUID& uuid); + void setCachedBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i, const LLUUID& uuid); void forceBakeAllTextures(bool slam_for_debug = false); static void processRebakeAvatarTextures(LLMessageSystem* msg, void**); - BOOL isUsingBakedTextures() const; // e.g. false if in appearance edit mode protected: /*virtual*/ void removeMissingBakedTextures(); @@ -238,10 +245,10 @@ protected: //-------------------------------------------------------------------- public: void requestLayerSetUploads(); - void requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i); - void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i); - LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const; - LLTexLayerSet* getLayerSet(LLVOAvatarDefines::EBakedTextureIndex baked_index) const; + void requestLayerSetUpload(LLAvatarAppearanceDefines::EBakedTextureIndex i); + void requestLayerSetUpdate(LLAvatarAppearanceDefines::ETextureIndex i); + LLViewerTexLayerSet* getLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const; + LLViewerTexLayerSet* getLayerSet(LLAvatarAppearanceDefines::ETextureIndex index) const; //-------------------------------------------------------------------- // Composites @@ -255,8 +262,8 @@ public: void setupComposites(); void updateComposites(); - const LLUUID& grabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const; - BOOL canGrabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const; + const LLUUID& grabBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const; + BOOL canGrabBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const; //-------------------------------------------------------------------- @@ -289,10 +296,9 @@ protected: **/ public: - /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type) const; void wearableUpdated(LLWearableType::EType type, BOOL upload_result); protected: - U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const; + U32 getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const; //-------------------------------------------------------------------- // Attachments @@ -332,8 +338,8 @@ private: **/ public: - static void onCustomizeStart(); - static void onCustomizeEnd(); + static void onCustomizeStart(bool disable_camera_switch = false); + static void onCustomizeEnd(bool disable_camera_switch = false); //-------------------------------------------------------------------- // Visibility @@ -357,6 +363,7 @@ public: static void dumpTotalLocalTextureByteCount(); void dumpLocalTextures() const; static void dumpScratchTextureByteCount(); + void dumpWearableInfo(LLAPRFile& outfile); //-------------------------------------------------------------------- // Avatar Rez Metrics @@ -364,32 +371,32 @@ public: public: struct LLAvatarTexData { - LLAvatarTexData(const LLUUID& id, LLVOAvatarDefines::ETextureIndex index) : + LLAvatarTexData(const LLUUID& id, LLAvatarAppearanceDefines::ETextureIndex index) : mAvatarID(id), mIndex(index) {} LLUUID mAvatarID; - LLVOAvatarDefines::ETextureIndex mIndex; + LLAvatarAppearanceDefines::ETextureIndex mIndex; }; void debugWearablesLoaded() { mDebugTimeWearablesLoaded = mDebugSelfLoadTimer.getElapsedTimeF32(); } void debugAvatarVisible() { mDebugTimeAvatarVisible = mDebugSelfLoadTimer.getElapsedTimeF32(); } void outputRezDiagnostics() const; void outputRezTiming(const std::string& msg) const; void reportAvatarRezTime() const; - void debugBakedTextureUpload(LLVOAvatarDefines::EBakedTextureIndex index, BOOL finished); + void debugBakedTextureUpload(LLAvatarAppearanceDefines::EBakedTextureIndex index, BOOL finished); static void debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); BOOL isAllLocalTextureDataFinal() const; - const LLTexLayerSet* debugGetLayerSet(LLVOAvatarDefines::EBakedTextureIndex index) const { return mBakedTextureDatas[index].mTexLayerSet; } - const std::string debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer + const LLViewerTexLayerSet* debugGetLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex index) const { return (LLViewerTexLayerSet*)(mBakedTextureDatas[index].mTexLayerSet); } + const std::string debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer const std::string debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD private: LLFrameTimer mDebugSelfLoadTimer; F32 mDebugTimeWearablesLoaded; F32 mDebugTimeAvatarVisible; - F32 mDebugTextureLoadTimes[LLVOAvatarDefines::TEX_NUM_INDICES][MAX_DISCARD_LEVEL+1]; // load time for each texture at each discard level - F32 mDebugBakedTextureTimes[LLVOAvatarDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture + F32 mDebugTextureLoadTimes[LLAvatarAppearanceDefines::TEX_NUM_INDICES][MAX_DISCARD_LEVEL+1]; // load time for each texture at each discard level + F32 mDebugBakedTextureTimes[LLAvatarAppearanceDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture void debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); /** Diagnostics diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp index b63103acb..59f1b959a 100644 --- a/indra/newview/llvoclouds.cpp +++ b/indra/newview/llvoclouds.cpp @@ -63,7 +63,7 @@ LLVOClouds::LLVOClouds(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mbCanSelect = FALSE; setNumTEs(1); LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(gCloudTextureID); - image->setBoostLevel(LLViewerTexture::BOOST_CLOUDS); + image->setBoostLevel(LLGLTexture::BOOST_CLOUDS); setTEImage(0, image); } @@ -79,11 +79,11 @@ BOOL LLVOClouds::isActive() const } -BOOL LLVOClouds::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOClouds::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS))) { - return TRUE; + return; } // Set dirty flag (so renderer will rebuild primitive) @@ -91,8 +91,6 @@ BOOL LLVOClouds::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } - - return TRUE; } diff --git a/indra/newview/llvoclouds.h b/indra/newview/llvoclouds.h index 685400f32..089f3efc1 100644 --- a/indra/newview/llvoclouds.h +++ b/indra/newview/llvoclouds.h @@ -69,7 +69,7 @@ public: /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area void updateFaceSize(S32 idx) { } - BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual U32 getPartitionType() const; diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 66c40fbb6..4c40dd76a 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -111,7 +111,7 @@ void LLVOGrass::updateSpecies() SpeciesMap::const_iterator it = sSpeciesTable.begin(); mSpecies = (*it).first; } - setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); } @@ -301,17 +301,17 @@ BOOL LLVOGrass::isActive() const return TRUE; } -BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GRASS))) { - return TRUE; + return; } if (!mDrawable) { // So drones work. - return TRUE; + return; } if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass @@ -321,14 +321,14 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) mNumBlades = 0 ; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); } - return TRUE ; + return; } else if(!mNumBlades)//restart grass rendering { mNumBlades = GRASS_MAX_BLADES ; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); - return TRUE ; + return; } if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime())) @@ -336,7 +336,7 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } - return TRUE; + return; } diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index 4dc79c4fd..1e1c97ea5 100644 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -79,7 +79,7 @@ public: void plantBlades(); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index 3300cb697..97b7418b4 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -2,31 +2,25 @@ * @file llvoground.cpp * @brief LLVOGround class implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -55,18 +49,8 @@ LLVOGround::~LLVOGround() { } -BOOL LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GROUND))) - { - return TRUE; - } - - /*if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - }*/ - return TRUE; } diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h index 0ccb0834a..290579b4d 100644 --- a/indra/newview/llvoground.h +++ b/indra/newview/llvoground.h @@ -2,31 +2,25 @@ * @file llvoground.h * @brief LLVOGround class header file * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,7 +41,7 @@ protected: public: LLVOGround(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Graphical stuff for objects - maybe broken out into render class // later? diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 55f4f656b..b0cc19cd7 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -143,8 +143,7 @@ static int scale_speaker_volume(float volume) return scaled_volume; } -class LLViewerVoiceAccountProvisionResponder : - public LLHTTPClient::ResponderWithResult +class LLViewerVoiceAccountProvisionResponder : public LLHTTPClient::ResponderWithResult { public: LLViewerVoiceAccountProvisionResponder(int retries) @@ -152,7 +151,7 @@ public: mRetries = retries; } - virtual void error(U32 status, const std::string& reason) + /*virtual*/ void error(U32 status, const std::string& reason) { if ( mRetries > 0 ) { @@ -167,7 +166,7 @@ public: } } - virtual void result(const LLSD& content) + /*virtual*/ void result(const LLSD& content) { if ( gVoiceClient ) { @@ -191,7 +190,8 @@ public: } } - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return viewerVoiceAccountProvisionResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return viewerVoiceAccountProvisionResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLViewerVoiceAccountProvisionResponder"; } private: int mRetries; @@ -1019,9 +1019,10 @@ class LLVoiceClientCapResponder : public LLHTTPClient::ResponderWithResult public: LLVoiceClientCapResponder(void){}; - virtual void error(U32 status, const std::string& reason); // called with bad status codes - virtual void result(const LLSD& content); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return voiceClientCapResponder_timeout; } + /*virtual*/ void error(U32 status, const std::string& reason); // called with bad status codes + /*virtual*/ void result(const LLSD& content); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return voiceClientCapResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLVoiceClientCapResponder"; } private: }; diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp index 4794cab32..0547b4504 100644 --- a/indra/newview/llvoicevisualizer.cpp +++ b/indra/newview/llvoicevisualizer.cpp @@ -142,7 +142,7 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type ) for (int i=0; isetPositionGroup(pos); } -BOOL LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; } void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent) diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index 4948ddf55..ecf149c67 100644 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -69,7 +69,7 @@ public: LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual F32 getBinRadius(); virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index de657beed..a9280517e 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -384,9 +384,9 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mSun.setIntensity(SUN_INTENSITY); mMoon.setIntensity(0.1f * SUN_INTENSITY); - mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI); + mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLGLTexture::BOOST_UI); mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI); + mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLGLTexture::BOOST_UI); mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1); mBloomTexturep->setNoDelete() ; @@ -478,9 +478,9 @@ void LLVOSky::restoreGL() { mSkyTex[i].restoreGL(); } - mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI); + mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLGLTexture::BOOST_UI); mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI); + mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLGLTexture::BOOST_UI); mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1); mBloomTexturep->setNoDelete() ; @@ -1053,9 +1053,8 @@ void LLVOSky::calcAtmospherics(void) mFadeColor.setAlpha(0); } -BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; } BOOL LLVOSky::updateSky() @@ -1426,6 +1425,7 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons LLStrider normalsp; LLStrider texCoordsp; LLStrider indicesp; + LLStrider colorsp; S32 index_offset; LLFace *facep; @@ -1482,7 +1482,7 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons if (!facep->getVertexBuffer()) { facep->setSize(4, 6); - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); //Singu Note: Using LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK on purpose. buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE); facep->setGeomIndex(0); facep->setIndicesIndex(0); @@ -1492,6 +1492,7 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons llassert(facep->getVertexBuffer()->getNumIndices() == 6); index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp); + facep->getColors(colorsp); if (-1 == index_offset) { @@ -1517,6 +1518,11 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons *indicesp++ = index_offset + 2; *indicesp++ = index_offset + 3; + *(colorsp++) = LLColor4::white; + *(colorsp++) = LLColor4::white; + *(colorsp++) = LLColor4::white; + *(colorsp++) = LLColor4::white; + facep->getVertexBuffer()->flush(); if (is_sun) diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index c669b92d9..2a150eccb 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -2,31 +2,25 @@ * @file llvosky.h * @brief LLVOSky class header file * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -145,7 +139,7 @@ protected: ~LLSkyTex(); - static S32 getResolution() { return sResolution; } + static S32 getResolution() { return sResolution; } static S32 getCurrent() { return sCurrent; } static S32 stepCurrent() { sCurrent++; sCurrent &= 1; return sCurrent; } static S32 getNext() { return ((sCurrent+1) & 1); } @@ -467,7 +461,7 @@ public: void cleanupGL(); void restoreGL(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); BOOL updateSky(); // Graphical stuff for objects - maybe broken out into render class @@ -616,8 +610,8 @@ protected: public: //by bao //fake vertex buffer updating - //to guaranttee at least updating one VBO buffer every frame - //to walk around the bug caused by ATI card --> DEV-3855 + //to guarantee at least updating one VBO buffer every frame + //to work around the bug caused by ATI card --> DEV-3855 // void createDummyVertexBuffer() ; void updateDummyVertexBuffer() ; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index c765371c6..a4d57e2d3 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -331,7 +331,7 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, // Load Species-Specific data // static const S32 MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 32 ; //frames. - mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); mTreeImagep->setMaxVirtualSizeResetInterval(MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); //allow to wait for at most 16 frames to reset virtual size. mBranchLength = sSpeciesTable[mSpecies]->mBranchLength; @@ -354,11 +354,11 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, return retval; } -BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE))) { - return TRUE; + return; } S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; @@ -389,7 +389,7 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) // *TODO: I don't know what's so special about trees // that they don't get REBUILD_POSITION automatically // at a higher level. - const LLVector3 &this_position = getPositionAgent(); + const LLVector3 &this_position = getPositionRegion(); if (this_position != mLastPosition) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); @@ -408,8 +408,6 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } mTrunkLOD = trunk_LOD; - - return TRUE; } const F32 TREE_BLEND_MIN = 1.f; @@ -858,10 +856,10 @@ void LLVOTree::updateMesh() LLMatrix4 matrix; // Translate to tree base HACK - adjustment in Z plants tree underground - const LLVector3 &pos_agent = getPositionAgent(); + const LLVector3 &pos_region = getPositionRegion(); //gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); LLMatrix4 trans_mat; - trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); + trans_mat.setTranslation(pos_region.mV[VX], pos_region.mV[VY], pos_region.mV[VZ] - 0.1f); trans_mat *= matrix; // Rotate to tree position and bend for current trunk/wind diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index c1c94563b..f90503030 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -65,7 +65,7 @@ public: void **user_data, U32 block_num, const EObjectUpdateType update_type, LLDataPacker *dp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Graphical stuff for objects - maybe broken out into render class later? /*virtual*/ void render(LLAgent &agent); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c7a7c44b0..bd3fb344a 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -185,7 +185,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, { if (!mTextureAnimp) { - mTextureAnimp = new LLViewerTextureAnim(); + mTextureAnimp = new LLViewerTextureAnim(this); } else { @@ -274,7 +274,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, { if (!mTextureAnimp) { - mTextureAnimp = new LLViewerTextureAnim(); + mTextureAnimp = new LLViewerTextureAnim(this); } else { @@ -317,157 +317,118 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, void LLVOVolume::animateTextures() { - F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; - S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); - - if (result) + if (!mDead) { - if (!mTexAnimMode) + F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; + S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); + + if (result) { - mFaceMappingChanged = TRUE; - gPipeline.markTextured(mDrawable); - } - mTexAnimMode = result | mTextureAnimp->mMode; + if (!mTexAnimMode) + { + mFaceMappingChanged = TRUE; + gPipeline.markTextured(mDrawable); + } + mTexAnimMode = result | mTextureAnimp->mMode; - S32 start=0, end=mDrawable->getNumFaces()-1; - if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) - { - start = end = mTextureAnimp->mFace; - } + S32 start=0, end=mDrawable->getNumFaces()-1; + if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) + { + start = end = mTextureAnimp->mFace; + } - for (S32 i = start; i <= end; i++) - { - LLFace* facep = mDrawable->getFace(i); - if (!facep) continue; - if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; + for (S32 i = start; i <= end; i++) + { + LLFace* facep = mDrawable->getFace(i); + if (!facep) continue; + if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; - const LLTextureEntry* te = facep->getTextureEntry(); + const LLTextureEntry* te = facep->getTextureEntry(); - if (!te) - { - continue; - } + if (!te) + { + continue; + } - if (!(result & LLViewerTextureAnim::ROTATE)) - { - te->getRotation(&rot); - } - if (!(result & LLViewerTextureAnim::TRANSLATE)) - { - te->getOffset(&off_s,&off_t); - } - if (!(result & LLViewerTextureAnim::SCALE)) - { - te->getScale(&scale_s, &scale_t); - } + if (!(result & LLViewerTextureAnim::ROTATE)) + { + te->getRotation(&rot); + } + if (!(result & LLViewerTextureAnim::TRANSLATE)) + { + te->getOffset(&off_s,&off_t); + } + if (!(result & LLViewerTextureAnim::SCALE)) + { + te->getScale(&scale_s, &scale_t); + } - if (!facep->mTextureMatrix) - { - facep->mTextureMatrix = new LLMatrix4(); - } + if (!facep->mTextureMatrix) + { + facep->mTextureMatrix = new LLMatrix4(); + } - LLMatrix4& tex_mat = *facep->mTextureMatrix; - tex_mat.setIdentity(); - LLVector3 trans ; - { - trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); - tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); - } + LLMatrix4& tex_mat = *facep->mTextureMatrix; + tex_mat.setIdentity(); + LLVector3 trans ; + { + trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); + tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + } - LLVector3 scale(scale_s, scale_t, 1.f); - LLQuaternion quat; - quat.setQuat(rot, 0, 0, -1.f); + LLVector3 scale(scale_s, scale_t, 1.f); + LLQuaternion quat; + quat.setQuat(rot, 0, 0, -1.f); - tex_mat.rotate(quat); + tex_mat.rotate(quat); - LLMatrix4 mat; - mat.initAll(scale, LLQuaternion(), LLVector3()); - tex_mat *= mat; + LLMatrix4 mat; + mat.initAll(scale, LLQuaternion(), LLVector3()); + tex_mat *= mat; - tex_mat.translate(trans); + tex_mat.translate(trans); + } } - } - else - { - if (mTexAnimMode && mTextureAnimp->mRate == 0) + else { - U8 start, count; - - if (mTextureAnimp->mFace == -1) + if (mTexAnimMode && mTextureAnimp->mRate == 0) { - start = 0; - count = getNumTEs(); - } - else - { - start = (U8) mTextureAnimp->mFace; - count = 1; - } + U8 start, count; - for (S32 i = start; i < start + count; i++) - { - if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) + if (mTextureAnimp->mFace == -1) { - setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); + start = 0; + count = getNumTEs(); } - if (mTexAnimMode & LLViewerTextureAnim::SCALE) + else { - setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); + start = (U8) mTextureAnimp->mFace; + count = 1; } - if (mTexAnimMode & LLViewerTextureAnim::ROTATE) - { - setTERotation(i, mTextureAnimp->mRot); - } - } - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - mTexAnimMode = 0; + for (S32 i = start; i < start + count; i++) + { + if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) + { + setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); + } + if (mTexAnimMode & LLViewerTextureAnim::SCALE) + { + setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); + } + if (mTexAnimMode & LLViewerTextureAnim::ROTATE) + { + setTERotation(i, mTextureAnimp->mRot); + } + } + + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + mTexAnimMode = 0; + } } } } -BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) -{ - LLViewerObject::idleUpdate(agent, world, time); - - //static LLFastTimer::DeclareTimer ftm("Volume Idle"); - //LLFastTimer t(ftm); - - if (mDead || mDrawable.isNull()) - { - return TRUE; - } - - /////////////////////// - // - // Do texture animation stuff - // - - if (mTextureAnimp && gAnimateTextures) - { - animateTextures(); - } - - // Dispatch to implementation - if (mVolumeImpl) - { - mVolumeImpl->doIdleUpdate(agent, world, time); - } - - const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40; - - if (mDrawable->isActive()) - { - if (mDrawable->isRoot() && - mDrawable->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES && - (!mDrawable->getParent() || !mDrawable->getParent()->isActive())) - { - mDrawable->makeStatic(); - } - } - - return TRUE; -} void LLVOVolume::updateTextures() { @@ -489,6 +450,7 @@ void LLVOVolume::updateTextures() } } + } } @@ -578,7 +540,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) { F32 area = (F32) camera->getScreenPixelArea(); vsize = area; - imagep->setBoostLevel(LLViewerTexture::BOOST_HUD); + imagep->setBoostLevel(LLGLTexture::BOOST_HUD); face->setPixelArea(area); // treat as full screen face->setVirtualSize(vsize); } @@ -589,7 +551,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) { if (permYouOwner()) { - imagep->setBoostLevel(LLViewerTexture::BOOST_HIGH); + imagep->setBoostLevel(LLGLTexture::BOOST_HIGH); } } } @@ -636,7 +598,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) if (mSculptTexture.notNull()) { mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), - (S32)LLViewerTexture::BOOST_SCULPTED)); + (S32)LLGLTexture::BOOST_SCULPTED)); mSculptTexture->setForSculpt() ; if(!mSculptTexture->isCachedRawImageReady()) @@ -655,7 +617,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) } } - S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture + S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ; if (texture_discard >= 0 && //texture has some data available @@ -711,8 +673,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) BOOL LLVOVolume::isActive() const { - return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()) || - (mDrawable.notNull() && mDrawable->isActive()); + return !mStatic; } BOOL LLVOVolume::setMaterial(const U8 material) @@ -840,7 +801,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo if (is404) { - setIcon(LLViewerTextureManager::getFetchedTextureFromFile("inv_item_mesh.tga", TRUE, LLViewerTexture::BOOST_UI)); + setIcon(LLViewerTextureManager::getFetchedTextureFromFile("inv_item_mesh.tga", TRUE, LLGLTexture::BOOST_UI)); //render prim proxy when mesh loading attempts give up volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE); @@ -920,7 +881,7 @@ void LLVOVolume::updateSculptTexture() LLUUID id = sculpt_params->getSculptTexture(); if (id.notNull()) { - mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); } } else @@ -958,7 +919,7 @@ void LLVOVolume::sculpt() S8 sculpt_components = 0; const U8* sculpt_data = NULL; - S32 discard_level = mSculptTexture->getDiscardLevel(); + S32 discard_level = mSculptTexture->getCachedRawImageLevel(); LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; S32 max_discard = mSculptTexture->getMaxDiscardLevel(); @@ -1153,13 +1114,13 @@ void LLVOVolume::updateFaceFlags() { for (S32 i = 0; i < getVolume()->getNumFaces(); i++) { - if(mDrawable->getNumFaces() <= i || getNumTEs() <= i) - return; - LLFace *face = mDrawable->getFace(i); if (face) { - BOOL fullbright = getTE(i)->getFullbright(); + LLTextureEntry *entry = getTE(i); + if(!entry) + continue; + BOOL fullbright = entry->getFullbright(); face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); if (fullbright || (mMaterial == LL_MCODE_LIGHT)) @@ -1971,7 +1932,7 @@ void LLVOVolume::updateSpotLightPriority() if (mLightTexture.notNull()) { mLightTexture->addTextureStats(mSpotLightPriority); - mLightTexture->setBoostLevel(LLViewerTexture::BOOST_CLOUDS); + mLightTexture->setBoostLevel(LLGLTexture::BOOST_CLOUDS); } } @@ -3102,6 +3063,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLVector4a* pos = dst_face.mPositions; + if( pos && dst_face.mExtents ) { LLFastTimer t(FTM_SKIN_RIGGED); @@ -4360,7 +4322,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else if (facep->canRenderAsMask()) { - if (te->getFullbright() || LLPipeline::sNoAlpha) + if (te->getFullbright() || fullbright || LLPipeline::sNoAlpha) { registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index dbf9800db..a83a33680 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -70,7 +70,7 @@ class LLVolumeInterface public: virtual ~LLVolumeInterface() { } virtual LLVolumeInterfaceType getInterfaceType() const = 0; - virtual void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0; + virtual void doIdleUpdate() = 0; virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0; virtual LLVector3 getPivotPosition() const = 0; virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0; @@ -116,8 +116,7 @@ public: void deleteFaces(); void animateTextures(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - + BOOL isVisible() const ; /*virtual*/ BOOL isActive() const; /*virtual*/ BOOL isAttachment() const; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 6f085d6cc..049a89d1a 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -106,17 +106,8 @@ void LLVOWater::updateTextures() } // Never gets called -BOOL LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - /*if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER))) - { - return TRUE; - } - if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - }*/ - return TRUE; } LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline) diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h index 02a577a50..1203fb2ea 100644 --- a/indra/newview/llvowater.h +++ b/indra/newview/llvowater.h @@ -64,7 +64,7 @@ public: static void initClass(); static void cleanupClass(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 492bfe174..757c04b7e 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -98,9 +98,9 @@ void LLVOWLSky::initSunDirection(LLVector3 const & sun_direction, { } -BOOL LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; + } BOOL LLVOWLSky::isActive(void) const diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h index 82abe79cb..82124587d 100644 --- a/indra/newview/llvowlsky.h +++ b/indra/newview/llvowlsky.h @@ -59,7 +59,7 @@ public: void initSunDirection(LLVector3 const & sun_direction, LLVector3 const & sun_angular_velocity); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ BOOL isActive(void) const; /*virtual*/ LLDrawable * createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 307edffdd..08f1d85a8 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -374,7 +374,7 @@ void LLWaterParamManager::updateShaderLinks() void LLWaterParamManager::update(LLViewerCamera * cam) { LLFastTimer ftm(FTM_UPDATE_WATERPARAM); - + // update the shaders and the menu propagateParameters(); diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp deleted file mode 100644 index 4da0c0ade..000000000 --- a/indra/newview/llwearable.cpp +++ /dev/null @@ -1,1356 +0,0 @@ -/** - * @file llwearable.cpp - * @brief LLWearable 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 "llagent.h" -#include "llagentcamera.h" -#include "llagentwearables.h" -#include "lldictionary.h" -#include "llfloatercustomize.h" -#include "lllocaltextureobject.h" -#include "llnotificationsutil.h" -#include "llviewertexturelist.h" -#include "llinventorymodel.h" -#include "llinventoryobserver.h" -#include "lltexlayer.h" -#include "lltexglobalcolor.h" -#include "lltrans.h" -#include "llviewerregion.h" -#include "llvisualparam.h" -#include "llvoavatar.h" -#include "llvoavatarself.h" -#include "llvoavatardefines.h" -#include "llwearable.h" -#include "llviewercontrol.h" - -using namespace LLVOAvatarDefines; - -// static -S32 LLWearable::sCurrentDefinitionVersion = 1; - -// support class - remove for 2.1 (hackity hack hack) -class LLOverrideBakedTextureUpdate -{ -public: - LLOverrideBakedTextureUpdate(bool temp_state) - { - U32 num_bakes = (U32) LLVOAvatarDefines::BAKED_NUM_INDICES; - for( U32 index = 0; index < num_bakes; ++index ) - { - composite_enabled[index] = gAgentAvatarp->isCompositeUpdateEnabled(index); - } - gAgentAvatarp->setCompositeUpdatesEnabled(temp_state); - } - - ~LLOverrideBakedTextureUpdate() - { - U32 num_bakes = (U32)LLVOAvatarDefines::BAKED_NUM_INDICES; - for( U32 index = 0; index < num_bakes; ++index ) - { - gAgentAvatarp->setCompositeUpdatesEnabled(index, composite_enabled[index]); - } - } -private: - bool composite_enabled[LLVOAvatarDefines::BAKED_NUM_INDICES]; -}; - -// Private local functions -static std::string terse_F32_to_string(F32 f); -static std::string asset_id_to_filename(const LLUUID &asset_id); - -LLWearable::LLWearable(const LLTransactionID& transaction_id) : - mDefinitionVersion(LLWearable::sCurrentDefinitionVersion), - mType(LLWearableType::WT_INVALID) -{ - mTransactionID = transaction_id; - mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID()); -} - -LLWearable::LLWearable(const LLAssetID& asset_id) : - mDefinitionVersion( LLWearable::sCurrentDefinitionVersion ), - mType(LLWearableType::WT_INVALID) -{ - mAssetID = asset_id; - mTransactionID.setNull(); -} - -LLWearable::~LLWearable() -{ -} - -const std::string& LLWearable::getTypeLabel() const -{ - return LLWearableType::getTypeLabel(mType); -} - -const std::string& LLWearable::getTypeName() const -{ - return LLWearableType::getTypeName(mType); -} - -LLAssetType::EType LLWearable::getAssetType() const -{ - return LLWearableType::getAssetType(mType); -} - - -// reX: new function -BOOL LLWearable::FileExportParams( FILE* file ) -{ - // wearable type - S32 type = (S32)mType; - fprintf( file, "type %d\n", type ); - - // parameters - S32 num_parameters = mVisualParamIndexMap.size(); - fprintf( file, "parameters %d\n", num_parameters ); - - for (visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin(); - iter != mVisualParamIndexMap.end(); ++iter) - { - S32 param_id = iter->first; - F32 param_weight = iter->second->getWeight(); - fprintf( file, "%d %s\n", param_id, terse_F32_to_string(param_weight).c_str() ); - } - - return TRUE; -} - -// reX: new function -BOOL LLWearable::FileExportTextures( FILE* file ) -{ - // wearable type - S32 type = (S32)mType; - fprintf( file, "type %d\n", type ); - - // texture entries - S32 num_textures = mTEMap.size(); - fprintf( file, "textures %d\n", num_textures ); - - for (te_map_t::iterator iter = mTEMap.begin(); - iter != mTEMap.end(); ++iter) - { - S32 te = iter->first; - fprintf( file, "%d %s\n", te, iter->second->getID().asString().c_str() ); - } - - return TRUE; -} - -BOOL LLWearable::exportFile(LLFILE* file) const -{ - // header and version - if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 ) - { - return FALSE; - } - - // name - if( fprintf( file, "%s\n", mName.c_str() ) < 0 ) - { - return FALSE; - } - - // description - if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 ) - { - return FALSE; - } - - // permissions - if( !mPermissions.exportFile( file ) ) - { - return FALSE; - } - - // sale info - if( !mSaleInfo.exportFile( file ) ) - { - return FALSE; - } - - // wearable type - S32 type = (S32)mType; - if( fprintf( file, "type %d\n", type ) < 0 ) - { - return FALSE; - } - - // parameters - S32 num_parameters = mVisualParamIndexMap.size(); - if( fprintf( file, "parameters %d\n", num_parameters ) < 0 ) - { - return FALSE; - } - - for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); - iter != mVisualParamIndexMap.end(); - ++iter) - { - S32 param_id = iter->first; - const LLVisualParam* param = iter->second; - F32 param_weight = param->getWeight(); - if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 ) - { - return FALSE; - } - } - - // texture entries - S32 num_textures = mTEMap.size(); - if( fprintf( file, "textures %d\n", num_textures ) < 0 ) - { - return FALSE; - } - - for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter) - { - S32 te = iter->first; - const LLUUID& image_id = iter->second->getID(); - if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 ) - { - return FALSE; - } - } - return TRUE; -} - - -void LLWearable::createVisualParams() -{ - for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); - param; - param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam()) - { - if (param->getWearableType() == mType) - { - addVisualParam(param->cloneParam(this)); - } - } - - // resync driver parameters to point to the newly cloned driven parameters - for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin(); - param_iter != mVisualParamIndexMap.end(); - ++param_iter) - { - LLVisualParam* param = param_iter->second; - LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam; - // need this line to disambiguate between versions of LLCharacter::getVisualParam() - LLVisualParam*(LLVOAvatarSelf::*avatar_function)(S32)const = &LLVOAvatarSelf::getVisualParam; - param->resetDrivenParams(); - if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false)) - { - if( !param->linkDrivenParams(boost::bind(avatar_function,gAgentAvatarp.get(),_1 ), true)) - { - llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl; - continue; - } - } - } -} - -BOOL LLWearable::importFile( LLFILE* file ) -{ - // *NOTE: changing the type or size of this buffer will require - // changes in the fscanf() code below. You would be better off - // rewriting this to use streams and not require an open FILE. - char text_buffer[2048]; /* Flawfinder: ignore */ - S32 fields_read = 0; - - // suppress texlayerset updates while wearables are being imported. Layersets will be updated - // when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed. - LLOverrideBakedTextureUpdate stop_bakes(false); - - // read header and version - fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion ); - if( fields_read != 1 ) - { - // Shouldn't really log the asset id for security reasons, but - // we need it in this case. - llwarns << "Bad Wearable asset header: " << mAssetID << llendl; - //gVFS->dumpMap(); - return FALSE; - } - - - // Temoprary hack to allow wearables with definition version 24 to still load. - // This should only affect lindens and NDA'd testers who have saved wearables in 2.0 - // the extra check for version == 24 can be removed before release, once internal testers - // have loaded these wearables again. See hack pt 2 at bottom of function to ensure that - // these wearables get re-saved with version definition 22. - if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 ) - { - llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl; - return FALSE; - } - - // name - int next_char = fgetc( file ); /* Flawfinder: ignore */ - if( '\n' == next_char ) - { - // no name - mName = ""; - } - else - { - ungetc( next_char, file ); - fields_read = fscanf( /* Flawfinder: ignore */ - file, - "%2047[^\n]", - text_buffer); - if( (1 != fields_read) || (fgetc( file ) != '\n') ) /* Flawfinder: ignore */ - { - llwarns << "Bad Wearable asset: early end of file" << llendl; - return FALSE; - } - mName = text_buffer; - LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN ); - } - - // description - next_char = fgetc( file ); /* Flawfinder: ignore */ - if( '\n' == next_char ) - { - // no description - mDescription = ""; - } - else - { - ungetc( next_char, file ); - fields_read = fscanf( /* Flawfinder: ignore */ - file, - "%2047[^\n]", - text_buffer ); - if( (1 != fields_read) || (fgetc( file ) != '\n') ) /* Flawfinder: ignore */ - { - llwarns << "Bad Wearable asset: early end of file" << llendl; - return FALSE; - } - mDescription = text_buffer; - LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN ); - } - - // permissions - S32 perm_version; - fields_read = fscanf( file, " permissions %d\n", &perm_version ); - if( (fields_read != 1) || (perm_version != 0) ) - { - llwarns << "Bad Wearable asset: missing permissions" << llendl; - return FALSE; - } - if( !mPermissions.importFile( file ) ) - { - return FALSE; - } - - // sale info - S32 sale_info_version; - fields_read = fscanf( file, " sale_info %d\n", &sale_info_version ); - if( (fields_read != 1) || (sale_info_version != 0) ) - { - llwarns << "Bad Wearable asset: missing sale_info" << llendl; - return FALSE; - } - // Sale info used to contain next owner perm. It is now in the - // permissions. Thus, we read that out, and fix legacy - // objects. It's possible this op would fail, but it should pick - // up the vast majority of the tasks. - BOOL has_perm_mask = FALSE; - U32 perm_mask = 0; - if( !mSaleInfo.importFile(file, has_perm_mask, perm_mask) ) - { - return FALSE; - } - if(has_perm_mask) - { - // fair use fix. - if(!(perm_mask & PERM_COPY)) - { - perm_mask |= PERM_TRANSFER; - } - mPermissions.setMaskNext(perm_mask); - } - - // wearable type - S32 type = -1; - fields_read = fscanf( file, "type %d\n", &type ); - if( fields_read != 1 ) - { - llwarns << "Bad Wearable asset: bad type" << llendl; - return FALSE; - } - if( 0 <= type && type < LLWearableType::WT_COUNT ) - { - setType((LLWearableType::EType)type); - } - else - { - mType = LLWearableType::WT_COUNT; - llwarns << "Bad Wearable asset: bad type #" << type << llendl; - return FALSE; - } - - // parameters header - S32 num_parameters = 0; - fields_read = fscanf( file, "parameters %d\n", &num_parameters ); - if( fields_read != 1 ) - { - llwarns << "Bad Wearable asset: missing parameters block" << llendl; - return FALSE; - } - - if( num_parameters != mVisualParamIndexMap.size() ) - { - llwarns << "Wearable parameter mismatch. Reading in " << num_parameters << " from file, but created " << mVisualParamIndexMap.size() << " from avatar parameters. type: " << mType << llendl; - } - - // parameters - S32 i; - for( i = 0; i < num_parameters; i++ ) - { - S32 param_id = 0; - F32 param_weight = 0.f; - fields_read = fscanf( file, "%d %f\n", ¶m_id, ¶m_weight ); - if( fields_read != 2 ) - { - llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl; - return FALSE; - } - mSavedVisualParamMap[param_id] = param_weight; - } - - // textures header - S32 num_textures = 0; - fields_read = fscanf( file, "textures %d\n", &num_textures); - if( fields_read != 1 ) - { - llwarns << "Bad Wearable asset: missing textures block" << llendl; - return FALSE; - } - - // textures - for( i = 0; i < num_textures; i++ ) - { - S32 te = 0; - fields_read = fscanf( /* Flawfinder: ignore */ - file, - "%d %2047s\n", - &te, text_buffer); - if( fields_read != 2 ) - { - llwarns << "Bad Wearable asset: bad texture, #" << i << llendl; - return FALSE; - } - - if( !LLUUID::validate( text_buffer ) ) - { - llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl; - return FALSE; - } - LLUUID id = LLUUID(text_buffer); - LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( id ); - if( mTEMap.find(te) != mTEMap.end() ) - { - delete mTEMap[te]; - } - if( mSavedTEMap.find(te) != mSavedTEMap.end() ) - { - delete mSavedTEMap[te]; - } - - if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) - { - image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLVOAvatarDefines::ETextureIndex)te), NULL); - } - LLUUID textureid(text_buffer); - mTEMap[te] = new LLLocalTextureObject(image, textureid); - mSavedTEMap[te] = new LLLocalTextureObject(image, textureid); - createLayers(te); - } - - // copy all saved param values to working params - revertValues(); - - return TRUE; -} - - -// Avatar parameter and texture definitions can change over time. -// This function returns true if parameters or textures have been added or removed -// since this wearable was created. -BOOL LLWearable::isOldVersion() const -{ - if (!isAgentAvatarValid()) return FALSE; - - if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion ) - { - llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl; - llassert(0); - } - - if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion ) - { - return TRUE; - } - - S32 param_count = 0; - for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); - param; - param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() ) - { - if( (param->getWearableType() == mType) && (param->isTweakable() ) ) - { - param_count++; - if( !is_in_map(mVisualParamIndexMap, param->getID() ) ) - { - return TRUE; - } - } - } - if( param_count != mVisualParamIndexMap.size() ) - { - return TRUE; - } - - - S32 te_count = 0; - for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) - { - if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) - { - te_count++; - if( !is_in_map(mTEMap, te ) ) - { - return TRUE; - } - } - } - if( te_count != mTEMap.size() ) - { - return TRUE; - } - - return FALSE; -} - -// Avatar parameter and texture definitions can change over time. -// * If parameters or textures have been REMOVED since the wearable was created, -// they're just ignored, so we consider the wearable clean even though isOldVersion() -// will return true. -// * If parameters or textures have been ADDED since the wearable was created, -// they are taken to have default values, so we consider the wearable clean -// only if those values are the same as the defaults. -BOOL LLWearable::isDirty() const -{ - if (!isAgentAvatarValid()) return FALSE; - - for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); - param; - param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() ) - { - if( (param->getWearableType() == mType) - && (param->isTweakable() ) - && !param->getCrossWearable()) - { - F32 current_weight = getVisualParamWeight(param->getID()); - current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() ); - F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight()); - saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() ); - - U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() ); - U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() ); - - if( a != b ) - { - //llwarns << "param ID " << param->getID() << " was changed." << llendl; - return TRUE; - } - } - } - - for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) - { - if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) - { - te_map_t::const_iterator current_iter = mTEMap.find(te); - if(current_iter != mTEMap.end()) - { - const LLUUID& current_image_id = current_iter->second->getID(); - te_map_t::const_iterator saved_iter = mSavedTEMap.find(te); - if(saved_iter != mSavedTEMap.end()) - { - const LLUUID& saved_image_id = saved_iter->second->getID(); - if (saved_image_id != current_image_id) - { - // saved vs current images are different, wearable is dirty - return TRUE; - } - } - else - { - // image found in current image list but not saved image list - return TRUE; - } - } - } - } - - return FALSE; -} - - -void LLWearable::setParamsToDefaults() -{ - if (!isAgentAvatarValid()) return; - - for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() ) - { - if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->isTweakable() ) ) - { - setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE); - } - } -} - -void LLWearable::setTexturesToDefaults() -{ - for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) - { - if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) - { - LLUUID id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); - LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id ); - if( mTEMap.find(te) == mTEMap.end() ) - { - mTEMap[te] = new LLLocalTextureObject(image, id); - createLayers(te); - } - else - { - // Local Texture Object already created, just set image and UUID - LLLocalTextureObject *lto = mTEMap[te]; - lto->setID(id); - lto->setImage(image); - } - } - } -} - -// Updates the user's avatar's appearance -void LLWearable::writeToAvatar() -{ - if (!isAgentAvatarValid()) return; - - ESex old_sex = gAgentAvatarp->getSex(); - - // Pull params - for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() ) - { - // cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the - // avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way. - if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) ) - { - S32 param_id = param->getID(); - F32 weight = getVisualParamWeight(param_id); - - gAgentAvatarp->setVisualParamWeight( param_id, weight, FALSE ); - } - } - - // Pull texture entries - for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) - { - if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) - { - te_map_t::const_iterator iter = mTEMap.find(te); - LLUUID image_id; - if(iter != mTEMap.end()) - { - image_id = iter->second->getID(); - } - else - { - image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); - } - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE ); - // MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this. - gAgentAvatarp->setLocalTextureTE(te, image, 0); - } - } - - ESex new_sex = gAgentAvatarp->getSex(); - if( old_sex != new_sex ) - { - gAgentAvatarp->updateSexDependentLayerSets( FALSE ); - } -} - - -// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values. -// static -void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake ) -{ - if (!isAgentAvatarValid()) return; - - // You can't just remove body parts. - if( (type == LLWearableType::WT_SHAPE) || - (type == LLWearableType::WT_SKIN) || - (type == LLWearableType::WT_HAIR) || - (type == LLWearableType::WT_EYES) ) - { - return; - } - - // Pull params - for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() ) - { - if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->isTweakable()) ) - { - S32 param_id = param->getID(); - gAgentAvatarp->setVisualParamWeight( param_id, param->getDefaultWeight(), upload_bake ); - } - } - - if(gAgentCamera.cameraCustomizeAvatar()) - { - gFloaterCustomize->wearablesChanged(type); - } - - gAgentAvatarp->updateVisualParams(); - gAgentAvatarp->wearableUpdated(type, FALSE); - -// if( upload_bake ) -// { -// gAgent.sendAgentSetAppearance(); -// } -} - -// Does not copy mAssetID. -// Definition version is current: removes obsolete enties and creates default values for new ones. -void LLWearable::copyDataFrom(const LLWearable* src) -{ - if (!isAgentAvatarValid()) return; - - mDefinitionVersion = LLWearable::sCurrentDefinitionVersion; - - mName = src->mName; - mDescription = src->mDescription; - mPermissions = src->mPermissions; - mSaleInfo = src->mSaleInfo; - - setType(src->mType); - - mSavedVisualParamMap.clear(); - // Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed) - for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); - param; - param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() ) - { - if( (param->getWearableType() == mType) ) - { - S32 id = param->getID(); - F32 weight = src->getVisualParamWeight(id); - mSavedVisualParamMap[id] = weight; - } - } - - destroyTextures(); - // Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed) - for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) - { - if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) - { - te_map_t::const_iterator iter = src->mTEMap.find(te); - LLUUID image_id; - LLViewerFetchedTexture *image = NULL; - if(iter != src->mTEMap.end()) - { - image = src->getLocalTextureObject(te)->getImage(); - image_id = src->getLocalTextureObject(te)->getID(); - mTEMap[te] = new LLLocalTextureObject(image, image_id); - mSavedTEMap[te] = new LLLocalTextureObject(image, image_id); - mTEMap[te]->setBakedReady(src->getLocalTextureObject(te)->getBakedReady()); - mTEMap[te]->setDiscard(src->getLocalTextureObject(te)->getDiscard()); - } - else - { - image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); - image = LLViewerTextureManager::getFetchedTexture( image_id ); - mTEMap[te] = new LLLocalTextureObject(image, image_id); - mSavedTEMap[te] = new LLLocalTextureObject(image, image_id); - } - createLayers(te); - } - } - - // 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(); -} - -void LLWearable::setItemID(const LLUUID& item_id) -{ - mItemID = item_id; -} - -const LLUUID& LLWearable::getItemID() const -{ - return mItemID; -} - -void LLWearable::setType(LLWearableType::EType type) -{ - mType = type; - createVisualParams(); -} - -LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) -{ - te_map_t::iterator iter = mTEMap.find(index); - if( iter != mTEMap.end() ) - { - LLLocalTextureObject* lto = iter->second; - return lto; - } - return NULL; -} - -const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const -{ - te_map_t::const_iterator iter = mTEMap.find(index); - if( iter != mTEMap.end() ) - { - const LLLocalTextureObject* lto = iter->second; - return lto; - } - return NULL; -} - -void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject <o) -{ - if( mTEMap.find(index) != mTEMap.end() ) - { - mTEMap.erase(index); - } - mTEMap[index] = new LLLocalTextureObject(lto); -} - - -void LLWearable::addVisualParam(LLVisualParam *param) -{ - if( mVisualParamIndexMap[param->getID()] ) - { - delete mVisualParamIndexMap[param->getID()]; - } - param->setIsDummy(FALSE); - mVisualParamIndexMap[param->getID()] = param; - mSavedVisualParamMap[param->getID()] = param->getDefaultWeight(); -} - -void LLWearable::setVisualParams() -{ - for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++) - { - S32 id = iter->first; - LLVisualParam *wearable_param = iter->second; - F32 value = wearable_param->getWeight(); - gAgentAvatarp->setVisualParamWeight(id, value, FALSE); - } -} - - -void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake) -{ - if( is_in_map(mVisualParamIndexMap, param_index ) ) - { - LLVisualParam *wearable_param = mVisualParamIndexMap[param_index]; - wearable_param->setWeight(value, upload_bake); - } - else - { - llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl; - } -} - -F32 LLWearable::getVisualParamWeight(S32 param_index) const -{ - if( is_in_map(mVisualParamIndexMap, param_index ) ) - { - const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second; - return wearable_param->getWeight(); - } - else - { - llwarns << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl; - } - return (F32)-1.0; -} - -LLVisualParam* LLWearable::getVisualParam(S32 index) const -{ - visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index); - return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second; -} - - -void LLWearable::getVisualParams(visual_param_vec_t &list) -{ - visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin(); - visual_param_index_map_t::iterator end = mVisualParamIndexMap.end(); - - // add all visual params to the passed-in vector - for( ; iter != end; ++iter ) - { - list.push_back(iter->second); - } -} - -void LLWearable::animateParams(F32 delta, BOOL upload_bake) -{ - for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin(); - iter != mVisualParamIndexMap.end(); - ++iter) - { - LLVisualParam *param = (LLVisualParam*) iter->second; - param->animate(delta, upload_bake); - } -} - -LLColor4 LLWearable::getClothesColor(S32 te) const -{ - LLColor4 color; - U32 param_name[3]; - if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) ) - { - for( U8 index = 0; index < 3; index++ ) - { - color.mV[index] = getVisualParamWeight(param_name[index]); - } - } - return color; -} - -void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake ) -{ - U32 param_name[3]; - if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) ) - { - for( U8 index = 0; index < 3; index++ ) - { - setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake); - } - } -} - -void LLWearable::revertValues() -{ - //update saved settings so wearable is no longer dirty - // non-driver params first - for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) - { - S32 id = iter->first; - F32 value = iter->second; - LLVisualParam *param = getVisualParam(id); - if(param && !dynamic_cast(param) ) - { - setVisualParamWeight(id, value, TRUE); - } - } - - //then driver params - for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) - { - S32 id = iter->first; - F32 value = iter->second; - LLVisualParam *param = getVisualParam(id); - if(param && dynamic_cast(param) ) - { - setVisualParamWeight(id, value, TRUE); - } - } - - // make sure that saved values are sane - for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) - { - S32 id = iter->first; - LLVisualParam *param = getVisualParam(id); - if( param ) - { - mSavedVisualParamMap[id] = param->getWeight(); - } - } - - syncImages(mSavedTEMap, mTEMap); - - - /*LLSidepanelAppearance *panel = dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance")); - if( panel ) - { - panel->updateScrollingPanelList(); - }*/ - if( gFloaterCustomize && gAgentWearables.getWearableIndex(this)==0 ) - gFloaterCustomize->updateScrollingPanelList(); - -} - -BOOL LLWearable::isOnTop() const -{ - return (this == gAgentWearables.getTopWearable(mType)); -} - -void LLWearable::createLayers(S32 te) -{ - LLTexLayerSet *layer_set = gAgentAvatarp->getLayerSet((ETextureIndex)te); - if (layer_set) - { - layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this); - } - else - { - llerrs << "could not find layerset for LTO in wearable!" << llendl; - } -} - -void LLWearable::saveValues() -{ - //update saved settings so wearable is no longer dirty - mSavedVisualParamMap.clear(); - for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter) - { - S32 id = iter->first; - LLVisualParam *wearable_param = iter->second; - F32 value = wearable_param->getWeight(); - mSavedVisualParamMap[id] = value; - } - - // Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed) - syncImages(mTEMap, mSavedTEMap); - - - /*LLSidepanelAppearance *panel = dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance")); - if( panel ) - { - panel->updateScrollingPanelList(); - }*/ - - if( gFloaterCustomize && gAgentWearables.getWearableIndex(this)==0) - gFloaterCustomize->updateScrollingPanelList(); -} - -void LLWearable::syncImages(te_map_t &src, te_map_t &dst) -{ - // Deep copy of src (copies only those tes that are current, filling in defaults where needed) - for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) - { - if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) - { - te_map_t::const_iterator iter = src.find(te); - LLUUID image_id; - LLViewerFetchedTexture *image = NULL; - LLLocalTextureObject *lto = NULL; - if(iter != src.end()) - { - // there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map. - lto = iter->second; - image = lto->getImage(); - image_id = lto->getID(); - } - else - { - // there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map. - image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); - image = LLViewerTextureManager::getFetchedTexture( image_id ); - } - - if( dst.find(te) != dst.end() ) - { - // there's already an entry in the destination map for the texture. Just update its values. - dst[te]->setImage(image); - dst[te]->setID(image_id); - } - else - { - // no entry found in the destination map, we need to create a new Local Texture Object - dst[te] = new LLLocalTextureObject(image, image_id); - } - - if( lto ) - { - // If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map. - dst[te]->setBakedReady(lto->getBakedReady()); - dst[te]->setDiscard(lto->getDiscard()); - } - } - } -} - -void LLWearable::destroyTextures() -{ - for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter ) - { - LLLocalTextureObject *lto = iter->second; - delete lto; - } - mTEMap.clear(); - for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter ) - { - LLLocalTextureObject *lto = iter->second; - delete lto; - } - mSavedTEMap.clear(); -} - -void LLWearable::pullCrossWearableValues() -{ - // scan through all of the avatar's visual parameters - for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); - param; - param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam()) - { - if( param ) - { - LLDriverParam *driver_param = dynamic_cast(param); - if(driver_param) - { - // parameter is a driver parameter, have it update its - driver_param->updateCrossDrivenParams(getType()); - } - } - } -} - -/*void LLWearable::readFromAvatar() -{ - LLVOAvatar* avatar = gAgentAvatarp; - llassert( avatar ); - if( !avatar ) - { - return; - } - - mDefinitionVersion = LLWearable::sCurrentDefinitionVersion; - - mVisualParamMap.clear(); - for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) - { - if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->isTweakable()) ) - { - mVisualParamMap[param->getID()] = param->getWeight(); - } - } - - mTEMap.clear(); - for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) - { - if( LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te ) == mType ) - { - LLViewerTexture* image = avatar->getTEImage( te ); - if( image ) - { - mTEMap[te] = image->getID(); - } - } - } - - //if( gFloaterCustomize ) - //{ - // mDescription = gFloaterCustomize->getWearableDescription( mType ); - //} -}*/ - - -void LLWearable::setLabelUpdated() const -{ - gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID()); -} - -void LLWearable::refreshName() -{ - LLUUID item_id = getItemID(); - LLInventoryItem* item = gInventory.getItem(item_id); - if( item ) - { - mName = item->getName(); - } -} - -struct LLWearableSaveData -{ - LLWearableType::EType mType; -}; - -void LLWearable::saveNewAsset() const -{ -// llinfos << "LLWearable::saveNewAsset() type: " << getTypeName() << llendl; - //llinfos << *this << llendl; - - const std::string filename = asset_id_to_filename(mAssetID); - LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */ - BOOL successful_save = FALSE; - if(fp && exportFile(fp)) - { - successful_save = TRUE; - } - if(fp) - { - fclose(fp); - fp = NULL; - } - if(!successful_save) - { - std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str()); - llwarns << buffer << llendl; - - LLSD args; - args["NAME"] = mName; - LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args); - return; - } - - // save it out to database - if( gAssetStorage ) - { - /* - std::string url = gAgent.getRegion()->getCapability("NewAgentInventory"); - if (!url.empty()) - { - llinfos << "Update Agent Inventory via capability" << llendl; - LLSD body; - body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetToFolderType(getAssetType())); - body["asset_type"] = LLAssetType::lookup(getAssetType()); - body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE); - body["name"] = getName(); - body["description"] = getDescription(); - LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename)); - } - else - { - } - */ - LLWearableSaveData* data = new LLWearableSaveData; - data->mType = mType; - gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(), - &LLWearable::onSaveNewAssetComplete, - (void*)data); - } -} - -// static -void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) -{ - LLWearableSaveData* data = (LLWearableSaveData*)userdata; - const std::string& type_name = LLWearableType::getTypeName(data->mType); - if(0 == status) - { - // Success - llinfos << "Saved wearable " << type_name << llendl; - } - else - { - std::string buffer = llformat("Unable to save %s to central asset store.", type_name.c_str()); - llwarns << buffer << " Status: " << status << llendl; - LLSD args; - args["NAME"] = type_name; - LLNotificationsUtil::add("CannotSaveToAssetStore", args); - } - - // Delete temp file - const std::string src_filename = asset_id_to_filename(new_asset_id); - LLFile::remove(src_filename); - - // delete the context data - delete data; - -} - -std::ostream& operator<<(std::ostream &s, const LLWearable &w) -{ - s << "wearable " << LLWearableType::getTypeName(w.mType) << "\n"; - s << " Name: " << w.mName << "\n"; - s << " Desc: " << w.mDescription << "\n"; - //w.mPermissions - //w.mSaleInfo - - s << " Params:" << "\n"; - for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin(); - iter != w.mVisualParamIndexMap.end(); ++iter) - { - S32 param_id = iter->first; - LLVisualParam *wearable_param = iter->second; - F32 param_weight = wearable_param->getWeight(); - s << " " << param_id << " " << param_weight << "\n"; - } - - s << " Textures:" << "\n"; - for (LLWearable::te_map_t::const_iterator iter = w.mTEMap.begin(); - iter != w.mTEMap.end(); ++iter) - { - S32 te = iter->first; - const LLUUID& image_id = iter->second->getID(); - s << " " << te << " " << image_id << "\n"; - } - return s; -} - - -std::string terse_F32_to_string(F32 f) -{ - std::string r = llformat("%.2f", f); - S32 len = r.length(); - - // "1.20" -> "1.2" - // "24.00" -> "24." - while (len > 0 && ('0' == r[len - 1])) - { - r.erase(len-1, 1); - len--; - } - if ('.' == r[len - 1]) - { - // "24." -> "24" - r.erase(len-1, 1); - } - else if (('-' == r[0]) && ('0' == r[1])) - { - // "-0.59" -> "-.59" - r.erase(1, 1); - } - else if ('0' == r[0]) - { - // "0.59" -> ".59" - r.erase(0, 1); - } - return r; -} - -std::string asset_id_to_filename(const LLUUID &asset_id) -{ - std::string asset_id_string; - asset_id.toString(asset_id_string); - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl"; - return filename; -} diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 6f6411ce3..507ce57e7 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -42,20 +42,23 @@ struct LLWearableArrivedData { LLWearableArrivedData(LLAssetType::EType asset_type, const std::string& wearable_name, - void(*asset_arrived_callback)(LLWearable*, void* userdata), + LLAvatarAppearance* avatarp, + void(*asset_arrived_callback)(LLViewerWearable*, void* userdata), void* userdata) : mAssetType( asset_type ), mCallback( asset_arrived_callback ), mUserdata( userdata ), mName( wearable_name ), - mRetries(0) + mRetries(0), + mAvatarp(avatarp) {} LLAssetType::EType mAssetType; - void (*mCallback)(LLWearable*, void* userdata); + void (*mCallback)(LLViewerWearable*, void* userdata); void* mUserdata; std::string mName; S32 mRetries; + LLAvatarAppearance *mAvatarp; }; //////////////////////////////////////////////////////////////////////////// @@ -72,10 +75,10 @@ void LLWearableList::cleanup() mList.clear(); } -void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata) +void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAvatarAppearance* avatarp, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLViewerWearable*, void* userdata), void* userdata) { llassert( (asset_type == LLAssetType::AT_CLOTHING) || (asset_type == LLAssetType::AT_BODYPART) ); - LLWearable* instance = get_if_there(mList, assetID, (LLWearable*)NULL ); + LLViewerWearable* instance = get_if_there(mList, assetID, (LLViewerWearable*)NULL ); if( instance ) { asset_arrived_callback( instance, userdata ); @@ -85,7 +88,7 @@ void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& weara gAssetStorage->getAssetData(assetID, asset_type, LLWearableList::processGetAssetReply, - (void*)new LLWearableArrivedData( asset_type, wearable_name, asset_arrived_callback, userdata ), + (void*)new LLWearableArrivedData( asset_type, wearable_name, avatarp, asset_arrived_callback, userdata ), TRUE); } } @@ -95,25 +98,31 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID { BOOL isNewWearable = FALSE; LLWearableArrivedData* data = (LLWearableArrivedData*) userdata; - LLWearable* wearable = NULL; // NULL indicates failure + LLViewerWearable* wearable = NULL; // NULL indicates failure + LLAvatarAppearance *avatarp = data->mAvatarp; if( !filename ) { LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL; } + else if(!avatarp) + { + LL_WARNS("Wearable") << "Bad asset request: missing avatar pointer." << LL_ENDL; + } else if (status >= 0) { // read the file - LLFILE* fp = LLFile::fopen(std::string(filename), "rb"); /*Flawfinder: ignore*/ - if( !fp ) + llifstream ifs(filename, llifstream::binary); + if( !ifs.is_open() ) { LL_WARNS("Wearable") << "Bad Wearable Asset: unable to open file: '" << filename << "'" << LL_ENDL; } else { - wearable = new LLWearable(uuid); - bool res = wearable->importFile( fp ); - if (!res) + wearable = new LLViewerWearable(uuid); + LLWearable::EImportResult result = wearable->importStream( + ifs, avatarp ); + if (LLWearable::SUCCESS != result) { if (wearable->getType() == LLWearableType::WT_COUNT) { @@ -123,9 +132,12 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID wearable = NULL; } - fclose( fp ); if(filename) { + if (ifs.is_open()) + { + ifs.close(); + } LLFile::remove(std::string(filename)); } } @@ -203,11 +215,11 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID } -LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std::string& new_name) +LLViewerWearable* LLWearableList::createCopy(const LLViewerWearable* old_wearable, const std::string& new_name) { lldebugs << "LLWearableList::createCopy()" << llendl; - LLWearable *wearable = generateNewWearable(); + LLViewerWearable *wearable = generateNewWearable(); wearable->copyDataFrom(old_wearable); LLPermissions perm(old_wearable->getPermissions()); @@ -222,12 +234,12 @@ LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std return wearable; } -LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type ) +LLViewerWearable* LLWearableList::createNewWearable( LLWearableType::EType type, LLAvatarAppearance *avatarp ) { lldebugs << "LLWearableList::createNewWearable()" << llendl; - LLWearable *wearable = generateNewWearable(); - wearable->setType( type ); + LLViewerWearable *wearable = generateNewWearable(); + wearable->setType( type, avatarp ); std::string name = LLTrans::getString( LLWearableType::getTypeDefaultNewName(wearable->getType()) ); wearable->setName( name ); @@ -251,13 +263,13 @@ LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type ) return wearable; } -LLWearable *LLWearableList::generateNewWearable() +LLViewerWearable *LLWearableList::generateNewWearable() { LLTransactionID tid; tid.generate(); LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); - LLWearable* wearable = new LLWearable(tid); + LLViewerWearable* wearable = new LLViewerWearable(tid); mList[new_asset_id] = wearable; return wearable; } diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h index 12d0037ae..d6f0fd09a 100644 --- a/indra/newview/llwearablelist.h +++ b/indra/newview/llwearablelist.h @@ -28,7 +28,7 @@ #define LL_LLWEARABLELIST_H #include "llmemory.h" -#include "llwearable.h" +#include "llviewerwearable.h" #include "lluuid.h" #include "llassetstorage.h" @@ -50,20 +50,21 @@ public: void getAsset(const LLAssetID& assetID, const std::string& wearable_name, + LLAvatarAppearance *avatarp, LLAssetType::EType asset_type, - void(*asset_arrived_callback)(LLWearable*, void* userdata), + void(*asset_arrived_callback)(LLViewerWearable*, void* userdata), void* userdata); - LLWearable* createCopy(const LLWearable* old_wearable, const std::string& new_name = std::string()); - LLWearable* createNewWearable(LLWearableType::EType type); + LLViewerWearable* createCopy(const LLViewerWearable* old_wearable, const std::string& new_name = std::string()); + LLViewerWearable* createNewWearable(LLWearableType::EType type, LLAvatarAppearance *avatarp); // Callback static void processGetAssetReply(const char* filename, const LLAssetID& assetID, void* user_data, S32 status, LLExtStat ext_status); protected: - LLWearable* generateNewWearable(); // used for the create... functions + LLViewerWearable* generateNewWearable(); // used for the create... functions private: - std::map mList; + std::map mList; }; #endif // LL_LLWEARABLELIST_H diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp new file mode 100644 index 000000000..b6f8e0a65 --- /dev/null +++ b/indra/newview/llwebprofile.cpp @@ -0,0 +1,330 @@ +/** + * @file llwebprofile.cpp + * @brief Web profile access. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwebprofile.h" + +// libs +#include "llbufferstream.h" +#include "llhttpclient.h" +#include "llimagepng.h" +#include "llplugincookiestore.h" + +// newview +#include "llpanelprofile.h" // getProfileURL (this is the original location LL put it). +#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals + +// third-party JSONCPP +#include // JSONCPP + +/* + * Workflow: + * 1. LLViewerMedia::setOpenIDCookie() + * -> GET https://my-demo.secondlife.com/ via LLViewerMediaWebProfileResponder + * -> LLWebProfile::setAuthCookie() + * 2. LLWebProfile::uploadImage() + * -> GET "https://my-demo.secondlife.com/snapshots/s3_upload_config" via ConfigResponder + * 3. LLWebProfile::post() + * -> POST via PostImageResponder + * -> redirect + * -> GET via PostImageRedirectResponder + */ + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfileResponders::ConfigResponder + +extern AIHTTPTimeoutPolicy webProfileResponders_timeout; + +class LLWebProfileResponders::ConfigResponder : public LLHTTPClient::ResponderWithCompleted +{ + LOG_CLASS(LLWebProfileResponders::ConfigResponder); + +public: + ConfigResponder(LLPointer imagep) + : mImagep(imagep) + { + } + + /*virtual*/ void completedRaw( + U32 status, + const std::string& reason, + const LLChannelDescriptors& channels, + const buffer_ptr_t& buffer) + { + LLBufferStream istr(channels, buffer.get()); + std::stringstream strstrm; + strstrm << istr.rdbuf(); + const std::string body = strstrm.str(); + + if (status != 200) + { + llwarns << "Failed to get upload config (" << status << ")" << llendl; + LLWebProfile::reportImageUploadStatus(false); + return; + } + + Json::Value root; + Json::Reader reader; + if (!reader.parse(body, root)) + { + llwarns << "Failed to parse upload config: " << reader.getFormatedErrorMessages() << llendl; + LLWebProfile::reportImageUploadStatus(false); + return; + } + + // *TODO: 404 = not supported by the grid + // *TODO: increase timeout or handle 499 Expired + + // Convert config to LLSD. + const Json::Value data = root["data"]; + const std::string upload_url = root["url"].asString(); + LLSD config; + config["acl"] = data["acl"].asString(); + config["AWSAccessKeyId"] = data["AWSAccessKeyId"].asString(); + config["Content-Type"] = data["Content-Type"].asString(); + config["key"] = data["key"].asString(); + config["policy"] = data["policy"].asString(); + config["success_action_redirect"] = data["success_action_redirect"].asString(); + config["signature"] = data["signature"].asString(); + config["add_loc"] = data.get("add_loc", "0").asString(); + config["caption"] = data.get("caption", "").asString(); + + // Do the actual image upload using the configuration. + LL_DEBUGS("Snapshots") << "Got upload config, POSTing image to " << upload_url << ", config=[" << config << "]" << LL_ENDL; + LLWebProfile::post(mImagep, config, upload_url); + } + +protected: + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return webProfileResponders_timeout; } + /*virtual*/ bool followRedir(void) const { return true; } + /*virtual*/ char const* getName(void) const { return "LLWebProfileResponders::ConfigResponder"; } + +private: + LLPointer mImagep; +}; + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfilePostImageRedirectResponder +class LLWebProfileResponders::PostImageRedirectResponder : public LLHTTPClient::ResponderWithCompleted +{ + LOG_CLASS(LLWebProfileResponders::PostImageRedirectResponder); + +public: + /*virtual*/ void completedRaw( + U32 status, + const std::string& reason, + const LLChannelDescriptors& channels, + const buffer_ptr_t& buffer) + { + if (status != 200) + { + llwarns << "Failed to upload image: " << status << " " << reason << llendl; + LLWebProfile::reportImageUploadStatus(false); + return; + } + + LLBufferStream istr(channels, buffer.get()); + std::stringstream strstrm; + strstrm << istr.rdbuf(); + const std::string body = strstrm.str(); + llinfos << "Image uploaded." << llendl; + LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << body << "]" << LL_ENDL; + LLWebProfile::reportImageUploadStatus(true); + } + +protected: + /*virtual*/ bool followRedir(void) const { return true; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return webProfileResponders_timeout; } + /*virtual*/ char const* getName(void) const { return "LLWebProfileResponders::PostImageRedirectResponder"; } + +private: + LLPointer mImagep; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfileResponders::PostImageResponder +class LLWebProfileResponders::PostImageResponder : public LLHTTPClient::ResponderWithCompleted +{ + LOG_CLASS(LLWebProfileResponders::PostImageResponder); + +public: + /*virtual*/ bool needsHeaders(void) const { return true; } + + /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& received_headers) + { + // Server abuses 303 status; Curl can't handle it because it tries to resent + // the just uploaded data, which fails + // (CURLE_SEND_FAIL_REWIND: Send failed since rewinding of the data stream failed). + // Handle it manually. + if (status == 303) + { + AIHTTPHeaders headers; + headers.addHeader("Accept", "*/*"); + headers.addHeader("Cookie", LLWebProfile::getAuthCookie()); + headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent()); + std::string redir_url; + received_headers.getFirstValue("location", redir_url); + LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << LL_ENDL; + LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers); + } + else + { + llwarns << "Unexpected POST status: " << status << " " << reason << llendl; + LL_DEBUGS("Snapshots") << "received_headers: [" << received_headers << "]" << LL_ENDL; + LLWebProfile::reportImageUploadStatus(false); + } + } + + // Override just to suppress warnings. + /*virtual*/ void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const buffer_ptr_t& buffer) + { + } + +protected: + /*virtual*/ bool redirect_status_ok(void) const { return true; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return webProfileResponders_timeout; } + /*virtual*/ char const* getName(void) const { return "LLWebProfileResponders::PostImageResponder"; } +}; + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfile + +std::string LLWebProfile::sAuthCookie; +LLWebProfile::status_callback_t LLWebProfile::mStatusCallback; + +// static +void LLWebProfile::uploadImage(LLPointer image, const std::string& caption, bool add_location) +{ + // Get upload configuration data. + std::string config_url(getProfileURL(LLStringUtil::null) + "snapshots/s3_upload_config"); + config_url += "?caption=" + LLURI::escape(caption); + config_url += "&add_loc=" + std::string(add_location ? "1" : "0"); + + LL_DEBUGS("Snapshots") << "Requesting " << config_url << LL_ENDL; + AIHTTPHeaders headers; + headers.addHeader("Accept", "*/*"); + headers.addHeader("Cookie", LLWebProfile::getAuthCookie()); + headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent()); + LLHTTPClient::get(config_url, new LLWebProfileResponders::ConfigResponder(image), headers); +} + +// static +void LLWebProfile::setAuthCookie(const std::string& cookie) +{ + LL_DEBUGS("Snapshots") << "Setting auth cookie: " << cookie << LL_ENDL; + sAuthCookie = cookie; +} + +// static +void LLWebProfile::post(LLPointer image, const LLSD& config, const std::string& url) +{ + if (dynamic_cast(image.get()) == 0) + { + llwarns << "Image to upload is not a PNG" << llendl; + llassert(dynamic_cast(image.get()) != 0); + return; + } + + const std::string boundary = "----------------------------0123abcdefab"; + + AIHTTPHeaders headers; + headers.addHeader("Accept", "*/*"); + headers.addHeader("Cookie", LLWebProfile::getAuthCookie()); + headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent()); + headers.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary); + + std::ostringstream body; + + // *NOTE: The order seems to matter. + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"key\"\r\n\r\n" + << config["key"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n" + << config["AWSAccessKeyId"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"acl\"\r\n\r\n" + << config["acl"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n" + << config["Content-Type"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"policy\"\r\n\r\n" + << config["policy"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"signature\"\r\n\r\n" + << config["signature"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n" + << config["success_action_redirect"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n" + << "Content-Type: image/png\r\n\r\n"; + size_t const body_size = body.str().size(); + + std::ostringstream footer; + footer << "\r\n--" << boundary << "--\r\n"; + size_t const footer_size = footer.str().size(); + + size_t size = body_size + image->getDataSize() + footer_size; + // postRaw() takes ownership of the buffer and releases it later. + char* data = new char [size]; + memcpy(data, body.str().data(), body_size); + // Insert the image data. + memcpy(data + body_size, image->getData(), image->getDataSize()); + memcpy(data + body_size + image->getDataSize(), footer.str().data(), footer_size); + + // Send request, successful upload will trigger posting metadata. + LLHTTPClient::postRaw(url, data, size, new LLWebProfileResponders::PostImageResponder(), headers/*,*/ DEBUG_CURLIO_PARAM(debug_off), no_keep_alive); +} + +// static +void LLWebProfile::reportImageUploadStatus(bool ok) +{ + if (mStatusCallback) + { + mStatusCallback(ok); + } +} + +// static +std::string LLWebProfile::getAuthCookie() +{ + // This is needed to test image uploads on Linux viewer built with OpenSSL 1.0.0 (0.9.8 works fine). + const char* debug_cookie = getenv("LL_SNAPSHOT_COOKIE"); + return debug_cookie ? debug_cookie : sAuthCookie; +} diff --git a/indra/newview/llwebprofile.h b/indra/newview/llwebprofile.h new file mode 100644 index 000000000..10279bffa --- /dev/null +++ b/indra/newview/llwebprofile.h @@ -0,0 +1,69 @@ +/** + * @file llwebprofile.h + * @brief Web profile access. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLWEBPROFILE_H +#define LL_LLWEBPROFILE_H + +#include "llimage.h" + +namespace LLWebProfileResponders +{ + class ConfigResponder; + class PostImageResponder; + class PostImageRedirectResponder; +}; + +/** + * @class LLWebProfile + * + * Manages interaction with, a web service allowing the upload of snapshot images + * taken within the viewer. + */ +class LLWebProfile +{ + LOG_CLASS(LLWebProfile); + +public: + typedef boost::function status_callback_t; + + static void uploadImage(LLPointer image, const std::string& caption, bool add_location); + static void setAuthCookie(const std::string& cookie); + static void setImageUploadResultCallback(status_callback_t cb) { mStatusCallback = cb; } + +private: + friend class LLWebProfileResponders::ConfigResponder; + friend class LLWebProfileResponders::PostImageResponder; + friend class LLWebProfileResponders::PostImageRedirectResponder; + + static void post(LLPointer image, const LLSD& config, const std::string& url); + static void reportImageUploadStatus(bool ok); + static std::string getAuthCookie(); + + static std::string sAuthCookie; + static status_callback_t mStatusCallback; +}; + +#endif // LL_LLWEBPROFILE_H diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp index d6383d311..5235334f9 100644 --- a/indra/newview/llwldaycycle.cpp +++ b/indra/newview/llwldaycycle.cpp @@ -348,7 +348,7 @@ bool LLWLDayCycle::hasReferencesTo(const LLWLParamKey& keyframe) const void LLWLDayCycle::removeReferencesTo(const LLWLParamKey& keyframe) { lldebugs << "Removing references to key frame " << keyframe.toLLSD() << llendl; - F32 keytime; + F32 keytime = 0.f; // Avoid compiler warning. bool might_exist; do { diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp index 0495d9c51..e6eb7299c 100644 --- a/indra/newview/llwlhandlers.cpp +++ b/indra/newview/llwlhandlers.cpp @@ -108,18 +108,25 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() if (mID != sCount) { LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL; - return; } - - if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + else if (!gAgent.getRegion() || gAgent.getRegion()->getRegionID().isNull()) + { + LL_WARNS("WindlightCaps") << "Ignoring responder. Current region is invalid." << LL_ENDL; + } + else if (unvalidated_content[0]["regionID"].asUUID().isNull()) + { + LL_WARNS("WindlightCaps") << "Ignoring responder. Response from invalid region." << LL_ENDL; + } + else if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) { LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting " << gAgent.getRegion()->getRegionID() << " but got " << unvalidated_content[0]["regionID"].asUUID() << ") - ignoring..." << LL_ENDL; - return; } - - LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content); + else + { + LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content); + } } /*virtual*/ void LLEnvironmentRequestResponder::error(U32 status, const std::string& reason) { diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h index af19c74b3..969e188b6 100644 --- a/indra/newview/llwlhandlers.h +++ b/indra/newview/llwlhandlers.h @@ -56,9 +56,10 @@ class LLEnvironmentRequestResponder: public LLHTTPClient::ResponderWithResult { LOG_CLASS(LLEnvironmentRequestResponder); public: - virtual void result(const LLSD& content); - virtual void error(U32 status, const std::string& reason); - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return environmentRequestResponder_timeout; } + /*virtual*/ void result(const LLSD& content); + /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return environmentRequestResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLEnvironmentRequestResponder"; } private: friend class LLEnvironmentRequest; @@ -80,7 +81,7 @@ private: static clock_t UPDATE_WAIT_SECONDS; }; -class LLEnvironmentApplyResponder: public LLHTTPClient::ResponderWithResult +class LLEnvironmentApplyResponder : public LLHTTPClient::ResponderWithResult { LOG_CLASS(LLEnvironmentApplyResponder); public: @@ -98,11 +99,12 @@ public: * fail_reason : string * } */ - virtual void result(const LLSD& content); + /*virtual*/ void result(const LLSD& content); - virtual void error(U32 status, const std::string& reason); // non-200 errors only + /*virtual*/ void error(U32 status, const std::string& reason); // non-200 errors only - virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return environmentApplyResponder_timeout; } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return environmentApplyResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLEnvironmentApplyResponder"; } private: friend class LLEnvironmentApply; diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 284da40cd..cbcd5ec4e 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -475,7 +475,7 @@ void LLWLParamManager::propagateParameters(void) void LLWLParamManager::update(LLViewerCamera * cam) { LLFastTimer ftm(FTM_UPDATE_WLPARAM); - + // update clouds, sun, and general mCurParams.updateCloudScrolling(); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index ff0d1558a..0ad2cfbda 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -682,6 +682,12 @@ void LLWorld::updateRegions(F32 max_update_time) void LLWorld::updateParticles() { + static const LLCachedControl freeze_time("FreezeTime",false); + if (freeze_time) + { + // don't move particles in snapshot mode + return; + } LLViewerPartSim::getInstance()->updateSimulation(); } diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 91e1e6cda..752be770f 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -47,46 +47,79 @@ #include "llviewertexturelist.h" #include "llviewerregion.h" #include "llregionflags.h" - #include "hippogridmanager.h" -bool LLWorldMap::sGotMapURL = false; -const F32 AGENTS_UPDATE_TIMER = 60.0; // Seconds between 2 agent requests for a region -const F32 REQUEST_ITEMS_TIMER = 10.f * 60.f; // 10 minutes +#include "llworldmapmessage.h" +#include "hippogridmanager.h" + +bool LLWorldMap::sGotMapURL = false; +// Timers to temporise database requests +const F32 AGENTS_UPDATE_TIMER = 60.0; // Seconds between 2 agent requests for a region +const F32 REQUEST_ITEMS_TIMER = 10.f * 60.f; // Seconds before we consider re-requesting item data for the grid + +//--------------------------------------------------------------------------- +// LLItemInfo +//--------------------------------------------------------------------------- -// For DEV-17507, do lazy image loading in llworldmapview.cpp instead, -// limiting requests to currently visible regions and minimizing the -// number of textures being requested simultaneously. -// -// Uncomment IMMEDIATE_IMAGE_LOAD to restore the old behavior -// -//#define IMMEDIATE_IMAGE_LOAD LLItemInfo::LLItemInfo(F32 global_x, F32 global_y, const std::string& name, - LLUUID id, - S32 extra, S32 extra2) + LLUUID id) : mName(name), mToolTip(""), mPosGlobal(global_x, global_y, 40.0), mID(id), - mSelected(FALSE), - mExtra(extra), - mExtra2(extra2) + mCount(1) +// mSelected(false) +// mColor() { - mRegionHandle = to_region_handle(mPosGlobal); } +//--------------------------------------------------------------------------- +// LLSimInfo +//--------------------------------------------------------------------------- + LLSimInfo::LLSimInfo(U64 handle) : mHandle(handle), mName(), mAgentsUpdateTime(0), - mShowAgentLocations(FALSE), mAccess(0x0), mRegionFlags(0x0), - mWaterHeight(0.f), - mAlpha(-1.f) + mFirstAgentRequest(true), + mSizeX(REGION_WIDTH_UNITS), + mSizeY(REGION_WIDTH_UNITS), + mAlpha(0.f) { } +void LLSimInfo::setLandForSaleImage (LLUUID image_id) +{ + mMapImageID[SIM_LAYER_OVERLAY] = image_id; + // Fetch the image + if (mMapImageID[SIM_LAYER_OVERLAY].notNull()) + { + mLayerImage[SIM_LAYER_OVERLAY] = LLViewerTextureManager::getFetchedTexture(mMapImageID[SIM_LAYER_OVERLAY], MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); + mLayerImage[SIM_LAYER_OVERLAY]->setAddressMode(LLTexUnit::TAM_CLAMP); + } + else + { + mLayerImage[SIM_LAYER_OVERLAY] = NULL; + } +} + +LLPointer LLSimInfo::getLandForSaleImage () +{ + if (mLayerImage[SIM_LAYER_OVERLAY].isNull() && mMapImageID[SIM_LAYER_OVERLAY].notNull()) + { + // Fetch the image if it hasn't been done yet (unlikely but...) + mLayerImage[SIM_LAYER_OVERLAY] = LLViewerTextureManager::getFetchedTexture(mMapImageID[SIM_LAYER_OVERLAY], MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); + mLayerImage[SIM_LAYER_OVERLAY]->setAddressMode(LLTexUnit::TAM_CLAMP); + } + if (!mLayerImage[SIM_LAYER_OVERLAY].isNull()) + { + // Boost the fetch level when we try to access that image + mLayerImage[SIM_LAYER_OVERLAY]->setBoostLevel(LLGLTexture::BOOST_MAP); + } + return mLayerImage[SIM_LAYER_OVERLAY]; +} LLVector3d LLSimInfo::getGlobalPos(const LLVector3& local_pos) const { @@ -109,18 +142,31 @@ LLVector3 LLSimInfo::getLocalPos(LLVector3d global_pos) const void LLSimInfo::clearImage() { - if (!mOverlayImage.isNull()) + for(U32 layer = SIM_LAYER_BEGIN; layer < SIM_LAYER_COUNT;++layer) { - mOverlayImage->setBoostLevel(0); - mOverlayImage = NULL; + if(!mLayerImage[layer].isNull()) + { + mLayerImage[layer]->setBoostLevel(0); + mLayerImage[layer]=NULL; + } } } -void LLSimInfo::dropImagePriority() +void LLSimInfo::dropImagePriority(sim_layer_type layer/* = SIM_LAYER_COUNT*/) { - if (!mOverlayImage.isNull()) + if(layer == SIM_LAYER_COUNT) { - mOverlayImage->setBoostLevel(0); + for(U32 layer = SIM_LAYER_BEGIN; layer < SIM_LAYER_COUNT;++layer) + { + if(!mLayerImage[layer].isNull()) + { + mLayerImage[layer]->setBoostLevel(0); + } + } + } + else if(layer < SIM_LAYER_COUNT && layer >= SIM_LAYER_BEGIN && !mLayerImage[layer].isNull()) + { + mLayerImage[layer]->setBoostLevel(0); } } @@ -129,116 +175,154 @@ void LLSimInfo::updateAgentCount(F64 time) { if ((time - mAgentsUpdateTime > AGENTS_UPDATE_TIMER) || mFirstAgentRequest) { - LLWorldMap::getInstance()->sendItemRequest(MAP_ITEM_AGENT_LOCATIONS, mHandle); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_AGENT_LOCATIONS, mHandle); mAgentsUpdateTime = time; mFirstAgentRequest = false; } } + +// Get the total agents count +const S32 LLSimInfo::getAgentCount() const +{ + S32 total_agent_count = 0; + for (LLSimInfo::item_info_list_t::const_iterator it = mAgentLocations.begin(); it != mAgentLocations.end(); ++it) + { + total_agent_count += it->getCount(); + } + return total_agent_count; +} + bool LLSimInfo::isName(const std::string& name) const { return (LLStringUtil::compareInsensitive(name, mName) == 0); } +void LLSimInfo::dump() const +{ + U32 x_pos, y_pos; + from_region_handle(mHandle, &x_pos, &y_pos); + + LL_INFOS("World Map") << x_pos << "," << y_pos + << " " << mName + << " " << (S32)mAccess + << " " << std::hex << mRegionFlags << std::dec + << " " << mSizeX << "x" << mSizeY +// << " " << mWaterHeight + << LL_ENDL; +} + +void LLSimInfo::clearItems() +{ + mTelehubs.clear(); + mInfohubs.clear(); + mPGEvents.clear(); + mMatureEvents.clear(); + mAdultEvents.clear(); + mLandForSale.clear(); + mLandForSaleAdult.clear(); +// We persist the agent count though as it is updated on a frequent basis +// mAgentLocations.clear(); +} + +void LLSimInfo::insertAgentLocation(const LLItemInfo& item) +{ + std::string name = item.getName(); + + // Find the last item in the list with a different name and erase them + item_info_list_t::iterator lastiter; + for (lastiter = mAgentLocations.begin(); lastiter != mAgentLocations.end(); ++lastiter) + { + LLItemInfo& info = *lastiter; + if (info.isName(name)) + { + break; + } + } + if (lastiter != mAgentLocations.begin()) + { + mAgentLocations.erase(mAgentLocations.begin(), lastiter); + } + + // Now append the new location + mAgentLocations.push_back(item); +} + //--------------------------------------------------------------------------- // World Map //--------------------------------------------------------------------------- LLWorldMap::LLWorldMap() : - mIsTrackingUnknownLocation( FALSE ), - mInvalidLocation( FALSE ), - mIsTrackingDoubleClick( FALSE ), - mIsTrackingCommit( FALSE ), - mUnknownLocation( 0, 0, 0 ), - mRequestLandForSale(true), - mCurrentMap(0), - mMinX(U32_MAX), - mMaxX(U32_MIN), - mMinY(U32_MAX), - mMaxY(U32_MIN), - mNeighborMap(NULL), - mTelehubCoverageMap(NULL), - mNeighborMapWidth(0), - mNeighborMapHeight(0), - mSLURLRegionName(), - mSLURLRegionHandle(0), - mSLURL(), - mSLURLCallback(0), - mSLURLTeleport(false) + mIsTrackingLocation( false ), + mIsTrackingFound( false ), + mIsInvalidLocation( false ), + mIsTrackingDoubleClick( false ), + mIsTrackingCommit( false ), + mTrackingLocation( 0, 0, 0 ), + mFirstRequest(true), + mMapLoaded(false) { - for (S32 map=0; map LLWorldMap::LLWorldMap()" << LL_ENDL; + /*for (U32 map=SIM_LAYER_BEGIN; map LLWorldMap::~LLWorldMap()" << LL_ENDL; reset(); - for (S32 map=0; map REQUEST_ITEMS_TIMER) + bool clear = false; + if ((mRequestTimer.getElapsedTimeF32() > REQUEST_ITEMS_TIMER) || mFirstRequest || force) { mRequestTimer.reset(); - mTelehubs.clear(); - mInfohubs.clear(); - mPGEvents.clear(); - mMatureEvents.clear(); - mAdultEvents.clear(); - mLandForSale.clear(); + LLSimInfo* sim_info = NULL; + for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + { + sim_info = it->second; + if (sim_info) + { + sim_info->clearItems(); + } + } + clear = true; + mFirstRequest = false; } -// mAgentLocationsMap.clear(); // persists -// mNumAgents.clear(); // persists + return clear; } - void LLWorldMap::clearImageRefs() { // We clear the reference to the images we're holding. @@ -252,11 +336,6 @@ void LLWorldMap::clearImageRefs() sim_info = it->second; if(sim_info) { - if (sim_info->mCurrentImage) - { - sim_info->mCurrentImage->setBoostLevel(0); - sim_info->mCurrentImage = NULL; - } sim_info->clearImage(); } } @@ -265,12 +344,13 @@ void LLWorldMap::clearImageRefs() // Doesn't clear the already-loaded sim infos, just re-requests them void LLWorldMap::clearSimFlags() { - for (S32 map=0; map::const_iterator it; - for (it = LLWorldMap::getInstance()->mSimInfoMap.begin(); it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it) + sim_info_map_t::iterator it = mSimInfoMap.find(handle); + if (it != mSimInfoMap.end()) { - const U64 handle = (*it).first; - LLSimInfo* info = (*it).second; - if(handle == findhandle) - { - return info; - } - U32 x = 0, y = 0; - from_region_handle(findhandle, &x, &y); - U32 checkRegionX, checkRegionY; - from_region_handle(handle, &checkRegionX, &checkRegionY); - - if(x >= checkRegionX && x < (checkRegionX + info->getSizeX()) && - y >= checkRegionY && y < (checkRegionY + info->getSizeY())) - { - return info; - } + return it->second; } return NULL; } @@ -358,256 +423,75 @@ bool LLWorldMap::simNameFromPosGlobal(const LLVector3d& pos_global, std::string return (sim_info != NULL); } -void LLWorldMap::setCurrentLayer(S32 layer, bool request_layer) -{ - //TODO: we only have 1 layer -SG - mCurrentMap = layer; - if (!mMapLoaded[layer] || request_layer) - { - sendMapLayerRequest(); - } - - if (mTelehubs.size() == 0 || - mInfohubs.size() == 0) - { - // Request for telehubs - sendItemRequest(MAP_ITEM_TELEHUB); - } - - if (mPGEvents.size() == 0) - { - // Request for events - sendItemRequest(MAP_ITEM_PG_EVENT); - } - - if (mMatureEvents.size() == 0) - { - // Request for events (mature) - sendItemRequest(MAP_ITEM_MATURE_EVENT); - } - - if (mAdultEvents.size() == 0) - { - // Request for events (adult) - sendItemRequest(MAP_ITEM_ADULT_EVENT); - } - - if (mLandForSale.size() == 0) - { - // Request for Land For Sale - sendItemRequest(MAP_ITEM_LAND_FOR_SALE); - } - - if (mLandForSaleAdult.size() == 0) - { - // Request for Land For Sale - sendItemRequest(MAP_ITEM_LAND_FOR_SALE_ADULT); - } - - clearImageRefs(); - clearSimFlags(); -} - -void LLWorldMap::sendItemRequest(U32 type, U64 handle) -{ - LLMessageSystem* msg = gMessageSystem; - S32 layer = mCurrentMap; - - msg->newMessageFast(_PREHASH_MapItemRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_Flags, layer); - msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim - msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim - - msg->nextBlockFast(_PREHASH_RequestData); - msg->addU32Fast(_PREHASH_ItemType, type); - msg->addU64Fast(_PREHASH_RegionHandle, handle); // If zero, filled in on sim - - gAgent.sendReliableMessage(); -} - // public void LLWorldMap::sendMapLayerRequest() { if (!gAgent.getRegion()) return; - LLSD body; - body["Flags"] = mCurrentMap; std::string url = gAgent.getRegion()->getCapability( gAgent.isGodlike() ? "MapLayerGod" : "MapLayer"); + U32 flags = layerToFlags((sim_layer_type)SIM_LAYER_COMPOSITE); if (!url.empty()) { - llinfos << "LLWorldMap::sendMapLayerRequest via capability" << llendl; + LLSD body; + body["Flags"] = (LLSD::Integer)flags; + //llinfos << "LLWorldMap::sendMapLayerRequest via capability" << llendl; LLHTTPClient::post(url, body, new LLMapLayerResponder); } else { - llinfos << "LLWorldMap::sendMapLayerRequest via message system" << llendl; + //llinfos << "LLWorldMap::sendMapLayerRequest via message system" << llendl; LLMessageSystem* msg = gMessageSystem; - S32 layer = mCurrentMap; // Request for layer msg->newMessageFast(_PREHASH_MapLayerRequest); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_Flags, layer); + msg->addU32Fast(_PREHASH_Flags, flags); msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim gAgent.sendReliableMessage(); - - if (mRequestLandForSale) - { - msg->newMessageFast(_PREHASH_MapLayerRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_Flags, 2); - msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim - msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim - gAgent.sendReliableMessage(); - } } } -// public -void LLWorldMap::sendNamedRegionRequest(std::string region_name) -{ - LLMessageSystem* msg = gMessageSystem; - S32 layer = mCurrentMap; - // Request for layer - msg->newMessageFast(_PREHASH_MapNameRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_Flags, layer); - msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim - msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim - msg->nextBlockFast(_PREHASH_NameData); - msg->addStringFast(_PREHASH_Name, region_name); - gAgent.sendReliableMessage(); -} -// public -void LLWorldMap::sendNamedRegionRequest(std::string region_name, - url_callback_t callback, - const std::string& callback_url, - bool teleport) // immediately teleport when result returned -{ - mSLURLRegionName = region_name; - mSLURLRegionHandle = 0; - mSLURL = callback_url; - mSLURLCallback = callback; - mSLURLTeleport = teleport; - - sendNamedRegionRequest(region_name); -} - -void LLWorldMap::sendHandleRegionRequest(U64 region_handle, - url_callback_t callback, - const std::string& callback_url, - bool teleport) // immediately teleport when result returned -{ - mSLURLRegionName.clear(); - mSLURLRegionHandle = region_handle; - mSLURL = callback_url; - mSLURLCallback = callback; - mSLURLTeleport = teleport; - - U32 global_x; - U32 global_y; - from_region_handle(region_handle, &global_x, &global_y); - U16 grid_x = (U16)(global_x / REGION_WIDTH_UNITS); - U16 grid_y = (U16)(global_y / REGION_WIDTH_UNITS); - - sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true); -} - -// public -void LLWorldMap::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent) -{ - S32 layer = mCurrentMap; - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_MapBlockRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - U32 flags = layer; - flags |= (return_nonexistent ? 0x10000 : 0); - msg->addU32Fast(_PREHASH_Flags, flags); - msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim - msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim - msg->nextBlockFast(_PREHASH_PositionData); - msg->addU16Fast(_PREHASH_MinX, min_x); - msg->addU16Fast(_PREHASH_MinY, min_y); - msg->addU16Fast(_PREHASH_MaxX, max_x); - msg->addU16Fast(_PREHASH_MaxY, max_y); - gAgent.sendReliableMessage(); - - if (mRequestLandForSale) - { - msg->newMessageFast(_PREHASH_MapBlockRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_Flags, 2); - msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim - msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim - msg->nextBlockFast(_PREHASH_PositionData); - msg->addU16Fast(_PREHASH_MinX, min_x); - msg->addU16Fast(_PREHASH_MinY, min_y); - msg->addU16Fast(_PREHASH_MaxX, max_x); - msg->addU16Fast(_PREHASH_MaxY, max_y); - gAgent.sendReliableMessage(); - } -} // public static void LLWorldMap::processMapLayerReply(LLMessageSystem* msg, void**) { - llinfos << "LLWorldMap::processMapLayerReply from message system" << llendl; + //llinfos << "LLWorldMap::processMapLayerReply from message system" << llendl; U32 agent_flags; msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); - if (agent_flags != (U32)LLWorldMap::getInstance()->mCurrentMap) + U32 layer = flagsToLayer(agent_flags); + if (layer != SIM_LAYER_COMPOSITE) { llwarns << "Invalid or out of date map image type returned!" << llendl; return; } LLUUID image_id; - //U32 left, right, top, bottom; S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_LayerData); - LLWorldMap::getInstance()->mMapLayers[agent_flags].clear(); + LLWorldMap::getInstance()->mMapLayers.clear(); -// bool use_web_map_tiles = useWebMapTiles(); - BOOL adjust = FALSE; for (S32 block=0; blockgetUUIDFast(_PREHASH_LayerData, _PREHASH_ImageID, new_layer.LayerImageID, block); - + U32 left, right, top, bottom; msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Left, left, block); msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Right, right, block); msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Top, top, block); msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Bottom, bottom, block); -// if (use_web_map_tiles) -// { -// new_layer.LayerImage = loadObjectsTile(left, bottom); // no good... Maybe using of level 2 and higher web maps ? -// } -// else -// { - new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); -// } + new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID, MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); gGL.getTexUnit(0)->bind(new_layer.LayerImage.get()); new_layer.LayerImage->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -617,269 +501,148 @@ void LLWorldMap::processMapLayerReply(LLMessageSystem* msg, void**) new_layer.LayerExtents.mBottom = bottom; new_layer.LayerExtents.mTop = top; - F32 x_meters = F32(left*REGION_WIDTH_UNITS); - F32 y_meters = F32(bottom*REGION_WIDTH_UNITS); - adjust = LLWorldMap::getInstance()->extendAABB(U32(x_meters), U32(y_meters), - U32(x_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getWidth()), - U32(y_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getHeight())) || adjust; - - LLWorldMap::getInstance()->mMapLayers[agent_flags].push_back(new_layer); + LLWorldMap::getInstance()->mMapLayers.push_back(new_layer); } - LLWorldMap::getInstance()->mMapLoaded[agent_flags] = TRUE; - if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); + LLWorldMap::getInstance()->mMapLoaded = true; } // public static bool LLWorldMap::useWebMapTiles() { - return gSavedSettings.getBOOL("UseWebMapTiles") && - (( gHippoGridManager->getConnectedGrid()->isSecondLife() || sGotMapURL) && LLWorldMap::getInstance()->mCurrentMap == 0); + static const LLCachedControl use_web_map_tiles("UseWebMapTiles",false); + return use_web_map_tiles && + (( gHippoGridManager->getConnectedGrid()->isSecondLife() || sGotMapURL)); } -// public static -LLPointer LLWorldMap::loadObjectsTile(U32 grid_x, U32 grid_y) +void LLWorldMap::reloadItems(bool force) { - // Get the grid coordinates - std::string imageurl = gSavedSettings.getString("MapServerURL") + llformat("map-%d-%d-%d-objects.jpg", 1, grid_x, grid_y); - - LLPointer img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl,TRUE,LLViewerTexture::BOOST_MAP,LLViewerTexture::LOD_TEXTURE); - img->setBoostLevel(LLViewerTexture::BOOST_MAP); - - // Return the smart pointer - return img; -} - -// public static -void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) -{ - U32 agent_flags; - msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); - - if ((S32)agent_flags < 0 || agent_flags >= MAP_SIM_IMAGE_TYPES) + //LL_INFOS("World Map") << "LLWorldMap::reloadItems()" << LL_ENDL; + if (clearItems(force)) { - llwarns << "Invalid map image type returned! " << agent_flags << llendl; - return; + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_TELEHUB); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_PG_EVENT); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_MATURE_EVENT); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_ADULT_EVENT); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_LAND_FOR_SALE); } - - S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data); - - bool found_null_sim = false; - -#ifdef IMMEDIATE_IMAGE_LOAD - bool use_web_map_tiles = useWebMapTiles(); -#endif - BOOL adjust = FALSE; - for (S32 block=0; blockgetU16Fast(_PREHASH_Data, _PREHASH_X, x_regions, block); - msg->getU16Fast(_PREHASH_Data, _PREHASH_Y, y_regions, block); - msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block); - msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, accesscode, block); - msg->getU32Fast(_PREHASH_Data, _PREHASH_RegionFlags, region_flags, block); - msg->getU8Fast(_PREHASH_Data, _PREHASH_WaterHeight, water_height, block); - msg->getU8Fast(_PREHASH_Data, _PREHASH_Agents, agents, block); - msg->getUUIDFast(_PREHASH_Data, _PREHASH_MapImageID, image_id, block); - if(msg->getNumberOfBlocksFast(_PREHASH_Size) > 0) + if(!mMapLoaded || force) + sendMapLayerRequest(); + } +} + + +// static public +// Insert a region in the region map +// returns true if region inserted, false otherwise +bool LLWorldMap::insertRegion(U32 x_world, U32 y_world, U32 x_size, U32 y_size, U32 agent_flags, std::string& name, LLUUID& image_id, U32 accesscode, U32 region_flags) +{ + // This region doesn't exist + if (accesscode == 255) + { + // Checks if the track point is in it and invalidates it if it is + if (LLWorldMap::getInstance()->isTrackingInRectangle( x_world, y_world, x_world + REGION_WIDTH_UNITS, y_world + REGION_WIDTH_UNITS)) { - msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeX, x_size, block); - msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeY, y_size, block); + LLWorldMap::getInstance()->setTrackingInvalid(); } - if(x_size == 0 || (x_size % 16) != 0|| (y_size % 16) != 0) + // return failure to insert + return false; + } + else + { + U64 handle = to_region_handle(x_world, y_world); + //LL_INFOS("World Map") << "Map sim : " << name << ", ID : " << image_id.getString() << LL_ENDL; + // Insert the region in the region map of the world map + // Loading the LLSimInfo object with what we got and insert it in the map + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if (siminfo == NULL) { - x_size = 256; - y_size = 256; + siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); } - U32 x_meters = x_regions * REGION_WIDTH_UNITS; - U32 y_meters = y_regions * REGION_WIDTH_UNITS; + siminfo->setName( name ); + siminfo->setAccess( accesscode ); + siminfo->setRegionFlags( region_flags ); + //siminfo->setWaterHeight((F32) water_height); + U32 layer = flagsToLayer(agent_flags); + if (layer == SIM_LAYER_OVERLAY) + siminfo->setLandForSaleImage(image_id); + else if(layer < SIM_LAYER_COUNT) + siminfo->setMapImageID( image_id, layer ); + siminfo->setSize( x_size, y_size ); - U64 handle = to_region_handle(x_meters, y_meters); - - if (accesscode == 255) + // Handle the location tracking (for teleport, UI feedback and info display) + if (LLWorldMap::getInstance()->isTrackingInRectangle( x_world, y_world, x_world + REGION_WIDTH_UNITS, y_world + REGION_WIDTH_UNITS)) { - // This region doesn't exist - if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) + if (siminfo->isDown()) { - // We were tracking this location, but it doesn't exist - LLWorldMap::getInstance()->mInvalidLocation = TRUE; - } - - found_null_sim = true; - } - else - { - adjust = LLWorldMap::getInstance()->extendAABB(x_meters, - y_meters, - x_meters+REGION_WIDTH_UNITS, - y_meters+REGION_WIDTH_UNITS) || adjust; - //LL_INFOS("World Map") << "Map sim : " << name << ", ID : " << image_id.getString() << LL_ENDL; - // Insert the region in the region map of the world map - // Loading the LLSimInfo object with what we got and insert it in the map - LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); - if (siminfo == NULL) - { - siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); - } - - siminfo->setName( name ); - siminfo->setAccess( accesscode ); - siminfo->setRegionFlags( region_flags ); - siminfo->setWaterHeight((F32) water_height); - siminfo->setMapImageID( image_id, agent_flags ); - siminfo->setSize( x_size, y_size ); - -#ifdef IMMEDIATE_IMAGE_LOAD - if (use_web_map_tiles) - { - siminfo->mCurrentImage = loadObjectsTile((U32)x_regions, (U32)y_regions); + // We were tracking this location, but it's no available + LLWorldMap::getInstance()->setTrackingInvalid(); } else { - siminfo->mCurrentImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE); + // We were tracking this location, and it does exist and is available + LLWorldMap::getInstance()->setTrackingValid(); } - gGL.getTexUnit(0)->bind(siminfo->mCurrentImage.get()); - siminfo->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); -#endif + } + // return insert region success + return true; + } +} + +// static public +// Insert an item in the relevant region map +// returns true if item inserted, false otherwise +bool LLWorldMap::insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID& uuid, U32 type, S32 extra, S32 extra2) +{ + // Create an item record for the received object + LLItemInfo new_item((F32)x_world, (F32)y_world, name, uuid); + + // Compute a region handle based on the objects coordinates + LLVector3d pos((F32)x_world, (F32)y_world, 40.0); + U64 handle = to_region_handle(pos); + + // Get the region record for that handle or NULL if we haven't browsed it yet + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if (siminfo == NULL) + { + siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); + } + + //LL_INFOS("World Map") << "Process item : type = " << type << LL_ENDL; + switch (type) + { + case MAP_ITEM_TELEHUB: // telehubs + { + /* Merov: we are not using the hub color anymore for display so commenting that out + // Telehub color + U32 X = x_world / REGION_WIDTH_UNITS; + U32 Y = y_world / REGION_WIDTH_UNITS; + F32 red = fmod((F32)X * 0.11f, 1.f) * 0.8f; + F32 green = fmod((F32)Y * 0.11f, 1.f) * 0.8f; + F32 blue = fmod(1.5f * (F32)(X + Y) * 0.11f, 1.f) * 0.8f; + F32 add_amt = (X % 2) ? 0.15f : -0.15f; + add_amt += (Y % 2) ? -0.15f : 0.15f; + LLColor4 color(red + add_amt, green + add_amt, blue + add_amt); + new_item.setColor(color); + */ - if (siminfo->mMapImageID[2].notNull()) + // extra2 specifies whether this is an infohub or a telehub. + if (extra2) { -#ifdef IMMEDIATE_IMAGE_LOAD - siminfo->mOverlayImage = LLViewerTextureManager::getFetchedTextureURL(siminfo->mMapImageID[2]); -#endif + siminfo->insertInfoHub(new_item); } else { - siminfo->mOverlayImage = NULL; - } - - if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) - { - if (siminfo->isDown()) - { - // We were tracking this location, but it doesn't exist - LLWorldMap::getInstance()->mInvalidLocation = true; - } - else - { - // We were tracking this location, and it does exist - bool is_tracking_dbl = LLWorldMap::getInstance()->mIsTrackingDoubleClick == TRUE; - gFloaterWorldMap->trackLocation(LLWorldMap::getInstance()->mUnknownLocation); - if (is_tracking_dbl) - { - LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); - gAgent.teleportViaLocation( pos_global ); - } - } + siminfo->insertTeleHub(new_item); } + break; } - - if(LLWorldMap::getInstance()->mSLURLCallback != NULL) - { - // Server returns definitive capitalization, SLURL might not have that. - if ((LLStringUtil::compareInsensitive(LLWorldMap::getInstance()->mSLURLRegionName, name)==0) - || (LLWorldMap::getInstance()->mSLURLRegionHandle == handle)) - { - url_callback_t callback = LLWorldMap::getInstance()->mSLURLCallback; - - LLWorldMap::getInstance()->mSLURLCallback = NULL; - LLWorldMap::getInstance()->mSLURLRegionName.clear(); - LLWorldMap::getInstance()->mSLURLRegionHandle = 0; - - callback(handle, LLWorldMap::getInstance()->mSLURL, image_id, LLWorldMap::getInstance()->mSLURLTeleport); - } - } - if( gAgent.mPendingLure && - (U16)(gAgent.mPendingLure->mPosGlobal.mdV[0] / REGION_WIDTH_UNITS) == x_regions && - (U16)(gAgent.mPendingLure->mPosGlobal.mdV[1] / REGION_WIDTH_UNITS) == y_regions ) - { - gAgent.onFoundLureDestination(); - } - } - - if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); - gFloaterWorldMap->updateSims(found_null_sim); -} - -// public static -void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**) -{ - U32 type; - msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ItemType, type); - - S32 num_blocks = msg->getNumberOfBlocks("Data"); - - for (S32 block=0; blockgetU32Fast(_PREHASH_Data, _PREHASH_X, X, block); - msg->getU32Fast(_PREHASH_Data, _PREHASH_Y, Y, block); - msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block); - msg->getUUIDFast(_PREHASH_Data, _PREHASH_ID, uuid, block); - msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra, extra, block); - msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra2, extra2, block); - - F32 world_x = (F32)X; - X /= REGION_WIDTH_UNITS; - F32 world_y = (F32)Y; - Y /= REGION_WIDTH_UNITS; - - LLItemInfo new_item(world_x, world_y, name, uuid, extra, extra2); - LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(new_item.getRegionHandle()); - - switch (type) - { - case MAP_ITEM_TELEHUB: // telehubs - { - // Telehub color, store in extra as 4 U8's - U8 *color = (U8 *)&new_item.mExtra; - - F32 red = fmod((F32)X * 0.11f, 1.f) * 0.8f; - F32 green = fmod((F32)Y * 0.11f, 1.f) * 0.8f; - F32 blue = fmod(1.5f * (F32)(X + Y) * 0.11f, 1.f) * 0.8f; - F32 add_amt = (X % 2) ? 0.15f : -0.15f; - add_amt += (Y % 2) ? -0.15f : 0.15f; - color[0] = U8((red + add_amt) * 255); - color[1] = U8((green + add_amt) * 255); - color[2] = U8((blue + add_amt) * 255); - color[3] = 255; - - // extra2 specifies whether this is an infohub or a telehub. - if (extra2) - { - LLWorldMap::getInstance()->mInfohubs.push_back(new_item); - } - else - { - LLWorldMap::getInstance()->mTelehubs.push_back(new_item); - } - - break; - } - case MAP_ITEM_PG_EVENT: // events - case MAP_ITEM_MATURE_EVENT: - case MAP_ITEM_ADULT_EVENT: + case MAP_ITEM_PG_EVENT: // events + case MAP_ITEM_MATURE_EVENT: + case MAP_ITEM_ADULT_EVENT: { struct tm* timep; // Convert to Pacific, based on server's opinion of whether @@ -894,252 +657,64 @@ void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**) timep->tm_min, (timep->tm_hour < 12 ? "AM" : "PM") ) ); - // HACK: store Z in extra2 - new_item.setElevation((F64)extra2); - if (type == MAP_ITEM_PG_EVENT) - { - LLWorldMap::getInstance()->mPGEvents.push_back(new_item); - } - else if (type == MAP_ITEM_MATURE_EVENT) - { - LLWorldMap::getInstance()->mMatureEvents.push_back(new_item); - } - else if (type == MAP_ITEM_ADULT_EVENT) - { - LLWorldMap::getInstance()->mAdultEvents.push_back(new_item); - } - - break; - } - case MAP_ITEM_LAND_FOR_SALE: // land for sale - case MAP_ITEM_LAND_FOR_SALE_ADULT: // adult land for sale + // HACK: store Z in extra2 + new_item.setElevation((F64)extra2); + if (type == MAP_ITEM_PG_EVENT) { - new_item.setTooltip(llformat("%d sq. m. %s%d", new_item.mExtra, - gHippoGridManager->getConnectedGrid()->getCurrencySymbol().c_str(), - new_item.mExtra2)); - if (type == MAP_ITEM_LAND_FOR_SALE) - { - LLWorldMap::getInstance()->mLandForSale.push_back(new_item); - } - else if (type == MAP_ITEM_LAND_FOR_SALE_ADULT) - { - LLWorldMap::getInstance()->mLandForSaleAdult.push_back(new_item); + siminfo->insertPGEvent(new_item); + } + else if (type == MAP_ITEM_MATURE_EVENT) + { + siminfo->insertMatureEvent(new_item); + } + else if (type == MAP_ITEM_ADULT_EVENT) + { + siminfo->insertAdultEvent(new_item); + } + break; + } + case MAP_ITEM_LAND_FOR_SALE: // land for sale + case MAP_ITEM_LAND_FOR_SALE_ADULT: // adult land for sale + { + new_item.setTooltip(llformat("%d sq. m. %s%d", extra, + gHippoGridManager->getConnectedGrid()->getCurrencySymbol().c_str(), + extra2)); + if (type == MAP_ITEM_LAND_FOR_SALE) + { + siminfo->insertLandForSale(new_item); + } + else if (type == MAP_ITEM_LAND_FOR_SALE_ADULT) + { + siminfo->insertLandForSaleAdult(new_item); } break; } case MAP_ITEM_CLASSIFIED: // classifieds { - //DEPRECATED: no longer used - break; - } - case MAP_ITEM_AGENT_LOCATIONS: // agent locations - { - if (!siminfo) - { - llinfos << "siminfo missing for " << new_item.getGlobalPosition().mdV[0] << ", " << new_item.getGlobalPosition().mdV[1] << llendl; - break; - } -// llinfos << "New Location " << new_item.mName << llendl; - - item_info_list_t& agentcounts = LLWorldMap::getInstance()->mAgentLocationsMap[new_item.getRegionHandle()]; - - // Find the last item in the list with a different name and erase them - item_info_list_t::iterator lastiter; - for (lastiter = agentcounts.begin(); lastiter!=agentcounts.end(); ++lastiter) - { - const LLItemInfo& info = *lastiter; - if (info.isName(new_item.getName())) - { - break; - } - } - if (lastiter != agentcounts.begin()) - { - agentcounts.erase(agentcounts.begin(), lastiter); - } - // Now append the new location - if (new_item.mExtra > 0) - { - agentcounts.push_back(new_item); - } - break; - } - default: - break; - }; - } -} - -void LLWorldMap::dump() -{ - for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) - { - U64 handle = (*it).first; - LLSimInfo* info = (*it).second; - - U32 x_pos, y_pos; - from_region_handle(handle, &x_pos, &y_pos); - - llinfos << x_pos << "," << y_pos - << " " << info->getName() - << " " << (S32)info->getAccess() - << " " << std::hex << info->getRegionFlags() << std::dec - << " " << info->getWaterHeight() - //<< " " << info->mTelehubName - //<< " " << info->mTelehubPosition - << llendl; - - if (info->mCurrentImage) - { - llinfos << "image discard " << (S32)info->mCurrentImage->getDiscardLevel() - << " fullwidth " << info->mCurrentImage->getWidth(0) - << " fullheight " << info->mCurrentImage->getHeight(0) - << " maxvirt " << info->mCurrentImage->getMaxVirtualSize() - << " maxdisc " << (S32)info->mCurrentImage->getMaxDiscardLevel() - << llendl; + //DEPRECATED: no longer used + break; } - } -} - - -BOOL LLWorldMap::extendAABB(U32 min_x, U32 min_y, U32 max_x, U32 max_y) -{ - BOOL rv = FALSE; - if (min_x < mMinX) - { - rv = TRUE; - mMinX = min_x; - } - if (min_y < mMinY) - { - rv = TRUE; - mMinY = min_y; - } - if (max_x > mMaxX) - { - rv = TRUE; - mMaxX = max_x; - } - if (max_y > mMaxY) - { - rv = TRUE; - mMaxY = max_y; - } - lldebugs << "World map aabb: (" << mMinX << ", " << mMinY << "), (" - << mMaxX << ", " << mMaxY << ")" << llendl; - return rv; -} - - -U32 LLWorldMap::getWorldWidth() const -{ - return mMaxX - mMinX; -} - - -U32 LLWorldMap::getWorldHeight() const -{ - return mMaxY - mMinY; -} - -BOOL LLWorldMap::coveredByTelehub(LLSimInfo* infop) -{ - /*if (!mTelehubCoverageMap) - { - return FALSE; - } - U32 x_pos, y_pos; - from_region_handle(infop->mHandle, &x_pos, &y_pos); - x_pos /= REGION_WIDTH_UNITS; - y_pos /= REGION_WIDTH_UNITS; - - S32 index = x_pos - (mMinX / REGION_WIDTH_UNITS - 1) + (mNeighborMapWidth * (y_pos - (mMinY / REGION_WIDTH_UNITS - 1))); - return mTelehubCoverageMap[index] != 0; */ - return FALSE; -} - -void LLWorldMap::updateTelehubCoverage() -{ - /*S32 neighbor_width = getWorldWidth() / REGION_WIDTH_UNITS + 2; - S32 neighbor_height = getWorldHeight() / REGION_WIDTH_UNITS + 2; - if (neighbor_width > mNeighborMapWidth || neighbor_height > mNeighborMapHeight) - { - mNeighborMapWidth = neighbor_width; - mNeighborMapHeight = neighbor_height; - delete mNeighborMap; - delete mTelehubCoverageMap; - - mNeighborMap = new U8[mNeighborMapWidth * mNeighborMapHeight]; - mTelehubCoverageMap = new U8[mNeighborMapWidth * mNeighborMapHeight]; - } - - memset(mNeighborMap, 0, mNeighborMapWidth * mNeighborMapHeight * sizeof(U8)); - memset(mTelehubCoverageMap, 0, mNeighborMapWidth * mNeighborMapHeight * sizeof(U8)); - - // leave 1 sim border - S32 min_x = (mMinX / REGION_WIDTH_UNITS) - 1; - S32 min_y = (mMinY / REGION_WIDTH_UNITS) - 1; - - std::map::const_iterator it; - for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) - { - U64 handle = (*it).first; - //LLSimInfo* info = (*it).second; - - U32 x_pos, y_pos; - from_region_handle(handle, &x_pos, &y_pos); - x_pos /= REGION_WIDTH_UNITS; - y_pos /= REGION_WIDTH_UNITS; - x_pos -= min_x; - y_pos -= min_y; - - S32 index = x_pos + (mNeighborMapWidth * y_pos); - mNeighborMap[index - 1]++; - mNeighborMap[index + 1]++; - mNeighborMap[index - mNeighborMapWidth]++; - mNeighborMap[index + mNeighborMapWidth]++; - } - - for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) - { - U64 handle = (*it).first; - LLSimInfo* info = (*it).second; - - U32 x_pos, y_pos; - from_region_handle(handle, &x_pos, &y_pos); - x_pos /= REGION_WIDTH_UNITS; - y_pos /= REGION_WIDTH_UNITS; - x_pos -= min_x; - y_pos -= min_y; - - S32 index = x_pos + (mNeighborMapWidth * y_pos); - - if (!info->mTelehubName.empty() && mNeighborMap[index]) + case MAP_ITEM_AGENT_LOCATIONS: // agent locations { - S32 x_start = llmax(0, S32(x_pos - 5)); - S32 x_span = llmin(mNeighborMapWidth - 1, (S32)(x_pos + 5)) - x_start + 1; - S32 y_start = llmax(0, (S32)y_pos - 5); - S32 y_end = llmin(mNeighborMapHeight - 1, (S32)(y_pos + 5)); - for (S32 y_index = y_start; y_index <= y_end; y_index++) +// LL_INFOS("World Map") << "New Location " << new_item.mName << LL_ENDL; + if (extra > 0) { - memset(&mTelehubCoverageMap[x_start + y_index * mNeighborMapWidth], 0xff, sizeof(U8) * x_span); + new_item.setCount(extra); + siminfo->insertAgentLocation(new_item); } + break; } + default: + break; } + return true; +} - for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) - { - U64 handle = (*it).first; - //LLSimInfo* info = (*it).second; - - U32 x_pos, y_pos; - from_region_handle(handle, &x_pos, &y_pos); - x_pos /= REGION_WIDTH_UNITS; - y_pos /= REGION_WIDTH_UNITS; - - S32 index = x_pos - min_x + (mNeighborMapWidth * (y_pos - min_y)); - mTelehubCoverageMap[index] *= mNeighborMap[index]; - }*/ +bool LLWorldMap::isTrackingInRectangle(F64 x0, F64 y0, F64 x1, F64 y1) +{ + if (!mIsTrackingLocation) + return false; + return ((mTrackingLocation[0] >= x0) && (mTrackingLocation[0] < x1) && (mTrackingLocation[1] >= y0) && (mTrackingLocation[1] < y1)); } // Drop priority of all images being fetched by the map @@ -1155,19 +730,85 @@ void LLWorldMap::dropImagePriorities() } } -LLPointer LLSimInfo::getLandForSaleImage () +// Load all regions in a given rectangle (in region grid coordinates, i.e. world / 256 meters) +void LLWorldMap::updateRegions(S32 x0, S32 y0, S32 x1, S32 y1) { - if (mOverlayImage.isNull() && mMapImageID[2].notNull()) + // Convert those boundaries to the corresponding (MAP_BLOCK_SIZE x MAP_BLOCK_SIZE) block coordinates + U32 global_x0 = x0 / MAP_BLOCK_SIZE; + U32 global_x1 = x1 / MAP_BLOCK_SIZE; + U32 global_y0 = y0 / MAP_BLOCK_SIZE; + U32 global_y1 = y1 / MAP_BLOCK_SIZE; + + //Singu note: There's a bunch of extra logic here, as opensim grids support sim coordinates that extend beyond the range + // used on the official grid. We basically just extend what LL had here by nesting the mMapBlockLoaded array in a 'dynamic' grid, + // essentially making that array a 'block' itself. An std::map was used to conserve memory, as we selectively only allocate desired + // blocks, and although lookups aren't blazingly fast with that container, it isn't likeley to accumulate very many entries. + + //MapBlockRequest uses U16 for coordinate components. + // In order not to exceed U16_MAX values, MAP_BLOCK_RES*MAP_BLOCK_SIZE*(i or j) can't exceed U16_MAX(65535) + U32 max_range = (U16_MAX+1)/MAP_BLOCK_RES/MAP_BLOCK_SIZE - 1; + + //Desired coordinate ranges in our 'dynamic' grid of 512x512 grids of 4x4 sim blocks. + U32 map_block_x0 = global_x0 / MAP_BLOCK_RES; + U32 map_block_x1 = llmin(global_x1 / MAP_BLOCK_RES, max_range); + U32 map_block_y0 = global_y0 / MAP_BLOCK_RES; + U32 map_block_y1 = llmin(global_y1 / MAP_BLOCK_RES, max_range); + + const bool layer_start = useWebMapTiles() ? SIM_LAYER_OVERLAY : SIM_LAYER_BEGIN; + for (U32 i = map_block_x0; i <= map_block_x1; ++i) { - // Fetch the image if it hasn't been done yet (unlikely but...) - mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID[2], MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); - mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP); - } - if (!mOverlayImage.isNull()) + for (U32 j = map_block_y0; j <= map_block_y1; ++j) { - // Boost the fetch level when we try to access that image - mOverlayImage->setBoostLevel(LLViewerTexture::BOOST_MAP); + + //Desired coordinate ranges in our 512x512 grids of 4x4 sim blocks. + x0 = global_x0 - i * MAP_BLOCK_RES; + x1 = llmin(global_x1 - i * (U32)MAP_BLOCK_RES, (U32)MAP_BLOCK_RES-1); + y0 = global_y0 - j * MAP_BLOCK_RES; + y1 = llmin(global_y1 - j * (U32)MAP_BLOCK_RES, (U32)MAP_BLOCK_RES-1); + + for(U32 layer = layer_start;layer &block = mMapBlockMap[layer][(i << 16) | j]; + if(block.empty()) + { + //New block. Allocate the array and set all entries to false. (seen as mMapBlockLoaded in v3) + block.resize(MAP_BLOCK_RES*MAP_BLOCK_RES,false); + } + + // Load the region info those blocks + for (S32 block_x = llmax(x0, 0); block_x <= llmin(x1, MAP_BLOCK_RES-1); ++block_x) + { + for (S32 block_y = llmax(y0, 0); block_y <= llmin(y1, MAP_BLOCK_RES-1); ++block_y) + { + S32 offset = block_x | (block_y * MAP_BLOCK_RES); + // if(!mMapBlockLoaded[LLWorldMap::getInstance()->mCurrentMap][offset]) + if (!block[offset]) + { + U16 min_x = (block_x + i * MAP_BLOCK_RES) * MAP_BLOCK_SIZE; + U16 max_x = min_x + MAP_BLOCK_SIZE - 1; + U16 min_y = (block_y + j * MAP_BLOCK_RES) * MAP_BLOCK_SIZE; + U32 max_y = min_y + MAP_BLOCK_SIZE - 1; + + //LL_INFOS("World Map") << "Loading Block (" << block_x << "," << block_y << ")" << LL_ENDL; + LLWorldMapMessage::getInstance()->sendMapBlockRequest(min_x, min_y, max_x, max_y, false, layerToFlags((sim_layer_type)layer)); + block[offset] = true; + } + } + } + } + } } - return mOverlayImage; } +void LLWorldMap::dump() +{ + LL_INFOS("World Map") << "LLWorldMap::dump()" << LL_ENDL; + for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + { + LLSimInfo* info = it->second; + if (info) + { + info->dump(); + } + } +} diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index c9e6be37e..fd654316d 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -51,39 +51,80 @@ class LLMessageSystem; - +// Description of objects like hubs, events, land for sale, people and more (TBD). +// Note: we don't store a "type" in there so we need to store instances of this class in +// well known objects (i.e. list of objects which type is "well known"). class LLItemInfo { public: - LLItemInfo(F32 global_x, F32 global_y, const std::string& name, LLUUID id, S32 extra = 0, S32 extra2 = 0); + LLItemInfo(F32 global_x, F32 global_y, const std::string& name, LLUUID id); // Setters void setTooltip(const std::string& tooltip) { mToolTip = tooltip; } void setElevation(F64 z) { mPosGlobal.mdV[VZ] = z; } + void setCount(S32 count) { mCount = count; } +// void setSelected(bool selected) { mSelected = selected; } +// void setColor(LLColor4 color) { mColor = color; } + // Accessors const LLVector3d& getGlobalPosition() const { return mPosGlobal; } const std::string& getName() const { return mName; } const std::string& getToolTip() const { return mToolTip; } const LLUUID& getUUID() const { return mID; } - U64 getRegionHandle() const { return mRegionHandle; } + S32 getCount() const { return mCount; } + + U64 getRegionHandle() const { return to_region_handle(mPosGlobal); } // Build the handle on the fly + bool isName(const std::string& name) const { return (mName == name); } // True if name same as item's name +// bool isSelected() const { return mSelected; } + private: - std::string mName; - std::string mToolTip; - LLVector3d mPosGlobal; - LLUUID mID; - U64 mRegionHandle; -public: //public for now.. non-standard. - BOOL mSelected; - S32 mExtra; - S32 mExtra2; + std::string mName; // Name of the individual item + std::string mToolTip; // Tooltip : typically, something to be displayed to the user when selecting this item + LLVector3d mPosGlobal; // Global world position + LLUUID mID; // UUID of the item + S32 mCount; // Number of elements in item (e.g. people count) + // Currently not used but might prove useful one day so we comment out +// bool mSelected; // Selected or not: updated by the viewer UI, not the simulator or asset DB +// LLColor4 mColor; // Color of the item }; -#define MAP_SIM_IMAGE_TYPES 3 -// 0 - Prim -// 1 - Terrain Only -// 2 - Overlay: Land For Sale +//Layer types that we intend to support. +enum sim_layer_type +{ + SIM_LAYER_BEGIN, + SIM_LAYER_COMPOSITE=0, //Legacy terrain+prim texture provided in MapBlockReply message. + SIM_LAYER_OVERLAY, //The land-for-sale overlay texture provided in MapBlockReply message. + SIM_LAYER_COUNT +}; +//The MapBlockRequest message 'layerflags' don't match the order of the sim_layer_type, so a few +//simple inline functions have been provided to convert between sim_layer_type and layerflag. +inline U32 layerToFlags(sim_layer_type layer) +{ + static U32 flags[SIM_LAYER_COUNT] = {0,2}; + return flags[layer]; +} +inline U32 flagsToLayer(U32 flags) +{ + //We only want the low two bytes, so mask out the rest. + if((flags & 0xFFFF) == 0) + return SIM_LAYER_COMPOSITE; + else if((flags & 0xFFFF) == 2) + return SIM_LAYER_OVERLAY; + else + return U32_MAX; +} + +// Info per region +// Such records are stored in a global map hold by the LLWorldMap and indexed by region handles. +// To avoid creating too many of them, they are requested in "blocks" corresponding to areas covered by the screen. +// Unfortunately, when the screen covers the whole world (zoomed out), that can translate in requesting info for +// every sim on the grid... Not good... +// To avoid this, the code implements a cut-off threshold for overlay graphics and, therefore, all LLSimInfo. +// In other words, when zooming out too much, we simply stop requesting LLSimInfo and +// LLItemInfo and just display the map tiles. +// As they are stored in different structures (LLSimInfo and LLWorldMipmap), this strategy is now workable. class LLSimInfo { public: @@ -96,62 +137,92 @@ public: LLVector3 getLocalPos(LLVector3d global_pos) const; void clearImage(); // Clears the reference to the Land for sale image for that region - void dropImagePriority(); // Drops the boost level of the Land for sale image for that region - LLPointer getLandForSaleImage(); // Get the overlay image, fetch it if necessary + void dropImagePriority(sim_layer_type layer = SIM_LAYER_COUNT); // Drops the boost level of the Land for sale image for that region void updateAgentCount(F64 time); // Send an item request for agent count on that region if time's up + // Setters void setName(std::string& name) { mName = name; } - void setSize(U16 sizeX, U16 sizeY) { mSizeX = sizeX; mSizeY = sizeY; } - void setAccess (U8 accesscode) { mAccess = accesscode; } + void setAccess (U32 accesscode) { mAccess = accesscode; } void setRegionFlags (U32 region_flags) { mRegionFlags = region_flags; } - void setWaterHeight (F32 water_height) { mWaterHeight = water_height; } + void setSize(U16 sizeX, U16 sizeY) { mSizeX = sizeX; mSizeY = sizeY; } void setAlpha(F32 alpha) { mAlpha = alpha; } + void setLandForSaleImage (LLUUID image_id); void setMapImageID (const LLUUID& id, const U8 &layer) { mMapImageID[layer] = id; } // Accessors std::string getName() const { return mName; } const std::string getFlagsString() const { return LLViewerRegion::regionFlagsToString(mRegionFlags); } - const U32 getRegionFlags() const { return mRegionFlags; } + const U64 getRegionFlags() const { return mRegionFlags; } const std::string getAccessString() const { return LLViewerRegion::accessToString((U8)mAccess); } const U8 getAccess() const { return mAccess; } + const S32 getAgentCount() const; // Compute the total agents count + LLPointer getLandForSaleImage(); // Get the overlay image, fetch it if necessary - const F32 getWaterHeight() const { return mWaterHeight; } const F32 getAlpha() const { return mAlpha; } - const U64 getHandle() const { return mHandle; } const U16 getSizeX() const { return mSizeX; } const U16 getSizeY() const { return mSizeY; } bool isName(const std::string& name) const; bool isDown() { return (mAccess == SIM_ACCESS_DOWN); } bool isPG() { return (mAccess <= SIM_ACCESS_PG); } bool isAdult() { return (mAccess == SIM_ACCESS_ADULT); } + + // Debug only + void dump() const; // Print the region info to the standard output + + // Items lists handling + typedef std::vector item_info_list_t; + void clearItems(); + + void insertTeleHub(const LLItemInfo& item) { mTelehubs.push_back(item); } + void insertInfoHub(const LLItemInfo& item) { mInfohubs.push_back(item); } + void insertPGEvent(const LLItemInfo& item) { mPGEvents.push_back(item); } + void insertMatureEvent(const LLItemInfo& item) { mMatureEvents.push_back(item); } + void insertAdultEvent(const LLItemInfo& item) { mAdultEvents.push_back(item); } + void insertLandForSale(const LLItemInfo& item) { mLandForSale.push_back(item); } + void insertLandForSaleAdult(const LLItemInfo& item) { mLandForSaleAdult.push_back(item); } + void insertAgentLocation(const LLItemInfo& item); + + const LLSimInfo::item_info_list_t& getTeleHub() const { return mTelehubs; } + const LLSimInfo::item_info_list_t& getInfoHub() const { return mInfohubs; } + const LLSimInfo::item_info_list_t& getPGEvent() const { return mPGEvents; } + const LLSimInfo::item_info_list_t& getMatureEvent() const { return mMatureEvents; } + const LLSimInfo::item_info_list_t& getAdultEvent() const { return mAdultEvents; } + const LLSimInfo::item_info_list_t& getLandForSale() const { return mLandForSale; } + const LLSimInfo::item_info_list_t& getLandForSaleAdult() const { return mLandForSaleAdult; } + const LLSimInfo::item_info_list_t& getAgentLocation() const { return mAgentLocations; } + private: U64 mHandle; std::string mName; F64 mAgentsUpdateTime; // Time stamp giving the last time the agents information was requested for that region bool mFirstAgentRequest; // Init agent request flag - U8 mAccess; + + U32 mAccess; // Down/up and maturity rating of the region U32 mRegionFlags; - F32 mWaterHeight; U16 mSizeX; U16 mSizeY; F32 mAlpha; public: - BOOL mShowAgentLocations; // are agents visible? - - // Image ID for the current overlay mode. - LLUUID mMapImageID[MAP_SIM_IMAGE_TYPES]; - - // Hold a reference to the currently displayed image. - LLPointer mCurrentImage; - LLPointer mOverlayImage; + // Handling the "land for sale / land for auction" overlay image + LLUUID mMapImageID[SIM_LAYER_COUNT]; // Image ID of the overlay image + LLPointer mLayerImage[SIM_LAYER_COUNT]; + + // Items for this region + // Those are data received through item requests (as opposed to block requests for the rest of the data) + item_info_list_t mTelehubs; // List of tele hubs in the region + item_info_list_t mInfohubs; // List of info hubs in the region + item_info_list_t mPGEvents; // List of PG events in the region + item_info_list_t mMatureEvents; // List of Mature events in the region + item_info_list_t mAdultEvents; // List of Adult events in the region (AO) + item_info_list_t mLandForSale; // List of Land for sales in the region + item_info_list_t mLandForSaleAdult; // List of Adult Land for sales in the region (AO) + item_info_list_t mAgentLocations; // List of agents in the region }; -#define MAP_BLOCK_RES 256 - struct LLWorldMapLayer { BOOL LayerDefined; @@ -162,6 +233,11 @@ struct LLWorldMapLayer LLWorldMapLayer() : LayerDefined(FALSE) { } }; +// We request region data on the world by "blocks" of (MAP_BLOCK_SIZE x MAP_BLOCK_SIZE) regions +// This is to reduce the number of requests to the asset DB and get things in big "blocks" +const S32 MAP_MAX_SIZE = 2048; +const S32 MAP_BLOCK_SIZE = 4; +const S32 MAP_BLOCK_RES = (MAP_MAX_SIZE / MAP_BLOCK_SIZE); class LLWorldMap : public LLSingleton { @@ -175,135 +251,103 @@ public: // clears the list void reset(); - // clear the visible items - void eraseItems(); - - // Removes references to cached images - void clearImageRefs(); - - // Clears the flags indicating that we've received sim infos - // Causes a re-request of the sim info without erasing extisting info - void clearSimFlags(); - - // Drops the priority of the images being fetched - void dropImagePriorities(); + void clearImageRefs(); // Clears the image references + void dropImagePriorities(); // Drops the priority of the images being fetched + void reloadItems(bool force = false); // Reload the items (people, hub, etc...) // Region Map access typedef std::map sim_info_map_t; const LLWorldMap::sim_info_map_t& getRegionMap() const { return mSimInfoMap; } - // Returns simulator information, or NULL if out of range + void updateRegions(S32 x0, S32 y0, S32 x1, S32 y1); // Requests region info for a rectangle of regions (in grid coordinates) + + // Insert a region and items in the map global instance + // Note: x_world and y_world in world coordinates (meters) + static bool insertRegion(U32 x_world, U32 y_world, U32 x_size, U32 y_size, U32 agent_flags, std::string& name, LLUUID& image_id, U32 accesscode, U32 region_flags); + static bool insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID& uuid, U32 type, S32 extra, S32 extra2); + + // Get info on sims (region) : note that those methods only search the range of loaded sims (the one that are being browsed) + // *not* the entire world. So a NULL return does not mean a down or unexisting region, just an out of range region. LLSimInfo* simInfoFromHandle(const U64 handle); - - // Returns simulator information, or NULL if out of range LLSimInfo* simInfoFromPosGlobal(const LLVector3d& pos_global); - - // Returns simulator information for named sim, or NULL if non-existent LLSimInfo* simInfoFromName(const std::string& sim_name); // Gets simulator name for a global position, returns true if it was found bool simNameFromPosGlobal(const LLVector3d& pos_global, std::string& outSimName ); - - // Sets the current layer - void setCurrentLayer(S32 layer, bool request_layer = false); - - void sendMapLayerRequest(); - void sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent = false); - void sendNamedRegionRequest(std::string region_name); - void sendNamedRegionRequest(std::string region_name, - url_callback_t callback, - const std::string& callback_url, - bool teleport); - void sendHandleRegionRequest(U64 region_handle, - url_callback_t callback, - const std::string& callback_url, - bool teleport); - void sendItemRequest(U32 type, U64 handle = 0); - - static void processMapLayerReply(LLMessageSystem*, void**); - static void processMapBlockReply(LLMessageSystem*, void**); - static void processMapItemReply(LLMessageSystem*, void**); - + static void gotMapServerURL(bool flag) { sGotMapURL = flag; } static bool useWebMapTiles(); - static LLPointer loadObjectsTile(U32 grid_x, U32 grid_y); void dump(); - // Extend the bounding box of the list of simulators. Returns true - // if the extents changed. - BOOL extendAABB(U32 x_min, U32 y_min, U32 x_max, U32 y_max); + // Track handling + void cancelTracking() { mIsTrackingLocation = false; mIsTrackingFound = false; mIsInvalidLocation = false; mIsTrackingDoubleClick = false; mIsTrackingCommit = false; } - // build coverage maps for telehub region visualization - void updateTelehubCoverage(); - BOOL coveredByTelehub(LLSimInfo* infop); + void setTracking(const LLVector3d& loc) { mIsTrackingLocation = true; mTrackingLocation = loc; mIsTrackingFound = false; mIsInvalidLocation = false; mIsTrackingDoubleClick = false; mIsTrackingCommit = false;} + void setTrackingInvalid() { mIsTrackingFound = true; mIsInvalidLocation = true; } + void setTrackingValid() { mIsTrackingFound = true; mIsInvalidLocation = false; } + void setTrackingDoubleClick() { mIsTrackingDoubleClick = true; } + void setTrackingCommit() { mIsTrackingCommit = true; } + + bool isTracking() { return mIsTrackingLocation; } + bool isTrackingValidLocation() { return mIsTrackingFound && !mIsInvalidLocation; } + bool isTrackingInvalidLocation() { return mIsTrackingFound && mIsInvalidLocation; } + bool isTrackingDoubleClick() { return mIsTrackingDoubleClick; } + bool isTrackingCommit() { return mIsTrackingCommit; } + bool isTrackingInRectangle(F64 x0, F64 y0, F64 x1, F64 y1); + + LLVector3d getTrackedPositionGlobal() const { return mTrackingLocation; } + + std::vector::iterator getMapLayerBegin() { return mMapLayers.begin(); } + std::vector::iterator getMapLayerEnd() { return mMapLayers.end(); } + std::map >::const_iterator findMapBlock(U32 layer, U32 x, U32 y) const + { return LLWorldMap::instance().mMapBlockMap[layer].find((x<<16)|y); } + std::map >::const_iterator getMapBlockEnd(U32 layer) const + { return LLWorldMap::instance().mMapBlockMap[layer].end(); } - // Bounds of the world, in meters - U32 getWorldWidth() const; - U32 getWorldHeight() const; - // World Mipmap delegation: currently used when drawing the mipmap void equalizeBoostLevels(); LLPointer getObjectsTile(U32 grid_x, U32 grid_y, S32 level, bool load = true) { return mWorldMipmap.getObjectsTile(grid_x, grid_y, level, load); } + static void processMapLayerReply(LLMessageSystem*, void**); private: bool clearItems(bool force = false); // Clears the item lists + void clearSimFlags(); // Clears the block flags indicating that we've already requested region infos // Create a region record corresponding to the handle, insert it in the region map and returns a pointer LLSimInfo* createSimInfoFromHandle(const U64 handle); - + // Map from region-handle to simulator info sim_info_map_t mSimInfoMap; -public: + // Request legacy background layers. + void sendMapLayerRequest(); - BOOL mIsTrackingUnknownLocation, mInvalidLocation, mIsTrackingDoubleClick, mIsTrackingCommit; - LLVector3d mUnknownLocation; - - bool mRequestLandForSale; - - typedef std::vector item_info_list_t; - item_info_list_t mTelehubs; - item_info_list_t mInfohubs; - item_info_list_t mPGEvents; - item_info_list_t mMatureEvents; - item_info_list_t mAdultEvents; - item_info_list_t mLandForSale; - item_info_list_t mLandForSaleAdult; - - std::map mNumAgents; - - typedef std::map agent_list_map_t; - agent_list_map_t mAgentLocationsMap; - - std::vector mMapLayers[MAP_SIM_IMAGE_TYPES]; - BOOL mMapLoaded[MAP_SIM_IMAGE_TYPES]; - BOOL * mMapBlockLoaded[MAP_SIM_IMAGE_TYPES]; - S32 mCurrentMap; - - // AABB of the list of simulators - U32 mMinX; - U32 mMaxX; - U32 mMinY; - U32 mMaxY; - - U8* mNeighborMap; - U8* mTelehubCoverageMap; - S32 mNeighborMapWidth; - S32 mNeighborMapHeight; + std::vector mMapLayers; + bool mMapLoaded; private: LLWorldMipmap mWorldMipmap; + // The World is divided in "blocks" of (MAP_BLOCK_SIZE x MAP_BLOCK_SIZE) regions that get requested at once. + // This boolean table avoids "blocks" to be requested multiple times. + // Issue: Not sure this scheme is foolproof though as I've seen + // cases where a block is never retrieved and, because of this boolean being set, never re-requested + //bool * mMapBlockLoaded[MAP_SIM_IMAGE_TYPES]; // Telling us if the block of regions has been requested or not + std::map > mMapBlockMap[SIM_LAYER_COUNT]; + + // Track location data : used while there's nothing tracked yet by LLTracker + bool mIsTrackingLocation; // True when we're tracking a point + bool mIsTrackingFound; // True when the tracking position has been found, valid or not + bool mIsInvalidLocation; // The region is down or the location does not correspond to an existing region + bool mIsTrackingDoubleClick; // User double clicked to set the location (i.e. teleport when found please...) + bool mIsTrackingCommit; // User used the search or landmark fields to set the location + LLVector3d mTrackingLocation; // World global position being tracked + + // General grid items request timing flags (used for events,hubs and land for sale) LLTimer mRequestTimer; - - // search for named region for url processing - std::string mSLURLRegionName; - U64 mSLURLRegionHandle; - std::string mSLURL; - url_callback_t mSLURLCallback; - bool mSLURLTeleport; - + bool mFirstRequest; + static bool sGotMapURL; }; diff --git a/indra/newview/llworldmapmessage.cpp b/indra/newview/llworldmapmessage.cpp new file mode 100644 index 000000000..b25a3db75 --- /dev/null +++ b/indra/newview/llworldmapmessage.cpp @@ -0,0 +1,301 @@ +/** + * @file llworldmapmessage.cpp + * @brief Handling of the messages to the DB made by and for the world map. + * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llworldmapmessage.h" +#include "message.h" + +#include "llworldmap.h" +#include "llagent.h" +#include "llfloaterworldmap.h" + +const U32 LAYER_FLAG = 2; + +//--------------------------------------------------------------------------- +// World Map Message Handling +//--------------------------------------------------------------------------- + +LLWorldMapMessage::LLWorldMapMessage() : + mSLURLRegionName(), + mSLURLRegionHandle(0), + mSLURL(), + mSLURLCallback(0), + mSLURLTeleport(false) +{ +} + +LLWorldMapMessage::~LLWorldMapMessage() +{ +} + +void LLWorldMapMessage::sendItemRequest(U32 type, U64 handle) +{ + //LL_INFOS("World Map") << "Send item request : type = " << type << LL_ENDL; + LLMessageSystem* msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_MapItemRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_Flags, LAYER_FLAG); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + + msg->nextBlockFast(_PREHASH_RequestData); + msg->addU32Fast(_PREHASH_ItemType, type); + msg->addU64Fast(_PREHASH_RegionHandle, handle); // If zero, filled in on sim + + gAgent.sendReliableMessage(); +} + +void LLWorldMapMessage::sendNamedRegionRequest(std::string region_name) +{ + //LL_INFOS("World Map") << "LLWorldMap::sendNamedRegionRequest()" << LL_ENDL; + LLMessageSystem* msg = gMessageSystem; + + // Request for layer + msg->newMessageFast(_PREHASH_MapNameRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_Flags, LAYER_FLAG); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + msg->nextBlockFast(_PREHASH_NameData); + msg->addStringFast(_PREHASH_Name, region_name); + gAgent.sendReliableMessage(); +} + +void LLWorldMapMessage::sendNamedRegionRequest(std::string region_name, + url_callback_t callback, + const std::string& callback_url, + bool teleport) // immediately teleport when result returned +{ + //LL_INFOS("World Map") << "LLWorldMap::sendNamedRegionRequest()" << LL_ENDL; + mSLURLRegionName = region_name; + mSLURLRegionHandle = 0; + mSLURL = callback_url; + mSLURLCallback = callback; + mSLURLTeleport = teleport; + + sendNamedRegionRequest(region_name); +} + +void LLWorldMapMessage::sendHandleRegionRequest(U64 region_handle, + url_callback_t callback, + const std::string& callback_url, + bool teleport) // immediately teleport when result returned +{ + //LL_INFOS("World Map") << "LLWorldMap::sendHandleRegionRequest()" << LL_ENDL; + mSLURLRegionName.clear(); + mSLURLRegionHandle = region_handle; + mSLURL = callback_url; + mSLURLCallback = callback; + mSLURLTeleport = teleport; + + U32 global_x; + U32 global_y; + from_region_handle(region_handle, &global_x, &global_y); + U16 grid_x = (U16)(global_x / REGION_WIDTH_UNITS); + U16 grid_y = (U16)(global_y / REGION_WIDTH_UNITS); + + sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true, LAYER_FLAG); +} + +// public +void LLWorldMapMessage::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent, S32 layer) +{ + //LL_INFOS("World Map") << "LLWorldMap::sendMapBlockRequest()" << ", min = (" << min_x << ", " << min_y << "), max = (" << max_x << ", " << max_y << "), nonexistent = " << return_nonexistent << LL_ENDL; + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_MapBlockRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + U32 flags = layer; + flags |= (return_nonexistent ? 0x10000 : 0); + msg->addU32Fast(_PREHASH_Flags, flags); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + msg->nextBlockFast(_PREHASH_PositionData); + msg->addU16Fast(_PREHASH_MinX, min_x); + msg->addU16Fast(_PREHASH_MinY, min_y); + msg->addU16Fast(_PREHASH_MaxX, max_x); + msg->addU16Fast(_PREHASH_MaxY, max_y); + gAgent.sendReliableMessage(); +} + +// public static +void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**) +{ + U32 agent_flags; + msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); + + U32 layer = flagsToLayer(agent_flags); + if (layer >= SIM_LAYER_COUNT) + { + llwarns << "Invalid map image type returned! layer = " << agent_flags << llendl; + return; + } + + S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data); + //LL_INFOS("World Map") << "LLWorldMap::processMapBlockReply(), num_blocks = " << num_blocks << LL_ENDL; + + bool found_null_sim = false; + + for (S32 block=0; blockgetU16Fast(_PREHASH_Data, _PREHASH_X, x_regions, block); + msg->getU16Fast(_PREHASH_Data, _PREHASH_Y, y_regions, block); + msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block); + msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, accesscode, block); + msg->getU32Fast(_PREHASH_Data, _PREHASH_RegionFlags, region_flags, block); +// msg->getU8Fast(_PREHASH_Data, _PREHASH_WaterHeight, water_height, block); +// msg->getU8Fast(_PREHASH_Data, _PREHASH_Agents, agents, block); + msg->getUUIDFast(_PREHASH_Data, _PREHASH_MapImageID, image_id, block); + if(msg->getNumberOfBlocksFast(_PREHASH_Size) > 0) + { + msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeX, x_size, block); + msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeY, y_size, block); + } + if(x_size == 0 || (x_size % 16) != 0|| (y_size % 16) != 0) + { + x_size = 256; + y_size = 256; + } + + U32 x_world = (U32)(x_regions) * REGION_WIDTH_UNITS; + U32 y_world = (U32)(y_regions) * REGION_WIDTH_UNITS; + + // name shouldn't be empty, see EXT-4568 + //llassert(!name.empty()); + + //Opensim bug. BlockRequest can return sims without names, with an accesscode that isn't 255. + // skip if this has happened. + if(name.empty() && accesscode != 255) + continue; + + // Insert that region in the world map, if failure, flag it as a "null_sim" + if (!(LLWorldMap::getInstance()->insertRegion(x_world, y_world, x_size, y_size, agent_flags, name, image_id, (U32)accesscode, region_flags))) + { + found_null_sim = true; + } + + // If we hit a valid tracking location, do what needs to be done app level wise + if (LLWorldMap::getInstance()->isTrackingValidLocation()) + { + LLVector3d pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal(); + if (LLWorldMap::getInstance()->isTrackingDoubleClick()) + { + // Teleport if the user double clicked + gAgent.teleportViaLocation(pos_global); + } + // Update the "real" tracker information + gFloaterWorldMap->trackLocation(pos_global); + } + + // Handle the SLURL callback if any + url_callback_t callback = LLWorldMapMessage::getInstance()->mSLURLCallback; + if(callback != NULL) + { + U64 handle = to_region_handle(x_world, y_world); + // Check if we reached the requested region + if ((LLStringUtil::compareInsensitive(LLWorldMapMessage::getInstance()->mSLURLRegionName, name)==0) + || (LLWorldMapMessage::getInstance()->mSLURLRegionHandle == handle)) + { + LLWorldMapMessage::getInstance()->mSLURLCallback = NULL; + LLWorldMapMessage::getInstance()->mSLURLRegionName.clear(); + LLWorldMapMessage::getInstance()->mSLURLRegionHandle = 0; + + callback(handle, LLWorldMapMessage::getInstance()->mSLURL, image_id, LLWorldMapMessage::getInstance()->mSLURLTeleport); + } + } + if( gAgent.mPendingLure && + (U16)(gAgent.mPendingLure->mPosGlobal.mdV[0] / REGION_WIDTH_UNITS) == x_regions && + (U16)(gAgent.mPendingLure->mPosGlobal.mdV[1] / REGION_WIDTH_UNITS) == y_regions ) + { + gAgent.onFoundLureDestination(); + } + } + // Tell the UI to update itself + gFloaterWorldMap->updateSims(found_null_sim); +} + +// public static +void LLWorldMapMessage::processMapItemReply(LLMessageSystem* msg, void**) +{ + //LL_INFOS("World Map") << "LLWorldMap::processMapItemReply()" << LL_ENDL; + U32 type; + msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ItemType, type); + + S32 num_blocks = msg->getNumberOfBlocks("Data"); + + for (S32 block=0; blockgetU32Fast(_PREHASH_Data, _PREHASH_X, X, block); + msg->getU32Fast(_PREHASH_Data, _PREHASH_Y, Y, block); + msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block); + msg->getUUIDFast(_PREHASH_Data, _PREHASH_ID, uuid, block); + msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra, extra, block); + msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra2, extra2, block); + + LLWorldMap::getInstance()->insertItem(X, Y, name, uuid, type, extra, extra2); + } +} +void LLWorldMapMessage::handleSLURL(std::string& name, U32 x_world, U32 y_world, LLUUID image_id) +{ + // Handle the SLURL callback if any + url_callback_t callback = LLWorldMapMessage::getInstance()->mSLURLCallback; + if(callback != NULL) + { + U64 handle = to_region_handle(x_world, y_world); + // Check if we reached the requested region + if ((LLStringUtil::compareInsensitive(LLWorldMapMessage::getInstance()->mSLURLRegionName, name)==0) + || (LLWorldMapMessage::getInstance()->mSLURLRegionHandle == handle)) + { + LLWorldMapMessage::getInstance()->mSLURLCallback = NULL; + LLWorldMapMessage::getInstance()->mSLURLRegionName.clear(); + LLWorldMapMessage::getInstance()->mSLURLRegionHandle = 0; + + callback(handle, LLWorldMapMessage::getInstance()->mSLURL, image_id, LLWorldMapMessage::getInstance()->mSLURLTeleport); + } + } +} + diff --git a/indra/newview/llworldmapmessage.h b/indra/newview/llworldmapmessage.h new file mode 100644 index 000000000..bd4bd7545 --- /dev/null +++ b/indra/newview/llworldmapmessage.h @@ -0,0 +1,79 @@ +/** + * @file llworldmapmessage.h + * @brief Handling of the messages to the DB made by and for the world map. + * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLWORLDMAPMESSAGE_H +#define LL_LLWORLDMAPMESSAGE_H + +// Handling of messages (send and process) as well as SLURL callback if necessary +class LLMessageSystem; + +class LLWorldMapMessage : public LLSingleton +{ +public: + typedef boost::function + url_callback_t; + + LLWorldMapMessage(); + ~LLWorldMapMessage(); + + // Process incoming answers to map stuff requests + static void processMapBlockReply(LLMessageSystem*, void**); + static void processMapItemReply(LLMessageSystem*, void**); + + // Request data for all regions in a rectangular area. Coordinates in grids (i.e. meters / 256). + void sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent, S32 layer = 2); + + // Various methods to request LLSimInfo data to the simulator and asset DB + void sendNamedRegionRequest(std::string region_name); + void sendNamedRegionRequest(std::string region_name, + url_callback_t callback, + const std::string& callback_url, + bool teleport); + void sendHandleRegionRequest(U64 region_handle, + url_callback_t callback, + const std::string& callback_url, + bool teleport); + + // Request item data for regions + // Note: the handle works *only* when requesting agent count (type = MAP_ITEM_AGENT_LOCATIONS). In that case, + // the request will actually be transitting through the spaceserver (all that is done on the sim). + // All other values of type do create a global grid request to the asset DB. So no need to try to get, say, + // the events for one particular region. For such a request, the handle is ignored. + void sendItemRequest(U32 type, U64 handle = 0); + + void handleSLURL(std::string& name, U32 x_world, U32 y_world, LLUUID image_id); + +private: + // Search for region (by name or handle) for SLURL processing and teleport + // None of this relies explicitly on the LLWorldMap instance so better handle it here + std::string mSLURLRegionName; + U64 mSLURLRegionHandle; + std::string mSLURL; + url_callback_t mSLURLCallback; + bool mSLURLTeleport; +}; + +#endif // LL_LLWORLDMAPMESSAGE_H diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index f8269833b..01d9ca29f 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -109,8 +109,6 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL; LLUIImagePtr LLWorldMapView::sForSaleImage = NULL; LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL; -F32 LLWorldMapView::sThresholdA = 48.f; -F32 LLWorldMapView::sThresholdB = 96.f; F32 LLWorldMapView::sPanX = 0.f; F32 LLWorldMapView::sPanY = 0.f; F32 LLWorldMapView::sTargetPanX = 0.f; @@ -124,11 +122,18 @@ F32 CONE_SIZE = 0.6f; std::map LLWorldMapView::sStringsMap; -const int SIM_NULL_MAP_SCALE=4; // width in pixels, where we start drawing "null" sims -const int SIM_MAP_AGENT_SCALE=8; // width in pixels, where we start drawing agents -const int SIM_MAP_SCALE=4; // width in pixels, where we start drawing sim tiles +F32 DRAW_TEXT_THRESHOLD = 96.f; + +const int SIM_MAP_AGENT_SCALE=32; // width in pixels, where we start drawing agents +const int SIM_DATA_SCALE=32; // width in pixels where we start requesting sim info const int SIM_LANDFORSALE_SCALE=32; +const int SIM_COMPOSITE_SCALE=2; // width in pixels, where we start drawing sim tiles. (legacy tiling method) +const int SIM_FETCH_SCALE=12; // width in pixels, where we start requesting sim tile textures. (legacy tiling method) + +// When on, draw an outline for each mipmap tile gotten from S3 +#define DEBUG_DRAW_TILE 0 + void LLWorldMapView::initClass() { @@ -241,6 +246,7 @@ LLWorldMapView::LLWorldMapView(const std::string& name, const LLRect& rect ) LLWorldMapView::~LLWorldMapView() { + //LL_INFOS("World Map") << "Destroying the map -> LLWorldMapView::~LLWorldMapView()" << LL_ENDL; cleanupTextures(); } @@ -254,6 +260,10 @@ void LLWorldMapView::cleanupTextures() // static void LLWorldMapView::setScale( F32 scale ) { + if(!LLWorldMap::useWebMapTiles()) //adjust the scale range if drawing legacy tiles to avoid drawing a bajillion 1x1 tiles. + { + scale = SIM_COMPOSITE_SCALE + scale*((256.f-SIM_COMPOSITE_SCALE)/256.f); + } if (scale != sMapScale) { F32 old_scale = sMapScale; @@ -306,7 +316,7 @@ void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap ) BOOL is_agent_in_region(LLViewerRegion* region, LLSimInfo* info) { - return ((region && info) && (info->isName(region->getName()))); + return (region && info && info->isName(region->getName())); } @@ -337,7 +347,6 @@ void LLWorldMapView::draw() gGL.matrixMode(LLRender::MM_MODELVIEW); // Clear the background alpha to 0 - gGL.flush(); gGL.setColorMask(false, true); gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f); gGL.setSceneBlendType(LLRender::BT_REPLACE); @@ -345,22 +354,29 @@ void LLWorldMapView::draw() gl_rect_2d(0, height, width, 0); } - gGL.flush(); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.setColorMask(true, true); gGL.setSceneBlendType(LLRender::BT_ALPHA); - if(gHippoGridManager->getConnectedGrid()->isSecondLife()) + static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); + if(LLWorldMap::useWebMapTiles()) drawMipmap(width, height); else - drawTiles(width, height); - gGL.flush(); - LLFontGL* font = LLFontGL::getFontSansSerifSmall(); + drawLegacyBackgroundLayers(width, height); - - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - gGL.setColorMask(true, true); + //Singu Note: This is done before drawing the transparent offline overlay. drawMipmap doesn't actually + // fill every possible block on the minimap. Every space must be filled for the offline overlay to look correct. + // Draw background rectangle + LLGLSUIDefault gls_ui; + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f); + gGL.blendFunc(LLRender::BF_ONE_MINUS_DEST_ALPHA, LLRender::BF_DEST_ALPHA); + gGL.color4fv( mBackgroundColor.mV ); + gl_rect_2d(0, height, width, 0); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + } // Draw the region name in the lower left corner for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); @@ -368,7 +384,7 @@ void LLWorldMapView::draw() { U64 handle = it->first; LLSimInfo* info = it->second; - + LLVector3d origin_global = from_region_handle(handle); // Find x and y position relative to camera's center. @@ -380,27 +396,104 @@ void LLWorldMapView::draw() // When the view isn't panned, 0,0 = center of rectangle F32 bottom = sPanY + half_height + relative_y; F32 left = sPanX + half_width + relative_x; - //F32 top = bottom + sMapScale ; - //F32 right = left + sMapScale ; + F32 top = bottom + sMapScale * ((F32)info->getSizeY() / REGION_WIDTH_METERS); + F32 right = left + sMapScale * ((F32)info->getSizeX() / REGION_WIDTH_METERS); + + // Discard if region is outside the screen rectangle (not visible on screen) + if ((top < 0.f) || (bottom > height) || + (right < 0.f) || (left > width) ) + { + // Drop the "land for sale" fetching priority since it's outside the view rectangle + info->dropImagePriority(); + continue; + } + + // This list is used by other methods to know which regions are indeed displayed on screen + + mVisibleRegions.push_back(handle); - info->mShowAgentLocations = (sMapScale >= SIM_MAP_AGENT_SCALE); - mVisibleRegions.push_back(handle); // Update the agent count for that region if we're not too zoomed out already if (sMapScale >= SIM_MAP_AGENT_SCALE) { info->updateAgentCount(current_time); } - std::string mesg; - if (sMapScale < sThresholdA) + F32 alpha = !LLWorldMap::useWebMapTiles() ? drawLegacySimTile(*info,left,top,right,bottom) : 1.f; + + if (info->isDown()) { + // Draw a transparent red square over down sims + gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_SOURCE_ALPHA); + gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.begin(LLRender::QUADS); + gGL.vertex2f(left, top); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, bottom); + gGL.vertex2f(right, top); + gGL.end(); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); } - else if (sMapScale < sThresholdB) + // As part of the AO project, we no longer want to draw access indicators; + // it's too complicated to get all the rules straight and will only + // cause confusion. + /********************** + else if (!info->isPG() && gAgent.isTeen()) { - // mesg = llformat( info->mAgents); + // If this is a mature region, and you are not, draw a line across it + gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.color3f(1.f, 0.f, 0.f); + gGL.begin(LLRender::LINES); + gGL.vertex2f(left, top); + gGL.vertex2f(right, bottom); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, top); + gGL.end(); + } + **********************/ + else if (map_show_land_for_sale && (sMapScale >= SIM_LANDFORSALE_SCALE)) + { + // Draw the overlay image "Land for Sale / Land for Auction" + LLViewerFetchedTexture* overlayimage = info->getLandForSaleImage(); + if (overlayimage) + { + // Inform the fetch mechanism of the size we need + S32 draw_size = llround(sMapScale); + overlayimage->setKnownDrawSize( llround(draw_size * LLUI::getScaleFactor().mV[VX] * ((F32)info->getSizeX() / REGION_WIDTH_METERS)), + llround(draw_size * LLUI::getScaleFactor().mV[VY] * ((F32)info->getSizeY() / REGION_WIDTH_METERS))); + // Draw something whenever we have enough info + if (overlayimage->hasGLTexture() && !overlayimage->isMissingAsset() && overlayimage->getID() != IMG_DEFAULT) + { + gGL.getTexUnit(0)->bind(overlayimage); + gGL.color4f(1.f, 1.f, 1.f, alpha); + gGL.begin(LLRender::QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3f(left, top, -0.5f); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3f(left, bottom, -0.5f); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3f(right, bottom, -0.5f); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3f(right, top, -0.5f); + gGL.end(); + } + } } else { + // If we're not displaying the "land for sale", drop fetching priority of both. + info->dropImagePriority(SIM_LAYER_OVERLAY); + } + + // Draw the region name in the lower left corner + if (sMapScale >= DRAW_TEXT_THRESHOLD) + { + LLFontGL* font = LLFontGL::getFontSansSerifSmall(); + std::string mesg; + //mesg = llformat("%d / %s (%s)", // info->mAgents, // info->mName.c_str(), @@ -408,14 +501,18 @@ void LLWorldMapView::draw() // [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-04 (RLVa-1.0.0a) if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) { - mesg = RlvStrings::getString(RLV_STRING_HIDDEN); + if(!info->getName().empty()) + mesg = RlvStrings::getString(RLV_STRING_HIDDEN); } // [/RLVa:KB] else if (info->isDown()) { - mesg = llformat( "%s (%s)", info->getName().c_str(), sStringsMap["offline"].c_str()); + if(info->getName().empty()) + mesg = llformat( "(%s)", sStringsMap["offline"].c_str()); + else + mesg = llformat( "%s (%s)", info->getName().c_str(), sStringsMap["offline"].c_str()); } - else + else if(!info->getName().empty()) // Online sims should have names... { mesg = info->getName(); U8 access = info->getAccess(); @@ -438,91 +535,151 @@ void LLWorldMapView::draw() break; } } - } - - if (!mesg.empty()) - { - font->renderUTF8( - mesg, 0, - llfloor(left + 3), - llfloor(bottom + 2), - LLColor4::white, - LLFontGL::LEFT, - LLFontGL::BASELINE, - LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW); - - // If map texture is still loading, - // display "Loading" placeholder text. - /*if ((simimage != NULL) && - simimage->getDiscardLevel() != 1 && - simimage->getDiscardLevel() != 0) + if (!mesg.empty()) { font->renderUTF8( - sStringsMap["loading"], 0, - llfloor(left + 18), - llfloor(top - 25), - LLColor4::white, - LLFontGL::LEFT, - LLFontGL::BASELINE, - LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW); - }*/ + mesg, 0, + llfloor(left + 3), llfloor(bottom + 2), + LLColor4::white, + LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); + } } + } - } - - - // Draw background rectangle - LLGLSUIDefault gls_ui; + static const LLCachedControl map_show_requests("MapShowRequests", false); + if(map_show_requests) { + const F32 map_to_pixels = MAP_MAX_SIZE*sMapScale; + const F32 block_to_pixels = MAP_BLOCK_SIZE*sMapScale; + const F32 padding = .25f*sMapScale; + + //In sim coords. + const F32 centerX = -sPanX/sMapScale + camera_global.mdV[VX]/REGION_WIDTH_METERS; + const F32 centerY = -sPanY/sMapScale + camera_global.mdV[VY]/REGION_WIDTH_METERS; + const F32 bottom = centerY - half_height/sMapScale ; + const F32 left = centerX - half_width/sMapScale ; + const F32 top = centerY + half_height/sMapScale ; + const F32 right = centerX + half_width/sMapScale ; + + const U32 max_range = (U16_MAX+1)/MAP_BLOCK_RES/MAP_BLOCK_SIZE - 1; + const U32 map_block_x0 = (U32)(llmax(left,0.f) / MAP_MAX_SIZE); + const U32 map_block_x1 = llclamp(U32(right / MAP_MAX_SIZE), U32(0), max_range); + const U32 map_block_y0 = (U32)(llmax(bottom,0.f) / MAP_MAX_SIZE); + const U32 map_block_y1 = llclamp(U32(top / MAP_MAX_SIZE), U32(0), max_range); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f); - gGL.blendFunc(LLRender::BF_ONE_MINUS_DEST_ALPHA, LLRender::BF_DEST_ALPHA); - gGL.color4fv( mBackgroundColor.mV ); - gl_rect_2d(0, height, width, 0); + + for(U32 i = map_block_x0; i <= map_block_x1; ++i) + { + const F32 base_left = i*map_to_pixels-left*sMapScale; + const F32 base_right = base_left + map_to_pixels; + if( base_right <= 0.f) + continue; + if( base_left >= width) + break; + for (U32 j = map_block_y0; j <= map_block_y1; ++j) + { + const F32 base_bottom = j*map_to_pixels-bottom*sMapScale; + const F32 base_top = base_bottom + map_to_pixels; + if( base_top <= 0.f) + continue; + if( base_bottom >= height) + break; + + std::map >::const_iterator it = LLWorldMap::getInstance()->findMapBlock(SIM_LAYER_OVERLAY,i,j); + + if(it != LLWorldMap::getInstance()->getMapBlockEnd(SIM_LAYER_OVERLAY)) + gGL.color4f(0.5f, 0.0f, 0.0f, 0.4f); + else + gGL.color4f(0.2f, .2f, 0.2f, 0.4f); + gGL.begin(LLRender::QUADS); + gGL.vertex2f(base_left+padding, base_top-padding); + gGL.vertex2f(base_left+padding, base_bottom+padding); + gGL.vertex2f(base_right-padding, base_bottom+padding); + gGL.vertex2f(base_right-padding, base_top-padding); + gGL.end(); + if(it != LLWorldMap::getInstance()->getMapBlockEnd(SIM_LAYER_OVERLAY)) + { + for(U32 x=0;x= width) + break; + for(U32 y=0;y= height) + break; + if(it->second[x | (y * MAP_BLOCK_RES)]) + gGL.color4f(0.0f, 0.5f, 0.0f, 0.4f); + else + gGL.color4f(0.4f, 0.0f, 0.0f, 0.4f); + gGL.begin(LLRender::QUADS); + gGL.vertex2f(block_left+padding, block_top-padding); + gGL.vertex2f(block_left+padding, block_bottom+padding); + gGL.vertex2f(block_right-padding, block_bottom+padding); + gGL.vertex2f(block_right-padding, block_top-padding); + gGL.end(); + + for(U32 sim_x=0;sim_x map_show_infohubs("MapShowInfohubs"); - if (map_show_infohubs) //(sMapScale >= sThresholdB) - { - drawGenericItems(LLWorldMap::getInstance()->mInfohubs, sInfohubImage); - } - - // Telehubs static const LLCachedControl map_show_telehubs("MapShowTelehubs"); - if (map_show_telehubs) //(sMapScale >= sThresholdB) + static const LLCachedControl map_show_mature_events("MapShowMatureEvents"); + static const LLCachedControl map_show_adult_events("MapShowAdultEvents"); + if(sMapScale >= DRAW_TEXT_THRESHOLD && (map_show_infohubs || + map_show_telehubs || + map_show_land_for_sale || + map_show_mature_events || + map_show_adult_events)) { - drawGenericItems(LLWorldMap::getInstance()->mTelehubs, sTelehubImage); + drawItems(); } - // Home Sweet Home + // Draw the Home location (always) LLVector3d home; if (gAgent.getHomePosGlobal(&home)) { drawImage(home, sHomeImage); } - static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); - if (map_show_land_for_sale) - { - drawGenericItems(LLWorldMap::getInstance()->mLandForSale, sForSaleImage); - // for 1.23, we're showing normal land and adult land in the same UI; you don't - // get a choice about which ones you want. If you're currently asking for adult - // content and land you'll get the adult land. - if (gAgent.canAccessAdult()) - { - drawGenericItems(LLWorldMap::getInstance()->mLandForSaleAdult, sForSaleAdultImage); - } - } - - drawEvents(); - - // Now draw your avatar after all that other stuff. + // Draw the current agent after all that other stuff. LLVector3d pos_global = gAgent.getPositionGlobal(); drawImage(pos_global, sAvatarYouImage); @@ -543,7 +700,7 @@ void LLWorldMapView::draw() // Draw icons for the avatars in each region. // Drawn after your avatar so you can see nearby people. static const LLCachedControl map_show_people("MapShowPeople"); - if (map_show_people) + if (map_show_people && sMapScale >= SIM_MAP_AGENT_SCALE) { drawAgents(); } @@ -565,23 +722,33 @@ void LLWorldMapView::draw() drawTracking( pos_global, gTrackColor, TRUE, LLTracker::getLabel(), LLTracker::getToolTip() ); } } - else if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation) + else if (LLWorldMap::getInstance()->isTracking()) { - if (LLWorldMap::getInstance()->mInvalidLocation) + if (LLWorldMap::getInstance()->isTrackingInvalidLocation()) { - // We know this location to be invalid + // We know this location to be invalid, draw a blue circle LLColor4 loading_color(0.0, 0.5, 1.0, 1.0); - drawTracking( LLWorldMap::getInstance()->mUnknownLocation, loading_color, TRUE, "Invalid Location", ""); + drawTracking( LLWorldMap::getInstance()->getTrackedPositionGlobal(), loading_color, TRUE, LLTrans::getString("InvalidLocation"), ""); } else { + // We don't know yet what that location is, draw a throbing blue circle double value = fmod(current_time, 2); - value = 0.5 + 0.5*cos(value * 3.14159f); + value = 0.5 + 0.5*cos(value * F_PI); LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0); - drawTracking( LLWorldMap::getInstance()->mUnknownLocation, loading_color, TRUE, "Loading...", ""); + drawTracking( LLWorldMap::getInstance()->getTrackedPositionGlobal(), loading_color, TRUE, LLTrans::getString("LoadingData"), ""); } } // #endif used to be here + + //Provide some feedback, because nothing will load if zoomed far out on the map when using legacy sim drawing. + if(!LLWorldMap::useWebMapTiles() && (sMapScale < SIM_FETCH_SCALE || sMapScale < SIM_DATA_SCALE)) + { + LLFontGL::getFontSansSerifSmall()->renderUTF8("(Zoom to resume loading)", 0, + width-2, LLFontGL::getFontSansSerifSmall()->getLineHeight()*1.5f, + LLColor4::white, + LLFontGL::RIGHT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); + } // turn off the scissor LLGLDisable no_scissor(GL_SCISSOR_TEST); @@ -591,6 +758,8 @@ void LLWorldMapView::draw() LLView::draw(); updateVisibleBlocks(); + + gGL.flush(); } // end draw() @@ -600,63 +769,50 @@ void LLWorldMapView::setVisible(BOOL visible) LLPanel::setVisible(visible); if (!visible) { - for (S32 map = 0; map < MAP_SIM_IMAGE_TYPES; map++) - { - for (U32 layer_idx=0; layer_idxmMapLayers[map].size(); ++layer_idx) - { - if (LLWorldMap::getInstance()->mMapLayers[map][layer_idx].LayerDefined) - { - LLWorldMapLayer *layer = &LLWorldMap::getInstance()->mMapLayers[map][layer_idx]; - layer->LayerImage->setBoostLevel(0); - } - } - } - for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); - it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) + std::vector::iterator begin = LLWorldMap::getInstance()->getMapLayerBegin(); + std::vector::iterator end = LLWorldMap::getInstance()->getMapLayerEnd(); + for(std::vector::iterator it = begin; it != end; ++it) { - LLSimInfo* info = (*it).second; - if (info->mCurrentImage.notNull()) + if (it->LayerDefined) { - info->mCurrentImage->setBoostLevel(0); - } - if (info->mOverlayImage.notNull()) - { - info->mOverlayImage->setBoostLevel(0); + it->LayerImage->setBoostLevel(0); } } + // Drop the download of tiles and images priority to nil if we hide the map + LLWorldMap::getInstance()->dropImagePriorities(); } } -void LLWorldMapView::drawTiles(S32 width, S32 height) { +void LLWorldMapView::drawLegacyBackgroundLayers(S32 width, S32 height) { const F32 half_width = F32(width) / 2.0f; const F32 half_height = F32(height) / 2.0f; - F32 layer_alpha = 1.f; LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - // Draw one image per layer - for (U32 layer_idx=0; layer_idxmMapLayers[LLWorldMap::getInstance()->mCurrentMap].size(); ++layer_idx) + std::vector::const_iterator begin = LLWorldMap::getInstance()->getMapLayerBegin(); + std::vector::const_iterator end = LLWorldMap::getInstance()->getMapLayerEnd(); + for (std::vector::const_iterator it = begin; it != end; ++it) { - if (!LLWorldMap::getInstance()->mMapLayers[LLWorldMap::getInstance()->mCurrentMap][layer_idx].LayerDefined) + if (!it->LayerDefined) { continue; } - LLWorldMapLayer *layer = &LLWorldMap::getInstance()->mMapLayers[LLWorldMap::getInstance()->mCurrentMap][layer_idx]; - LLViewerTexture *current_image = layer->LayerImage; + const LLWorldMapLayer& layer = *it; + LLViewerTexture *current_image = layer.LayerImage; - if (current_image->isMissingAsset()) + if (!current_image || current_image->isMissingAsset() || current_image->getID() == IMG_DEFAULT) { continue; // better to draw nothing than the missing asset image } - LLVector3d origin_global((F64)layer->LayerExtents.mLeft * REGION_WIDTH_METERS, (F64)layer->LayerExtents.mBottom * REGION_WIDTH_METERS, 0.f); + LLVector3d origin_global((F64)layer.LayerExtents.mLeft * REGION_WIDTH_METERS, (F64)layer.LayerExtents.mBottom * REGION_WIDTH_METERS, 0.f); // Find x and y position relative to camera's center. LLVector3d rel_region_pos = origin_global - camera_global; F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; - F32 pix_width = sMapScale*(layer->LayerExtents.getWidth() + 1); - F32 pix_height = sMapScale*(layer->LayerExtents.getHeight() + 1); + F32 pix_width = sMapScale*(layer.LayerExtents.getWidth() + 1); + F32 pix_height = sMapScale*(layer.LayerExtents.getHeight() + 1); // When the view isn't panned, 0,0 = center of rectangle F32 bottom = sPanY + half_height + relative_y; @@ -676,11 +832,11 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { continue; } - current_image->setBoostLevel(LLViewerTexture::BOOST_MAP_VISIBLE); - current_image->setKnownDrawSize(llround(pix_width * LLUI::sGLScaleFactor.mV[VX]), - llround(pix_height * LLUI::sGLScaleFactor.mV[VY])); + current_image->setBoostLevel(LLGLTexture::BOOST_MAP); + current_image->setKnownDrawSize(llround(pix_width * LLUI::getScaleFactor().mV[VX]), + llround(pix_height * LLUI::getScaleFactor().mV[VY])); - if (!current_image->hasGLTexture()) + if (!current_image->hasGLTexture()) //Still loading. { continue; // better to draw nothing than the default image } @@ -692,11 +848,8 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.getTexUnit(0)->bind(current_image); // Draw map image into RGB - //gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gGL.flush(); gGL.setColorMask(true, false); - gGL.color4f(1.f, 1.f, 1.f, layer_alpha); - + gGL.color4f(1.f, 1.f, 1.f, 1.f); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.0f, 1.0f); gGL.vertex3f(left, top, -1.0f); @@ -707,9 +860,7 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.texCoord2f(1.0f, 1.0f); gGL.vertex3f(right, top, -1.0f); gGL.end(); - // draw an alpha of 1 where the sims are visible - gGL.flush(); gGL.setColorMask(false, true); gGL.color4f(1.f, 1.f, 1.f, 1.f); @@ -723,458 +874,78 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.texCoord2f(1.0f, 1.0f); gGL.vertex2f(right, top); gGL.end(); + + gGL.setColorMask(true, true); } +} - gGL.flush(); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - gGL.setColorMask(true, true); - - F32 sim_alpha = 1.f; - - // Draw one image per region, centered on the camera position. +F32 LLWorldMapView::drawLegacySimTile(LLSimInfo& sim_info, S32 left, S32 top, S32 right, S32 bottom) +{ + const F32 ALPHA_CUTOFF = 0.001f; const S32 MAX_SIMULTANEOUS_TEX = 100; const S32 MAX_REQUEST_PER_TICK = 5; const S32 MIN_REQUEST_PER_TICK = 1; S32 textures_requested_this_tick = 0; + LLViewerFetchedTexture* simimage = sim_info.mLayerImage[SIM_LAYER_COMPOSITE]; - bool use_web_map_tiles = LLWorldMap::useWebMapTiles(); - - for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); - it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) + const bool sim_visible = sMapScale >= SIM_COMPOSITE_SCALE; + const bool sim_fetchable = sMapScale >= SIM_FETCH_SCALE; + + if(sim_fetchable) { - U64 handle = (*it).first; - LLSimInfo* info = (*it).second; - - LLViewerTexture* simimage = info->mCurrentImage; - LLViewerTexture* overlayimage = info->mOverlayImage; - - if (sMapScale < SIM_MAP_SCALE) - { - if (simimage != NULL) simimage->setBoostLevel(0); - if (overlayimage != NULL) overlayimage->setBoostLevel(0); - continue; - } - - LLVector3d origin_global = from_region_handle(handle); - LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - - // Find x and y position relative to camera's center. - LLVector3d rel_region_pos = origin_global - camera_global; - F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; - F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; - - // When the view isn't panned, 0,0 = center of rectangle - F32 bottom = sPanY + half_height + relative_y; - F32 left = sPanX + half_width + relative_x; - F32 top = bottom + sMapScale * ((F32)info->getSizeY() / 256.f); - F32 right = left + sMapScale * ((F32)info->getSizeX() / 256.f); - - // Switch to world map texture (if available for this region) if either: - // 1. Tiles are zoomed out small enough, or - // 2. Sim's texture has not been loaded yet - F32 map_scale_cutoff = SIM_MAP_SCALE; -#if 0 // This is always false, as REGION_FLAGS_NULL_LAYER doesn't exist anymore - if ((info->getRegionFlags() & REGION_FLAGS_NULL_LAYER) > 0) - { - map_scale_cutoff = SIM_NULL_MAP_SCALE; - } -#endif - - bool sim_visible = - (sMapScale >= map_scale_cutoff) && - (simimage != NULL) && - (simimage->hasGLTexture()); - - if (sim_visible) - { - // Fade in - if (info->getAlpha() < 0.0f) - info->setAlpha( 1.f ); // don't fade initially - else - info->setAlpha(lerp(info->getAlpha(), 1.f, LLCriticalDamp::getInterpolant(0.15f))); - } - else - { - // Fade out - if (info->getAlpha() < 0.0f) - info->setAlpha( 0.f ); // don't fade initially - else - info->setAlpha(lerp(info->getAlpha(), 0.f, LLCriticalDamp::getInterpolant(0.15f))); - } - - // discard regions that are outside the rectangle - // and discard small regions - if (top < 0.f || - bottom > height || - right < 0.f || - left > width ) - { - if (simimage != NULL) simimage->setBoostLevel(0); - if (overlayimage != NULL) overlayimage->setBoostLevel(0); - continue; - } - - if (info->mCurrentImage.isNull()) + if (!simimage && sim_info.mMapImageID[SIM_LAYER_COMPOSITE].notNull() && sim_info.mMapImageID[SIM_LAYER_COMPOSITE] != IMG_DEFAULT) { if ((textures_requested_this_tick < MIN_REQUEST_PER_TICK) || ((LLAppViewer::getTextureFetch()->getNumRequests() < MAX_SIMULTANEOUS_TEX) && (textures_requested_this_tick < MAX_REQUEST_PER_TICK))) { textures_requested_this_tick++; - if (use_web_map_tiles && info->getSizeX() == REGION_WIDTH_UNITS && - info->getSizeY() == REGION_WIDTH_UNITS) - { - LLVector3d region_pos = info->getGlobalOrigin(); - info->mCurrentImage = LLWorldMap::loadObjectsTile((U32)(region_pos.mdV[VX] / REGION_WIDTH_UNITS), (U32)(region_pos.mdV[VY] / REGION_WIDTH_UNITS)); - } - else - { - info->mCurrentImage = LLViewerTextureManager::getFetchedTexture(info->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE); - } - info->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); - simimage = info->mCurrentImage; - gGL.getTexUnit(0)->bind(simimage); - } - } - if (info->mOverlayImage.isNull() && info->mMapImageID[2].notNull()) - { - if ((textures_requested_this_tick < MIN_REQUEST_PER_TICK) || - ((LLAppViewer::getTextureFetch()->getNumRequests() < MAX_SIMULTANEOUS_TEX) && - (textures_requested_this_tick < MAX_REQUEST_PER_TICK))) - { - textures_requested_this_tick++; - info->mOverlayImage = LLViewerTextureManager::getFetchedTexture(info->mMapImageID[2], MIPMAP_TRUE); - info->mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP); - overlayimage = info->mOverlayImage; - gGL.getTexUnit(0)->bind(overlayimage); + simimage = sim_info.mLayerImage[SIM_LAYER_COMPOSITE] = LLViewerTextureManager::getFetchedTexture(sim_info.mMapImageID[SIM_LAYER_COMPOSITE], MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); + simimage->setAddressMode(LLTexUnit::TAM_CLAMP); } } + } - // Bias the priority escalation for images nearer - LLVector3d center_global = origin_global; - center_global.mdV[VX] += 128.0; - center_global.mdV[VY] += 128.0; + const bool sim_drawable = simimage && !simimage->isMissingAsset() && simimage->getID() != IMG_DEFAULT; + const bool sim_fetching = sim_drawable && !simimage->hasGLTexture(); + const F32 fade_target = sim_visible ? 1.f : 0.f; + //Logic is a bit confusing here. Basically, we want to fade out on zoom-out, and fade in on either zoom-in OR texture has finished fetching. + //However, we instantly hide the tile if the texture is invalid or hasn't loaded. The tile never would have been visible before this, anyhow. + if (!sim_drawable || sim_fetching) + sim_info.setAlpha( 0.f ); + else if (llabs(sim_info.getAlpha() - fade_target) > ALPHA_CUTOFF) //This gives us a nice fade when a visible sims texture finishes loading, or visiblity has changed. + sim_info.setAlpha(lerp(sim_info.getAlpha(), fade_target, LLCriticalDamp::getInterpolant(0.15f))); + F32 alpha = sim_info.getAlpha(); + + //call setKnownDrawSize if image is still loading, or its actually being drawn. + if(sim_fetching || alpha >= ALPHA_CUTOFF) + { S32 draw_size = llround(sMapScale); - if (simimage != NULL) + simimage->setKnownDrawSize( llround(draw_size * LLUI::getScaleFactor().mV[VX] * ((F32)sim_info.getSizeX() / REGION_WIDTH_METERS)), + llround(draw_size * LLUI::getScaleFactor().mV[VY] * ((F32)sim_info.getSizeY() / REGION_WIDTH_METERS))); + simimage->setBoostLevel(LLGLTexture::BOOST_MAP); + if(alpha >= ALPHA_CUTOFF) { - simimage->setBoostLevel(LLViewerTexture::BOOST_MAP); - simimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX] * ((F32)info->getSizeX() / REGION_WIDTH_UNITS)), - llround(draw_size * LLUI::sGLScaleFactor.mV[VY] * ((F32)info->getSizeY() / REGION_WIDTH_UNITS))); - } - - if (overlayimage != NULL) - { - overlayimage->setBoostLevel(LLViewerTexture::BOOST_MAP); - overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX] * ((F32)info->getSizeX() / REGION_WIDTH_UNITS)), - llround(draw_size * LLUI::sGLScaleFactor.mV[VY] * ((F32)info->getSizeY() / REGION_WIDTH_UNITS))); - } - -// LLTextureView::addDebugImage(simimage); - - if (sim_visible && info->getAlpha() > 0.001f) - { - // Draw using the texture. If we don't clamp we get artifact at - // the edge. - LLGLSUIDefault gls_ui; - if (simimage != NULL) - gGL.getTexUnit(0)->bind(simimage); - - gGL.setSceneBlendType(LLRender::BT_ALPHA); - F32 alpha = sim_alpha * info->getAlpha(); - gGL.color4f(1.f, 1.0f, 1.0f, alpha); - + gGL.getTexUnit(0)->bind(simimage); + gGL.color4f(1.f, 1.f, 1.f, alpha); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); - gGL.vertex3f(left, top, 0.f); + gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); - gGL.vertex3f(left, bottom, 0.f); + gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); - gGL.vertex3f(right, bottom, 0.f); + gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); - gGL.vertex3f(right, top, 0.f); - gGL.end(); - - static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); - if (map_show_land_for_sale && overlayimage && overlayimage->hasGLTexture()) - { - gGL.getTexUnit(0)->bind(overlayimage); - gGL.color4f(1.f, 1.f, 1.f, alpha); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0.f, 1.f); - gGL.vertex3f(left, top, -0.5f); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex3f(left, bottom, -0.5f); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex3f(right, bottom, -0.5f); - gGL.texCoord2f(1.f, 1.f); - gGL.vertex3f(right, top, -0.5f); - gGL.end(); - } - - if (true /*V3: REGION_FLAGS_NULL_LAYER doesn't exist... (info->getRegionFlags() & REGION_FLAGS_NULL_LAYER) == 0*/) - { - // draw an alpha of 1 where the sims are visible (except NULL sims) - gGL.flush(); - gGL.setSceneBlendType(LLRender::BT_REPLACE); - gGL.setColorMask(false, true); - gGL.color4f(1.f, 1.f, 1.f, 1.f); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin(LLRender::QUADS); - gGL.vertex2f(left, top); - gGL.vertex2f(left, bottom); - gGL.vertex2f(right, bottom); - gGL.vertex2f(right, top); - gGL.end(); - - gGL.flush(); - gGL.setColorMask(true, true); - } - } - - if (info->isDown()) - { - // Draw a transparent red square over down sims - gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_SOURCE_ALPHA); - gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin(LLRender::QUADS); - gGL.vertex2f(left, top); - gGL.vertex2f(left, bottom); - gGL.vertex2f(right, bottom); gGL.vertex2f(right, top); gGL.end(); } - - // As part of the AO project, we no longer want to draw access indicators; - // it's too complicated to get all the rules straight and will only - // cause confusion. - /********************** - // If this is mature, and you are not, draw a line across it - if (info->mAccess != SIM_ACCESS_DOWN - && info->mAccess > SIM_ACCESS_PG - && gAgent.isTeen()) - { - gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color3f(1.f, 0.f, 0.f); - gGL.begin(LLRender::LINES); - gGL.vertex2f(left, top); - gGL.vertex2f(right, bottom); - gGL.vertex2f(left, bottom); - gGL.vertex2f(right, top); - gGL.end(); - } - **********************/ } -} - -void LLWorldMapView::drawGenericItems(const LLWorldMap::item_info_list_t& items, LLUIImagePtr image) -{ - LLWorldMap::item_info_list_t::const_iterator e; - for (e = items.begin(); e != items.end(); ++e) + else //Either the texture is invalid or view has zoomed out far enough and the sim has fully faded away. { - drawGenericItem(*e, image); + sim_info.dropImagePriority(SIM_LAYER_COMPOSITE); } -} - -void LLWorldMapView::drawGenericItem(const LLItemInfo& item, LLUIImagePtr image) -{ - drawImage(item.getGlobalPosition(), image); -} - - -void LLWorldMapView::drawImage(const LLVector3d& global_pos, LLUIImagePtr image, const LLColor4& color) -{ - LLVector3 pos_map = globalPosToView( global_pos ); - image->draw(llround(pos_map.mV[VX] - image->getWidth() /2.f), - llround(pos_map.mV[VY] - image->getHeight()/2.f), - color); -} - -void LLWorldMapView::drawImageStack(const LLVector3d& global_pos, LLUIImagePtr image, U32 count, F32 offset, const LLColor4& color) -{ - LLVector3 pos_map = globalPosToView( global_pos ); - for(U32 i=0; idraw(llround(pos_map.mV[VX] - image->getWidth() /2.f), - llround(pos_map.mV[VY] - image->getHeight()/2.f + i*offset), - color); - } -} - - -void LLWorldMapView::drawAgents() -{ - if(sMapScale < SIM_MAP_AGENT_SCALE) - return; - - F32 agents_scale = (sMapScale * 0.9f) / 256.f; - - LLColor4 avatar_color = gColors.getColor( "MapAvatar" ); - // LLColor4 friend_color = gColors.getColor( "MapFriend" ); - - for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) - { - U64 handle = *iter; - LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); - if (siminfo && (siminfo->isDown())) - { - continue; - } - LLWorldMap::agent_list_map_t::iterator counts_iter = LLWorldMap::getInstance()->mAgentLocationsMap.find(handle); - if (siminfo && siminfo->mShowAgentLocations && counts_iter != LLWorldMap::getInstance()->mAgentLocationsMap.end()) - { - // Show Individual agents (or little stacks where real agents are) - LLWorldMap::item_info_list_t& agentcounts = counts_iter->second; - S32 sim_agent_count = 0; - for (LLWorldMap::item_info_list_t::iterator iter = agentcounts.begin(); - iter != agentcounts.end(); ++iter) - { - const LLItemInfo& info = *iter; - S32 agent_count = info.mExtra; - sim_agent_count += info.mExtra; - // Here's how we'd choose the color if info.mID were available but it's not being sent: - //LLColor4 color = (agent_count == 1 && is_agent_friend(info.mID)) ? friend_color : avatar_color; - drawImageStack(info.getGlobalPosition(), sAvatarSmallImage, agent_count, 3.f, avatar_color); - } - LLWorldMap::getInstance()->mNumAgents[handle] = sim_agent_count; // override mNumAgents for this sim - } - else - { - // Show agent 'stack' at center of sim - S32 num_agents = LLWorldMap::getInstance()->mNumAgents[handle]; - if (num_agents > 0) - { - LLVector3d region_center = from_region_handle(handle); - region_center[VX] += REGION_WIDTH_METERS / 2; - region_center[VY] += REGION_WIDTH_METERS / 2; - // Reduce the stack size as you zoom out - always display at lease one agent where there is one or more - S32 agent_count = (S32)(((num_agents-1) * agents_scale + (num_agents-1) * 0.1f)+.1f) + 1; - drawImageStack(region_center, sAvatarSmallImage, agent_count, 3.f, avatar_color); - } - } - } -} - - -void LLWorldMapView::drawEvents() -{ - bool mature_enabled = gAgent.canAccessMature(); - bool adult_enabled = gAgent.canAccessAdult(); - - static const LLCachedControl map_show_pg_events("MapShowPGEvents"); - static const LLCachedControl map_show_mature_events("MapShowMatureEvents"); - static const LLCachedControl map_show_adult_events("MapShowAdultEvents"); - - BOOL show_pg = map_show_pg_events; - BOOL show_mature = mature_enabled && map_show_mature_events; - BOOL show_adult = adult_enabled && map_show_adult_events; - - // First the non-selected events - LLWorldMap::item_info_list_t::const_iterator e; - if (show_pg) - { - for (e = LLWorldMap::getInstance()->mPGEvents.begin(); e != LLWorldMap::getInstance()->mPGEvents.end(); ++e) - { - if (!e->mSelected) - { - drawGenericItem(*e, sEventImage); - } - } - } - if (show_mature) - { - for (e = LLWorldMap::getInstance()->mMatureEvents.begin(); e != LLWorldMap::getInstance()->mMatureEvents.end(); ++e) - { - if (!e->mSelected) - { - drawGenericItem(*e, sEventMatureImage); - } - } - } - if (show_adult) - { - for (e = LLWorldMap::getInstance()->mAdultEvents.begin(); e != LLWorldMap::getInstance()->mAdultEvents.end(); ++e) - { - if (!e->mSelected) - { - drawGenericItem(*e, sEventAdultImage); - } - } - } - // Then the selected events - if (show_pg) - { - for (e = LLWorldMap::getInstance()->mPGEvents.begin(); e != LLWorldMap::getInstance()->mPGEvents.end(); ++e) - { - if (e->mSelected) - { - drawGenericItem(*e, sEventImage); - } - } - } - if (show_mature) - { - for (e = LLWorldMap::getInstance()->mMatureEvents.begin(); e != LLWorldMap::getInstance()->mMatureEvents.end(); ++e) - { - if (e->mSelected) - { - drawGenericItem(*e, sEventMatureImage); - } - } - } - if (show_adult) - { - for (e = LLWorldMap::getInstance()->mAdultEvents.begin(); e != LLWorldMap::getInstance()->mAdultEvents.end(); ++e) - { - if (e->mSelected) - { - drawGenericItem(*e, sEventAdultImage); - } - } - } -} - - -void LLWorldMapView::drawFrustum() -{ - // Draw frustum - F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS; - - F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); - F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); - F32 far_clip_pixels = far_clip_meters * meters_to_pixels; - - F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); - F32 half_width_pixels = half_width_meters * meters_to_pixels; - - F32 ctr_x = getRect().getWidth() * 0.5f + sPanX; - F32 ctr_y = getRect().getHeight() * 0.5f + sPanY; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // Since we don't rotate the map, we have to rotate the frustum. - gGL.pushMatrix(); - gGL.translatef( ctr_x, ctr_y, 0 ); - gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); - - // Draw triangle with more alpha in far pixels to make it - // fade out in distance. - gGL.begin( LLRender::TRIANGLES ); - gGL.color4f(1.f, 1.f, 1.f, 0.25f); - gGL.vertex2f( 0, 0 ); - - gGL.color4f(1.f, 1.f, 1.f, 0.02f); - gGL.vertex2f( -half_width_pixels, far_clip_pixels ); - - gGL.color4f(1.f, 1.f, 1.f, 0.02f); - gGL.vertex2f( half_width_pixels, far_clip_pixels ); - gGL.end(); - gGL.popMatrix(); + return alpha; } void LLWorldMapView::drawMipmap(S32 width, S32 height) @@ -1212,90 +983,6 @@ void LLWorldMapView::drawMipmap(S32 width, S32 height) // Render the current level sVisibleTilesLoaded = drawMipmapLevel(width, height, level); - const F32 half_width = F32(width) / 2.0f; - const F32 half_height = F32(height) / 2.0f; - LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - - for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); - it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) - { - U64 handle = it->first; - LLSimInfo* info = it->second; - - LLVector3d origin_global = from_region_handle(handle); - - // Find x and y position relative to camera's center. - LLVector3d rel_region_pos = origin_global - camera_global; - F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; - F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; - - // Coordinates of the sim in pixels in the UI panel - // When the view isn't panned, 0,0 = center of rectangle - F32 bottom = sPanY + half_height + relative_y; - F32 left = sPanX + half_width + relative_x; - F32 top = bottom + sMapScale ; - F32 right = left + sMapScale ; - - // Discard if region is outside the screen rectangle (not visible on screen) - if ((top < 0.f) || (bottom > height) || - (right < 0.f) || (left > width) ) - { - // Drop the "land for sale" fetching priority since it's outside the view rectangle - info->dropImagePriority(); - continue; - } - - if (info->isDown()) - { - // Draw a transparent red square over down sims - gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_SOURCE_ALPHA); - gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin(LLRender::QUADS); - gGL.vertex2f(left, top); - gGL.vertex2f(left, bottom); - gGL.vertex2f(right, bottom); - gGL.vertex2f(right, top); - gGL.end(); - } - - if (gSavedSettings.getBOOL("MapShowLandForSale") && (sMapScale >= SIM_LANDFORSALE_SCALE)) - { - // Draw the overlay image "Land for Sale / Land for Auction" - LLViewerFetchedTexture* overlayimage = info->getLandForSaleImage(); - if (overlayimage) - { - // Inform the fetch mechanism of the size we need - S32 draw_size = llround(sMapScale); - overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY])); - // Draw something whenever we have enough info - if (overlayimage->hasGLTexture() && !overlayimage->isMissingAsset()) - { - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - gGL.getTexUnit(0)->bind(overlayimage); - gGL.color4f(1.f, 1.f, 1.f, 1.f); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0.f, 1.f); - gGL.vertex3f(left, top, -0.5f); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex3f(left, bottom, -0.5f); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex3f(right, bottom, -0.5f); - gGL.texCoord2f(1.f, 1.f); - gGL.vertex3f(right, top, -0.5f); - gGL.end(); - } - } - } - else - { - // If we're not displaying the "land for sale", drop its fetching priority - info->dropImagePriority(); - } - } - return; } @@ -1348,13 +1035,13 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load F32 left = pos_screen[VX]; F32 bottom = pos_screen[VY]; // Compute the NE corner coordinates of the tile now - LLSimInfo* simInfo = LLWorldMap::instance().simInfoFromHandle(to_region_handle(grid_x, grid_y)); + /*LLSimInfo* simInfo = LLWorldMap::instance().simInfoFromHandle(to_region_handle(grid_x, grid_y)); if(simInfo != NULL) { pos_global[VX] += ((F32)tile_width * ((F32)simInfo->getSizeX() / REGION_WIDTH_METERS)); pos_global[VY] += ((F32)tile_width * ((F32)simInfo->getSizeY() / REGION_WIDTH_METERS)); } - else + else*/ { pos_global[VX] += tile_width; pos_global[VY] += tile_width; @@ -1367,10 +1054,7 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load LLGLSUIDefault gls_ui; gGL.getTexUnit(0)->bind(simimage.get()); simimage->setAddressMode(LLTexUnit::TAM_CLAMP); - - gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.color4f(1.f, 1.0f, 1.0f, 1.0f); - gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex3f(left, top, 0.f); @@ -1385,6 +1069,7 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load drawTileOutline(level, top, left, bottom, right); #endif // DEBUG_DRAW_TILE } + //else } else { @@ -1398,6 +1083,206 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load return (completed_tiles == total_tiles); } +// Draw lines (rectangle outline and cross) to visualize the position of the tile +// Used for debug only +void LLWorldMapView::drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right) +{ + gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + if (level == 1) + gGL.color3f(1.f, 0.f, 0.f); // red + else if (level == 2) + gGL.color3f(0.f, 1.f, 0.f); // green + else if (level == 3) + gGL.color3f(0.f, 0.f, 1.f); // blue + else if (level == 4) + gGL.color3f(1.f, 1.f, 0.f); // yellow + else if (level == 5) + gGL.color3f(1.f, 0.f, 1.f); // magenta + else if (level == 6) + gGL.color3f(0.f, 1.f, 1.f); // cyan + else if (level == 7) + gGL.color3f(1.f, 1.f, 1.f); // white + else + gGL.color3f(0.f, 0.f, 0.f); // black + gGL.begin(LLRender::LINE_STRIP); + gGL.vertex2f(left, top); + gGL.vertex2f(right, bottom); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, top); + gGL.vertex2f(left, top); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, bottom); + gGL.vertex2f(right, top); + gGL.end(); + + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); +} + +void LLWorldMapView::drawGenericItems(const LLSimInfo::item_info_list_t& items, LLUIImagePtr image) +{ + LLSimInfo::item_info_list_t::const_iterator e; + for (e = items.begin(); e != items.end(); ++e) + { + drawGenericItem(*e, image); + } +} + +void LLWorldMapView::drawGenericItem(const LLItemInfo& item, LLUIImagePtr image) +{ + drawImage(item.getGlobalPosition(), image); +} + + +void LLWorldMapView::drawImage(const LLVector3d& global_pos, LLUIImagePtr image, const LLColor4& color) +{ + LLVector3 pos_map = globalPosToView( global_pos ); + image->draw(llround(pos_map.mV[VX] - image->getWidth() /2.f), + llround(pos_map.mV[VY] - image->getHeight()/2.f), + color); +} + +void LLWorldMapView::drawImageStack(const LLVector3d& global_pos, LLUIImagePtr image, U32 count, F32 offset, const LLColor4& color) +{ + LLVector3 pos_map = globalPosToView( global_pos ); + for(U32 i=0; idraw(llround(pos_map.mV[VX] - image->getWidth() /2.f), + llround(pos_map.mV[VY] - image->getHeight()/2.f + i*offset), + color); + } +} + +void LLWorldMapView::drawItems() +{ + bool mature_enabled = gAgent.canAccessMature(); + bool adult_enabled = gAgent.canAccessAdult(); + + static const LLCachedControl map_show_infohubs("MapShowInfohubs"); + static const LLCachedControl map_show_telehubs("MapShowTelehubs"); + static const LLCachedControl map_show_pg_events("MapShowPGEvents"); + static const LLCachedControl map_show_mature_events("MapShowMatureEvents"); + static const LLCachedControl map_show_adult_events("MapShowAdultEvents"); + static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); + + BOOL show_mature = mature_enabled && map_show_mature_events; + BOOL show_adult = adult_enabled && map_show_adult_events; + + for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) + { + U64 handle = *iter; + LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if ((info == NULL) || (info->isDown())) + { + continue; + } + // Infohubs + if (map_show_infohubs) + { + drawGenericItems(info->getInfoHub(), sInfohubImage); + } + // Telehubs + if (map_show_telehubs) + { + drawGenericItems(info->getTeleHub(), sTelehubImage); + } + // Land for sale + if (map_show_land_for_sale) + { + drawGenericItems(info->getLandForSale(), sForSaleImage); + // for 1.23, we're showing normal land and adult land in the same UI; you don't + // get a choice about which ones you want. If you're currently asking for adult + // content and land you'll get the adult land. + if (gAgent.canAccessAdult()) + { + drawGenericItems(info->getLandForSaleAdult(), sForSaleAdultImage); + } + } + // PG Events + if (map_show_pg_events) + { + drawGenericItems(info->getPGEvent(), sEventImage); + } + // Mature Events + if (show_mature) + { + drawGenericItems(info->getMatureEvent(), sEventMatureImage); + } + // Adult Events + if (show_adult) + { + drawGenericItems(info->getAdultEvent(), sEventAdultImage); + } + } +} + +void LLWorldMapView::drawAgents() +{ + F32 agents_scale = (sMapScale * 0.9f) / 256.f; + + LLColor4 avatar_color = gColors.getColor( "MapAvatar" ); + // LLColor4 friend_color = gColors.getColor( "MapFriend" ); + + for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) + { + U64 handle = *iter; + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if ((siminfo == NULL) || (siminfo->isDown())) + { + continue; + } + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getAgentLocation().begin(); + while (it != siminfo->getAgentLocation().end()) + { + // Show Individual agents (or little stacks where real agents are) + + // Here's how we'd choose the color if info.mID were available but it's not being sent: + // LLColor4 color = (agent_count == 1 && is_agent_friend(info.mID)) ? friend_color : avatar_color; + // Reduce the stack size as you zoom out - always display at lease one agent where there is one or more + S32 agent_count = (S32)(((it->getCount()-1) * agents_scale + (it->getCount()-1) * 0.1f)+.1f) + 1; + drawImageStack(it->getGlobalPosition(), sAvatarSmallImage, agent_count, 3.f, avatar_color); + ++it; + } + } +} + +void LLWorldMapView::drawFrustum() +{ + // Draw frustum + F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS; + + F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); + F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); + F32 far_clip_pixels = far_clip_meters * meters_to_pixels; + + F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); + F32 half_width_pixels = half_width_meters * meters_to_pixels; + + F32 ctr_x = getRect().getWidth() * 0.5f + sPanX; + F32 ctr_y = getRect().getHeight() * 0.5f + sPanY; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + // Since we don't rotate the map, we have to rotate the frustum. + gGL.pushMatrix(); + gGL.translatef( ctr_x, ctr_y, 0 ); + gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); + + // Draw triangle with more alpha in far pixels to make it + // fade out in distance. + gGL.begin( LLRender::TRIANGLES ); + gGL.color4f(1.f, 1.f, 1.f, 0.25f); + gGL.vertex2f( 0, 0 ); + + gGL.color4f(1.f, 1.f, 1.f, 0.02f); + gGL.vertex2f( -half_width_pixels, far_clip_pixels ); + + gGL.color4f(1.f, 1.f, 1.f, 0.02f); + gGL.vertex2f( half_width_pixels, far_clip_pixels ); + gGL.end(); + gGL.popMatrix(); +} LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos ) { LLVector3d relative_pos_global = global_pos - gAgentCamera.getCameraPositionGlobal(); @@ -1468,9 +1353,7 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& text_x, text_y, LLColor4::white, LLFontGL::HCENTER, - LLFontGL::BASELINE, - LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW); + LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); if (tooltip != "") { @@ -1481,9 +1364,7 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& text_x, text_y, LLColor4::white, LLFontGL::HCENTER, - LLFontGL::BASELINE, - LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW); + LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); } } } @@ -1517,8 +1398,9 @@ LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y ) BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen ) { LLVector3d pos_global = viewPosToGlobal(x, y); + U64 handle = to_region_handle(pos_global); - LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); + LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); if (info) { LLViewerRegion *region = gAgent.getRegion(); @@ -1532,8 +1414,8 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic if (!info->isDown()) { - S32 agent_count = LLWorldMap::getInstance()->mNumAgents[info->getHandle()]; - if (region && region->getHandle() == info->getHandle()) + S32 agent_count = info->getAgentCount(); + if (region && (region->getHandle() == handle)) { ++agent_count; // Bump by 1 if we're here } @@ -1621,7 +1503,7 @@ static void drawDot(F32 x_pixels, F32 y_pixels, // static void LLWorldMapView::drawAvatar(F32 x_pixels, F32 y_pixels, - LLColor4 color, + const LLColor4& color, F32 relative_z, F32 dot_radius) { @@ -1932,7 +1814,7 @@ bool LLWorldMapView::checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bo gFloaterWorldMap->trackGenericItem(item); } - item.mSelected = TRUE; +// item.mSelected = TRUE; *id = item.getUUID(); return true; @@ -1956,111 +1838,119 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, *hit_type = 0; // hit nothing - LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE; - LLWorldMap::getInstance()->mIsTrackingDoubleClick = FALSE; - LLWorldMap::getInstance()->mIsTrackingCommit = FALSE; + LLWorldMap::getInstance()->cancelTracking(); - LLWorldMap::item_info_list_t::iterator it; - - // clear old selected stuff - for (it = LLWorldMap::getInstance()->mPGEvents.begin(); it != LLWorldMap::getInstance()->mPGEvents.end(); ++it) - { - (*it).mSelected = FALSE; - } - for (it = LLWorldMap::getInstance()->mMatureEvents.begin(); it != LLWorldMap::getInstance()->mMatureEvents.end(); ++it) - { - (*it).mSelected = FALSE; - } - for (it = LLWorldMap::getInstance()->mAdultEvents.begin(); it != LLWorldMap::getInstance()->mAdultEvents.end(); ++it) - { - (*it).mSelected = FALSE; - } - for (it = LLWorldMap::getInstance()->mLandForSale.begin(); it != LLWorldMap::getInstance()->mLandForSale.end(); ++it) - { - (*it).mSelected = FALSE; - } - - // Select event you clicked on static const LLCachedControl map_show_pg_events("MapShowPGEvents"); - if (map_show_pg_events) - { - for (it = LLWorldMap::getInstance()->mPGEvents.begin(); it != LLWorldMap::getInstance()->mPGEvents.end(); ++it) - { - LLItemInfo& event = *it; - - if (checkItemHit(x, y, event, id, false)) - { - *hit_type = MAP_ITEM_PG_EVENT; - mItemPicked = TRUE; - gFloaterWorldMap->trackEvent(event); - return; - } - } - } static const LLCachedControl map_show_mature_events("MapShowMatureEvents"); - if (map_show_mature_events) - { - for (it = LLWorldMap::getInstance()->mMatureEvents.begin(); it != LLWorldMap::getInstance()->mMatureEvents.end(); ++it) - { - LLItemInfo& event = *it; - - if (checkItemHit(x, y, event, id, false)) - { - *hit_type = MAP_ITEM_MATURE_EVENT; - mItemPicked = TRUE; - gFloaterWorldMap->trackEvent(event); - return; - } - } - } static const LLCachedControl map_show_adult_events("MapShowAdultEvents"); - if (map_show_adult_events) - { - for (it = LLWorldMap::getInstance()->mAdultEvents.begin(); it != LLWorldMap::getInstance()->mAdultEvents.end(); ++it) - { - LLItemInfo& event = *it; - - if (checkItemHit(x, y, event, id, false)) - { - *hit_type = MAP_ITEM_ADULT_EVENT; - mItemPicked = TRUE; - gFloaterWorldMap->trackEvent(event); - return; - } - } - } static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); - if (map_show_land_for_sale) - { - for (it = LLWorldMap::getInstance()->mLandForSale.begin(); it != LLWorldMap::getInstance()->mLandForSale.end(); ++it) - { - LLItemInfo& land = *it; - if (checkItemHit(x, y, land, id, true)) - { - *hit_type = MAP_ITEM_LAND_FOR_SALE; - mItemPicked = TRUE; - return; - } - } - - for (it = LLWorldMap::getInstance()->mLandForSaleAdult.begin(); it != LLWorldMap::getInstance()->mLandForSaleAdult.end(); ++it) - { - LLItemInfo& land = *it; + if(sMapScale >= DRAW_TEXT_THRESHOLD) + { + bool show_mature = gAgent.canAccessMature() && map_show_mature_events; + bool show_adult = gAgent.canAccessAdult() && map_show_adult_events; - if (checkItemHit(x, y, land, id, true)) - { - *hit_type = MAP_ITEM_LAND_FOR_SALE_ADULT; - mItemPicked = TRUE; - return; - } + // Test hits if trackable data are displayed, otherwise, we don't even bother + if (map_show_pg_events || show_mature || show_adult || map_show_land_for_sale) + { + // Iterate through the visible regions + for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) + { + U64 handle = *iter; + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if ((siminfo == NULL) || (siminfo->isDown())) + { + continue; + } + // If on screen check hits with the visible item lists + if (map_show_pg_events) + { + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getPGEvent().begin(); + while (it != siminfo->getPGEvent().end()) + { + LLItemInfo event = *it; + if (checkItemHit(x, y, event, id, false)) + { + *hit_type = MAP_ITEM_PG_EVENT; + mItemPicked = TRUE; + gFloaterWorldMap->trackEvent(event); + return; + } + ++it; + } + } + if (show_mature) + { + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getMatureEvent().begin(); + while (it != siminfo->getMatureEvent().end()) + { + LLItemInfo event = *it; + if (checkItemHit(x, y, event, id, false)) + { + *hit_type = MAP_ITEM_MATURE_EVENT; + mItemPicked = TRUE; + gFloaterWorldMap->trackEvent(event); + return; + } + ++it; + } + } + if (show_adult) + { + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getAdultEvent().begin(); + while (it != siminfo->getAdultEvent().end()) + { + LLItemInfo event = *it; + if (checkItemHit(x, y, event, id, false)) + { + *hit_type = MAP_ITEM_ADULT_EVENT; + mItemPicked = TRUE; + gFloaterWorldMap->trackEvent(event); + return; + } + ++it; + } + } + if (map_show_land_for_sale) + { + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getLandForSale().begin(); + while (it != siminfo->getLandForSale().end()) + { + LLItemInfo event = *it; + if (checkItemHit(x, y, event, id, true)) + { + *hit_type = MAP_ITEM_LAND_FOR_SALE; + mItemPicked = TRUE; + return; + } + ++it; + } + // for 1.23, we're showing normal land and adult land in the same UI; you don't + // get a choice about which ones you want. If you're currently asking for adult + // content and land you'll get the adult land. + if (gAgent.canAccessAdult()) + { + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getLandForSaleAdult().begin(); + while (it != siminfo->getLandForSaleAdult().end()) + { + LLItemInfo event = *it; + if (checkItemHit(x, y, event, id, true)) + { + *hit_type = MAP_ITEM_LAND_FOR_SALE_ADULT; + mItemPicked = TRUE; + return; + } + ++it; + } + } + } + } } } - // If we get here, we haven't clicked on an icon + // If we get here, we haven't clicked on anything gFloaterWorldMap->trackLocation(pos_global); mItemPicked = FALSE; - *id = LLUUID::null; return; } @@ -2121,58 +2011,35 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask ) return FALSE; } -U32 LLWorldMapView::updateBlock(S32 block_x, S32 block_y) +void LLWorldMapView::updateVisibleBlocks() { - U32 blocks_requested = 0; - S32 offset = block_x | (block_y * MAP_BLOCK_RES); - if (!LLWorldMap::getInstance()->mMapBlockLoaded[LLWorldMap::getInstance()->mCurrentMap][offset]) - { -// llinfos << "Loading Block (" << block_x << "," << block_y << ")" << llendl; - LLWorldMap::getInstance()->sendMapBlockRequest(block_x << 3, block_y << 3, (block_x << 3) + 7, (block_y << 3) + 7); - LLWorldMap::getInstance()->mMapBlockLoaded[LLWorldMap::getInstance()->mCurrentMap][offset] = TRUE; - blocks_requested++; - } - return blocks_requested; -} - -U32 LLWorldMapView::updateVisibleBlocks() -{ - if (sMapScale < SIM_MAP_SCALE) + if (sMapScale < SIM_DATA_SCALE) { // We don't care what is loaded if we're zoomed out - return 0; + return; } + // Load the blocks visible in the current World Map view + + // Get the World Map view coordinates and boundaries LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - - F32 pixels_per_region = sMapScale; const S32 width = getRect().getWidth(); const S32 height = getRect().getHeight(); - // Convert pan to sim coordinates - S32 world_center_x_lo = S32(((-sPanX - width/2) / pixels_per_region) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); - S32 world_center_x_hi = S32(((-sPanX + width/2) / pixels_per_region) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); - S32 world_center_y_lo = S32(((-sPanY - height/2) / pixels_per_region) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); - S32 world_center_y_hi = S32(((-sPanY + height/2)/ pixels_per_region) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); + const F32 half_width = F32(width) / 2.0f; + const F32 half_height = F32(height) / 2.0f; - // Find the corresponding 8x8 block - S32 world_block_x_lo = world_center_x_lo >> 3; - S32 world_block_x_hi = world_center_x_hi >> 3; - S32 world_block_y_lo = world_center_y_lo >> 3; - S32 world_block_y_hi = world_center_y_hi >> 3; + // Compute center into sim grid coordinates + S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); + S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); - U32 blocks_requested = 0; - const U32 max_blocks_requested = 9; + // Compute the boundaries into sim grid coordinates + S32 world_left = world_center_x - S32(half_width / sMapScale) - 1; + S32 world_right = world_center_x + S32(half_width / sMapScale) + 1; + S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1; + S32 world_top = world_center_y + S32(half_height / sMapScale) + 1; - for (S32 block_x = llmax(world_block_x_lo, 0); block_x <= llmin(world_block_x_hi, MAP_BLOCK_RES-1); ++block_x) - { - for (S32 block_y = llmax(world_block_y_lo, 0); block_y <= llmin(world_block_y_hi, MAP_BLOCK_RES-1); ++block_y) - { - blocks_requested += updateBlock(block_x, block_y); - if (blocks_requested >= max_blocks_requested) - return blocks_requested; - } - } - return blocks_requested; + //LL_INFOS("World Map") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL; + LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top); } BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask ) @@ -2262,9 +2129,9 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) } default: { - if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation) + if (LLWorldMap::getInstance()->isTracking()) { - LLWorldMap::getInstance()->mIsTrackingDoubleClick = TRUE; + LLWorldMap::getInstance()->setTrackingDoubleClick(); } else { diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index 97c79dddf..1df0bfba2 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -86,16 +86,17 @@ public: LLVector3d viewPosToGlobal(S32 x,S32 y); virtual void draw(); - void drawTiles(S32 width, S32 height); - void drawGenericItems(const LLWorldMap::item_info_list_t& items, LLUIImagePtr image); + void drawLegacyBackgroundLayers(S32 width, S32 height); //draw legacy background 'layer' tiles. Only available on official grids, I believe. + F32 drawLegacySimTile(LLSimInfo& sim_info, S32 left, S32 top, S32 right, S32 bottom); //draw legacy sim texture (provided in MapBlockReply message). + void drawGenericItems(const LLSimInfo::item_info_list_t& items, LLUIImagePtr image); void drawGenericItem(const LLItemInfo& item, LLUIImagePtr image); void drawImage(const LLVector3d& global_pos, LLUIImagePtr image, const LLColor4& color = LLColor4::white); void drawImageStack(const LLVector3d& global_pos, LLUIImagePtr image, U32 count, F32 offset, const LLColor4& color); void drawAgents(); - void drawEvents(); + void drawItems(); void drawFrustum(); void drawMipmap(S32 width, S32 height); - bool drawMipmapLevel(S32 width, S32 height, S32 level, bool load = true); + bool drawMipmapLevel(S32 width, S32 height, S32 level, bool load = true); static void cleanupTextures(); @@ -119,7 +120,7 @@ public: S32 overlap ); static void drawAvatar( F32 x_pixels, F32 y_pixels, - LLColor4 color, + const LLColor4& color, F32 relative_z = 0.f, F32 dot_radius = 3.f); static void drawIconName(F32 x_pixels, @@ -132,9 +133,7 @@ public: static void clearLastClick() { sHandledLastClick = FALSE; } // if the view changes, download additional sim info as needed - // return value is number of blocks newly requested. - U32 updateBlock(S32 block_x, S32 block_y); - U32 updateVisibleBlocks(); + void updateVisibleBlocks(); protected: void setDirectionPos( LLTextBox* text_box, F32 rotation ); @@ -161,8 +160,6 @@ public: static LLUIImagePtr sForSaleImage; static LLUIImagePtr sForSaleAdultImage; - static F32 sThresholdA; - static F32 sThresholdB; static F32 sPixelsPerMeter; // world meters to map pixels static F32 sMapScale; // scale = size of a region in pixels @@ -202,6 +199,9 @@ public: handle_list_t mVisibleRegions; // set every frame static std::map sStringsMap; + +private: + void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right); }; #endif diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp index 17ca2d573..e27c5d644 100644 --- a/indra/newview/llworldmipmap.cpp +++ b/indra/newview/llworldmipmap.cpp @@ -78,23 +78,23 @@ void LLWorldMipmap::equalizeBoostLevels() // For each tile for (sublevel_tiles_t::iterator iter = level_mipmap.begin(); iter != level_mipmap.end(); iter++) { - LLPointer img = iter->second; + LLPointer img = iter->second; S32 current_boost_level = img->getBoostLevel(); - if (current_boost_level == LLViewerTexture::BOOST_MAP_VISIBLE) + if (current_boost_level == LLGLTexture::BOOST_MAP_VISIBLE) { // If level was BOOST_MAP_VISIBLE, the tile has been used in the last draw so keep it high - img->setBoostLevel(LLViewerTexture::BOOST_MAP); + img->setBoostLevel(LLGLTexture::BOOST_MAP); } else { // If level was BOOST_MAP only (or anything else...), the tile wasn't used in the last draw // so we drop its boost level to BOOST_NONE. - img->setBoostLevel(LLViewerTexture::BOOST_NONE); + img->setBoostLevel(LLGLTexture::BOOST_NONE); } #if DEBUG_TILES_STAT // Increment some stats if compile option on nb_tiles++; - if (current_boost_level == LLViewerTexture::BOOST_MAP_VISIBLE) + if (current_boost_level == LLGLTexture::BOOST_MAP_VISIBLE) { nb_visible++; } @@ -120,8 +120,8 @@ void LLWorldMipmap::dropBoostLevels() // For each tile for (sublevel_tiles_t::iterator iter = level_mipmap.begin(); iter != level_mipmap.end(); iter++) { - LLPointer img = iter->second; - img->setBoostLevel(LLViewerTexture::BOOST_NONE); + LLPointer img = iter->second; + img->setBoostLevel(LLGLTexture::BOOST_NONE); } } } @@ -178,7 +178,7 @@ LLPointer LLWorldMipmap::getObjectsTile(U32 grid_x, U32 // Boost the tile level so to mark it's in use *if* load on if (load) { - img->setBoostLevel(LLViewerTexture::BOOST_MAP_VISIBLE); + img->setBoostLevel(LLGLTexture::BOOST_MAP_VISIBLE); } return img; } @@ -195,8 +195,8 @@ LLPointer LLWorldMipmap::loadObjectsTile(U32 grid_x, U32 // END DEBUG //LL_INFOS("World Map") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL; - LLPointer img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl); - img->setBoostLevel(LLViewerTexture::BOOST_MAP); + LLPointer img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + img->setBoostLevel(LLGLTexture::BOOST_MAP); // Return the smart pointer return img; @@ -224,7 +224,7 @@ void LLWorldMipmap::cleanMissedTilesFromLevel(S32 level) sublevel_tiles_t::iterator it = level_mipmap.begin(); while (it != level_mipmap.end()) { - LLPointer img = it->second; + LLPointer img = it->second; if (img->isMissingAsset()) { level_mipmap.erase(it++); diff --git a/indra/newview/llxmlrpcresponder.h b/indra/newview/llxmlrpcresponder.h index df01692ae..25615f236 100644 --- a/indra/newview/llxmlrpcresponder.h +++ b/indra/newview/llxmlrpcresponder.h @@ -99,6 +99,8 @@ private: XMLRPC_REQUEST mResponse; public: + XMLRPCResponder(void) : mBufferSize(0), mReceivedHTTPHeader(false), mResponse(NULL) { } + // Accessors. F64 transferRate(void) const; bool is_downloading(void) const { return mReceivedHTTPHeader; } @@ -110,6 +112,7 @@ public: /*virtual*/ void completed_headers(U32 status, std::string const& reason, AITransferInfo* info); /*virtual*/ void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return XMLRPCResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "XMLRPCResponder"; } }; #endif // LLXMLRPCRESPONDER_H diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 867370945..3dcdd421c 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -142,6 +142,8 @@ void check_stack_depth(S32 stack_depth) //#define DEBUG_INDICES #endif +bool gShiftFrame = false; + const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f; @@ -345,8 +347,9 @@ void validate_framebuffer_object(); bool addDeferredAttachments(LLRenderTarget& target) { + static const LLCachedControl SHPrecisionDeferredNormals("SHPrecisionDeferredNormals",false); return target.addColorAttachment(GL_RGBA) && //specular - target.addColorAttachment(GL_RGBA); //normal+z + target.addColorAttachment(SHPrecisionDeferredNormals ? GL_RGB10_A2 : GL_RGBA); //normal+z } LLPipeline::LLPipeline() : @@ -403,6 +406,7 @@ void LLPipeline::init() refreshCachedSettings(); gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); + gOctreeReserveCapacity = llmin(gSavedSettings.getU32("OctreeReserveNodeCapacity"),U32(512)); sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); @@ -427,19 +431,37 @@ void LLPipeline::init() LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); resetFrameStats(); - for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + if (gSavedSettings.getBOOL("DisableAllRenderFeatures")) { - mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled + clearAllRenderDebugFeatures(); + } + else + { + setAllRenderDebugFeatures(); // By default, all debugging features on + } + clearAllRenderDebugDisplays(); // All debug displays off + + if (gSavedSettings.getBOOL("DisableAllRenderTypes")) + { + clearAllRenderTypes(); + } + else + { + setAllRenderTypes(); // By default, all rendering types start enabled + // Don't turn on ground when this is set + // Mac Books with intel 950s need this + if(!gSavedSettings.getBOOL("RenderGround")) + { + toggleRenderType(RENDER_TYPE_GROUND); + } } - mRenderDebugFeatureMask = 0xffffffff; // All debugging features on - mRenderDebugMask = 0; // All debug starts off - - // Don't turn on ground when this is set - // Mac Books with intel 950s need this - if(!gSavedSettings.getBOOL("RenderGround")) + // make sure RenderPerformanceTest persists (hackity hack hack) + // disables non-object rendering (UI, sky, water, etc) + if (gSavedSettings.getBOOL("RenderPerformanceTest")) { - toggleRenderType(RENDER_TYPE_GROUND); + gSavedSettings.setBOOL("RenderPerformanceTest", FALSE); + gSavedSettings.setBOOL("RenderPerformanceTest", TRUE); } mOldRenderDebugMask = mRenderDebugMask; @@ -547,6 +569,7 @@ void LLPipeline::cleanup() mInitialized = FALSE; mDeferredVB = NULL; + mCubeVB = NULL; } //============================================================================ @@ -623,7 +646,43 @@ void LLPipeline::allocatePhysicsBuffer() } } -void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) +bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) +{ + refreshCachedSettings(); + + bool save_settings = sRenderDeferred; + if (save_settings) + { + // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets + gSavedSettings.setBOOL("RenderInitError", TRUE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + } + + eFBOStatus ret = doAllocateScreenBuffer(resX, resY); + + if (save_settings) + { + // don't disable shaders on next session + gSavedSettings.setBOOL("RenderInitError", FALSE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + } + + if (ret == FBO_FAILURE) + { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled + //NOTE: if the session closes successfully after this call, deferred rendering will be + // disabled on future sessions + if (LLPipeline::sRenderDeferred) + { + gSavedSettings.setBOOL("RenderDeferred", FALSE); + LLPipeline::refreshCachedSettings(); + } + } + + return ret == FBO_SUCCESS_FULLRES; +} + + +LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY) { refreshCachedSettings(); static const LLCachedControl RenderFSAASamples("RenderFSAASamples",0); @@ -634,8 +693,12 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) // - if not multisampled, shrink resolution and try again (favor X resolution over Y) // Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state + eFBOStatus ret = FBO_SUCCESS_FULLRES; if (!allocateScreenBuffer(resX, resY, samples)) { + //failed to allocate at requested specification, return false + ret = FBO_FAILURE; + releaseScreenBuffers(); //reduce number of samples while (samples > 0) @@ -643,7 +706,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) samples /= 2; if (allocateScreenBuffer(resX, resY, samples)) { //success - return; + return FBO_SUCCESS_LOWRES; } releaseScreenBuffers(); } @@ -656,22 +719,23 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) resY /= 2; if (allocateScreenBuffer(resX, resY, samples)) { - return; + return FBO_SUCCESS_LOWRES; } releaseScreenBuffers(); resX /= 2; if (allocateScreenBuffer(resX, resY, samples)) { - return; + return FBO_SUCCESS_LOWRES; } releaseScreenBuffers(); } llwarns << "Unable to allocate screen buffer at any resolution!" << llendl; } -} + return ret; +} bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) { @@ -688,10 +752,6 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (LLPipeline::sRenderDeferred) { - // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets - gSavedSettings.setBOOL("RenderInitError", TRUE); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); - S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); BOOL ssao = gSavedSettings.getBOOL("RenderDeferredSSAO"); BOOL RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField"); @@ -759,9 +819,11 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) } } - // don't disable shaders on next session - gSavedSettings.setBOOL("RenderInitError", FALSE); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + //HACK make screenbuffer allocations start failing after 30 seconds + if (gSavedSettings.getBOOL("SimulateFBOFailure")) + { + return false; + } } else { @@ -783,7 +845,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if(mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples)) mScreen.setSampleBuffer(&mSampleBuffer); else - mSampleBuffer.release(); + { + mSampleBuffer.release(); + return false; + } } } @@ -860,7 +925,7 @@ void LLPipeline::releaseGLBuffers() mWaterRef.release(); mWaterDis.release(); - for (U32 i = 0; i < 3; i++) + for (U32 i = 0; i < 2; i++) { mGlow[i].release(); } @@ -926,16 +991,26 @@ void LLPipeline::createGLBuffers() GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + + if (LLPipeline::sRenderGlow) { //screen space glow buffers const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); - for (U32 i = 0; i < 3; i++) + glClearColor(0,0,0,0); + gGL.setColorMask(true, true); + for (U32 i = 0; i < 2; i++) { - mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); + if(mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE)) + { + mGlow[i].bindTarget(); + mGlow[i].clear(); + mGlow[i].unbindTarget(); + } } + allocateScreenBuffer(resX,resY); } @@ -1456,6 +1531,22 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) } +//static +void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) +{ + LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET); + for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); + iter != gPipeline.mNearbyLights.end();) + { + if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) + { + gPipeline.mLights.erase(iter->drawable); + gPipeline.mNearbyLights.erase(iter++); + } + else ++iter; + } +} + U32 LLPipeline::addObject(LLViewerObject *vobj) { llassert_always(vobj); @@ -1643,6 +1734,10 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); if (done) { + if (drawablep->isRoot()) + { + drawablep->makeStatic(); + } drawablep->clearState(LLDrawable::ON_MOVE_LIST); if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) { //will likely not receive any future world matrix updates @@ -1775,6 +1870,7 @@ void LLPipeline::grabReferences(LLCullResult& result) void LLPipeline::clearReferences() { sCull = NULL; + mGroupSaveQ1.clear(); } void check_references(LLSpatialGroup* group, LLDrawable* drawable) @@ -2337,6 +2433,65 @@ void LLPipeline::updateGL() }*/ } +void LLPipeline::clearRebuildGroups() +{ + LLSpatialGroup::sg_vector_t hudGroups; + + mGroupQ1Locked = true; + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } + } + + // Clear the group + //mGroupQ1.clear(); //Assign already clears... + + // Copy the saved HUD groups back in + mGroupQ1.assign(hudGroups.begin(), hudGroups.end()); + mGroupQ1Locked = false; + + // Clear the HUD groups + hudGroups.clear(); + + mGroupQ2Locked = true; + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); + iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } + } + + // Clear the group + //mGroupQ2.clear(); //Assign already clears... + + // Copy the saved HUD groups back in + mGroupQ2.assign(hudGroups.begin(), hudGroups.end()); + mGroupQ2Locked = false; +} + static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups"); void LLPipeline::rebuildPriorityGroups() @@ -2359,6 +2514,7 @@ void LLPipeline::rebuildPriorityGroups() group->clearState(LLSpatialGroup::IN_BUILD_Q1); } + mGroupSaveQ1 = mGroupQ1; mGroupQ1.clear(); mGroupQ1Locked = false; @@ -5037,38 +5193,34 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad // UPDATE THE EXISTING NEARBY LIGHTS - if (!LLPipeline::sSkipUpdate) + light_set_t cur_nearby_lights; + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) { - light_set_t cur_nearby_lights; - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) + const Light* light = &(*iter); + LLDrawable* drawable = light->drawable; + LLVOVolume* volight = drawable->getVOVolume(); + if (!volight || !drawable->isState(LLDrawable::LIGHT)) { - const Light* light = &(*iter); - LLDrawable* drawable = light->drawable; - LLVOVolume* volight = drawable->getVOVolume(); - if (!volight || !drawable->isState(LLDrawable::LIGHT)) - { - setLight(drawable,false); //remove from mLight list - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - if (light->fade <= -LIGHT_FADE_TIME) - { - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - if (!sRenderAttachedLights && volight && volight->isAttachment()) - { - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - - F32 dist = calc_light_dist(volight, cam_pos, max_dist); - cur_nearby_lights.insert(Light(drawable, dist, light->fade)); + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; } - mNearbyLights = cur_nearby_lights; + if (light->fade <= -LIGHT_FADE_TIME) + { + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; + } + if (!sRenderAttachedLights && volight && volight->isAttachment()) + { + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; + } + + F32 dist = calc_light_dist(volight, cam_pos, max_dist); + cur_nearby_lights.insert(Light(drawable, dist, light->fade)); } - + mNearbyLights = cur_nearby_lights; + // FIND NEW LIGHTS THAT ARE IN RANGE light_set_t new_nearby_lights; for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); @@ -5820,6 +5972,34 @@ BOOL LLPipeline::toggleRenderDebugFeatureControl(void* data) return gPipeline.hasRenderDebugFeatureMask(bit); } +void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value) +{ + if (value) + { + gPipeline.mRenderDebugFeatureMask |= bit; + } + else + { + gPipeline.mRenderDebugFeatureMask &= !bit; + } +} + +void LLPipeline::pushRenderDebugFeatureMask() +{ + mRenderDebugFeatureStack.push(mRenderDebugFeatureMask); +} + +void LLPipeline::popRenderDebugFeatureMask() +{ + if (mRenderDebugFeatureStack.empty()) + { + llerrs << "Depleted render feature stack." << llendl; + } + + mRenderDebugFeatureMask = mRenderDebugFeatureStack.top(); + mRenderDebugFeatureStack.pop(); +} + // static void LLPipeline::setRenderScriptedBeacons(BOOL val) { @@ -6159,7 +6339,8 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) } void LLPipeline::resetVertexBuffers() -{ mResetVertexBuffers = true; +{ + mResetVertexBuffers = true; } static LLFastTimer::DeclareTimer FTM_RESET_VB("Reset VB"); @@ -6200,6 +6381,8 @@ void LLPipeline::doResetVertexBuffers() if(LLPostProcess::instanceExists()) LLPostProcess::getInstance()->destroyGL(); + LLVOPartGroup::destroyGL(); + LLVertexBuffer::cleanupClass(); //delete all name pool caches @@ -6432,8 +6615,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b { { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); - mGlow[2].bindTarget(); - mGlow[2].clear(); + mGlow[1].bindTarget(); + mGlow[1].clear(); } gGlowExtractProgram.bind(); @@ -6472,7 +6655,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGL.getTexUnit(0)->unbind(mScreen.getUsage()); - mGlow[2].flush(); + mGlow[1].flush(); } tc1.setVec(0,0); @@ -6504,14 +6687,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b mGlow[i%2].clear(); } - if (i == 0) - { - gGL.getTexUnit(0)->bind(&mGlow[2]); - } - else - { - gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]); - } + gGL.getTexUnit(0)->bind(&mGlow[(i+1)%2]); if (i%2 == 0) { @@ -7217,14 +7393,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR_INV, 1.0/ssao_factor); LLVector3 ssao_effect = RenderSSAOEffect; - F32 matrix_diag = (ssao_effect[0] + 2.0*ssao_effect[1])/3.0; - F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1])/3.0; - // This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by - // value factor, and scales remainder by saturation factor - F32 ssao_effect_mat[] = { matrix_diag, matrix_nondiag, matrix_nondiag, - matrix_nondiag, matrix_diag, matrix_nondiag, - matrix_nondiag, matrix_nondiag, matrix_diag}; - shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat); + shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_EFFECT, ssao_effect[0]); F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); F32 shadow_bias_error = 1.f + RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); @@ -7774,10 +7943,10 @@ void LLPipeline::renderDeferredLighting() pushRenderTypeMask(); andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, LLPipeline::RENDER_TYPE_FULLBRIGHT, - LLPipeline::RENDER_TYPE_VOLUME, + //LLPipeline::RENDER_TYPE_VOLUME, LLPipeline::RENDER_TYPE_GLOW, LLPipeline::RENDER_TYPE_BUMP, - LLPipeline::RENDER_TYPE_PASS_SIMPLE, + /*LLPipeline::RENDER_TYPE_PASS_SIMPLE, //These aren't used. LLPipeline::RENDER_TYPE_PASS_ALPHA, LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, LLPipeline::RENDER_TYPE_PASS_BUMP, @@ -7789,7 +7958,7 @@ void LLPipeline::renderDeferredLighting() LLPipeline::RENDER_TYPE_PASS_GRASS, LLPipeline::RENDER_TYPE_PASS_SHINY, LLPipeline::RENDER_TYPE_PASS_INVISIBLE, - LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,*/ LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); @@ -8559,9 +8728,6 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector 3,7 }; - LLVector3 center = (max+min)*0.5f; - LLVector3 size = (max-min)*0.5f; - for (U32 i = 0; i < 12; i++) { for (U32 j = 0; j < 6; ++j) @@ -8720,7 +8886,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); //currently used for amount to extrude frusta corners for constructing shadow frusta - LLVector3 n = RenderShadowNearDist; + //LLVector3 n = RenderShadowNearDist; //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; //put together a universal "near clip" plane for shadow frusta @@ -9682,25 +9848,25 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) BOOL LLPipeline::hasRenderBatches(const U32 type) const { - return sCull->getRenderMapSize(type) > 0; + return sCull->hasRenderMap(type); } -LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type) const { return sCull->beginRenderMap(type); } -LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type) const { return sCull->endRenderMap(type); } -LLCullResult::sg_iterator LLPipeline::beginAlphaGroups() +LLCullResult::sg_iterator LLPipeline::beginAlphaGroups() const { return sCull->beginAlphaGroups(); } -LLCullResult::sg_iterator LLPipeline::endAlphaGroups() +LLCullResult::sg_iterator LLPipeline::endAlphaGroups() const { return sCull->endAlphaGroups(); } @@ -9825,6 +9991,22 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...) } } +void LLPipeline::setAllRenderTypes() +{ + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = TRUE; + } +} + +void LLPipeline::clearAllRenderTypes() +{ + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = FALSE; + } +} + void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color) { DebugBlip blip(position, color); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e5ed58ca1..a0e89bbdf 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -123,8 +123,25 @@ public: void createGLBuffers(); void createLUTBuffers(); - void allocateScreenBuffer(U32 resX, U32 resY); + //allocate the largest screen buffer possible up to resX, resY + //returns true if full size buffer allocated, false if some other size is allocated + bool allocateScreenBuffer(U32 resX, U32 resY); + + typedef enum { + FBO_SUCCESS_FULLRES = 0, + FBO_SUCCESS_LOWRES, + FBO_FAILURE + } eFBOStatus; + +private: + //implementation of above, wrapped for easy error handling + eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY); +public: + + //attempt to allocate screen buffers at resX, resY + //returns true if allocation successful, false otherwise bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples); + void allocatePhysicsBuffer(); void resetVertexBuffers(LLDrawable* drawable); @@ -155,6 +172,8 @@ public: void unlinkDrawable(LLDrawable*); + static void removeMutedAVsLights(LLVOAvatar*); + // Object related methods void markVisible(LLDrawable *drawablep, LLCamera& camera); void markOccluder(LLSpatialGroup* group); @@ -227,6 +246,7 @@ public: void updateGL(); void rebuildPriorityGroups(); void rebuildGroups(); + void clearRebuildGroups(); //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); @@ -296,30 +316,38 @@ public: void setLight(LLDrawable *drawablep, BOOL is_light); BOOL hasRenderBatches(const U32 type) const; - LLCullResult::drawinfo_iterator beginRenderMap(U32 type); - LLCullResult::drawinfo_iterator endRenderMap(U32 type); - LLCullResult::sg_iterator beginAlphaGroups(); - LLCullResult::sg_iterator endAlphaGroups(); + LLCullResult::drawinfo_iterator beginRenderMap(U32 type) const; + LLCullResult::drawinfo_iterator endRenderMap(U32 type) const; + LLCullResult::sg_iterator beginAlphaGroups() const; + LLCullResult::sg_iterator endAlphaGroups() const; 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; } - - + 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; void setRenderTypeMask(U32 type, ...); - void orRenderTypeMask(U32 type, ...); + // This is equivalent to 'setRenderTypeMask' + //void orRenderTypeMask(U32 type, ...); void andRenderTypeMask(U32 type, ...); void clearRenderTypeMask(U32 type, ...); + void setAllRenderTypes(); + void clearAllRenderTypes(); void pushRenderTypeMask(); void popRenderTypeMask(); + void pushRenderDebugFeatureMask(); + void popRenderDebugFeatureMask(); + static void toggleRenderType(U32 type); // For UI control of render features @@ -332,6 +360,7 @@ public: static void toggleRenderPairedTypeControl(void* data); static BOOL toggleRenderDebugControl(void* data); static BOOL toggleRenderDebugFeatureControl(void* data); + static void setRenderDebugFeatureControl(U32 bit, bool value); static void setRenderParticleBeacons(BOOL val); static void toggleRenderParticleBeacons(void* data); @@ -582,7 +611,7 @@ public: LLRenderTarget mWaterDis; //texture for making the glow - LLRenderTarget mGlow[3]; + LLRenderTarget mGlow[2]; //noise map U32 mNoiseMap; @@ -604,6 +633,7 @@ protected: U32 mRenderDebugFeatureMask; U32 mRenderDebugMask; + std::stack mRenderDebugFeatureStack; U32 mOldRenderDebugMask; @@ -655,6 +685,8 @@ protected: LLSpatialGroup::sg_vector_t mGroupQ1; //priority LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref + LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called U32 mMeshDirtyQueryObject; diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index 4a4e1ff81..2f01d4a84 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -129,6 +129,8 @@ void RlvSettings::initClass() if (gSavedSettings.controlExists(RLV_SETTING_AVATAROFFSET_Z)) gSavedSettings.getControl(RLV_SETTING_AVATAROFFSET_Z)->getSignal()->connect(boost::bind(&onChangedAvatarOffset, _2)); + if (gSavedSettings.controlExists(RLV_SETTING_TOPLEVELMENU)) + gSavedSettings.getControl(RLV_SETTING_TOPLEVELMENU)->getSignal()->connect(boost::bind(&onChangedMenuLevel)); fInitialized = true; } } @@ -155,6 +157,14 @@ bool RlvSettings::onChangedAvatarOffset(const LLSD& sdValue) gAgent.sendAgentSetAppearance(); return true; } +// Checked: 2011-08-16 (RLVa-1.4.0b) | Added: RLVa-1.4.0b +bool RlvSettings::onChangedMenuLevel() +{ + rlvMenuToggleVisible(); + return true; +} + +// Checked: 2010-02-27 (RLVa-1.2.0a) | Added: RLVa-1.1.0i bool RlvSettings::onChangedSettingBOOL(const LLSD& sdValue, bool* pfSetting) { if (pfSetting) @@ -526,6 +536,36 @@ void rlvMenuToggleEnabled(void*) return; } +// Checked: 2011-08-16 (RLVa-1.4.0b) | Added: RLVa-1.4.0b +void rlvMenuToggleVisible() +{ + bool fTopLevel = rlvGetSetting(RLV_SETTING_TOPLEVELMENU, true); + bool fRlvEnabled = rlv_handler_t::isEnabled(); + + //LLMenuGL* pRLVaMenuMain = gMenuBarView->getChildMenuByName("RLVa Main", FALSE); + // RELEASE-RLVa: LL defines CLIENT_MENU_NAME but we can't get to it from here so we need to keep those two in sync manually + LLMenuGL* pAdvancedMenu = gMenuBarView->getChildMenuByName("Advanced", FALSE); + //LLMenuGL* pRLVaMenuEmbed = pAdvancedMenu->getChildMenuByName("RLVa Embedded", FALSE); + + gMenuBarView->setItemVisible("RLVa Main", (fRlvEnabled) && (fTopLevel)); + if (!pAdvancedMenu) return; + pAdvancedMenu->setItemVisible("RLVa Embedded", (fRlvEnabled) && (!fTopLevel)); + + /* Singu Note: In the future when we have advanced menu in xml, we will want to use this to move the menu. + if ( (rlv_handler_t::isEnabled()) && (pRLVaMenuMain) && (pRLVaMenuEmbed) && + ( ((fTopLevel) && (1 == pRLVaMenuMain->getItemCount())) || ((!fTopLevel) && (1 == pRLVaMenuEmbed->getItemCount())) ) ) + { + LLMenuGL* pMenuFrom = (fTopLevel) ? pRLVaMenuEmbed : pRLVaMenuMain; + LLMenuGL* pMenuTo = (fTopLevel) ? pRLVaMenuMain : pRLVaMenuEmbed; + while (LLMenuItemGL* pItem = pMenuFrom->getItem(1)) + { + pMenuFrom->removeChild(pItem); + pMenuTo->addChild(pItem); + pItem->updateBranchParent(pMenuTo); + } + }*/ +} + bool RlvEnableIfNot::handleEvent(LLPointer, const LLSD& userdata) { bool fEnable = true; diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index e44c06f57..463b6f17d 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -198,7 +198,7 @@ typedef bool (RlvCommandHandler::*rlvCommandHandler)(const RlvCommand& rlvCmd, E BOOL rlvMenuCheckEnabled(void*); void rlvMenuToggleEnabled(void*); -//void rlvMenuToggleVisible(void*); +void rlvMenuToggleVisible(); //bool rlvMenuEnableIfNot(const LLSD& sdParam); class RlvEnableIfNot : public LLMemberListener { diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 853af1d82..71ed40b0a 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -881,7 +881,7 @@ bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const if ( (getCompositeInfo(idItem, &strComposite, &pFolder)) && (cstrItemType != strComposite) ) { LLUUID idCompositeItem; - if ((type = LLWearable::typeNameToType(strComposite)) != WT_INVALID) + if ((type = LLViewerWearable::typeNameToType(strComposite)) != WT_INVALID) { idCompositeItem = gAgent.getWearableItem(type); } @@ -931,7 +931,7 @@ bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const case LLAssetType::AT_BODYPART: case LLAssetType::AT_CLOTHING: { - LLWearable* pWearable = gAgent.getWearableFromWearableItem(pItem->getUUID()); + LLViewerWearable* pWearable = gAgent.getWearableFromWearableItem(pItem->getUUID()); if ( (pWearable) && (!isRemovable(pWearable->getType())) ) return false; // If one wearable in the folder is non-removeable then the entire folder should be } @@ -1054,14 +1054,6 @@ BOOL RlvHandler::setEnabled(BOOL fEnable) RlvUIEnabler::getInstance(); } - // RELEASE-RLVa: LL defines CLIENT_MENU_NAME but we can't get to it from here so we need to keep those two in sync manually - LLMenuGL* pClientMenu = NULL; - if ( (gMenuBarView) && ((pClientMenu = gMenuBarView->getChildMenuByName("Advanced", FALSE)) != NULL) ) - { - pClientMenu->setItemVisible("RLVa", m_fEnabled); - pClientMenu->setItemEnabled("RLVa", m_fEnabled); - } - return m_fEnabled; // Return enabled/disabled state } diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 455f7dfa3..936dd41db 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -472,7 +472,7 @@ void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAc } else { - const LLWearable* pWearable = gAgentWearables.getWearableFromItemID(pItem->getUUID()); + const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(pItem->getUUID()); if ( (pWearable) && (isForceRemovable(pWearable, false)) ) remWearable(pWearable); } @@ -612,7 +612,7 @@ void RlvForceWear::forceDetach(const LLViewerJointAttachment* pAttachPt) } // Checked: 2010-03-19 (RLVa-1.1.3b) | Modified: RLVa-1.2.0a -bool RlvForceWear::isForceRemovable(const LLWearable* pWearable, bool fCheckComposite /*=true*/, const LLUUID& idExcept /*=LLUUID::null*/) +bool RlvForceWear::isForceRemovable(const LLViewerWearable* pWearable, bool fCheckComposite /*=true*/, const LLUUID& idExcept /*=LLUUID::null*/) { // Wearable can be removed by an RLV command if: // - its asset type is AT_CLOTHING @@ -640,13 +640,13 @@ bool RlvForceWear::isForceRemovable(LLWearableType::EType wtType, bool fCheckCom { // Wearable type can be removed by an RLV command if there's at least one currently worn wearable that can be removed for (U32 idxWearable = 0, cntWearable = gAgentWearables.getWearableCount(wtType); idxWearable < cntWearable; idxWearable++) - if (isForceRemovable(gAgentWearables.getWearable(wtType, idxWearable), fCheckComposite, idExcept)) + if (isForceRemovable(gAgentWearables.getViewerWearable(wtType, idxWearable), fCheckComposite, idExcept)) return true; return false; } // Checked: 2010-03-19 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a -void RlvForceWear::forceRemove(const LLWearable* pWearable) +void RlvForceWear::forceRemove(const LLViewerWearable* pWearable) { // Sanity check - no need to process duplicate removes if ( (!pWearable) || (isRemWearable(pWearable)) ) @@ -675,7 +675,7 @@ void RlvForceWear::forceRemove(const LLWearable* pWearable) void RlvForceWear::forceRemove(LLWearableType::EType wtType) { for (U32 idxWearable = 0, cntWearable = gAgentWearables.getWearableCount(wtType); idxWearable < cntWearable; idxWearable++) - forceRemove(gAgentWearables.getWearable(wtType, idxWearable)); + forceRemove(gAgentWearables.getViewerWearable(wtType, idxWearable)); } // Checked: 2010-03-19 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a @@ -784,7 +784,7 @@ void RlvForceWear::remAttachment(const LLViewerObject* pAttachObj) // Checked: 2010-08-30 (RLVa-1.1.3b) | Modified: RLVa-1.2.1c void RlvForceWear::addWearable(const LLViewerInventoryItem* pItem, EWearAction eAction) { - const LLWearable* pWearable = gAgentWearables.getWearableFromItemID(pItem->getLinkedUUID()); + const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(pItem->getLinkedUUID()); // When replacing remove all currently worn wearables of this type *unless* the item is currently worn if ( (ACTION_WEAR_REPLACE == eAction) && (!pWearable) ) forceRemove(pItem->getWearableType()); @@ -812,7 +812,7 @@ void RlvForceWear::addWearable(const LLViewerInventoryItem* pItem, EWearAction e } // Checked: 2010-08-30 (RLVa-1.1.3b) | Modified: RLVa-1.2.1c -void RlvForceWear::remWearable(const LLWearable* pWearable) +void RlvForceWear::remWearable(const LLViewerWearable* pWearable) { // Remove it from 'm_addWearables' if it's queued for wearing const LLViewerInventoryItem* pItem = gInventory.getItem(pWearable->getItemID()); @@ -850,7 +850,7 @@ void RlvForceWear::done() // Wearables if (m_remWearables.size()) { - for (std::list::const_iterator itWearable = m_remWearables.begin(); itWearable != m_remWearables.end(); ++itWearable) + for (std::list::const_iterator itWearable = m_remWearables.begin(); itWearable != m_remWearables.end(); ++itWearable) pAppearanceMgr->removeItemFromAvatar((*itWearable)->getItemID()); m_remWearables.clear(); } @@ -883,7 +883,7 @@ void RlvForceWear::done() for (std::list::const_iterator itAttachObj = m_remAttachments.begin(); itAttachObj != m_remAttachments.end(); ++itAttachObj) { - pAppearanceMgr->removeCOFItemLinks((*itAttachObj)->getAttachmentItemID(), false); + pAppearanceMgr->removeCOFItemLinks((*itAttachObj)->getAttachmentItemID()); } m_remAttachments.clear(); diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 7ecb7b065..390f98edc 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -26,6 +26,8 @@ #include "rlvdefines.h" #include "rlvcommon.h" +class LLViewerWearable; + // ============================================================================ // RlvCommand // @@ -237,9 +239,9 @@ public: void forceDetach(const LLViewerJointAttachment* ptAttachPt); // Wearables - static bool isForceRemovable(const LLWearable* pWearable, bool fCheckComposite = true, const LLUUID& idExcept = LLUUID::null); + static bool isForceRemovable(const LLViewerWearable* pWearable, bool fCheckComposite = true, const LLUUID& idExcept = LLUUID::null); static bool isForceRemovable(LLWearableType::EType wtType, bool fCheckComposite = true, const LLUUID& idExcept = LLUUID::null); - void forceRemove(const LLWearable* pWearable); + void forceRemove(const LLViewerWearable* pWearable); void forceRemove(LLWearableType::EType wtType); public: @@ -248,7 +250,7 @@ protected: void addAttachment(const LLViewerInventoryItem* pItem, EWearAction eAction); void remAttachment(const LLViewerObject* pAttachObj); void addWearable(const LLViewerInventoryItem* pItem, EWearAction eAction); - void remWearable(const LLWearable* pWearable); + void remWearable(const LLViewerWearable* pWearable); // Convenience (prevents long lines that run off the screen elsewhere) bool isAddAttachment(const LLViewerInventoryItem* pItem) const @@ -277,7 +279,7 @@ protected: } return fFound; } - bool isRemWearable(const LLWearable* pWearable) const + bool isRemWearable(const LLViewerWearable* pWearable) const { return std::find(m_remWearables.begin(), m_remWearables.end(), pWearable) != m_remWearables.end(); } @@ -291,7 +293,7 @@ protected: addattachments_map_t m_addAttachments; LLInventoryModel::item_array_t m_addGestures; std::list m_remAttachments; - std::list m_remWearables; + std::list m_remWearables; LLInventoryModel::item_array_t m_remGestures; private: diff --git a/indra/newview/rlvlocks.cpp b/indra/newview/rlvlocks.cpp index 2fa4736db..268d27f98 100644 --- a/indra/newview/rlvlocks.cpp +++ b/indra/newview/rlvlocks.cpp @@ -936,7 +936,7 @@ bool RlvWearableLocks::canRemove(LLWearableType::EType eType) const { // NOTE: we return TRUE if the wearable type has at least one wearable that can be removed by the user for (U32 idxWearable = 0, cntWearable = gAgentWearables.getWearableCount(eType); idxWearable < cntWearable; idxWearable++) - if (!isLockedWearable(gAgentWearables.getWearable(eType, idxWearable))) + if (!isLockedWearable(gAgentWearables.getViewerWearable(eType, idxWearable))) return true; return false; } @@ -946,13 +946,13 @@ bool RlvWearableLocks::hasLockedWearable(LLWearableType::EType eType) const { // NOTE: we return TRUE if there is at least 1 non-removable wearable currently worn on this wearable type for (U32 idxWearable = 0, cntWearable = gAgentWearables.getWearableCount(eType); idxWearable < cntWearable; idxWearable++) - if (isLockedWearable(gAgentWearables.getWearable(eType, idxWearable))) + if (isLockedWearable(gAgentWearables.getViewerWearable(eType, idxWearable))) return true; return false; } // Checked: 2010-03-19 (RLVa-1.2.0a) | Added: RLVa-1.2.0a -bool RlvWearableLocks::isLockedWearableExcept(const LLWearable* pWearable, const LLUUID& idRlvObj) const +bool RlvWearableLocks::isLockedWearableExcept(const LLViewerWearable* pWearable, const LLUUID& idRlvObj) const { if (idRlvObj.isNull()) return isLockedWearable(pWearable); diff --git a/indra/newview/rlvlocks.h b/indra/newview/rlvlocks.h index ac207450d..6e185e322 100644 --- a/indra/newview/rlvlocks.h +++ b/indra/newview/rlvlocks.h @@ -21,6 +21,7 @@ #include "llagentwearables.h" #include "lleventtimer.h" #include "llvoavatarself.h" +#include "llviewerwearable.h" #include "rlvdefines.h" #include "rlvcommon.h" @@ -237,9 +238,9 @@ public: void removeWearableTypeLock(LLWearableType::EType eType, const LLUUID& idRlvObj, ERlvLockMask eLock); // Returns TRUE if the wearable is RLV_LOCK_REMOVE locked - bool isLockedWearable(const LLWearable* pWearable) const; + bool isLockedWearable(const LLViewerWearable* pWearable) const; // Returns TRUE if the wearable is RLV_LOCK_REMOVE locked by anything other than idRlvObj - bool isLockedWearableExcept(const LLWearable* pWearable, const LLUUID& idRlvObj) const; + bool isLockedWearableExcept(const LLViewerWearable* pWearable, const LLUUID& idRlvObj) const; // NOTE: isLockedWearableType doesn't check if a worn wearable is a specific wearable lock so don't let these be called by the outside protected: @@ -503,7 +504,7 @@ inline bool RlvWearableLocks::canRemove(const LLInventoryItem* pItem) const { // The specified item can be removed if its wearable can be removed RLV_ASSERT( (pItem) && (LLInventoryType::IT_WEARABLE == pItem->getInventoryType()) ); - const LLWearable* pWearable = (pItem) ? gAgentWearables.getWearableFromItemID(pItem->getLinkedUUID()) : NULL; + const LLViewerWearable* pWearable = (pItem) ? gAgentWearables.getWearableFromItemID(pItem->getLinkedUUID()) : NULL; return (pWearable) && (!isLockedWearable(pWearable)); } @@ -540,7 +541,7 @@ inline bool RlvWearableLocks::hasLockedWearableType(ERlvLockMask eLock) const } // Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.2.0a -inline bool RlvWearableLocks::isLockedWearable(const LLWearable* pWearable) const +inline bool RlvWearableLocks::isLockedWearable(const LLViewerWearable* pWearable) const { // Wearable is locked if: // - it's specifically marked as non-removable diff --git a/indra/newview/rlvui.cpp b/indra/newview/rlvui.cpp index 2f1d59091..e50c0c054 100644 --- a/indra/newview/rlvui.cpp +++ b/indra/newview/rlvui.cpp @@ -227,7 +227,7 @@ void RlvUIEnabler::onToggleShowLoc() // Close the "Estate Tools" floater is it's currently visible if (LLFloaterRegionInfo::instanceVisible()) LLFloaterRegionInfo::hideInstance(); - LLFloaterGodTools::hide(NULL); + LLFloaterGodTools::hide(); } } @@ -265,7 +265,7 @@ void RlvUIEnabler::onToggleShowNames(bool fQuitting) else { LLAvatarNameCache::setForceDisplayNames(false); - LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getS32("PhoenixNameSystem") != 0); + LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getS32("PhoenixNameSystem") == 1 || gSavedSettings.getS32("PhoenixNameSystem") == 2); } LLVOAvatar::invalidateNameTags(); // See handleDisplayNamesOptionChanged() } diff --git a/indra/newview/sgmemstat.cpp b/indra/newview/sgmemstat.cpp index d4e22a882..d8c4a3f5a 100644 --- a/indra/newview/sgmemstat.cpp +++ b/indra/newview/sgmemstat.cpp @@ -18,7 +18,7 @@ #include "llviewerprecompiledheaders.h" #include "sgmemstat.h" -#if (!LL_WINDOWS && !LL_LINUX) +#if (!(LL_LINUX || LL_USE_TCMALLOC)) bool SGMemStat::haveStat() { return false; } diff --git a/indra/newview/shfloatermediaticker.cpp b/indra/newview/shfloatermediaticker.cpp index a2c995153..c44b3fdb9 100644 --- a/indra/newview/shfloatermediaticker.cpp +++ b/indra/newview/shfloatermediaticker.cpp @@ -65,7 +65,6 @@ SHFloaterMediaTicker::SHFloaterMediaTicker() : LLFloater()/*, LLSingleton + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/Blackdark/textures/0098b015-3daf-4cfe-a72f-915369ea97c2.tga b/indra/newview/skins/Blackdark/textures/0098b015-3daf-4cfe-a72f-915369ea97c2.tga new file mode 100644 index 000000000..352bcdad2 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/0098b015-3daf-4cfe-a72f-915369ea97c2.tga differ diff --git a/indra/newview/skins/Blackdark/textures/3c18c87e-5f50-14e2-e744-f44734aa365f.tga b/indra/newview/skins/Blackdark/textures/3c18c87e-5f50-14e2-e744-f44734aa365f.tga new file mode 100644 index 000000000..e90ab295b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/3c18c87e-5f50-14e2-e744-f44734aa365f.tga differ diff --git a/indra/newview/skins/Blackdark/textures/5748decc-f629-461c-9a36-a35a221fe21f.tga b/indra/newview/skins/Blackdark/textures/5748decc-f629-461c-9a36-a35a221fe21f.tga new file mode 100644 index 000000000..55e379309 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/5748decc-f629-461c-9a36-a35a221fe21f.tga differ diff --git a/indra/newview/skins/Blackdark/textures/7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b.tga b/indra/newview/skins/Blackdark/textures/7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b.tga new file mode 100644 index 000000000..a79430cef Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b.tga differ diff --git a/indra/newview/skins/Blackdark/textures/7dabc040-ec13-2309-ddf7-4f161f6de2f4.tga b/indra/newview/skins/Blackdark/textures/7dabc040-ec13-2309-ddf7-4f161f6de2f4.tga new file mode 100644 index 000000000..534ecba91 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/7dabc040-ec13-2309-ddf7-4f161f6de2f4.tga differ diff --git a/indra/newview/skins/Blackdark/textures/89e9fc7c-0b16-457d-be4f-136270759c4d.tga b/indra/newview/skins/Blackdark/textures/89e9fc7c-0b16-457d-be4f-136270759c4d.tga new file mode 100644 index 000000000..6cc9ea194 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/89e9fc7c-0b16-457d-be4f-136270759c4d.tga differ diff --git a/indra/newview/skins/Blackdark/textures/9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1.tga b/indra/newview/skins/Blackdark/textures/9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1.tga new file mode 100644 index 000000000..e90ab295b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1.tga differ diff --git a/indra/newview/skins/Blackdark/textures/active_speakers.tga b/indra/newview/skins/Blackdark/textures/active_speakers.tga new file mode 100644 index 000000000..1e0eb5a32 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/active_speakers.tga differ diff --git a/indra/newview/skins/Blackdark/textures/active_voice_tab.tga b/indra/newview/skins/Blackdark/textures/active_voice_tab.tga new file mode 100644 index 000000000..c104ba289 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/active_voice_tab.tga differ diff --git a/indra/newview/skins/Blackdark/textures/arrow_down.tga b/indra/newview/skins/Blackdark/textures/arrow_down.tga new file mode 100644 index 000000000..89a793bcb Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/arrow_down.tga differ diff --git a/indra/newview/skins/Blackdark/textures/arrow_up.tga b/indra/newview/skins/Blackdark/textures/arrow_up.tga new file mode 100644 index 000000000..5b03c5433 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/arrow_up.tga differ diff --git a/indra/newview/skins/Blackdark/textures/b4870163-6208-42a9-9801-93133bf9a6cd.tga b/indra/newview/skins/Blackdark/textures/b4870163-6208-42a9-9801-93133bf9a6cd.tga new file mode 100644 index 000000000..35d979972 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/b4870163-6208-42a9-9801-93133bf9a6cd.tga differ diff --git a/indra/newview/skins/Blackdark/textures/badge_error.j2c b/indra/newview/skins/Blackdark/textures/badge_error.j2c new file mode 100644 index 000000000..efb5c375c Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/badge_error.j2c differ diff --git a/indra/newview/skins/Blackdark/textures/badge_note.j2c b/indra/newview/skins/Blackdark/textures/badge_note.j2c new file mode 100644 index 000000000..ef5db9e0d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/badge_note.j2c differ diff --git a/indra/newview/skins/Blackdark/textures/badge_ok.j2c b/indra/newview/skins/Blackdark/textures/badge_ok.j2c new file mode 100644 index 000000000..8ceee01c6 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/badge_ok.j2c differ diff --git a/indra/newview/skins/Blackdark/textures/badge_warn.j2c b/indra/newview/skins/Blackdark/textures/badge_warn.j2c new file mode 100644 index 000000000..8fb85be69 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/badge_warn.j2c differ diff --git a/indra/newview/skins/Blackdark/textures/black.tga b/indra/newview/skins/Blackdark/textures/black.tga new file mode 100644 index 000000000..e368ea496 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/black.tga differ diff --git a/indra/newview/skins/Blackdark/textures/btn_chatbar.tga b/indra/newview/skins/Blackdark/textures/btn_chatbar.tga new file mode 100644 index 000000000..07117925a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/btn_chatbar.tga differ diff --git a/indra/newview/skins/Blackdark/textures/btn_chatbar_selected.tga b/indra/newview/skins/Blackdark/textures/btn_chatbar_selected.tga new file mode 100644 index 000000000..a935ed396 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/btn_chatbar_selected.tga differ diff --git a/indra/newview/skins/Blackdark/textures/button_anim_pause.tga b/indra/newview/skins/Blackdark/textures/button_anim_pause.tga new file mode 100644 index 000000000..5a8f2f544 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/button_anim_pause.tga differ diff --git a/indra/newview/skins/Blackdark/textures/button_anim_pause_selected.tga b/indra/newview/skins/Blackdark/textures/button_anim_pause_selected.tga new file mode 100644 index 000000000..380e00416 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/button_anim_pause_selected.tga differ diff --git a/indra/newview/skins/Blackdark/textures/button_anim_play.tga b/indra/newview/skins/Blackdark/textures/button_anim_play.tga new file mode 100644 index 000000000..d7a7220d4 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/button_anim_play.tga differ diff --git a/indra/newview/skins/Blackdark/textures/button_anim_play_selected.tga b/indra/newview/skins/Blackdark/textures/button_anim_play_selected.tga new file mode 100644 index 000000000..778fbf062 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/button_anim_play_selected.tga differ diff --git a/indra/newview/skins/Blackdark/textures/button_anim_stop.tga b/indra/newview/skins/Blackdark/textures/button_anim_stop.tga new file mode 100644 index 000000000..f470fa927 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/button_anim_stop.tga differ diff --git a/indra/newview/skins/Blackdark/textures/button_anim_stop_selected.tga b/indra/newview/skins/Blackdark/textures/button_anim_stop_selected.tga new file mode 100644 index 000000000..e07ea176a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/button_anim_stop_selected.tga differ diff --git a/indra/newview/skins/Blackdark/textures/button_disabled_32x128.tga b/indra/newview/skins/Blackdark/textures/button_disabled_32x128.tga new file mode 100644 index 000000000..fd117209f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/button_disabled_32x128.tga differ diff --git a/indra/newview/skins/Blackdark/textures/button_enabled_32x128.tga b/indra/newview/skins/Blackdark/textures/button_enabled_32x128.tga new file mode 100644 index 000000000..fd117209f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/button_enabled_32x128.tga differ diff --git a/indra/newview/skins/Blackdark/textures/button_enabled_selected_32x128.tga b/indra/newview/skins/Blackdark/textures/button_enabled_selected_32x128.tga new file mode 100644 index 000000000..138b908b2 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/button_enabled_selected_32x128.tga differ diff --git a/indra/newview/skins/Blackdark/textures/c1e21504-f136-451d-b8e9-929037812f1d.tga b/indra/newview/skins/Blackdark/textures/c1e21504-f136-451d-b8e9-929037812f1d.tga new file mode 100644 index 000000000..53c8959a6 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/c1e21504-f136-451d-b8e9-929037812f1d.tga differ diff --git a/indra/newview/skins/Blackdark/textures/c63f124c-6340-4fbf-b59e-0869a44adb64.tga b/indra/newview/skins/Blackdark/textures/c63f124c-6340-4fbf-b59e-0869a44adb64.tga new file mode 100644 index 000000000..cbc02b4a4 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/c63f124c-6340-4fbf-b59e-0869a44adb64.tga differ diff --git a/indra/newview/skins/Blackdark/textures/cam_rotate_in.tga b/indra/newview/skins/Blackdark/textures/cam_rotate_in.tga new file mode 100644 index 000000000..84c647202 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/cam_rotate_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/cam_rotate_out.tga b/indra/newview/skins/Blackdark/textures/cam_rotate_out.tga new file mode 100644 index 000000000..2bcd371a7 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/cam_rotate_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/cam_tracking_in.tga b/indra/newview/skins/Blackdark/textures/cam_tracking_in.tga new file mode 100644 index 000000000..c23119944 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/cam_tracking_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/cam_tracking_out.tga b/indra/newview/skins/Blackdark/textures/cam_tracking_out.tga new file mode 100644 index 000000000..9cc25d21c Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/cam_tracking_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/cam_zoom_minus_in.tga b/indra/newview/skins/Blackdark/textures/cam_zoom_minus_in.tga new file mode 100644 index 000000000..29261e484 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/cam_zoom_minus_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/cam_zoom_out.tga b/indra/newview/skins/Blackdark/textures/cam_zoom_out.tga new file mode 100644 index 000000000..c0e771aab Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/cam_zoom_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/cam_zoom_plus_in.tga b/indra/newview/skins/Blackdark/textures/cam_zoom_plus_in.tga new file mode 100644 index 000000000..b342dde08 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/cam_zoom_plus_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/ce15fd63-b0b6-463c-a37d-ea6393208b3e.tga b/indra/newview/skins/Blackdark/textures/ce15fd63-b0b6-463c-a37d-ea6393208b3e.tga new file mode 100644 index 000000000..0717b393e Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/ce15fd63-b0b6-463c-a37d-ea6393208b3e.tga differ diff --git a/indra/newview/skins/Blackdark/textures/checkbox_disabled_false.tga b/indra/newview/skins/Blackdark/textures/checkbox_disabled_false.tga new file mode 100644 index 000000000..aa57cd211 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/checkbox_disabled_false.tga differ diff --git a/indra/newview/skins/Blackdark/textures/checkbox_disabled_true.tga b/indra/newview/skins/Blackdark/textures/checkbox_disabled_true.tga new file mode 100644 index 000000000..5dfee7d46 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/checkbox_disabled_true.tga differ diff --git a/indra/newview/skins/Blackdark/textures/checkbox_enabled_false.tga b/indra/newview/skins/Blackdark/textures/checkbox_enabled_false.tga new file mode 100644 index 000000000..fb8265b18 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/checkbox_enabled_false.tga differ diff --git a/indra/newview/skins/Blackdark/textures/checkbox_enabled_true.tga b/indra/newview/skins/Blackdark/textures/checkbox_enabled_true.tga new file mode 100644 index 000000000..8372e309b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/checkbox_enabled_true.tga differ diff --git a/indra/newview/skins/Blackdark/textures/circle.tga b/indra/newview/skins/Blackdark/textures/circle.tga new file mode 100644 index 000000000..d7097e3a3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/circle.tga differ diff --git a/indra/newview/skins/Blackdark/textures/close_in_blue.tga b/indra/newview/skins/Blackdark/textures/close_in_blue.tga new file mode 100644 index 000000000..c58e052b8 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/close_in_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/close_inactive.tga b/indra/newview/skins/Blackdark/textures/close_inactive.tga new file mode 100644 index 000000000..30f6e7b5f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/close_inactive.tga differ diff --git a/indra/newview/skins/Blackdark/textures/close_inactive_blue.tga b/indra/newview/skins/Blackdark/textures/close_inactive_blue.tga new file mode 100644 index 000000000..2f912df59 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/close_inactive_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/closebox.tga b/indra/newview/skins/Blackdark/textures/closebox.tga new file mode 100644 index 000000000..5e1195526 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/closebox.tga differ diff --git a/indra/newview/skins/Blackdark/textures/combobox_arrow.tga b/indra/newview/skins/Blackdark/textures/combobox_arrow.tga new file mode 100644 index 000000000..4bdcf6e14 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/combobox_arrow.tga differ diff --git a/indra/newview/skins/Blackdark/textures/d07f6eed-b96a-47cd-b51d-400ad4a1c428.j2c b/indra/newview/skins/Blackdark/textures/d07f6eed-b96a-47cd-b51d-400ad4a1c428.j2c new file mode 100644 index 000000000..4b73b25ac Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/d07f6eed-b96a-47cd-b51d-400ad4a1c428.j2c differ diff --git a/indra/newview/skins/Blackdark/textures/darkgray.tga b/indra/newview/skins/Blackdark/textures/darkgray.tga new file mode 100644 index 000000000..e69be0893 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/darkgray.tga differ diff --git a/indra/newview/skins/Blackdark/textures/default_land_picture.j2c b/indra/newview/skins/Blackdark/textures/default_land_picture.j2c new file mode 100644 index 000000000..6e2a85a46 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/default_land_picture.j2c differ diff --git a/indra/newview/skins/Blackdark/textures/default_profile_picture.j2c b/indra/newview/skins/Blackdark/textures/default_profile_picture.j2c new file mode 100644 index 000000000..31d741e88 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/default_profile_picture.j2c differ diff --git a/indra/newview/skins/Blackdark/textures/direction_arrow.tga b/indra/newview/skins/Blackdark/textures/direction_arrow.tga new file mode 100644 index 000000000..59149e1d5 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/direction_arrow.tga differ diff --git a/indra/newview/skins/Blackdark/textures/down_arrow.png b/indra/newview/skins/Blackdark/textures/down_arrow.png new file mode 100644 index 000000000..46bb251f5 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/down_arrow.png differ diff --git a/indra/newview/skins/Blackdark/textures/eye_button_active.tga b/indra/newview/skins/Blackdark/textures/eye_button_active.tga new file mode 100644 index 000000000..d4a9c2455 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/eye_button_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/eye_button_inactive.tga b/indra/newview/skins/Blackdark/textures/eye_button_inactive.tga new file mode 100644 index 000000000..edfdeba45 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/eye_button_inactive.tga differ diff --git a/indra/newview/skins/Blackdark/textures/ff9a71eb-7414-4cf8-866e-a701deb7c3cf.tga b/indra/newview/skins/Blackdark/textures/ff9a71eb-7414-4cf8-866e-a701deb7c3cf.tga new file mode 100644 index 000000000..534ecba91 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/ff9a71eb-7414-4cf8-866e-a701deb7c3cf.tga differ diff --git a/indra/newview/skins/Blackdark/textures/ff_edit_mine_button.tga b/indra/newview/skins/Blackdark/textures/ff_edit_mine_button.tga new file mode 100644 index 000000000..150354d99 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/ff_edit_mine_button.tga differ diff --git a/indra/newview/skins/Blackdark/textures/ff_edit_theirs_button.tga b/indra/newview/skins/Blackdark/textures/ff_edit_theirs_button.tga new file mode 100644 index 000000000..2a0efd61f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/ff_edit_theirs_button.tga differ diff --git a/indra/newview/skins/Blackdark/textures/ff_online_status_button.tga b/indra/newview/skins/Blackdark/textures/ff_online_status_button.tga new file mode 100644 index 000000000..058a66f26 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/ff_online_status_button.tga differ diff --git a/indra/newview/skins/Blackdark/textures/ff_visible_map_button.tga b/indra/newview/skins/Blackdark/textures/ff_visible_map_button.tga new file mode 100644 index 000000000..9053eed64 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/ff_visible_map_button.tga differ diff --git a/indra/newview/skins/Blackdark/textures/ff_visible_online_button.tga b/indra/newview/skins/Blackdark/textures/ff_visible_online_button.tga new file mode 100644 index 000000000..8d4d3a8d2 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/ff_visible_online_button.tga differ diff --git a/indra/newview/skins/Blackdark/textures/flyout_btn_left.tga b/indra/newview/skins/Blackdark/textures/flyout_btn_left.tga new file mode 100644 index 000000000..1ff9aea29 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/flyout_btn_left.tga differ diff --git a/indra/newview/skins/Blackdark/textures/flyout_btn_left_disabled.tga b/indra/newview/skins/Blackdark/textures/flyout_btn_left_disabled.tga new file mode 100644 index 000000000..1ff9aea29 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/flyout_btn_left_disabled.tga differ diff --git a/indra/newview/skins/Blackdark/textures/flyout_btn_left_selected.tga b/indra/newview/skins/Blackdark/textures/flyout_btn_left_selected.tga new file mode 100644 index 000000000..c0245c65d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/flyout_btn_left_selected.tga differ diff --git a/indra/newview/skins/Blackdark/textures/flyout_btn_right.tga b/indra/newview/skins/Blackdark/textures/flyout_btn_right.tga new file mode 100644 index 000000000..932e39abd Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/flyout_btn_right.tga differ diff --git a/indra/newview/skins/Blackdark/textures/flyout_btn_right_disabled.tga b/indra/newview/skins/Blackdark/textures/flyout_btn_right_disabled.tga new file mode 100644 index 000000000..932e39abd Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/flyout_btn_right_disabled.tga differ diff --git a/indra/newview/skins/Blackdark/textures/flyout_btn_right_selected.tga b/indra/newview/skins/Blackdark/textures/flyout_btn_right_selected.tga new file mode 100644 index 000000000..9a69d39d9 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/flyout_btn_right_selected.tga differ diff --git a/indra/newview/skins/Blackdark/textures/flyout_left.tga b/indra/newview/skins/Blackdark/textures/flyout_left.tga new file mode 100644 index 000000000..af599c019 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/flyout_left.tga differ diff --git a/indra/newview/skins/Blackdark/textures/flyout_left_disabled.tga b/indra/newview/skins/Blackdark/textures/flyout_left_disabled.tga new file mode 100644 index 000000000..af599c019 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/flyout_left_disabled.tga differ diff --git a/indra/newview/skins/Blackdark/textures/flyout_left_selected.tga b/indra/newview/skins/Blackdark/textures/flyout_left_selected.tga new file mode 100644 index 000000000..b55567d88 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/flyout_left_selected.tga differ diff --git a/indra/newview/skins/Blackdark/textures/folder_arrow.tga b/indra/newview/skins/Blackdark/textures/folder_arrow.tga new file mode 100644 index 000000000..734a00a84 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/folder_arrow.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_active-speakers-dot-lvl0.tga b/indra/newview/skins/Blackdark/textures/icn_active-speakers-dot-lvl0.tga new file mode 100644 index 000000000..35846cef3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_active-speakers-dot-lvl0.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_active-speakers-dot-lvl1.tga b/indra/newview/skins/Blackdark/textures/icn_active-speakers-dot-lvl1.tga new file mode 100644 index 000000000..1f9f564fa Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_active-speakers-dot-lvl1.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_active-speakers-dot-lvl2.tga b/indra/newview/skins/Blackdark/textures/icn_active-speakers-dot-lvl2.tga new file mode 100644 index 000000000..b2e5609f1 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_active-speakers-dot-lvl2.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_active-speakers-typing1.tga b/indra/newview/skins/Blackdark/textures/icn_active-speakers-typing1.tga new file mode 100644 index 000000000..3706c96e0 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_active-speakers-typing1.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_active-speakers-typing2.tga b/indra/newview/skins/Blackdark/textures/icn_active-speakers-typing2.tga new file mode 100644 index 000000000..0d127f946 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_active-speakers-typing2.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_active-speakers-typing3.tga b/indra/newview/skins/Blackdark/textures/icn_active-speakers-typing3.tga new file mode 100644 index 000000000..031b3ad34 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_active-speakers-typing3.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_chatbar.tga b/indra/newview/skins/Blackdark/textures/icn_chatbar.tga new file mode 100644 index 000000000..b89dfc432 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_chatbar.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_clear_lineeditor.tga b/indra/newview/skins/Blackdark/textures/icn_clear_lineeditor.tga new file mode 100644 index 000000000..8cd8310c6 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_clear_lineeditor.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_label_media.tga b/indra/newview/skins/Blackdark/textures/icn_label_media.tga new file mode 100644 index 000000000..b16c528e9 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_label_media.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_label_music.tga b/indra/newview/skins/Blackdark/textures/icn_label_music.tga new file mode 100644 index 000000000..515f170b6 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_label_music.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_label_web.tga b/indra/newview/skins/Blackdark/textures/icn_label_web.tga new file mode 100644 index 000000000..6cacfad7a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_label_web.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_media-pause_active.tga b/indra/newview/skins/Blackdark/textures/icn_media-pause_active.tga new file mode 100644 index 000000000..8988829aa Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_media-pause_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_media-pause_disabled.tga b/indra/newview/skins/Blackdark/textures/icn_media-pause_disabled.tga new file mode 100644 index 000000000..4690f4256 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_media-pause_disabled.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_media-pause_enabled.tga b/indra/newview/skins/Blackdark/textures/icn_media-pause_enabled.tga new file mode 100644 index 000000000..c01399e27 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_media-pause_enabled.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_media-play_enabled.tga b/indra/newview/skins/Blackdark/textures/icn_media-play_enabled.tga new file mode 100644 index 000000000..accac38b0 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_media-play_enabled.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_media-stop_enabled.tga b/indra/newview/skins/Blackdark/textures/icn_media-stop_enabled.tga new file mode 100644 index 000000000..d935fa317 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_media-stop_enabled.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_media.tga b/indra/newview/skins/Blackdark/textures/icn_media.tga new file mode 100644 index 000000000..2a035ba5d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_media.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_media_movie.tga b/indra/newview/skins/Blackdark/textures/icn_media_movie.tga new file mode 100644 index 000000000..b16c528e9 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_media_movie.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_media_web.tga b/indra/newview/skins/Blackdark/textures/icn_media_web.tga new file mode 100644 index 000000000..a92ae962b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_media_web.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_music.tga b/indra/newview/skins/Blackdark/textures/icn_music.tga new file mode 100644 index 000000000..81da5abcf Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_music.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_pause.tga b/indra/newview/skins/Blackdark/textures/icn_pause.tga new file mode 100644 index 000000000..3bc286f5f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_pause.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_play.tga b/indra/newview/skins/Blackdark/textures/icn_play.tga new file mode 100644 index 000000000..a23ef52e3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_play.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_rounded-text-field.tga b/indra/newview/skins/Blackdark/textures/icn_rounded-text-field.tga new file mode 100644 index 000000000..1f1e72572 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_rounded-text-field.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_scrollbar.tga b/indra/newview/skins/Blackdark/textures/icn_scrollbar.tga new file mode 100644 index 000000000..5b56da71a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_scrollbar.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_scrollbar_bg.tga b/indra/newview/skins/Blackdark/textures/icn_scrollbar_bg.tga new file mode 100644 index 000000000..5b56da71a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_scrollbar_bg.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_scrollbar_thumb.tga b/indra/newview/skins/Blackdark/textures/icn_scrollbar_thumb.tga new file mode 100644 index 000000000..5b56da71a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_scrollbar_thumb.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_slide-groove_dark.tga b/indra/newview/skins/Blackdark/textures/icn_slide-groove_dark.tga new file mode 100644 index 000000000..d893fada0 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_slide-groove_dark.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_slide-highlight.tga b/indra/newview/skins/Blackdark/textures/icn_slide-highlight.tga new file mode 100644 index 000000000..d371cd066 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_slide-highlight.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_slide-thumb_dark.tga b/indra/newview/skins/Blackdark/textures/icn_slide-thumb_dark.tga new file mode 100644 index 000000000..cf96786fd Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_slide-thumb_dark.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_speaker-muted_dark.tga b/indra/newview/skins/Blackdark/textures/icn_speaker-muted_dark.tga new file mode 100644 index 000000000..8f2c80dd2 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_speaker-muted_dark.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_speaker_dark.tga b/indra/newview/skins/Blackdark/textures/icn_speaker_dark.tga new file mode 100644 index 000000000..c2ee04044 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_speaker_dark.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_stop.tga b/indra/newview/skins/Blackdark/textures/icn_stop.tga new file mode 100644 index 000000000..2925b3853 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_stop.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_toolbar_build.tga b/indra/newview/skins/Blackdark/textures/icn_toolbar_build.tga new file mode 100644 index 000000000..c7cab6b38 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_toolbar_build.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_toolbar_fly.tga b/indra/newview/skins/Blackdark/textures/icn_toolbar_fly.tga new file mode 100644 index 000000000..c7cab6b38 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_toolbar_fly.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_toolbar_inventory.tga b/indra/newview/skins/Blackdark/textures/icn_toolbar_inventory.tga new file mode 100644 index 000000000..c7cab6b38 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_toolbar_inventory.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_toolbar_map.tga b/indra/newview/skins/Blackdark/textures/icn_toolbar_map.tga new file mode 100644 index 000000000..c7cab6b38 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_toolbar_map.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_toolbar_minimap.tga b/indra/newview/skins/Blackdark/textures/icn_toolbar_minimap.tga new file mode 100644 index 000000000..c7cab6b38 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_toolbar_minimap.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_toolbar_radar.tga b/indra/newview/skins/Blackdark/textures/icn_toolbar_radar.tga new file mode 100644 index 000000000..d1a55ed74 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_toolbar_radar.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_toolbar_search.tga b/indra/newview/skins/Blackdark/textures/icn_toolbar_search.tga new file mode 100644 index 000000000..c7cab6b38 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_toolbar_search.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_toolbar_snapshot.tga b/indra/newview/skins/Blackdark/textures/icn_toolbar_snapshot.tga new file mode 100644 index 000000000..c7cab6b38 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_toolbar_snapshot.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_voice-call-end.tga b/indra/newview/skins/Blackdark/textures/icn_voice-call-end.tga new file mode 100644 index 000000000..84056b90a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_voice-call-end.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_voice-call-start.tga b/indra/newview/skins/Blackdark/textures/icn_voice-call-start.tga new file mode 100644 index 000000000..7babfd318 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_voice-call-start.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_voice-groupfocus.tga b/indra/newview/skins/Blackdark/textures/icn_voice-groupfocus.tga new file mode 100644 index 000000000..913bd0969 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_voice-groupfocus.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_voice-localchat.tga b/indra/newview/skins/Blackdark/textures/icn_voice-localchat.tga new file mode 100644 index 000000000..5c1456602 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_voice-localchat.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_voice-pvtfocus.tga b/indra/newview/skins/Blackdark/textures/icn_voice-pvtfocus.tga new file mode 100644 index 000000000..76e72fd3a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_voice-pvtfocus.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_voice_ptt-off.tga b/indra/newview/skins/Blackdark/textures/icn_voice_ptt-off.tga new file mode 100644 index 000000000..530425dd7 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_voice_ptt-off.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on-lvl1.tga b/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on-lvl1.tga new file mode 100644 index 000000000..95cadd33d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on-lvl1.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on-lvl2.tga b/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on-lvl2.tga new file mode 100644 index 000000000..aeae781c5 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on-lvl2.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on-lvl3.tga b/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on-lvl3.tga new file mode 100644 index 000000000..081265efb Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on-lvl3.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on.tga b/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on.tga new file mode 100644 index 000000000..78f21cc59 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icn_voice_ptt-on.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_auction.tga b/indra/newview/skins/Blackdark/textures/icon_auction.tga new file mode 100644 index 000000000..3aa21d323 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_auction.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_avatar_offline.tga b/indra/newview/skins/Blackdark/textures/icon_avatar_offline.tga new file mode 100644 index 000000000..620e0f7c1 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_avatar_offline.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_avatar_online.tga b/indra/newview/skins/Blackdark/textures/icon_avatar_online.tga new file mode 100644 index 000000000..6350237ee Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_avatar_online.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_event.tga b/indra/newview/skins/Blackdark/textures/icon_event.tga new file mode 100644 index 000000000..23f246b91 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_event.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_event_adult.tga b/indra/newview/skins/Blackdark/textures/icon_event_adult.tga new file mode 100644 index 000000000..7202e6734 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_event_adult.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_event_mature.tga b/indra/newview/skins/Blackdark/textures/icon_event_mature.tga new file mode 100644 index 000000000..103c5e535 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_event_mature.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_for_sale.tga b/indra/newview/skins/Blackdark/textures/icon_for_sale.tga new file mode 100644 index 000000000..09405d383 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_for_sale.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_for_sale_adult.tga b/indra/newview/skins/Blackdark/textures/icon_for_sale_adult.tga new file mode 100644 index 000000000..147f724e7 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_for_sale_adult.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_group.tga b/indra/newview/skins/Blackdark/textures/icon_group.tga new file mode 100644 index 000000000..1e5c31aa3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_group.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_groupnotice.tga b/indra/newview/skins/Blackdark/textures/icon_groupnotice.tga new file mode 100644 index 000000000..b8cd107d3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_groupnotice.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_groupnoticeinventory.tga b/indra/newview/skins/Blackdark/textures/icon_groupnoticeinventory.tga new file mode 100644 index 000000000..9749e5779 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_groupnoticeinventory.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_lock.tga b/indra/newview/skins/Blackdark/textures/icon_lock.tga new file mode 100644 index 000000000..5de6cc10e Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_lock.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_place.tga b/indra/newview/skins/Blackdark/textures/icon_place.tga new file mode 100644 index 000000000..7f842ba65 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_place.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_popular.tga b/indra/newview/skins/Blackdark/textures/icon_popular.tga new file mode 100644 index 000000000..6bdc6ede3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_popular.tga differ diff --git a/indra/newview/skins/Blackdark/textures/icon_top_pick.tga b/indra/newview/skins/Blackdark/textures/icon_top_pick.tga new file mode 100644 index 000000000..4466e8be7 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/icon_top_pick.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_animation.tga b/indra/newview/skins/Blackdark/textures/inv_folder_animation.tga new file mode 100644 index 000000000..b7eae76e3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_animation.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_bodypart.tga b/indra/newview/skins/Blackdark/textures/inv_folder_bodypart.tga new file mode 100644 index 000000000..17658d7b0 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_bodypart.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_callingcard.tga b/indra/newview/skins/Blackdark/textures/inv_folder_callingcard.tga new file mode 100644 index 000000000..dd42c8c68 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_callingcard.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_clothing.tga b/indra/newview/skins/Blackdark/textures/inv_folder_clothing.tga new file mode 100644 index 000000000..bc4f71a5a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_clothing.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_gesture.tga b/indra/newview/skins/Blackdark/textures/inv_folder_gesture.tga new file mode 100644 index 000000000..f3a775c29 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_gesture.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_landmark.tga b/indra/newview/skins/Blackdark/textures/inv_folder_landmark.tga new file mode 100644 index 000000000..2b7ca30d6 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_landmark.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_lostandfound.tga b/indra/newview/skins/Blackdark/textures/inv_folder_lostandfound.tga new file mode 100644 index 000000000..dbef38773 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_lostandfound.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_notecard.tga b/indra/newview/skins/Blackdark/textures/inv_folder_notecard.tga new file mode 100644 index 000000000..675717e8d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_notecard.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_object.tga b/indra/newview/skins/Blackdark/textures/inv_folder_object.tga new file mode 100644 index 000000000..a477d020f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_object.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_plain_closed.tga b/indra/newview/skins/Blackdark/textures/inv_folder_plain_closed.tga new file mode 100644 index 000000000..824dd9569 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_plain_closed.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_plain_open.tga b/indra/newview/skins/Blackdark/textures/inv_folder_plain_open.tga new file mode 100644 index 000000000..c5f6ee59c Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_plain_open.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_script.tga b/indra/newview/skins/Blackdark/textures/inv_folder_script.tga new file mode 100644 index 000000000..919967843 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_script.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_snapshot.tga b/indra/newview/skins/Blackdark/textures/inv_folder_snapshot.tga new file mode 100644 index 000000000..8610eb5ae Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_snapshot.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_sound.tga b/indra/newview/skins/Blackdark/textures/inv_folder_sound.tga new file mode 100644 index 000000000..f9988a916 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_sound.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_texture.tga b/indra/newview/skins/Blackdark/textures/inv_folder_texture.tga new file mode 100644 index 000000000..924224ec1 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_texture.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_folder_trash.tga b/indra/newview/skins/Blackdark/textures/inv_folder_trash.tga new file mode 100644 index 000000000..7613d8cde Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_folder_trash.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_animation.tga b/indra/newview/skins/Blackdark/textures/inv_item_animation.tga new file mode 100644 index 000000000..527cef6d0 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_animation.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_attach.tga b/indra/newview/skins/Blackdark/textures/inv_item_attach.tga new file mode 100644 index 000000000..d5ed000d3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_attach.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_callingcard_offline.tga b/indra/newview/skins/Blackdark/textures/inv_item_callingcard_offline.tga new file mode 100644 index 000000000..e47b728ac Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_callingcard_offline.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_callingcard_online.tga b/indra/newview/skins/Blackdark/textures/inv_item_callingcard_online.tga new file mode 100644 index 000000000..e42058b76 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_callingcard_online.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_clothing.tga b/indra/newview/skins/Blackdark/textures/inv_item_clothing.tga new file mode 100644 index 000000000..10fa1b05a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_clothing.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_eyes.tga b/indra/newview/skins/Blackdark/textures/inv_item_eyes.tga new file mode 100644 index 000000000..4ddf340fa Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_eyes.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_gesture.tga b/indra/newview/skins/Blackdark/textures/inv_item_gesture.tga new file mode 100644 index 000000000..93b4194f6 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_gesture.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_gloves.tga b/indra/newview/skins/Blackdark/textures/inv_item_gloves.tga new file mode 100644 index 000000000..d09ae8d9d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_gloves.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_hair.tga b/indra/newview/skins/Blackdark/textures/inv_item_hair.tga new file mode 100644 index 000000000..98bb2e62f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_hair.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_jacket.tga b/indra/newview/skins/Blackdark/textures/inv_item_jacket.tga new file mode 100644 index 000000000..3056bbea3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_jacket.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_landmark.tga b/indra/newview/skins/Blackdark/textures/inv_item_landmark.tga new file mode 100644 index 000000000..aed756f7e Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_landmark.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_landmark_visited.tga b/indra/newview/skins/Blackdark/textures/inv_item_landmark_visited.tga new file mode 100644 index 000000000..6260fc544 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_landmark_visited.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_notecard.tga b/indra/newview/skins/Blackdark/textures/inv_item_notecard.tga new file mode 100644 index 000000000..ca3b77fdf Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_notecard.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_object.tga b/indra/newview/skins/Blackdark/textures/inv_item_object.tga new file mode 100644 index 000000000..447dc0f0b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_object.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_object_multi.tga b/indra/newview/skins/Blackdark/textures/inv_item_object_multi.tga new file mode 100644 index 000000000..85c0142f7 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_object_multi.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_pants.tga b/indra/newview/skins/Blackdark/textures/inv_item_pants.tga new file mode 100644 index 000000000..f2c55a7e0 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_pants.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_script.tga b/indra/newview/skins/Blackdark/textures/inv_item_script.tga new file mode 100644 index 000000000..310049e71 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_script.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_script_dangerous.tga b/indra/newview/skins/Blackdark/textures/inv_item_script_dangerous.tga new file mode 100644 index 000000000..2898a5f97 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_script_dangerous.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_shape.tga b/indra/newview/skins/Blackdark/textures/inv_item_shape.tga new file mode 100644 index 000000000..051a5cb3f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_shape.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_shirt.tga b/indra/newview/skins/Blackdark/textures/inv_item_shirt.tga new file mode 100644 index 000000000..10fa1b05a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_shirt.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_shoes.tga b/indra/newview/skins/Blackdark/textures/inv_item_shoes.tga new file mode 100644 index 000000000..4888cb8a6 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_shoes.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_skin.tga b/indra/newview/skins/Blackdark/textures/inv_item_skin.tga new file mode 100644 index 000000000..f9db6b04c Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_skin.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_skirt.tga b/indra/newview/skins/Blackdark/textures/inv_item_skirt.tga new file mode 100644 index 000000000..af9f20482 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_skirt.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_snapshot.tga b/indra/newview/skins/Blackdark/textures/inv_item_snapshot.tga new file mode 100644 index 000000000..97dea8760 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_snapshot.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_socks.tga b/indra/newview/skins/Blackdark/textures/inv_item_socks.tga new file mode 100644 index 000000000..57dbc1841 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_socks.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_sound.tga b/indra/newview/skins/Blackdark/textures/inv_item_sound.tga new file mode 100644 index 000000000..4f4e6b1ee Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_sound.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_texture.tga b/indra/newview/skins/Blackdark/textures/inv_item_texture.tga new file mode 100644 index 000000000..f67e02571 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_texture.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_underpants.tga b/indra/newview/skins/Blackdark/textures/inv_item_underpants.tga new file mode 100644 index 000000000..017a890cf Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_underpants.tga differ diff --git a/indra/newview/skins/Blackdark/textures/inv_item_undershirt.tga b/indra/newview/skins/Blackdark/textures/inv_item_undershirt.tga new file mode 100644 index 000000000..2eca04dbd Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/inv_item_undershirt.tga differ diff --git a/indra/newview/skins/Blackdark/textures/lightgray.tga b/indra/newview/skins/Blackdark/textures/lightgray.tga new file mode 100644 index 000000000..e69be0893 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/lightgray.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_avatar_16.tga b/indra/newview/skins/Blackdark/textures/map_avatar_16.tga new file mode 100644 index 000000000..42d8c1e29 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_avatar_16.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_avatar_8.tga b/indra/newview/skins/Blackdark/textures/map_avatar_8.tga new file mode 100644 index 000000000..7eb7c20f1 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_avatar_8.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_avatar_above_8.tga b/indra/newview/skins/Blackdark/textures/map_avatar_above_8.tga new file mode 100644 index 000000000..6faefccc7 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_avatar_above_8.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_avatar_below_8.tga b/indra/newview/skins/Blackdark/textures/map_avatar_below_8.tga new file mode 100644 index 000000000..5ad671c26 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_avatar_below_8.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_avatar_you_8.tga b/indra/newview/skins/Blackdark/textures/map_avatar_you_8.tga new file mode 100644 index 000000000..f10f96b10 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_avatar_you_8.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_event.tga b/indra/newview/skins/Blackdark/textures/map_event.tga new file mode 100644 index 000000000..103c5e535 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_event.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_event_adult.tga b/indra/newview/skins/Blackdark/textures/map_event_adult.tga new file mode 100644 index 000000000..7202e6734 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_event_adult.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_event_mature.tga b/indra/newview/skins/Blackdark/textures/map_event_mature.tga new file mode 100644 index 000000000..23f246b91 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_event_mature.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_home.tga b/indra/newview/skins/Blackdark/textures/map_home.tga new file mode 100644 index 000000000..85dde9ef7 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_home.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_infohub.tga b/indra/newview/skins/Blackdark/textures/map_infohub.tga new file mode 100644 index 000000000..173b93e39 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_infohub.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_telehub.tga b/indra/newview/skins/Blackdark/textures/map_telehub.tga new file mode 100644 index 000000000..d89bcfa40 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_telehub.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_track_16.tga b/indra/newview/skins/Blackdark/textures/map_track_16.tga new file mode 100644 index 000000000..14d49b93b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_track_16.tga differ diff --git a/indra/newview/skins/Blackdark/textures/map_track_8.tga b/indra/newview/skins/Blackdark/textures/map_track_8.tga new file mode 100644 index 000000000..d9605dde1 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/map_track_8.tga differ diff --git a/indra/newview/skins/Blackdark/textures/minimize.tga b/indra/newview/skins/Blackdark/textures/minimize.tga new file mode 100644 index 000000000..151a3078f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/minimize.tga differ diff --git a/indra/newview/skins/Blackdark/textures/minimize_inactive.tga b/indra/newview/skins/Blackdark/textures/minimize_inactive.tga new file mode 100644 index 000000000..d7e1b4057 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/minimize_inactive.tga differ diff --git a/indra/newview/skins/Blackdark/textures/minimize_pressed.tga b/indra/newview/skins/Blackdark/textures/minimize_pressed.tga new file mode 100644 index 000000000..573452ce9 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/minimize_pressed.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_backward_in.tga b/indra/newview/skins/Blackdark/textures/move_backward_in.tga new file mode 100644 index 000000000..56b605382 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_backward_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_backward_out.tga b/indra/newview/skins/Blackdark/textures/move_backward_out.tga new file mode 100644 index 000000000..b8064fd58 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_backward_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_down_in.tga b/indra/newview/skins/Blackdark/textures/move_down_in.tga new file mode 100644 index 000000000..eec8f5764 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_down_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_down_out.tga b/indra/newview/skins/Blackdark/textures/move_down_out.tga new file mode 100644 index 000000000..47993a89e Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_down_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_forward_in.tga b/indra/newview/skins/Blackdark/textures/move_forward_in.tga new file mode 100644 index 000000000..3a9644124 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_forward_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_forward_out.tga b/indra/newview/skins/Blackdark/textures/move_forward_out.tga new file mode 100644 index 000000000..f0f72d1d6 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_forward_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_left_in.tga b/indra/newview/skins/Blackdark/textures/move_left_in.tga new file mode 100644 index 000000000..5c0e910a7 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_left_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_left_out.tga b/indra/newview/skins/Blackdark/textures/move_left_out.tga new file mode 100644 index 000000000..68947f297 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_left_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_right_in.tga b/indra/newview/skins/Blackdark/textures/move_right_in.tga new file mode 100644 index 000000000..086e24bfd Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_right_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_right_out.tga b/indra/newview/skins/Blackdark/textures/move_right_out.tga new file mode 100644 index 000000000..b242201ca Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_right_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_turn_left_in.tga b/indra/newview/skins/Blackdark/textures/move_turn_left_in.tga new file mode 100644 index 000000000..6aad5b2c6 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_turn_left_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_turn_left_out.tga b/indra/newview/skins/Blackdark/textures/move_turn_left_out.tga new file mode 100644 index 000000000..c6e3c4f8f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_turn_left_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_turn_right_in.tga b/indra/newview/skins/Blackdark/textures/move_turn_right_in.tga new file mode 100644 index 000000000..f8b56235b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_turn_right_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_turn_right_out.tga b/indra/newview/skins/Blackdark/textures/move_turn_right_out.tga new file mode 100644 index 000000000..f20a6cfac Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_turn_right_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_up_in.tga b/indra/newview/skins/Blackdark/textures/move_up_in.tga new file mode 100644 index 000000000..9d2da6942 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_up_in.tga differ diff --git a/indra/newview/skins/Blackdark/textures/move_up_out.tga b/indra/newview/skins/Blackdark/textures/move_up_out.tga new file mode 100644 index 000000000..8caed0655 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/move_up_out.tga differ diff --git a/indra/newview/skins/Blackdark/textures/mute_icon.tga b/indra/newview/skins/Blackdark/textures/mute_icon.tga new file mode 100644 index 000000000..879b9e618 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/mute_icon.tga differ diff --git a/indra/newview/skins/Blackdark/textures/notify_box_icon.tga b/indra/newview/skins/Blackdark/textures/notify_box_icon.tga new file mode 100644 index 000000000..880aca9b4 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/notify_box_icon.tga differ diff --git a/indra/newview/skins/Blackdark/textures/notify_caution_icon.tga b/indra/newview/skins/Blackdark/textures/notify_caution_icon.tga new file mode 100644 index 000000000..ac6660c16 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/notify_caution_icon.tga differ diff --git a/indra/newview/skins/Blackdark/textures/notify_next.png b/indra/newview/skins/Blackdark/textures/notify_next.png new file mode 100644 index 000000000..9b371e03e Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/notify_next.png differ diff --git a/indra/newview/skins/Blackdark/textures/notify_tip_icon.tga b/indra/newview/skins/Blackdark/textures/notify_tip_icon.tga new file mode 100644 index 000000000..0451da099 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/notify_tip_icon.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_cone.tga b/indra/newview/skins/Blackdark/textures/object_cone.tga new file mode 100644 index 000000000..13f0ef4c3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_cone.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_cone_active.tga b/indra/newview/skins/Blackdark/textures/object_cone_active.tga new file mode 100644 index 000000000..6d537ffc0 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_cone_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_cube.tga b/indra/newview/skins/Blackdark/textures/object_cube.tga new file mode 100644 index 000000000..4ff84f30a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_cube.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_cube_active.tga b/indra/newview/skins/Blackdark/textures/object_cube_active.tga new file mode 100644 index 000000000..69baee736 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_cube_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_cylinder.tga b/indra/newview/skins/Blackdark/textures/object_cylinder.tga new file mode 100644 index 000000000..bf379550b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_cylinder.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_cylinder_active.tga b/indra/newview/skins/Blackdark/textures/object_cylinder_active.tga new file mode 100644 index 000000000..fdf9edc10 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_cylinder_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_grass.tga b/indra/newview/skins/Blackdark/textures/object_grass.tga new file mode 100644 index 000000000..4ab3ee64d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_grass.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_grass_active.tga b/indra/newview/skins/Blackdark/textures/object_grass_active.tga new file mode 100644 index 000000000..4457a81b8 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_grass_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_hemi_cone.tga b/indra/newview/skins/Blackdark/textures/object_hemi_cone.tga new file mode 100644 index 000000000..89b17d3dc Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_hemi_cone.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_hemi_cone_active.tga b/indra/newview/skins/Blackdark/textures/object_hemi_cone_active.tga new file mode 100644 index 000000000..1cffd21f3 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_hemi_cone_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_hemi_cylinder.tga b/indra/newview/skins/Blackdark/textures/object_hemi_cylinder.tga new file mode 100644 index 000000000..933c42f52 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_hemi_cylinder.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_hemi_cylinder_active.tga b/indra/newview/skins/Blackdark/textures/object_hemi_cylinder_active.tga new file mode 100644 index 000000000..18ee8cf14 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_hemi_cylinder_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_hemi_sphere.tga b/indra/newview/skins/Blackdark/textures/object_hemi_sphere.tga new file mode 100644 index 000000000..7293b45a7 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_hemi_sphere.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_hemi_sphere_active.tga b/indra/newview/skins/Blackdark/textures/object_hemi_sphere_active.tga new file mode 100644 index 000000000..5fe5bbf3c Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_hemi_sphere_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_prism.tga b/indra/newview/skins/Blackdark/textures/object_prism.tga new file mode 100644 index 000000000..f1fccda62 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_prism.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_prism_active.tga b/indra/newview/skins/Blackdark/textures/object_prism_active.tga new file mode 100644 index 000000000..30f16efb1 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_prism_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_pyramid.tga b/indra/newview/skins/Blackdark/textures/object_pyramid.tga new file mode 100644 index 000000000..f4d1d46e1 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_pyramid.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_pyramid_active.tga b/indra/newview/skins/Blackdark/textures/object_pyramid_active.tga new file mode 100644 index 000000000..9b2e5ceab Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_pyramid_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_ring.tga b/indra/newview/skins/Blackdark/textures/object_ring.tga new file mode 100644 index 000000000..aaf5783f5 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_ring.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_ring_active.tga b/indra/newview/skins/Blackdark/textures/object_ring_active.tga new file mode 100644 index 000000000..2e133b3bf Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_ring_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_sphere.tga b/indra/newview/skins/Blackdark/textures/object_sphere.tga new file mode 100644 index 000000000..5875478ba Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_sphere.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_sphere_active.tga b/indra/newview/skins/Blackdark/textures/object_sphere_active.tga new file mode 100644 index 000000000..0abbb0247 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_sphere_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_tetrahedron.tga b/indra/newview/skins/Blackdark/textures/object_tetrahedron.tga new file mode 100644 index 000000000..808456f85 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_tetrahedron.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_tetrahedron_active.tga b/indra/newview/skins/Blackdark/textures/object_tetrahedron_active.tga new file mode 100644 index 000000000..3eedb5b92 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_tetrahedron_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_torus.tga b/indra/newview/skins/Blackdark/textures/object_torus.tga new file mode 100644 index 000000000..3ef02f88d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_torus.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_torus_active.tga b/indra/newview/skins/Blackdark/textures/object_torus_active.tga new file mode 100644 index 000000000..df5120ae4 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_torus_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_tree.tga b/indra/newview/skins/Blackdark/textures/object_tree.tga new file mode 100644 index 000000000..b4df5cd6c Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_tree.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_tree_active.tga b/indra/newview/skins/Blackdark/textures/object_tree_active.tga new file mode 100644 index 000000000..38099b213 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_tree_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_tube.tga b/indra/newview/skins/Blackdark/textures/object_tube.tga new file mode 100644 index 000000000..c89c56846 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_tube.tga differ diff --git a/indra/newview/skins/Blackdark/textures/object_tube_active.tga b/indra/newview/skins/Blackdark/textures/object_tube_active.tga new file mode 100644 index 000000000..1ba9ebc70 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/object_tube_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/preview.png b/indra/newview/skins/Blackdark/textures/preview.png new file mode 100644 index 000000000..2022d7c88 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/preview.png differ diff --git a/indra/newview/skins/Blackdark/textures/progress_fill.tga b/indra/newview/skins/Blackdark/textures/progress_fill.tga new file mode 100644 index 000000000..bbdf5dd0b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/progress_fill.tga differ diff --git a/indra/newview/skins/Blackdark/textures/progressbar_fill.tga b/indra/newview/skins/Blackdark/textures/progressbar_fill.tga new file mode 100644 index 000000000..144c18790 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/progressbar_fill.tga differ diff --git a/indra/newview/skins/Blackdark/textures/progressbar_track.tga b/indra/newview/skins/Blackdark/textures/progressbar_track.tga new file mode 100644 index 000000000..4b84e9ec9 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/progressbar_track.tga differ diff --git a/indra/newview/skins/Blackdark/textures/ptt_lock_off.tga b/indra/newview/skins/Blackdark/textures/ptt_lock_off.tga new file mode 100644 index 000000000..d66f49840 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/ptt_lock_off.tga differ diff --git a/indra/newview/skins/Blackdark/textures/ptt_lock_on.tga b/indra/newview/skins/Blackdark/textures/ptt_lock_on.tga new file mode 100644 index 000000000..432db2f00 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/ptt_lock_on.tga differ diff --git a/indra/newview/skins/Blackdark/textures/radio_active_false.tga b/indra/newview/skins/Blackdark/textures/radio_active_false.tga new file mode 100644 index 000000000..6a83f31fe Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/radio_active_false.tga differ diff --git a/indra/newview/skins/Blackdark/textures/radio_active_true.tga b/indra/newview/skins/Blackdark/textures/radio_active_true.tga new file mode 100644 index 000000000..feac2ee2b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/radio_active_true.tga differ diff --git a/indra/newview/skins/Blackdark/textures/radio_inactive_false.tga b/indra/newview/skins/Blackdark/textures/radio_inactive_false.tga new file mode 100644 index 000000000..950f09c39 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/radio_inactive_false.tga differ diff --git a/indra/newview/skins/Blackdark/textures/radio_inactive_true.tga b/indra/newview/skins/Blackdark/textures/radio_inactive_true.tga new file mode 100644 index 000000000..8e57118ae Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/radio_inactive_true.tga differ diff --git a/indra/newview/skins/Blackdark/textures/resize_handle_bottom_right_blue.tga b/indra/newview/skins/Blackdark/textures/resize_handle_bottom_right_blue.tga new file mode 100644 index 000000000..8290bfa65 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/resize_handle_bottom_right_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/restore.tga b/indra/newview/skins/Blackdark/textures/restore.tga new file mode 100644 index 000000000..5e369fdfc Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/restore.tga differ diff --git a/indra/newview/skins/Blackdark/textures/restore_inactive.tga b/indra/newview/skins/Blackdark/textures/restore_inactive.tga new file mode 100644 index 000000000..ce545d90d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/restore_inactive.tga differ diff --git a/indra/newview/skins/Blackdark/textures/restore_pressed.tga b/indra/newview/skins/Blackdark/textures/restore_pressed.tga new file mode 100644 index 000000000..8a25087be Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/restore_pressed.tga differ diff --git a/indra/newview/skins/Blackdark/textures/rounded_square.j2c b/indra/newview/skins/Blackdark/textures/rounded_square.j2c new file mode 100644 index 000000000..c3dfe8f10 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/rounded_square.j2c differ diff --git a/indra/newview/skins/Blackdark/textures/rounded_square.tga b/indra/newview/skins/Blackdark/textures/rounded_square.tga new file mode 100644 index 000000000..4f4bf05f8 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/rounded_square.tga differ diff --git a/indra/newview/skins/Blackdark/textures/rounded_square_soft.tga b/indra/newview/skins/Blackdark/textures/rounded_square_soft.tga new file mode 100644 index 000000000..4f4bf05f8 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/rounded_square_soft.tga differ diff --git a/indra/newview/skins/Blackdark/textures/script_error.j2c b/indra/newview/skins/Blackdark/textures/script_error.j2c new file mode 100644 index 000000000..ad6be04a7 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/script_error.j2c differ diff --git a/indra/newview/skins/Blackdark/textures/script_error.tga b/indra/newview/skins/Blackdark/textures/script_error.tga new file mode 100644 index 000000000..8fa12e711 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/script_error.tga differ diff --git a/indra/newview/skins/Blackdark/textures/scrollbutton_down_in_blue.tga b/indra/newview/skins/Blackdark/textures/scrollbutton_down_in_blue.tga new file mode 100644 index 000000000..4bdcf6e14 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/scrollbutton_down_in_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/scrollbutton_down_out_blue.tga b/indra/newview/skins/Blackdark/textures/scrollbutton_down_out_blue.tga new file mode 100644 index 000000000..4bdcf6e14 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/scrollbutton_down_out_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/scrollbutton_left_in_blue.tga b/indra/newview/skins/Blackdark/textures/scrollbutton_left_in_blue.tga new file mode 100644 index 000000000..e90ab295b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/scrollbutton_left_in_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/scrollbutton_left_out_blue.tga b/indra/newview/skins/Blackdark/textures/scrollbutton_left_out_blue.tga new file mode 100644 index 000000000..e90ab295b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/scrollbutton_left_out_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/scrollbutton_right_in_blue.tga b/indra/newview/skins/Blackdark/textures/scrollbutton_right_in_blue.tga new file mode 100644 index 000000000..534ecba91 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/scrollbutton_right_in_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/scrollbutton_right_out_blue.tga b/indra/newview/skins/Blackdark/textures/scrollbutton_right_out_blue.tga new file mode 100644 index 000000000..534ecba91 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/scrollbutton_right_out_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/scrollbutton_up_in_blue.tga b/indra/newview/skins/Blackdark/textures/scrollbutton_up_in_blue.tga new file mode 100644 index 000000000..2e2f58339 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/scrollbutton_up_in_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/scrollbutton_up_out_blue.tga b/indra/newview/skins/Blackdark/textures/scrollbutton_up_out_blue.tga new file mode 100644 index 000000000..2e2f58339 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/scrollbutton_up_out_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/sm_rounded_corners_simple.tga b/indra/newview/skins/Blackdark/textures/sm_rounded_corners_simple.tga new file mode 100644 index 000000000..054fdd39a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/sm_rounded_corners_simple.tga differ diff --git a/indra/newview/skins/Blackdark/textures/spacer24.tga b/indra/newview/skins/Blackdark/textures/spacer24.tga new file mode 100644 index 000000000..c7cab6b38 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/spacer24.tga differ diff --git a/indra/newview/skins/Blackdark/textures/spacer35.tga b/indra/newview/skins/Blackdark/textures/spacer35.tga new file mode 100644 index 000000000..b88bc6680 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/spacer35.tga differ diff --git a/indra/newview/skins/Blackdark/textures/spin_down_in_blue.tga b/indra/newview/skins/Blackdark/textures/spin_down_in_blue.tga new file mode 100644 index 000000000..bcbf526f1 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/spin_down_in_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/spin_down_out_blue.tga b/indra/newview/skins/Blackdark/textures/spin_down_out_blue.tga new file mode 100644 index 000000000..1af2ed9cb Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/spin_down_out_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/spin_up_in_blue.tga b/indra/newview/skins/Blackdark/textures/spin_up_in_blue.tga new file mode 100644 index 000000000..6bf3c1306 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/spin_up_in_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/spin_up_out_blue.tga b/indra/newview/skins/Blackdark/textures/spin_up_out_blue.tga new file mode 100644 index 000000000..9a9bc6468 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/spin_up_out_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/square_btn_32x128.tga b/indra/newview/skins/Blackdark/textures/square_btn_32x128.tga new file mode 100644 index 000000000..d23d413aa Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/square_btn_32x128.tga differ diff --git a/indra/newview/skins/Blackdark/textures/square_btn_selected_32x128.tga b/indra/newview/skins/Blackdark/textures/square_btn_selected_32x128.tga new file mode 100644 index 000000000..2f48098d2 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/square_btn_selected_32x128.tga differ diff --git a/indra/newview/skins/Blackdark/textures/startup_logo.j2c b/indra/newview/skins/Blackdark/textures/startup_logo.j2c new file mode 100644 index 000000000..ab28cf37d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/startup_logo.j2c differ diff --git a/indra/newview/skins/Blackdark/textures/status_buy_currency.tga b/indra/newview/skins/Blackdark/textures/status_buy_currency.tga new file mode 100644 index 000000000..f4a28b32b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_buy_currency.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_buy_currency_pressed.tga b/indra/newview/skins/Blackdark/textures/status_buy_currency_pressed.tga new file mode 100644 index 000000000..f4a28b32b Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_buy_currency_pressed.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_buy_land.tga b/indra/newview/skins/Blackdark/textures/status_buy_land.tga new file mode 100644 index 000000000..60c395c03 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_buy_land.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_buy_land_pressed.tga b/indra/newview/skins/Blackdark/textures/status_buy_land_pressed.tga new file mode 100644 index 000000000..60c395c03 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_buy_land_pressed.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_health.tga b/indra/newview/skins/Blackdark/textures/status_health.tga new file mode 100644 index 000000000..f5eefc5a9 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_health.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_no_build.tga b/indra/newview/skins/Blackdark/textures/status_no_build.tga new file mode 100644 index 000000000..41934a600 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_no_build.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_no_fly.tga b/indra/newview/skins/Blackdark/textures/status_no_fly.tga new file mode 100644 index 000000000..0aa7fa71d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_no_fly.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_no_push.tga b/indra/newview/skins/Blackdark/textures/status_no_push.tga new file mode 100644 index 000000000..6d5987217 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_no_push.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_no_scripts.tga b/indra/newview/skins/Blackdark/textures/status_no_scripts.tga new file mode 100644 index 000000000..3bce6ad6f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_no_scripts.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_no_voice.tga b/indra/newview/skins/Blackdark/textures/status_no_voice.tga new file mode 100644 index 000000000..aeeed6ed0 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_no_voice.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_script_debug.tga b/indra/newview/skins/Blackdark/textures/status_script_debug.tga new file mode 100644 index 000000000..7d895eb0a Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_script_debug.tga differ diff --git a/indra/newview/skins/Blackdark/textures/status_search_btn.png b/indra/newview/skins/Blackdark/textures/status_search_btn.png new file mode 100644 index 000000000..b755f6f10 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_search_btn.png differ diff --git a/indra/newview/skins/Blackdark/textures/status_search_btn_pressed.png b/indra/newview/skins/Blackdark/textures/status_search_btn_pressed.png new file mode 100644 index 000000000..c19945885 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_search_btn_pressed.png differ diff --git a/indra/newview/skins/Blackdark/textures/status_voice.tga b/indra/newview/skins/Blackdark/textures/status_voice.tga new file mode 100644 index 000000000..aeeed6ed0 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/status_voice.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tab_bottom_blue.tga b/indra/newview/skins/Blackdark/textures/tab_bottom_blue.tga new file mode 100644 index 000000000..e6de7a5a1 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tab_bottom_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tab_bottom_selected_blue.tga b/indra/newview/skins/Blackdark/textures/tab_bottom_selected_blue.tga new file mode 100644 index 000000000..b7f6db9b8 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tab_bottom_selected_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tab_left.tga b/indra/newview/skins/Blackdark/textures/tab_left.tga new file mode 100644 index 000000000..4348b19ce Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tab_left.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tab_left_selected.tga b/indra/newview/skins/Blackdark/textures/tab_left_selected.tga new file mode 100644 index 000000000..63932fc15 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tab_left_selected.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tab_top_blue.tga b/indra/newview/skins/Blackdark/textures/tab_top_blue.tga new file mode 100644 index 000000000..ddcd519f2 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tab_top_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tab_top_selected_blue.tga b/indra/newview/skins/Blackdark/textures/tab_top_selected_blue.tga new file mode 100644 index 000000000..3b7df6e46 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tab_top_selected_blue.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tabarea.tga b/indra/newview/skins/Blackdark/textures/tabarea.tga new file mode 100644 index 000000000..5517aebfc Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tabarea.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tearoff_pressed.tga b/indra/newview/skins/Blackdark/textures/tearoff_pressed.tga new file mode 100644 index 000000000..8581ab701 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tearoff_pressed.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tearoffbox.tga b/indra/newview/skins/Blackdark/textures/tearoffbox.tga new file mode 100644 index 000000000..27af31c4d Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tearoffbox.tga differ diff --git a/indra/newview/skins/Blackdark/textures/textures.xml b/indra/newview/skins/Blackdark/textures/textures.xml new file mode 100644 index 000000000..5955a8ede --- /dev/null +++ b/indra/newview/skins/Blackdark/textures/textures.xml @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/Blackdark/textures/tool_dozer.tga b/indra/newview/skins/Blackdark/textures/tool_dozer.tga new file mode 100644 index 000000000..e4b05a581 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tool_dozer.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tool_dozer_active.tga b/indra/newview/skins/Blackdark/textures/tool_dozer_active.tga new file mode 100644 index 000000000..d76f7d5d1 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tool_dozer_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tool_zoom.tga b/indra/newview/skins/Blackdark/textures/tool_zoom.tga new file mode 100644 index 000000000..72fe14195 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tool_zoom.tga differ diff --git a/indra/newview/skins/Blackdark/textures/tool_zoom_active.tga b/indra/newview/skins/Blackdark/textures/tool_zoom_active.tga new file mode 100644 index 000000000..9579aef2e Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/tool_zoom_active.tga differ diff --git a/indra/newview/skins/Blackdark/textures/toolbar_bg.tga b/indra/newview/skins/Blackdark/textures/toolbar_bg.tga new file mode 100644 index 000000000..dbea376a4 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/toolbar_bg.tga differ diff --git a/indra/newview/skins/Blackdark/textures/toolbar_btn_disabled.tga b/indra/newview/skins/Blackdark/textures/toolbar_btn_disabled.tga new file mode 100644 index 000000000..fd117209f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/toolbar_btn_disabled.tga differ diff --git a/indra/newview/skins/Blackdark/textures/toolbar_btn_enabled.tga b/indra/newview/skins/Blackdark/textures/toolbar_btn_enabled.tga new file mode 100644 index 000000000..fd117209f Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/toolbar_btn_enabled.tga differ diff --git a/indra/newview/skins/Blackdark/textures/toolbar_btn_selected.tga b/indra/newview/skins/Blackdark/textures/toolbar_btn_selected.tga new file mode 100644 index 000000000..86dc40f09 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/toolbar_btn_selected.tga differ diff --git a/indra/newview/skins/Blackdark/textures/toolbar_tab.tga b/indra/newview/skins/Blackdark/textures/toolbar_tab.tga new file mode 100644 index 000000000..610d2f335 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/toolbar_tab.tga differ diff --git a/indra/newview/skins/Blackdark/textures/up_arrow.png b/indra/newview/skins/Blackdark/textures/up_arrow.png new file mode 100644 index 000000000..5c60a61db Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/up_arrow.png differ diff --git a/indra/newview/skins/Blackdark/textures/white.tga b/indra/newview/skins/Blackdark/textures/white.tga new file mode 100644 index 000000000..55e379309 Binary files /dev/null and b/indra/newview/skins/Blackdark/textures/white.tga differ diff --git a/indra/newview/skins/Blacklightblue/License and Credit.txt b/indra/newview/skins/Blacklightblue/License and Credit.txt new file mode 100644 index 000000000..8e57c5ba0 --- /dev/null +++ b/indra/newview/skins/Blacklightblue/License and Credit.txt @@ -0,0 +1,4 @@ +This skin was modified by JB Kraft from the default linden skin provided. +This skin was modified by Chalice Yao from the default linden skin and JB Kraft's skin. + +All Images and modifications done are provided free to use, modify, and distribute, so long as this infomation is distributed with it. diff --git a/indra/newview/skins/Blacklightblue/colors.xml b/indra/newview/skins/Blacklightblue/colors.xml new file mode 100644 index 000000000..ac4ad8772 --- /dev/null +++ b/indra/newview/skins/Blacklightblue/colors.xml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/Blacklightblue/textures/0098b015-3daf-4cfe-a72f-915369ea97c2.tga b/indra/newview/skins/Blacklightblue/textures/0098b015-3daf-4cfe-a72f-915369ea97c2.tga new file mode 100644 index 000000000..a60bd521f Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/0098b015-3daf-4cfe-a72f-915369ea97c2.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/3c18c87e-5f50-14e2-e744-f44734aa365f.tga b/indra/newview/skins/Blacklightblue/textures/3c18c87e-5f50-14e2-e744-f44734aa365f.tga new file mode 100644 index 000000000..e90ab295b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/3c18c87e-5f50-14e2-e744-f44734aa365f.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b.tga b/indra/newview/skins/Blacklightblue/textures/7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b.tga new file mode 100644 index 000000000..b776b11d0 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/7dabc040-ec13-2309-ddf7-4f161f6de2f4.tga b/indra/newview/skins/Blacklightblue/textures/7dabc040-ec13-2309-ddf7-4f161f6de2f4.tga new file mode 100644 index 000000000..534ecba91 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/7dabc040-ec13-2309-ddf7-4f161f6de2f4.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1.tga b/indra/newview/skins/Blacklightblue/textures/9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1.tga new file mode 100644 index 000000000..e90ab295b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/active_speakers.tga b/indra/newview/skins/Blacklightblue/textures/active_speakers.tga new file mode 100644 index 000000000..ec097fcd4 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/active_speakers.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/active_voice_tab.tga b/indra/newview/skins/Blacklightblue/textures/active_voice_tab.tga new file mode 100644 index 000000000..3037e9668 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/active_voice_tab.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/arrow_down.tga b/indra/newview/skins/Blacklightblue/textures/arrow_down.tga new file mode 100644 index 000000000..89a793bcb Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/arrow_down.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/arrow_up.tga b/indra/newview/skins/Blacklightblue/textures/arrow_up.tga new file mode 100644 index 000000000..5b03c5433 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/arrow_up.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/b4870163-6208-42a9-9801-93133bf9a6cd.tga b/indra/newview/skins/Blacklightblue/textures/b4870163-6208-42a9-9801-93133bf9a6cd.tga new file mode 100644 index 000000000..54f7c6ece Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/b4870163-6208-42a9-9801-93133bf9a6cd.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/badge_error.j2c b/indra/newview/skins/Blacklightblue/textures/badge_error.j2c new file mode 100644 index 000000000..efb5c375c Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/badge_error.j2c differ diff --git a/indra/newview/skins/Blacklightblue/textures/badge_note.j2c b/indra/newview/skins/Blacklightblue/textures/badge_note.j2c new file mode 100644 index 000000000..ef5db9e0d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/badge_note.j2c differ diff --git a/indra/newview/skins/Blacklightblue/textures/badge_ok.j2c b/indra/newview/skins/Blacklightblue/textures/badge_ok.j2c new file mode 100644 index 000000000..8ceee01c6 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/badge_ok.j2c differ diff --git a/indra/newview/skins/Blacklightblue/textures/badge_warn.j2c b/indra/newview/skins/Blacklightblue/textures/badge_warn.j2c new file mode 100644 index 000000000..8fb85be69 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/badge_warn.j2c differ diff --git a/indra/newview/skins/Blacklightblue/textures/btn_chatbar.tga b/indra/newview/skins/Blacklightblue/textures/btn_chatbar.tga new file mode 100644 index 000000000..07117925a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/btn_chatbar.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/btn_chatbar_selected.tga b/indra/newview/skins/Blacklightblue/textures/btn_chatbar_selected.tga new file mode 100644 index 000000000..3446bf168 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/btn_chatbar_selected.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/button_anim_pause.tga b/indra/newview/skins/Blacklightblue/textures/button_anim_pause.tga new file mode 100644 index 000000000..f4ad7adc0 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/button_anim_pause.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/button_anim_pause_selected.tga b/indra/newview/skins/Blacklightblue/textures/button_anim_pause_selected.tga new file mode 100644 index 000000000..64268de2c Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/button_anim_pause_selected.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/button_anim_play.tga b/indra/newview/skins/Blacklightblue/textures/button_anim_play.tga new file mode 100644 index 000000000..9843aec5f Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/button_anim_play.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/button_anim_play_selected.tga b/indra/newview/skins/Blacklightblue/textures/button_anim_play_selected.tga new file mode 100644 index 000000000..d102c2b06 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/button_anim_play_selected.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/button_anim_stop.tga b/indra/newview/skins/Blacklightblue/textures/button_anim_stop.tga new file mode 100644 index 000000000..4c28986bf Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/button_anim_stop.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/button_anim_stop_selected.tga b/indra/newview/skins/Blacklightblue/textures/button_anim_stop_selected.tga new file mode 100644 index 000000000..afb1536e0 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/button_anim_stop_selected.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/button_disabled_32x128.tga b/indra/newview/skins/Blacklightblue/textures/button_disabled_32x128.tga new file mode 100644 index 000000000..d33fbe464 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/button_disabled_32x128.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/button_enabled_32x128.tga b/indra/newview/skins/Blacklightblue/textures/button_enabled_32x128.tga new file mode 100644 index 000000000..d33fbe464 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/button_enabled_32x128.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/button_enabled_selected_32x128.tga b/indra/newview/skins/Blacklightblue/textures/button_enabled_selected_32x128.tga new file mode 100644 index 000000000..a7ef5b78d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/button_enabled_selected_32x128.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/c1e21504-f136-451d-b8e9-929037812f1d.tga b/indra/newview/skins/Blacklightblue/textures/c1e21504-f136-451d-b8e9-929037812f1d.tga new file mode 100644 index 000000000..0db2e5061 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/c1e21504-f136-451d-b8e9-929037812f1d.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/c63f124c-6340-4fbf-b59e-0869a44adb64.tga b/indra/newview/skins/Blacklightblue/textures/c63f124c-6340-4fbf-b59e-0869a44adb64.tga new file mode 100644 index 000000000..2e8d54b35 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/c63f124c-6340-4fbf-b59e-0869a44adb64.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/cam_rotate_in.tga b/indra/newview/skins/Blacklightblue/textures/cam_rotate_in.tga new file mode 100644 index 000000000..129c9982e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/cam_rotate_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/cam_rotate_out.tga b/indra/newview/skins/Blacklightblue/textures/cam_rotate_out.tga new file mode 100644 index 000000000..bd7c80e29 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/cam_rotate_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/cam_tracking_in.tga b/indra/newview/skins/Blacklightblue/textures/cam_tracking_in.tga new file mode 100644 index 000000000..1d5b32a3c Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/cam_tracking_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/cam_tracking_out.tga b/indra/newview/skins/Blacklightblue/textures/cam_tracking_out.tga new file mode 100644 index 000000000..8bac4a1f2 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/cam_tracking_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/cam_zoom_minus_in.tga b/indra/newview/skins/Blacklightblue/textures/cam_zoom_minus_in.tga new file mode 100644 index 000000000..58cb426be Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/cam_zoom_minus_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/cam_zoom_out.tga b/indra/newview/skins/Blacklightblue/textures/cam_zoom_out.tga new file mode 100644 index 000000000..6b117abc1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/cam_zoom_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/cam_zoom_plus_in.tga b/indra/newview/skins/Blacklightblue/textures/cam_zoom_plus_in.tga new file mode 100644 index 000000000..c427f4ba9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/cam_zoom_plus_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ce15fd63-b0b6-463c-a37d-ea6393208b3e.tga b/indra/newview/skins/Blacklightblue/textures/ce15fd63-b0b6-463c-a37d-ea6393208b3e.tga new file mode 100644 index 000000000..dfe32943a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ce15fd63-b0b6-463c-a37d-ea6393208b3e.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/checkbox_disabled_false.tga b/indra/newview/skins/Blacklightblue/textures/checkbox_disabled_false.tga new file mode 100644 index 000000000..aa57cd211 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/checkbox_disabled_false.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/checkbox_disabled_true.tga b/indra/newview/skins/Blacklightblue/textures/checkbox_disabled_true.tga new file mode 100644 index 000000000..30bc6d4c9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/checkbox_disabled_true.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/checkbox_enabled_false.tga b/indra/newview/skins/Blacklightblue/textures/checkbox_enabled_false.tga new file mode 100644 index 000000000..fb8265b18 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/checkbox_enabled_false.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/checkbox_enabled_true.tga b/indra/newview/skins/Blacklightblue/textures/checkbox_enabled_true.tga new file mode 100644 index 000000000..1b43d2abb Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/checkbox_enabled_true.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/close_in_blue.tga b/indra/newview/skins/Blacklightblue/textures/close_in_blue.tga new file mode 100644 index 000000000..c58e052b8 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/close_in_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/close_inactive_blue.tga b/indra/newview/skins/Blacklightblue/textures/close_inactive_blue.tga new file mode 100644 index 000000000..2f912df59 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/close_inactive_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/closebox.tga b/indra/newview/skins/Blacklightblue/textures/closebox.tga new file mode 100644 index 000000000..5e1195526 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/closebox.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/combobox_arrow.tga b/indra/newview/skins/Blacklightblue/textures/combobox_arrow.tga new file mode 100644 index 000000000..cd592c3df Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/combobox_arrow.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/d07f6eed-b96a-47cd-b51d-400ad4a1c428.j2c b/indra/newview/skins/Blacklightblue/textures/d07f6eed-b96a-47cd-b51d-400ad4a1c428.j2c new file mode 100644 index 000000000..4b73b25ac Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/d07f6eed-b96a-47cd-b51d-400ad4a1c428.j2c differ diff --git a/indra/newview/skins/Blacklightblue/textures/default_land_picture.j2c b/indra/newview/skins/Blacklightblue/textures/default_land_picture.j2c new file mode 100644 index 000000000..6e2a85a46 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/default_land_picture.j2c differ diff --git a/indra/newview/skins/Blacklightblue/textures/default_profile_picture.j2c b/indra/newview/skins/Blacklightblue/textures/default_profile_picture.j2c new file mode 100644 index 000000000..31d741e88 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/default_profile_picture.j2c differ diff --git a/indra/newview/skins/Blacklightblue/textures/direction_arrow.tga b/indra/newview/skins/Blacklightblue/textures/direction_arrow.tga new file mode 100644 index 000000000..59149e1d5 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/direction_arrow.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/down_arrow.png b/indra/newview/skins/Blacklightblue/textures/down_arrow.png new file mode 100644 index 000000000..88c8c8481 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/down_arrow.png differ diff --git a/indra/newview/skins/Blacklightblue/textures/eye_button_active.tga b/indra/newview/skins/Blacklightblue/textures/eye_button_active.tga new file mode 100644 index 000000000..8cda9a6a0 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/eye_button_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/eye_button_inactive.tga b/indra/newview/skins/Blacklightblue/textures/eye_button_inactive.tga new file mode 100644 index 000000000..92a289f11 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/eye_button_inactive.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ff9a71eb-7414-4cf8-866e-a701deb7c3cf.tga b/indra/newview/skins/Blacklightblue/textures/ff9a71eb-7414-4cf8-866e-a701deb7c3cf.tga new file mode 100644 index 000000000..534ecba91 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ff9a71eb-7414-4cf8-866e-a701deb7c3cf.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ff_edit_mine_button.tga b/indra/newview/skins/Blacklightblue/textures/ff_edit_mine_button.tga new file mode 100644 index 000000000..d2feac64b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ff_edit_mine_button.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ff_edit_theirs_button.tga b/indra/newview/skins/Blacklightblue/textures/ff_edit_theirs_button.tga new file mode 100644 index 000000000..ae0f5c977 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ff_edit_theirs_button.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ff_online_status_button.tga b/indra/newview/skins/Blacklightblue/textures/ff_online_status_button.tga new file mode 100644 index 000000000..30b70ccd4 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ff_online_status_button.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ff_visible_map.tga b/indra/newview/skins/Blacklightblue/textures/ff_visible_map.tga new file mode 100644 index 000000000..d8ed32336 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ff_visible_map.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ff_visible_map_button.tga b/indra/newview/skins/Blacklightblue/textures/ff_visible_map_button.tga new file mode 100644 index 000000000..ca1bb7697 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ff_visible_map_button.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ff_visible_online.tga b/indra/newview/skins/Blacklightblue/textures/ff_visible_online.tga new file mode 100644 index 000000000..2b76d72ec Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ff_visible_online.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ff_visible_online_button.tga b/indra/newview/skins/Blacklightblue/textures/ff_visible_online_button.tga new file mode 100644 index 000000000..f0a4414e0 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ff_visible_online_button.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/flyout_btn_left.tga b/indra/newview/skins/Blacklightblue/textures/flyout_btn_left.tga new file mode 100644 index 000000000..3e4e2625c Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/flyout_btn_left.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/flyout_btn_left_disabled.tga b/indra/newview/skins/Blacklightblue/textures/flyout_btn_left_disabled.tga new file mode 100644 index 000000000..3e4e2625c Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/flyout_btn_left_disabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/flyout_btn_left_selected.tga b/indra/newview/skins/Blacklightblue/textures/flyout_btn_left_selected.tga new file mode 100644 index 000000000..b8e809c57 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/flyout_btn_left_selected.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/flyout_btn_right.tga b/indra/newview/skins/Blacklightblue/textures/flyout_btn_right.tga new file mode 100644 index 000000000..c59ad0043 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/flyout_btn_right.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/flyout_btn_right_disabled.tga b/indra/newview/skins/Blacklightblue/textures/flyout_btn_right_disabled.tga new file mode 100644 index 000000000..c59ad0043 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/flyout_btn_right_disabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/flyout_btn_right_selected.tga b/indra/newview/skins/Blacklightblue/textures/flyout_btn_right_selected.tga new file mode 100644 index 000000000..70afe2d34 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/flyout_btn_right_selected.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/flyout_left.tga b/indra/newview/skins/Blacklightblue/textures/flyout_left.tga new file mode 100644 index 000000000..a759112e1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/flyout_left.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/flyout_left_disabled.tga b/indra/newview/skins/Blacklightblue/textures/flyout_left_disabled.tga new file mode 100644 index 000000000..a759112e1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/flyout_left_disabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/flyout_left_selected.tga b/indra/newview/skins/Blacklightblue/textures/flyout_left_selected.tga new file mode 100644 index 000000000..783dc6270 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/flyout_left_selected.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/folder_arrow.tga b/indra/newview/skins/Blacklightblue/textures/folder_arrow.tga new file mode 100644 index 000000000..734a00a84 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/folder_arrow.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_chatbar.tga b/indra/newview/skins/Blacklightblue/textures/icn_chatbar.tga new file mode 100644 index 000000000..b89dfc432 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_chatbar.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_label_media.tga b/indra/newview/skins/Blacklightblue/textures/icn_label_media.tga new file mode 100644 index 000000000..b16c528e9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_label_media.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_label_music.tga b/indra/newview/skins/Blacklightblue/textures/icn_label_music.tga new file mode 100644 index 000000000..515f170b6 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_label_music.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_label_web.tga b/indra/newview/skins/Blacklightblue/textures/icn_label_web.tga new file mode 100644 index 000000000..6cacfad7a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_label_web.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media-pause_active.tga b/indra/newview/skins/Blacklightblue/textures/icn_media-pause_active.tga new file mode 100644 index 000000000..4d10aff70 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media-pause_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media-pause_disabled.tga b/indra/newview/skins/Blacklightblue/textures/icn_media-pause_disabled.tga new file mode 100644 index 000000000..7689cb709 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media-pause_disabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media-pause_enabled.tga b/indra/newview/skins/Blacklightblue/textures/icn_media-pause_enabled.tga new file mode 100644 index 000000000..6ea800a30 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media-pause_enabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media-play_active.tga b/indra/newview/skins/Blacklightblue/textures/icn_media-play_active.tga new file mode 100644 index 000000000..fb7d843a3 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media-play_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media-play_disabled.tga b/indra/newview/skins/Blacklightblue/textures/icn_media-play_disabled.tga new file mode 100644 index 000000000..0306e94c6 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media-play_disabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media-play_enabled.tga b/indra/newview/skins/Blacklightblue/textures/icn_media-play_enabled.tga new file mode 100644 index 000000000..51b6807ae Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media-play_enabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media-stop_active.tga b/indra/newview/skins/Blacklightblue/textures/icn_media-stop_active.tga new file mode 100644 index 000000000..de0644867 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media-stop_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media-stop_disabled.tga b/indra/newview/skins/Blacklightblue/textures/icn_media-stop_disabled.tga new file mode 100644 index 000000000..6c18bbeda Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media-stop_disabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media-stop_enabled.tga b/indra/newview/skins/Blacklightblue/textures/icn_media-stop_enabled.tga new file mode 100644 index 000000000..8738cdc9e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media-stop_enabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media.tga b/indra/newview/skins/Blacklightblue/textures/icn_media.tga new file mode 100644 index 000000000..9743d4708 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media_movie.tga b/indra/newview/skins/Blacklightblue/textures/icn_media_movie.tga new file mode 100644 index 000000000..b16c528e9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media_movie.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_media_web.tga b/indra/newview/skins/Blacklightblue/textures/icn_media_web.tga new file mode 100644 index 000000000..a92ae962b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_media_web.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_music-play.tga b/indra/newview/skins/Blacklightblue/textures/icn_music-play.tga new file mode 100644 index 000000000..4249627ca Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_music-play.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_music.tga b/indra/newview/skins/Blacklightblue/textures/icn_music.tga new file mode 100644 index 000000000..a7c2845dc Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_music.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_pause.tga b/indra/newview/skins/Blacklightblue/textures/icn_pause.tga new file mode 100644 index 000000000..3bc286f5f Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_pause.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_play.tga b/indra/newview/skins/Blacklightblue/textures/icn_play.tga new file mode 100644 index 000000000..a23ef52e3 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_play.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_rounded-text-field.tga b/indra/newview/skins/Blacklightblue/textures/icn_rounded-text-field.tga new file mode 100644 index 000000000..1f1e72572 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_rounded-text-field.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_slide-groove_dark.tga b/indra/newview/skins/Blacklightblue/textures/icn_slide-groove_dark.tga new file mode 100644 index 000000000..9b9c2e4c4 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_slide-groove_dark.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_slide-highlight.tga b/indra/newview/skins/Blacklightblue/textures/icn_slide-highlight.tga new file mode 100644 index 000000000..d371cd066 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_slide-highlight.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_slide-thumb_dark.tga b/indra/newview/skins/Blacklightblue/textures/icn_slide-thumb_dark.tga new file mode 100644 index 000000000..dd34dc0df Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_slide-thumb_dark.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_speaker-muted_dark.tga b/indra/newview/skins/Blacklightblue/textures/icn_speaker-muted_dark.tga new file mode 100644 index 000000000..8f2c80dd2 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_speaker-muted_dark.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_speaker_dark.tga b/indra/newview/skins/Blacklightblue/textures/icn_speaker_dark.tga new file mode 100644 index 000000000..c2ee04044 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_speaker_dark.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_stop.tga b/indra/newview/skins/Blacklightblue/textures/icn_stop.tga new file mode 100644 index 000000000..2925b3853 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_stop.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_toolbar_radar.tga b/indra/newview/skins/Blacklightblue/textures/icn_toolbar_radar.tga new file mode 100644 index 000000000..d1a55ed74 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_toolbar_radar.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_voice-groupfocus.tga b/indra/newview/skins/Blacklightblue/textures/icn_voice-groupfocus.tga new file mode 100644 index 000000000..913bd0969 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_voice-groupfocus.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_voice-localchat.tga b/indra/newview/skins/Blacklightblue/textures/icn_voice-localchat.tga new file mode 100644 index 000000000..5c1456602 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_voice-localchat.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_voice-pvtfocus.tga b/indra/newview/skins/Blacklightblue/textures/icn_voice-pvtfocus.tga new file mode 100644 index 000000000..76e72fd3a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_voice-pvtfocus.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-off.tga b/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-off.tga new file mode 100644 index 000000000..530425dd7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-off.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on-lvl1.tga b/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on-lvl1.tga new file mode 100644 index 000000000..b64551cc0 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on-lvl1.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on-lvl2.tga b/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on-lvl2.tga new file mode 100644 index 000000000..348591e3d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on-lvl2.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on-lvl3.tga b/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on-lvl3.tga new file mode 100644 index 000000000..081265efb Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on-lvl3.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on.tga b/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on.tga new file mode 100644 index 000000000..f9eb32926 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icn_voice_ptt-on.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_auction.tga b/indra/newview/skins/Blacklightblue/textures/icon_auction.tga new file mode 100644 index 000000000..3aa21d323 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_auction.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_avatar_offline.tga b/indra/newview/skins/Blacklightblue/textures/icon_avatar_offline.tga new file mode 100644 index 000000000..620e0f7c1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_avatar_offline.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_avatar_online.tga b/indra/newview/skins/Blacklightblue/textures/icon_avatar_online.tga new file mode 100644 index 000000000..6350237ee Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_avatar_online.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_diurnal.tga b/indra/newview/skins/Blacklightblue/textures/icon_diurnal.tga new file mode 100644 index 000000000..fc720c826 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_diurnal.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_event.tga b/indra/newview/skins/Blacklightblue/textures/icon_event.tga new file mode 100644 index 000000000..23f246b91 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_event.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_event_adult.tga b/indra/newview/skins/Blacklightblue/textures/icon_event_adult.tga new file mode 100644 index 000000000..7202e6734 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_event_adult.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_event_mature.tga b/indra/newview/skins/Blacklightblue/textures/icon_event_mature.tga new file mode 100644 index 000000000..103c5e535 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_event_mature.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_for_sale.tga b/indra/newview/skins/Blacklightblue/textures/icon_for_sale.tga new file mode 100644 index 000000000..09405d383 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_for_sale.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_for_sale_adult.tga b/indra/newview/skins/Blacklightblue/textures/icon_for_sale_adult.tga new file mode 100644 index 000000000..147f724e7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_for_sale_adult.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_group.tga b/indra/newview/skins/Blacklightblue/textures/icon_group.tga new file mode 100644 index 000000000..1e5c31aa3 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_group.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_groupnotice.tga b/indra/newview/skins/Blacklightblue/textures/icon_groupnotice.tga new file mode 100644 index 000000000..6b312a9ec Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_groupnotice.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_groupnoticeinventory.tga b/indra/newview/skins/Blacklightblue/textures/icon_groupnoticeinventory.tga new file mode 100644 index 000000000..06f59e583 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_groupnoticeinventory.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_lock.tga b/indra/newview/skins/Blacklightblue/textures/icon_lock.tga new file mode 100644 index 000000000..5de6cc10e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_lock.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_place.tga b/indra/newview/skins/Blacklightblue/textures/icon_place.tga new file mode 100644 index 000000000..7f842ba65 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_place.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_popular.tga b/indra/newview/skins/Blacklightblue/textures/icon_popular.tga new file mode 100644 index 000000000..6bdc6ede3 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_popular.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/icon_top_pick.tga b/indra/newview/skins/Blacklightblue/textures/icon_top_pick.tga new file mode 100644 index 000000000..4466e8be7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/icon_top_pick.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_animation.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_animation.tga new file mode 100644 index 000000000..ffe56a15f Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_animation.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_bodypart.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_bodypart.tga new file mode 100644 index 000000000..10076c380 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_bodypart.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_callingcard.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_callingcard.tga new file mode 100644 index 000000000..b5d08a816 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_callingcard.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_clothing.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_clothing.tga new file mode 100644 index 000000000..5467b3bf8 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_clothing.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_gesture.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_gesture.tga new file mode 100644 index 000000000..400a8e5c7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_gesture.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_landmark.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_landmark.tga new file mode 100644 index 000000000..901526259 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_landmark.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_lostandfound.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_lostandfound.tga new file mode 100644 index 000000000..7451c35b8 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_lostandfound.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_notecard.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_notecard.tga new file mode 100644 index 000000000..d8ebca11a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_notecard.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_object.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_object.tga new file mode 100644 index 000000000..c7951ccce Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_object.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_plain_closed.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_plain_closed.tga new file mode 100644 index 000000000..b46f97d11 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_plain_closed.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_plain_open.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_plain_open.tga new file mode 100644 index 000000000..c4b0f3f61 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_plain_open.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_script.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_script.tga new file mode 100644 index 000000000..c280d4282 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_script.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_snapshot.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_snapshot.tga new file mode 100644 index 000000000..8b2dfa5fa Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_snapshot.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_sound.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_sound.tga new file mode 100644 index 000000000..e0ebed0d3 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_sound.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_texture.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_texture.tga new file mode 100644 index 000000000..2d69c84f6 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_texture.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_folder_trash.tga b/indra/newview/skins/Blacklightblue/textures/inv_folder_trash.tga new file mode 100644 index 000000000..e6ffad1e0 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_folder_trash.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_animation.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_animation.tga new file mode 100644 index 000000000..715189fda Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_animation.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_attach.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_attach.tga new file mode 100644 index 000000000..2da7ef8e7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_attach.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_callingcard_offline.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_callingcard_offline.tga new file mode 100644 index 000000000..70e7a2645 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_callingcard_offline.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_callingcard_online.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_callingcard_online.tga new file mode 100644 index 000000000..8e394063b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_callingcard_online.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_clothing.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_clothing.tga new file mode 100644 index 000000000..b41096371 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_clothing.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_eyes.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_eyes.tga new file mode 100644 index 000000000..0cfebb69d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_eyes.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_gesture.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_gesture.tga new file mode 100644 index 000000000..95c1da44e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_gesture.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_gloves.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_gloves.tga new file mode 100644 index 000000000..6f55738ee Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_gloves.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_hair.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_hair.tga new file mode 100644 index 000000000..13ffe09c3 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_hair.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_jacket.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_jacket.tga new file mode 100644 index 000000000..a1b518c63 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_jacket.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_landmark.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_landmark.tga new file mode 100644 index 000000000..addf5eb0e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_landmark.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_landmark_visited.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_landmark_visited.tga new file mode 100644 index 000000000..b16f9a1b8 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_landmark_visited.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_notecard.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_notecard.tga new file mode 100644 index 000000000..c7b3bf557 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_notecard.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_object.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_object.tga new file mode 100644 index 000000000..9c407b1d5 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_object.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_object_multi.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_object_multi.tga new file mode 100644 index 000000000..d2ed12df3 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_object_multi.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_pants.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_pants.tga new file mode 100644 index 000000000..517c94712 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_pants.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_script.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_script.tga new file mode 100644 index 000000000..8e602f595 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_script.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_script_dangerous.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_script_dangerous.tga new file mode 100644 index 000000000..b5a1bc947 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_script_dangerous.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_shape.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_shape.tga new file mode 100644 index 000000000..d28bb2583 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_shape.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_shirt.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_shirt.tga new file mode 100644 index 000000000..b41096371 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_shirt.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_shoes.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_shoes.tga new file mode 100644 index 000000000..f124ed458 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_shoes.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_skin.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_skin.tga new file mode 100644 index 000000000..169fbc1d5 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_skin.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_skirt.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_skirt.tga new file mode 100644 index 000000000..cd0292210 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_skirt.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_snapshot.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_snapshot.tga new file mode 100644 index 000000000..fcf7316bd Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_snapshot.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_socks.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_socks.tga new file mode 100644 index 000000000..0ccb575ce Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_socks.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_sound.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_sound.tga new file mode 100644 index 000000000..1bb8adfa1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_sound.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_texture.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_texture.tga new file mode 100644 index 000000000..7016ae080 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_texture.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_underpants.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_underpants.tga new file mode 100644 index 000000000..b9f29c688 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_underpants.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/inv_item_undershirt.tga b/indra/newview/skins/Blacklightblue/textures/inv_item_undershirt.tga new file mode 100644 index 000000000..a62b1d853 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/inv_item_undershirt.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_avatar_16.tga b/indra/newview/skins/Blacklightblue/textures/map_avatar_16.tga new file mode 100644 index 000000000..42d8c1e29 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_avatar_16.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_avatar_8.tga b/indra/newview/skins/Blacklightblue/textures/map_avatar_8.tga new file mode 100644 index 000000000..7eb7c20f1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_avatar_8.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_avatar_above_8.tga b/indra/newview/skins/Blacklightblue/textures/map_avatar_above_8.tga new file mode 100644 index 000000000..6faefccc7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_avatar_above_8.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_avatar_below_8.tga b/indra/newview/skins/Blacklightblue/textures/map_avatar_below_8.tga new file mode 100644 index 000000000..5ad671c26 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_avatar_below_8.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_avatar_you_8.tga b/indra/newview/skins/Blacklightblue/textures/map_avatar_you_8.tga new file mode 100644 index 000000000..a865e017b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_avatar_you_8.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_event.tga b/indra/newview/skins/Blacklightblue/textures/map_event.tga new file mode 100644 index 000000000..103c5e535 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_event.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_event_adult.tga b/indra/newview/skins/Blacklightblue/textures/map_event_adult.tga new file mode 100644 index 000000000..7202e6734 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_event_adult.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_event_mature.tga b/indra/newview/skins/Blacklightblue/textures/map_event_mature.tga new file mode 100644 index 000000000..23f246b91 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_event_mature.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_home.tga b/indra/newview/skins/Blacklightblue/textures/map_home.tga new file mode 100644 index 000000000..85dde9ef7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_home.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_infohub.tga b/indra/newview/skins/Blacklightblue/textures/map_infohub.tga new file mode 100644 index 000000000..173b93e39 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_infohub.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_telehub.tga b/indra/newview/skins/Blacklightblue/textures/map_telehub.tga new file mode 100644 index 000000000..d89bcfa40 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_telehub.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_track_16.tga b/indra/newview/skins/Blacklightblue/textures/map_track_16.tga new file mode 100644 index 000000000..14d49b93b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_track_16.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/map_track_8.tga b/indra/newview/skins/Blacklightblue/textures/map_track_8.tga new file mode 100644 index 000000000..d9605dde1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/map_track_8.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/media_icon.tga b/indra/newview/skins/Blacklightblue/textures/media_icon.tga new file mode 100644 index 000000000..868da3734 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/media_icon.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/minimize.tga b/indra/newview/skins/Blacklightblue/textures/minimize.tga new file mode 100644 index 000000000..151a3078f Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/minimize.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/minimize_inactive.tga b/indra/newview/skins/Blacklightblue/textures/minimize_inactive.tga new file mode 100644 index 000000000..d7e1b4057 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/minimize_inactive.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/minimize_pressed.tga b/indra/newview/skins/Blacklightblue/textures/minimize_pressed.tga new file mode 100644 index 000000000..573452ce9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/minimize_pressed.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_backward_in.tga b/indra/newview/skins/Blacklightblue/textures/move_backward_in.tga new file mode 100644 index 000000000..74bfba196 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_backward_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_backward_out.tga b/indra/newview/skins/Blacklightblue/textures/move_backward_out.tga new file mode 100644 index 000000000..0cb143cd8 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_backward_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_down_in.tga b/indra/newview/skins/Blacklightblue/textures/move_down_in.tga new file mode 100644 index 000000000..90b0c76d5 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_down_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_down_out.tga b/indra/newview/skins/Blacklightblue/textures/move_down_out.tga new file mode 100644 index 000000000..93058b043 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_down_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_forward_in.tga b/indra/newview/skins/Blacklightblue/textures/move_forward_in.tga new file mode 100644 index 000000000..5f1735552 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_forward_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_forward_out.tga b/indra/newview/skins/Blacklightblue/textures/move_forward_out.tga new file mode 100644 index 000000000..e5c826b9b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_forward_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_left_in.tga b/indra/newview/skins/Blacklightblue/textures/move_left_in.tga new file mode 100644 index 000000000..8ba5abdd2 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_left_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_left_out.tga b/indra/newview/skins/Blacklightblue/textures/move_left_out.tga new file mode 100644 index 000000000..a428f9739 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_left_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_right_in.tga b/indra/newview/skins/Blacklightblue/textures/move_right_in.tga new file mode 100644 index 000000000..6dd30876f Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_right_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_right_out.tga b/indra/newview/skins/Blacklightblue/textures/move_right_out.tga new file mode 100644 index 000000000..bfce731ab Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_right_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_turn_left_in.tga b/indra/newview/skins/Blacklightblue/textures/move_turn_left_in.tga new file mode 100644 index 000000000..db410d697 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_turn_left_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_turn_left_out.tga b/indra/newview/skins/Blacklightblue/textures/move_turn_left_out.tga new file mode 100644 index 000000000..31bcc42a1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_turn_left_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_turn_right_in.tga b/indra/newview/skins/Blacklightblue/textures/move_turn_right_in.tga new file mode 100644 index 000000000..e22898c2a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_turn_right_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_turn_right_out.tga b/indra/newview/skins/Blacklightblue/textures/move_turn_right_out.tga new file mode 100644 index 000000000..69fb9f400 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_turn_right_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_up_in.tga b/indra/newview/skins/Blacklightblue/textures/move_up_in.tga new file mode 100644 index 000000000..54c641f5b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_up_in.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/move_up_out.tga b/indra/newview/skins/Blacklightblue/textures/move_up_out.tga new file mode 100644 index 000000000..28e6f60aa Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/move_up_out.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/mute_icon.tga b/indra/newview/skins/Blacklightblue/textures/mute_icon.tga new file mode 100644 index 000000000..879b9e618 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/mute_icon.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/notify_box_icon.tga b/indra/newview/skins/Blacklightblue/textures/notify_box_icon.tga new file mode 100644 index 000000000..880aca9b4 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/notify_box_icon.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/notify_caution_icon.tga b/indra/newview/skins/Blacklightblue/textures/notify_caution_icon.tga new file mode 100644 index 000000000..ac6660c16 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/notify_caution_icon.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/notify_next.png b/indra/newview/skins/Blacklightblue/textures/notify_next.png new file mode 100644 index 000000000..9b371e03e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/notify_next.png differ diff --git a/indra/newview/skins/Blacklightblue/textures/notify_tip_icon.tga b/indra/newview/skins/Blacklightblue/textures/notify_tip_icon.tga new file mode 100644 index 000000000..0451da099 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/notify_tip_icon.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_cone.tga b/indra/newview/skins/Blacklightblue/textures/object_cone.tga new file mode 100644 index 000000000..3cd51dfeb Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_cone.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_cone_active.tga b/indra/newview/skins/Blacklightblue/textures/object_cone_active.tga new file mode 100644 index 000000000..ab8137c05 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_cone_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_cube.tga b/indra/newview/skins/Blacklightblue/textures/object_cube.tga new file mode 100644 index 000000000..3395522c2 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_cube.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_cube_active.tga b/indra/newview/skins/Blacklightblue/textures/object_cube_active.tga new file mode 100644 index 000000000..40886cf0d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_cube_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_cylinder.tga b/indra/newview/skins/Blacklightblue/textures/object_cylinder.tga new file mode 100644 index 000000000..2d13f3be6 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_cylinder.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_cylinder_active.tga b/indra/newview/skins/Blacklightblue/textures/object_cylinder_active.tga new file mode 100644 index 000000000..328d10355 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_cylinder_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_grass.tga b/indra/newview/skins/Blacklightblue/textures/object_grass.tga new file mode 100644 index 000000000..8b1943d18 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_grass.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_grass_active.tga b/indra/newview/skins/Blacklightblue/textures/object_grass_active.tga new file mode 100644 index 000000000..55cdbaa3a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_grass_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_hemi_cone.tga b/indra/newview/skins/Blacklightblue/textures/object_hemi_cone.tga new file mode 100644 index 000000000..2cd4a33b0 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_hemi_cone.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_hemi_cone_active.tga b/indra/newview/skins/Blacklightblue/textures/object_hemi_cone_active.tga new file mode 100644 index 000000000..459c723b9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_hemi_cone_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_hemi_cylinder.tga b/indra/newview/skins/Blacklightblue/textures/object_hemi_cylinder.tga new file mode 100644 index 000000000..669f78f89 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_hemi_cylinder.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_hemi_cylinder_active.tga b/indra/newview/skins/Blacklightblue/textures/object_hemi_cylinder_active.tga new file mode 100644 index 000000000..154ab9b13 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_hemi_cylinder_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_hemi_sphere.tga b/indra/newview/skins/Blacklightblue/textures/object_hemi_sphere.tga new file mode 100644 index 000000000..d1815a5a9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_hemi_sphere.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_hemi_sphere_active.tga b/indra/newview/skins/Blacklightblue/textures/object_hemi_sphere_active.tga new file mode 100644 index 000000000..e5e0c45c7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_hemi_sphere_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_prism.tga b/indra/newview/skins/Blacklightblue/textures/object_prism.tga new file mode 100644 index 000000000..099026cc4 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_prism.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_prism_active.tga b/indra/newview/skins/Blacklightblue/textures/object_prism_active.tga new file mode 100644 index 000000000..fa9d0b98d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_prism_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_pyramid.tga b/indra/newview/skins/Blacklightblue/textures/object_pyramid.tga new file mode 100644 index 000000000..7927c8b4e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_pyramid.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_pyramid_active.tga b/indra/newview/skins/Blacklightblue/textures/object_pyramid_active.tga new file mode 100644 index 000000000..b20b33e26 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_pyramid_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_ring.tga b/indra/newview/skins/Blacklightblue/textures/object_ring.tga new file mode 100644 index 000000000..49603f1bd Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_ring.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_ring_active.tga b/indra/newview/skins/Blacklightblue/textures/object_ring_active.tga new file mode 100644 index 000000000..0229818c6 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_ring_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_sphere.tga b/indra/newview/skins/Blacklightblue/textures/object_sphere.tga new file mode 100644 index 000000000..7bfae3b6d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_sphere.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_sphere_active.tga b/indra/newview/skins/Blacklightblue/textures/object_sphere_active.tga new file mode 100644 index 000000000..6d27f4fc1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_sphere_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_tetrahedron.tga b/indra/newview/skins/Blacklightblue/textures/object_tetrahedron.tga new file mode 100644 index 000000000..717881b4e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_tetrahedron.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_tetrahedron_active.tga b/indra/newview/skins/Blacklightblue/textures/object_tetrahedron_active.tga new file mode 100644 index 000000000..fc0a609f6 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_tetrahedron_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_torus.tga b/indra/newview/skins/Blacklightblue/textures/object_torus.tga new file mode 100644 index 000000000..33d493106 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_torus.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_torus_active.tga b/indra/newview/skins/Blacklightblue/textures/object_torus_active.tga new file mode 100644 index 000000000..44f42ed8e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_torus_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_tree.tga b/indra/newview/skins/Blacklightblue/textures/object_tree.tga new file mode 100644 index 000000000..880a2fa2a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_tree.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_tree_active.tga b/indra/newview/skins/Blacklightblue/textures/object_tree_active.tga new file mode 100644 index 000000000..219f1f829 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_tree_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_tube.tga b/indra/newview/skins/Blacklightblue/textures/object_tube.tga new file mode 100644 index 000000000..49ee35ede Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_tube.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/object_tube_active.tga b/indra/newview/skins/Blacklightblue/textures/object_tube_active.tga new file mode 100644 index 000000000..655ebb01f Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/object_tube_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/preview.png b/indra/newview/skins/Blacklightblue/textures/preview.png new file mode 100644 index 000000000..57c16eaf3 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/preview.png differ diff --git a/indra/newview/skins/Blacklightblue/textures/progress_fill.tga b/indra/newview/skins/Blacklightblue/textures/progress_fill.tga new file mode 100644 index 000000000..a5363463a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/progress_fill.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/progressbar_fill.tga b/indra/newview/skins/Blacklightblue/textures/progressbar_fill.tga new file mode 100644 index 000000000..266f47288 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/progressbar_fill.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/progressbar_track.tga b/indra/newview/skins/Blacklightblue/textures/progressbar_track.tga new file mode 100644 index 000000000..4b84e9ec9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/progressbar_track.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ptt_lock_off.tga b/indra/newview/skins/Blacklightblue/textures/ptt_lock_off.tga new file mode 100644 index 000000000..d66f49840 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ptt_lock_off.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/ptt_lock_on.tga b/indra/newview/skins/Blacklightblue/textures/ptt_lock_on.tga new file mode 100644 index 000000000..432db2f00 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/ptt_lock_on.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/radio_active_false.tga b/indra/newview/skins/Blacklightblue/textures/radio_active_false.tga new file mode 100644 index 000000000..3fdaecb5b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/radio_active_false.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/radio_active_true.tga b/indra/newview/skins/Blacklightblue/textures/radio_active_true.tga new file mode 100644 index 000000000..8d7520a21 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/radio_active_true.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/radio_inactive_false.tga b/indra/newview/skins/Blacklightblue/textures/radio_inactive_false.tga new file mode 100644 index 000000000..6cc182a27 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/radio_inactive_false.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/radio_inactive_true.tga b/indra/newview/skins/Blacklightblue/textures/radio_inactive_true.tga new file mode 100644 index 000000000..c8a4e5b2c Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/radio_inactive_true.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/resize_handle_bottom_right_blue.tga b/indra/newview/skins/Blacklightblue/textures/resize_handle_bottom_right_blue.tga new file mode 100644 index 000000000..8290bfa65 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/resize_handle_bottom_right_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/restore.tga b/indra/newview/skins/Blacklightblue/textures/restore.tga new file mode 100644 index 000000000..5e369fdfc Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/restore.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/restore_inactive.tga b/indra/newview/skins/Blacklightblue/textures/restore_inactive.tga new file mode 100644 index 000000000..ce545d90d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/restore_inactive.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/restore_pressed.tga b/indra/newview/skins/Blacklightblue/textures/restore_pressed.tga new file mode 100644 index 000000000..8a25087be Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/restore_pressed.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/rounded_square.j2c b/indra/newview/skins/Blacklightblue/textures/rounded_square.j2c new file mode 100644 index 000000000..c3dfe8f10 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/rounded_square.j2c differ diff --git a/indra/newview/skins/Blacklightblue/textures/rounded_square.tga b/indra/newview/skins/Blacklightblue/textures/rounded_square.tga new file mode 100644 index 000000000..4f4bf05f8 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/rounded_square.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/rounded_square_soft.tga b/indra/newview/skins/Blacklightblue/textures/rounded_square_soft.tga new file mode 100644 index 000000000..4f4bf05f8 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/rounded_square_soft.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/script_error.j2c b/indra/newview/skins/Blacklightblue/textures/script_error.j2c new file mode 100644 index 000000000..ad6be04a7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/script_error.j2c differ diff --git a/indra/newview/skins/Blacklightblue/textures/script_error.tga b/indra/newview/skins/Blacklightblue/textures/script_error.tga new file mode 100644 index 000000000..8fa12e711 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/script_error.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/scrollbutton_down_in_blue.tga b/indra/newview/skins/Blacklightblue/textures/scrollbutton_down_in_blue.tga new file mode 100644 index 000000000..cd592c3df Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/scrollbutton_down_in_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/scrollbutton_down_out_blue.tga b/indra/newview/skins/Blacklightblue/textures/scrollbutton_down_out_blue.tga new file mode 100644 index 000000000..cd592c3df Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/scrollbutton_down_out_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/scrollbutton_left_in_blue.tga b/indra/newview/skins/Blacklightblue/textures/scrollbutton_left_in_blue.tga new file mode 100644 index 000000000..b65d199ae Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/scrollbutton_left_in_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/scrollbutton_left_out_blue.tga b/indra/newview/skins/Blacklightblue/textures/scrollbutton_left_out_blue.tga new file mode 100644 index 000000000..b65d199ae Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/scrollbutton_left_out_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/scrollbutton_right_in_blue.tga b/indra/newview/skins/Blacklightblue/textures/scrollbutton_right_in_blue.tga new file mode 100644 index 000000000..9b571add3 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/scrollbutton_right_in_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/scrollbutton_right_out_blue.tga b/indra/newview/skins/Blacklightblue/textures/scrollbutton_right_out_blue.tga new file mode 100644 index 000000000..9b571add3 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/scrollbutton_right_out_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/scrollbutton_up_in_blue.tga b/indra/newview/skins/Blacklightblue/textures/scrollbutton_up_in_blue.tga new file mode 100644 index 000000000..8e78742ff Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/scrollbutton_up_in_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/scrollbutton_up_out_blue.tga b/indra/newview/skins/Blacklightblue/textures/scrollbutton_up_out_blue.tga new file mode 100644 index 000000000..8e78742ff Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/scrollbutton_up_out_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/sm_rounded_corners_simple.tga b/indra/newview/skins/Blacklightblue/textures/sm_rounded_corners_simple.tga new file mode 100644 index 000000000..054fdd39a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/sm_rounded_corners_simple.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/smicon_warn.tga b/indra/newview/skins/Blacklightblue/textures/smicon_warn.tga new file mode 100644 index 000000000..de8cce2a7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/smicon_warn.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/spacer24.tga b/indra/newview/skins/Blacklightblue/textures/spacer24.tga new file mode 100644 index 000000000..c7cab6b38 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/spacer24.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/spacer35.tga b/indra/newview/skins/Blacklightblue/textures/spacer35.tga new file mode 100644 index 000000000..b88bc6680 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/spacer35.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/spin_down_in_blue.tga b/indra/newview/skins/Blacklightblue/textures/spin_down_in_blue.tga new file mode 100644 index 000000000..ebf99c3a7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/spin_down_in_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/spin_down_out_blue.tga b/indra/newview/skins/Blacklightblue/textures/spin_down_out_blue.tga new file mode 100644 index 000000000..1af2ed9cb Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/spin_down_out_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/spin_up_in_blue.tga b/indra/newview/skins/Blacklightblue/textures/spin_up_in_blue.tga new file mode 100644 index 000000000..54412201e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/spin_up_in_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/spin_up_out_blue.tga b/indra/newview/skins/Blacklightblue/textures/spin_up_out_blue.tga new file mode 100644 index 000000000..9a9bc6468 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/spin_up_out_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/startup_logo.j2c b/indra/newview/skins/Blacklightblue/textures/startup_logo.j2c new file mode 100644 index 000000000..e0a705489 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/startup_logo.j2c differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_buy_currency.tga b/indra/newview/skins/Blacklightblue/textures/status_buy_currency.tga new file mode 100644 index 000000000..f4a28b32b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_buy_currency.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_buy_currency_pressed.tga b/indra/newview/skins/Blacklightblue/textures/status_buy_currency_pressed.tga new file mode 100644 index 000000000..f4a28b32b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_buy_currency_pressed.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_buy_land.tga b/indra/newview/skins/Blacklightblue/textures/status_buy_land.tga new file mode 100644 index 000000000..60c395c03 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_buy_land.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_buy_land_pressed.tga b/indra/newview/skins/Blacklightblue/textures/status_buy_land_pressed.tga new file mode 100644 index 000000000..60c395c03 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_buy_land_pressed.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_health.tga b/indra/newview/skins/Blacklightblue/textures/status_health.tga new file mode 100644 index 000000000..f5eefc5a9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_health.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_no_build.tga b/indra/newview/skins/Blacklightblue/textures/status_no_build.tga new file mode 100644 index 000000000..41934a600 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_no_build.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_no_fly.tga b/indra/newview/skins/Blacklightblue/textures/status_no_fly.tga new file mode 100644 index 000000000..0aa7fa71d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_no_fly.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_no_push.tga b/indra/newview/skins/Blacklightblue/textures/status_no_push.tga new file mode 100644 index 000000000..6d5987217 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_no_push.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_no_scripts.tga b/indra/newview/skins/Blacklightblue/textures/status_no_scripts.tga new file mode 100644 index 000000000..3bce6ad6f Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_no_scripts.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_no_voice.tga b/indra/newview/skins/Blacklightblue/textures/status_no_voice.tga new file mode 100644 index 000000000..aeeed6ed0 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_no_voice.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_script_debug.tga b/indra/newview/skins/Blacklightblue/textures/status_script_debug.tga new file mode 100644 index 000000000..7d895eb0a Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_script_debug.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_search_btn.png b/indra/newview/skins/Blacklightblue/textures/status_search_btn.png new file mode 100644 index 000000000..1798559e7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_search_btn.png differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_search_btn_pressed.png b/indra/newview/skins/Blacklightblue/textures/status_search_btn_pressed.png new file mode 100644 index 000000000..c19945885 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_search_btn_pressed.png differ diff --git a/indra/newview/skins/Blacklightblue/textures/status_voice.tga b/indra/newview/skins/Blacklightblue/textures/status_voice.tga new file mode 100644 index 000000000..aeeed6ed0 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/status_voice.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tab_bottom_blue.tga b/indra/newview/skins/Blacklightblue/textures/tab_bottom_blue.tga new file mode 100644 index 000000000..e6de7a5a1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tab_bottom_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tab_bottom_selected_blue.tga b/indra/newview/skins/Blacklightblue/textures/tab_bottom_selected_blue.tga new file mode 100644 index 000000000..685d4da55 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tab_bottom_selected_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tab_left.tga b/indra/newview/skins/Blacklightblue/textures/tab_left.tga new file mode 100644 index 000000000..0220020e8 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tab_left.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tab_left_selected.tga b/indra/newview/skins/Blacklightblue/textures/tab_left_selected.tga new file mode 100644 index 000000000..485f324d1 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tab_left_selected.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tab_top_blue.tga b/indra/newview/skins/Blacklightblue/textures/tab_top_blue.tga new file mode 100644 index 000000000..ddcd519f2 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tab_top_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tab_top_selected_blue.tga b/indra/newview/skins/Blacklightblue/textures/tab_top_selected_blue.tga new file mode 100644 index 000000000..1e871986e Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tab_top_selected_blue.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tabarea.tga b/indra/newview/skins/Blacklightblue/textures/tabarea.tga new file mode 100644 index 000000000..5517aebfc Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tabarea.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tearoff_pressed.tga b/indra/newview/skins/Blacklightblue/textures/tearoff_pressed.tga new file mode 100644 index 000000000..8581ab701 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tearoff_pressed.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tearoffbox.tga b/indra/newview/skins/Blacklightblue/textures/tearoffbox.tga new file mode 100644 index 000000000..27af31c4d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tearoffbox.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/textures.xml b/indra/newview/skins/Blacklightblue/textures/textures.xml new file mode 100644 index 000000000..5955a8ede --- /dev/null +++ b/indra/newview/skins/Blacklightblue/textures/textures.xml @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/Blacklightblue/textures/tool_dozer.tga b/indra/newview/skins/Blacklightblue/textures/tool_dozer.tga new file mode 100644 index 000000000..bf3a8999d Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tool_dozer.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tool_dozer_active.tga b/indra/newview/skins/Blacklightblue/textures/tool_dozer_active.tga new file mode 100644 index 000000000..09c0e79f9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tool_dozer_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tool_zoom.tga b/indra/newview/skins/Blacklightblue/textures/tool_zoom.tga new file mode 100644 index 000000000..67692e95b Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tool_zoom.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/tool_zoom_active.tga b/indra/newview/skins/Blacklightblue/textures/tool_zoom_active.tga new file mode 100644 index 000000000..084ff39be Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/tool_zoom_active.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/toolbar_bg.tga b/indra/newview/skins/Blacklightblue/textures/toolbar_bg.tga new file mode 100644 index 000000000..3a1127611 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/toolbar_bg.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/toolbar_btn_disabled.tga b/indra/newview/skins/Blacklightblue/textures/toolbar_btn_disabled.tga new file mode 100644 index 000000000..d33fbe464 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/toolbar_btn_disabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/toolbar_btn_enabled.tga b/indra/newview/skins/Blacklightblue/textures/toolbar_btn_enabled.tga new file mode 100644 index 000000000..d33fbe464 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/toolbar_btn_enabled.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/toolbar_btn_selected.tga b/indra/newview/skins/Blacklightblue/textures/toolbar_btn_selected.tga new file mode 100644 index 000000000..1b46118b9 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/toolbar_btn_selected.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/toolbar_tab.tga b/indra/newview/skins/Blacklightblue/textures/toolbar_tab.tga new file mode 100644 index 000000000..f9a7d50d2 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/toolbar_tab.tga differ diff --git a/indra/newview/skins/Blacklightblue/textures/up_arrow.png b/indra/newview/skins/Blacklightblue/textures/up_arrow.png new file mode 100644 index 000000000..1e55b6ca7 Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/up_arrow.png differ diff --git a/indra/newview/skins/Blacklightblue/textures/up_arrow.tga b/indra/newview/skins/Blacklightblue/textures/up_arrow.tga new file mode 100644 index 000000000..4dcb587ca Binary files /dev/null and b/indra/newview/skins/Blacklightblue/textures/up_arrow.tga differ diff --git a/indra/newview/skins/Blackred/License and Credit.txt b/indra/newview/skins/Blackred/License and Credit.txt new file mode 100644 index 000000000..fe1f04c89 --- /dev/null +++ b/indra/newview/skins/Blackred/License and Credit.txt @@ -0,0 +1,6 @@ +This skin was modified by JB Kraft from the default linden skin provided. +This skin was modified by Chalice Yao from the default linden skin and JB Kraft's skin. +This skin was modified by LordGregGreg Back from the default linden skin and JB Kraft's skin. + + +All Images and modifications done are provided free to use, modify, and distribute, so long as this infomation is distributed with it. diff --git a/indra/newview/skins/Blackred/colors.xml b/indra/newview/skins/Blackred/colors.xml new file mode 100644 index 000000000..640ef35d9 --- /dev/null +++ b/indra/newview/skins/Blackred/colors.xml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/Blackred/textures/0098b015-3daf-4cfe-a72f-915369ea97c2.tga b/indra/newview/skins/Blackred/textures/0098b015-3daf-4cfe-a72f-915369ea97c2.tga new file mode 100644 index 000000000..d930e8964 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/0098b015-3daf-4cfe-a72f-915369ea97c2.tga differ diff --git a/indra/newview/skins/Blackred/textures/3c18c87e-5f50-14e2-e744-f44734aa365f.tga b/indra/newview/skins/Blackred/textures/3c18c87e-5f50-14e2-e744-f44734aa365f.tga new file mode 100644 index 000000000..e90ab295b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/3c18c87e-5f50-14e2-e744-f44734aa365f.tga differ diff --git a/indra/newview/skins/Blackred/textures/7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b.tga b/indra/newview/skins/Blackred/textures/7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b.tga new file mode 100644 index 000000000..febd7d6ee Binary files /dev/null and b/indra/newview/skins/Blackred/textures/7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b.tga differ diff --git a/indra/newview/skins/Blackred/textures/7dabc040-ec13-2309-ddf7-4f161f6de2f4.tga b/indra/newview/skins/Blackred/textures/7dabc040-ec13-2309-ddf7-4f161f6de2f4.tga new file mode 100644 index 000000000..534ecba91 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/7dabc040-ec13-2309-ddf7-4f161f6de2f4.tga differ diff --git a/indra/newview/skins/Blackred/textures/9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1.tga b/indra/newview/skins/Blackred/textures/9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1.tga new file mode 100644 index 000000000..e90ab295b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1.tga differ diff --git a/indra/newview/skins/Blackred/textures/active_speakers.tga b/indra/newview/skins/Blackred/textures/active_speakers.tga new file mode 100644 index 000000000..492669ee4 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/active_speakers.tga differ diff --git a/indra/newview/skins/Blackred/textures/active_voice_tab.tga b/indra/newview/skins/Blackred/textures/active_voice_tab.tga new file mode 100644 index 000000000..100df0d64 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/active_voice_tab.tga differ diff --git a/indra/newview/skins/Blackred/textures/arrow_down.tga b/indra/newview/skins/Blackred/textures/arrow_down.tga new file mode 100644 index 000000000..89a793bcb Binary files /dev/null and b/indra/newview/skins/Blackred/textures/arrow_down.tga differ diff --git a/indra/newview/skins/Blackred/textures/arrow_up.tga b/indra/newview/skins/Blackred/textures/arrow_up.tga new file mode 100644 index 000000000..5b03c5433 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/arrow_up.tga differ diff --git a/indra/newview/skins/Blackred/textures/b4870163-6208-42a9-9801-93133bf9a6cd.tga b/indra/newview/skins/Blackred/textures/b4870163-6208-42a9-9801-93133bf9a6cd.tga new file mode 100644 index 000000000..fd2743fed Binary files /dev/null and b/indra/newview/skins/Blackred/textures/b4870163-6208-42a9-9801-93133bf9a6cd.tga differ diff --git a/indra/newview/skins/Blackred/textures/badge_error.j2c b/indra/newview/skins/Blackred/textures/badge_error.j2c new file mode 100644 index 000000000..efb5c375c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/badge_error.j2c differ diff --git a/indra/newview/skins/Blackred/textures/badge_note.j2c b/indra/newview/skins/Blackred/textures/badge_note.j2c new file mode 100644 index 000000000..ef5db9e0d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/badge_note.j2c differ diff --git a/indra/newview/skins/Blackred/textures/badge_ok.j2c b/indra/newview/skins/Blackred/textures/badge_ok.j2c new file mode 100644 index 000000000..8ceee01c6 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/badge_ok.j2c differ diff --git a/indra/newview/skins/Blackred/textures/badge_warn.j2c b/indra/newview/skins/Blackred/textures/badge_warn.j2c new file mode 100644 index 000000000..8fb85be69 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/badge_warn.j2c differ diff --git a/indra/newview/skins/Blackred/textures/black.tga b/indra/newview/skins/Blackred/textures/black.tga new file mode 100644 index 000000000..e368ea496 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/black.tga differ diff --git a/indra/newview/skins/Blackred/textures/btn_chatbar.tga b/indra/newview/skins/Blackred/textures/btn_chatbar.tga new file mode 100644 index 000000000..07117925a Binary files /dev/null and b/indra/newview/skins/Blackred/textures/btn_chatbar.tga differ diff --git a/indra/newview/skins/Blackred/textures/btn_chatbar_selected.tga b/indra/newview/skins/Blackred/textures/btn_chatbar_selected.tga new file mode 100644 index 000000000..57e515005 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/btn_chatbar_selected.tga differ diff --git a/indra/newview/skins/Blackred/textures/button_anim_pause.tga b/indra/newview/skins/Blackred/textures/button_anim_pause.tga new file mode 100644 index 000000000..7f81d1536 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/button_anim_pause.tga differ diff --git a/indra/newview/skins/Blackred/textures/button_anim_pause_selected.tga b/indra/newview/skins/Blackred/textures/button_anim_pause_selected.tga new file mode 100644 index 000000000..650ca0aad Binary files /dev/null and b/indra/newview/skins/Blackred/textures/button_anim_pause_selected.tga differ diff --git a/indra/newview/skins/Blackred/textures/button_anim_play.tga b/indra/newview/skins/Blackred/textures/button_anim_play.tga new file mode 100644 index 000000000..a8b7b74c5 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/button_anim_play.tga differ diff --git a/indra/newview/skins/Blackred/textures/button_anim_play_selected.tga b/indra/newview/skins/Blackred/textures/button_anim_play_selected.tga new file mode 100644 index 000000000..ff9fb98b1 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/button_anim_play_selected.tga differ diff --git a/indra/newview/skins/Blackred/textures/button_anim_stop.tga b/indra/newview/skins/Blackred/textures/button_anim_stop.tga new file mode 100644 index 000000000..f8583d2da Binary files /dev/null and b/indra/newview/skins/Blackred/textures/button_anim_stop.tga differ diff --git a/indra/newview/skins/Blackred/textures/button_anim_stop_selected.tga b/indra/newview/skins/Blackred/textures/button_anim_stop_selected.tga new file mode 100644 index 000000000..0e1b3eb8c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/button_anim_stop_selected.tga differ diff --git a/indra/newview/skins/Blackred/textures/button_disabled_32x128.tga b/indra/newview/skins/Blackred/textures/button_disabled_32x128.tga new file mode 100644 index 000000000..9e7f3744d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/button_disabled_32x128.tga differ diff --git a/indra/newview/skins/Blackred/textures/button_enabled_32x128.tga b/indra/newview/skins/Blackred/textures/button_enabled_32x128.tga new file mode 100644 index 000000000..9e7f3744d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/button_enabled_32x128.tga differ diff --git a/indra/newview/skins/Blackred/textures/button_enabled_selected_32x128.tga b/indra/newview/skins/Blackred/textures/button_enabled_selected_32x128.tga new file mode 100644 index 000000000..e77a70a1c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/button_enabled_selected_32x128.tga differ diff --git a/indra/newview/skins/Blackred/textures/c1e21504-f136-451d-b8e9-929037812f1d.tga b/indra/newview/skins/Blackred/textures/c1e21504-f136-451d-b8e9-929037812f1d.tga new file mode 100644 index 000000000..7251dcc18 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/c1e21504-f136-451d-b8e9-929037812f1d.tga differ diff --git a/indra/newview/skins/Blackred/textures/c63f124c-6340-4fbf-b59e-0869a44adb64.tga b/indra/newview/skins/Blackred/textures/c63f124c-6340-4fbf-b59e-0869a44adb64.tga new file mode 100644 index 000000000..6fa784e11 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/c63f124c-6340-4fbf-b59e-0869a44adb64.tga differ diff --git a/indra/newview/skins/Blackred/textures/cam_rotate_in.tga b/indra/newview/skins/Blackred/textures/cam_rotate_in.tga new file mode 100644 index 000000000..9eadb772b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/cam_rotate_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/cam_rotate_out.tga b/indra/newview/skins/Blackred/textures/cam_rotate_out.tga new file mode 100644 index 000000000..f86135251 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/cam_rotate_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/cam_tracking_in.tga b/indra/newview/skins/Blackred/textures/cam_tracking_in.tga new file mode 100644 index 000000000..b3d5b2ad2 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/cam_tracking_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/cam_tracking_out.tga b/indra/newview/skins/Blackred/textures/cam_tracking_out.tga new file mode 100644 index 000000000..2835219ff Binary files /dev/null and b/indra/newview/skins/Blackred/textures/cam_tracking_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/cam_zoom_minus_in.tga b/indra/newview/skins/Blackred/textures/cam_zoom_minus_in.tga new file mode 100644 index 000000000..ac54c5332 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/cam_zoom_minus_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/cam_zoom_out.tga b/indra/newview/skins/Blackred/textures/cam_zoom_out.tga new file mode 100644 index 000000000..8e6c519a9 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/cam_zoom_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/cam_zoom_plus_in.tga b/indra/newview/skins/Blackred/textures/cam_zoom_plus_in.tga new file mode 100644 index 000000000..cd2960d8e Binary files /dev/null and b/indra/newview/skins/Blackred/textures/cam_zoom_plus_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/ce15fd63-b0b6-463c-a37d-ea6393208b3e.tga b/indra/newview/skins/Blackred/textures/ce15fd63-b0b6-463c-a37d-ea6393208b3e.tga new file mode 100644 index 000000000..3c7cb5594 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/ce15fd63-b0b6-463c-a37d-ea6393208b3e.tga differ diff --git a/indra/newview/skins/Blackred/textures/checkbox_disabled_false.tga b/indra/newview/skins/Blackred/textures/checkbox_disabled_false.tga new file mode 100644 index 000000000..aa57cd211 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/checkbox_disabled_false.tga differ diff --git a/indra/newview/skins/Blackred/textures/checkbox_disabled_true.tga b/indra/newview/skins/Blackred/textures/checkbox_disabled_true.tga new file mode 100644 index 000000000..a198113bc Binary files /dev/null and b/indra/newview/skins/Blackred/textures/checkbox_disabled_true.tga differ diff --git a/indra/newview/skins/Blackred/textures/checkbox_enabled_false.tga b/indra/newview/skins/Blackred/textures/checkbox_enabled_false.tga new file mode 100644 index 000000000..fb8265b18 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/checkbox_enabled_false.tga differ diff --git a/indra/newview/skins/Blackred/textures/checkbox_enabled_true.tga b/indra/newview/skins/Blackred/textures/checkbox_enabled_true.tga new file mode 100644 index 000000000..59d67abdf Binary files /dev/null and b/indra/newview/skins/Blackred/textures/checkbox_enabled_true.tga differ diff --git a/indra/newview/skins/Blackred/textures/close_in_blue.tga b/indra/newview/skins/Blackred/textures/close_in_blue.tga new file mode 100644 index 000000000..c58e052b8 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/close_in_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/close_inactive_blue.tga b/indra/newview/skins/Blackred/textures/close_inactive_blue.tga new file mode 100644 index 000000000..2f912df59 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/close_inactive_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/closebox.tga b/indra/newview/skins/Blackred/textures/closebox.tga new file mode 100644 index 000000000..5e1195526 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/closebox.tga differ diff --git a/indra/newview/skins/Blackred/textures/combobox_arrow.tga b/indra/newview/skins/Blackred/textures/combobox_arrow.tga new file mode 100644 index 000000000..3c01e32d2 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/combobox_arrow.tga differ diff --git a/indra/newview/skins/Blackred/textures/d07f6eed-b96a-47cd-b51d-400ad4a1c428.j2c b/indra/newview/skins/Blackred/textures/d07f6eed-b96a-47cd-b51d-400ad4a1c428.j2c new file mode 100644 index 000000000..4b73b25ac Binary files /dev/null and b/indra/newview/skins/Blackred/textures/d07f6eed-b96a-47cd-b51d-400ad4a1c428.j2c differ diff --git a/indra/newview/skins/Blackred/textures/darkgray.tga b/indra/newview/skins/Blackred/textures/darkgray.tga new file mode 100644 index 000000000..e69be0893 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/darkgray.tga differ diff --git a/indra/newview/skins/Blackred/textures/default_land_picture.j2c b/indra/newview/skins/Blackred/textures/default_land_picture.j2c new file mode 100644 index 000000000..6e2a85a46 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/default_land_picture.j2c differ diff --git a/indra/newview/skins/Blackred/textures/default_profile_picture.j2c b/indra/newview/skins/Blackred/textures/default_profile_picture.j2c new file mode 100644 index 000000000..31d741e88 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/default_profile_picture.j2c differ diff --git a/indra/newview/skins/Blackred/textures/direction_arrow.tga b/indra/newview/skins/Blackred/textures/direction_arrow.tga new file mode 100644 index 000000000..59149e1d5 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/direction_arrow.tga differ diff --git a/indra/newview/skins/Blackred/textures/down_arrow.png b/indra/newview/skins/Blackred/textures/down_arrow.png new file mode 100644 index 000000000..abd706481 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/down_arrow.png differ diff --git a/indra/newview/skins/Blackred/textures/eye_button_active.tga b/indra/newview/skins/Blackred/textures/eye_button_active.tga new file mode 100644 index 000000000..d0f7f6a3f Binary files /dev/null and b/indra/newview/skins/Blackred/textures/eye_button_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/eye_button_inactive.tga b/indra/newview/skins/Blackred/textures/eye_button_inactive.tga new file mode 100644 index 000000000..7e7ca0619 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/eye_button_inactive.tga differ diff --git a/indra/newview/skins/Blackred/textures/ff9a71eb-7414-4cf8-866e-a701deb7c3cf.tga b/indra/newview/skins/Blackred/textures/ff9a71eb-7414-4cf8-866e-a701deb7c3cf.tga new file mode 100644 index 000000000..534ecba91 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/ff9a71eb-7414-4cf8-866e-a701deb7c3cf.tga differ diff --git a/indra/newview/skins/Blackred/textures/ff_edit_mine_button.tga b/indra/newview/skins/Blackred/textures/ff_edit_mine_button.tga new file mode 100644 index 000000000..0398bbae1 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/ff_edit_mine_button.tga differ diff --git a/indra/newview/skins/Blackred/textures/ff_edit_theirs_button.tga b/indra/newview/skins/Blackred/textures/ff_edit_theirs_button.tga new file mode 100644 index 000000000..06109c1d2 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/ff_edit_theirs_button.tga differ diff --git a/indra/newview/skins/Blackred/textures/ff_online_status_button.tga b/indra/newview/skins/Blackred/textures/ff_online_status_button.tga new file mode 100644 index 000000000..0cc4d4f10 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/ff_online_status_button.tga differ diff --git a/indra/newview/skins/Blackred/textures/ff_visible_map_button.tga b/indra/newview/skins/Blackred/textures/ff_visible_map_button.tga new file mode 100644 index 000000000..7daf492f8 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/ff_visible_map_button.tga differ diff --git a/indra/newview/skins/Blackred/textures/ff_visible_online_button.tga b/indra/newview/skins/Blackred/textures/ff_visible_online_button.tga new file mode 100644 index 000000000..8a18d4d44 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/ff_visible_online_button.tga differ diff --git a/indra/newview/skins/Blackred/textures/flyout_btn_left.tga b/indra/newview/skins/Blackred/textures/flyout_btn_left.tga new file mode 100644 index 000000000..eeb4e944b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/flyout_btn_left.tga differ diff --git a/indra/newview/skins/Blackred/textures/flyout_btn_left_disabled.tga b/indra/newview/skins/Blackred/textures/flyout_btn_left_disabled.tga new file mode 100644 index 000000000..eeb4e944b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/flyout_btn_left_disabled.tga differ diff --git a/indra/newview/skins/Blackred/textures/flyout_btn_left_selected.tga b/indra/newview/skins/Blackred/textures/flyout_btn_left_selected.tga new file mode 100644 index 000000000..67df7dc38 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/flyout_btn_left_selected.tga differ diff --git a/indra/newview/skins/Blackred/textures/flyout_btn_right.tga b/indra/newview/skins/Blackred/textures/flyout_btn_right.tga new file mode 100644 index 000000000..2f4a5bbec Binary files /dev/null and b/indra/newview/skins/Blackred/textures/flyout_btn_right.tga differ diff --git a/indra/newview/skins/Blackred/textures/flyout_btn_right_disabled.tga b/indra/newview/skins/Blackred/textures/flyout_btn_right_disabled.tga new file mode 100644 index 000000000..2f4a5bbec Binary files /dev/null and b/indra/newview/skins/Blackred/textures/flyout_btn_right_disabled.tga differ diff --git a/indra/newview/skins/Blackred/textures/flyout_btn_right_selected.tga b/indra/newview/skins/Blackred/textures/flyout_btn_right_selected.tga new file mode 100644 index 000000000..36f63c3de Binary files /dev/null and b/indra/newview/skins/Blackred/textures/flyout_btn_right_selected.tga differ diff --git a/indra/newview/skins/Blackred/textures/flyout_left.tga b/indra/newview/skins/Blackred/textures/flyout_left.tga new file mode 100644 index 000000000..4503ddf8c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/flyout_left.tga differ diff --git a/indra/newview/skins/Blackred/textures/flyout_left_disabled.tga b/indra/newview/skins/Blackred/textures/flyout_left_disabled.tga new file mode 100644 index 000000000..4503ddf8c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/flyout_left_disabled.tga differ diff --git a/indra/newview/skins/Blackred/textures/flyout_left_selected.tga b/indra/newview/skins/Blackred/textures/flyout_left_selected.tga new file mode 100644 index 000000000..7552ba6ed Binary files /dev/null and b/indra/newview/skins/Blackred/textures/flyout_left_selected.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_media-pause_active.tga b/indra/newview/skins/Blackred/textures/icn_media-pause_active.tga new file mode 100644 index 000000000..8988829aa Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_media-pause_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_media-pause_disabled.tga b/indra/newview/skins/Blackred/textures/icn_media-pause_disabled.tga new file mode 100644 index 000000000..4690f4256 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_media-pause_disabled.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_media-pause_enabled.tga b/indra/newview/skins/Blackred/textures/icn_media-pause_enabled.tga new file mode 100644 index 000000000..c01399e27 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_media-pause_enabled.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_media-play_enabled.tga b/indra/newview/skins/Blackred/textures/icn_media-play_enabled.tga new file mode 100644 index 000000000..accac38b0 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_media-play_enabled.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_media-stop_enabled.tga b/indra/newview/skins/Blackred/textures/icn_media-stop_enabled.tga new file mode 100644 index 000000000..d935fa317 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_media-stop_enabled.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_media.tga b/indra/newview/skins/Blackred/textures/icn_media.tga new file mode 100644 index 000000000..2a035ba5d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_media.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_music.tga b/indra/newview/skins/Blackred/textures/icn_music.tga new file mode 100644 index 000000000..81da5abcf Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_music.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_rounded-text-field.tga b/indra/newview/skins/Blackred/textures/icn_rounded-text-field.tga new file mode 100644 index 000000000..1f1e72572 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_rounded-text-field.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_slide-groove_dark.tga b/indra/newview/skins/Blackred/textures/icn_slide-groove_dark.tga new file mode 100644 index 000000000..96a247ad9 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_slide-groove_dark.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_slide-highlight.tga b/indra/newview/skins/Blackred/textures/icn_slide-highlight.tga new file mode 100644 index 000000000..d371cd066 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_slide-highlight.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_slide-thumb_dark.tga b/indra/newview/skins/Blackred/textures/icn_slide-thumb_dark.tga new file mode 100644 index 000000000..452cdc6d1 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_slide-thumb_dark.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_speaker-muted_dark.tga b/indra/newview/skins/Blackred/textures/icn_speaker-muted_dark.tga new file mode 100644 index 000000000..8f2c80dd2 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_speaker-muted_dark.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_toolbar_radar.tga b/indra/newview/skins/Blackred/textures/icn_toolbar_radar.tga new file mode 100644 index 000000000..d1a55ed74 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_toolbar_radar.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_voice-call-end.tga b/indra/newview/skins/Blackred/textures/icn_voice-call-end.tga new file mode 100644 index 000000000..84056b90a Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_voice-call-end.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_voice-call-start.tga b/indra/newview/skins/Blackred/textures/icn_voice-call-start.tga new file mode 100644 index 000000000..7babfd318 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_voice-call-start.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_voice-groupfocus.tga b/indra/newview/skins/Blackred/textures/icn_voice-groupfocus.tga new file mode 100644 index 000000000..913bd0969 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_voice-groupfocus.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_voice-localchat.tga b/indra/newview/skins/Blackred/textures/icn_voice-localchat.tga new file mode 100644 index 000000000..5c1456602 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_voice-localchat.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_voice-pvtfocus.tga b/indra/newview/skins/Blackred/textures/icn_voice-pvtfocus.tga new file mode 100644 index 000000000..76e72fd3a Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_voice-pvtfocus.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_voice_ptt-off.tga b/indra/newview/skins/Blackred/textures/icn_voice_ptt-off.tga new file mode 100644 index 000000000..530425dd7 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_voice_ptt-off.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_voice_ptt-on-lvl1.tga b/indra/newview/skins/Blackred/textures/icn_voice_ptt-on-lvl1.tga new file mode 100644 index 000000000..818c58915 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_voice_ptt-on-lvl1.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_voice_ptt-on-lvl2.tga b/indra/newview/skins/Blackred/textures/icn_voice_ptt-on-lvl2.tga new file mode 100644 index 000000000..48d44b10a Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_voice_ptt-on-lvl2.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_voice_ptt-on-lvl3.tga b/indra/newview/skins/Blackred/textures/icn_voice_ptt-on-lvl3.tga new file mode 100644 index 000000000..081265efb Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_voice_ptt-on-lvl3.tga differ diff --git a/indra/newview/skins/Blackred/textures/icn_voice_ptt-on.tga b/indra/newview/skins/Blackred/textures/icn_voice_ptt-on.tga new file mode 100644 index 000000000..8ce21f4a6 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icn_voice_ptt-on.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_auction.tga b/indra/newview/skins/Blackred/textures/icon_auction.tga new file mode 100644 index 000000000..3aa21d323 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_auction.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_avatar_offline.tga b/indra/newview/skins/Blackred/textures/icon_avatar_offline.tga new file mode 100644 index 000000000..620e0f7c1 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_avatar_offline.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_avatar_online.tga b/indra/newview/skins/Blackred/textures/icon_avatar_online.tga new file mode 100644 index 000000000..6350237ee Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_avatar_online.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_event.tga b/indra/newview/skins/Blackred/textures/icon_event.tga new file mode 100644 index 000000000..23f246b91 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_event.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_event_adult.tga b/indra/newview/skins/Blackred/textures/icon_event_adult.tga new file mode 100644 index 000000000..7202e6734 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_event_adult.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_event_mature.tga b/indra/newview/skins/Blackred/textures/icon_event_mature.tga new file mode 100644 index 000000000..103c5e535 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_event_mature.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_for_sale.tga b/indra/newview/skins/Blackred/textures/icon_for_sale.tga new file mode 100644 index 000000000..09405d383 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_for_sale.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_for_sale_adult.tga b/indra/newview/skins/Blackred/textures/icon_for_sale_adult.tga new file mode 100644 index 000000000..147f724e7 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_for_sale_adult.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_group.tga b/indra/newview/skins/Blackred/textures/icon_group.tga new file mode 100644 index 000000000..1e5c31aa3 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_group.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_groupnotice.tga b/indra/newview/skins/Blackred/textures/icon_groupnotice.tga new file mode 100644 index 000000000..a3e35a0bf Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_groupnotice.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_groupnoticeinventory.tga b/indra/newview/skins/Blackred/textures/icon_groupnoticeinventory.tga new file mode 100644 index 000000000..780d6fadd Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_groupnoticeinventory.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_lock.tga b/indra/newview/skins/Blackred/textures/icon_lock.tga new file mode 100644 index 000000000..5de6cc10e Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_lock.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_place.tga b/indra/newview/skins/Blackred/textures/icon_place.tga new file mode 100644 index 000000000..7f842ba65 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_place.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_popular.tga b/indra/newview/skins/Blackred/textures/icon_popular.tga new file mode 100644 index 000000000..6bdc6ede3 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_popular.tga differ diff --git a/indra/newview/skins/Blackred/textures/icon_top_pick.tga b/indra/newview/skins/Blackred/textures/icon_top_pick.tga new file mode 100644 index 000000000..4466e8be7 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/icon_top_pick.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_animation.tga b/indra/newview/skins/Blackred/textures/inv_folder_animation.tga new file mode 100644 index 000000000..2054a466d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_animation.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_bodypart.tga b/indra/newview/skins/Blackred/textures/inv_folder_bodypart.tga new file mode 100644 index 000000000..9a17c90b8 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_bodypart.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_callingcard.tga b/indra/newview/skins/Blackred/textures/inv_folder_callingcard.tga new file mode 100644 index 000000000..514cc6095 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_callingcard.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_clothing.tga b/indra/newview/skins/Blackred/textures/inv_folder_clothing.tga new file mode 100644 index 000000000..c61e15c66 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_clothing.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_gesture.tga b/indra/newview/skins/Blackred/textures/inv_folder_gesture.tga new file mode 100644 index 000000000..761b1b87b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_gesture.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_landmark.tga b/indra/newview/skins/Blackred/textures/inv_folder_landmark.tga new file mode 100644 index 000000000..94bf17e62 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_landmark.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_lostandfound.tga b/indra/newview/skins/Blackred/textures/inv_folder_lostandfound.tga new file mode 100644 index 000000000..c31b71f15 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_lostandfound.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_notecard.tga b/indra/newview/skins/Blackred/textures/inv_folder_notecard.tga new file mode 100644 index 000000000..8fe38da90 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_notecard.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_object.tga b/indra/newview/skins/Blackred/textures/inv_folder_object.tga new file mode 100644 index 000000000..56bce2ca0 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_object.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_plain_closed.tga b/indra/newview/skins/Blackred/textures/inv_folder_plain_closed.tga new file mode 100644 index 000000000..28c78ce39 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_plain_closed.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_plain_open.tga b/indra/newview/skins/Blackred/textures/inv_folder_plain_open.tga new file mode 100644 index 000000000..baf6db64a Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_plain_open.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_script.tga b/indra/newview/skins/Blackred/textures/inv_folder_script.tga new file mode 100644 index 000000000..b42b464fa Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_script.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_snapshot.tga b/indra/newview/skins/Blackred/textures/inv_folder_snapshot.tga new file mode 100644 index 000000000..d3c02d31d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_snapshot.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_sound.tga b/indra/newview/skins/Blackred/textures/inv_folder_sound.tga new file mode 100644 index 000000000..d7cf45f11 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_sound.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_texture.tga b/indra/newview/skins/Blackred/textures/inv_folder_texture.tga new file mode 100644 index 000000000..684ca9d43 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_texture.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_folder_trash.tga b/indra/newview/skins/Blackred/textures/inv_folder_trash.tga new file mode 100644 index 000000000..50ad9dacd Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_folder_trash.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_animation.tga b/indra/newview/skins/Blackred/textures/inv_item_animation.tga new file mode 100644 index 000000000..1269e7c7b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_animation.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_attach.tga b/indra/newview/skins/Blackred/textures/inv_item_attach.tga new file mode 100644 index 000000000..38204e590 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_attach.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_callingcard_offline.tga b/indra/newview/skins/Blackred/textures/inv_item_callingcard_offline.tga new file mode 100644 index 000000000..7373451db Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_callingcard_offline.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_callingcard_online.tga b/indra/newview/skins/Blackred/textures/inv_item_callingcard_online.tga new file mode 100644 index 000000000..602648494 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_callingcard_online.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_clothing.tga b/indra/newview/skins/Blackred/textures/inv_item_clothing.tga new file mode 100644 index 000000000..0dd6ddb90 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_clothing.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_eyes.tga b/indra/newview/skins/Blackred/textures/inv_item_eyes.tga new file mode 100644 index 000000000..c75ebbccf Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_eyes.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_gesture.tga b/indra/newview/skins/Blackred/textures/inv_item_gesture.tga new file mode 100644 index 000000000..45e94bb0f Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_gesture.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_gloves.tga b/indra/newview/skins/Blackred/textures/inv_item_gloves.tga new file mode 100644 index 000000000..f380dd9af Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_gloves.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_hair.tga b/indra/newview/skins/Blackred/textures/inv_item_hair.tga new file mode 100644 index 000000000..dce7798af Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_hair.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_jacket.tga b/indra/newview/skins/Blackred/textures/inv_item_jacket.tga new file mode 100644 index 000000000..af742f687 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_jacket.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_landmark.tga b/indra/newview/skins/Blackred/textures/inv_item_landmark.tga new file mode 100644 index 000000000..db67487fb Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_landmark.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_landmark_visited.tga b/indra/newview/skins/Blackred/textures/inv_item_landmark_visited.tga new file mode 100644 index 000000000..c74745070 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_landmark_visited.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_notecard.tga b/indra/newview/skins/Blackred/textures/inv_item_notecard.tga new file mode 100644 index 000000000..c7d3decc8 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_notecard.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_object.tga b/indra/newview/skins/Blackred/textures/inv_item_object.tga new file mode 100644 index 000000000..8431a6081 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_object.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_object_multi.tga b/indra/newview/skins/Blackred/textures/inv_item_object_multi.tga new file mode 100644 index 000000000..f1485c0ae Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_object_multi.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_pants.tga b/indra/newview/skins/Blackred/textures/inv_item_pants.tga new file mode 100644 index 000000000..fc2f1779c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_pants.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_script.tga b/indra/newview/skins/Blackred/textures/inv_item_script.tga new file mode 100644 index 000000000..1ac3df150 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_script.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_script_dangerous.tga b/indra/newview/skins/Blackred/textures/inv_item_script_dangerous.tga new file mode 100644 index 000000000..613f80445 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_script_dangerous.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_shape.tga b/indra/newview/skins/Blackred/textures/inv_item_shape.tga new file mode 100644 index 000000000..fb78f6c6f Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_shape.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_shirt.tga b/indra/newview/skins/Blackred/textures/inv_item_shirt.tga new file mode 100644 index 000000000..0dd6ddb90 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_shirt.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_shoes.tga b/indra/newview/skins/Blackred/textures/inv_item_shoes.tga new file mode 100644 index 000000000..c46fddc01 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_shoes.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_skin.tga b/indra/newview/skins/Blackred/textures/inv_item_skin.tga new file mode 100644 index 000000000..9e9b952a9 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_skin.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_skirt.tga b/indra/newview/skins/Blackred/textures/inv_item_skirt.tga new file mode 100644 index 000000000..cf1b928f4 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_skirt.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_snapshot.tga b/indra/newview/skins/Blackred/textures/inv_item_snapshot.tga new file mode 100644 index 000000000..59e032d8e Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_snapshot.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_socks.tga b/indra/newview/skins/Blackred/textures/inv_item_socks.tga new file mode 100644 index 000000000..2b80ebca0 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_socks.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_sound.tga b/indra/newview/skins/Blackred/textures/inv_item_sound.tga new file mode 100644 index 000000000..d43a10e1d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_sound.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_texture.tga b/indra/newview/skins/Blackred/textures/inv_item_texture.tga new file mode 100644 index 000000000..ede9fd9a8 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_texture.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_underpants.tga b/indra/newview/skins/Blackred/textures/inv_item_underpants.tga new file mode 100644 index 000000000..abcffc3bd Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_underpants.tga differ diff --git a/indra/newview/skins/Blackred/textures/inv_item_undershirt.tga b/indra/newview/skins/Blackred/textures/inv_item_undershirt.tga new file mode 100644 index 000000000..22c47f8df Binary files /dev/null and b/indra/newview/skins/Blackred/textures/inv_item_undershirt.tga differ diff --git a/indra/newview/skins/Blackred/textures/lightgray.tga b/indra/newview/skins/Blackred/textures/lightgray.tga new file mode 100644 index 000000000..e69be0893 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/lightgray.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_avatar_16.tga b/indra/newview/skins/Blackred/textures/map_avatar_16.tga new file mode 100644 index 000000000..42d8c1e29 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_avatar_16.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_avatar_8.tga b/indra/newview/skins/Blackred/textures/map_avatar_8.tga new file mode 100644 index 000000000..7eb7c20f1 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_avatar_8.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_avatar_above_8.tga b/indra/newview/skins/Blackred/textures/map_avatar_above_8.tga new file mode 100644 index 000000000..6faefccc7 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_avatar_above_8.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_avatar_below_8.tga b/indra/newview/skins/Blackred/textures/map_avatar_below_8.tga new file mode 100644 index 000000000..5ad671c26 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_avatar_below_8.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_avatar_you_8.tga b/indra/newview/skins/Blackred/textures/map_avatar_you_8.tga new file mode 100644 index 000000000..673b30e19 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_avatar_you_8.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_event.tga b/indra/newview/skins/Blackred/textures/map_event.tga new file mode 100644 index 000000000..103c5e535 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_event.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_event_adult.tga b/indra/newview/skins/Blackred/textures/map_event_adult.tga new file mode 100644 index 000000000..7202e6734 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_event_adult.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_event_mature.tga b/indra/newview/skins/Blackred/textures/map_event_mature.tga new file mode 100644 index 000000000..23f246b91 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_event_mature.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_home.tga b/indra/newview/skins/Blackred/textures/map_home.tga new file mode 100644 index 000000000..85dde9ef7 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_home.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_infohub.tga b/indra/newview/skins/Blackred/textures/map_infohub.tga new file mode 100644 index 000000000..173b93e39 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_infohub.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_telehub.tga b/indra/newview/skins/Blackred/textures/map_telehub.tga new file mode 100644 index 000000000..d89bcfa40 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_telehub.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_track_16.tga b/indra/newview/skins/Blackred/textures/map_track_16.tga new file mode 100644 index 000000000..14d49b93b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_track_16.tga differ diff --git a/indra/newview/skins/Blackred/textures/map_track_8.tga b/indra/newview/skins/Blackred/textures/map_track_8.tga new file mode 100644 index 000000000..d9605dde1 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/map_track_8.tga differ diff --git a/indra/newview/skins/Blackred/textures/minimize.tga b/indra/newview/skins/Blackred/textures/minimize.tga new file mode 100644 index 000000000..151a3078f Binary files /dev/null and b/indra/newview/skins/Blackred/textures/minimize.tga differ diff --git a/indra/newview/skins/Blackred/textures/minimize_inactive.tga b/indra/newview/skins/Blackred/textures/minimize_inactive.tga new file mode 100644 index 000000000..d7e1b4057 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/minimize_inactive.tga differ diff --git a/indra/newview/skins/Blackred/textures/minimize_pressed.tga b/indra/newview/skins/Blackred/textures/minimize_pressed.tga new file mode 100644 index 000000000..573452ce9 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/minimize_pressed.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_backward_in.tga b/indra/newview/skins/Blackred/textures/move_backward_in.tga new file mode 100644 index 000000000..8fe21404c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_backward_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_backward_out.tga b/indra/newview/skins/Blackred/textures/move_backward_out.tga new file mode 100644 index 000000000..f46c021f9 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_backward_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_down_in.tga b/indra/newview/skins/Blackred/textures/move_down_in.tga new file mode 100644 index 000000000..6405730ff Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_down_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_down_out.tga b/indra/newview/skins/Blackred/textures/move_down_out.tga new file mode 100644 index 000000000..8d3efee37 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_down_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_forward_in.tga b/indra/newview/skins/Blackred/textures/move_forward_in.tga new file mode 100644 index 000000000..ba3454a95 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_forward_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_forward_out.tga b/indra/newview/skins/Blackred/textures/move_forward_out.tga new file mode 100644 index 000000000..67e407a41 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_forward_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_left_in.tga b/indra/newview/skins/Blackred/textures/move_left_in.tga new file mode 100644 index 000000000..11109bff1 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_left_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_left_out.tga b/indra/newview/skins/Blackred/textures/move_left_out.tga new file mode 100644 index 000000000..a2ea88a82 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_left_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_right_in.tga b/indra/newview/skins/Blackred/textures/move_right_in.tga new file mode 100644 index 000000000..2634947d2 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_right_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_right_out.tga b/indra/newview/skins/Blackred/textures/move_right_out.tga new file mode 100644 index 000000000..cab385318 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_right_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_turn_left_in.tga b/indra/newview/skins/Blackred/textures/move_turn_left_in.tga new file mode 100644 index 000000000..5dc8a0e6b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_turn_left_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_turn_left_out.tga b/indra/newview/skins/Blackred/textures/move_turn_left_out.tga new file mode 100644 index 000000000..00c4bfebe Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_turn_left_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_turn_right_in.tga b/indra/newview/skins/Blackred/textures/move_turn_right_in.tga new file mode 100644 index 000000000..17ddb7b72 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_turn_right_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_turn_right_out.tga b/indra/newview/skins/Blackred/textures/move_turn_right_out.tga new file mode 100644 index 000000000..c26cb2c2c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_turn_right_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_up_in.tga b/indra/newview/skins/Blackred/textures/move_up_in.tga new file mode 100644 index 000000000..251a561bf Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_up_in.tga differ diff --git a/indra/newview/skins/Blackred/textures/move_up_out.tga b/indra/newview/skins/Blackred/textures/move_up_out.tga new file mode 100644 index 000000000..e1e377d09 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/move_up_out.tga differ diff --git a/indra/newview/skins/Blackred/textures/notify_box_icon.tga b/indra/newview/skins/Blackred/textures/notify_box_icon.tga new file mode 100644 index 000000000..880aca9b4 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/notify_box_icon.tga differ diff --git a/indra/newview/skins/Blackred/textures/notify_caution_icon.tga b/indra/newview/skins/Blackred/textures/notify_caution_icon.tga new file mode 100644 index 000000000..ac6660c16 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/notify_caution_icon.tga differ diff --git a/indra/newview/skins/Blackred/textures/notify_next.png b/indra/newview/skins/Blackred/textures/notify_next.png new file mode 100644 index 000000000..9b371e03e Binary files /dev/null and b/indra/newview/skins/Blackred/textures/notify_next.png differ diff --git a/indra/newview/skins/Blackred/textures/notify_tip_icon.tga b/indra/newview/skins/Blackred/textures/notify_tip_icon.tga new file mode 100644 index 000000000..0451da099 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/notify_tip_icon.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_cone.tga b/indra/newview/skins/Blackred/textures/object_cone.tga new file mode 100644 index 000000000..943433322 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_cone.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_cone_active.tga b/indra/newview/skins/Blackred/textures/object_cone_active.tga new file mode 100644 index 000000000..44055b403 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_cone_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_cube.tga b/indra/newview/skins/Blackred/textures/object_cube.tga new file mode 100644 index 000000000..d62bdb89c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_cube.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_cube_active.tga b/indra/newview/skins/Blackred/textures/object_cube_active.tga new file mode 100644 index 000000000..07ca2cd7c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_cube_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_cylinder.tga b/indra/newview/skins/Blackred/textures/object_cylinder.tga new file mode 100644 index 000000000..82bf54261 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_cylinder.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_cylinder_active.tga b/indra/newview/skins/Blackred/textures/object_cylinder_active.tga new file mode 100644 index 000000000..2ab658cbb Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_cylinder_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_grass.tga b/indra/newview/skins/Blackred/textures/object_grass.tga new file mode 100644 index 000000000..6f91db20d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_grass.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_grass_active.tga b/indra/newview/skins/Blackred/textures/object_grass_active.tga new file mode 100644 index 000000000..58f54ac9b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_grass_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_hemi_cone.tga b/indra/newview/skins/Blackred/textures/object_hemi_cone.tga new file mode 100644 index 000000000..44ce6d4be Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_hemi_cone.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_hemi_cone_active.tga b/indra/newview/skins/Blackred/textures/object_hemi_cone_active.tga new file mode 100644 index 000000000..011206ec5 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_hemi_cone_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_hemi_cylinder.tga b/indra/newview/skins/Blackred/textures/object_hemi_cylinder.tga new file mode 100644 index 000000000..1d1eca748 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_hemi_cylinder.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_hemi_cylinder_active.tga b/indra/newview/skins/Blackred/textures/object_hemi_cylinder_active.tga new file mode 100644 index 000000000..24f68e9f9 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_hemi_cylinder_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_hemi_sphere.tga b/indra/newview/skins/Blackred/textures/object_hemi_sphere.tga new file mode 100644 index 000000000..fbce7dcfc Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_hemi_sphere.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_hemi_sphere_active.tga b/indra/newview/skins/Blackred/textures/object_hemi_sphere_active.tga new file mode 100644 index 000000000..a9a0e6939 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_hemi_sphere_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_prism.tga b/indra/newview/skins/Blackred/textures/object_prism.tga new file mode 100644 index 000000000..e5586d59e Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_prism.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_prism_active.tga b/indra/newview/skins/Blackred/textures/object_prism_active.tga new file mode 100644 index 000000000..961efc9bd Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_prism_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_pyramid.tga b/indra/newview/skins/Blackred/textures/object_pyramid.tga new file mode 100644 index 000000000..bbf8164ce Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_pyramid.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_pyramid_active.tga b/indra/newview/skins/Blackred/textures/object_pyramid_active.tga new file mode 100644 index 000000000..fec59ac62 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_pyramid_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_ring.tga b/indra/newview/skins/Blackred/textures/object_ring.tga new file mode 100644 index 000000000..37d242f41 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_ring.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_ring_active.tga b/indra/newview/skins/Blackred/textures/object_ring_active.tga new file mode 100644 index 000000000..ba9e01c81 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_ring_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_sphere.tga b/indra/newview/skins/Blackred/textures/object_sphere.tga new file mode 100644 index 000000000..3d6d9ca39 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_sphere.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_sphere_active.tga b/indra/newview/skins/Blackred/textures/object_sphere_active.tga new file mode 100644 index 000000000..201006ddb Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_sphere_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_tetrahedron.tga b/indra/newview/skins/Blackred/textures/object_tetrahedron.tga new file mode 100644 index 000000000..4808cb3f3 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_tetrahedron.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_tetrahedron_active.tga b/indra/newview/skins/Blackred/textures/object_tetrahedron_active.tga new file mode 100644 index 000000000..ddbf9ddfb Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_tetrahedron_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_torus.tga b/indra/newview/skins/Blackred/textures/object_torus.tga new file mode 100644 index 000000000..70154676b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_torus.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_torus_active.tga b/indra/newview/skins/Blackred/textures/object_torus_active.tga new file mode 100644 index 000000000..99ef2666b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_torus_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_tree.tga b/indra/newview/skins/Blackred/textures/object_tree.tga new file mode 100644 index 000000000..246ad80f6 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_tree.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_tree_active.tga b/indra/newview/skins/Blackred/textures/object_tree_active.tga new file mode 100644 index 000000000..1adf9c3f3 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_tree_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_tube.tga b/indra/newview/skins/Blackred/textures/object_tube.tga new file mode 100644 index 000000000..15e0a1c3d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_tube.tga differ diff --git a/indra/newview/skins/Blackred/textures/object_tube_active.tga b/indra/newview/skins/Blackred/textures/object_tube_active.tga new file mode 100644 index 000000000..d382e740e Binary files /dev/null and b/indra/newview/skins/Blackred/textures/object_tube_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/preview.png b/indra/newview/skins/Blackred/textures/preview.png new file mode 100644 index 000000000..294a6a03a Binary files /dev/null and b/indra/newview/skins/Blackred/textures/preview.png differ diff --git a/indra/newview/skins/Blackred/textures/progress_fill.tga b/indra/newview/skins/Blackred/textures/progress_fill.tga new file mode 100644 index 000000000..bbdf5dd0b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/progress_fill.tga differ diff --git a/indra/newview/skins/Blackred/textures/progressbar_fill.tga b/indra/newview/skins/Blackred/textures/progressbar_fill.tga new file mode 100644 index 000000000..03601c432 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/progressbar_fill.tga differ diff --git a/indra/newview/skins/Blackred/textures/progressbar_track.tga b/indra/newview/skins/Blackred/textures/progressbar_track.tga new file mode 100644 index 000000000..4b84e9ec9 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/progressbar_track.tga differ diff --git a/indra/newview/skins/Blackred/textures/ptt_lock_off.tga b/indra/newview/skins/Blackred/textures/ptt_lock_off.tga new file mode 100644 index 000000000..d66f49840 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/ptt_lock_off.tga differ diff --git a/indra/newview/skins/Blackred/textures/ptt_lock_on.tga b/indra/newview/skins/Blackred/textures/ptt_lock_on.tga new file mode 100644 index 000000000..432db2f00 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/ptt_lock_on.tga differ diff --git a/indra/newview/skins/Blackred/textures/radio_active_false.tga b/indra/newview/skins/Blackred/textures/radio_active_false.tga new file mode 100644 index 000000000..c3a3c2951 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/radio_active_false.tga differ diff --git a/indra/newview/skins/Blackred/textures/radio_active_true.tga b/indra/newview/skins/Blackred/textures/radio_active_true.tga new file mode 100644 index 000000000..9c03e4f16 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/radio_active_true.tga differ diff --git a/indra/newview/skins/Blackred/textures/radio_inactive_false.tga b/indra/newview/skins/Blackred/textures/radio_inactive_false.tga new file mode 100644 index 000000000..5154d2511 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/radio_inactive_false.tga differ diff --git a/indra/newview/skins/Blackred/textures/radio_inactive_true.tga b/indra/newview/skins/Blackred/textures/radio_inactive_true.tga new file mode 100644 index 000000000..c1b5c829f Binary files /dev/null and b/indra/newview/skins/Blackred/textures/radio_inactive_true.tga differ diff --git a/indra/newview/skins/Blackred/textures/resize_handle_bottom_right_blue.tga b/indra/newview/skins/Blackred/textures/resize_handle_bottom_right_blue.tga new file mode 100644 index 000000000..8290bfa65 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/resize_handle_bottom_right_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/restore.tga b/indra/newview/skins/Blackred/textures/restore.tga new file mode 100644 index 000000000..5e369fdfc Binary files /dev/null and b/indra/newview/skins/Blackred/textures/restore.tga differ diff --git a/indra/newview/skins/Blackred/textures/restore_inactive.tga b/indra/newview/skins/Blackred/textures/restore_inactive.tga new file mode 100644 index 000000000..ce545d90d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/restore_inactive.tga differ diff --git a/indra/newview/skins/Blackred/textures/restore_pressed.tga b/indra/newview/skins/Blackred/textures/restore_pressed.tga new file mode 100644 index 000000000..8a25087be Binary files /dev/null and b/indra/newview/skins/Blackred/textures/restore_pressed.tga differ diff --git a/indra/newview/skins/Blackred/textures/rounded_square.j2c b/indra/newview/skins/Blackred/textures/rounded_square.j2c new file mode 100644 index 000000000..c3dfe8f10 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/rounded_square.j2c differ diff --git a/indra/newview/skins/Blackred/textures/rounded_square.tga b/indra/newview/skins/Blackred/textures/rounded_square.tga new file mode 100644 index 000000000..4f4bf05f8 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/rounded_square.tga differ diff --git a/indra/newview/skins/Blackred/textures/rounded_square_soft.tga b/indra/newview/skins/Blackred/textures/rounded_square_soft.tga new file mode 100644 index 000000000..4f4bf05f8 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/rounded_square_soft.tga differ diff --git a/indra/newview/skins/Blackred/textures/script_error.j2c b/indra/newview/skins/Blackred/textures/script_error.j2c new file mode 100644 index 000000000..ad6be04a7 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/script_error.j2c differ diff --git a/indra/newview/skins/Blackred/textures/script_error.tga b/indra/newview/skins/Blackred/textures/script_error.tga new file mode 100644 index 000000000..8fa12e711 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/script_error.tga differ diff --git a/indra/newview/skins/Blackred/textures/scrollbutton_down_in_blue.tga b/indra/newview/skins/Blackred/textures/scrollbutton_down_in_blue.tga new file mode 100644 index 000000000..3c01e32d2 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/scrollbutton_down_in_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/scrollbutton_down_out_blue.tga b/indra/newview/skins/Blackred/textures/scrollbutton_down_out_blue.tga new file mode 100644 index 000000000..3c01e32d2 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/scrollbutton_down_out_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/scrollbutton_left_in_blue.tga b/indra/newview/skins/Blackred/textures/scrollbutton_left_in_blue.tga new file mode 100644 index 000000000..6e2de5448 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/scrollbutton_left_in_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/scrollbutton_left_out_blue.tga b/indra/newview/skins/Blackred/textures/scrollbutton_left_out_blue.tga new file mode 100644 index 000000000..6e2de5448 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/scrollbutton_left_out_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/scrollbutton_right_in_blue.tga b/indra/newview/skins/Blackred/textures/scrollbutton_right_in_blue.tga new file mode 100644 index 000000000..bd5b99a6e Binary files /dev/null and b/indra/newview/skins/Blackred/textures/scrollbutton_right_in_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/scrollbutton_right_out_blue.tga b/indra/newview/skins/Blackred/textures/scrollbutton_right_out_blue.tga new file mode 100644 index 000000000..bd5b99a6e Binary files /dev/null and b/indra/newview/skins/Blackred/textures/scrollbutton_right_out_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/scrollbutton_up_in_blue.tga b/indra/newview/skins/Blackred/textures/scrollbutton_up_in_blue.tga new file mode 100644 index 000000000..e513eb409 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/scrollbutton_up_in_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/scrollbutton_up_out_blue.tga b/indra/newview/skins/Blackred/textures/scrollbutton_up_out_blue.tga new file mode 100644 index 000000000..e513eb409 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/scrollbutton_up_out_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/sm_rounded_corners_simple.tga b/indra/newview/skins/Blackred/textures/sm_rounded_corners_simple.tga new file mode 100644 index 000000000..054fdd39a Binary files /dev/null and b/indra/newview/skins/Blackred/textures/sm_rounded_corners_simple.tga differ diff --git a/indra/newview/skins/Blackred/textures/spin_down_in_blue.tga b/indra/newview/skins/Blackred/textures/spin_down_in_blue.tga new file mode 100644 index 000000000..c52fbce3a Binary files /dev/null and b/indra/newview/skins/Blackred/textures/spin_down_in_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/spin_down_out_blue.tga b/indra/newview/skins/Blackred/textures/spin_down_out_blue.tga new file mode 100644 index 000000000..1af2ed9cb Binary files /dev/null and b/indra/newview/skins/Blackred/textures/spin_down_out_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/spin_up_in_blue.tga b/indra/newview/skins/Blackred/textures/spin_up_in_blue.tga new file mode 100644 index 000000000..03e45db36 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/spin_up_in_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/spin_up_out_blue.tga b/indra/newview/skins/Blackred/textures/spin_up_out_blue.tga new file mode 100644 index 000000000..9a9bc6468 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/spin_up_out_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/square_btn_32x128.tga b/indra/newview/skins/Blackred/textures/square_btn_32x128.tga new file mode 100644 index 000000000..d23d413aa Binary files /dev/null and b/indra/newview/skins/Blackred/textures/square_btn_32x128.tga differ diff --git a/indra/newview/skins/Blackred/textures/square_btn_selected_32x128.tga b/indra/newview/skins/Blackred/textures/square_btn_selected_32x128.tga new file mode 100644 index 000000000..2f48098d2 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/square_btn_selected_32x128.tga differ diff --git a/indra/newview/skins/Blackred/textures/startup_logo.j2c b/indra/newview/skins/Blackred/textures/startup_logo.j2c new file mode 100644 index 000000000..b28219f36 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/startup_logo.j2c differ diff --git a/indra/newview/skins/Blackred/textures/status_buy_currency.tga b/indra/newview/skins/Blackred/textures/status_buy_currency.tga new file mode 100644 index 000000000..f4a28b32b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_buy_currency.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_buy_currency_pressed.tga b/indra/newview/skins/Blackred/textures/status_buy_currency_pressed.tga new file mode 100644 index 000000000..f4a28b32b Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_buy_currency_pressed.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_buy_land.tga b/indra/newview/skins/Blackred/textures/status_buy_land.tga new file mode 100644 index 000000000..60c395c03 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_buy_land.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_buy_land_pressed.tga b/indra/newview/skins/Blackred/textures/status_buy_land_pressed.tga new file mode 100644 index 000000000..60c395c03 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_buy_land_pressed.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_health.tga b/indra/newview/skins/Blackred/textures/status_health.tga new file mode 100644 index 000000000..f5eefc5a9 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_health.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_no_build.tga b/indra/newview/skins/Blackred/textures/status_no_build.tga new file mode 100644 index 000000000..41934a600 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_no_build.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_no_fly.tga b/indra/newview/skins/Blackred/textures/status_no_fly.tga new file mode 100644 index 000000000..0aa7fa71d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_no_fly.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_no_push.tga b/indra/newview/skins/Blackred/textures/status_no_push.tga new file mode 100644 index 000000000..6d5987217 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_no_push.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_no_scripts.tga b/indra/newview/skins/Blackred/textures/status_no_scripts.tga new file mode 100644 index 000000000..3bce6ad6f Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_no_scripts.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_no_voice.tga b/indra/newview/skins/Blackred/textures/status_no_voice.tga new file mode 100644 index 000000000..aeeed6ed0 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_no_voice.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_script_debug.tga b/indra/newview/skins/Blackred/textures/status_script_debug.tga new file mode 100644 index 000000000..7d895eb0a Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_script_debug.tga differ diff --git a/indra/newview/skins/Blackred/textures/status_search_btn.png b/indra/newview/skins/Blackred/textures/status_search_btn.png new file mode 100644 index 000000000..f6db36fbc Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_search_btn.png differ diff --git a/indra/newview/skins/Blackred/textures/status_search_btn_pressed.png b/indra/newview/skins/Blackred/textures/status_search_btn_pressed.png new file mode 100644 index 000000000..c19945885 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_search_btn_pressed.png differ diff --git a/indra/newview/skins/Blackred/textures/status_voice.tga b/indra/newview/skins/Blackred/textures/status_voice.tga new file mode 100644 index 000000000..aeeed6ed0 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/status_voice.tga differ diff --git a/indra/newview/skins/Blackred/textures/tab_bottom_blue.tga b/indra/newview/skins/Blackred/textures/tab_bottom_blue.tga new file mode 100644 index 000000000..e6de7a5a1 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tab_bottom_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/tab_bottom_selected_blue.tga b/indra/newview/skins/Blackred/textures/tab_bottom_selected_blue.tga new file mode 100644 index 000000000..ae38121e0 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tab_bottom_selected_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/tab_left.tga b/indra/newview/skins/Blackred/textures/tab_left.tga new file mode 100644 index 000000000..db15d2734 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tab_left.tga differ diff --git a/indra/newview/skins/Blackred/textures/tab_left_selected.tga b/indra/newview/skins/Blackred/textures/tab_left_selected.tga new file mode 100644 index 000000000..212e58575 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tab_left_selected.tga differ diff --git a/indra/newview/skins/Blackred/textures/tab_top_blue.tga b/indra/newview/skins/Blackred/textures/tab_top_blue.tga new file mode 100644 index 000000000..ddcd519f2 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tab_top_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/tab_top_selected_blue.tga b/indra/newview/skins/Blackred/textures/tab_top_selected_blue.tga new file mode 100644 index 000000000..93a5695a6 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tab_top_selected_blue.tga differ diff --git a/indra/newview/skins/Blackred/textures/tearoff_pressed.tga b/indra/newview/skins/Blackred/textures/tearoff_pressed.tga new file mode 100644 index 000000000..8581ab701 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tearoff_pressed.tga differ diff --git a/indra/newview/skins/Blackred/textures/tearoffbox.tga b/indra/newview/skins/Blackred/textures/tearoffbox.tga new file mode 100644 index 000000000..27af31c4d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tearoffbox.tga differ diff --git a/indra/newview/skins/Blackred/textures/textures.xml b/indra/newview/skins/Blackred/textures/textures.xml new file mode 100644 index 000000000..5955a8ede --- /dev/null +++ b/indra/newview/skins/Blackred/textures/textures.xml @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/Blackred/textures/tool_dozer.tga b/indra/newview/skins/Blackred/textures/tool_dozer.tga new file mode 100644 index 000000000..a8814a1ac Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tool_dozer.tga differ diff --git a/indra/newview/skins/Blackred/textures/tool_dozer_active.tga b/indra/newview/skins/Blackred/textures/tool_dozer_active.tga new file mode 100644 index 000000000..40557c9cb Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tool_dozer_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/tool_zoom.tga b/indra/newview/skins/Blackred/textures/tool_zoom.tga new file mode 100644 index 000000000..3ebbe4fcd Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tool_zoom.tga differ diff --git a/indra/newview/skins/Blackred/textures/tool_zoom_active.tga b/indra/newview/skins/Blackred/textures/tool_zoom_active.tga new file mode 100644 index 000000000..df1b379e9 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/tool_zoom_active.tga differ diff --git a/indra/newview/skins/Blackred/textures/toolbar_bg.tga b/indra/newview/skins/Blackred/textures/toolbar_bg.tga new file mode 100644 index 000000000..bddb1f41c Binary files /dev/null and b/indra/newview/skins/Blackred/textures/toolbar_bg.tga differ diff --git a/indra/newview/skins/Blackred/textures/toolbar_btn_disabled.tga b/indra/newview/skins/Blackred/textures/toolbar_btn_disabled.tga new file mode 100644 index 000000000..9e7f3744d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/toolbar_btn_disabled.tga differ diff --git a/indra/newview/skins/Blackred/textures/toolbar_btn_enabled.tga b/indra/newview/skins/Blackred/textures/toolbar_btn_enabled.tga new file mode 100644 index 000000000..9e7f3744d Binary files /dev/null and b/indra/newview/skins/Blackred/textures/toolbar_btn_enabled.tga differ diff --git a/indra/newview/skins/Blackred/textures/toolbar_btn_selected.tga b/indra/newview/skins/Blackred/textures/toolbar_btn_selected.tga new file mode 100644 index 000000000..d37f2d872 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/toolbar_btn_selected.tga differ diff --git a/indra/newview/skins/Blackred/textures/toolbar_tab.tga b/indra/newview/skins/Blackred/textures/toolbar_tab.tga new file mode 100644 index 000000000..a79d8bc43 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/toolbar_tab.tga differ diff --git a/indra/newview/skins/Blackred/textures/up_arrow.png b/indra/newview/skins/Blackred/textures/up_arrow.png new file mode 100644 index 000000000..6beea5fd7 Binary files /dev/null and b/indra/newview/skins/Blackred/textures/up_arrow.png differ diff --git a/indra/newview/skins/apollo/colors.xml b/indra/newview/skins/apollo/colors.xml index 434115514..eb3cbaeb0 100644 --- a/indra/newview/skins/apollo/colors.xml +++ b/indra/newview/skins/apollo/colors.xml @@ -152,7 +152,7 @@ - + diff --git a/indra/newview/skins/blackdark.xml b/indra/newview/skins/blackdark.xml new file mode 100644 index 000000000..8f83e11f1 --- /dev/null +++ b/indra/newview/skins/blackdark.xml @@ -0,0 +1,14 @@ + + + skin_name + Black Dark + author_name + Unknown + additional_author_names + Linden Lab + skin_info + + folder_name + Blackdark + + diff --git a/indra/newview/skins/blacklightblue.xml b/indra/newview/skins/blacklightblue.xml new file mode 100644 index 000000000..8ade2a477 --- /dev/null +++ b/indra/newview/skins/blacklightblue.xml @@ -0,0 +1,14 @@ + + + skin_name + Black Light Blue + author_name + Chalice Yao + additional_author_names + JB Kraft, Linden Lab + skin_info + + folder_name + Blacklightblue + + diff --git a/indra/newview/skins/blackred.xml b/indra/newview/skins/blackred.xml new file mode 100644 index 000000000..93a2ed074 --- /dev/null +++ b/indra/newview/skins/blackred.xml @@ -0,0 +1,14 @@ + + + skin_name + Black Red + author_name + LordGregGreg Back + additional_author_names + Chalice Yao, JB Kraft, Linden Lab + skin_info + + folder_name + Blackred + + diff --git a/indra/newview/skins/default/colors_base.xml b/indra/newview/skins/default/colors_base.xml index eaed66c4d..651f4c232 100644 --- a/indra/newview/skins/default/colors_base.xml +++ b/indra/newview/skins/default/colors_base.xml @@ -153,6 +153,7 @@ + diff --git a/indra/newview/skins/default/textures/icon_name.tga b/indra/newview/skins/default/textures/icon_name.tga new file mode 100644 index 000000000..54b1a3d6a Binary files /dev/null and b/indra/newview/skins/default/textures/icon_name.tga differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 3552b3eaf..a49fdd786 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -100,7 +100,8 @@ - + + diff --git a/indra/newview/skins/default/xui/en-us/floater_about_land.xml b/indra/newview/skins/default/xui/en-us/floater_about_land.xml index f40659986..ae6c96de5 100644 --- a/indra/newview/skins/default/xui/en-us/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en-us/floater_about_land.xml @@ -773,7 +773,7 @@ Only large parcels can be listed in search. mouse_opaque="true" name="Snapshot:" v_pad="0" width="278"> Snapshot: - diff --git a/indra/newview/skins/default/xui/en-us/floater_chat_history_barless.xml b/indra/newview/skins/default/xui/en-us/floater_chat_history_barless.xml new file mode 100644 index 000000000..fd6eb9091 --- /dev/null +++ b/indra/newview/skins/default/xui/en-us/floater_chat_history_barless.xml @@ -0,0 +1,42 @@ + + + Connecting to in-world Voice Chat... + Connected + Voice not available at your current location + Disconnected from in-world Voice Chat + icn_voice-localchat.tga + -- Instant message logging enabled -- + -- End of Log -- + '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS]. + '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS]. + Take in-world money ([CURRENCY]) from you + Act on your control inputs + Remap your control inputs + Animate your avatar + Attach to your avatar + Release ownership and become public + Link and delink from other objects + Add and remove joints with other objects + Change its permissions + Track your camera + Teleport you + Control your camera + + + + Gestures + + + +