diff options
Diffstat (limited to 'indra')
482 files changed, 20022 insertions, 13048 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 001bb4b935..0a54163644 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -41,6 +41,7 @@ endif ("${CMAKE_SOURCE_DIR}/../autobuild.xml" IS_NEWER_THAN "${CMAKE_BINARY_DIR}  add_subdirectory(cmake)  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}llcorehttp) @@ -63,71 +64,53 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)  endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)  add_custom_target(viewer) -if (VIEWER) -  add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger) -  add_subdirectory(${LIBS_OPEN_PREFIX}llplugin) -  add_subdirectory(${LIBS_OPEN_PREFIX}llui) -  add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components) - -  # Legacy C++ tests. Build always, run if LL_TESTS is true. -  add_subdirectory(${VIEWER_PREFIX}test) - -  # viewer media plugins -  add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins) - -  # llplugin testbed code (is this the right way to include it?) -  if (LL_TESTS AND NOT LINUX) -    add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest) -  endif (LL_TESTS AND NOT LINUX) - -  if (LINUX) -    add_subdirectory(${VIEWER_PREFIX}linux_crash_logger) -    add_dependencies(viewer linux-crash-logger-strip-target) -  elseif (DARWIN) -    add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) -    add_subdirectory(${VIEWER_PREFIX}mac_updater) -    add_dependencies(viewer mac-updater mac-crash-logger) -  elseif (WINDOWS) -    add_subdirectory(${VIEWER_PREFIX}win_crash_logger) -    # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake -    if (EXISTS ${VIEWER_DIR}win_setup) -      add_subdirectory(${VIEWER_DIR}win_setup) -    endif (EXISTS ${VIEWER_DIR}win_setup) -    add_subdirectory(${VIEWER_PREFIX}win_updater) -    # add_dependencies(viewer windows-updater windows-setup windows-crash-logger) -    add_dependencies(viewer windows-updater windows-crash-logger) -  elseif (SOLARIS) -    add_subdirectory(solaris_crash_logger) -    add_dependencies(viewer solaris-crash-logger) -  endif (LINUX) - -  add_subdirectory(${VIEWER_PREFIX}newview) -  add_dependencies(viewer secondlife-bin) -endif (VIEWER) - -# Linux builds the viewer and server in 2 separate projects -# In order for build server to work on linux,  -# the viewer project needs a server target. -# This is not true for mac and windows. -if (LINUX)  -  add_custom_target(server) +add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger) +add_subdirectory(${LIBS_OPEN_PREFIX}llplugin) +add_subdirectory(${LIBS_OPEN_PREFIX}llui) +add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components) + +# Legacy C++ tests. Build always, run if LL_TESTS is true. +add_subdirectory(${VIEWER_PREFIX}test) + +# viewer media plugins +add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins) + +# llplugin testbed code (is this the right way to include it?) +if (LL_TESTS AND NOT LINUX) +  add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest) +endif (LL_TESTS AND NOT LINUX) + +if (LINUX) +  add_subdirectory(${VIEWER_PREFIX}linux_crash_logger) +  add_subdirectory(${VIEWER_PREFIX}linux_updater) +  if (INSTALL_PROPRIETARY) +      include(LLAppearanceUtility) +      add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR}) +  endif (INSTALL_PROPRIETARY) +  add_dependencies(viewer linux-crash-logger-strip-target linux-updater) +elseif (DARWIN) +  add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) +  add_subdirectory(${VIEWER_PREFIX}mac_updater) +  add_dependencies(viewer mac-updater mac-crash-logger) +elseif (WINDOWS) +  add_subdirectory(${VIEWER_PREFIX}win_crash_logger) +  # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake +  if (EXISTS ${VIEWER_DIR}win_setup) +    add_subdirectory(${VIEWER_DIR}win_setup) +  endif (EXISTS ${VIEWER_DIR}win_setup) +  add_subdirectory(${VIEWER_PREFIX}win_updater) +  # add_dependencies(viewer windows-updater windows-setup windows-crash-logger) +  add_dependencies(viewer windows-updater windows-crash-logger) +elseif (SOLARIS) +  add_subdirectory(solaris_crash_logger) +  add_dependencies(viewer solaris-crash-logger)  endif (LINUX) -if (SERVER) -  if (NOT LINUX) -    add_custom_target(server) -  endif (NOT LINUX) -  include(${SERVER_PREFIX}Server.cmake) -endif (SERVER) - -# Windows builds include tools like VFS tool -if (SERVER) -  if (WINDOWS) -    add_subdirectory(${SERVER_PREFIX}tools) -  endif (WINDOWS) -endif (SERVER) + +add_subdirectory(${VIEWER_PREFIX}newview) +add_dependencies(viewer secondlife-bin)  if (LL_TESTS) -  # Define after the custom viewer and server targets are created so +  # Define after the custom targets are created so    # individual apps can add themselves as dependencies    add_subdirectory(${INTEGRATION_TESTS_PREFIX}integration_tests)  endif (LL_TESTS) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 452fd5f356..fb5c759493 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -2,6 +2,9 @@  #  # Compilation options shared by all Second Life components. +if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) +set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") +  include(Variables)  # Portable compilation flags. @@ -150,41 +153,21 @@ if (LINUX)        -pthread        ) -  if (SERVER) -    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-60") -    if (EXISTS /etc/debian_version) -      FILE(READ /etc/debian_version DEBIAN_VERSION) -    else (EXISTS /etc/debian_version) -      set(DEBIAN_VERSION "") -    endif (EXISTS /etc/debian_version) - -    if (NOT DEBIAN_VERSION STREQUAL "3.1") -      add_definitions(-DCTYPE_WORKAROUND) -    endif (NOT DEBIAN_VERSION STREQUAL "3.1") - -    if (EXISTS /usr/lib/mysql4/mysql) -      link_directories(/usr/lib/mysql4/mysql) -    endif (EXISTS /usr/lib/mysql4/mysql) - -  endif (SERVER) - -  if (VIEWER) -    add_definitions(-DAPPID=secondlife) -    add_definitions(-fvisibility=hidden) -    # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work.  Sigh!  The viewer doesn't need to catch SIGCHLD anyway. -    add_definitions(-DLL_IGNORE_SIGCHLD) -    if (WORD_SIZE EQUAL 32) -      add_definitions(-march=pentium4) -    endif (WORD_SIZE EQUAL 32) -    add_definitions(-mfpmath=sse) -    #add_definitions(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2 -    if (NOT STANDALONE) -      # this stops us requiring a really recent glibc at runtime -      add_definitions(-fno-stack-protector) -      # linking can be very memory-hungry, especially the final viewer link -      set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory") -    endif (NOT STANDALONE) -  endif (VIEWER) +  add_definitions(-DAPPID=secondlife) +  add_definitions(-fvisibility=hidden) +  # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work.  Sigh!  The viewer doesn't need to catch SIGCHLD anyway. +  add_definitions(-DLL_IGNORE_SIGCHLD) +  if (WORD_SIZE EQUAL 32) +    add_definitions(-march=pentium4) +  endif (WORD_SIZE EQUAL 32) +  add_definitions(-mfpmath=sse) +  #add_definitions(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2 +  if (NOT STANDALONE) +    # this stops us requiring a really recent glibc at runtime +    add_definitions(-fno-stack-protector) +    # linking can be very memory-hungry, especially the final viewer link +    set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory") +  endif (NOT STANDALONE)    set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")    set(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}") @@ -198,7 +181,7 @@ if (DARWIN)    # ucontext_t struct when _XOPEN_SOURCE is not defined (rdar://problem/5578699 ).    # As a workaround, define _XOPEN_SOURCE before including ucontext.h.    add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE) -  set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first") +  set(CMAKE_CXX_LINK_FLAGS "-Wl,-no_compact_unwind -Wl,-headerpad_max_install_names,-search_paths_first")    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")    set(DARWIN_extra_cstar_flags "-mlong-branch -g")    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}") @@ -254,6 +237,4 @@ else (STANDALONE)        )  endif (STANDALONE) -if(SERVER) -  include_directories(${LIBS_PREBUILT_DIR}/include/havok) -endif(SERVER) +endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake index daafa00fe2..492ba2adea 100644 --- a/indra/cmake/APR.cmake +++ b/indra/cmake/APR.cmake @@ -49,9 +49,7 @@ else (STANDALONE)    set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/apr-1)    if (LINUX) -    if (VIEWER) -      list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid) -    endif (VIEWER) +    list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)      list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} rt)    endif (LINUX)  endif (STANDALONE) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 569034a6fb..a21fa90950 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -14,48 +14,66 @@ set(cmake_SOURCE_FILES      Boost.cmake      BuildVersion.cmake      CARes.cmake -    CURL.cmake      CMakeCopyIfDifferent.cmake +    ConfigurePkgConfig.cmake +    CURL.cmake      Copy3rdPartyLibs.cmake -    CSharpMacros.cmake      DBusGlib.cmake +    DeploySharedLibs.cmake      DirectX.cmake +    DragDrop.cmake      EXPAT.cmake +    ExamplePlugin.cmake +    FMOD.cmake      FindAPR.cmake +    FindAutobuild.cmake      FindBerkeleyDB.cmake      FindCARes.cmake -    FindELFIO.cmake      FindFMOD.cmake +    FindGLH.cmake +    FindGoogleBreakpad.cmake      FindGooglePerfTools.cmake -    FindMono.cmake -    FindMySQL.cmake +    FindHUNSPELL.cmake +    FindJsonCpp.cmake +    FindNDOF.cmake      FindOpenJPEG.cmake +    FindSCP.cmake      FindXmlRpcEpi.cmake      FindZLIB.cmake -    FMOD.cmake      FreeType.cmake +    GLEXT.cmake +    GLH.cmake      GLOD.cmake      GStreamer010Plugin.cmake +    GetPrerequisites_2_8.cmake +    Glui.cmake +    Glut.cmake +    GoogleBreakpad.cmake +    GoogleMock.cmake      GooglePerfTools.cmake +    Havok.cmake      Hunspell.cmake      JPEG.cmake +    JsonCpp.cmake      LLAddBuildTest.cmake +    LLAppearance.cmake +    LLAppearanceUtility.cmake      LLAudio.cmake      LLCharacter.cmake      LLCommon.cmake      LLCrashLogger.cmake -    LLDatabase.cmake      LLImage.cmake      LLImageJ2COJ.cmake      LLInventory.cmake      LLKDU.cmake +    LLLogin.cmake      LLMath.cmake      LLMessage.cmake +    LLPhysicsExtensions.cmake      LLPlugin.cmake      LLPrimitive.cmake -    LLPhysicsExtensions.cmake      LLRender.cmake -    LLScene.cmake +    LLSharedLibs.cmake      LLTestCommand.cmake      LLUI.cmake      LLVFS.cmake @@ -63,21 +81,26 @@ set(cmake_SOURCE_FILES      LLXML.cmake      LScript.cmake      Linking.cmake -    MonoEmbed.cmake -    MySQL.cmake +    MediaPluginBase.cmake      NDOF.cmake      OPENAL.cmake      OpenGL.cmake      OpenJPEG.cmake      OpenSSL.cmake      PNG.cmake -    Python.cmake +    PluginAPI.cmake      Prebuilt.cmake +    PulseAudio.cmake +    Python.cmake +    QuickTimePlugin.cmake      TemplateCheck.cmake      Tut.cmake      UI.cmake      UnixInstall.cmake      Variables.cmake +    ViewerMiscLibs.cmake +    VisualLeakDetector.cmake +    WebKitLibPlugin.cmake      XmlRpcEpi.cmake      ZLIB.cmake      ) @@ -88,10 +111,6 @@ set(master_SOURCE_FILES      ../CMakeLists.txt      ) -if (SERVER) -  list(APPEND master_SOURCE_FILES ../Server.cmake) -endif (SERVER) -  source_group("Master Rules" FILES ${master_SOURCE_FILES})  set_source_files_properties(${cmake_SOURCE_FILES} ${master_SOURCE_FILES} diff --git a/indra/cmake/CSharpMacros.cmake b/indra/cmake/CSharpMacros.cmake deleted file mode 100644 index a4dd815043..0000000000 --- a/indra/cmake/CSharpMacros.cmake +++ /dev/null @@ -1,142 +0,0 @@ -# - This is a support module for easy Mono/C# handling with CMake -# It defines the following macros: -# -# ADD_CS_LIBRARY (<target> <source>) -# ADD_CS_EXECUTABLE (<target> <source>) -# INSTALL_GAC (<target>) -# -# Note that the order of the arguments is important. -# -# You can optionally set the variable CS_FLAGS to tell the macros whether -# to pass additional flags to the compiler. This is particularly useful to -# set assembly references, unsafe code, etc... These flags are always reset -# after the target was added so you don't have to care about that. -# -# copyright (c) 2007 Arno Rehn arno@arnorehn.de -# -# Redistribution and use is allowed according to the terms of the GPL license. - - -# ----- support macros ----- -MACRO(GET_CS_LIBRARY_TARGET_DIR) -        IF (NOT LIBRARY_OUTPUT_PATH) -                SET(CS_LIBRARY_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR}) -        ELSE (NOT LIBRARY_OUTPUT_PATH) -                SET(CS_LIBRARY_TARGET_DIR ${LIBRARY_OUTPUT_PATH}) -        ENDIF (NOT LIBRARY_OUTPUT_PATH) -ENDMACRO(GET_CS_LIBRARY_TARGET_DIR) - -MACRO(GET_CS_EXECUTABLE_TARGET_DIR) -        IF (NOT EXECUTABLE_OUTPUT_PATH) -                SET(CS_EXECUTABLE_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR}) -        ELSE (NOT EXECUTABLE_OUTPUT_PATH) -                SET(CS_EXECUTABLE_TARGET_DIR ${EXECUTABLE_OUTPUT_PATH}) -        ENDIF (NOT EXECUTABLE_OUTPUT_PATH) -ENDMACRO(GET_CS_EXECUTABLE_TARGET_DIR) - -MACRO(MAKE_PROPER_FILE_LIST) -        FOREACH(file ${ARGN}) -                # first assume it's a relative path -                FILE(GLOB globbed ${CMAKE_CURRENT_SOURCE_DIR}/${file}) -                IF(globbed) -                        FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${file} native) -                ELSE(globbed) -                        FILE(TO_NATIVE_PATH ${file} native) -                ENDIF(globbed) -                SET(proper_file_list ${proper_file_list} ${native}) -                SET(native "") -        ENDFOREACH(file) -ENDMACRO(MAKE_PROPER_FILE_LIST) -# ----- end support macros ----- - -MACRO(ADD_CS_LIBRARY target) -        GET_CS_LIBRARY_TARGET_DIR() -         -        SET(target_DLL "${CS_LIBRARY_TARGET_DIR}/${target}.dll") -        MAKE_PROPER_FILE_LIST(${ARGN}) -        FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_DLL}) -         -        SET(target_KEY "${CMAKE_CURRENT_SOURCE_DIR}/${target}.key") -        SET(target_CS_FLAGS "${CS_FLAGS}") -        IF(${target}_CS_FLAGS) -                LIST(APPEND target_CS_FLAGS ${${target}_CS_FLAGS}) -        ENDIF(${target}_CS_FLAGS) -        IF(EXISTS ${target_KEY}) -                LIST(APPEND target_CS_FLAGS -keyfile:${target_KEY}) -        ENDIF(EXISTS ${target_KEY}) - -        FOREACH(ref ${${target}_REFS}) -                SET(ref_DLL ${CMAKE_CURRENT_BINARY_DIR}/${ref}.dll) -                IF(EXISTS ${ref_DLL}) -                        LIST(APPEND target_CS_FLAGS -r:${ref_DLL}) -                ELSE(EXISTS ${ref_DLL}) -                        LIST(APPEND target_CS_FLAGS -r:${ref}) -                ENDIF(EXISTS ${ref_DLL}) -        ENDFOREACH(ref ${${target}_REFS}) - -        ADD_CUSTOM_COMMAND (OUTPUT ${target_DLL} -                COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_DLL} -target:library ${proper_file_list} -                MAIN_DEPENDENCY ${proper_file_list} -                DEPENDS ${ARGN} -                COMMENT "Building ${relative_path}") -        ADD_CUSTOM_TARGET (${target} ALL DEPENDS ${target_DLL}) - -        FOREACH(ref ${${target}_REFS}) -                GET_TARGET_PROPERTY(is_target ${ref} TYPE) -                IF(is_target) -                        ADD_DEPENDENCIES(${target} ${ref}) -                ENDIF(is_target) -        ENDFOREACH(ref ${${target}_REFS}) - -        SET(relative_path "") -        SET(proper_file_list "") -ENDMACRO(ADD_CS_LIBRARY) - -MACRO(ADD_CS_EXECUTABLE target) -        GET_CS_EXECUTABLE_TARGET_DIR() -         -        # Seems like cmake doesn't like the ".exe" ending for custom commands. -        # If we call it ${target}.exe, 'make' will later complain about a missing rule. -        # Create a fake target instead. -        SET(target_EXE "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe") -        SET(target_TOUCH "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe-built") -        GET_DIRECTORY_PROPERTY(clean ADDITIONAL_MAKE_CLEAN_FILES) -        LIST(APPEND clean ${target}.exe) -        SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${clean}") -        MAKE_PROPER_FILE_LIST(${ARGN}) -        FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_EXE}) -        SET(target_CS_FLAGS "${CS_FLAGS}") -         -        FOREACH(ref ${${target}_REFS}) -                SET(ref_DLL ${CMAKE_CURRENT_SOURCE_DIR}/${ref}.dll) -                IF(EXISTS ${ref_DLL}) -                        LIST(APPEND target_CS_FLAGS -r:${ref_DLL}) -                ELSE(EXISTS ${ref_DLL}) -                        LIST(APPEND target_CS_FLAGS -r:${ref}) -                ENDIF(EXISTS ${ref_DLL}) -        ENDFOREACH(ref ${${target}_REFS}) - -        ADD_CUSTOM_COMMAND (OUTPUT "${target_TOUCH}" -                COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_EXE} ${proper_file_list} -                COMMAND ${CMAKE_COMMAND} -E touch ${target_TOUCH} -                MAIN_DEPENDENCY ${ARGN} -                DEPENDS ${ARGN} -                COMMENT "Building ${relative_path}") -        ADD_CUSTOM_TARGET ("${target}" ALL DEPENDS "${target_TOUCH}") - -        FOREACH(ref ${${target}_REFS}) -                GET_TARGET_PROPERTY(is_target ${ref} TYPE) -                IF(is_target) -                        ADD_DEPENDENCIES(${target} ${ref}) -                ENDIF(is_target) -        ENDFOREACH(ref ${${target}_REFS}) - -        SET(relative_path "") -        SET(proper_file_list "") -ENDMACRO(ADD_CS_EXECUTABLE) - -MACRO(INSTALL_GAC target) -        GET_CS_LIBRARY_TARGET_DIR() -         -        INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${GACUTIL_EXECUTABLE} -i ${CS_LIBRARY_TARGET_DIR}/${target}.dll -package 2.0)") -ENDMACRO(INSTALL_GAC target) diff --git a/indra/cmake/ConfigurePkgConfig.cmake b/indra/cmake/ConfigurePkgConfig.cmake new file mode 100644 index 0000000000..82ee3e7a5b --- /dev/null +++ b/indra/cmake/ConfigurePkgConfig.cmake @@ -0,0 +1,74 @@ +# -*- cmake -*- + +SET(DEBUG_PKG_CONFIG "YES") + +# Don't change this if manually set by user. +IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "") + +  # Guess at architecture-specific system library paths. +  if (WORD_SIZE EQUAL 32) +    SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib) +    SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib) +    SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu) +    SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu) +  else (WORD_SIZE EQUAL 32) +    SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib) +    SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib) +    SET(PKG_CONFIG_MULTI_GUESS /usr/local/lib/x86_64-linux-gnu) +    SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu) +  endif (WORD_SIZE EQUAL 32) +   +  # Use DPKG architecture, if available. +  IF (${DPKG_ARCH}) +    SET(PKG_CONFIG_MULTI_GUESS /usr/lib/${DPKG_ARCH}) +    SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usrlocal/lib/${DPKG_ARCH}) +  ENDIF (${DPKG_ARCH}) +   +  # Explicitly include anything listed in PKG_CONFIG_PATH +  string(REPLACE ":" ";" PKG_CONFIG_PATH_LIST "$ENV{PKG_CONFIG_PATH}") +  FOREACH(PKG_CONFIG_DIR ${PKG_CONFIG_PATH_LIST}) +    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_DIR}/pkgconfig") +  ENDFOREACH(PKG_CONFIG_DIR) + +  # Look for valid pkgconfig directories. +  FIND_PATH(PKG_CONFIG_ENV pkgconfig ENV LD_LIBRARY_PATH) +  FIND_PATH(PKG_CONFIG_MULTI pkgconfig HINT ${PKG_CONFIG_MULTI_GUESS}) +  FIND_PATH(PKG_CONFIG_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_MULTI_LOCAL_GUESS}) +  FIND_PATH(PKG_CONFIG_NO_MULTI pkgconfig HINT ${PKG_CONFIG_NO_MULTI_GUESS}) +  FIND_PATH(PKG_CONFIG_NO_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_NO_MULTI_LOCAL_GUESS}) + +  # Add anything we found to our list. +  IF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND)  +    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_ENV}/pkgconfig") +  ENDIF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND)  + +  IF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND)  +    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI}/pkgconfig") +  ENDIF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND)  + +  IF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND)  +    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI_LOCAL}/pkgconfig") +  ENDIF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND)  + +  IF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND)  +    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI}/pkgconfig") +  ENDIF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND)  + +  IF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND)  +    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI_LOCAL}/pkgconfig") +  ENDIF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND)  + +  # Also add some non-architecture specific package locations. +  SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:/usr/share/pkgconfig:/usr/local/share/pkgconfig") + +  # Remove first unwanted ':' +  string(SUBSTRING ${VALID_PKG_LIBDIRS} 1 -1 VALID_PKG_LIBDIRS) + +  # Set PKG_CONFIG_LIBDIR environment. +  SET(ENV{PKG_CONFIG_LIBDIR} ${VALID_PKG_LIBDIRS}) +ENDIF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "") + +IF(DEBUG_PKG_CONFIG) +  MESSAGE(STATUS "Using PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}") +ENDIF(DEBUG_PKG_CONFIG) + diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index c32e357da3..338da4743e 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -266,7 +266,7 @@ elseif(LINUX)          libdb-5.1.so          libexpat.so          libexpat.so.1 -        libglod.so +        libGLOD.so          libgmock_main.so          libgmock.so.0          libgmodule-2.0.so diff --git a/indra/cmake/CopyBackToSource.cmake b/indra/cmake/CopyBackToSource.cmake deleted file mode 100644 index d217df9aec..0000000000 --- a/indra/cmake/CopyBackToSource.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -*- cmake -*- -# Copies a binary back to the source directory - -MACRO(COPY_BACK_TO_SOURCE target) -   GET_TARGET_PROPERTY(FROM ${target} LOCATION) -   SET(TO ${CMAKE_CURRENT_SOURCE_DIR}) -   #MESSAGE("TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO}") -   ADD_CUSTOM_COMMAND( -        TARGET ${target} POST_BUILD -        COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO} -        DEPENDS ${FROM} -        COMMENT "Copying ${target} to ${CMAKE_CURRENT_BINARY_DIR}" -        ) -ENDMACRO(COPY_BACK_TO_SOURCE) - - diff --git a/indra/cmake/DirectX.cmake b/indra/cmake/DirectX.cmake index b2a18805d4..25163d0322 100644 --- a/indra/cmake/DirectX.cmake +++ b/indra/cmake/DirectX.cmake @@ -1,8 +1,9 @@  # -*- cmake -*- -if (VIEWER AND WINDOWS) +if (WINDOWS)    find_path(DIRECTX_INCLUDE_DIR dxdiag.h              "$ENV{DXSDK_DIR}/Include" +            "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Include"              "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Include"              "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Include"              "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Include" @@ -25,6 +26,7 @@ if (VIEWER AND WINDOWS)    find_path(DIRECTX_LIBRARY_DIR dxguid.lib              "$ENV{DXSDK_DIR}/Lib/x86" +            "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Lib/x86"              "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Lib/x86"              "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Lib/x86"              "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Lib/x86" @@ -43,4 +45,4 @@ if (VIEWER AND WINDOWS)      message(FATAL_ERROR "Could not find DirectX SDK Libraries")    endif (DIRECTX_LIBRARY_DIR) -endif (VIEWER AND WINDOWS) +endif (WINDOWS) diff --git a/indra/cmake/DragDrop.cmake b/indra/cmake/DragDrop.cmake index c0424396e5..b70aa6b6ee 100644 --- a/indra/cmake/DragDrop.cmake +++ b/indra/cmake/DragDrop.cmake @@ -1,23 +1,20 @@  # -*- cmake -*- -if (VIEWER) +set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off") -  set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off") +if (OS_DRAG_DROP) -  if (OS_DRAG_DROP) +  if (WINDOWS) +    add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) +  endif (WINDOWS) -    if (WINDOWS) -      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) -    endif (WINDOWS) +  if (DARWIN) +    add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) +  endif (DARWIN) -    if (DARWIN) -      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) -    endif (DARWIN) +  if (LINUX) +    add_definitions(-DLL_OS_DRAGDROP_ENABLED=0) +  endif (LINUX) -    if (LINUX) -      add_definitions(-DLL_OS_DRAGDROP_ENABLED=0) -    endif (LINUX) +endif (OS_DRAG_DROP) -  endif (OS_DRAG_DROP) - -endif (VIEWER) diff --git a/indra/cmake/Externals.cmake b/indra/cmake/Externals.cmake deleted file mode 100644 index 26f3b56049..0000000000 --- a/indra/cmake/Externals.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# -*- cmake -*- - -include(Python) -include(FindSVN) - -macro (use_svn_external _binary _path _url _rev) -  if (NOT STANDALONE) -    if(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed) -      if(SVN_FOUND) -        if(DEBUG_EXTERNALS) -          message("cd ${_path} && ${SVN_EXECUTABLE} checkout -r ${_rev} ${_url} ${_binary}") -        endif(DEBUG_EXTERNALS) -        execute_process(COMMAND ${SVN_EXECUTABLE} -          checkout -          -r ${_rev} -          ${_url} -          ${_binary} -          WORKING_DIRECTORY ${_path} -          RESULT_VARIABLE ${_binary}_installed -          ) -      else(SVN_FOUND) -        message(FATAL_ERROR "Failed to find SVN_EXECUTABLE") -      endif(SVN_FOUND) -      file(WRITE ${CMAKE_BINARY_DIR}/temp/${_binary}_installed "${${_binary}_installed}") -    else(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed) -      set(${_binary}_installed 0) -    endif(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed) -    if(NOT ${_binary}_installed EQUAL 0) -      message(FATAL_ERROR -              "Failed to download or unpack prebuilt '${_binary}'." -              " Process returned ${${_binary}_installed}.") -    endif (NOT ${_binary}_installed EQUAL 0) -  endif (NOT STANDALONE) -endmacro (use_svn_external _binary _path _url _rev) diff --git a/indra/cmake/FindELFIO.cmake b/indra/cmake/FindELFIO.cmake deleted file mode 100644 index 8a5421ab9c..0000000000 --- a/indra/cmake/FindELFIO.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# -*- cmake -*- - -# - Find ELFIO -# Find the ELFIO includes and library -# This module defines -#  ELFIO_INCLUDE_DIR, where to find elfio.h, etc. -#  ELFIO_LIBRARIES, the libraries needed to use ELFIO. -#  ELFIO_FOUND, If false, do not try to use ELFIO. -# also defined, but not for general use are -#  ELFIO_LIBRARY, where to find the ELFIO library. - -FIND_PATH(ELFIO_INCLUDE_DIR ELFIO/ELFIO.h -/usr/local/include -/usr/include -) - -SET(ELFIO_NAMES ${ELFIO_NAMES} ELFIO) -FIND_LIBRARY(ELFIO_LIBRARY -  NAMES ${ELFIO_NAMES} -  PATHS /usr/lib /usr/local/lib -  ) - -IF (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR) -    SET(ELFIO_LIBRARIES ${ELFIO_LIBRARY}) -    SET(ELFIO_FOUND "YES") -ELSE (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR) -  SET(ELFIO_FOUND "NO") -ENDIF (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR) - - -IF (ELFIO_FOUND) -   IF (NOT ELFIO_FIND_QUIETLY) -      MESSAGE(STATUS "Found ELFIO: ${ELFIO_LIBRARIES}") -   ENDIF (NOT ELFIO_FIND_QUIETLY) -ELSE (ELFIO_FOUND) -   IF (ELFIO_FIND_REQUIRED) -      MESSAGE(FATAL_ERROR "Could not find ELFIO library") -   ENDIF (ELFIO_FIND_REQUIRED) -ENDIF (ELFIO_FOUND) - -# Deprecated declarations. -SET (NATIVE_ELFIO_INCLUDE_PATH ${ELFIO_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_ELFIO_LIB_PATH ${ELFIO_LIBRARY} PATH) - -MARK_AS_ADVANCED( -  ELFIO_LIBRARY -  ELFIO_INCLUDE_DIR -  ) diff --git a/indra/cmake/FindLLQtWebkit.cmake b/indra/cmake/FindLLQtWebkit.cmake deleted file mode 100644 index 2f666d3bf0..0000000000 --- a/indra/cmake/FindLLQtWebkit.cmake +++ /dev/null @@ -1,62 +0,0 @@ -# -*- cmake -*- - -# - Find llqtwebkit -# Find the llqtwebkit includes and library -# This module defines -#  LLQTWEBKIT_INCLUDE_DIR, where to find llqtwebkit.h, etc. -#  LLQTWEBKIT_LIBRARY, the llqtwebkit library with full path. -#  LLQTWEBKIT_FOUND, If false, do not try to use llqtwebkit. -# also defined, but not for general use are -#  LLQTWEBKIT_LIBRARIES, the libraries needed to use llqtwebkit. -#  LLQTWEBKIT_LIBRARY_DIRS, where to find the llqtwebkit library. -#  LLQTWEBKIT_DEFINITIONS - You should add_definitions(${LLQTWEBKIT_DEFINITIONS}) -#      before compiling code that includes llqtwebkit library files. - -# Try to use pkg-config first. -# This allows to have two different libllqtwebkit packages installed: -# one for viewer 2.x and one for viewer 1.x. -include(FindPkgConfig) -if (PKG_CONFIG_FOUND) -    if (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION) -        set(_PACKAGE_ARGS libllqtwebkit>=${LLQtWebkit_FIND_VERSION} REQUIRED) -    else (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION) -        set(_PACKAGE_ARGS libllqtwebkit) -    endif (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION) -    if (NOT "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_LESS "2.8.2") -      # As virtually nobody will have a pkg-config file for this, do this check always quiet. -      # Unfortunately cmake 2.8.2 or higher is required for pkg_check_modules to have a 'QUIET'. -      set(_PACKAGE_ARGS ${_PACKAGE_ARGS} QUIET) -    endif () -    pkg_check_modules(LLQTWEBKIT ${_PACKAGE_ARGS}) -endif (PKG_CONFIG_FOUND) -set(LLQTWEBKIT_DEFINITIONS ${LLQTWEBKIT_CFLAGS_OTHER}) - -find_path(LLQTWEBKIT_INCLUDE_DIR llqtwebkit.h NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_INCLUDE_DIRS}) - -find_library(LLQTWEBKIT_LIBRARY NAMES llqtwebkit NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_LIBRARY_DIRS}) - -if (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND)   # If pkg-config couldn't find it, pretend we don't have pkg-config. -   set(LLQTWEBKIT_LIBRARIES llqtwebkit) -   get_filename_component(LLQTWEBKIT_LIBRARY_DIRS ${LLQTWEBKIT_LIBRARY} PATH) -endif (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND) - -# Handle the QUIETLY and REQUIRED arguments and set LLQTWEBKIT_FOUND -# to TRUE if all listed variables are TRUE. -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( -  LLQTWEBKIT -  DEFAULT_MSG -  LLQTWEBKIT_LIBRARY -  LLQTWEBKIT_INCLUDE_DIR -  LLQTWEBKIT_LIBRARIES -  LLQTWEBKIT_LIBRARY_DIRS -  ) - -mark_as_advanced( -  LLQTWEBKIT_LIBRARY -  LLQTWEBKIT_INCLUDE_DIR -  LLQTWEBKIT_LIBRARIES -  LLQTWEBKIT_LIBRARY_DIRS -  LLQTWEBKIT_DEFINITIONS -  ) - diff --git a/indra/cmake/FindMT.cmake b/indra/cmake/FindMT.cmake deleted file mode 100644 index 5239a4c2f5..0000000000 --- a/indra/cmake/FindMT.cmake +++ /dev/null @@ -1,15 +0,0 @@ -#Find the windows manifest tool. - -FIND_PROGRAM(HAVE_MANIFEST_TOOL NAMES mt -                 PATHS -                 "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/VC/bin" -                 "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/Common7/Tools/Bin" -                 "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/SDK/v2.0/Bin") -IF(HAVE_MANIFEST_TOOL) -    MESSAGE(STATUS "Found Mainfest Tool. Embedding custom manifests.") -ELSE(HAVE_MANIFEST_TOOL) -    MESSAGE(FATAL_ERROR "Manifest tool, mt.exe, can't be found.") -ENDIF(HAVE_MANIFEST_TOOL) - -STRING(REPLACE "/MANIFEST" "/MANIFEST:NO" CMAKE_EXE_LINKER_FLAGS  -      ${CMAKE_EXE_LINKER_FLAGS}) diff --git a/indra/cmake/FindMono.cmake b/indra/cmake/FindMono.cmake deleted file mode 100644 index d956c48656..0000000000 --- a/indra/cmake/FindMono.cmake +++ /dev/null @@ -1,68 +0,0 @@ -# - Try to find the mono, mcs, gmcs and gacutil -# -# defines -# -# MONO_FOUND - system has mono, mcs, gmcs and gacutil -# MONO_PATH - where to find 'mono' -# MCS_PATH - where to find 'mcs' -# GMCS_PATH - where to find 'gmcs' -# GACUTIL_PATH - where to find 'gacutil' -# -# copyright (c) 2007 Arno Rehn arno@arnorehn.de -# -# Redistribution and use is allowed according to the terms of the GPL license. -# Removed the check for gmcs - -FIND_PROGRAM (MONO_EXECUTABLE mono -             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin" -             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin" -             /bin -             /usr/bin -             /usr/local/bin -) -FIND_PROGRAM (MCS_EXECUTABLE mcs -             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin" -             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin" -             /bin -             /usr/bin -             /usr/local/bin -) -FIND_PROGRAM (GMCS_EXECUTABLE gmcs -             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin" -             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin" -             /bin -             /usr/bin -             /usr/local/bin -) -FIND_PROGRAM (GACUTIL_EXECUTABLE gacutil -             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin" -             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin" -             /bin -             /usr/bin -             /usr/local/bin -) -FIND_PROGRAM (ILASM_EXECUTABLE -             NAMES ilasm.bat ilasm -             NO_DEFAULT_PATH -             PATHS "$ENV{PROGRAMFILES}/Mono-1.9.1/bin" "$ENV{PROGRAMFILES}/Mono-1.2.6/bin" /bin /usr/bin /usr/local/bin -) - -SET (MONO_FOUND FALSE) - -IF (MONO_EXECUTABLE AND MCS_EXECUTABLE AND GACUTIL_EXECUTABLE) -        SET (MONO_FOUND TRUE) -ENDIF (MONO_EXECUTABLE AND MCS_EXECUTABLE AND GACUTIL_EXECUTABLE) - -IF (MONO_FOUND) -        IF (NOT Mono_FIND_QUIETLY) -                MESSAGE(STATUS "Found mono: ${MONO_EXECUTABLE}") -                MESSAGE(STATUS "Found mcs: ${MCS_EXECUTABLE}") -                MESSAGE(STATUS "Found gacutil: ${GACUTIL_EXECUTABLE}") -        ENDIF (NOT Mono_FIND_QUIETLY) -ELSE (MONO_FOUND) -        IF (Mono_FIND_REQUIRED) -                MESSAGE(FATAL_ERROR "Could not find one or more of the following programs: mono, mcs, gacutil") -        ENDIF (Mono_FIND_REQUIRED) -ENDIF (MONO_FOUND) - -MARK_AS_ADVANCED(MONO_EXECUTABLE MCS_EXECUTABLE GACUTIL_EXECUTABLE) diff --git a/indra/cmake/FindMySQL.cmake b/indra/cmake/FindMySQL.cmake deleted file mode 100644 index 431940328f..0000000000 --- a/indra/cmake/FindMySQL.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# -*- cmake -*- - -# - Find MySQL -# Find the MySQL includes and library -# This module defines -#  MYSQL_INCLUDE_DIR, where to find mysql.h, etc. -#  MYSQL_LIBRARIES, the libraries needed to use Mysql. -#  MYSQL_FOUND, If false, do not try to use Mysql. -# also defined, but not for general use are -#  MYSQL_LIBRARY, where to find the Mysql library. - -FIND_PATH(MYSQL_INCLUDE_DIR mysql/mysql.h -/usr/local/include -/usr/include -) - -SET(MYSQL_NAMES ${MYSQL_NAMES} mysqlclient) -FIND_LIBRARY(MYSQL_LIBRARY -  NAMES ${MYSQL_NAMES} -  PATHS /usr/lib/mysql /usr/lib /usr/local/lib/mysql /usr/local/lib -  ) - -IF (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR) -    SET(MYSQL_LIBRARIES ${MYSQL_LIBRARY}) -    SET(MYSQL_FOUND "YES") -ELSE (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR) -  SET(MYSQL_FOUND "NO") -ENDIF (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR) - - -IF (MYSQL_FOUND) -   IF (NOT MYSQL_FIND_QUIETLY) -      MESSAGE(STATUS "Found MySQL: ${MYSQL_LIBRARIES}") -   ENDIF (NOT MYSQL_FIND_QUIETLY) -ELSE (MYSQL_FOUND) -   IF (MYSQL_FIND_REQUIRED) -      MESSAGE(FATAL_ERROR "Could not find MySQL library") -   ENDIF (MYSQL_FIND_REQUIRED) -ENDIF (MYSQL_FOUND) - -# Deprecated declarations. -SET (NATIVE_MYSQL_INCLUDE_PATH ${MYSQL_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_MYSQL_LIB_PATH ${MYSQL_LIBRARY} PATH) - -MARK_AS_ADVANCED( -  MYSQL_LIBRARY -  MYSQL_INCLUDE_DIR -  ) diff --git a/indra/cmake/FindSVN.cmake b/indra/cmake/FindSVN.cmake deleted file mode 100644 index 3322be4ca9..0000000000 --- a/indra/cmake/FindSVN.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# -*- cmake -*- -# -# Find the svn executable for exporting old svn:externals. -# -# Input variables: -#   SVN_FIND_REQUIRED - set this if configuration should fail without scp -# -# Output variables: -# -#   SVN_FOUND - set if svn was found -#   SVN_EXECUTABLE - path to svn executable -#   SVN_BATCH_FLAG - how to put svn into batch mode - - -SET(SVN_EXECUTABLE) -FIND_PROGRAM(SVN_EXECUTABLE NAMES svn svn.exe) - -IF (SVN_EXECUTABLE) -  SET(SVN_FOUND ON) -ELSE (SVN_EXECUTABLE) -  SET(SVN_FOUND OFF) -ENDIF (SVN_EXECUTABLE) - -IF (SVN_FOUND) -  GET_FILENAME_COMPONENT(_svn_name ${SVN_EXECUTABLE} NAME_WE) -  SET(SVN_BATCH_FLAG --non-interactive) -ELSE (SVN_FOUND) -  IF (SVN_FIND_REQUIRED) -    MESSAGE(FATAL_ERROR "Could not find svn executable") -  ENDIF (SVN_FIND_REQUIRED) -ENDIF (SVN_FOUND) - -MARK_AS_ADVANCED(SVN_EXECUTABLE SVN_FOUND SVN_BATCH_FLAG) - diff --git a/indra/cmake/GLEXT.cmake b/indra/cmake/GLEXT.cmake new file mode 100644 index 0000000000..0a3dd976b4 --- /dev/null +++ b/indra/cmake/GLEXT.cmake @@ -0,0 +1,8 @@ +# -*- cmake -*- +include(Prebuilt) + +if (NOT STANDALONE) +  use_prebuilt_binary(glext) +  use_prebuilt_binary(glh_linear) +  set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) +endif (NOT STANDALONE) diff --git a/indra/cmake/GLOD.cmake b/indra/cmake/GLOD.cmake index 77221d55ed..6bdbaf621e 100644 --- a/indra/cmake/GLOD.cmake +++ b/indra/cmake/GLOD.cmake @@ -6,4 +6,4 @@ if (NOT STANDALONE)  endif (NOT STANDALONE)  set(GLOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) -set(GLOD_LIBRARIES glod) +set(GLOD_LIBRARIES GLOD) diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake index 73b3642ae6..f3fd008e49 100644 --- a/indra/cmake/GooglePerfTools.cmake +++ b/indra/cmake/GooglePerfTools.cmake @@ -10,7 +10,7 @@ if (STANDALONE)  else (STANDALONE)    if (WINDOWS)      if (USE_TCMALLOC) -       use_prebuilt_binary(tcmalloc) +       use_prebuilt_binary(gperftools)         set(TCMALLOC_LIBRARIES            debug libtcmalloc_minimal-debug           optimized libtcmalloc_minimal) @@ -23,7 +23,7 @@ else (STANDALONE)    endif (WINDOWS)    if (LINUX)      if (USE_TCMALLOC) -      use_prebuilt_binary(tcmalloc) +      use_prebuilt_binary(gperftools)        set(TCMALLOC_LIBRARIES           tcmalloc)      else (USE_TCMALLOC) diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake index 5c0768abfa..44f81ce332 100644 --- a/indra/cmake/Havok.cmake +++ b/indra/cmake/Havok.cmake @@ -1,6 +1,10 @@  # -*- cmake -*- +if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) +set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") +  use_prebuilt_binary(havok-source) +  set(Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Source)  list(APPEND Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Demo) @@ -8,14 +12,14 @@ set(HAVOK_DEBUG_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)  set(HAVOK_RELEASE_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)  if (LL_DEBUG_HAVOK) -   if (WIN32) -      # Always link relwithdebinfo to havok-hybrid on windows. -      set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid) -   else (WIN32) -      set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug) -   endif (WIN32) +  if (WIN32) +    # Always link relwithdebinfo to havok-hybrid on windows. +    set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid) +  else (WIN32) +    set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug) +  endif (WIN32)  else (LL_DEBUG_HAVOK) -   set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok) +  set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)  endif (LL_DEBUG_HAVOK)  set(HAVOK_LIBS @@ -45,39 +49,89 @@ unset(HK_DEBUG_LIBRARIES)  unset(HK_RELEASE_LIBRARIES)  unset(HK_RELWITHDEBINFO_LIBRARIES) +# *TODO: Figure out why we need to extract like this...  foreach(HAVOK_LIB ${HAVOK_LIBS}) -        find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH}) -        find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH}) -        find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}) -         -        if(LINUX) -            set(cmd "mkdir") -            set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}") -            set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}") -            set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}") - -            exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv) -            exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv) -            exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv) - -            set(cmd "ar") -            set(arg " -xv") -            set(arg "${arg} ../lib${HAVOK_LIB}.a") -            exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv) -            exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv) -            exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv) - -            file(GLOB extracted_debug "${debug_dir}/*.o") -            file(GLOB extracted_release "${release_dir}/*.o") -            file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o") -            list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug}) -            list(APPEND HK_RELEASE_LIBRARIES ${extracted_release}) -            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo}) -        else(LINUX) -        # Win32 -            list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}}) -            list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}}) -            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}}) -        endif (LINUX) +  find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH}) +  find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH}) +  find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}) +   +  if(LINUX) +    set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}") +    set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}") +    set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}") + +    # Try to avoid extracting havok library each time we run cmake. +    if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted") +      file(READ ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted "havok_${HAVOK_LIB}_extracted") +      if(DEBUG_PREBUILT) +        message(STATUS "havok_${HAVOK_LIB}_extracted: \"${havok_${HAVOK_LIB}_extracted}\"") +      endif(DEBUG_PREBUILT) +    endif("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted") + +    if(${CMAKE_BINARY_DIR}/temp/havok-source_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0) +      if(DEBUG_PREBUILT) +        MESSAGE(STATUS "Extracting ${HAVOK_LIB}...") +      endif(DEBUG_PREBUILT) +      set(cmd "mkdir") + +      if(DEBUG_PREBUILT) +        MESSAGE(STATUS "${cmd} ${debug_dir}") +      endif(DEBUG_PREBUILT) +      exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv) + +      if(DEBUG_PREBUILT) +        MESSAGE(STATUS "${cmd} ${release_dir}") +      endif(DEBUG_PREBUILT) +      exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv) + +      if(DEBUG_PREBUILT) +        MESSAGE(STATUS "${cmd} ${relwithdebinfo_dir}") +      endif(DEBUG_PREBUILT) +      exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv) + +      set(cmd "ar") +      set(arg " -xv") +      set(arg "${arg} ../lib${HAVOK_LIB}.a") +      if(DEBUG_PREBUILT) +        MESSAGE(STATUS "cd ${debug_dir} && ${cmd} ${arg}") +      endif(DEBUG_PREBUILT) +      exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv) + +      if(DEBUG_PREBUILT) +        MESSAGE(STATUS "cd ${release_dir} && ${cmd} ${arg}") +      endif(DEBUG_PREBUILT) +      exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv) + +      if(DEBUG_PREBUILT) +        MESSAGE(STATUS "cd ${relwithdebinfo_dir} && ${cmd} ${arg}") +      endif(DEBUG_PREBUILT) +      exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv) + +      # Just assume success for now. +      set(havok_${HAVOK_LIB}_extracted 0) +      file(WRITE ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted "${havok_${HAVOK_LIB}_extracted}") + +    endif(${CMAKE_BINARY_DIR}/temp/havok-source_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0) + +    file(GLOB extracted_debug "${debug_dir}/*.o") +    file(GLOB extracted_release "${release_dir}/*.o") +    file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o") + +    if(DEBUG_PREBUILT) +      MESSAGE(STATUS "extracted_debug ${debug_dir}/*.o") +      MESSAGE(STATUS "extracted_release ${release_dir}/*.o") +      MESSAGE(STATUS "extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o") +    endif(DEBUG_PREBUILT) + +    list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug}) +    list(APPEND HK_RELEASE_LIBRARIES ${extracted_release}) +    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo}) +  else(LINUX) +  # Win32 +    list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}}) +    list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}}) +    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}}) +  endif (LINUX)  endforeach(HAVOK_LIB) +endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/LLAppearance.cmake b/indra/cmake/LLAppearance.cmake new file mode 100644 index 0000000000..bd3795a526 --- /dev/null +++ b/indra/cmake/LLAppearance.cmake @@ -0,0 +1,17 @@ +# -*- cmake -*- + +include(Variables) + +set(LLAPPEARANCE_INCLUDE_DIRS +    ${LIBS_OPEN_DIR}/llappearance +    ) + +if (BUILD_HEADLESS) +  set(LLAPPEARANCE_HEADLESS_LIBRARIES +    llappearanceheadless +    ) +endif (BUILD_HEADLESS) + +set(LLAPPEARANCE_LIBRARIES llappearance) + + diff --git a/indra/cmake/LLAppearanceUtility.cmake b/indra/cmake/LLAppearanceUtility.cmake new file mode 100644 index 0000000000..bea45543de --- /dev/null +++ b/indra/cmake/LLAppearanceUtility.cmake @@ -0,0 +1,12 @@ +# -*- cmake -*- +include(Prebuilt) + +# Linux proprietary build only +if (INSTALL_PROPRIETARY) +    if(LINUX) +        use_prebuilt_binary(llappearanceutility-source) +        set(LLAPPEARANCEUTILITY_SRC_DIR ${LIBS_PREBUILT_DIR}/llappearanceutility/src) +        set(LLAPPEARANCEUTILITY_BIN_DIR ${CMAKE_BINARY_DIR}/llappearanceutility) +    endif (LINUX) +endif (INSTALL_PROPRIETARY) + diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index c254bf6f05..b52556a73e 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -10,6 +10,8 @@ set(LLCOMMON_INCLUDE_DIRS      ${LIBS_OPEN_DIR}/llcommon      ${APRUTIL_INCLUDE_DIR}      ${APR_INCLUDE_DIR} +    ) +set(LLCOMMON_SYSTEM_INCLUDE_DIRS      ${Boost_INCLUDE_DIRS}      ) diff --git a/indra/cmake/LLDatabase.cmake b/indra/cmake/LLDatabase.cmake deleted file mode 100644 index 6526101386..0000000000 --- a/indra/cmake/LLDatabase.cmake +++ /dev/null @@ -1,10 +0,0 @@ -# -*- cmake -*- - -include(MySQL) - -set(LLDATABASE_INCLUDE_DIRS -    ${LIBS_SERVER_DIR}/lldatabase -    ${MYSQL_INCLUDE_DIR} -    ) - -set(LLDATABASE_LIBRARIES lldatabase) diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake index 8427928151..ae71ee4c0d 100644 --- a/indra/cmake/LLRender.cmake +++ b/indra/cmake/LLRender.cmake @@ -1,5 +1,6 @@  # -*- cmake -*- +include(Variables)  include(FreeType)  include(GLH) @@ -8,27 +9,12 @@ set(LLRENDER_INCLUDE_DIRS      ${GLH_INCLUDE_DIR}      ) -if (SERVER AND LINUX) -  set(LLRENDER_LIBRARIES -      llrenderheadless -      ) -else (SERVER AND LINUX) +if (BUILD_HEADLESS) +  set(LLRENDER_HEADLESS_LIBRARIES +    llrenderheadless +    ) +endif (BUILD_HEADLESS)  set(LLRENDER_LIBRARIES      llrender      ) -endif (SERVER AND LINUX) -# mapserver requires certain files to be copied so LL_MESA_HEADLESS can be set -# differently for different object files. -macro (copy_server_sources ) -  foreach (PREFIX ${ARGV}) -    add_custom_command( -        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp -        COMMAND ${CMAKE_COMMAND} -        ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}.cpp -             ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp -        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}.cpp -        ) -    list(APPEND server_SOURCE_FILES ${PREFIX}_server.cpp) -  endforeach (PREFIX ${_copied_SOURCES}) -endmacro (copy_server_sources _copied_SOURCES) diff --git a/indra/cmake/LLScene.cmake b/indra/cmake/LLScene.cmake deleted file mode 100644 index 96ad5085a2..0000000000 --- a/indra/cmake/LLScene.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -*- cmake -*- - -set(LLSCENE_INCLUDE_DIRS -    ${LIBS_SERVER_DIR}/llscene -    ) - -set(LLSCENE_LIBRARIES llscene) diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake index b4bb9a078a..0def507e65 100644 --- a/indra/cmake/LLWindow.cmake +++ b/indra/cmake/LLWindow.cmake @@ -1,6 +1,7 @@  # -*- cmake -*- -include(OpenGL) +include(Variables) +include(GLEXT)  include(Prebuilt)  if (STANDALONE) @@ -13,17 +14,15 @@ if (STANDALONE)        SDL_LIBRARY        )  else (STANDALONE) -  use_prebuilt_binary(mesa) -  if (LINUX AND VIEWER) +  if (LINUX)      use_prebuilt_binary(SDL)      set (SDL_FOUND TRUE)      set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/i686-linux)      set (SDL_LIBRARY SDL directfb fusion direct) -  endif (LINUX AND VIEWER) +  endif (LINUX)  endif (STANDALONE)  if (SDL_FOUND) -  add_definitions(-DLL_SDL=1)    include_directories(${SDL_INCLUDE_DIR})  endif (SDL_FOUND) @@ -32,12 +31,12 @@ set(LLWINDOW_INCLUDE_DIRS      ${LIBS_OPEN_DIR}/llwindow      ) -if (SERVER AND LINUX) -  set(LLWINDOW_LIBRARIES -      llwindowheadless -      ) -else (SERVER AND LINUX) -  set(LLWINDOW_LIBRARIES -      llwindow -      ) -endif (SERVER AND LINUX) +if (BUILD_HEADLESS) +  set(LLWINDOW_HEADLESS_LIBRARIES +    llwindowheadless +    ) +endif (BUILD_HEADLESS) + +set(LLWINDOW_LIBRARIES +    llwindow +    ) diff --git a/indra/cmake/LLXML.cmake b/indra/cmake/LLXML.cmake index 64dfdb604f..b093c76297 100644 --- a/indra/cmake/LLXML.cmake +++ b/indra/cmake/LLXML.cmake @@ -5,8 +5,10 @@ include(EXPAT)  set(LLXML_INCLUDE_DIRS      ${LIBS_OPEN_DIR}/llxml -    ${Boost_INCLUDE_DIRS}      ${EXPAT_INCLUDE_DIRS}      ) +set(LLXML_SYSTEM_INCLUDE_DIRS +    ${Boost_INCLUDE_DIRS} +    )  set(LLXML_LIBRARIES llxml) diff --git a/indra/cmake/LLXUIXML.cmake b/indra/cmake/LLXUIXML.cmake deleted file mode 100644 index b8bfe48c77..0000000000 --- a/indra/cmake/LLXUIXML.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -*- cmake -*- - -set(LLXUIXML_INCLUDE_DIRS -    ${LIBS_OPEN_DIR}/llxuixml -    ) - -set(LLXUIXML_LIBRARIES llxuixml) diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake index c3e3a80fd0..b9c9e531fc 100644 --- a/indra/cmake/Linking.cmake +++ b/indra/cmake/Linking.cmake @@ -1,5 +1,8 @@  # -*- cmake -*- +if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) +set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") +  include(Variables)  set(ARCH_PREBUILT_DIRS ${AUTOBUILD_INSTALL_DIR}/lib) @@ -69,3 +72,5 @@ else (WINDOWS)  endif (WINDOWS)  mark_as_advanced(DL_LIBRARY PTHREAD_LIBRARY WINDOWS_LIBRARIES) + +endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/MonoDeps.cmake b/indra/cmake/MonoDeps.cmake deleted file mode 100644 index 52d5491563..0000000000 --- a/indra/cmake/MonoDeps.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# -*- cmake -*- - -set(MONO_PREBUILT_LIBRARIES_DIR ${LIBS_PREBUILT_DIR}/mono/1.0) - -set(MONO_PREBUILT_LIBRARIES -     Iesi.Collections.dll -     Iesi.Collections.pdb -     Mono.CompilerServices.SymbolWriter.dll -     Mono.PEToolkit.dll -     Mono.PEToolkit.pdb -     Mono.Security.dll -     PEAPI.dll -     RAIL.dll -     RAIL.pdb -  ) -   -  set(MONO_CORE_LIBRARIES -    System.dll -    System.Xml.dll -    mscorlib.dll) -     -if(WINDOWS) -    set(MONO_DEPENDENCIES -        DomainCreator -        DomainRegister -        LslLibrary -        LslUserScript -        Script -        ScriptTypes -        TestFormat -        UserScript -        UThread -        UThreadInjector -        ) -else(WINDOWS) -    set(MONO_DEPENDENCIES -        DomainCreator_POST_BUILD -        DomainRegister_POST_BUILD -        LslLibrary_POST_BUILD -        LslUserScript_POST_BUILD -        Script_POST_BUILD -        ScriptTypes_POST_BUILD -        TestFormat_POST_BUILD -        UserScript_POST_BUILD -        UThread_POST_BUILD -        UThreadInjector_POST_BUILD -        ) -endif(WINDOWS) diff --git a/indra/cmake/MonoEmbed.cmake b/indra/cmake/MonoEmbed.cmake deleted file mode 100644 index 30890aed21..0000000000 --- a/indra/cmake/MonoEmbed.cmake +++ /dev/null @@ -1,57 +0,0 @@ -# -*- cmake -*- - -include(Prebuilt) -use_prebuilt_binary(libmono) - -SET(GLIB_2_0 glib-2.0) - -if (WINDOWS) -    SET(MONO_LIB mono)  -else (WINDOWS) -    SET(MONO_LIB mono) -    SET(M_LIBRARIES m) -    SET(GTHREAD_2_0 gthread-2.0) -endif(WINDOWS) - - -IF (DARWIN) - -  FIND_LIBRARY(MONO_LIBRARY NAMES Mono) -  # Find_file doesnt work as expected. Hardcode relative to Mono.framework.  -  #FIND_FILE(GLIB_CONFIG glibconfig.h ${MONO_LIBRARY}) -  #FIND_FILE(MONO_GLIB_LIBRARY glib.h ${MONO_LIBRARY}) -  SET(MONO_GLIB_LIBRARY ${MONO_LIBRARY}/Headers/glib-2.0/) -  SET(GLIB_CONFIG ${MONO_LIBRARY}/Libraries/glib-2.0/include/) -  SET(MONO_LIB_DIRECTORY ${MONO_LIBRARY}/Libraries) - -  IF (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG) -    MESSAGE(STATUS "Found Mono for embedding") -    INCLUDE_DIRECTORIES(${MONO_GLIB_LIBRARY} ${GLIB_CONFIG}) -    LINK_DIRECTORIES(${MONO_LIB_DIRECTORY}) -  ELSE (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG) -    MESSAGE(FATAL_ERROR "Mono not found for embedding")    -    MESSAGE(${MONO_LIBRARY}) -    MESSAGE(${MONO_GLIB_LIBRARY}) -    MESSAGE(${GLIB_CONFIG}) -  ENDIF (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG) - -ELSE (DARWIN) - -  SET(MONO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)   -  SET(GLIB_2_0_PLATFORM_INCLUDE_DIR -    ${LIBS_PREBUILT_DIR}/include/glib-2.0) -  SET(GLIB_2_0_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/glib-2.0) - -  INCLUDE_DIRECTORIES( -    ${MONO_INCLUDE_DIR}  -    ${GLIB_2_0_PLATFORM_INCLUDE_DIR}  -    ${GLIB_2_0_INCLUDE_DIR}) -     -ENDIF (DARWIN)  - -SET(MONO_LIBRARIES  -    ${MONO_LIB}  -    ${M_LIBRARIES}  -    ${GLIB_2_0} -    ${GTHREAD_2_0}  -) diff --git a/indra/cmake/MySQL.cmake b/indra/cmake/MySQL.cmake deleted file mode 100644 index 218482449d..0000000000 --- a/indra/cmake/MySQL.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# -*- cmake -*- -include(Linking) -include(Prebuilt) - -use_prebuilt_binary(mysql) - -if (LINUX) -  if (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1") -    set(MYSQL_LIBRARIES mysqlclient) -    set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) -  else (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1") -    # Use the native MySQL library on a 64-bit system. -    set(MYSQL_FIND_QUIETLY ON) -    set(MYSQL_FIND_REQUIRED ON) -    include(FindMySQL) -  endif (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1") -elseif (WINDOWS) -  set(MYSQL_LIBRARIES mysqlclient) -  set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) -elseif (DARWIN) -  set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) -  set(MYSQL_LIBRARIES -    optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libmysqlclient.a -    debug ${ARCH_PREBUILT_DIRS_DEBUG}/libmysqlclient.a -    ) -endif (LINUX) diff --git a/indra/cmake/OpenGL.cmake b/indra/cmake/OpenGL.cmake index 0a3dd976b4..2259c99293 100644 --- a/indra/cmake/OpenGL.cmake +++ b/indra/cmake/OpenGL.cmake @@ -1,8 +1,12 @@  # -*- cmake -*- + +include(Variables)  include(Prebuilt) -if (NOT STANDALONE) -  use_prebuilt_binary(glext) -  use_prebuilt_binary(glh_linear) -  set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) -endif (NOT STANDALONE) +if (BUILD_HEADLESS) +  SET(OPENGL_glu_LIBRARY GLU) +  SET(OPENGL_HEADLESS_LIBRARIES OSMesa16 dl GLU) +endif (BUILD_HEADLESS) + +include(FindOpenGL) + diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake index dbb4dfc46c..ac0cbde253 100644 --- a/indra/cmake/Prebuilt.cmake +++ b/indra/cmake/Prebuilt.cmake @@ -1,5 +1,8 @@  # -*- cmake -*- +if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) +set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") +  include(FindAutobuild)  if(INSTALL_PROPRIETARY)    include(FindSCP) @@ -51,3 +54,5 @@ macro (use_prebuilt_binary _binary)      endif (NOT ${_binary}_installed EQUAL 0)    endif (NOT STANDALONE_${_binary})  endmacro (use_prebuilt_binary _binary) + +endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake index 748c8c2bec..a81c9307fc 100644 --- a/indra/cmake/Python.cmake +++ b/indra/cmake/Python.cmake @@ -23,7 +23,7 @@ if (WINDOWS)  elseif (EXISTS /etc/debian_version)    # On Debian and Ubuntu, avoid Python 2.4 if possible. -  find_program(PYTHON_EXECUTABLE python2.5 python2.3 python PATHS /usr/bin) +  find_program(PYTHON_EXECUTABLE python PATHS /usr/bin)    if (PYTHON_EXECUTABLE)      set(PYTHONINTERP_FOUND ON) diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake index 91e5258fb7..d0fd4df03a 100644 --- a/indra/cmake/UI.cmake +++ b/indra/cmake/UI.cmake @@ -1,5 +1,6 @@  # -*- cmake -*-  include(Prebuilt) +include(FreeType)  if (STANDALONE)    include(FindPkgConfig) @@ -47,6 +48,7 @@ else (STANDALONE)          pangoft2-1.0          pangox-1.0          pangoxft-1.0 +        ${FREETYPE_LIBRARIES}          )    endif (LINUX) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 4b459f1a48..6ec621632b 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -8,24 +8,20 @@  #   DARWIN  - Mac OS X  #   LINUX   - Linux  #   WINDOWS - Windows -# -# What to build: -# -#   VIEWER - viewer and other viewer-side components -#   SERVER - simulator and other server-side bits  # Relative and absolute paths to subtrees. +if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) +set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") +  if(NOT DEFINED COMMON_CMAKE_DIR)      set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake")  endif(NOT DEFINED COMMON_CMAKE_DIR)  set(LIBS_CLOSED_PREFIX)  set(LIBS_OPEN_PREFIX) -set(LIBS_SERVER_PREFIX)  set(SCRIPTS_PREFIX ../scripts) -set(SERVER_PREFIX)  set(VIEWER_PREFIX)  set(INTEGRATION_TESTS_PREFIX)  set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation") @@ -43,9 +39,7 @@ else(LIBS_COMMON_DIR)  endif(LIBS_COMMON_DIR)  set(LIBS_OPEN_DIR ${LIBS_COMMON_DIR}) -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(AUTOBUILD_INSTALL_DIR ${CMAKE_BINARY_DIR}/packages) @@ -79,21 +73,57 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")    # If someone has specified a word size, use that to determine the    # architecture.  Otherwise, let the architecture specify the word size.    if (WORD_SIZE EQUAL 32) +    #message(STATUS "WORD_SIZE is 32")      set(ARCH i686)    elseif (WORD_SIZE EQUAL 64) +    #message(STATUS "WORD_SIZE is 64")      set(ARCH x86_64)    else (WORD_SIZE EQUAL 32) +    #message(STATUS "WORD_SIZE is UNDEFINED")      execute_process(COMMAND uname -m COMMAND sed s/i.86/i686/                      OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)      if (ARCH STREQUAL x86_64) +      #message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}")        set(WORD_SIZE 64)      else (ARCH STREQUAL x86_64) +      #message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}")        set(WORD_SIZE 32)      endif (ARCH STREQUAL x86_64)    endif (WORD_SIZE EQUAL 32) +  if (WORD_SIZE EQUAL 32) +    set(DEB_ARCHITECTURE i386) +    set(FIND_LIBRARY_USE_LIB64_PATHS OFF) +    set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib32 ${CMAKE_SYSTEM_LIBRARY_PATH}) +  else (WORD_SIZE EQUAL 32) +    set(DEB_ARCHITECTURE amd64) +    set(FIND_LIBRARY_USE_LIB64_PATHS ON) +  endif (WORD_SIZE EQUAL 32) + +  execute_process(COMMAND dpkg-architecture -a${DEB_ARCHITECTURE} -qDEB_HOST_MULTIARCH  +      RESULT_VARIABLE DPKG_RESULT +      OUTPUT_VARIABLE DPKG_ARCH +      OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) +  #message (STATUS "DPKG_RESULT ${DPKG_RESULT}, DPKG_ARCH ${DPKG_ARCH}") +  if (DPKG_RESULT EQUAL 0) +    set(CMAKE_LIBRARY_ARCHITECTURE ${DPKG_ARCH}) +    set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib/${DPKG_ARCH} /usr/local/lib/${DPKG_ARCH} ${CMAKE_SYSTEM_LIBRARY_PATH}) +  endif (DPKG_RESULT EQUAL 0) + +  include(ConfigurePkgConfig) +    set(LL_ARCH ${ARCH}_linux)    set(LL_ARCH_DIR ${ARCH}-linux) + +  if (INSTALL_PROPRIETARY) +    # Only turn on headless if we can find osmesa libraries. +    include(FindPkgConfig) +    #pkg_check_modules(OSMESA osmesa) +    #if (OSMESA_FOUND) +    #  set(BUILD_HEADLESS ON CACHE BOOL "Build headless libraries.") +    #endif (OSMESA_FOUND) +  endif (INSTALL_PROPRIETARY) +  endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")  if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") @@ -140,7 +170,6 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")  # Default deploy grid  set(GRID agni CACHE STRING "Target Grid") -set(VIEWER ON CACHE BOOL "Build Second Life viewer.")  set(VIEWER_CHANNEL "LindenDeveloper" CACHE STRING "Viewer Channel Name")  set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for A/B Testing") @@ -153,21 +182,8 @@ set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")  set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.")  set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.") -if (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics) -    set(SERVER ON CACHE BOOL "Build Second Life server software.") -endif (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics) - -if (LINUX AND SERVER AND VIEWER) -  MESSAGE(FATAL_ERROR " -The indra source does not currently support building SERVER and VIEWER at the same time. -Please set one of these values to OFF in your CMake cache file. -(either by running ccmake or by editing CMakeCache.txt by hand) -For more information, please see JIRA DEV-14943 - Cmake Linux cannot build both VIEWER and SERVER in one build environment -  ") -endif (LINUX AND SERVER AND VIEWER) - -  set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")  source_group("CMake Rules" FILES CMakeLists.txt) +endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/VisualLeakDetector.cmake b/indra/cmake/VisualLeakDetector.cmake index d3ba554e46..27e93e28bb 100644 --- a/indra/cmake/VisualLeakDetector.cmake +++ b/indra/cmake/VisualLeakDetector.cmake @@ -1,15 +1,12 @@  # -*- cmake -*- -if (VIEWER) +set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off") -  set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off") +if (INCLUDE_VLD_CMAKE) -  if (INCLUDE_VLD_CMAKE) +  if (WINDOWS) +    add_definitions(-DINCLUDE_VLD=1) +  endif (WINDOWS) -    if (WINDOWS) -      add_definitions(-DINCLUDE_VLD=1) -    endif (WINDOWS) +endif (INCLUDE_VLD_CMAKE) -  endif (INCLUDE_VLD_CMAKE) - -endif (VIEWER) diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt index af5c9fb2e7..36a7d38bb7 100644 --- a/indra/integration_tests/llimage_libtest/CMakeLists.txt +++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt @@ -16,6 +16,9 @@ include_directories(      ${LLVFS_INCLUDE_DIRS}      ${LLIMAGE_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  set(llimage_libtest_SOURCE_FILES      llimage_libtest.cpp diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt index 91c9f20c10..e83b4e8cd7 100644 --- a/indra/integration_tests/llui_libtest/CMakeLists.txt +++ b/indra/integration_tests/llui_libtest/CMakeLists.txt @@ -34,6 +34,10 @@ include_directories(      ${LLXML_INCLUDE_DIRS}      ${LIBS_PREBUILD_DIR}/include/hunspell      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(llui_libtest_SOURCE_FILES      llui_libtest.cpp diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt index 98ebdc7487..e0d0c9fc69 100644 --- a/indra/linux_crash_logger/CMakeLists.txt +++ b/indra/linux_crash_logger/CMakeLists.txt @@ -20,6 +20,10 @@ include_directories(      ${LLVFS_INCLUDE_DIRS}      ${LLXML_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(linux_crash_logger_SOURCE_FILES      linux_crash_logger.cpp diff --git a/indra/linux_updater/CMakeLists.txt b/indra/linux_updater/CMakeLists.txt new file mode 100644 index 0000000000..4a9e82f9b6 --- /dev/null +++ b/indra/linux_updater/CMakeLists.txt @@ -0,0 +1,57 @@ +# -*- cmake -*- + +project(linux_updater) + +include(00-Common) +include(CURL) +include(CARes) +include(OpenSSL) +include(UI) +include(LLCommon) +include(LLMessage) +include(LLVFS) +include(LLXML) +include(LLUI) +include(Linking) + +include_directories( +    ${LLCOMMON_INCLUDE_DIRS} +    ${LLVFS_INCLUDE_DIRS} +    ${LLXML_INCLUDE_DIRS} +    ${LLUI_INCLUDE_DIRS} +    ${CURL_INCLUDE_DIRS} +    ${CARES_INCLUDE_DIRS} +    ${OPENSSL_INCLUDE_DIRS} +    ${UI_INCLUDE_DIRS} +    ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    ) + +set(linux_updater_SOURCE_FILES linux_updater.cpp) + +set(linux_updater_HEADER_FILES CMakeLists.txt) + +set_source_files_properties(${linux_updater_HEADER_FILES} +                            PROPERTIES HEADER_FILES_ONLY TRUE) + +list(APPEND linux_updater_SOURCE_FILES ${linux_updater_HEADER_FILES}) + +add_executable(linux-updater ${linux_updater_SOURCE_FILES}) + +target_link_libraries(linux-updater +    ${CURL_LIBRARIES} +    ${CARES_LIBRARIES} +    ${OPENSSL_LIBRARIES} +    ${CRYPTO_LIBRARIES} +    ${LLMESSAGE_LIBRARIES} +    ${UI_LIBRARIES} +    ${LLXML_LIBRARIES} +    ${LLUI_LIBRARIES} +    ${LLVFS_LIBRARIES} +    ${LLCOMMON_LIBRARIES} +    ) + +add_custom_target(linux-updater-target ALL +                  DEPENDS linux-updater) diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp new file mode 100644 index 0000000000..86fa596aef --- /dev/null +++ b/indra/linux_updater/linux_updater.cpp @@ -0,0 +1,924 @@ +/** + * @file linux_updater.cpp + * @author Kyle Ambroff <ambroff@lindenlab.com>, Tofu Linden + * @brief Viewer update program for unix platforms that support GTK+ + * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include <unistd.h> +#include <signal.h> +#include <errno.h> + +#include "linden_common.h" +#include "llerrorcontrol.h" +#include "llfile.h" +#include "lldir.h" +#include "lldiriterator.h" + +/*==========================================================================*| +// IQA-490: Use of LLTrans -- by this program at least -- appears to be buggy. +// With it, the 3.3.2 beta 1 linux-updater.bin crashes; without it seems stable. +#include "llxmlnode.h" +#include "lltrans.h" +|*==========================================================================*/ + +static class LLTrans +{ +public: +	LLTrans(); +	static std::string getString(const std::string& key); + +private: +	std::string _getString(const std::string& key) const; + +	typedef std::map<std::string, std::string> MessageMap; +	MessageMap mMessages; +} sLLTransInstance; + +#include <curl/curl.h> +#include <map> +#include <boost/foreach.hpp> + +extern "C" { +#include <gtk/gtk.h> +} + +const guint UPDATE_PROGRESS_TIMEOUT = 100; +const guint UPDATE_PROGRESS_TEXT_TIMEOUT = 1000; +const guint ROTATE_IMAGE_TIMEOUT = 8000; + +typedef struct _updater_app_state { +	std::string app_name; +	std::string url; +	std::string file; +	std::string image_dir; +	std::string dest_dir; +	std::string strings_dirs; +	std::string strings_file; + +	LLDirIterator *image_dir_iter; + +	GtkWidget *window; +	GtkWidget *progress_bar; +	GtkWidget *image; + +	double progress_value; +	bool activity_mode; + +	guint image_rotation_timeout_id; +	guint progress_update_timeout_id; +	guint update_progress_text_timeout_id; + +	bool failure; +} UpdaterAppState; + +// List of entries from strings.xml to always replace +static std::set<std::string> default_trans_args; +void init_default_trans_args() +{ +        default_trans_args.insert("SECOND_LIFE"); // World +        default_trans_args.insert("APP_NAME"); +        default_trans_args.insert("SECOND_LIFE_GRID"); +        default_trans_args.insert("SUPPORT_SITE"); +} + +bool translate_init(std::string comma_delim_path_list, +		    std::string base_xml_name) +{ +	return true; +/*==========================================================================*| +	init_default_trans_args(); + +	// extract paths string vector from comma-delimited flat string +	std::vector<std::string> paths; +	LLStringUtil::getTokens(comma_delim_path_list, paths, ","); // split over ',' + +	for(std::vector<std::string>::iterator it = paths.begin(), end_it = paths.end(); +		it != end_it; +		++it) +	{ +		(*it) = gDirUtilp->findSkinnedFilename(*it, base_xml_name); +	} + +	// suck the translation xml files into memory +	LLXMLNodePtr root; +	bool success = LLXMLNode::getLayeredXMLNode(root, paths); +	if (!success) +	{ +		// couldn't load string table XML +		return false; +	} +	else +	{ +		// get those strings out of the XML +		LLTrans::parseStrings(root, default_trans_args); +		return true; +	} +|*==========================================================================*/ +} + + +void updater_app_ui_init(void); +void updater_app_quit(UpdaterAppState *app_state); +void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state); +std::string next_image_filename(std::string& image_path, LLDirIterator& iter); +void display_error(GtkWidget *parent, std::string title, std::string message); +BOOL install_package(std::string package_file, std::string destination); +BOOL spawn_viewer(UpdaterAppState *app_state); + +extern "C" { +	void on_window_closed(GtkWidget *sender, GdkEvent *event, gpointer state); +	gpointer worker_thread_cb(gpointer *data); +	int download_progress_cb(gpointer data, double t, double d, double utotal, double ulnow); +	gboolean rotate_image_cb(gpointer data); +	gboolean progress_update_timeout(gpointer data); +	gboolean update_progress_text_timeout(gpointer data); +} + +void updater_app_ui_init(UpdaterAppState *app_state) +{ +	GtkWidget *vbox; +	GtkWidget *summary_label; +	GtkWidget *description_label; +	GtkWidget *frame; + +	llassert(app_state != NULL); + +	// set up window and main container +	std::string window_title = LLTrans::getString("UpdaterWindowTitle"); +	app_state->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); +	gtk_window_set_title(GTK_WINDOW(app_state->window), +			     window_title.c_str()); +	gtk_window_set_resizable(GTK_WINDOW(app_state->window), FALSE); +	gtk_window_set_position(GTK_WINDOW(app_state->window), +				GTK_WIN_POS_CENTER_ALWAYS); + +	gtk_container_set_border_width(GTK_CONTAINER(app_state->window), 12); +	g_signal_connect(G_OBJECT(app_state->window), "delete-event", +			 G_CALLBACK(on_window_closed), app_state); + +	vbox = gtk_vbox_new(FALSE, 6); +	gtk_container_add(GTK_CONTAINER(app_state->window), vbox); + +	// set top label +	std::ostringstream label_ostr; +	label_ostr << "<big><b>" +		   << LLTrans::getString("UpdaterNowUpdating") +		   << "</b></big>"; + +	summary_label = gtk_label_new(NULL); +	gtk_label_set_use_markup(GTK_LABEL(summary_label), TRUE); +	gtk_label_set_markup(GTK_LABEL(summary_label), +			     label_ostr.str().c_str()); +	gtk_misc_set_alignment(GTK_MISC(summary_label), 0, 0.5); +	gtk_box_pack_start(GTK_BOX(vbox), summary_label, FALSE, FALSE, 0); + +	// create the description label +	description_label = gtk_label_new(LLTrans::getString("UpdaterUpdatingDescriptive").c_str()); +	gtk_label_set_line_wrap(GTK_LABEL(description_label), TRUE); +	gtk_misc_set_alignment(GTK_MISC(description_label), 0, 0.5); +	gtk_box_pack_start(GTK_BOX(vbox), description_label, FALSE, FALSE, 0); + +	// If an image path has been set, load the background images +	if (!app_state->image_dir.empty()) { +		frame = gtk_frame_new(NULL); +		gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); +		gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); + +		// load the first image +		app_state->image = gtk_image_new_from_file +			(next_image_filename(app_state->image_dir, *app_state->image_dir_iter).c_str()); +		gtk_widget_set_size_request(app_state->image, 340, 310); +		gtk_container_add(GTK_CONTAINER(frame), app_state->image); + +		// rotate the images every 5 seconds +		app_state->image_rotation_timeout_id = g_timeout_add +			(ROTATE_IMAGE_TIMEOUT, rotate_image_cb, app_state); +	} + +	// set up progress bar, and update it roughly every 1/10 of a second +	app_state->progress_bar = gtk_progress_bar_new(); +	gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar), +				  LLTrans::getString("UpdaterProgressBarTextWithEllipses").c_str()); +	gtk_box_pack_start(GTK_BOX(vbox), +			   app_state->progress_bar, FALSE, TRUE, 0); +	app_state->progress_update_timeout_id = g_timeout_add +		(UPDATE_PROGRESS_TIMEOUT, progress_update_timeout, app_state); +	app_state->update_progress_text_timeout_id = g_timeout_add +		(UPDATE_PROGRESS_TEXT_TIMEOUT, update_progress_text_timeout, app_state); + +	gtk_widget_show_all(app_state->window); +} + +gboolean rotate_image_cb(gpointer data) +{ +	UpdaterAppState *app_state; +	std::string filename; + +	llassert(data != NULL); +	app_state = (UpdaterAppState *) data; + +	filename = next_image_filename(app_state->image_dir, *app_state->image_dir_iter); + +	gdk_threads_enter(); +	gtk_image_set_from_file(GTK_IMAGE(app_state->image), filename.c_str()); +	gdk_threads_leave(); + +	return TRUE; +} + +std::string next_image_filename(std::string& image_path, LLDirIterator& iter) +{ +	std::string image_filename; +	iter.next(image_filename); +	return gDirUtilp->add(image_path, image_filename); +} + +void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data) +{ +	UpdaterAppState *app_state; + +	llassert(data != NULL); +	app_state = (UpdaterAppState *) data; + +	updater_app_quit(app_state); +} + +void updater_app_quit(UpdaterAppState *app_state) +{ +	if (app_state != NULL) +	{ +		g_source_remove(app_state->progress_update_timeout_id); + +		if (!app_state->image_dir.empty()) +		{ +			g_source_remove(app_state->image_rotation_timeout_id); +		} +	} + +	gtk_main_quit(); +} + +void display_error(GtkWidget *parent, std::string title, std::string message) +{ +	GtkWidget *dialog; + +	dialog = gtk_message_dialog_new(GTK_WINDOW(parent), +					GTK_DIALOG_DESTROY_WITH_PARENT, +					GTK_MESSAGE_ERROR, +					GTK_BUTTONS_OK, +					"%s", message.c_str()); +	gtk_window_set_title(GTK_WINDOW(dialog), title.c_str()); +	gtk_dialog_run(GTK_DIALOG(dialog)); +	gtk_widget_destroy(dialog); +} + +gpointer worker_thread_cb(gpointer data) +{ +	UpdaterAppState *app_state; +	CURL *curl; +	CURLcode result; +	FILE *package_file; +	GError *error = NULL; +	int fd; + +	//g_return_val_if_fail (data != NULL, NULL); +	app_state = (UpdaterAppState *) data; + +	try { + +		if(!app_state->url.empty()) +		{ +			char* tmp_local_filename = NULL; +			// create temporary file to store the package. +			fd = g_file_open_tmp +				("secondlife-update-XXXXXX", &tmp_local_filename, &error); +			if (error != NULL) +			{ +				llerrs << "Unable to create temporary file: " +					   << error->message +					   << llendl; + +				g_error_free(error); +				throw 0; +			} + +			if(tmp_local_filename != NULL) +			{ +				app_state->file = tmp_local_filename; +				g_free(tmp_local_filename); +			} + +			package_file = fdopen(fd, "wb"); +			if (package_file == NULL) +			{ +				llerrs << "Failed to create temporary file: " +					   << app_state->file.c_str() +					   << llendl; + +				gdk_threads_enter(); +				display_error(app_state->window, +							  LLTrans::getString("UpdaterFailDownloadTitle"), +							  LLTrans::getString("UpdaterFailUpdateDescriptive")); +				gdk_threads_leave(); +				throw 0; +			} + +			// initialize curl and start downloading the package +			llinfos << "Downloading package: " << app_state->url << llendl; + +			curl = curl_easy_init(); +			if (curl == NULL) +			{ +				llerrs << "Failed to initialize libcurl" << llendl; + +				gdk_threads_enter(); +				display_error(app_state->window, +							  LLTrans::getString("UpdaterFailDownloadTitle"), +							  LLTrans::getString("UpdaterFailUpdateDescriptive")); +				gdk_threads_leave(); +				throw 0; +			} + +			curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str()); +			curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE); +			curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE); +			curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file); +			curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); +			curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, +							 &download_progress_cb); +			curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state); + +			result = curl_easy_perform(curl); +			fclose(package_file); +			curl_easy_cleanup(curl); + +			if (result) +			{ +				llerrs << "Failed to download update: " +					   << app_state->url +					   << llendl; + +				gdk_threads_enter(); +				display_error(app_state->window, +							  LLTrans::getString("UpdaterFailDownloadTitle"), +							  LLTrans::getString("UpdaterFailUpdateDescriptive")); +				gdk_threads_leave(); + +				throw 0; +			} +		} + +		// now pulse the progres bar back and forth while the package is +		// being unpacked +		gdk_threads_enter(); +		std::string installing_msg = LLTrans::getString("UpdaterNowInstalling"); +		gtk_progress_bar_set_text( +			GTK_PROGRESS_BAR(app_state->progress_bar), +			installing_msg.c_str()); +		app_state->activity_mode = TRUE; +		gdk_threads_leave(); + +		// *TODO: if the destination is not writable, terminate this +		// thread and show file chooser? +		if (!install_package(app_state->file.c_str(), app_state->dest_dir)) +		{ +			llwarns << "Failed to install package to destination: " +				<< app_state->dest_dir +				<< llendl; + +			gdk_threads_enter(); +			display_error(app_state->window, +						  LLTrans::getString("UpdaterFailInstallTitle"), +						  LLTrans::getString("UpdaterFailUpdateDescriptive")); +			//"Failed to update " + app_state->app_name, +			gdk_threads_leave(); +			throw 0; +		} + +		// try to spawn the new viewer +		if (!spawn_viewer(app_state)) +		{ +			llwarns << "Viewer was not installed properly in : " +				<< app_state->dest_dir +				<< llendl; + +			gdk_threads_enter(); +			display_error(app_state->window, +						  LLTrans::getString("UpdaterFailStartTitle"), +						  LLTrans::getString("UpdaterFailUpdateDescriptive")); +			gdk_threads_leave(); +			throw 0; +		} +	} +	catch (...) +	{ +		app_state->failure = TRUE; +	} + +	gdk_threads_enter(); +	updater_app_quit(app_state); +	gdk_threads_leave(); + +	return NULL; +} + + +gboolean less_anal_gspawnsync(gchar **argv, +			      gchar **stderr_output, +			      gint *child_exit_status, +			      GError **spawn_error) +{ +	// store current SIGCHLD handler if there is one, replace with default +	// handler to make glib happy +	struct sigaction sigchld_backup; +	struct sigaction sigchld_appease_glib; +	sigchld_appease_glib.sa_handler = SIG_DFL; +	sigemptyset(&sigchld_appease_glib.sa_mask); +	sigchld_appease_glib.sa_flags = 0; +	sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup); + +	gboolean rtn = g_spawn_sync(NULL, +				    argv, +				    NULL, +				    (GSpawnFlags) (G_SPAWN_STDOUT_TO_DEV_NULL), +				    NULL, +				    NULL, +				    NULL, +				    stderr_output, +				    child_exit_status, +				    spawn_error); + +	// restore SIGCHLD handler +	sigaction(SIGCHLD, &sigchld_backup, NULL); + +	return rtn; +} + + +// perform a rename, or perform a (prompted) root rename if that fails +int +rename_with_sudo_fallback(const std::string& filename, const std::string& newname) +{ +	int rtncode = ::rename(filename.c_str(), newname.c_str()); +	lldebugs << "rename result is: " << rtncode << " / " << errno << llendl; +	if (rtncode && (EACCES == errno || EPERM == errno || EXDEV == errno)) +	{ +		llinfos << "Permission problem in rename, or moving between different mount points.  Retrying as a mv under a sudo." << llendl; +		// failed due to permissions, try again as a gksudo or kdesu mv wrapper hack +		char *sudo_cmd = NULL; +		sudo_cmd = g_find_program_in_path("gksudo"); +		if (!sudo_cmd) +		{ +			sudo_cmd = g_find_program_in_path("kdesu"); +		} +		if (sudo_cmd) +		{ +			char *mv_cmd = NULL; +			mv_cmd = g_find_program_in_path("mv"); +			if (mv_cmd) +			{ +				char *src_string_copy = g_strdup(filename.c_str()); +				char *dst_string_copy = g_strdup(newname.c_str()); +				char* argv[] = +					{ +						sudo_cmd, +						mv_cmd, +						src_string_copy, +						dst_string_copy, +						NULL +					}; + +				gchar *stderr_output = NULL; +				gint child_exit_status = 0; +				GError *spawn_error = NULL; +				if (!less_anal_gspawnsync(argv, &stderr_output, +							  &child_exit_status, &spawn_error)) +				{ +					llwarns << "Failed to spawn child process: " +						<< spawn_error->message +						<< llendl; +				} +				else if (child_exit_status) +				{ +					llwarns << "mv command failed: " +						<< (stderr_output ? stderr_output : "(no reason given)") +						<< llendl; +				} +				else +				{ +					// everything looks good, clear the error code +					rtncode = 0; +				} + +				g_free(src_string_copy); +				g_free(dst_string_copy); +				if (spawn_error) g_error_free(spawn_error); +			} +		} +	} +	return rtncode; +} + +gboolean install_package(std::string package_file, std::string destination) +{ +	char *tar_cmd = NULL; +	std::ostringstream command; + +	// Find the absolute path to the 'tar' command. +	tar_cmd = g_find_program_in_path("tar"); +	if (!tar_cmd) +	{ +		llerrs << "`tar' was not found in $PATH" << llendl; +		return FALSE; +	} +	llinfos << "Found tar command: " << tar_cmd << llendl; + +	// Unpack the tarball in a temporary place first, then move it to +	// its final destination +	std::string tmp_dest_dir = gDirUtilp->getTempFilename(); +	if (LLFile::mkdir(tmp_dest_dir, 0744)) +	{ +		llerrs << "Failed to create directory: " +		       << destination +		       << llendl; + +		return FALSE; +	} + +	char *package_file_string_copy = g_strdup(package_file.c_str()); +	char *tmp_dest_dir_string_copy = g_strdup(tmp_dest_dir.c_str()); +	gchar *argv[8] = { +		tar_cmd, +		const_cast<gchar*>("--strip"), const_cast<gchar*>("1"), +		const_cast<gchar*>("-xjf"), +		package_file_string_copy, +		const_cast<gchar*>("-C"), tmp_dest_dir_string_copy, +		NULL, +	}; + +	llinfos << "Untarring package: " << package_file << llendl; + +	// store current SIGCHLD handler if there is one, replace with default +	// handler to make glib happy +	struct sigaction sigchld_backup; +	struct sigaction sigchld_appease_glib; +	sigchld_appease_glib.sa_handler = SIG_DFL; +	sigemptyset(&sigchld_appease_glib.sa_mask); +	sigchld_appease_glib.sa_flags = 0; +	sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup); + +	gchar *stderr_output = NULL; +	gint child_exit_status = 0; +	GError *untar_error = NULL; +	if (!less_anal_gspawnsync(argv, &stderr_output, +				  &child_exit_status, &untar_error)) +	{ +		llwarns << "Failed to spawn child process: " +			<< untar_error->message +			<< llendl; +		return FALSE; +	} + +	if (child_exit_status) +	{ +	 	llwarns << "Untar command failed: " +			<< (stderr_output ? stderr_output : "(no reason given)") +			<< llendl; +		return FALSE; +	} + +	g_free(tar_cmd); +	g_free(package_file_string_copy); +	g_free(tmp_dest_dir_string_copy); +	g_free(stderr_output); +	if (untar_error) g_error_free(untar_error); + +	// move the existing package out of the way if it exists +	if (gDirUtilp->fileExists(destination)) +	{ +		std::string backup_dir = destination + ".backup"; +		int oldcounter = 1; +		while (gDirUtilp->fileExists(backup_dir)) +		{ +			// find a foo.backup.N folder name that isn't taken yet +			backup_dir = destination + ".backup." + llformat("%d", oldcounter); +			++oldcounter; +		} + +		if (rename_with_sudo_fallback(destination, backup_dir)) +		{ +			llwarns << "Failed to move directory: '" +				<< destination << "' -> '" << backup_dir +				<< llendl; +			return FALSE; +		} +	} + +	// The package has been unpacked in a staging directory, now we just +	// need to move it to its destination. +	if (rename_with_sudo_fallback(tmp_dest_dir, destination)) +	{ +		llwarns << "Failed to move installation to the destination: " +			<< destination +			<< llendl; +		return FALSE; +	} + +	// \0/ Success! +	return TRUE; +} + +gboolean progress_update_timeout(gpointer data) +{ +	UpdaterAppState *app_state; + +	llassert(data != NULL); + +	app_state = (UpdaterAppState *) data; + +	gdk_threads_enter(); +	if (app_state->activity_mode) +	{ +		gtk_progress_bar_pulse +			(GTK_PROGRESS_BAR(app_state->progress_bar)); +	} +	else +	{ +		gtk_progress_set_value(GTK_PROGRESS(app_state->progress_bar), +				       app_state->progress_value); +	} +	gdk_threads_leave(); + +	return TRUE; +} + +gboolean update_progress_text_timeout(gpointer data) +{ +	UpdaterAppState *app_state; + +	llassert(data != NULL); +	app_state = (UpdaterAppState *) data; + +	if (app_state->activity_mode == TRUE) +	{ +		// We no longer need this timeout, it will be removed. +		return FALSE; +	} + +	if (!app_state->progress_value) +	{ +		return TRUE; +	} + +	std::string progress_text = llformat((LLTrans::getString("UpdaterProgressBarText")+" (%.0f%%)").c_str(), app_state->progress_value); + +	gdk_threads_enter(); +	gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar), +				  progress_text.c_str()); +	gdk_threads_leave(); + +	return TRUE; +} + +int download_progress_cb(gpointer data, +			 double t, +			 double d, +			 double utotal, +			 double ulnow) +{ +	UpdaterAppState *app_state; + +	llassert(data != NULL); +	app_state = (UpdaterAppState *) data; + +	if (t <= 0.0) +	{ +		app_state->progress_value = 0; +	} +	else +	{ +		app_state->progress_value = d * 100.0 / t; +	} +	return 0; +} + +BOOL spawn_viewer(UpdaterAppState *app_state) +{ +	llassert(app_state != NULL); + +	std::string cmd = app_state->dest_dir + "/secondlife"; +	GError *error = NULL; + +	// We want to spawn the Viewer on the same display as the updater app +	gboolean success = gdk_spawn_command_line_on_screen +		(gtk_widget_get_screen(app_state->window), cmd.c_str(), &error); + +	if (!success) +	{ +		llwarns << "Failed to launch viewer: " << error->message +			<< llendl; +	} + +	if (error) g_error_free(error); + +	return success; +} + +void show_usage_and_exit() +{ +	std::cout << "Usage: linux-updater <--url URL | --file FILE> --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE" +		  << "[--image-dir PATH]" +		  << std::endl; +	exit(1); +} + +void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state) +{ +	int i; + +	for (i = 1; i < argc; i++) +	{ +		if ((!strcmp(argv[i], "--url")) && (++i < argc)) +		{ +			app_state->url = argv[i]; +		} +		else if ((!strcmp(argv[i], "--file")) && (++i < argc)) +		{ +			app_state->file = argv[i]; +		} +		else if ((!strcmp(argv[i], "--name")) && (++i < argc)) +		{ +			app_state->app_name = argv[i]; +		} +		else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc)) +		{ +			app_state->image_dir = argv[i]; +			app_state->image_dir_iter = new LLDirIterator(argv[i], "*.jpg"); +		} +		else if ((!strcmp(argv[i], "--dest")) && (++i < argc)) +		{ +			app_state->dest_dir = argv[i]; +		} +		else if ((!strcmp(argv[i], "--stringsdir")) && (++i < argc)) +		{ +			app_state->strings_dirs = argv[i]; +		} +		else if ((!strcmp(argv[i], "--stringsfile")) && (++i < argc)) +		{ +			app_state->strings_file = argv[i]; +		} +		else +		{ +			// show usage, an invalid option was given. +			show_usage_and_exit(); +		} +	} + +	if (app_state->app_name.empty() +	    || (app_state->url.empty() && app_state->file.empty()) +	    || app_state->dest_dir.empty()) +	{ +		show_usage_and_exit(); +	} + +	app_state->progress_value = 0.0; +	app_state->activity_mode = FALSE; +	app_state->failure = FALSE; + +	translate_init(app_state->strings_dirs, app_state->strings_file); +} + +int main(int argc, char **argv) +{ +	UpdaterAppState* app_state = new UpdaterAppState; + +	parse_args_and_init(argc, argv, app_state); + +	// Initialize logger, and rename old log file +	gDirUtilp->initAppDirs("SecondLife"); +	LLError::initForApplication +		(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); +	std::string old_log_file = gDirUtilp->getExpandedFilename +		(LL_PATH_LOGS, "updater.log.old"); +	std::string log_file = +		gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log"); +	LLFile::rename(log_file, old_log_file); +	LLError::logToFile(log_file); + +	// initialize gthreads and gtk+ +	if (!g_thread_supported()) +	{ +		g_thread_init(NULL); +		gdk_threads_init(); +	} + +	gtk_init(&argc, &argv); + +	// create UI +	updater_app_ui_init(app_state); + +	//llinfos << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << llendl; + +	// create download thread +	g_thread_create(GThreadFunc(worker_thread_cb), app_state, FALSE, NULL); + +	gdk_threads_enter(); +	gtk_main(); +	gdk_threads_leave(); + +	// Delete the file only if created from url download. +	if(!app_state->url.empty() && !app_state->file.empty()) +	{ +		if (gDirUtilp->fileExists(app_state->file)) +		{ +			LLFile::remove(app_state->file); +		} +	} + +	bool success = !app_state->failure; +	delete app_state->image_dir_iter; +	delete app_state; +	return success ? 0 : 1; +} + +/***************************************************************************** +*   Dummy LLTrans implementation (IQA-490) +*****************************************************************************/ +static LLTrans sStaticStrings; + +// lookup +std::string LLTrans::_getString(const std::string& key) const +{ +	MessageMap::const_iterator found = mMessages.find(key); +	if (found != mMessages.end()) +	{ +		return found->second; +	} +	LL_WARNS("linux_updater") << "No message for key '" << key +							  << "' -- add to LLTrans::LLTrans() in linux_updater.cpp" +							  << LL_ENDL; +	return key; +} + +// static lookup +std::string LLTrans::getString(const std::string& key) +{ +    return sLLTransInstance._getString(key); +} + +// initialization +LLTrans::LLTrans() +{ +	typedef std::pair<const char*, const char*> Pair; +	static const Pair data[] = +	{ +		Pair("UpdaterFailDownloadTitle", +			 "Failed to download update"), +		Pair("UpdaterFailInstallTitle", +			 "Failed to install update"), +		Pair("UpdaterFailStartTitle", +			 "Failed to start viewer"), +		Pair("UpdaterFailUpdateDescriptive", +			 "An error occurred while updating Second Life. " +			 "Please download the latest version from www.secondlife.com."), +		Pair("UpdaterNowInstalling", +			 "Installing Second Life..."), +		Pair("UpdaterNowUpdating", +			 "Now updating Second Life..."), +		Pair("UpdaterProgressBarText", +			 "Downloading update"), +		Pair("UpdaterProgressBarTextWithEllipses", +			 "Downloading update..."), +		Pair("UpdaterUpdatingDescriptive", +			 "Your Second Life Viewer is being updated to the latest release. " +			 "This may take some time, so please be patient."), +		Pair("UpdaterWindowTitle", +			 "Second Life Update") +	}; + +	BOOST_FOREACH(Pair pair, data) +	{ +		mMessages[pair.first] = pair.second; +	} +} diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt new file mode 100644 index 0000000000..0dbd58b7cd --- /dev/null +++ b/indra/llappearance/CMakeLists.txt @@ -0,0 +1,118 @@ +# -*- cmake -*- + +project(llappearance) + +include(00-Common) +include(LLCommon) +include(LLCharacter) +include(LLImage) +include(LLInventory) +include(LLMath) +include(LLMessage) +include(LLRender) +include(LLVFS) +include(LLWindow) +include(LLXML) +include(Linking) + +include_directories( +    ${LLCOMMON_INCLUDE_DIRS} +    ${LLCHARACTER_INCLUDE_DIRS} +    ${LLIMAGE_INCLUDE_DIRS} +    ${LLINVENTORY_INCLUDE_DIRS} +    ${LLMATH_INCLUDE_DIRS} +    ${LLRENDER_INCLUDE_DIRS} +    ${LLVFS_INCLUDE_DIRS} +    ${LLWINDOW_INCLUDE_DIRS} +    ${LLXML_INCLUDE_DIRS} +    ) + +set(llappearance_SOURCE_FILES +    llavatarappearance.cpp +    llavatarjoint.cpp +    llavatarjointmesh.cpp +    lldriverparam.cpp +    lllocaltextureobject.cpp +    llpolyskeletaldistortion.cpp +    llpolymesh.cpp +    llpolymorph.cpp +    lltexglobalcolor.cpp +    lltexlayer.cpp +    lltexlayerparams.cpp +    lltexturemanagerbridge.cpp +    llwearable.cpp +    llwearabledata.cpp +    llwearabletype.cpp +    llviewervisualparam.cpp +    llavatarappearancedefines.cpp +    ) +     +set(llappearance_HEADER_FILES +    CMakeLists.txt + +    llavatarappearance.h +    llavatarjoint.h +    llavatarjointmesh.h +    lldriverparam.h +    lljointpickname.h +    lllocaltextureobject.h +    llpolyskeletaldistortion.h +    llpolymesh.h +    llpolymorph.h +    lltexglobalcolor.h +    lltexlayer.h +    lltexlayerparams.h +    lltexturemanagerbridge.h +    llwearable.h +    llwearabledata.h +    llwearabletype.h +    llviewervisualparam.h +    llavatarappearancedefines.h +    ) + +set_source_files_properties(${llappearance_HEADER_FILES} +                            PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES}) + +add_library (llappearance ${llappearance_SOURCE_FILES}) + +target_link_libraries(llappearance +    ${LLCHARACTER_LIBRARIES} +    ${LLINVENTORY_LIBRARIES} +    ${LLIMAGE_LIBRARIES} +    ${LLRENDER_LIBRARIES} +    ${LLVFS_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${LLXML_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${LLCOMMON_LIBRARIES} +    ) + +if (BUILD_HEADLESS) +  add_library (llappearanceheadless ${llappearance_SOURCE_FILES}) +   +  target_link_libraries(llappearanceheadless +      ${LLCHARACTER_LIBRARIES} +      ${LLINVENTORY_LIBRARIES} +      ${LLIMAGE_LIBRARIES} +      ${LLRENDERHEADLESS_LIBRARIES} +      ${LLVFS_LIBRARIES} +      ${LLMATH_LIBRARIES} +      ${LLXML_LIBRARIES} +      ${LLMATH_LIBRARIES} +      ${LLCOMMON_LIBRARIES} +      ) +endif (BUILD_HEADLESS) + +#add unit tests +#if (LL_TESTS) +#    INCLUDE(LLAddBuildTest) +#    SET(llappearance_TEST_SOURCE_FILES +#      # no real unit tests yet! +#      ) +#    LL_ADD_PROJECT_UNIT_TESTS(llappearance "${llappearance_TEST_SOURCE_FILES}") + +    #set(TEST_DEBUG on) +#    set(test_libs llappearance ${LLCOMMON_LIBRARIES}) +#endif (LL_TESTS) diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp new file mode 100644 index 0000000000..3bb759d458 --- /dev/null +++ b/indra/llappearance/llavatarappearance.cpp @@ -0,0 +1,1953 @@ +/**  + * @File llavatarappearance.cpp + * @brief Implementation 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$ + */ + +#if LL_MSVC +// disable warning about boost::lexical_cast returning uninitialized data +// when it fails to parse the string +#pragma warning (disable:4701) +#endif + +#include "linden_common.h" + +#include "llavatarappearance.h" +#include "llavatarappearancedefines.h" +#include "llavatarjointmesh.h" +#include "imageids.h" +#include "lldir.h" +#include "lldeleteutils.h" +#include "llpolymorph.h" +#include "llpolymesh.h" +#include "llpolyskeletaldistortion.h" +#include "llstl.h" +#include "lltexglobalcolor.h" +#include "llwearabledata.h" + + +#if LL_MSVC +// disable boost::lexical_cast warning +#pragma warning (disable:4702) +#endif + +#include <boost/lexical_cast.hpp> + +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<LLAvatarBoneInfo*> 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<LLAvatarBoneInfo*> 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) +{ +	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<std::string>(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); +		} +	} + +	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(); +	mJointMap.clear(); + +	clearSkeleton(); +	deleteAndClearArray(mCollisionVolumes); + +	deleteAndClear(mTexSkinColor); +	deleteAndClear(mTexHairColor); +	deleteAndClear(mTexEyeColor); + +	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; +	} + +	//------------------------------------------------------------------------- +	// <linden_avatar version="1.0"> (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); +	// *TODO: What about 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(); + +	F32 old_offset = mAvatarOffset.mV[VZ]; + +	mAvatarOffset.mV[VZ] = getVisualParamWeight(AVATAR_HOVER); + +	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; + +	mAvatarOffset.mV[VX] = 0.0f; +	mAvatarOffset.mV[VY] = 0.0f; + +	// Certain configurations of avatars can force the overall height (with offset) to go negative. +	// Enforce a constraint to make sure we don't go below 0.1 meters. +	// Camera positioning and other things start to break down when your avatar is "walking" while being fully underground +	if (new_body_size.mV[VZ] + mAvatarOffset.mV[VZ] < 0.1f)  +	{ +		mAvatarOffset.mV[VZ] = -(new_body_size.mV[VZ] - 0.11f); // avoid floating point rounding making the above check continue to fail. + +		llassert(new_body_size.mV[VZ] + mAvatarOffset.mV[VZ] >= 0.1f); + +		if (mWearableData && isSelf())  +		{ +			LLWearable* shape = mWearableData->getWearable(LLWearableType::WT_SHAPE, 0); +			if (shape)  +			{ +				shape->setVisualParamWeight(AVATAR_HOVER, mAvatarOffset.mV[VZ], false); +			} +		} +	} + +	if (new_body_size != mBodySize || old_offset != mAvatarOffset.mV[VZ]) +	{ +		mBodySize = new_body_size; +		bodySizeChanged(); +	} +} + +//----------------------------------------------------------------------------- +// parseSkeletonFile() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename) +{ +	//------------------------------------------------------------------------- +	// 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) +{ +	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)); +	} + +	return TRUE; +} + + +//----------------------------------------------------------------------------- +// buildSkeleton() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info) +{ +	//------------------------------------------------------------------------- +	// 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() +{ +	//------------------------------------------------------------------------- +	// 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(); + +// 	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(); + +} + +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 : <skeleton> +	if( !loadSkeletonNode() ) +	{ +		llwarns << "avatar file: loadNodeSkeleton() failed" << llendl; +		return FALSE; +	} +	 +	// avatar_lad.xml : <mesh> +	if( !loadMeshNodes() ) +	{ +		llwarns << "avatar file: loadNodeMesh() failed" << llendl; +		return FALSE; +	} +	 +	// avatar_lad.xml : <global_color> +	if( sAvatarXmlInfo->mTexSkinColorInfo ) +	{ +		mTexSkinColor = new LLTexGlobalColor( this ); +		if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) ) +		{ +			llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl; +			return FALSE; +		} +	} +	else +	{ +		llwarns << "<global_color> 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 << "<global_color> 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 << "<global_color> name=\"eye_color\" not found" << llendl; +		return FALSE; +	} +	 +	// avatar_lad.xml : <layer_set> +	if (sAvatarXmlInfo->mLayerInfoList.empty()) +	{ +		llwarns << "avatar file: missing <layer_set> node" << llendl; +		return FALSE; +	} + +	if (sAvatarXmlInfo->mMorphMaskInfoList.empty()) +	{ +		llwarns << "avatar file: missing <morph_masks> node" << llendl; +		return FALSE; +	} + +	// avatar_lad.xml : <morph_masks> +	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 : <driver_parameters> +	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 " << getID().asString() << " 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 <skeleton> 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 <mesh> 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: <mesh> 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 << "<layer_set> 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 > mNumCollisionVolumes) +	{ +		return LLVector3::zero; +	} + +	return mCollisionVolumes[joint_index].getVolumePos(volume_offset); +} + +//----------------------------------------------------------------------------- +// findCollisionVolume() +//----------------------------------------------------------------------------- +LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id) +{ +	if ((S32)volume_id > mNumCollisionVolumes) +	{ +		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(); +} + + + +// 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 <skeleton> nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root) +{ +	LLXmlTreeNode* node = root->getChildByName( "skeleton" ); +	if( !node ) +	{ +		llwarns << "avatar file: missing <skeleton>" << 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 <mesh> 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: <mesh> 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: <mesh> 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: <mesh> 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 <global_color> 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 <layer_set> 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 <driver_parameters> 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 <driver_parameters> 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<LLPolyMorphTarget*>(morph_target); +	if (target) +	{ +		target->addPendingMorphMask(); +	} +} + + + diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h new file mode 100644 index 0000000000..bce2540258 --- /dev/null +++ b/indra/llappearance/llavatarappearance.h @@ -0,0 +1,448 @@ +/** + * @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(); + +/**                    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; } + +	 +/**                    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<std::string, LLJoint*> 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<LLAvatarJoint*> avatar_joint_list_t; +	avatar_joint_list_t	mSkeleton; +	 +	//-------------------------------------------------------------------- +	// Pelvis height adjustment members. +	//-------------------------------------------------------------------- +public: +	LLVector3			mBodySize; +	LLVector3			mAvatarOffset; +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<std::string, LLPolyMesh*> 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<LLMaskedMorph *> 	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> 	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<LLViewerVisualParamInfo*,BOOL> morph_info_pair_t; // LLPolyMorphTargetInfo stored here +			typedef std::vector<morph_info_pair_t> 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<LLAvatarMeshInfo*> mesh_info_list_t; +		mesh_info_list_t mMeshInfoList; + +		typedef std::vector<LLViewerVisualParamInfo*> 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<LLAvatarAttachmentInfo*> attachment_info_list_t; +		attachment_info_list_t mAttachmentInfoList; + +		LLTexGlobalColorInfo *mTexSkinColorInfo; +		LLTexGlobalColorInfo *mTexHairColorInfo; +		LLTexGlobalColorInfo *mTexEyeColorInfo; + +		typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t; +		layer_info_list_t mLayerInfoList; + +		typedef std::vector<LLDriverParamInfo*> 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<LLAvatarMorphInfo*> 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 index 1ed4e3b61c..f1c78946a1 100644 --- a/indra/newview/llvoavatardefines.cpp +++ b/indra/llappearance/llavatarappearancedefines.cpp @@ -1,6 +1,6 @@  /**  - * @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=viewerlgpl$   * Second Life Viewer Source Code @@ -24,21 +24,20 @@   * $/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.   */ -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)); @@ -66,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,   @@ -110,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++)  	{ @@ -160,7 +159,7 @@ void LLVOAvatarDictionary::createAssociations()  } -LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name, +LLAvatarAppearanceDictionary::TextureEntry::TextureEntry(const std::string &name,  												 bool is_local_texture,   												 EBakedTextureIndex baked_texture_index,  												 const std::string &default_image_name, @@ -175,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, @@ -216,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 @@ -239,23 +238,30 @@ 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 == "") -	{ -		return IMG_DEFAULT_AVATAR; -	} -	else +	U8 index = 0; +	while (index < BAKED_NUM_INDICES)  	{ -		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 index 35bb37463a..8a1d2c4707 100644 --- a/indra/newview/llvoavatardefines.h +++ b/indra/llappearance/llavatarappearancedefines.h @@ -1,6 +1,6 @@  /**  - * @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=viewerlgpl$ @@ -25,26 +25,30 @@   * $/LicenseInfo$   */ -#ifndef LLVOAVATAR_DEFINES_H -#define LLVOAVATAR_DEFINES_H +#ifndef LL_AVATARAPPEARANCE_DEFINES_H +#define LL_AVATARAPPEARANCE_DEFINES_H  #include <vector> -#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;  extern const S32 SCRATCH_TEX_HEIGHT;  extern const S32 IMPOSTOR_PERIOD; +static const U32 AVATAR_HOVER = 11001; +  //--------------------------------------------------------------------  // Enums  //--------------------------------------------------------------------  enum ETextureIndex  { +	TEX_INVALID = -1,  	TEX_HEAD_BODYPAINT = 0,  	TEX_UPPER_SHIRT,  	TEX_LOWER_PANTS, @@ -111,21 +115,21 @@ typedef std::vector<EMeshIndex> mesh_vec_t;  typedef std::vector<LLWearableType::EType> 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<LLVOAvatarDictionary> +class LLAvatarAppearanceDictionary : public LLSingleton<LLAvatarAppearanceDictionary>  {  	//--------------------------------------------------------------------  	// Constructors and Destructors  	//--------------------------------------------------------------------  public: -	LLVOAvatarDictionary(); -	virtual ~LLVOAvatarDictionary(); +	LLAvatarAppearanceDictionary(); +	virtual ~LLAvatarAppearanceDictionary();  private:  	void createAssociations(); @@ -166,20 +170,20 @@ public:  		MeshEntry(EBakedTextureIndex baked_index,   				  const std::string &name, // names of mesh types as they are used in avatar_lad.xml  				  U8 level, -				  LLViewerJoint::PickName pick); +				  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 LLJointPickName 	mPickName;  	}; -	struct Meshes : public LLDictionary<EMeshIndex, MeshEntry> +	struct MeshEntries : public LLDictionary<EMeshIndex, MeshEntry>  	{ -		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 @@ -215,14 +219,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 //LL_VO_AVATARDEFINES_H +#endif //LL_AVATARAPPEARANCE_DEFINES_H diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp new file mode 100644 index 0000000000..6ab341af64 --- /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<LLAvatarJoint*>(*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<LLAvatarJoint*>(*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<LLAvatarJoint*>(*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<LLAvatarJoint*>(*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<LLAvatarJoint*>(*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<LLAvatarJoint*>(*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 0000000000..fec91503c7 --- /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 0000000000..4a5cff1dc3 --- /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; sj<mNumSkinJoints; sj++) +	{ +		LLSkinJoint &js = mSkinJoints[sj]; + +		if (js.mJoint != current_joint) +		{ +			continue; +		} + +		// we've found a skinjoint for this joint.. + +		// is the last joint in the array our parent? +		if(mMesh->mJointRenderData.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 0000000000..6486932cdf --- /dev/null +++ b/indra/llappearance/llavatarjointmesh.h @@ -0,0 +1,145 @@ +/**  + * @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<LLGLTexture>		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); + +	// 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; }	 + +	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 index 885cae1737..1f7e8b8652 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,67 +176,25 @@ 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;  } -#if 0 // obsolete -BOOL LLDriverParam::parseData(LLXmlTreeNode* node) -{ -	LLDriverParamInfo* info = new LLDriverParamInfo; - -	info->parseXml(node); -	if (!setInfo(info)) -	{ -		delete info; -		return FALSE; -	} -	return TRUE; -} -#endif -  void LLDriverParam::setWeight(F32 weight, BOOL upload_bake)  {  	F32 min_weight = getMinWeight(); @@ -456,6 +413,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 >= mDriven.size()) +	{ +		return NULL; +	} +	return mDriven[index].mParam; +} +  //-----------------------------------------------------------------------------  // setAnimationTarget()  //----------------------------------------------------------------------------- @@ -511,6 +482,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 +527,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 +595,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<LLWearable*> (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 index 216cf003e1..040c9cf5be 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,6 +71,7 @@ public:  protected:  	typedef std::deque<LLDrivenEntryInfo> entry_info_list_t;  	entry_info_list_t mDrivenInfoList; +	LLDriverParam* mDriverParam; // backpointer  };  //----------------------------------------------------------------------------- @@ -78,10 +79,11 @@ protected:  LL_ALIGN_PREFIX(16)  class LLDriverParam : public LLViewerVisualParam  { -	friend class LLPhysicsMotion; // physics motion needs to access driven params directly. +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) @@ -99,14 +101,14 @@ public:  	//   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;  	// LLVisualParam Virtual functions -	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node);  	/*virtual*/ void				apply( ESex sex ) {} // apply is called separately for each driven param.  	/*virtual*/ void				setWeight(F32 weight, BOOL upload_bake);  	/*virtual*/ void				setAnimationTarget( F32 target_value, BOOL upload_bake ); @@ -122,6 +124,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); @@ -132,7 +137,7 @@ protected:  	entry_list_t mDriven;  	LLViewerVisualParam* mCurrentDistortionParam;  	// Backlink only; don't make this an LLPointer. -	LLVOAvatar* mAvatarp; +	LLAvatarAppearance* mAvatarAppearance;  	LLWearable* mWearablep;  } LL_ALIGN_POSTFIX(16); diff --git a/indra/llappearance/lljointpickname.h b/indra/llappearance/lljointpickname.h new file mode 100644 index 0000000000..1d41a761fc --- /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<LLAvatarJointMesh*> avatar_joint_mesh_list_t; + +#endif // LL_LLJOINTPICKNAME_H diff --git a/indra/newview/lllocaltextureobject.cpp b/indra/llappearance/lllocaltextureobject.cpp index 07ec0fab95..7e36a06797 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 index b9bfc5472f..9b9f41fd19 100644 --- a/indra/newview/lllocaltextureobject.h +++ b/indra/llappearance/lllocaltextureobject.h @@ -29,11 +29,10 @@  #include <boost/shared_ptr.hpp> -#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<LLViewerFetchedTexture>  			mImage; +	LLPointer<LLGLTexture>			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 index 5f5258bbce..a01457246e 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 "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); @@ -241,7 +240,7 @@ BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )  			mBaseNormals[i].clear();  			mBaseBinormals[i].clear();  			mTexCoords[i].clear(); -			mWeights[i] = 0.f; +            mWeights[i] = 0.f;          }          mNumVertices = numVertices;          return TRUE; @@ -1046,250 +1045,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 index 28da230541..ef1dfb1adb 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 <string>  #include <map> @@ -39,7 +39,7 @@  //#include "lldarray.h"  class LLSkinJoint; -class LLVOAvatar; +class LLAvatarAppearance;  class LLWearable;  //#define USE_STRIPS	// Use tri-strips for rendering. @@ -319,8 +319,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<LLJointRenderData*>	mJointRenderData; @@ -362,90 +362,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<LLPolySkeletalBoneInfo> bone_info_list_t; -	bone_info_list_t mBoneInfoList; -}; - -//----------------------------------------------------------------------------- -// LLPolySkeletalDeformation -// A set of joint scale data for deforming the avatar mesh -//----------------------------------------------------------------------------- - -LL_ALIGN_PREFIX(16) -class LLPolySkeletalDistortion : public LLViewerVisualParam -{ -public: -	LLPolySkeletalDistortion(LLVOAvatar *avatarp); -	~LLPolySkeletalDistortion(); - -	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 -	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: -	LL_ALIGN_16(LLVector4a	mDefaultVec); - -	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t; -	joint_vec_map_t mJointScales; -	joint_vec_map_t mJointOffsets; -	// Backlink only; don't make this an LLPointer. -	LLVOAvatar *mAvatar; -} LL_ALIGN_POSTFIX(16); - -#endif // LL_LLPOLYMESH_H +#endif // LL_LLPOLYMESHINTERFACE_H diff --git a/indra/newview/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index 495fdc348c..8a17819083 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -27,13 +27,14 @@  //-----------------------------------------------------------------------------  // Header Files  //----------------------------------------------------------------------------- -#include "llviewerprecompiledheaders.h"  #include "llpolymorph.h" -#include "llvoavatar.h" +#include "llavatarappearance.h" +#include "llavatarjoint.h"  #include "llwearable.h"  #include "llxmltree.h"  #include "llendianswizzle.h" +#include "llpolymesh.h"  //#include "../tools/imdebug/imdebug.h" @@ -343,7 +344,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 index 24940c52e0..ee380ae7c3 100644 --- a/indra/newview/llpolymorph.h +++ b/indra/llappearance/llpolymorph.h @@ -32,10 +32,10 @@  #include "llviewervisualparam.h" +class LLAvatarJointCollisionVolume;  class LLPolyMeshSharedData; -class LLVOAvatar;  class LLVector2; -class LLViewerJointCollisionVolume; +class LLAvatarJointCollisionVolume;  class LLWearable;  //----------------------------------------------------------------------------- @@ -119,10 +119,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 0000000000..4ba16691c2 --- /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 0000000000..774bc7dfa2 --- /dev/null +++ b/indra/llappearance/llpolyskeletaldistortion.h @@ -0,0 +1,131 @@ +/**  + * @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 <string> +#include <map> +#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; +}; + +LL_ALIGN_PREFIX(16) +class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo +{ +	friend class LLPolySkeletalDistortion; +public: +	 +	LLPolySkeletalDistortionInfo(); +	/*virtual*/ ~LLPolySkeletalDistortionInfo() {}; +	 +	/*virtual*/ BOOL parseXml(LLXmlTreeNode* node); + +protected: +	typedef std::vector<LLPolySkeletalBoneInfo> 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: +	LL_ALIGN_16(LLVector4a mDefaultVec); +	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t; +	joint_vec_map_t mJointScales; +	joint_vec_map_t mJointOffsets; +	// Backlink only; don't make this an LLPointer. +	LLAvatarAppearance *mAvatar; +} LL_ALIGN_POSTFIX(16); + +#endif // LL_LLPOLYSKELETALDISTORTION_H + diff --git a/indra/newview/lltexglobalcolor.cpp b/indra/llappearance/lltexglobalcolor.cpp index ebe5ccd6c0..f38b982104 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 index ae04798445..2867479876 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 index ad09af6594..f951a982e5 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 "../llui/llui.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; } @@ -96,125 +89,17 @@ private:  };  //----------------------------------------------------------------------------- -// 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.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 @@ -222,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(); @@ -238,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; @@ -305,42 +150,20 @@ BOOL LLTexLayerSetBuffer::render()  		gAlphaMaskProgram.bind();  		gAlphaMaskProgram.setMinimumAlpha(0.004f);  	} +	else +	{ +		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.00f); +	}  	LLVertexBuffer::unbind();  	// 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)  	{ @@ -353,374 +176,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<LLImageRaw> 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<LLImageRaw> 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<LLImageJ2C> 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<LLImageJ2C> integrity_test = new LLImageJ2C; -			S32 file_size = 0; -			 -			//data buffer MUST be allocated using LLImageBase -			LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE); -			file_size = file.getSize(); -			U8* data = integrity_test->allocateData(file_size); -			file.read(data, 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.  //----------------------------------------------------------------------------- @@ -790,7 +250,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(); @@ -798,7 +258,7 @@ void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar)  		 layer_iter++)  	{  		LLTexLayerInfo *layer_info = *layer_iter; -		layer_info->createVisualParams(avatar); +		layer_info->createVisualParams(appearance);  	}  } @@ -809,16 +269,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(); @@ -844,13 +303,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; @@ -910,21 +369,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 )  { @@ -1025,43 +469,31 @@ const std::string LLTexLayerSet::getBodyRegionName() const  	return mInfo->mBodyRegion;   } -void LLTexLayerSet::requestUpdate() -{ -	if( mUpdatesEnabled ) -	{ -		createComposite(); -		mComposite->requestUpdate();  -	} -} - -void LLTexLayerSet::requestUpload() -{ -	createComposite(); -	mComposite->requestUpload(); -} -void LLTexLayerSet::cancelUpload() +// virtual +void LLTexLayerSet::asLLSD(LLSD& sd) const  { -	if(mComposite) +	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);  	{ -		mComposite->cancelUpload(); +		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::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()  { @@ -1071,18 +503,6 @@ void LLTexLayerSet::destroyComposite()  	}  } -void LLTexLayerSet::setUpdatesEnabled( BOOL b ) -{ -	mUpdatesEnabled = b;  -} - - -void LLTexLayerSet::updateComposite() -{ -	createComposite(); -	mComposite->requestUpdateImmediate(); -} -  LLTexLayerSetBuffer* LLTexLayerSet::getComposite()  {  	if (!mComposite) @@ -1097,22 +517,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; @@ -1125,7 +549,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; @@ -1182,7 +606,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 @@ -1297,11 +721,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; @@ -1368,7 +792,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(); @@ -1376,7 +800,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; @@ -1390,7 +814,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; @@ -1498,6 +922,59 @@ 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) +	{ +		LLWearableType::EType type = LLWearableType::WT_INVALID; +		param_color_list_t::const_iterator color_iter = mParamColorList.begin(); +		param_alpha_list_t::const_iterator alpha_iter = mParamAlphaList.begin(); + +		for (; color_iter != mParamColorList.end(); color_iter++) +		{ +			LLTexLayerParamColor* param = *color_iter; +			if (param)  +			{ +				LLWearableType::EType new_type = (LLWearableType::EType)param->getWearableType(); +				if (new_type != LLWearableType::WT_INVALID && new_type != type)  +				{ +					if (type != LLWearableType::WT_INVALID)  +					{ +						return LLWearableType::WT_INVALID; +					} +					type = new_type; +				} +			} +		} + +		for (; alpha_iter != mParamAlphaList.end(); alpha_iter++) +		{ +			LLTexLayerParamAlpha* param = *alpha_iter; +			if (param)  +			{ +				LLWearableType::EType new_type = (LLWearableType::EType)param->getWearableType(); +				if (new_type != LLWearableType::WT_INVALID && new_type != type)  +				{ +					if (type != LLWearableType::WT_INVALID)  +					{ +						return LLWearableType::WT_INVALID; +					} +					type = new_type; +				} +			} +		} + +		return type; +	} +	return LLAvatarAppearanceDictionary::getTEWearableType(te); +} +  LLTexLayerInterface::ERenderPass LLTexLayerInterface::getRenderPass() const  {  	return mInfo->mRenderPass;  @@ -1586,6 +1063,12 @@ LLTexLayer::~LLTexLayer()  } +void LLTexLayer::asLLSD(LLSD& sd) const +{ +	// *TODO: Finish +	sd["id"] = getUUID(); +} +  //-----------------------------------------------------------------------------  // setInfo  //----------------------------------------------------------------------------- @@ -1637,17 +1120,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; @@ -1687,7 +1174,8 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)  			}  		}//*/ -		renderMorphMasks(x, y, width, height, net_color); +		const bool force_render = true; +		renderMorphMasks(x, y, width, height, net_color, force_render);  		alpha_mask_specified = TRUE;  		gGL.flush();  		gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA); @@ -1704,7 +1192,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(); @@ -1717,15 +1205,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(); @@ -1737,11 +1228,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 @@ -1754,7 +1247,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); @@ -1776,8 +1269,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 ); @@ -1834,7 +1328,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])  		{ @@ -1851,7 +1345,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;  	} @@ -1876,7 +1370,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; @@ -1901,7 +1395,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; @@ -1929,8 +1423,15 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)  	addAlphaMask(data, originX, originY, width, height);  } -BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color) +static LLFastTimer::DeclareTimer FTM_RENDER_MORPH_MASKS("renderMorphMasks"); +void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render)  { +	if (!force_render && !hasMorph()) +	{ +		lldebugs << "skipping renderMorphMasks for " << getUUID() << llendl; +		return; +	} +	LLFastTimer t(FTM_RENDER_MORPH_MASKS);  	BOOL success = TRUE;  	llassert( !mParamAlphaList.empty() ); @@ -1966,6 +1467,11 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC  	{  		LLTexLayerParamAlpha* param = *iter;  		success &= param->render( x, y, width, height ); +		if (!success && !force_render) +		{ +			lldebugs << "Failed to render param " << param->getID() << " ; skipping morph mask." << llendl; +			return; +		}  	}  	// Approximates a min() function @@ -1975,7 +1481,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; @@ -1991,25 +1497,29 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC  		}  	} -	if( !getInfo()->mStaticImageFileName.empty() ) +	if( !getInfo()->mStaticImageFileName.empty() && getInfo()->mStaticImageIsMask )  	{ -		LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); +		LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);  		if( tex )  		{ -			if(	(tex->getComponents() == 4) || -				( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) ) +			if(	(tex->getComponents() == 4) || (tex->getComponents() == 1) )  			{  				LLGLSNoAlphaTest gls_no_alpha_test;  				gGL.getTexUnit(0)->bind(tex, TRUE);  				gl_rect_2d_simple_tex( width, height );  				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  			} +			else +			{ +				llwarns << "Skipping rendering of " << getInfo()->mStaticImageFileName  +						<< "; expected 1 or 4 components." << llendl; +			}  		}  	}  	// Draw a rectangle with the layer color to multiply the alpha by that color's alpha.  	// Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO ); -	if (layer_color.mV[VW] != 1.f) +	if ( !is_approx_equal(layer_color.mV[VW], 1.f) )  	{  		LLGLDisable no_alpha(GL_ALPHA_TEST);  		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -2044,7 +1554,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 @@ -2057,17 +1567,17 @@ 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);  	} - -	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()) @@ -2076,7 +1586,8 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32  		findNetColor( &net_color );  		// TODO: eliminate need for layer morph mask valid flag  		invalidateMorphMasks(); -		renderMorphMasks(originX, originY, width, height, net_color); +		const bool force_render = false; +		renderMorphMasks(originX, originY, width, height, net_color, force_render);  		alphaData = getAlphaData();  	}  	if (alphaData) @@ -2085,7 +1596,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32  		{  			U8 curAlpha = data[i];  			U16 resultAlpha = curAlpha; -			resultAlpha *= (alphaData[i] + 1); +			resultAlpha *= ( ((U16)alphaData[i]) + 1);  			resultAlpha = resultAlpha >> 8;  			data[i] = (U8)resultAlpha;  		} @@ -2110,7 +1621,7 @@ LLUUID LLTexLayer::getUUID() const  	LLUUID uuid;  	if( getInfo()->mLocalTexture != -1 )  	{ -			LLViewerTexture* tex = mLocalTextureObject->getImage(); +			LLGLTexture* tex = mLocalTextureObject->getImage();  			if (tex)  			{  				uuid = mLocalTextureObject->getID(); @@ -2118,7 +1629,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(); @@ -2141,13 +1652,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())  {  } @@ -2168,18 +1681,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; @@ -2234,7 +1746,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const  		}  		if (layer)  		{ -			wearable->writeToAvatar(); +			wearable->writeToAvatar(mAvatarAppearance);  			layer->setLTO(lto);  			success &= layer->render(x,y,width,height);  		} @@ -2341,7 +1853,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++ ) @@ -2408,8 +1920,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() ) @@ -2436,9 +1950,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<LLViewerTexture> tex; +	LLFastTimer t(FTM_LOAD_STATIC_TEXTURE); +	LLPointer<LLGLTexture> tex;  	const char *namekey = mImageNames.addString(file_name);  	texture_map_t::const_iterator iter = mStaticImageList.find(namekey); @@ -2448,17 +1964,24 @@ LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_n  	}  	else  	{ -		tex = LLViewerTextureManager::getLocalTexture( FALSE ); +		llassert(gTextureManagerBridgep); +		tex = gTextureManagerBridgep->getLocalTexture( FALSE );  		LLPointer<LLImageRaw> image_raw = new LLImageRaw;  		if( loadImageRaw( file_name, image_raw ) )  		{  			if( (image_raw->getComponents() == 1) && is_mask )  			{ -				// Note: these are static, unchanging images so it's ok to assume -				// that once an image is a mask it's always a mask. -				tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); +				// Convert grayscale alpha masks from single channel into RGBA. +				// Fill RGB with black to allow fixed function gl calls +				// to match shader implementation. +				LLPointer<LLImageRaw> alpha_image_raw = image_raw; +				image_raw = new LLImageRaw(image_raw->getWidth(), +										   image_raw->getHeight(), +										   4); + +				image_raw->copyUnscaledAlphaMask(alpha_image_raw, LLColor4U::black);  			} -			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); @@ -2477,8 +2000,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); @@ -2492,23 +2017,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 index 4f43547dae..959d6e499a 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/llappearance/lltexlayer.h @@ -28,14 +28,15 @@  #define LL_LLTEXLAYER_H  #include <deque> -#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; @@ -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<LLWearable*> wearable_cache_t;  	mutable wearable_cache_t mWearableCache; // mutable b/c most get- require updating this cache  }; @@ -153,17 +160,18 @@ public:  	BOOL					findNetColor(LLColor4* color) const;  	/*virtual*/ BOOL		blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer  	/*virtual*/ void		gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height); -	BOOL					renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color); +	void					renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render);  	void					addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height);  	/*virtual*/ BOOL		isInvisibleAlphaMask() const;  	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<U32, U8*> 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<LLTexLayerInterface *> layer_list_t;  	layer_list_t				mLayerList;  	layer_list_t				mMaskLayerList;  	LLPointer<LLTexLayerSetBuffer>	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<LLTexLayerStaticImageList>  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<const char*, LLPointer<LLViewerTexture> > texture_map_t; +	typedef std::map<const char*, LLPointer<LLGLTexture> > texture_map_t;  	texture_map_t 		mStaticImageList;  	typedef std::map<const char*, LLPointer<LLImageTGA> > 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 index 8972827eff..6aae9a8cc1 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 "../llui/llui.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,10 @@ 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()) -			{ -				upload_bake = FALSE; -			} -			mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake); +			mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);  			mTexLayer->invalidateMorphMasks();  		}  	} @@ -218,11 +217,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 +229,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 +238,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 +249,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 +291,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 +309,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 +334,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 +404,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 +427,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 +472,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 index c812199796..b38d28d3eb 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;  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -63,7 +65,7 @@ class LLTexLayerParamAlpha : public LLTexLayerParam  {  public:  	LLTexLayerParamAlpha( LLTexLayerInterface* layer ); -	LLTexLayerParamAlpha( LLVOAvatar* avatar ); +	LLTexLayerParamAlpha( LLAvatarAppearance* appearance );  	/*virtual*/ ~LLTexLayerParamAlpha();  	void* operator new(size_t size) @@ -100,7 +102,7 @@ public:  	BOOL					getMultiplyBlend() const;  private: -	LLPointer<LLViewerTexture>	mCachedProcessedTexture; +	LLPointer<LLGLTexture>	mCachedProcessedTexture;  	LLPointer<LLImageTGA>	mStaticImageTGA;  	LLPointer<LLImageRaw>	mStaticImageRaw;  	BOOL					mNeedsCreateTexture; @@ -153,7 +155,7 @@ public:  	};  	LLTexLayerParamColor( LLTexLayerInterface* layer ); -	LLTexLayerParamColor( LLVOAvatar* avatar ); +	LLTexLayerParamColor( LLAvatarAppearance* appearance );  	void* operator new(size_t size)  	{ diff --git a/indra/llappearance/lltexturemanagerbridge.cpp b/indra/llappearance/lltexturemanagerbridge.cpp new file mode 100644 index 0000000000..33f2185e4f --- /dev/null +++ b/indra/llappearance/lltexturemanagerbridge.cpp @@ -0,0 +1,32 @@ + /**  + * @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 "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 0000000000..4b814b522d --- /dev/null +++ b/indra/llappearance/lltexturemanagerbridge.h @@ -0,0 +1,46 @@ +/**  + * @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 LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) = 0; +	virtual LLPointer<LLGLTexture> 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 index f0cf9b7692..cc81bcf118 100644 --- a/indra/newview/llviewervisualparam.cpp +++ b/indra/llappearance/llviewervisualparam.cpp @@ -27,11 +27,10 @@  //-----------------------------------------------------------------------------  // 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 index 2826e6c316..2826e6c316 100644 --- a/indra/newview/llviewervisualparam.h +++ b/indra/llappearance/llviewervisualparam.h diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp new file mode 100644 index 0000000000..d86a460511 --- /dev/null +++ b/indra/llappearance/llwearable.cpp @@ -0,0 +1,781 @@ +/**  + * @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); + +// 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); +} + +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.exportLegacyStream( output_stream ) ) +	{ +		return FALSE; +	} + +	// sale info +	if( !mSaleInfo.exportLegacyStream( 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[PARSE_BUFFER_SIZE];		/* 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 (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) +	{ +		llwarns << "Failed to read wearable asset input stream." << llendl; +		return LLWearable::FAILURE; +	} +	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 may be empty +    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 may be empty +	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 may have extra empty lines before the correct line +	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) +	{ +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading permissions" << llendl; +		return LLWearable::FAILURE; +	} +	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.importLegacyStream( input_stream ) ) +	{ +		return LLWearable::FAILURE; +	} + +	// sale info +	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) +	{ +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading sale info" << llendl; +		return LLWearable::FAILURE; +	} +	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.importLegacyStream(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 (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) +	{ +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading type" << llendl; +		return LLWearable::FAILURE; +	} +	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 (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) +	{ +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading parameters header" << llendl; +		return LLWearable::FAILURE; +	} +	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 (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) +		{ +			llwarns << "Bad Wearable asset: early end of input stream "  +					<< "while reading parameter #" << i << llendl; +			return LLWearable::FAILURE; +		} +		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 (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) +	{ +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading textures header" << i << llendl; +		return LLWearable::FAILURE; +	} +	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 (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) +		{ +			llwarns << "Bad Wearable asset: early end of input stream "  +					<< "while reading textures #" << i << llendl; +			return LLWearable::FAILURE; +		} +		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; +} + +BOOL LLWearable::getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size) +{ +	if (!input_stream.good()) +	{ +		return FALSE; +	} + +	do  +	{ +		input_stream.getline(buffer, buffer_size); +	} +	while (input_stream.good() && buffer[0]=='\0'); + +	return (buffer[0] != '\0');  +} + + +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<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq() +{ +	std::vector<LLLocalTextureObject*> 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<LLDriverParam*>(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<LLDriverParam*>(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; +} + diff --git a/indra/newview/llwearable.h b/indra/llappearance/llwearable.h index 3d8c53a755..6f5a1e14e8 100644 --- a/indra/newview/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -27,31 +27,25 @@  #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:  	virtual ~LLWearable(); @@ -59,11 +53,8 @@ public:  	// Accessors  	//--------------------------------------------------------------------  public: -	const LLUUID&				getItemID() const; -	const LLAssetID&			getAssetID() const { return mAssetID; } -	const LLTransactionID&		getTransactionID() const { return mTransactionID; } -	LLWearableType::EType				getType() const	{ return mType; } -	void						setType(LLWearableType::EType type); +	LLWearableType::EType		getType() const	{ return mType; } +	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; } @@ -77,32 +68,26 @@ 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<LLVisualParam*> 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); +	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 LLUUID		getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const = 0;  	LLLocalTextureObject* getLocalTextureObject(S32 index);  	const LLLocalTextureObject* getLocalTextureObject(S32 index) const; @@ -110,7 +95,6 @@ public:  	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; @@ -120,27 +104,22 @@ 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<S32, LLLocalTextureObject*> te_map_t; -	typedef std::map<S32, LLVisualParam *>    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); +	BOOL				getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size);  	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. @@ -148,18 +127,16 @@ private:  	std::string			mDescription;  	LLPermissions		mPermissions;  	LLSaleInfo			mSaleInfo; -	LLAssetID mAssetID; -	LLTransactionID		mTransactionID;  	LLWearableType::EType		mType;  	typedef std::map<S32, F32> param_map_t;  	param_map_t mSavedVisualParamMap; // last saved version of visual params +	typedef std::map<S32, LLVisualParam *>    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 0000000000..68fdcca782 --- /dev/null +++ b/indra/llappearance/llwearabledata.cpp @@ -0,0 +1,360 @@ +/**  + * @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) +{ +	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) +{ +	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, +								   bool trigger_updated /* = true */) +{ +	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); +		if (trigger_updated) +		{ +			const BOOL removed = FALSE; +			wearableUpdated(wearable, removed); +		} +		return mWearableDatas[type].size()-1; +	} +	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) +{ +	LLWearable *wearable = getWearable(type, index); +	if (wearable) +	{ +		mWearableDatas[type].erase(mWearableDatas[type].begin() + index); +		const BOOL removed = TRUE; +		wearableUpdated(wearable, removed); +	} +} + +void LLWearableData::clearWearableType(const LLWearableType::EType type) +{ +	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); +	if (wearable_iter == mWearableDatas.end()) +	{ +		return; +	} +	wearableentry_vec_t& wearable_vec = wearable_iter->second; +	wearable_vec.clear(); +} + +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<LLDriverParam*>(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 +{ +	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; +} + + diff --git a/indra/llappearance/llwearabledata.h b/indra/llappearance/llwearabledata.h new file mode 100644 index 0000000000..03bd179f25 --- /dev/null +++ b/indra/llappearance/llwearabledata.h @@ -0,0 +1,109 @@ +/**  + * @file llwearabledata.h + * @brief LLWearableData 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_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,  +								 bool trigger_updated = true); +	virtual void	wearableUpdated(LLWearable *wearable, BOOL removed); +	void 			popWearable(LLWearable *wearable); +	void			popWearable(const LLWearableType::EType type, U32 index); +	void			clearWearableType(const LLWearableType::EType type); +	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 {} + +	//-------------------------------------------------------------------- +	// Member variables +	//-------------------------------------------------------------------- +protected: +	LLAvatarAppearance* mAvatarAppearance; +	typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts) +	typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t;	// wearable "categories" arranged by wearable type +	wearableentry_map_t mWearableDatas; + +}; + + + +#endif // LL_WEARABLEDATA_H + diff --git a/indra/newview/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp index c090ab5c3d..618e2a1941 100644 --- a/indra/newview/llwearabletype.cpp +++ b/indra/llappearance/llwearabletype.cpp @@ -24,23 +24,35 @@   * $/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), -		mLabel(LLTrans::getString(name)), +		mLabel(sTrans->getString(name)),  		mIconName(iconName),  		mDisableCameraSwitch(disable_camera_switch),  		mAllowMultiwear(allow_multiwear) @@ -50,7 +62,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;  }; @@ -64,26 +76,26 @@ public:  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_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::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_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, 	LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE)); + +	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 @@ -131,7 +143,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 index d633b4807e..e51e6731d3 100644 --- a/indra/newview/llwearabletype.h +++ b/indra/llappearance/llwearabletype.h @@ -29,9 +29,16 @@  #include "llassettype.h"  #include "lldictionary.h" -#include "llinventoryicon.h" +#include "llinventorytype.h"  #include "llsingleton.h" +class LLTranslationBridge +{ +public: +	virtual std::string getString(const std::string &xml_desc) = 0; +}; + +  class LLWearableType  {  public:  @@ -59,12 +66,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/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index 632e5d46e3..24d2531106 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -88,6 +88,10 @@ list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES})  add_library (llaudio ${llaudio_SOURCE_FILES})  target_link_libraries(      llaudio +    ${LLCOMMON_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${LLMESSAGE_LIBRARIES} +    ${LLVFS_LIBRARIES}      ${VORBISENC_LIBRARIES}      ${VORBISFILE_LIBRARIES}      ${VORBIS_LIBRARIES} diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index a1712699eb..2573417b26 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -16,6 +16,10 @@ include_directories(      ${LLVFS_INCLUDE_DIRS}      ${LLXML_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(llcharacter_SOURCE_FILES      llanimationstates.cpp @@ -76,6 +80,15 @@ list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES})  add_library (llcharacter ${llcharacter_SOURCE_FILES}) +target_link_libraries( +    llcharacter +    ${LLCOMMON_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${LLMESSAGE_LIBRARIES} +    ${LLVFS_LIBRARIES} +    ${LLXML_LIBRARIES} +    ) +  # Add tests  if (LL_TESTS) diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 0a6a8f9fa6..85cf1cd3f5 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -286,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 3ebb2bffb0..5740dbce77 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -93,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; @@ -197,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/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 19907933cb..09a7c11a22 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -40,7 +40,9 @@ S32 LLJoint::sNumTouches = 0;  // LLJoint()  // Class Constructor  //----------------------------------------------------------------------------- -LLJoint::LLJoint() + + +void LLJoint::init()  {  	mName = "unnamed";  	mParent = NULL; @@ -48,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;  } @@ -58,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) diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index dc3c58cf64..2b1e2005c6 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -105,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 ); @@ -178,7 +183,6 @@ 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 ); diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp index 809b312abe..f7cb0f76b7 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 281fb14781..60ea7a369a 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;  //----------------------------------------------------------------------------- @@ -150,6 +160,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 @@ -161,6 +174,7 @@ protected:  	S32					mID;				// id for storing weight/morphtarget compares compactly  	LLVisualParamInfo	*mInfo; +	EParamLocation		mParamLocation;		// where does this visual param live?  } LL_ALIGN_POSTFIX(16);  #endif // LL_LLVisualParam_H diff --git a/indra/llcharacter/tests/lljoint_test.cpp b/indra/llcharacter/tests/lljoint_test.cpp index e92aa832d6..da151808f2 100644 --- a/indra/llcharacter/tests/lljoint_test.cpp +++ b/indra/llcharacter/tests/lljoint_test.cpp @@ -150,11 +150,11 @@ namespace tut  	template<> template<>  	void lljoint_object::test<11>()  	{ -		LLJoint lljoint("parent");  		S32 joint_num = 12; -		lljoint.setJointNum(joint_num); +		LLJoint lljoint(joint_num); +		lljoint.setName("parent");  		S32 jointNum = 	lljoint.getJointNum(); -		ensure("setJointNum()/getJointNum failed ", (jointNum == joint_num)); +		ensure("getJointNum failed ", (jointNum == joint_num));  	}  	template<> template<> diff --git a/indra/llcommon/imageids.cpp b/indra/llcommon/imageids.cpp index fe11465221..7d647e5c36 100644 --- a/indra/llcommon/imageids.cpp +++ b/indra/llcommon/imageids.cpp @@ -68,3 +68,6 @@ const LLUUID TERRAIN_MOUNTAIN_DETAIL	("303cd381-8560-7579-23f1-f0a880799740"); /  const LLUUID TERRAIN_ROCK_DETAIL		("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER  const LLUUID DEFAULT_WATER_NORMAL		("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER + +const LLUUID IMG_CHECKERBOARD_RGBA     ("2585a0f3-4163-6dd1-0f34-ad48cb909e25"); // dataserver + diff --git a/indra/llcommon/imageids.h b/indra/llcommon/imageids.h index e0c2683fdc..18c8ecb074 100644 --- a/indra/llcommon/imageids.h +++ b/indra/llcommon/imageids.h @@ -66,4 +66,5 @@ LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL;  LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL; +LL_COMMON_API extern const LLUUID IMG_CHECKERBOARD_RGBA;  #endif diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp index 95ecce509b..642bd82e90 100644 --- a/indra/llcommon/llavatarname.cpp +++ b/indra/llcommon/llavatarname.cpp @@ -178,6 +178,21 @@ std::string LLAvatarName::getCompleteName() const  	return name;  } +std::string LLAvatarName::getLegacyName() const +{ +	if (mLegacyFirstName.empty() && mLegacyLastName.empty()) // display names disabled? +	{ +		return mDisplayName; +	} + +	std::string name; +	name.reserve( mLegacyFirstName.size() + 1 + mLegacyLastName.size() ); +	name = mLegacyFirstName; +	name += " "; +	name += mLegacyLastName; +	return name; +} +  std::string LLAvatarName::getDisplayName() const  {  	if (sUseDisplayNames) diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index 4827353018..7542a8dece 100644 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -63,6 +63,11 @@ public:  	// For normal names, returns "James Linden (james.linden)"  	// When display names are disabled returns just "James Linden"  	std::string getCompleteName() const; + +	// Returns "James Linden" or "bobsmith123 Resident" for backwards +	// compatibility with systems like voice and muting +	// *TODO: Eliminate this in favor of username only +	std::string getLegacyName() const;  	// "José Sanchez" or "James Linden", UTF-8 encoded Unicode  	// Takes the display name preference into account. This is truly the name that should  diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h index bc3bc3e74a..c752859a36 100644 --- a/indra/llcommon/lldictionary.h +++ b/indra/llcommon/lldictionary.h @@ -30,6 +30,8 @@  #include <map>  #include <string> +#include "llerror.h" +  struct LL_COMMON_API LLDictionaryEntry  {  	LLDictionaryEntry(const std::string &name); diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 6970c29092..9b15804e97 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -561,6 +561,12 @@ std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()  	return mChildren;  } +// static +LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer() +{ +        return *NamedTimerFactory::instance().getRootTimer(); +} +  //static  void LLFastTimer::nextFrame()  { diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index e42e549df5..81c4b78775 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -91,6 +91,8 @@ public:  		U32 getHistoricalCount(S32 history_index = 0) const;  		U32 getHistoricalCalls(S32 history_index = 0) const; +		static NamedTimer& getRootNamedTimer(); +  		void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); }  		FrameState& getFrameState() const; diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index c51d042a3d..bc615ed39e 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -56,6 +56,8 @@ std::string strerr(int errn)  	return buffer;  } +typedef std::basic_ios<char,std::char_traits < char > > _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 @@ -324,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] @@ -385,117 +388,681 @@ LLFILE *	LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,in  	return (0);  } -/************** input file stream ********************************/ +#endif /* LL_WINDOWS */ -void llifstream::close() -{	// close the C stream -	if (_Filebuffer && _Filebuffer->close() == 0) +/************** 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)  	{ -		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/ +		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;  } -void llifstream::open(const std::string& _Filename,	/* Flawfinder: ignore */ -	ios_base::openmode _Mode, -	int _Prot) -{	// open a C stream with specified mode +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<char*>(__ibuf), __ilen); +		__elen = fwrite(reinterpret_cast<void*>(__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<char*>(__builtin_alloca(__blen)); -	LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::in, _Prot); -	if(filep == NULL) +		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<char*>(__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)  	{ -		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/ -		return; +		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<char*>(this->eback()), +			//			__buflen); +			__ilen = fread(reinterpret_cast<void*>(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<char_type*> +						(_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"));  	} -	llassert(_Filebuffer == NULL); -	_Filebuffer = new _Myfb(filep); -	_ShouldClose = true; -	_Myios::init(_Filebuffer); +	return __ret;  } -bool llifstream::is_open() const -{	// test if C stream has been opened -	if(_Filebuffer) -		return (_Filebuffer->is_open()); -	return false; +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<char*>(__s), __n); +			__len = fread(reinterpret_cast<void*>(__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;  } -llifstream::~llifstream() + +std::streamsize llstdio_filebuf::xsputn(char_type* __s, std::streamsize __n)  { -	if (_ShouldClose) +	// 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)  	{ -		close(); +		// 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<const char*>(this->pbase()); +			//__ret = _M_file.xsputn_2(__buf, __buffill, +			//			reinterpret_cast<const char*>(__s), __n); +			if (__buffill) +			{ +				__ret = fwrite(__buf, 1, __buffill, _M_file.file()); +			} +			if (__ret == __buffill) +			{ +				__ret += fwrite(reinterpret_cast<const char*>(__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);  	} -	delete _Filebuffer; +	else +		__ret = __streambuf_type::xsputn(__s, __n); +    return __ret;  } -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) +int llstdio_filebuf::sync() +{ +	return (_M_file.sync() == 0 ? 0 : -1); +} +#endif + +/************** input file stream ********************************/ -{	// construct with named file and specified mode -	open(_Filename, _Mode | ios_base::in, _Prot);	/* Flawfinder: ignore */ + +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 -/************** output file stream ********************************/ -bool llofstream::is_open() const +// 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();  } -void llofstream::open(const std::string& _Filename,	/* Flawfinder: ignore */ -	ios_base::openmode _Mode, -	int _Prot) +void llifstream::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::in) == 0) +#if LL_WINDOWS +	{ +		_Myios::setstate(ios_base::failbit); +	} +	else  	{ -		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/ -		return; +		_Myios::clear();  	} -	llassert(_Filebuffer==NULL); -	_Filebuffer = new _Myfb(filep); -	_ShouldClose = true; -	_Myios::init(_Filebuffer); +#else +	{ +		this->setstate(ios_base::failbit); +	} +	else +	{ +		this->clear(); +	} +#endif  } -void llofstream::close() +void llifstream::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  	}  } + +/************** 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, -	std::ios_base::openmode _Mode, -	int _Prot) -		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) -{	// construct with named file and specified mode -	open(_Filename, _Mode , _Prot);	/* Flawfinder: ignore */ +		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 -llofstream::~llofstream() +#if !LL_WINDOWS +// explicit +llofstream::llofstream(int __fd, +			ios_base::openmode _Mode, size_t _Size) : +	_M_filebuf(__fd, _Mode, _Size), +	std::ostream()  { -	// destroy the object -	if (_ShouldClose) +	this->init(&_M_filebuf); +} +#endif + +bool llofstream::is_open() const +{	// test if C stream has been opened +	return _M_filebuf.is_open(); +} + +void llofstream::open(const char* _Filename, ios_base::openmode _Mode) +{	// open a C stream with specified mode +	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0) +#if LL_WINDOWS +	{ +		_Myios::setstate(ios_base::failbit); +	} +	else  	{ -		close(); +		_Myios::clear();  	} -	delete _Filebuffer; +#else +	{ +		this->setstate(ios_base::failbit); +	} +	else +	{ +		this->clear(); +	} +#endif  } -#endif // #if USE_LLFILESTREAMS +void llofstream::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 +	} +}  /************** helper functions ********************************/ diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index dd7d36513a..9d70db96ea 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -35,16 +35,9 @@   * Attempts to mostly mirror the POSIX style IO functions.   */ -typedef FILE	LLFILE; +typedef FILE LLFILE;  #include <fstream> - -#ifdef LL_WINDOWS -#define	USE_LLFILESTREAMS	1 -#else -#define	USE_LLFILESTREAMS	0 -#endif -  #include <sys/stat.h>  #if LL_WINDOWS @@ -52,6 +45,8 @@ typedef FILE	LLFILE;  typedef struct _stat	llstat;  #else  typedef struct stat		llstat; +#include <ext/stdio_filebuf.h> +#include <bits/postypes.h>  #endif  #ifndef S_ISREG @@ -83,142 +78,342 @@ 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 llifstream	:	public	std::basic_istream < char , std::char_traits < char > > +class LL_COMMON_API llstdio_filebuf : public _Myfb  { -	// input stream associated with a C stream  public: -	typedef std::basic_ifstream<char,std::char_traits < char > > _Myt; -	typedef std::basic_filebuf<char,std::char_traits< char > > _Myfb; -	typedef std::basic_ios<char,std::char_traits< char > > _Myios; - -	llifstream() -		: std::basic_istream<char,std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) -	{	// construct unopened -	} +	/** +	 * deferred initialization / destruction +	*/ +	llstdio_filebuf() : _Myfb() {} +	virtual ~llstdio_filebuf() {}  + +	/** +	 *  @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<size_t>(BUFSIZ)) : +		    size_t __size = static_cast<size_t>(1)) : +#if LL_WINDOWS +		_Myfb(__f) {} +#else +		_Myfb(__f, __mode, __size) {} +#endif -	explicit llifstream(const std::string& _Filename, -		ios_base::openmode _Mode = ios_base::in, -		int _Prot = (int)ios_base::_Openprot); - -	explicit llifstream(_Filet *_File) -		: std::basic_istream<char,std::char_traits< char > >(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(); +	/** +	 *  @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<size_t>(BUFSIZ)) : +		size_t __size = static_cast<size_t>(1)) : +		_Myfb(__fd, __mode, __size) {} +#endif -private: -	_Myfb* _Filebuffer;	// the file buffer -	bool _ShouldClose; +// *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*, std::streamsize); +#endif  }; -class LL_COMMON_API llofstream	:	public	std::basic_ostream< char , std::char_traits < char > > +/** + *  @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_ostream< char , std::char_traits < char > > _Myt; -	typedef std::basic_filebuf< char , std::char_traits < char > > _Myfb; -	typedef std::basic_ios<char,std::char_traits < char > > _Myios; - -	llofstream() -		: std::basic_ostream<char,std::char_traits < char > >(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<char,std::char_traits < char > >(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; -	} +	// 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); +	explicit llifstream(const char* _Filename, +			ios_base::openmode _Mode = ios_base::in); + +	/** +	 *  @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<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(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<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(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<llstdio_filebuf*>(&_M_filebuf); } + +	/** +	 *  @brief  Wrapper to test for an open file. +	 *  @return  @c rdbuf()->is_open() +	*/  	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 */ - +	/** +	 *  @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: -	_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); -	} +	llstdio_filebuf _M_filebuf;  }; -class LL_COMMON_API llofstream	:	public	std::ofstream +/** + *  @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: -	llofstream() : std::ofstream() -	{ -	} +	// 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<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(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<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(1)); +#endif -	explicit llofstream(const std::string& _Filename, std::_Ios_Openmode _Mode = out) -		: std::ofstream(_Filename.c_str(), _Mode) -	{ -	} +	/** +	 *  @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<llstdio_filebuf*>(&_M_filebuf); } + +	/** +	 *  @brief  Wrapper to test for an open file. +	 *  @return  @c rdbuf()->is_open() +	*/ +	bool is_open() const; -	void open(const std::string& _Filename, std::_Ios_Openmode _Mode = out)	/* Flawfinder: ignore */ -	{ -		std::ofstream::open(_Filename.c_str(), _Mode); -	} +	/** +	 *  @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;  }; -#endif  /**   * @breif filesize helpers. diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 41d3eb0bf3..731e58bd20 100644 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -100,7 +100,7 @@ LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& i  	LLSD ret;  	LLSD cur; -	while (!is.eof() && LLSDSerialize::fromXML(cur, is)) +	while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))  	{  		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)  		{ diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 6b549e4b6f..ad4fce6f35 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -1453,8 +1453,8 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option  	case LLSD::TypeUUID:  	{  		ostr.put('u'); -		LLSD::UUID value = data.asUUID(); -		ostr.write((const char*)(&value.mData), UUID_BYTES); +		LLUUID temp = data.asUUID(); +		ostr.write((const char*)(&(temp.mData)), UUID_BYTES);  		break;  	} diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index 86e3fc864c..e7a5507385 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -300,7 +300,7 @@ public:  	/**   	 * @brief Constructor  	 */ -	LLSDXMLParser(); +	LLSDXMLParser(bool emit_errors=true);  protected:  	/**  @@ -747,25 +747,25 @@ public:  		return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);  	} -	static S32 fromXMLEmbedded(LLSD& sd, std::istream& str) +	static S32 fromXMLEmbedded(LLSD& sd, std::istream& str, bool emit_errors=true)  	{  		// no need for max_bytes since xml formatting is not  		// subvertable by bad sizes. -		LLPointer<LLSDXMLParser> p = new LLSDXMLParser; +		LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);  		return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED);  	}  	// Line oriented parser, 30% faster than fromXML(), but can  	// only be used when you know you have the complete XML  	// document available in the stream. -	static S32 fromXMLDocument(LLSD& sd, std::istream& str) +	static S32 fromXMLDocument(LLSD& sd, std::istream& str, bool emit_errors=true)  	{ -		LLPointer<LLSDXMLParser> p = new LLSDXMLParser(); +		LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);  		return p->parseLines(str, sd);  	} -	static S32 fromXML(LLSD& sd, std::istream& str) +	static S32 fromXML(LLSD& sd, std::istream& str, bool emit_errors=true)  	{ -		return fromXMLEmbedded(sd, str); -//		return fromXMLDocument(sd, str); +		return fromXMLEmbedded(sd, str, emit_errors); +//		return fromXMLDocument(sd, str, emit_errors);  	}  	/* diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index 34b3dbb99a..cef743a7be 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -250,7 +250,7 @@ std::string LLSDXMLFormatter::escapeString(const std::string& in)  class LLSDXMLParser::Impl  {  public: -	Impl(); +	Impl(bool emit_errors);  	~Impl();  	S32 parse(std::istream& input, LLSD& data); @@ -294,6 +294,7 @@ private:  	static const XML_Char* findAttribute(const XML_Char* name, const XML_Char** pairs); +	bool mEmitErrors;  	XML_Parser	mParser; @@ -315,7 +316,8 @@ private:  }; -LLSDXMLParser::Impl::Impl() +LLSDXMLParser::Impl::Impl(bool emit_errors) +	: mEmitErrors(emit_errors)  {  	mParser = XML_ParserCreate(NULL);  	reset(); @@ -402,7 +404,10 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)  		{  			((char*) buffer)[count ? count - 1 : 0] = '\0';  		} -		llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl; +		if (mEmitErrors) +		{ +			llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl; +		}  		data = LLSD();  		return LLSDParser::PARSE_FAILURE;  	} @@ -480,7 +485,10 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)  	if (status == XML_STATUS_ERROR    		&& !mGracefullStop)  	{ -		llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl; +		if (mEmitErrors) +		{ +			llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl; +		}  		return LLSDParser::PARSE_FAILURE;  	} @@ -897,7 +905,7 @@ LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* na  /**   * LLSDXMLParser   */ -LLSDXMLParser::LLSDXMLParser() : impl(* new Impl) +LLSDXMLParser::LLSDXMLParser(bool emit_errors /* = true */) : impl(* new Impl(emit_errors))  {  } diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h index b19ba3bf74..ef68a0eaf5 100644 --- a/indra/llcommon/llversionserver.h +++ b/indra/llcommon/llversionserver.h @@ -30,7 +30,7 @@  const S32 LL_VERSION_MAJOR = 2;  const S32 LL_VERSION_MINOR = 1;  const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 13828; +const S32 LL_VERSION_BUILD = 264760;  const char * const LL_CHANNEL = "Second Life Server"; diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 0b0c74b3d3..ae5e3ecade 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -30,7 +30,7 @@  const S32 LL_VERSION_MAJOR = 3;  const S32 LL_VERSION_MINOR = 5;  const S32 LL_VERSION_PATCH = 1; -const S32 LL_VERSION_BUILD = 0; +const S32 LL_VERSION_BUILD = 264760;  const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp index 4c3bc674af..afc0c18cd0 100644 --- a/indra/llcommon/tests/bitpack_test.cpp +++ b/indra/llcommon/tests/bitpack_test.cpp @@ -71,7 +71,6 @@ namespace tut  		U8 packbuffer[255];  		U8 unpackbuffer[255];  		int pack_bufsize = 0; -		int unpack_bufsize = 0;  		LLBitPack bitpack(packbuffer, 255); @@ -81,21 +80,20 @@ namespace tut  		pack_bufsize = bitpack.flushBitPack();  		LLBitPack bitunpack(packbuffer, pack_bufsize*8); -		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); +		bitunpack.bitUnpack(&unpackbuffer[0], 8);  		ensure("bitPack: individual unpack: 0", unpackbuffer[0] == (U8) str[0]); -		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); +		bitunpack.bitUnpack(&unpackbuffer[0], 8);  		ensure("bitPack: individual unpack: 1", unpackbuffer[0] == (U8) str[1]); -		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); +		bitunpack.bitUnpack(&unpackbuffer[0], 8);  		ensure("bitPack: individual unpack: 2", unpackbuffer[0] == (U8) str[2]); -		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); +		bitunpack.bitUnpack(&unpackbuffer[0], 8);  		ensure("bitPack: individual unpack: 3", unpackbuffer[0] == (U8) str[3]); -		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); +		bitunpack.bitUnpack(&unpackbuffer[0], 8);  		ensure("bitPack: individual unpack: 4", unpackbuffer[0] == (U8) str[4]); -		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); +		bitunpack.bitUnpack(&unpackbuffer[0], 8);  		ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]); -		unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, 8*4); // Life +		bitunpack.bitUnpack(unpackbuffer, 8*4); // Life  		ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4); -		ensure("keep compiler quiet", unpack_bufsize == unpack_bufsize);  	}  	// U32 packing diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp index 454695ff9f..e769c3e22c 100644 --- a/indra/llcommon/tests/llinstancetracker_test.cpp +++ b/indra/llcommon/tests/llinstancetracker_test.cpp @@ -267,7 +267,6 @@ namespace tut          {              existing.insert(&*uki);          } -        Unkeyed* puk = NULL;          try          {              // We don't expect the assignment to take place because we expect @@ -280,7 +279,7 @@ namespace tut              // realize we're testing the C++ implementation more than              // Unkeyed's implementation, but this seems an important point to              // nail down. -            puk = new Unkeyed("throw"); +            new Unkeyed("throw");          }          catch (const Badness&)          { diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt index b2639aec30..12986de8b2 100644 --- a/indra/llcrashlogger/CMakeLists.txt +++ b/indra/llcrashlogger/CMakeLists.txt @@ -16,6 +16,10 @@ include_directories(      ${LLVFS_INCLUDE_DIRS}      ${LLXML_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(llcrashlogger_SOURCE_FILES      llcrashlogger.cpp diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 34e25a8a71..fb2d43e3b0 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -147,7 +147,7 @@ void LLCrashLogger::gatherFiles()  	// Look for it in the debug_info.log file  	if (debug_log_file.is_open()) -	{		 +	{  		LLSDSerialize::fromXML(mDebugLog, debug_log_file);  		mCrashInPreviousExec = mDebugLog["CrashNotHandled"].asBoolean(); diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index ea8c1a1107..e837b0cac2 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -7,12 +7,15 @@ include(LLCommon)  include(LLImage)  include(LLMath)  include(LLVFS) +include(LLKDU) +include(LLImageJ2COJ)  include(ZLIB)  include(LLAddBuildTest)  include(Tut)  include_directories(      ${LLCOMMON_INCLUDE_DIRS} +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}      ${LLMATH_INCLUDE_DIRS}      ${LLVFS_INCLUDE_DIRS}      ${PNG_INCLUDE_DIRS} @@ -56,8 +59,16 @@ list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES})  add_library (llimage ${llimage_SOURCE_FILES})  # Libraries on which this library depends, needed for Linux builds  # Sort by high-level to low-level +if (USE_KDU) +    target_link_libraries(llimage ${LLKDU_LIBRARIES}) +else (USE_KDU) +    target_link_libraries(llimage ${LLIMAGEJ2COJ_LIBRARIES}) +endif (USE_KDU) +  target_link_libraries(llimage -    llcommon +    ${LLVFS_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${LLCOMMON_LIBRARIES}      ${JPEG_LIBRARIES}      ${PNG_LIBRARIES}      ${ZLIB_LIBRARIES} diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 3f8d1baddd..c8a05e1fae 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -640,6 +640,29 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )  	}  } +void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) +{ +	LLImageRaw* dst = this;  // Just for clarity. + +	llassert( 1 == src->getComponents() ); +	llassert( 4 == dst->getComponents() ); +	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); + +	S32 pixels = getWidth() * getHeight(); +	U8* src_data = src->getData(); +	U8* dst_data = dst->getData(); +	for ( S32 i = 0; i < pixels; i++ ) +	{ +		dst_data[0] = fill.mV[0]; +		dst_data[1] = fill.mV[1]; +		dst_data[2] = fill.mV[2]; +		dst_data[3] = src_data[0]; +		src_data += 1; +		dst_data += 4; +	} +} + +  // Fill the buffer with a constant color  void LLImageRaw::fill( const LLColor4U& color )  { diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 1d56411ae8..2277afc585 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -230,6 +230,11 @@ public:  	// Src and dst are same size.  Src has 3 components.  Dst has 4 components.  	void copyUnscaled3onto4( LLImageRaw* src ); +	// Src and dst are same size.  Src has 1 component.  Dst has 4 components. +	// Alpha component is set to source alpha mask component. +	// RGB components are set to fill color. +	void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill); +  	// Src and dst can be any size.  Src and dst have same number of components.  	void copyScaled( LLImageRaw* src ); diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp index 58426d31fa..920ae2891f 100644 --- a/indra/llimage/llimagetga.cpp +++ b/indra/llimage/llimagetga.cpp @@ -132,12 +132,12 @@ BOOL LLImageTGA::updateData()  	**	  FIELD 2 :	COLOR MAP TYPE (1 BYTES)			  	**	  FIELD 3 :	IMAGE TYPE CODE (1 BYTES)			  	**					= 0	NO IMAGE DATA INCLUDED		 -	**					= 1	UNCOMPRESSED, COLOR-MAPPED IMAGE -	**					= 2	UNCOMPRESSED, TRUE-COLOR IMAGE	 -	**					= 3	UNCOMPRESSED, BLACK AND WHITE IMAGE -	**					= 9	RUN-LENGTH ENCODED COLOR-MAPPED IMAGE -	**					= 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE -	**					= 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE +	**					= (0001) 1	UNCOMPRESSED, COLOR-MAPPED IMAGE +	**					= (0010) 2	UNCOMPRESSED, TRUE-COLOR IMAGE	 +	**					= (0011) 3	UNCOMPRESSED, BLACK AND WHITE IMAGE +	**					= (1001) 9	RUN-LENGTH ENCODED COLOR-MAPPED IMAGE +	**					= (1010) 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE +	**					= (1011) 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE  	**	  FIELD 4 :	COLOR MAP SPECIFICATION	(5 BYTES)		  	**				4.1 : COLOR MAP ORIGIN (2 BYTES)	  	**				4.2 : COLOR MAP LENGTH (2 BYTES)	 diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index a80ae73dca..41d58c6deb 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -288,7 +288,15 @@ void LLInventoryObject::setCreationDate(time_t creation_date_utc)  } +const std::string& LLInventoryItem::getDescription() const +{ +	return mDescription; +} +const std::string& LLInventoryItem::getActualDescription() const +{ +	return mDescription; +}  ///----------------------------------------------------------------------------  /// Class LLInventoryItem @@ -389,11 +397,6 @@ void LLInventoryItem::setAssetUUID(const LLUUID& asset_id)  } -const std::string& LLInventoryItem::getDescription() const -{ -	return mDescription; -} -  U32 LLInventoryItem::getCRC32() const  {  	// *FIX: Not a real crc - more of a checksum. diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index 4516e548df..99716ed7be 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -160,6 +160,7 @@ public:  	virtual const LLUUID& getCreatorUUID() const;  	virtual const LLUUID& getAssetUUID() const;  	virtual const std::string& getDescription() const; +	virtual const std::string& getActualDescription() const; // Does not follow links  	virtual const LLSaleInfo& getSaleInfo() const;  	virtual LLInventoryType::EType getInventoryType() const;  	virtual U32 getFlags() const; diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h index 645ebab234..fc3c78cf50 100644 --- a/indra/llinventory/llinventorytype.h +++ b/indra/llinventory/llinventorytype.h @@ -69,6 +69,53 @@ public:  		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); diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt index bdac2eded7..b8f8b420c3 100644 --- a/indra/llkdu/CMakeLists.txt +++ b/indra/llkdu/CMakeLists.txt @@ -41,7 +41,10 @@ set_source_files_properties(${llkdu_HEADER_FILES}  list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES})  if (USE_KDU) -  add_library (${LLKDU_LIBRARIES} ${llkdu_SOURCE_FILES}) +  add_library (llkdu ${llkdu_SOURCE_FILES}) + +  target_link_libraries(llkdu +    ${KDU_LIBRARY})    # Add tests    if (LL_TESTS) diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 5865ae030c..0614fd92ef 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -7,6 +7,7 @@ include(LLCommon)  include_directories(      ${LLCOMMON_INCLUDE_DIRS} +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}      )  set(llmath_SOURCE_FILES @@ -99,6 +100,10 @@ list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES})  add_library (llmath ${llmath_SOURCE_FILES}) +target_link_libraries(llmath +    ${LLCOMMON_LIBRARIES} +    ) +  # Add tests  if (LL_TESTS)    include(LLAddBuildTest) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 02c8d2b86f..3f06e6b99e 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6066,12 +6066,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  	S32 max_t = volume->getPath().mPath.size();  	// S32 i; -	S32 num_vertices = 0, num_indices = 0;  	S32	grid_size = (profile.size()-1)/4; -	S32	quad_count = (grid_size * grid_size); - -	num_vertices = (grid_size+1)*(grid_size+1); -	num_indices = quad_count * 4;  	LLVector4a& min = mExtents[0];  	LLVector4a& max = mExtents[1]; diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index d98781e9e6..1a90c32fe4 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -218,6 +218,9 @@ add_library (llmessage ${llmessage_SOURCE_FILES})  target_link_libraries(    llmessage    ${CURL_LIBRARIES} +  ${LLCOMMON_LIBRARIES} +  ${LLVFS_LIBRARES} +  ${LLMATH_LIBRARIES}    ${CARES_LIBRARIES}    ${OPENSSL_LIBRARIES}    ${CRYPTO_LIBRARIES} @@ -243,7 +246,7 @@ if (LL_TESTS)      ${LLVFS_LIBRARIES}      ${LLMATH_LIBRARIES}      ${LLCOMMON_LIBRARIES} -      ${GOOGLEMOCK_LIBRARIES} +    ${GOOGLEMOCK_LIBRARIES}      )    LL_ADD_INTEGRATION_TEST( diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 8f91d2a23f..9a68093427 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -435,8 +435,10 @@ void LLAvatarNameCache::cleanupClass()  void LLAvatarNameCache::importFile(std::istream& istr)  {  	LLSD data; -	S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr); -	if (parse_count < 1) return; +	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr)) +	{ +		return; +	}  	// by convention LLSD storage is a map  	// we only store one entry in the map diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 3fb36eecf0..267c48e1d2 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -308,8 +308,10 @@ boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback&  bool LLCacheName::importFile(std::istream& istr)  {  	LLSD data; -	if(LLSDSerialize::fromXMLDocument(data, istr) < 1) +	if(LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr)) +	{  		return false; +	}  	// We'll expire entries more than a week old  	U32 now = (U32)time(NULL); diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 8ffa8e4271..47041a2880 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -175,9 +175,11 @@ void LLCurl::Responder::completedRaw(  {  	LLSD content;  	LLBufferStream istr(channels, buffer.get()); -	if (!LLSDSerialize::fromXML(content, istr)) +	const bool emit_errors = false; +	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(content, istr, emit_errors))  	{  		llinfos << "Failed to deserialize LLSD. " << mURL << " [" << status << "]: " << reason << llendl; +		content["reason"] = reason;  	}  	completed(status, reason, content); diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp index d6ed08055e..7dcf160c9b 100644 --- a/indra/llmessage/llhttpassetstorage.cpp +++ b/indra/llmessage/llhttpassetstorage.cpp @@ -747,9 +747,9 @@ LLAssetRequest* LLHTTPAssetStorage::findNextRequest(LLAssetStorage::request_list  	request_list_t::iterator running_end   = running.end();  	request_list_t::iterator pending_iter = pending.begin(); -	request_list_t::iterator pending_end  = pending.end(); +  	// Loop over all pending requests until we miss finding it in the running list. -	for (; pending_iter != pending_end; ++pending_iter) +	for (; pending_iter != pending.end(); ++pending_iter)  	{  		LLAssetRequest* req = *pending_iter;  		// Look for this pending request in the running list. diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 0c325a68aa..3561459bb4 100644..100755 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -222,7 +222,11 @@ static void request(  {  	if (!LLHTTPClient::hasPump())  	{ -		responder->completed(U32_MAX, "No pump", LLSD()); +		if (responder) +		{ +			responder->completed(U32_MAX, "No pump", LLSD()); +		} +		delete body_injector;  		return;  	}  	LLPumpIO::chain_t chain; @@ -230,8 +234,13 @@ static void request(  	LLURLRequest* req = new LLURLRequest(method, url);  	if(!req->isValid())//failed  	{ -		delete req ; -		return ; +		if (responder) +		{ +			responder->completed(498, "Internal Error - curl failure", LLSD()); +		} +		delete req; +		delete body_injector; +		return;  	}  	req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req); diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp index f5d7a9abb6..0b59209af1 100644 --- a/indra/llmessage/llhttpclientadapter.cpp +++ b/indra/llmessage/llhttpclientadapter.cpp @@ -43,8 +43,11 @@ void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr respo  void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers)   {  	LLSD empty_pragma_header = headers; -	// as above -	empty_pragma_header["Pragma"] = " "; +	if (!empty_pragma_header.has("Pragma")) +	{ +		// as above +		empty_pragma_header["Pragma"] = " "; +	}  	LLHTTPClient::get(url, responder, empty_pragma_header);  } diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index 0287026659..2043bae5e7 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -592,6 +592,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(  	PUMP_DEBUG;  	apr_pool_t* new_pool = NULL;  	apr_status_t status = apr_pool_create(&new_pool, mPool); +	if(ll_apr_warn_status(status)) +	{ +		if(new_pool) +		{	 +			apr_pool_destroy(new_pool); +		} +		return STATUS_ERROR; +	} +  	apr_socket_t* socket = NULL;  	status = apr_socket_accept(  		&socket, diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h index 7b796a0fa8..1cf940918b 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/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 227efdb07a..627d591839 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -174,6 +174,10 @@ LLURLRequest::~LLURLRequest()  void LLURLRequest::setURL(const std::string& url)  {  	mDetail->mURL = url; +	if (url.empty()) +	{ +		llwarns << "empty URL specified" << llendl; +	}  }  std::string LLURLRequest::getURL() const diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index d7658862da..39cfb6019e 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -279,6 +279,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"); @@ -305,6 +307,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"); @@ -1376,3 +1380,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 da2b613f53..573e10dc0b 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -279,6 +279,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; @@ -305,6 +307,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; @@ -1376,4 +1380,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/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp index 7c3def6024..87cbafa404 100644 --- a/indra/llmessage/tests/llhttpclient_test.cpp +++ b/indra/llmessage/tests/llhttpclient_test.cpp @@ -47,37 +47,6 @@  namespace tut  { -	LLSD storage; - -	class LLSDStorageNode : public LLHTTPNode -	{ -	public: -		LLSD simpleGet() const					{ return storage; } -		LLSD simplePut(const LLSD& value) const	{ storage = value; return LLSD(); } -	}; - -	class ErrorNode : public LLHTTPNode -	{ -	public: -		void get(ResponsePtr r, const LLSD& context) const -			{ r->status(599, "Intentional error"); } -		void post(ResponsePtr r, const LLSD& context, const LLSD& input) const -			{ r->status(input["status"], input["reason"]); } -	}; - -	class TimeOutNode : public LLHTTPNode -	{ -	public: -		void get(ResponsePtr r, const LLSD& context) const -		{ -            /* do nothing, the request will eventually time out */  -		} -	}; - -	LLHTTPRegistration<LLSDStorageNode> gStorageNode("/test/storage"); -	LLHTTPRegistration<ErrorNode>		gErrorNode("/test/error"); -	LLHTTPRegistration<TimeOutNode>		gTimeOutNode("/test/timeout"); -  	struct HTTPClientTestData  	{  	public: @@ -91,7 +60,6 @@ namespace tut  			ensure("Set environment variable PORT to local test server port", PORT);  			apr_pool_create(&mPool, NULL);  			LLCurl::initClass(false); -			mServerPump = new LLPumpIO(mPool);  			mClientPump = new LLPumpIO(mPool);  			LLHTTPClient::setPump(*mClientPump); @@ -99,20 +67,11 @@ namespace tut  		~HTTPClientTestData()  		{ -			delete mServerPump;  			delete mClientPump;  			LLProxy::cleanupClass();  			apr_pool_destroy(mPool);  		} -		void setupTheServer() -		{ -			LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888); - -			LLHTTPStandardServices::useServices(); -			LLHTTPRegistrar::buildAllServices(root); -		} -  		void runThePump(float timeout = 100.0f)  		{  			LLTimer timer; @@ -120,11 +79,7 @@ namespace tut  			while(!mSawCompleted && !mSawCompletedHeader && !timer.hasExpired())  			{ -				if (mServerPump) -				{ -					mServerPump->pump(); -					mServerPump->callback(); -				} +				LLFrameTimer::updateFrameTime();  				if (mClientPump)  				{  					mClientPump->pump(); @@ -133,18 +88,11 @@ namespace tut  			}  		} -		void killServer() -		{ -			delete mServerPump; -			mServerPump = NULL; -		} -  		const char* const PORT;  		const std::string local_server;  	private:  		apr_pool_t* mPool; -		LLPumpIO* mServerPump;  		LLPumpIO* mClientPump;  	protected: @@ -288,14 +236,12 @@ namespace tut  		sd["list"][1]["three"] = 3;  		sd["list"][1]["four"] = 4; -		setupTheServer(); - -		LLHTTPClient::post("http://localhost:8888/web/echo", sd, newResult()); +		LLHTTPClient::post(local_server + "web/echo", sd, newResult());  		runThePump();  		ensureStatusOK();  		ensure_equals("echoed result matches", getResult(), sd);  	} - +		  	template<> template<>  		void HTTPClientTestObject::test<4>()  	{ @@ -303,12 +249,11 @@ namespace tut  		sd["message"] = "This is my test message."; -		setupTheServer(); -		LLHTTPClient::put("http://localhost:8888/test/storage", sd, newResult()); +		LLHTTPClient::put(local_server + "test/storage", sd, newResult());  		runThePump();  		ensureStatusOK(); -		LLHTTPClient::get("http://localhost:8888/test/storage", newResult()); +		LLHTTPClient::get(local_server + "test/storage", newResult());  		runThePump();  		ensureStatusOK();  		ensure_equals("echoed result matches", getResult(), sd); @@ -322,9 +267,7 @@ namespace tut  		sd["status"] = 543;  		sd["reason"] = "error for testing"; -		setupTheServer(); - -		LLHTTPClient::post("http://localhost:8888/test/error", sd, newResult()); +		LLHTTPClient::post(local_server + "test/error", sd, newResult());  		runThePump();  		ensureStatusError();  		ensure_contains("reason", mReason, sd["reason"]); @@ -333,23 +276,16 @@ namespace tut  	template<> template<>  		void HTTPClientTestObject::test<6>()  	{ -		setupTheServer(); - -		LLHTTPClient::get("http://localhost:8888/test/timeout", newResult()); -		runThePump(1.0f); -		killServer(); -		runThePump(); +		const F32 timeout = 1.0f; +		LLHTTPClient::get(local_server + "test/timeout", newResult(), LLSD(), timeout); +		runThePump(timeout * 5.0f);  		ensureStatusError(); -		ensure_equals("reason", mReason, "STATUS_ERROR"); +		ensure_equals("reason", mReason, "STATUS_EXPIRED");  	}  	template<> template<>  		void HTTPClientTestObject::test<7>()  	{ -		// Can not use the little mini server.  The blocking request -		// won't ever let it run.  Instead get from a known LLSD -		// source and compare results with the non-blocking get which -		// is tested against the mini server earlier.  		LLHTTPClient::get(local_server, newResult());  		runThePump();  		ensureStatusOK(); diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py index fe4f3a8c01..e45249b1cb 100644 --- a/indra/llmessage/tests/test_llsdmessage_peer.py +++ b/indra/llmessage/tests/test_llsdmessage_peer.py @@ -39,6 +39,9 @@ sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python"))  from indra.util.fastest_elementtree import parse as xml_parse  from indra.base import llsd  from testrunner import freeport, run, debug, VERBOSE +import time + +_storage=None  class TestHTTPRequestHandler(BaseHTTPRequestHandler):      """This subclass of BaseHTTPRequestHandler is to receive and echo @@ -90,21 +93,14 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):          # Read the provided POST data.          self.answer(self.read_xml()) +    def do_PUT(self): +        # Read the provided PUT data. +        self.answer(self.read_xml()) +      def answer(self, data, withdata=True): +        global _storage          debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path) -        if "fail" not in self.path: -            data = data.copy()          # we're going to modify -            # Ensure there's a "reply" key in data, even if there wasn't before -            data["reply"] = data.get("reply", llsd.LLSD("success")) -            response = llsd.format_xml(data) -            debug("success: %s", response) -            self.send_response(200) -            self.send_header("Content-type", "application/llsd+xml") -            self.send_header("Content-Length", str(len(response))) -            self.end_headers() -            if withdata: -                self.wfile.write(response) -        else:                           # fail requested +        if "fail" in self.path or "test/error" in self.path: # fail requested              status = data.get("status", 500)              # self.responses maps an int status to a (short, long) pair of              # strings. We want the longer string. That's why we pass a string @@ -117,6 +113,30 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):                                                     "without providing a reason" % status))[1])              debug("fail requested: %s: %r", status, reason)              self.send_error(status, reason) +        else: +            if "web/echo" in self.path: +                pass +            elif "test/timeout" in self.path: +                time.sleep(5.0) +                return +            elif "test/storage" in self.path: +                if "GET" == self.command: +                    data = _storage +                else: +                    _storage = data +                    data = "ok" +            else: +                data = data.copy()          # we're going to modify +                # Ensure there's a "reply" key in data, even if there wasn't before +                data["reply"] = data.get("reply", llsd.LLSD("success")) +            response = llsd.format_xml(data) +            debug("success: %s", response) +            self.send_response(200) +            self.send_header("Content-type", "application/llsd+xml") +            self.send_header("Content-Length", str(len(response))) +            self.end_headers() +            if withdata: +                self.wfile.write(response)      if not VERBOSE:          # When VERBOSE is set, skip both these overrides because they exist to diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 1353b7a458..75d89aac78 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -22,6 +22,10 @@ include_directories(      ${LLWINDOW_INCLUDE_DIRS}      ${LLQTWEBKIT_INCLUDE_DIR}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(llplugin_SOURCE_FILES      llpluginclassmedia.cpp diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 71a6145b58..a4da7674d5 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -31,6 +31,7 @@  #include "llpluginprocessparent.h"  #include "llpluginmessagepipe.h"  #include "llpluginmessageclasses.h" +#include "llsdserialize.h"  #include "stringize.h"  #include "llapr.h" @@ -836,7 +837,7 @@ void LLPluginProcessParent::receiveMessageRaw(const std::string &message)  	LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL;  	LLPluginMessage parsed; -	if(parsed.parse(message) != -1) +	if(LLSDParser::PARSE_FAILURE != parsed.parse(message))  	{  		if(parsed.hasValue("blocking_request"))  		{ diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index 8183467dc5..03412d95d5 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -12,6 +12,9 @@ include_directories(      ${LLMESSAGE_INCLUDE_DIRS}      ${LLCOMMON_INCLUDE_DIRS}  ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  if (DARWIN)      include(CMakeFindFrameworks) diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index e4d9de7eb6..1768a06a27 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -14,10 +14,14 @@ include_directories(      ${LLMATH_INCLUDE_DIRS}      ${LLMESSAGE_INCLUDE_DIRS}      ${LLXML_INCLUDE_DIRS} -    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}      ${LIBS_PREBUILT_DIR}/include/collada      ${LIBS_PREBUILT_DIR}/include/collada/1.4      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS} +    )  set(llprimitive_SOURCE_FILES      llmaterialtable.cpp @@ -59,6 +63,15 @@ list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})  add_library (llprimitive ${llprimitive_SOURCE_FILES}) +target_link_libraries(llprimitive +    ${LLCOMMON_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${LLMESSAGE_LIBRARIES} +    ${LLXML_LIBRARIES} +    ${LLPHYSICSEXTENSIONS_LIBRARIES} +    ) + +  #add unit tests  if (LL_TESTS)      INCLUDE(LLAddBuildTest) diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 946251f383..c340fc2d35 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -38,6 +38,7 @@  #include "lldatapacker.h"  #include "llsdutil_math.h"  #include "llprimtexturelist.h" +#include "imageids.h"  /**   * exported constants @@ -1230,94 +1231,78 @@ 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)  	{ +		tec.face_count = 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 = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES); -	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++) -	{ -		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); +	for (U32 i = 0; i < tec.face_count; i++) +	{ +		LLUUID& req_id = ((LLUUID*)tec.image_data)[i]; +		retval |= setTETexture(i, req_id); +		retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]); +		retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF); +		retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); +		retval |= setTEBumpShinyFullbright(i, tec.bump[i]); +		retval |= setTEMediaTexGen(i, tec.media_flags[i]); +		retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF); +		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 @@ -1334,6 +1319,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 8dcaa8c740..6a8b59c81c 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -289,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: @@ -360,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/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 516af93316..669b70aa43 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -3,7 +3,7 @@  project(llrender)  include(00-Common) -include(FindOpenGL) +include(OpenGL)  include(FreeType)  include(LLCommon)  include(LLImage) @@ -25,21 +25,31 @@ include_directories(      ${LLXML_INCLUDE_DIRS}      ${LLVFS_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(llrender_SOURCE_FILES      llcubemap.cpp +    llfontbitmapcache.cpp      llfontfreetype.cpp      llfontgl.cpp -    llfontbitmapcache.cpp      llfontregistry.cpp +    llgl.cpp      llgldbg.cpp      llglslshader.cpp +    llgltexture.cpp      llimagegl.cpp      llpostprocess.cpp +    llrender.cpp +    llrender2dutils.cpp      llrendernavprim.cpp      llrendersphere.cpp +    llrendertarget.cpp      llshadermgr.cpp      lltexture.cpp +    lluiimage.cpp      llvertexbuffer.cpp      ) @@ -56,14 +66,17 @@ set(llrender_HEADER_FILES      llglheaders.h      llglslshader.h      llglstates.h +    llgltexture.h      llgltypes.h      llimagegl.h      llpostprocess.h      llrender.h +    llrender2dutils.h      llrendernavprim.h      llrendersphere.h      llshadermgr.h      lltexture.h +    lluiimage.h      llvertexbuffer.h      ) @@ -72,33 +85,47 @@ set_source_files_properties(${llrender_HEADER_FILES}  list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES}) -if (SERVER AND NOT WINDOWS AND NOT DARWIN) -  copy_server_sources( -      llgl -      llrender -      ) - - -  set_source_files_properties( -    ${server_SOURCE_FILES} -    PROPERTIES -    COMPILE_FLAGS "-DLL_MESA=1 -DLL_MESA_HEADLESS=1" -    ) +if (BUILD_HEADLESS)    add_library (llrenderheadless      ${llrender_SOURCE_FILES} -    ${server_SOURCE_FILES}      ) -else (SERVER AND NOT WINDOWS AND NOT DARWIN) -  list(APPEND llrender_SOURCE_FILES -      llgl.cpp -      llrender.cpp -      llrendertarget.cpp -      ) -endif (SERVER AND NOT WINDOWS AND NOT DARWIN) + +  set_property(TARGET llrenderheadless +    PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 +    ) + +  target_link_libraries(llrenderheadless +    ${LLCOMMON_LIBRARIES} +    ${LLIMAGE_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${LLRENDER_HEADLESS_LIBRARIES} +    ${LLVFS_LIBRARIES} +    ${LLXML_LIBRARIES} +    ${LLVFS_LIBRARIES} +    ${LLWINDOW_HEADLESS_LIBRARIES} +    ${OPENGL_HEADLESS_LIBRARIES}) + +endif (BUILD_HEADLESS) +  add_library (llrender ${llrender_SOURCE_FILES}) + +if (SDL_FOUND) +  set_property(TARGET llrender +    PROPERTY COMPILE_DEFINITIONS LL_SDL=1 +    ) +endif (SDL_FOUND) +  # Libraries on which this library depends, needed for Linux builds  # Sort by high-level to low-level  target_link_libraries(llrender  -    llimage  +    ${LLCOMMON_LIBRARIES} +    ${LLIMAGE_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${LLRENDER_LIBRARIES} +    ${LLVFS_LIBRARIES} +    ${LLXML_LIBRARIES} +    ${LLVFS_LIBRARIES} +    ${LLWINDOW_LIBRARIES}      ${FREETYPE_LIBRARIES}      ${OPENGL_LIBRARIES}) + diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 66d4ad2d87..058bef43a5 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -485,14 +485,11 @@ void LLFontFreetype::renderGlyph(U32 glyph_index) const  	if (mFTFace == NULL)  		return; -	int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT ); -	llassert(!error); +	llassert_always(! FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT) ); -	error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode); +	llassert_always(! FT_Render_Glyph(mFTFace->glyph, gFontRenderMode) );  	mRenderGlyphCount++; -	 -	llassert(!error);  }  void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi) diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 8772779645..c4f36cabd0 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -541,7 +541,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch  	BOOL clip = FALSE;  	F32 cur_x = 0; -	F32 drawn_x = 0;  	S32 start_of_last_word = 0;  	BOOL in_word = FALSE; @@ -629,7 +628,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch  		// Round after kerning.  		cur_x = (F32)llround(cur_x); -		drawn_x = cur_x;  	}  	if( clip ) diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index b5bdba996f..f5ca8d5b04 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -223,7 +223,7 @@ std::string currentOsName()  	return "Windows";  #elif LL_DARWIN  	return "Mac"; -#elif LL_SDL +#elif LL_SDL || LL_MESA_HEADLESS  	return "Linux";  #else  	return ""; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 29f454ab54..d521114c9e 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -1486,6 +1486,7 @@ void assert_glerror()  void clear_glerror()  {  	glGetError(); +	glGetError();  }  /////////////////////////////////////////////////////////////// diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 5c68cb46eb..cf21101e35 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -159,6 +159,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 0000000000..d06ed5e57b --- /dev/null +++ b/indra/llrender/llgltexture.cpp @@ -0,0 +1,396 @@ +/**  + * @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() ;		 +		} +	} +} + +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) +{ +	llassert(mGLTexturep.notNull()) ; + +	return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ; +} + +BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) +{ +	llassert(mGLTexturep.notNull()) ; + +	return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ; +} + +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; +} + + diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h new file mode 100644 index 0000000000..e69b322d60 --- /dev/null +++ b/indra/llrender/llgltexture.h @@ -0,0 +1,199 @@ +/**  + * @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 +	}; + +	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; + +	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       setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height); +	void       setGLTextureCreated (bool initialized); +	void       setCategory(S32 category) ; + +	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 ; +	LLGLTextureState getTextureState() const { return mTextureState; } +	 +	//--------------------------------------------------------------------------------------------- +	//end of functions to access LLImageGL +	//--------------------------------------------------------------------------------------------- + +	//----------------- +	/*virtual*/ void setActive() ; +	void forceActive() ; +	void setNoDelete() ; +	void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; } +	BOOL getDontDiscard() const { return mDontDiscard; } +	//-----------------	 + +private: +	void cleanup(); +	void init(); + +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<LLImageGL> mGLTexturep ; +	S8 mDontDiscard;			// Keep full res version of this image (for UI, etc) + +protected: +	LLGLTextureState  mTextureState ; + + +}; + +#endif // LL_GL_TEXTURE_H + diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index a4d7872ec2..249b8da880 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -74,6 +74,9 @@ S32 LLImageGL::sCurTexSizeBar = -1 ;  S32 LLImageGL::sCurTexPickSize = -1 ;  S32 LLImageGL::sMaxCategories = 1 ; +//optimization for when we don't need to calculate mIsMask +BOOL LLImageGL::sSkipAnalyzeAlpha; +  //------------------------  //****************************************************************************************************  //End for texture auditing use only @@ -169,8 +172,9 @@ BOOL is_little_endian()  	return (*c == 0x78) ;  }  //static  -void LLImageGL::initClass(S32 num_catagories)  +void LLImageGL::initClass(S32 num_catagories, BOOL skip_analyze_alpha /* = false */)  { +	sSkipAnalyzeAlpha = skip_analyze_alpha;  }  //static  @@ -611,14 +615,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) @@ -738,8 +744,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  				S32 w = width, h = height;  				const U8* prev_mip_data = 0;  				const U8* cur_mip_data = 0; -				S32 prev_mip_size = 0; +#ifdef SHOW_ASSERT  				S32 cur_mip_size = 0; +#endif  				mMipLevels = nummips; @@ -748,18 +755,24 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  					if (m==0)  					{  						cur_mip_data = data_in; +#ifdef SHOW_ASSERT  						cur_mip_size = width * height * mComponents;  +#endif  					}  					else  					{  						S32 bytes = w * h * mComponents; +#ifdef SHOW_ASSERT  						llassert(prev_mip_data); -						llassert(prev_mip_size == bytes*4); +						llassert(cur_mip_size == bytes*4); +#endif  						U8* new_data = new U8[bytes];  						llassert_always(new_data);  						LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);  						cur_mip_data = new_data; +#ifdef SHOW_ASSERT  						cur_mip_size = bytes;  +#endif  					}  					llassert(w > 0 && h > 0 && cur_mip_data);  					{ @@ -792,7 +805,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  						delete[] prev_mip_data;  					}  					prev_mip_data = cur_mip_data; -					prev_mip_size = cur_mip_size;  					w >>= 1;  					h >>= 1;  				} @@ -1053,8 +1065,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); @@ -1115,8 +1129,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) @@ -1220,9 +1236,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()  { -	if (gHeadlessClient) return FALSE; +	LLFastTimer t(FTM_CREATE_GL_TEXTURE1);  	if (gGLManager.mIsDisabled)  	{  		llwarns << "Trying to create a texture while GL is disabled!" << llendl; @@ -1250,9 +1267,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)  { -	if (gHeadlessClient) return FALSE; +	LLFastTimer t(FTM_CREATE_GL_TEXTURE2);  	if (gGLManager.mIsDisabled)  	{  		llwarns << "Trying to create a texture while GL is disabled!" << llendl; @@ -1324,8 +1342,10 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S  	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(); @@ -1702,6 +1722,12 @@ BOOL LLImageGL::getBoundRecently() const  	return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);  } +BOOL LLImageGL::getIsAlphaMask() const +{ +	llassert_always(!sSkipAnalyzeAlpha); +	return mIsMask; +} +  void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)  {  	mTarget = target; @@ -1799,7 +1825,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()  void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)  { -	if(!mNeedsAlphaAndPickMask) +	if(sSkipAnalyzeAlpha || !mNeedsAlphaAndPickMask)  	{  		return ;  	} diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index cf3c484c79..57a052b258 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -142,7 +142,7 @@ public:  	BOOL getHasGLTexture() const { return mTexName != 0; }  	LLGLuint getTexName() const { return mTexName; } -	BOOL getIsAlphaMask() const { return mIsMask; } +	BOOL getIsAlphaMask() const;  	BOOL getIsResident(BOOL test_now = FALSE); // not const @@ -262,11 +262,12 @@ public:  #endif  public: -	static void initClass(S32 num_catagories) ; +	static void initClass(S32 num_catagories, BOOL skip_analyze_alpha = false);   	static void cleanupClass() ;  private:  	static S32 sMaxCategories; +	static BOOL sSkipAnalyzeAlpha;  	//the flag to allow to call readBackRaw(...).  	//can be removed if we do not use that function at all. diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 4597d06260..c60eb8d9d9 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -357,7 +357,6 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)  }  // LLRenderTarget is unavailible on the mapserver since it uses FBOs. -#if !LL_MESA_HEADLESS  bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)  {  	if (mIndex < 0) return false; @@ -380,7 +379,6 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)  	return true;  } -#endif // LL_MESA_HEADLESS  bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)  { diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp new file mode 100644 index 0000000000..d3cfbaf03a --- /dev/null +++ b/indra/llrender/llrender2dutils.cpp @@ -0,0 +1,1608 @@ +/**  + * @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.pushUIMatrix(); +	left += LLFontGL::sCurOrigin.mX; +	right += LLFontGL::sCurOrigin.mX; +	bottom += LLFontGL::sCurOrigin.mY; +	top += LLFontGL::sCurOrigin.mY; + +	gGL.loadUIIdentity(); +	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.popUIMatrix(); +} + + +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 = gGL.getUIScale(); +	const LLVector3 ui_translation = (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]; +	LLVector3 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] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); +		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); +		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); +		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); +		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); +		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); +		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom); +		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); +		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); +		pos[index] = LLVector3(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] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); +		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); +		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); +		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); +		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); +		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); +		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); +		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); +		index++; + +		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); +		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); +		pos[index] = LLVector3(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] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); +		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); +		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop); +		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); +		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); +		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); +		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); +		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop); +		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f); +		index++; + +		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); +		pos[index] = LLVector3(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]; +		LLVector3 pos[NUM_VERTICES]; + +		gGL.begin(LLRender::QUADS); +		{ +			LLVector3 ui_scale = gGL.getUIScale(); +			LLVector3 ui_translation = 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] = LLVector3(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] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f); +			index++; + +			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); +			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f); +			index++; + +			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); +			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f); +			index++; + +			gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); +		} +		gGL.end(); +	} +	else +	{ +		gGL.pushUIMatrix(); +		gGL.translateUI((F32)x, (F32)y, 0.f); +	 +		F32 offset_x = F32(width/2); +		F32 offset_y = F32(height/2); + +		gGL.translateUI(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.popUIMatrix(); +	} +} + + +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.pushUIMatrix(); +	{ +		gGL.translateUI(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.popUIMatrix(); +} + +void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled) +{ +	gGL.pushUIMatrix(); +	{ +		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +		gGL.translateUI(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.popUIMatrix(); +} + +// 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.pushUIMatrix(); +	{ +		gGL.translateUI(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.translateUI(0.f, 0.f, width); +			gl_washer_2d(radius - width, radius, steps, side_color, side_color); +		} +	} +	gGL.popUIMatrix(); +} + +// Draw gray and white checkerboard with black border +void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha) +{ +	if (!LLGLSLShader::sNoFixedFunction) +	{  +	// Initialize the first time this is called. +	const S32 PIXELS = 32; +	static GLubyte checkerboard[PIXELS * PIXELS]; +	static BOOL first = TRUE; +	if( first ) +	{ +		for( S32 i = 0; i < PIXELS; i++ ) +		{ +			for( S32 j = 0; j < PIXELS; j++ ) +			{ +				checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF; +			} +		} +		first = FALSE; +	} +	 +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +	// ...white squares +	gGL.color4f( 1.f, 1.f, 1.f, alpha ); +	gl_rect_2d(rect); + +	// ...gray squares +	gGL.color4f( .7f, .7f, .7f, alpha ); +	gGL.flush(); + +		glPolygonStipple( checkerboard ); + +		LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE); +		gl_rect_2d(rect); +	} +	else +	{ //polygon stipple is deprecated, use "Checker" texture +		LLPointer<LLUIImage> img = LLRender2D::getUIImage("Checker"); +		gGL.getTexUnit(0)->bind(img->getImage()); +		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); +		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + +		LLColor4 color(1.f, 1.f, 1.f, alpha); +		LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f); + +		gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), +			img->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(); +} + +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.pushUIMatrix(); + +	gGL.translateUI((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.popUIMatrix(); +} + +//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.pushUIMatrix(); + +	gGL.translateUI((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.popUIMatrix(); +} + +void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,  +							 const LLVector3& width_vec, const LLVector3& height_vec) +{ +	gGL.begin(LLRender::QUADS); +	{ +		// draw bottom left +		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom); +		gGL.vertex3f(0.f, 0.f, 0.f); + +		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); + +		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV); + +		// draw bottom middle +		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); + +		// draw bottom right +		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV); + +		gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom); +		gGL.vertex3fv(width_vec.mV); + +		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); + +		// draw left  +		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); + +		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV); + +		// draw middle +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); + +		// draw right  +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); + +		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV); + +		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); + +		// draw top left +		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV); + +		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop); +		gGL.vertex3fv((height_vec).mV); + +		// draw top middle +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV); + +		// draw top right +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); + +		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV); + +		gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop); +		gGL.vertex3fv((width_vec + height_vec).mV); + +		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV); +	} +	gGL.end(); + +} + +// 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.translateUI(x,y,z); +	LLFontGL::sCurOrigin.mX += (S32) x; +	LLFontGL::sCurOrigin.mY += (S32) y; +	LLFontGL::sCurDepth += z; +} + +//static +void LLRender2D::pushMatrix() +{ +	gGL.pushUIMatrix(); +	LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth)); +} + +//static +void LLRender2D::popMatrix() +{ +	gGL.popUIMatrix(); +	LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first; +	LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second; +	LLFontGL::sOriginStack.pop_back(); +} + +//static  +void LLRender2D::loadIdentity() +{ +	gGL.loadUIIdentity();  +	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<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority) +{ +	if (sImageProvider) +	{ +		return sImageProvider->getUIImageByID(image_id, priority); +	} +	else +	{ +		return NULL; +	} +} + +//static  +LLPointer<LLUIImage> LLRender2D::getUIImage(const std::string& name, S32 priority) +{ +	if (!name.empty() && sImageProvider) +		return sImageProvider->getUIImage(name, priority); +	else +		return NULL; +} + diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h new file mode 100644 index 0000000000..4884422c58 --- /dev/null +++ b/indra/llrender/llrender2dutils.h @@ -0,0 +1,163 @@ +/**  + * @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& 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_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 LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, 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<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0); +	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0); + +	static LLVector2		sGLScaleFactor; +private: +	static LLImageProviderInterface* sImageProvider; +}; + +class LLImageProviderInterface +{ +protected: +	LLImageProviderInterface() {}; +	virtual ~LLImageProviderInterface() {}; +public: +	virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0; +	virtual LLPointer<LLUIImage> 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 e35feda2d5..25109268e8 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -579,3 +579,5 @@ void LLRenderTarget::getViewport(S32* viewport)  	viewport[3] = mResY;  } + + diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index cf15f66d31..765a727b5b 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -28,7 +28,6 @@  #define LL_LLRENDERTARGET_H  // LLRenderTarget is unavailible on the mapserver since it uses FBOs. -#if !LL_MESA_HEADLESS  #include "llgl.h"  #include "llrender.h" @@ -156,7 +155,5 @@ protected:  	static LLRenderTarget* sBoundTarget;  }; -#endif //!LL_MESA_HEADLESS -  #endif diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h index 569a65c2e0..093bac20d1 100644 --- a/indra/llrender/lltexture.h +++ b/indra/llrender/lltexture.h @@ -38,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 ; @@ -53,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 index 9ed98f941f..b954b66350 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<LLTexture> image)  :	mName(name), @@ -130,10 +130,10 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c  		 }  	} -	LLUI::pushMatrix(); +	LLRender2D::pushMatrix();  	{   		LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);  -		LLUI::translate(rect_origin.mV[VX], +		LLRender2D::translate(rect_origin.mV[VX],  						rect_origin.mV[VY],   						rect_origin.mV[VZ]);  		gGL.getTexUnit(0)->bind(getImage()); @@ -152,7 +152,7 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c  								rect.getWidth() * x_axis,   								rect.getHeight() * y_axis); -	} LLUI::popMatrix(); +	} LLRender2D::popMatrix();  } @@ -209,7 +209,7 @@ namespace LLInitParam  			return;  		} -		LLUIImage* imagep =  LLUI::getUIImage(name()); +		LLUIImage* imagep =  LLRender2D::getUIImage(name());  		if (imagep)  		{  			updateValue(imagep); diff --git a/indra/llui/lluiimage.h b/indra/llrender/lluiimage.h index 7817ba1c7b..7817ba1c7b 100644 --- a/indra/llui/lluiimage.h +++ b/indra/llrender/lluiimage.h diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index dfbd8cd4ee..4909b43e8a 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -402,7 +402,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  {  	if (sLastMask != data_mask)  	{ -		bool error = false;  		if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 30)  		{ @@ -469,7 +468,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  						{  							if (gDebugSession)  							{ -								error = true;  								gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;  							}  							else @@ -489,7 +487,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  					{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)  						if (gDebugSession)  						{ -							error = true;  							gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;  						}  						else @@ -548,8 +545,10 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  }  //static +static LLFastTimer::DeclareTimer FTM_VB_DRAW_ARRAYS("drawArrays");  void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)  { +	LLFastTimer t(FTM_VB_DRAW_ARRAYS);  	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);  	gGL.syncMatrices(); @@ -784,6 +783,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const  	placeFence();  } +static LLFastTimer::DeclareTimer FTM_GL_DRAW_ARRAYS("GL draw arrays");  void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const  {  	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); @@ -818,8 +818,11 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const  		return;  	} -	stop_glerror(); -	glDrawArrays(sGLMode[mode], first, count); +	{ +		LLFastTimer t2(FTM_GL_DRAW_ARRAYS); +		stop_glerror(); +		glDrawArrays(sGLMode[mode], first, count); +	}  	stop_glerror();  	placeFence();  } @@ -1565,8 +1568,10 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo  				{  					if (map_range)  					{ +#ifndef LL_MESA_HEADLESS  						glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);  						glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE); +#endif  						src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);  					}  					else @@ -1740,8 +1745,10 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range  				{  					if (map_range)  					{ +#ifndef LL_MESA_HEADLESS  						glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);  						glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE); +#endif  						src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);  					}  					else @@ -1868,7 +1875,9 @@ void LLVertexBuffer::unmapBuffer()  						}  						else if (gGLManager.mHasFlushBufferRange)  						{ +#ifndef LL_MESA_HEADLESS  							glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length); +#endif  						}  						stop_glerror();  					} @@ -1934,8 +1943,10 @@ void LLVertexBuffer::unmapBuffer()  						else if (gGLManager.mHasFlushBufferRange)  						{  #ifdef GL_APPLE_flush_buffer_range +#ifndef LL_MESA_HEADLESS  							glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);  #endif +#endif  						}  						stop_glerror();  					} @@ -2209,7 +2220,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  			setup = setup || bindBuffer || bindIndices;  		} -		bool error = false;  		if (gDebugGL && !mGLArray)  		{  			GLint buff; @@ -2218,7 +2228,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  			{  				if (gDebugSession)  				{ -					error = true;  					gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;  				}  				else @@ -2234,7 +2243,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  				{  					if (gDebugSession)  					{ -						error = true;  						gFailLog << "Invalid GL index buffer bound: " << buff <<  std::endl;  					}  					else diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 9c961d67d6..34a08603fa 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -25,6 +25,10 @@ include_directories(      ${LLXML_INCLUDE_DIRS}      ${LIBS_PREBUILD_DIR}/include/hunspell      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(llui_SOURCE_FILES      llaccordionctrl.cpp @@ -113,7 +117,6 @@ set(llui_SOURCE_FILES      lluicolortable.cpp      lluictrl.cpp      lluictrlfactory.cpp -    lluiimage.cpp      lluistring.cpp      llundo.cpp      llurlaction.cpp @@ -227,7 +230,6 @@ set(llui_HEADER_FILES      lluifwd.h      llui.h      lluicolor.h -    lluiimage.h      lluistring.h      llundo.h      llurlaction.h diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp index 9e48dcde7e..6a1b48a08a 100644 --- a/indra/llui/llchatentry.cpp +++ b/indra/llui/llchatentry.cpp @@ -25,6 +25,7 @@   */  #include "linden_common.h" +#include "llscrollcontainer.h"  #include "llchatentry.h" @@ -42,7 +43,9 @@ LLChatEntry::LLChatEntry(const Params& p)   	mHasHistory(p.has_history),   	mIsExpandable(p.is_expandable),   	mExpandLinesCount(p.expand_lines_count), - 	mPrevLinesCount(0) + 	mPrevLinesCount(0), +	mSingleLineMode(false), +	mPrevExpandedLineCount(S32_MAX)  {  	// Initialize current history line iterator  	mCurrentHistoryLine = mLineHistory.begin(); @@ -82,20 +85,23 @@ boost::signals2::connection LLChatEntry::setTextExpandedCallback(const commit_si  void LLChatEntry::expandText()  { +	S32 line_count = mSingleLineMode ? 1 : mExpandLinesCount; +  	int visible_lines_count = llabs(getVisibleLines(true).first - getVisibleLines(true).second); -	bool can_expand = getLineCount() <= mExpandLinesCount; +	bool can_changed = getLineCount() <= line_count || line_count < mPrevExpandedLineCount ; +	mPrevExpandedLineCount = line_count;  	// true if pasted text has more lines than expand height limit and expand limit is not reached yet -	bool text_pasted = (getLineCount() > mExpandLinesCount) && (visible_lines_count < mExpandLinesCount); +	bool text_pasted = (getLineCount() > line_count) && (visible_lines_count < line_count); -	if (mIsExpandable && (can_expand || text_pasted) && getLineCount() != mPrevLinesCount) +	if (mIsExpandable && (can_changed || text_pasted || mSingleLineMode) && getLineCount() != mPrevLinesCount)  	{  		int lines_height = 0;  		if (text_pasted)  		{  			// text is pasted and now mLineInfoList.size() > mExpandLineCounts and mLineInfoList is not empty, -			// so lines_height is the sum of the last 'mExpandLinesCount' lines height -			lines_height = (mLineInfoList.end() - mExpandLinesCount)->mRect.mTop - mLineInfoList.back().mRect.mBottom; +			// so lines_height is the sum of the last 'expanded_line_count' lines height +			lines_height = (mLineInfoList.end() - line_count)->mRect.mTop - mLineInfoList.back().mRect.mBottom;  		}  		else  		{ @@ -114,6 +120,8 @@ void LLChatEntry::expandText()  		{  			(*mTextExpandedSignal)(this, LLSD() );  		} + +		needsReflow();  	}  } @@ -235,3 +243,15 @@ BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)  	return handled;  } + +void LLChatEntry::enableSingleLineMode(bool single_line_mode) +{ +	if (mScroller) +	{ +		mScroller->setSize(single_line_mode ? 0 : -1); +	} + +	mSingleLineMode = single_line_mode; +	mPrevLinesCount = -1; +	setWordWrap(!single_line_mode); +} diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h index 49181c8d78..49c8d21450 100644 --- a/indra/llui/llchatentry.h +++ b/indra/llui/llchatentry.h @@ -65,6 +65,7 @@ public:      /*virtual*/ void	onFocusReceived();      /*virtual*/ void	onFocusLost(); +	void enableSingleLineMode(bool single_line_mode);  	boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);  private: @@ -95,9 +96,11 @@ private:  	line_history_t						mLineHistory;			// line history storage  	bool								mHasHistory;			// flag for enabled/disabled line history  	bool								mIsExpandable; +	bool								mSingleLineMode; -	int									mExpandLinesCount; -	int									mPrevLinesCount; +	S32									mExpandLinesCount; +	S32									mPrevLinesCount; +	S32									mPrevExpandedLineCount;  };  #endif /* LLCHATENTRY_H_ */ diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 41e5d74042..d4e14d9419 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -551,7 +551,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; diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index 161496b1f5..c216d593a2 100644 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -243,7 +243,6 @@ void LLConsole::draw()  void LLConsole::Paragraph::makeParagraphColorSegments (const LLColor4 &color)   {  	LLSD paragraph_color_segments; -	LLColor4 lcolor=color;  	paragraph_color_segments[0]["text"] =wstring_to_utf8str(mParagraphText);  	LLSD color_sd = color.getValue(); diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 8feaf654f0..8aa1eb7cd5 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -1055,12 +1055,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )  		LLMenuGL::sMenuContainer->hideMenus();  	} -	LLView *item = NULL; -	if (getChildCount() > 0) -	{ -		item = *(getChildList()->begin()); -	} -  	switch( key )  	{  	case KEY_F2: diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h index 899cc3a326..beac212441 100644 --- a/indra/llui/llfunctorregistry.h +++ b/indra/llui/llfunctorregistry.h @@ -69,7 +69,6 @@ public:  	bool registerFunctor(const std::string& name, ResponseFunctor f)  	{  		bool retval = true; -		typename FunctorMap::iterator it = mMap.find(name);  		if (mMap.count(name) == 0)  		{  			mMap[name] = f; @@ -96,7 +95,6 @@ public:  	FUNCTOR_TYPE getFunctor(const std::string& name)  	{ -		typename FunctorMap::iterator it = mMap.find(name);  		if (mMap.count(name) != 0)  		{  			return mMap[name]; diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index c1cd04186b..795dacdbb0 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -367,7 +367,6 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  	const llwchar* base = wtext.c_str();  	const llwchar* cur = base; -	const llwchar* line = NULL;  	while( *cur )  	{ @@ -385,9 +384,6 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  				}  			} -			// Start of a new line -			line = cur; -  			// Skip white space  			while( *cur && isspace(*cur) && (*cur != '\n')  )  			{ diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index e642883991..e33ac1d5c2 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -476,7 +476,6 @@ void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp)  		if (lp->mResizeBar == NULL)  		{  			LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM; -			LLRect resize_bar_rect = getRect();  			LLResizeBar::Params resize_params;  			resize_params.name("resize"); diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 6976b06a92..5478e85e13 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -2023,8 +2023,8 @@ void LLLineEditor::draw()  				LLRect screen_pos = calcScreenRect();  				LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - 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 );  			}  		} @@ -2571,7 +2571,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 6841301219..0620e0f52d 100644 --- a/indra/llui/lllocalcliprect.cpp +++ b/indra/llui/lllocalcliprect.cpp @@ -33,7 +33,7 @@  LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled) -:	mScissorState(GL_SCISSOR_TEST), +	:	mScissorState(GL_SCISSOR_TEST),  	mEnabled(enabled)  {  	if (mEnabled) @@ -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();  } @@ -100,10 +100,10 @@ void LLScreenClipRect::updateScissorRegion()  // LLLocalClipRect  //---------------------------------------------------------------------------  LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */) -:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,  -					rect.mTop + LLFontGL::sCurOrigin.mY,  -					rect.mRight + LLFontGL::sCurOrigin.mX,  -					rect.mBottom + LLFontGL::sCurOrigin.mY), enabled) +	:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,  +	rect.mTop + LLFontGL::sCurOrigin.mY,  +	rect.mRight + LLFontGL::sCurOrigin.mX,  +	rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)  {}  LLLocalClipRect::~LLLocalClipRect() diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 5d3bf7a670..13887cbe73 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -642,3 +642,8 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data )  {  	changeLine( mStepSize, TRUE );  } + +void LLScrollbar::setThickness(S32 thickness) +{ +	mThickness = thickness < 0 ? LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize") : thickness; +} diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index ff74f753b9..21fd2d631e 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -124,6 +124,9 @@ public:  	void				onLineUpBtnPressed(const LLSD& data);  	void				onLineDownBtnPressed(const LLSD& data); +		 +	S32					getThickness() const { return mThickness; } +	void				setThickness(S32 thickness);  private:  	void				updateThumbRect(); diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 2fd187a526..cbcce0ece5 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -73,7 +73,8 @@ LLScrollContainer::Params::Params()  	hide_scrollbar("hide_scrollbar"),  	min_auto_scroll_rate("min_auto_scroll_rate", 100),  	max_auto_scroll_rate("max_auto_scroll_rate", 1000), -	reserve_scroll_corner("reserve_scroll_corner", false) +	reserve_scroll_corner("reserve_scroll_corner", false), +	size("size", -1)  {} @@ -88,9 +89,12 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)  	mReserveScrollCorner(p.reserve_scroll_corner),  	mMinAutoScrollRate(p.min_auto_scroll_rate),  	mMaxAutoScrollRate(p.max_auto_scroll_rate), -	mScrolledView(NULL) +	mScrolledView(NULL), +	mSize(p.size)  { -	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); +	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0); +	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize); +  	LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );  	LLViewBorder::Params params;  	params.name("scroll border"); @@ -276,7 +280,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,  												  EAcceptance* accept,  												  std::string& tooltip_msg)  { -	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);  	// Scroll folder view if needed.  Never accepts a drag or drop.  	*accept = ACCEPT_NO;  	BOOL handled = autoScroll(x, y); @@ -292,7 +295,8 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,  bool LLScrollContainer::autoScroll(S32 x, S32 y)  { -	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); +	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0); +	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);  	bool scrolling = false;  	if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() ) @@ -365,7 +369,9 @@ bool LLScrollContainer::autoScroll(S32 x, S32 y)  void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const  {  	const LLRect& doc_rect = getScrolledViewRect(); -	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); +	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0); +	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize); +  	S32 doc_width = doc_rect.getWidth();  	S32 doc_height = doc_rect.getHeight(); @@ -406,7 +412,9 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height  void LLScrollContainer::draw()  { -	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); +	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0); +	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize); +  	if (mAutoScrolling)  	{  		// add acceleration to autoscroll @@ -515,7 +523,9 @@ void LLScrollContainer::updateScroll()  	{  		return;  	} -	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); +	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0); +	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize); +  	LLRect doc_rect = mScrolledView->getRect();  	S32 doc_width = doc_rect.getWidth();  	S32 doc_height = doc_rect.getHeight(); @@ -716,3 +726,9 @@ S32 LLScrollContainer::getBorderWidth() const  	return 0;  } +void LLScrollContainer::setSize(S32 size) +{ +	mSize = size; +	mScrollbar[VERTICAL]->setThickness(size); +	mScrollbar[HORIZONTAL]->setThickness(size); +} diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index d87c95b3d7..4eb43539b8 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -68,6 +68,7 @@ public:  							max_auto_scroll_rate;  		Optional<LLUIColor>	bg_color;  		Optional<LLScrollbar::callback_t> scroll_callback; +		Optional<S32>		size;  		Params();  	}; @@ -116,6 +117,9 @@ public:  	bool autoScroll(S32 x, S32 y); +	S32 getSize() const { return mSize; } +	void setSize(S32 thickness); +  protected:  	LLView*		mScrolledView; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 1a9f5874a1..4adfd42edd 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1805,6 +1805,9 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)  			// (N.B. callbacks don't take const refs as id is local scope)  			bool is_group = (mContextMenuType == MENU_GROUP);  			LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; +			registrar.add("Url.ShowProfile", boost::bind(&LLScrollListCtrl::showProfile, id, is_group)); +			registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id)); +			registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));  			registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));  			registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));  			registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group)); @@ -1825,11 +1828,33 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)  	return FALSE;  } -void LLScrollListCtrl::showNameDetails(std::string id, bool is_group) +void LLScrollListCtrl::showProfile(std::string id, bool is_group)  {  	// show the resident's profile or the group profile  	std::string sltype = is_group ? "group" : "agent";  	std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about"; +	LLUrlAction::showProfile(slurl); +} + +void LLScrollListCtrl::sendIM(std::string id) +{ +	// send im to the resident +	std::string slurl = "secondlife:///app/agent/" + id + "/about"; +	LLUrlAction::sendIM(slurl); +} + +void LLScrollListCtrl::addFriend(std::string id) +{ +	// add resident to friends list +	std::string slurl = "secondlife:///app/agent/" + id + "/about"; +	LLUrlAction::addFriend(slurl); +} + +void LLScrollListCtrl::showNameDetails(std::string id, bool is_group) +{ +	// open the resident's details or the group details +	std::string sltype = is_group ? "group" : "agent"; +	std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";  	LLUrlAction::clickAction(slurl);  } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 0b629a76f7..7bc558f742 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -430,6 +430,9 @@ private:  	BOOL			setSort(S32 column, BOOL ascending);  	S32				getLinesPerPage(); +	static void		showProfile(std::string id, bool is_group); +	static void		sendIM(std::string id); +	static void		addFriend(std::string id);  	static void		showNameDetails(std::string id, bool is_group);  	static void		copyNameToClipboard(std::string id, bool is_group);  	static void		copySLURLToClipboard(std::string id, bool is_group); diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp index a189375fbe..250372da5b 100644 --- a/indra/llui/llspellcheck.cpp +++ b/indra/llui/llspellcheck.cpp @@ -145,10 +145,14 @@ void LLSpellChecker::refreshDictionaryMap()  	// Load dictionary information (file name, friendly name, ...)  	llifstream user_file(user_path + DICT_FILE_MAIN, std::ios::binary); -	if ( (!user_file.is_open()) || (0 == LLSDSerialize::fromXMLDocument(sDictMap, user_file)) || (0 == sDictMap.size()) ) +	if ( (!user_file.is_open())  +		|| (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(sDictMap, user_file))  +		|| (0 == sDictMap.size()) )  	{  		llifstream app_file(app_path + DICT_FILE_MAIN, std::ios::binary); -		if ( (!app_file.is_open()) || (0 == LLSDSerialize::fromXMLDocument(sDictMap, app_file)) || (0 == sDictMap.size()) ) +		if ( (!app_file.is_open())  +			|| (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(sDictMap, app_file))  +			|| (0 == sDictMap.size()) )  		{  			return;  		} diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 6f895ed939..fd98155704 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1215,9 +1215,11 @@ void LLTabContainer::removeTabPanel(LLPanel* child)  				removeChild( tuple->mButton );  			}   			delete tuple->mButton; +            tuple->mButton = NULL;   			removeChild( tuple->mTabPanel );  // 			delete tuple->mTabPanel; +            tuple->mTabPanel = NULL;  			mTabList.erase( iter );  			delete tuple; @@ -1279,9 +1281,11 @@ void LLTabContainer::deleteAllTabs()  		removeChild( tuple->mButton );  		delete tuple->mButton; +        tuple->mButton = NULL;   		removeChild( tuple->mTabPanel );  // 		delete tuple->mTabPanel; +        tuple->mTabPanel = NULL;  	}  	// Actually delete the tuples themselves @@ -1484,9 +1488,8 @@ BOOL LLTabContainer::setTab(S32 which)  		{  			LLTabTuple* tuple = *iter;  			BOOL is_selected = ( tuple == selected_tuple ); -                          // Although the selected tab must be complete, we may have hollow LLTabTuple tucked in the list -            if (tuple->mButton) +            if (tuple && tuple->mButton)              {                  tuple->mButton->setUseEllipses(mUseTabEllipses);                  tuple->mButton->setHAlign(mFontHalign); @@ -1494,7 +1497,7 @@ BOOL LLTabContainer::setTab(S32 which)                  // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs                  tuple->mButton->setTabStop( is_selected );              } -            if (tuple->mTabPanel) +            if (tuple && tuple->mTabPanel)              {                  tuple->mTabPanel->setVisible( is_selected );                  //tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here. @@ -1525,7 +1528,7 @@ BOOL LLTabContainer::setTab(S32 which)  					else  					{  						S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size  + tabcntr_arrow_btn_size + 1); -						S32 running_tab_width = tuple->mButton->getRect().getWidth(); +						S32 running_tab_width = (tuple && tuple->mButton ? tuple->mButton->getRect().getWidth() : 0);  						S32 j = i - 1;  						S32 min_scroll_pos = i;  						if (running_tab_width < available_width_with_arrows) @@ -1533,7 +1536,7 @@ BOOL LLTabContainer::setTab(S32 which)  							while (j >= 0)  							{  								LLTabTuple* other_tuple = getTab(j); -								running_tab_width += other_tuple->mButton->getRect().getWidth(); +								running_tab_width += (other_tuple && other_tuple->mButton ? other_tuple->mButton->getRect().getWidth() : 0);  								if (running_tab_width > available_width_with_arrows)  								{  									break; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index ebc9ee244e..e70992129a 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -443,6 +443,7 @@ void LLTextBase::drawSelectionBackground()  			++rect_it)  		{  			LLRect selection_rect = *rect_it; +			selection_rect = *rect_it;  			selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);  			gl_rect_2d(selection_rect, selection_color);  		} @@ -520,8 +521,8 @@ void LLTextBase::drawCursor()  			LLRect screen_pos = calcScreenRect();  			LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_rect.mLeft), screen_pos.mBottom + llfloor(cursor_rect.mTop) ); -			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 );  		}  	} @@ -1917,7 +1918,6 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)  	registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url));  	registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));  	registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url)); -	registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));  	registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));  	registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));  	registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url)); @@ -3201,7 +3201,23 @@ S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin  	LLFontGL::EWordWrapStyle word_wrap_style = (line_offset == 0)   		? LLFontGL::WORD_BOUNDARY_IF_POSSIBLE   		: LLFontGL::ONLY_WORD_BOUNDARIES; -	S32 num_chars = mStyle->getFont()->maxDrawableChars(text.c_str() + segment_offset + mStart,  +	 +	 +	LLWString offsetString(text.c_str() + segment_offset + mStart); + +	if(getLength() < segment_offset + mStart) +	{ +		llerrs << "getLength() < segment_offset + mStart\t getLength()\t" << getLength() << "\tsegment_offset:\t"  +						<< segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << "\tmax_chars\t" << max_chars << llendl; +	} + +	if(offsetString.length() + 1 < max_chars) +	{ +		llerrs << "offsetString.length() + 1 < max_chars\t max_chars:\t" << max_chars << "\toffsetString.length():\t" << offsetString.length() +			<< getLength() << "\tsegment_offset:\t" << segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << llendl; +	} +	 +	S32 num_chars = mStyle->getFont()->maxDrawableChars(offsetString.c_str(),   												(F32)num_pixels,  												max_chars,   												word_wrap_style); @@ -3474,3 +3490,7 @@ F32	LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 select  	return 0.0;  } +void LLTextBase::setWordWrap(bool wrap) +{ +	mWordWrap = wrap; +} diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index ad566a36d3..20a73387b5 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -41,6 +41,7 @@  #include <boost/signals2.hpp> +class LLScrollContainer;  class LLContextMenu;  class LLUrlMatch; @@ -434,6 +435,9 @@ public:  	virtual void			appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo);  	boost::signals2::connection setURLClickedCallback(const commit_signal_t::slot_type& cb); +	void					setWordWrap(bool wrap); +	LLScrollContainer*		getScrollContainer() const { return mScroller; } +  protected:  	// helper structs  	struct compare_bottom; @@ -634,7 +638,7 @@ protected:  	// support widgets  	LLContextMenu*				mPopupMenu;  	LLView*						mDocumentView; -	class LLScrollContainer*	mScroller; +	LLScrollContainer*			mScroller;  	// transient state  	S32							mReflowIndex;		// index at which to start reflow.  S32_MAX indicates no reflow needed. diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index d5e08fa29b..834f213097 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -956,12 +956,18 @@ S32 LLTextEditor::insert(S32 pos, const LLWString &wstr, bool group_with_next_op  S32 LLTextEditor::remove(S32 pos, S32 length, bool group_with_next_op)  {  	S32 end_pos = getEditableIndex(pos + length, true); +	BOOL removedChar = FALSE;  	segment_vec_t segments_to_remove;  	// store text segments  	getSegmentsInRange(segments_to_remove, pos, pos + length, false); +	 +	if(pos <= end_pos) +	{ +		removedChar = execute( new TextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) ); +	} -	return execute( new TextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) ); +	return removedChar;  }  S32 LLTextEditor::overwriteChar(S32 pos, llwchar wc) @@ -2911,7 +2917,7 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)  S32 LLTextEditor::getPreeditFontSize() const  { -	return llround((F32)mFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]); +	return llround((F32)mFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);  }  BOOL LLTextEditor::isDirty() const diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 1c74395c66..3d9f5cbbc2 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -653,7 +653,6 @@ void LLToolBar::updateLayoutAsNeeded()  	S32 max_row_length = 0;  	S32 max_length; -	S32 max_total_girth;  	S32 cur_start;  	S32 cur_row ;  	S32 row_pad_start; @@ -664,7 +663,6 @@ void LLToolBar::updateLayoutAsNeeded()  	if (orientation == LLLayoutStack::HORIZONTAL)  	{  		max_length = getRect().getWidth() - mPadLeft - mPadRight; -		max_total_girth = getRect().getHeight() - mPadTop - mPadBottom;  		row_pad_start = mPadLeft;  		row_pad_end = mPadRight;  		cur_row = mPadTop; @@ -673,7 +671,6 @@ void LLToolBar::updateLayoutAsNeeded()  	else // VERTICAL  	{  		max_length = getRect().getHeight() - mPadTop - mPadBottom; -		max_total_girth = getRect().getWidth() - mPadLeft - mPadRight;  		row_pad_start = mPadTop;  		row_pad_end = mPadBottom;  		cur_row = mPadLeft; @@ -841,7 +838,6 @@ void LLToolBar::draw()  	if (mDragAndDropTarget && !mButtonCommands.empty())  	{  		LLRect caret_rect = caret->getRect(); -		LLRect toolbar_rect = getRect();  		if (getOrientation(mSideType) == LLLayoutStack::HORIZONTAL)  		{  			caret->setRect(LLRect(mDragx-caret_rect.getWidth()/2+1, diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 2a774d54a3..0ddb149738 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -39,6 +39,7 @@  #include "llrect.h"  #include "lldir.h"  #include "llgl.h" +#include "llsd.h"  // Project includes  #include "llcommandmanager.h" @@ -69,16 +70,13 @@  //  // Globals  // -const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);  // Language for UI construction  std::map<std::string, std::string> gTranslation;  std::list<std::string> gUntranslated;  /*static*/ LLUI::settings_map_t LLUI::sSettingGroups; -/*static*/ LLImageProviderInterface* LLUI::sImageProvider = NULL;  /*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;  /*static*/ LLUIAudioCallback LLUI::sDeferredAudioCallback = NULL; -/*static*/ LLVector2		LLUI::sGLScaleFactor(1.f, 1.f);  /*static*/ LLWindow*		LLUI::sWindow = NULL;  /*static*/ LLView*			LLUI::sRootView = NULL;  /*static*/ BOOL                         LLUI::sDirty = FALSE; @@ -158,1474 +156,6 @@ void make_ui_sound_deferred(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.pushUIMatrix(); -	left += LLFontGL::sCurOrigin.mX; -	right += LLFontGL::sCurOrigin.mX; -	bottom += LLFontGL::sCurOrigin.mY; -	top += LLFontGL::sCurOrigin.mY; - -	gGL.loadUIIdentity(); -	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.popUIMatrix(); -} - - -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 = gGL.getUIScale(); -	const LLVector3 ui_translation = (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]; -	LLVector3 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] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); -		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); -		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); -		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); -		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); -		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); -		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom); -		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); -		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); -		pos[index] = LLVector3(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] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); -		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); -		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); -		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); -		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); -		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); -		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); -		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); -		index++; - -		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); -		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); -		pos[index] = LLVector3(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] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); -		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); -		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop); -		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); -		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); -		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); -		pos[index] = LLVector3(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] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); -		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop); -		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f); -		index++; - -		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); -		pos[index] = LLVector3(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]; -		LLVector3 pos[NUM_VERTICES]; - -		gGL.begin(LLRender::QUADS); -		{ -			LLVector3 ui_scale = gGL.getUIScale(); -			LLVector3 ui_translation = 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] = LLVector3(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] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f); -			index++; - -			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); -			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f); -			index++; - -			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); -			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f); -			index++; - -			gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); -		} -		gGL.end(); -	} -	else -	{ -		gGL.pushUIMatrix(); -		gGL.translateUI((F32)x, (F32)y, 0.f); -	 -		F32 offset_x = F32(width/2); -		F32 offset_y = F32(height/2); - -		gGL.translateUI(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.popUIMatrix(); -	} -} - - -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.pushUIMatrix(); -	{ -		gGL.translateUI(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.popUIMatrix(); -} - -void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled) -{ -	gGL.pushUIMatrix(); -	{ -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -		gGL.translateUI(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.popUIMatrix(); -} - -// 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.pushUIMatrix(); -	{ -		gGL.translateUI(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.translateUI(0.f, 0.f, width); -			gl_washer_2d(radius - width, radius, steps, side_color, side_color); -		} -	} -	gGL.popUIMatrix(); -} - -// Draw gray and white checkerboard with black border -void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha) -{ -	if (!LLGLSLShader::sNoFixedFunction) -	{  -	// Initialize the first time this is called. -	const S32 PIXELS = 32; -	static GLubyte checkerboard[PIXELS * PIXELS]; -	static BOOL first = TRUE; -	if( first ) -	{ -		for( S32 i = 0; i < PIXELS; i++ ) -		{ -			for( S32 j = 0; j < PIXELS; j++ ) -			{ -				checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF; -			} -		} -		first = FALSE; -	} -	 -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - -	// ...white squares -	gGL.color4f( 1.f, 1.f, 1.f, alpha ); -	gl_rect_2d(rect); - -	// ...gray squares -	gGL.color4f( .7f, .7f, .7f, alpha ); -	gGL.flush(); - -		glPolygonStipple( checkerboard ); - -		LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE); -		gl_rect_2d(rect); -	} -	else -	{ //polygon stipple is deprecated, use "Checker" texture -		LLPointer<LLUIImage> img = LLUI::getUIImage("Checker"); -		gGL.getTexUnit(0)->bind(img->getImage()); -		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); -		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - -		LLColor4 color(1.f, 1.f, 1.f, alpha); -		LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f); - -		gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), -			img->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(); -} - -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.pushUIMatrix(); - -	gGL.translateUI((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.popUIMatrix(); -} - -//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.pushUIMatrix(); - -	gGL.translateUI((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.popUIMatrix(); -} - -void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,  -							 const LLVector3& width_vec, const LLVector3& height_vec) -{ -	gGL.begin(LLRender::QUADS); -	{ -		// draw bottom left -		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom); -		gGL.vertex3f(0.f, 0.f, 0.f); - -		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); - -		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV); - -		// draw bottom middle -		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); - -		// draw bottom right -		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV); - -		gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom); -		gGL.vertex3fv(width_vec.mV); - -		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom); -		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); - -		// draw left  -		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); - -		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV); - -		// draw middle -		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); - -		// draw right  -		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); - -		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom); -		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV); - -		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop); -		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); - -		// draw top left -		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV); - -		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop); -		gGL.vertex3fv((height_vec).mV); - -		// draw top middle -		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV); - -		// draw top right -		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); - -		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop); -		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV); - -		gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop); -		gGL.vertex3fv((width_vec + height_vec).mV); - -		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop); -		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV); -	} -	gGL.end(); - -} - -  void LLUI::initClass(const settings_map_t& settings,  					 LLImageProviderInterface* image_provider,  					 LLUIAudioCallback audio_callback, @@ -1633,6 +163,7 @@ void LLUI::initClass(const settings_map_t& settings,  					 const LLVector2* scale_factor,  					 const std::string& language)  { +	LLRender2D::initClass(image_provider,scale_factor);  	sSettingGroups = settings;  	if ((get_ptr_in_map(sSettingGroups, std::string("config")) == NULL) || @@ -1642,10 +173,8 @@ void LLUI::initClass(const settings_map_t& settings,  		llerrs << "Failure to initialize configuration groups" << llendl;  	} -	sImageProvider = image_provider;  	sAudioCallback = audio_callback;  	sDeferredAudioCallback = deferred_audio_callback; -	sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;  	sWindow = NULL; // set later in startup  	LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow"); @@ -1679,10 +208,7 @@ void LLUI::initClass(const settings_map_t& settings,  void LLUI::cleanupClass()  { -	if(sImageProvider) -	{ -	sImageProvider->cleanUp(); -} +	LLRender2D::cleanupClass();  }  void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups) @@ -1706,60 +232,12 @@ void LLUI::dirtyRect(LLRect rect)  	}		  } - -//static -void LLUI::translate(F32 x, F32 y, F32 z) -{ -	gGL.translateUI(x,y,z); -	LLFontGL::sCurOrigin.mX += (S32) x; -	LLFontGL::sCurOrigin.mY += (S32) y; -	LLFontGL::sCurDepth += z; -} - -//static -void LLUI::pushMatrix() -{ -	gGL.pushUIMatrix(); -	LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth)); -} - -//static -void LLUI::popMatrix() -{ -	gGL.popUIMatrix(); -	LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first; -	LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second; -	LLFontGL::sOriginStack.pop_back(); -} - -//static  -void LLUI::loadIdentity() -{ -	gGL.loadUIIdentity();  -	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]);  	LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert());  } @@ -1770,8 +248,8 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y)  	LLCoordWindow cursor_pos_window;  	getWindow()->getCursorPosition(&cursor_pos_window);  	LLCoordGL cursor_pos_gl(cursor_pos_window.convert()); -	*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  @@ -1885,21 +363,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 @@ -1916,27 +394,6 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen)  	glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom);  } -//static -LLPointer<LLUIImage> LLUI::getUIImageByID(const LLUUID& image_id, S32 priority) -{ -	if (sImageProvider) -	{ -		return sImageProvider->getUIImageByID(image_id, priority); -	} -	else -	{ -		return NULL; -	} -} - -//static  -LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name, S32 priority) -{ -	if (!name.empty() && sImageProvider) -		return sImageProvider->getUIImage(name, priority); -	else -		return NULL; -}  LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)  { diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 4c1703392a..0a0e0e164e 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -1,6 +1,6 @@  /**    * @file llui.h - * @brief GL function declarations and other general static UI services. + * @brief General static UI services.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code @@ -24,122 +24,38 @@   * $/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 "v2math.h"  #include "llinitparam.h"  #include "llregistry.h" +#include "llrender2dutils.h" +#include "llpointer.h"  #include "lluicolor.h"  #include "lluicolortable.h" +#include "lluiimage.h"  #include <boost/signals2.hpp>  #include "lllazyvalue.h"  #include "llframetimer.h"  #include <limits> -// LLUIFactory -#include "llsd.h" -  // for initparam specialization  #include "llfontgl.h" -class LLColor4;  -class LLVector3; -class LLVector2; -class LLUIImage;  class LLUUID;  class LLWindow;  class LLView;  class LLHelp; -// UI colors -extern const LLColor4 UI_VERTEX_COLOR;  void make_ui_sound(const char* name);  void make_ui_sound_deferred(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& 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_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 LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, 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;  typedef	void (*LLUIAudioCallback)(const LLUUID& uuid); @@ -281,10 +197,10 @@ public:  	static void cleanupClass();  	static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& ); -	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); }  	static LLRect	sDirtyRect;  	static BOOL		sDirty; @@ -329,10 +245,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<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0); -	static LLPointer<LLUIImage> 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<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0) +		{ return LLRender2D::getUIImageByID(image_id, priority); } +	static LLPointer<LLUIImage> 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); @@ -362,12 +281,10 @@ public:  	static settings_map_t sSettingGroups;  	static LLUIAudioCallback sAudioCallback;  	static LLUIAudioCallback sDeferredAudioCallback; -	static LLVector2		sGLScaleFactor;  	static LLWindow*		sWindow;  	static LLView*			sRootView;  	static LLHelp*			sHelpImpl;  private: -	static LLImageProviderInterface* sImageProvider;  	static std::vector<std::string> sXUIPaths;  	static LLFrameTimer		sMouseIdleTimer;  	static add_popup_t		sAddPopupFunc; @@ -378,18 +295,6 @@ private:  // Moved LLLocalClipRect to lllocalcliprect.h -//RN: maybe this needs to moved elsewhere? -class LLImageProviderInterface -{ -protected: -	LLImageProviderInterface() {}; -	virtual ~LLImageProviderInterface() {}; -public: -	virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0; -	virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0; -	virtual void cleanUp() = 0; -}; -  class LLCallbackRegistry  {  public: @@ -438,10 +343,11 @@ public:  	// this avoids a MSVC bug where non-referenced static members are "optimized" away  	// even if their constructors have side effects -	void reference() +	S32 reference()  	{  		S32 dummy;  		dummy = 0; +		return dummy;  	}  }; @@ -600,7 +506,4 @@ namespace LLInitParam  	};  } -extern LLGLSLShader gSolidColorProgram; -extern LLGLSLShader gUIProgram; -  #endif diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 8f0a48018f..c3f0e92cb0 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -31,7 +31,7 @@  #include "llurlentry_stub.cpp"  #include "lltut.h"  #include "../lluicolortable.h" -#include "../lluiimage.h" +#include "../llrender/lluiimage.h"  #include <boost/regex.hpp> diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index 109d3ca7bb..55c1efefef 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -28,7 +28,7 @@  #include "linden_common.h"  #include "../llurlmatch.h" -#include "../lluiimage.h" +#include "../llrender/lluiimage.h"  #include "lltut.h"  // link seams diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt index 3c68b279f7..67dce8c073 100644 --- a/indra/llvfs/CMakeLists.txt +++ b/indra/llvfs/CMakeLists.txt @@ -8,6 +8,7 @@ include(UnixInstall)  include_directories(      ${LLCOMMON_INCLUDE_DIRS} +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}      )  set(llvfs_SOURCE_FILES @@ -44,12 +45,12 @@ if (LINUX)    LIST(APPEND llvfs_SOURCE_FILES lldir_linux.cpp)    LIST(APPEND llvfs_HEADER_FILES lldir_linux.h) -  if (VIEWER AND INSTALL) +  if (INSTALL)      set_source_files_properties(lldir_linux.cpp                                  PROPERTIES COMPILE_FLAGS                                  "-DAPP_RO_DATA_DIR=\\\"${APP_SHARE_DIR}\\\""                                  ) -  endif (VIEWER AND INSTALL) +  endif (INSTALL)  endif (LINUX)  if (WINDOWS) @@ -70,6 +71,7 @@ set(vfs_BOOST_LIBRARIES      )  target_link_libraries(llvfs +    ${LLCOMMON_LIBRARIES}      ${vfs_BOOST_LIBRARIES}      ) diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp index ca749c5eaf..03d2cc25e3 100644 --- a/indra/llvfs/llvfile.cpp +++ b/indra/llvfs/llvfile.cpp @@ -32,6 +32,7 @@  #include "llthread.h"  #include "llstat.h"  #include "llvfs.h" +#include "llmemory.h"  const S32 LLVFile::READ			= 0x00000001;  const S32 LLVFile::WRITE		= 0x00000002; @@ -134,13 +135,13 @@ U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S  		data = NULL;  	}  	else -	{ -		data = new U8[file_size]; +	{		 +		data = (U8*) ll_aligned_malloc_16(file_size);  		file.read(data, file_size);	/* Flawfinder: ignore */   		if (file.getLastBytesRead() != (S32)file_size)  		{ -			delete[] data; +			ll_aligned_free(data);  			data = NULL;  			file_size = 0;  		} diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 341bddfffd..ad010164eb 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -32,12 +32,17 @@ include_directories(      ${LLXML_INCLUDE_DIRS}      ${DIRECTX_INCLUDE_DIR}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(llwindow_SOURCE_FILES      llkeyboard.cpp      llkeyboardheadless.cpp      llwindowheadless.cpp      llwindowcallbacks.cpp +    llwindow.cpp      )  set(llwindow_HEADER_FILES @@ -50,7 +55,6 @@ set(llwindow_HEADER_FILES      )  set(viewer_SOURCE_FILES -    llwindow.cpp      llmousehandler.cpp      ) @@ -62,13 +66,43 @@ set(viewer_HEADER_FILES  # Libraries on which this library depends, needed for Linux builds  # Sort by high-level to low-level -if (LINUX AND VIEWER) +if (LINUX)    set(llwindow_LINK_LIBRARIES +      ${LLCOMMON_LIBRARIES} +      ${LLIMAGE_LIBRARIES} +      ${LLMATH_LIBRARIES} +      ${LLRENDER_LIBRARIES} +      ${LLVFS_LIBRARIES} +      ${LLWINDOW_LIBRARIES} +      ${LLXML_LIBRARIES}        ${UI_LIBRARIES}     # for GTK        ${SDL_LIBRARY}        fontconfig          # For FCInit and other FC* functions.        ) -endif (LINUX AND VIEWER) + +  list(APPEND viewer_SOURCE_FILES  +       llkeyboardsdl.cpp  +       llwindowsdl.cpp +       ) +  list(APPEND viewer_HEADER_FILES +       llkeyboardsdl.h +       llwindowsdl.h +       ) + +  if (BUILD_HEADLESS) +    set(llwindowheadless_LINK_LIBRARIES +        ${LLCOMMON_LIBRARIES} +        ${LLIMAGE_LIBRARIES} +        ${LLMATH_LIBRARIES} +        ${LLRENDER_HEADLESS_LIBRARIES} +        ${LLVFS_LIBRARIES} +        ${LLWINDOW_HEADLESS_LIBRARIES} +        ${LLXML_LIBRARIES} +        fontconfig          # For FCInit and other FC* functions. +        ) +  endif (BUILD_HEADLESS) + +endif (LINUX)  if (DARWIN)    list(APPEND llwindow_SOURCE_FILES @@ -91,16 +125,6 @@ if (DARWIN)        )  endif (DARWIN) -if (LINUX AND VIEWER) -  list(APPEND viewer_SOURCE_FILES  -       llkeyboardsdl.cpp  -       llwindowsdl.cpp -       ) -  list(APPEND viewer_HEADER_FILES -       llkeyboardsdl.h -       llwindowsdl.h -       ) -endif (LINUX AND VIEWER)  if (WINDOWS)    list(APPEND llwindow_SOURCE_FILES @@ -133,40 +157,41 @@ endif (SOLARIS)  set_source_files_properties(${llwindow_HEADER_FILES}                              PROPERTIES HEADER_FILE_ONLY TRUE) -if (SERVER AND NOT WINDOWS AND NOT DARWIN) -  set(server_SOURCE_FILES +if (BUILD_HEADLESS) +  set(llwindowheadless_SOURCE_FILES         llwindowmesaheadless.cpp +       llmousehandler.cpp         ) -  set(server_HEADER_FILES +  set(llwindowheadless_HEADER_FILES         llwindowmesaheadless.h +       llmousehandler.h         ) -  copy_server_sources( -      llwindow -      ) - - -  set_source_files_properties( -    ${server_SOURCE_FILES} -    PROPERTIES -    COMPILE_FLAGS "-DLL_MESA=1 -DLL_MESA_HEADLESS=1" -    )    add_library (llwindowheadless      ${llwindow_SOURCE_FILES} -    ${server_SOURCE_FILES} +    ${llwindowheadless_SOURCE_FILES}      ) -  target_link_libraries (llwindowheadless ${llwindow_LINK_LIBRARIES}) -endif (SERVER AND NOT WINDOWS AND NOT DARWIN) +  set_property(TARGET llwindowheadless +    PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 +    ) +  target_link_libraries (llwindowheadless ${llwindowheadless_LINK_LIBRARIES} dl) +endif (BUILD_HEADLESS)  if (llwindow_HEADER_FILES)    list(APPEND llwindow_SOURCE_FILES ${llwindow_HEADER_FILES})  endif (llwindow_HEADER_FILES) -  list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) -if (VIEWER) -  add_library (llwindow -    ${llwindow_SOURCE_FILES} -    ${viewer_SOURCE_FILES} +list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) + +add_library (llwindow +  ${llwindow_SOURCE_FILES} +  ${viewer_SOURCE_FILES} +  ) + +if (SDL_FOUND) +  set_property(TARGET llwindow +    PROPERTY COMPILE_DEFINITIONS LL_SDL=1      ) -  target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) -endif (VIEWER) +endif (SDL_FOUND) + +target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) diff --git a/indra/llwindow/GL/glh_extensions.h b/indra/llwindow/GL/glh_extensions.h index d89d85930b..554cb1731f 100644 --- a/indra/llwindow/GL/glh_extensions.h +++ b/indra/llwindow/GL/glh_extensions.h @@ -113,7 +113,7 @@ static const char* EatNonWhiteSpace(const char *str)  int glh_init_extensions(const char *origReqExts)  {  	// Length of requested extensions string -	unsigned reqExtsLen; +	//unsigned reqExtsLen;  	char *reqExts;  	// Ptr for individual extensions within reqExts  	char *reqExt; @@ -155,8 +155,8 @@ int glh_init_extensions(const char *origReqExts)  		return TRUE;  	}  	reqExts = strdup(origReqExts); -	reqExtsLen = (S32)strlen(reqExts);  	/* +	reqExtsLen = (S32)strlen(reqExts);  	if (NULL == gGLHExts.mUnsupportedExts)  	{  		gGLHExts.mUnsupportedExts = (char*)malloc(reqExtsLen + 1); diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index a15114cb9b..205466e936 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -1636,35 +1636,53 @@ void check_vm_bloat()  {  #if LL_LINUX  	// watch our own VM and RSS sizes, warn if we bloated rapidly -	FILE *fp = fopen("/proc/self/stat", "r"); +	static const std::string STATS_FILE = "/proc/self/stat"; +	FILE *fp = fopen(STATS_FILE.c_str(), "r");  	if (fp)  	{  		static long long last_vm_size = 0;  		static long long last_rss_size = 0;  		const long long significant_vm_difference = 250 * 1024*1024;  		const long long significant_rss_difference = 50 * 1024*1024; +		long long this_vm_size = 0; +		long long this_rss_size = 0;  		ssize_t res;  		size_t dummy; -		char *ptr; +		char *ptr = NULL;  		for (int i=0; i<22; ++i) // parse past the values we don't want  		{ -			ptr = NULL;  			res = getdelim(&ptr, &dummy, ' ', fp); +			if (-1 == res) +			{ +				llwarns << "Unable to parse " << STATS_FILE << llendl; +				goto finally; +			}  			free(ptr); +			ptr = NULL;  		}  		// 23rd space-delimited entry is vsize -		ptr = NULL;  		res = getdelim(&ptr, &dummy, ' ', fp);  		llassert(ptr); -		long long this_vm_size = atoll(ptr); +		if (-1 == res) +		{ +			llwarns << "Unable to parse " << STATS_FILE << llendl; +			goto finally; +		} +		this_vm_size = atoll(ptr);  		free(ptr); -		// 24th space-delimited entry is RSS  		ptr = NULL; +		// 24th space-delimited entry is RSS  		res = getdelim(&ptr, &dummy, ' ', fp);  		llassert(ptr); -		long long this_rss_size = getpagesize() * atoll(ptr); +		if (-1 == res) +		{ +			llwarns << "Unable to parse " << STATS_FILE << llendl; +			goto finally; +		} +		this_rss_size = getpagesize() * atoll(ptr);  		free(ptr); +		ptr = NULL;  		llinfos << "VM SIZE IS NOW " << (this_vm_size/(1024*1024)) << " MB, RSS SIZE IS NOW " << (this_rss_size/(1024*1024)) << " MB" << llendl; @@ -1697,6 +1715,12 @@ void check_vm_bloat()  		last_rss_size = this_rss_size;  		last_vm_size = this_vm_size; +finally: +		if (NULL != ptr) +		{ +			free(ptr); +			ptr = NULL; +		}  		fclose(fp);  	}  #endif // LL_LINUX diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt index beefcda361..cf96f26a77 100644 --- a/indra/llxml/CMakeLists.txt +++ b/indra/llxml/CMakeLists.txt @@ -13,6 +13,9 @@ include_directories(      ${LLMATH_INCLUDE_DIRS}      ${LLVFS_INCLUDE_DIRS}      ) +include_directories( +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  set(llxml_SOURCE_FILES      llcontrol.cpp @@ -39,9 +42,10 @@ list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES})  add_library (llxml ${llxml_SOURCE_FILES})  # Libraries on which this library depends, needed for Linux builds  # Sort by high-level to low-level -target_link_libraries( llxml -    llvfs -    llmath +target_link_libraries(llxml +    ${LLVFS_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${LLCOMMON_LIBRARIES}      ${EXPAT_LIBRARIES}      ) diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 53d9380f4f..666c03e9ff 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -850,12 +850,10 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v  		return 0;  	} -	S32 ret = LLSDSerialize::fromXML(settings, infile); - -	if (ret <= 0) +	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile))  	{  		infile.close(); -		llwarns << "Unable to open LLSD control file " << filename << ". Trying Legacy Method." << llendl;		 +		llwarns << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << llendl;  		return loadFromFileLegacy(filename, TRUE, TYPE_STRING);  	} diff --git a/indra/lscript/lscript_compile/CMakeLists.txt b/indra/lscript/lscript_compile/CMakeLists.txt index 3ed2892e0e..07662005b9 100644 --- a/indra/lscript/lscript_compile/CMakeLists.txt +++ b/indra/lscript/lscript_compile/CMakeLists.txt @@ -45,6 +45,9 @@ include_directories(      ${LLPRIMITIVE_INCLUDE_DIRS}      ${LSCRIPT_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  set(lscript_generated_SOURCE_FILES      indra.l.cpp @@ -95,6 +98,7 @@ add_custom_command(        ${CMAKE_CURRENT_BINARY_DIR}/indra.l.cpp      COMMAND ${FLEX}      ARGS +      -P indra_        -o${CMAKE_CURRENT_BINARY_DIR}/indra.l.cpp        ${CMAKE_CURRENT_SOURCE_DIR}/indra.l      DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/indra.l @@ -112,8 +116,10 @@ if (WINDOWS)          ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp          ${CMAKE_CURRENT_BINARY_DIR}/indra.y.hpp        COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bison.bat +      ARGS          ${BISON} ${M4_PATH} -        ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp +        -p indra_ +        -d -o ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp          ${CMAKE_CURRENT_SOURCE_DIR}/indra.y        DEPENDS          ${CMAKE_CURRENT_SOURCE_DIR}/bison.bat @@ -128,6 +134,7 @@ else (WINDOWS)        COMMAND          ${BISON}        ARGS +        -p indra_          -d -o ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp          ${CMAKE_CURRENT_SOURCE_DIR}/indra.y        DEPENDS diff --git a/indra/lscript/lscript_compile/bison.bat b/indra/lscript/lscript_compile/bison.bat index 0baff4e5ef..d40997225e 100644 --- a/indra/lscript/lscript_compile/bison.bat +++ b/indra/lscript/lscript_compile/bison.bat @@ -2,10 +2,11 @@  @REM find m4, even if neither program is present in PATH.
  @set bison=%1
 -set M4PATH=%2
 +shift
 +set M4PATH=%1
 +shift
  set M4=
 -@set output=%3
 -@set input=%4
  set PATH=%M4PATH%;%PATH%
 -%bison% -d -o %output% %input%
 +@REM %* does not work with shift...
 +%bison% %1 %2 %3 %4 %5 %6 %7 %8 %9
 diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l index 307a5561a0..71da95b8f5 100644 --- a/indra/lscript/lscript_compile/indra.l +++ b/indra/lscript/lscript_compile/indra.l @@ -56,6 +56,29 @@ void parse_string();  #define ECHO do { } while (0) +#define yyparse indra_parse +#define yyerror indra_error +#define yylval indra_lval +#define yy_create_buffer indra__create_buffer +#define yy_delete_buffer indra__delete_buffer +#define yy_flex_debug indra__flex_debug +#define yy_init_buffer indra__init_buffer +#define yy_flush_buffer indra__flush_buffer +#define yy_load_buffer_state indra__load_buffer_state +#define yy_switch_to_buffer indra__switch_to_buffer +#define yyin indra_in +#define yyleng indra_leng +#define yylex indra_lex +#define yylineno indra_lineno +#define yyout indra_out +#define yyrestart indra_restart +#define yytext indra_text +#define yywrap indra_wrap +#define yyalloc indra_alloc +#define yyrealloc indra_realloc +#define yyfree indra_free + +  #if defined(__cplusplus)  extern "C" { int yylex( void ); }  extern "C" { int yyparse( void ); } diff --git a/indra/lscript/lscript_execute/CMakeLists.txt b/indra/lscript/lscript_execute/CMakeLists.txt index 3a16ffdc01..49605982a8 100644 --- a/indra/lscript/lscript_execute/CMakeLists.txt +++ b/indra/lscript/lscript_execute/CMakeLists.txt @@ -10,6 +10,9 @@ include_directories(      ${LLMATH_INCLUDE_DIRS}      ${LSCRIPT_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  set(lscript_execute_SOURCE_FILES      llscriptresource.cpp diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp index d79e9f8bde..b12d2e4a16 100644 --- a/indra/lscript/lscript_execute/lscript_execute.cpp +++ b/indra/lscript/lscript_execute/lscript_execute.cpp @@ -806,16 +806,7 @@ void LLScriptExecute::runInstructions(BOOL b_print, const LLUUID &id,  	//  is there a fault?  	//	if yes, print out message and exit  	S32 value = getVersion(); -	S32 major_version = 0; -	if (value == LSL2_VERSION1_END_NUMBER) -	{ -		major_version = 1; -	} -	else if (value == LSL2_VERSION_NUMBER) -	{ -		major_version = 2; -	} -	else +	if ( (value != LSL2_VERSION1_END_NUMBER) && (value != LSL2_VERSION_NUMBER) )  	{  		setFault(LSRF_VERSION_MISMATCH);  	} diff --git a/indra/lscript/lscript_execute/lscript_readlso.cpp b/indra/lscript/lscript_execute/lscript_readlso.cpp index 35caa41ae1..8b41cb5a72 100644 --- a/indra/lscript/lscript_execute/lscript_readlso.cpp +++ b/indra/lscript/lscript_execute/lscript_readlso.cpp @@ -123,7 +123,7 @@ void LLScriptLSOParse::printRegisters(LLFILE *fp)  void LLScriptLSOParse::printGlobals(LLFILE *fp)  {  	// print out registers first -	S32				offset, varoffset; +	S32				varoffset;  	S32				ivalue;  	F32				fpvalue;  	LLVector3		vvalue; @@ -144,7 +144,7 @@ void LLScriptLSOParse::printGlobals(LLFILE *fp)  		// get offset to skip past name  		varoffset = global_v_offset; -		offset = bytestream2integer(mRawData, global_v_offset); +		bytestream2integer(mRawData, global_v_offset);  		// get typeexport  		type = *(mRawData + global_v_offset++); @@ -262,8 +262,6 @@ void LLScriptLSOParse::printGlobalFunctions(LLFILE *fp)  		fprintf(fp, "[Function #%d] [0x%X] %s\n", function_number, orig_function_offset, name);  		fprintf(fp, "\tReturn Type: %s\n", LSCRIPTTypeNames[type]);  		type = *(mRawData + function_offset++); -		S32 params; -		params = 0;  		S32 pcount = 0;  		while (type)  		{ @@ -347,7 +345,6 @@ void LLScriptLSOParse::printStates(LLFILE *fp)  				read_ahead = event_jump_table;  				S32 temp_end; -				S32 dummy;  				opcode_end = worst_case_opcode_end; @@ -356,7 +353,7 @@ void LLScriptLSOParse::printStates(LLFILE *fp)  					if (event_handlers & LSCRIPTStateBitField[k])  					{  						temp_end = bytestream2integer(mRawData, read_ahead); -						dummy = bytestream2integer(mRawData, read_ahead); +						bytestream2integer(mRawData, read_ahead);  						if (  (temp_end < opcode_end)  							&&(temp_end > event_offset))  						{ diff --git a/indra/lscript/lscript_library/CMakeLists.txt b/indra/lscript/lscript_library/CMakeLists.txt index f6bc67a994..5af850c41b 100644 --- a/indra/lscript/lscript_library/CMakeLists.txt +++ b/indra/lscript/lscript_library/CMakeLists.txt @@ -28,5 +28,8 @@ include_directories(      ${LLMATH_INCLUDE_DIRS}      ${LSCRIPT_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  add_library (lscript_library ${lscript_library_SOURCE_FILES}) diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt index 3906a3bb8c..c59645bd70 100644 --- a/indra/mac_crash_logger/CMakeLists.txt +++ b/indra/mac_crash_logger/CMakeLists.txt @@ -19,6 +19,10 @@ include_directories(      ${LLVFS_INCLUDE_DIRS}      ${LLXML_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(mac_crash_logger_SOURCE_FILES      mac_crash_logger.cpp diff --git a/indra/mac_updater/CMakeLists.txt b/indra/mac_updater/CMakeLists.txt index 00dcedecaa..a644984e58 100644 --- a/indra/mac_updater/CMakeLists.txt +++ b/indra/mac_updater/CMakeLists.txt @@ -7,6 +7,7 @@ include(OpenSSL)  include(CURL)  include(CARes)  include(LLCommon) +include(LLMessage)  include(LLVFS)  include(Linking) @@ -52,6 +53,7 @@ set_target_properties(mac-updater    )  target_link_libraries(mac-updater +    ${LLMESSAGE_LIBRARIES}      ${LLVFS_LIBRARIES}      ${OPENSSL_LIBRARIES}      ${CRYPTO_LIBRARIES} diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt index 3ad94b0c64..7367b9e5e6 100644 --- a/indra/media_plugins/base/CMakeLists.txt +++ b/indra/media_plugins/base/CMakeLists.txt @@ -11,7 +11,7 @@ include(LLRender)  include(LLWindow)  include(Linking)  include(PluginAPI) -include(FindOpenGL) +include(OpenGL)  include_directories(      ${LLPLUGIN_INCLUDE_DIRS} @@ -21,6 +21,9 @@ include_directories(      ${LLRENDER_INCLUDE_DIRS}      ${LLWINDOW_INCLUDE_DIRS}  ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  ### media_plugin_base diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt index 54dc5de1ea..171645ef04 100644 --- a/indra/media_plugins/example/CMakeLists.txt +++ b/indra/media_plugins/example/CMakeLists.txt @@ -12,7 +12,7 @@ include(LLWindow)  include(Linking)  include(PluginAPI)  include(MediaPluginBase) -include(FindOpenGL) +include(OpenGL)  include(ExamplePlugin) @@ -25,6 +25,9 @@ include_directories(      ${LLRENDER_INCLUDE_DIRS}      ${LLWINDOW_INCLUDE_DIRS}  ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  ### media_plugin_example diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt index 5786bd1e25..447f6e0689 100644 --- a/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -12,7 +12,7 @@ include(LLWindow)  include(Linking)  include(PluginAPI)  include(MediaPluginBase) -include(FindOpenGL) +include(OpenGL)  include(GStreamer010Plugin) @@ -27,6 +27,9 @@ include_directories(      ${GSTREAMER010_INCLUDE_DIRS}      ${GSTREAMER010_PLUGINS_BASE_INCLUDE_DIRS}  ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  ### media_plugin_gstreamer010 diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp index cdb7f4faeb..932aaffa1b 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp @@ -278,10 +278,9 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps)  static gboolean  gst_slvideo_start (GstBaseSink * bsink)  { -	GstSLVideo *slvideo;  	gboolean ret = TRUE; -	slvideo = GST_SLVIDEO(bsink); +	GST_SLVIDEO(bsink);  	return ret;  } diff --git a/indra/media_plugins/quicktime/CMakeLists.txt b/indra/media_plugins/quicktime/CMakeLists.txt index f0b8f0d167..58391007ff 100644 --- a/indra/media_plugins/quicktime/CMakeLists.txt +++ b/indra/media_plugins/quicktime/CMakeLists.txt @@ -12,7 +12,7 @@ include(LLWindow)  include(Linking)  include(PluginAPI)  include(MediaPluginBase) -include(FindOpenGL) +include(OpenGL)  include(QuickTimePlugin)  include_directories( @@ -24,6 +24,9 @@ include_directories(      ${LLRENDER_INCLUDE_DIRS}      ${LLWINDOW_INCLUDE_DIRS}  ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  if (DARWIN)      include(CMakeFindFrameworks) diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt index b36291f0e8..0c1c3d800e 100644 --- a/indra/media_plugins/webkit/CMakeLists.txt +++ b/indra/media_plugins/webkit/CMakeLists.txt @@ -13,7 +13,7 @@ include(UI)  include(Linking)  include(PluginAPI)  include(MediaPluginBase) -include(FindOpenGL) +include(OpenGL)  include(PulseAudio)  include(WebKitLibPlugin) @@ -29,6 +29,9 @@ include_directories(      ${LLWINDOW_INCLUDE_DIRS}      ${LLQTWEBKIT_INCLUDE_DIR}  ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  ### media_plugin_webkit diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index bd0169fb2f..4f7ce88165 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -12,7 +12,7 @@ include(DragDrop)  include(EXPAT)  include(FMOD)  include(OPENAL) -include(FindOpenGL) +include(OpenGL)  include(Hunspell)  include(JsonCpp)  include(LLAudio) @@ -46,6 +46,7 @@ include(LLLogin)  include(VisualLeakDetector)  include(GLOD)  include(CMakeCopyIfDifferent) +include(LLAppearance)  if (NOT HAVOK_TPV)     # When using HAVOK_TPV, the library is precompiled, so no need for this @@ -67,7 +68,6 @@ include_directories(      ${LLINVENTORY_INCLUDE_DIRS}      ${LLMATH_INCLUDE_DIRS}      ${LLMESSAGE_INCLUDE_DIRS} -    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}      ${LLPLUGIN_INCLUDE_DIRS}      ${LLPRIMITIVE_INCLUDE_DIRS}      ${LLRENDER_INCLUDE_DIRS} @@ -83,6 +83,13 @@ include_directories(      ${LIBS_PREBUILD_DIR}/include/hunspell      ${OPENAL_LIB_INCLUDE_DIRS}      ${LIBS_PREBUILT_DIR}/include/collada/1.4 +    ${LLAPPEARANCE_INCLUDE_DIRS} +    ) + +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}      )  set(viewer_SOURCE_FILES @@ -169,7 +176,6 @@ set(viewer_SOURCE_FILES      lldrawpooltree.cpp      lldrawpoolwater.cpp      lldrawpoolwlsky.cpp -    lldriverparam.cpp      lldynamictexture.cpp      llemote.cpp      llenvmanager.cpp @@ -334,7 +340,6 @@ set(viewer_SOURCE_FILES      lllistcontextmenu.cpp      lllistview.cpp      lllocalbitmaps.cpp -    lllocaltextureobject.cpp      lllocationhistory.cpp      lllocationinputctrl.cpp      lllogchat.cpp @@ -454,12 +459,11 @@ set(viewer_SOURCE_FILES      llpersistentnotificationstorage.cpp      llphysicsmotion.cpp      llphysicsshapebuilderutil.cpp +    llpipelinelistener.cpp      llplacesinventorybridge.cpp      llplacesinventorypanel.cpp      llplacesfolderview.cpp      llpopupview.cpp -    llpolymesh.cpp -    llpolymorph.cpp      llpostcard.cpp      llpreview.cpp      llpreviewanim.cpp @@ -510,9 +514,6 @@ set(viewer_SOURCE_FILES      llsyswellwindow.cpp      llteleporthistory.cpp      llteleporthistorystorage.cpp -    lltexglobalcolor.cpp -    lltexlayer.cpp -    lltexlayerparams.cpp      lltextureatlas.cpp      lltextureatlasmanager.cpp      lltexturecache.cpp @@ -610,18 +611,18 @@ 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      llviewerwindowlistener.cpp      llvlcomposition.cpp      llvlmanager.cpp      llvoavatar.cpp -    llvoavatardefines.cpp      llvoavatarself.cpp      llvocache.cpp      llvograss.cpp @@ -642,10 +643,8 @@ set(viewer_SOURCE_FILES      llwatchdog.cpp      llwaterparammanager.cpp      llwaterparamset.cpp -    llwearable.cpp      llwearableitemslist.cpp      llwearablelist.cpp -    llwearabletype.cpp      llweb.cpp      llwebprofile.cpp      llwebsharing.cpp @@ -757,7 +756,6 @@ set(viewer_HEADER_FILES      lldrawpooltree.h      lldrawpoolwater.h      lldrawpoolwlsky.h -    lldriverparam.h      lldynamictexture.h      llemote.h      llenvmanager.h @@ -921,7 +919,6 @@ set(viewer_HEADER_FILES      lllistcontextmenu.h      lllistview.h      lllocalbitmaps.h -    lllocaltextureobject.h      lllocationhistory.h      lllocationinputctrl.h      lllogchat.h @@ -1030,11 +1027,10 @@ set(viewer_HEADER_FILES      llpersistentnotificationstorage.h      llphysicsmotion.h      llphysicsshapebuilderutil.h +    llpipelinelistener.h      llplacesinventorybridge.h      llplacesinventorypanel.h      llplacesfolderview.h -    llpolymesh.h -    llpolymorph.h      llpopupview.h      llpostcard.h      llpreview.h @@ -1088,9 +1084,6 @@ set(viewer_HEADER_FILES      lltable.h      llteleporthistory.h      llteleporthistorystorage.h -    lltexglobalcolor.h -    lltexlayer.h -    lltexlayerparams.h      lltextureatlas.h      lltextureatlasmanager.h      lltexturecache.h @@ -1189,18 +1182,18 @@ 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      llviewerwindowlistener.h      llvlcomposition.h      llvlmanager.h      llvoavatar.h -    llvoavatardefines.h      llvoavatarself.h      llvocache.h      llvograss.h @@ -1221,10 +1214,8 @@ set(viewer_HEADER_FILES      llwatchdog.h      llwaterparammanager.h      llwaterparamset.h -    llwearable.h      llwearableitemslist.h      llwearablelist.h -    llwearabletype.h      llweb.h      llwebprofile.h      llwebsharing.h @@ -1579,6 +1570,12 @@ add_executable(${VIEWER_BINARY_NAME}      ${viewer_SOURCE_FILES}      ) +if (SDL_FOUND) +  set_property(TARGET ${VIEWER_BINARY_NAME} +    PROPERTY COMPILE_DEFINITIONS LL_SDL=1 +    ) +endif (SDL_FOUND) +  # add package files  file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST       ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py) @@ -1864,19 +1861,9 @@ target_link_libraries(${VIEWER_BINARY_NAME}      ${LLPHYSICS_LIBRARIES}      ${LLPHYSICSEXTENSIONS_LIBRARIES}      ${TCMALLOC_LIBRARIES} +    ${LLAPPEARANCE_LIBRARIES}      ) -if (USE_KDU) -    target_link_libraries(${VIEWER_BINARY_NAME} -        ${LLKDU_LIBRARIES} -        ${KDU_LIBRARY} -        ) -else (USE_KDU) -    target_link_libraries(${VIEWER_BINARY_NAME} -        ${LLIMAGEJ2COJ_LIBRARIES} -        ) -endif (USE_KDU) -  build_version(viewer)  set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH @@ -2096,6 +2083,15 @@ if (LL_TESTS)    )    set_source_files_properties( +    llworldmap.cpp +    llworldmipmap.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_SOURCE_FILES  +    tests/llviewertexture_stub.cpp +    #llviewertexturelist.cpp +  ) + +  set_source_files_properties(      lltranslate.cpp      PROPERTIES      LL_TEST_ADDITIONAL_LIBRARIES "${JSONCPP_LIBRARIES}" diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 5c7cacedec..1802e14703 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -2,6 +2,6 @@  CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 2.1.0.13828"; -CFBundleGetInfoString = "Second Life version 2.1.0.13828, Copyright 2004-2009 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 3.4.1.264760"; +CFBundleGetInfoString = "Second Life version 3.4.1.264760, Copyright 2004-2009 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index f7b11b217c..035d6cbe6c 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -60,7 +60,7 @@  		</dict>  	</array>  	<key>CFBundleVersion</key> -	<string>2.1.0.13828</string> +	<string>3.4.1.264760</string>  	<key>CSResourcesFileMapped</key>  	<true/>  </dict> diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 92a241857e..92a241857e 100644..100755 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 89a8f74b0c..b291de0dbd 100644..100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2004,6 +2004,39 @@        <key>Value</key>        <string />      </map> +  <key>DebugAvatarAppearanceMessage</key> +  <map> +    <key>Comment</key> +    <string>Dump a bunch of XML files when handling appearance messages</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +  <key>DebugAvatarExperimentalServerAppearanceUpdate</key> +  <map> +    <key>Comment</key> +    <string>Experiment with sending full cof_contents instead of cof_version</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +    <key>DebugAvatarAppearanceServiceURLOverride</key> +    <map> +      <key>Comment</key> +      <string>URL to use for baked texture requests; overrides value returned by login server.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string /> +    </map>  	<key>DebugAvatarRezTime</key>  	<map>  		<key>Comment</key> @@ -2026,6 +2059,17 @@      <key>Value</key>      <integer>1</integer>    </map> +  <key>DebugAvatarCompositeBaked</key> +  <map> +    <key>Comment</key> +    <string>Colorize avatar meshes based on baked/composite state.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map>      <key>DebugBeaconLineWidth</key>      <map>        <key>Comment</key> @@ -2037,6 +2081,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>DebugForceAppearanceRequestFailure</key> +    <map> +      <key>Comment</key> +      <string>Request wrong cof version to test the failure path for server appearance update requests.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>DebugHideEmptySystemFolders</key>      <map>        <key>Comment</key> @@ -4381,6 +4436,28 @@        <key>Value</key>        <real>1.0</real>      </map> +    <key>InventoryDebugSimulateOpFailureRate</key> +    <map> +      <key>Comment</key> +        <string>Rate at which we simulate failures of copy/link requests in some operations</string> +      <key>Persist</key> +        <integer>1</integer> +      <key>Type</key> +        <string>F32</string> +      <key>Value</key> +        <real>0.0</real> +    </map> +    <key>InventoryDebugSimulateLateOpRate</key> +    <map> +      <key>Comment</key> +        <string>Rate at which we simulate late-completing copy/link requests in some operations</string> +      <key>Persist</key> +        <integer>1</integer> +      <key>Type</key> +        <string>F32</string> +      <key>Value</key> +        <real>0.0</real> +    </map>      <key>InventoryDisplayInbox</key>      <map>          <key>Comment</key> @@ -8915,6 +8992,28 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>DisableAllRenderTypes</key> +    <map> +      <key>Comment</key> +      <string>Disables all rendering types.</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>DisableAllRenderFeatures</key> +    <map> +      <key>Comment</key> +      <string>Disables all rendering features.</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>RenderHUDInSnapshot</key>      <map>        <key>Comment</key> @@ -13352,6 +13451,28 @@        <key>Value</key>        <integer>-1</integer>      </map> +    <key>MaxFPS</key> +    <map> +      <key>Comment</key> +      <string>Yield some time to the local host if we reach a threshold framerate.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <integer>-1.0</integer> +    </map> +    <key>ForcePeriodicRenderingTime</key> +    <map> +      <key>Comment</key> +      <string>Periodically enable all rendering masks for a single frame.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <integer>-1.0</integer> +    </map>      <key>ZoomDirect</key>      <map>        <key>Comment</key> @@ -14337,5 +14458,17 @@      <key>Value</key>      <integer>0</integer>    </map> + +  <key>DisablePrecacheDelayAfterTeleporting</key> +  <map> +    <key>Comment</key> +    <string>Disables the artificial delay in the viewer that precaches some incoming assets</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map>  </map>  </llsd> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index ada374f892..590f41283b 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -292,6 +292,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>NearbyChatIsNotCollapsed</key> +    <map> +      <key>Comment</key> +      <string>Saving expanded/collapsed state of the nearby chat between sessions</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>ShowFavoritesOnLogin</key>          <map>          <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl index 99a6fe85fe..9c82056fd7 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl @@ -31,7 +31,7 @@ out vec4 frag_color;  uniform float minimum_alpha; -vec4 diffuseLookup(vec2 texcoord); +/* vec4 diffuseLookup(vec2 texcoord); */  vec3 fullbrightAtmosTransport(vec3 light);  vec4 applyWaterFog(vec4 color); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl index df182168f3..d3dacf9bc4 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl @@ -32,7 +32,7 @@ out vec4 frag_color;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; -vec4 diffuseLookup(vec2 texcoord); +/* vec4 diffuseLookup(vec2 texcoord); */  vec3 fullbrightAtmosTransport(vec3 light);  vec4 applyWaterFog(vec4 color); diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 99dbfcae51..284e9c44b2 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -1084,6 +1084,23 @@           scale="0 0 .5" />        </param_skeleton>      </param> + +    <param +     id="11001" +     group="0" +     name="Hover" +     wearable="shape" +     edit_group="shape_body" +     edit_group_order="4" +     label_min="Lower" +     label_max="Higher" +     value_min="-2" +     value_max="2" +     value_default="0" +     camera_distance="2.5"> +      <param_skeleton /> +    </param> +    </skeleton>    <mesh @@ -12291,6 +12308,17 @@ render_pass="bump">  	 <param_driver />      </param> +    <param +     id="11000" +     group="0" +     name="AppearanceMessage_Version" +     label="AppearanceMessage Version" +     value_default="0" +     value_min="0" +     value_max="255"> +	 <param_driver /> +    </param> +    </driver_parameters>    <morph_masks> diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 20936c6460..1381e49c62 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -45,6 +45,7 @@ if [ "`uname -m`" = "x86_64" ]; then      echo '64-bit Linux detected.'  fi +  ## Everything below this line is just for advanced troubleshooters.  ##------------------------------------------------------------------- @@ -60,7 +61,15 @@ fi  export SDL_VIDEO_X11_DGAMOUSE=0  ## - Works around a problem with misconfigured 64-bit systems not finding GL -export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}":/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri +I386_MULTIARCH="$(dpkg-architecture -ai386 -qDEB_HOST_MULTIARCH 2>/dev/null)" +MULTIARCH_ERR=$? +if [ $MULTIARCH_ERR -eq 0 ]; then +    echo 'Multi-arch support detected.' +    MULTIARCH_GL_DRIVERS="/usr/lib/${I386_MULTIARCH}/dri" +    export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:${MULTIARCH_GL_DRIVERS}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri" +else +    export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri" +fi  ## - The 'scim' GTK IM module widely crashes the viewer.  Avoid it.  if [ "$GTK_IM_MODULE" = "scim" ]; then @@ -117,18 +126,32 @@ export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"  # Simply embedding $(<etc/gridargs.dat) into a command line treats each of  # Second, Life and Developer as separate args -- no good. We need bash to  # process quotes using eval. -# First read it without scanning, then scan that string. Break quoted words +# First, check if we have been instructed to skip reading in gridargs.dat: +skip_gridargs=false +argnum=0 +for ARG in "$@"; do +    if [ "--skip-gridargs" == "$ARG" ]; then +        skip_gridargs=true +    else +        ARGS[$argnum]="$ARG" +        argnum=$(($argnum+1)) +    fi +done + +# Second, read it without scanning, then scan that string. Break quoted words  # into a bash array. Note that if gridargs.dat is empty, or contains only  # whitespace, the resulting gridargs array will be empty -- zero entries --  # therefore "${gridargs[@]}" entirely vanishes from the command line below,  # just as we want. -eval gridargs=("$(<etc/gridargs.dat)") +if ! $skip_gridargs ; then +    eval gridargs=("$(<etc/gridargs.dat)") +fi  # Run the program.  # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the  # command line. But DO quote "$@": preserve separate args as individually  # quoted. Similar remarks about the contents of gridargs. -$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "$@" +$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "${ARGS[@]}"  LL_RUN_ERR=$?  # Handle any resulting errors diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index 8767955fcb..7662a9689d 100644 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -56,9 +56,9 @@ public:  		}  	} -	void error( U32 statusNum, const std::string& reason ) +	void errorWithContent( U32 statusNum, const std::string& reason, const LLSD& content )  	{ -		llwarns	<< "Transport error "<<reason<<llendl;	 +		llwarns << "Transport error [status:" << statusNum << "]: " << content <<llendl;  		clearPendingRequests();  		LLAccountingCostObserver* observer = mObserverHandle.get(); diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 094d502078..8c42defa73 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -35,6 +35,7 @@  #include "llagentlistener.h"  #include "llagentwearables.h"  #include "llagentui.h" +#include "llappearancemgr.h"  #include "llanimationstates.h"  #include "llcallingcard.h"  #include "llcapabilitylistener.h" @@ -91,7 +92,7 @@  #include "llworldmap.h"  #include "stringize.h" -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines;  extern LLMenuBarGL* gMenuBarView; @@ -808,6 +809,29 @@ void LLAgent::standUp()  } +void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id) +{ +	llinfos << "called" << llendl; + + +	// Old-style appearance entering a server-bake region. +	if (isAgentAvatarValid() && +		!gAgentAvatarp->isUsingServerBakes() && +		(mRegionp->getCentralBakeVersion()>0)) +	{ +		llinfos << "update requested due to region transition" << llendl; +		LLAppearanceMgr::instance().requestServerAppearanceUpdate(); +	} +	// new-style appearance entering a non-bake region, +	// need to check for existence of the baking service. +	else if (isAgentAvatarValid() && +			 gAgentAvatarp->isUsingServerBakes() && +			 mRegionp->getCentralBakeVersion()==0) +	{ +		gAgentAvatarp->checkForUnsupportedServerBakeAppearance(); +	} +} +  //-----------------------------------------------------------------------------  // setRegion()  //----------------------------------------------------------------------------- @@ -903,6 +927,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)); +	}  } @@ -1685,13 +1722,11 @@ void LLAgent::autoPilot(F32 *delta_yaw)  		*delta_yaw = yaw; -		// Compute when to start slowing down and when to stop -		F32 stop_distance = mAutoPilotStopDistance; +		// Compute when to start slowing down  		F32 slow_distance;  		if (getFlying())  		{  			slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f); -			stop_distance = llmax(2.f, mAutoPilotStopDistance);  		}  		else  		{ @@ -2277,7 +2312,7 @@ void LLAgent::setStartPosition( U32 location_id )      if (isAgentAvatarValid())      {          // the z height is at the agent's feet -        agent_pos.mV[VZ] -= 0.5f * gAgentAvatarp->mBodySize.mV[VZ]; +        agent_pos.mV[VZ] -= 0.5f * (gAgentAvatarp->mBodySize.mV[VZ] + gAgentAvatarp->mAvatarOffset.mV[VZ]);      }      agent_pos.mV[VX] = llclamp( agent_pos.mV[VX], INSET, REGION_WIDTH - INSET ); @@ -2496,7 +2531,7 @@ public:  	virtual ~LLMaturityPreferencesResponder();  	virtual void result(const LLSD &pContent); -	virtual void error(U32 pStatus, const std::string& pReason); +	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);  protected: @@ -2534,11 +2569,11 @@ void LLMaturityPreferencesResponder::result(const LLSD &pContent)  	mAgent->handlePreferredMaturityResult(actualMaturity);  } -void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason) +void LLMaturityPreferencesResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)  {  	llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) -		<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '" -		<< pReason << "' [status:" << pStatus << "]" << llendl; +		<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error with [status:" +		<< pStatus << "]: " << (pContent.isDefined() ? pContent : LLSD(pReason)) << llendl;  	mAgent->handlePreferredMaturityError();  } @@ -2698,7 +2733,7 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)  		// If we don't have a region, report it as an error  		if (getRegion() == NULL)  		{ -			responderPtr->error(0U, "region is not defined"); +			responderPtr->errorWithContent(0U, "region is not defined", LLSD());  		}  		else  		{ @@ -2708,7 +2743,8 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)  			// If the capability is not defined, report it as an error  			if (url.empty())  			{ -				responderPtr->error(0U, "capability 'UpdateAgentInformation' is not defined for region"); +				responderPtr->errorWithContent(0U,  +							"capability 'UpdateAgentInformation' is not defined for region", LLSD());  			}  			else  			{ @@ -3576,7 +3612,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *  		return;  	} -	if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) +	if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())  	{  		// ignore baked textures when in customize mode  		return; @@ -3600,7 +3636,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; @@ -4207,27 +4243,82 @@ void LLAgent::requestLeaveGodMode()  	sendReliableMessage();  } +// For debugging, trace agent state at times appearance message are sent out. +void LLAgent::dumpSentAppearance(const std::string& dump_prefix) +{ +	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 +	{ +		LL_DEBUGS("Avatar") << "dumping sent appearance message to " << fullpath << llendl; +	} + +	LLVisualParam* appearance_version_param = gAgentAvatarp->getVisualParam(11000); +	if (appearance_version_param) +	{ +		F32 value = appearance_version_param->getWeight(); +		dump_visual_param(file, appearance_version_param, value); +	} +	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); +		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); +		 ++iter) +	{ +		const ETextureIndex index = iter->first; +		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; +		if (texture_dict->mIsBakedTexture) +		{ +			LLTextureEntry* entry = gAgentAvatarp->getTE((U8) index); +			const LLUUID& uuid = entry->getID(); +			apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", index, uuid.asString().c_str()); +		} +	} +} +  //-----------------------------------------------------------------------------  // sendAgentSetAppearance()  //-----------------------------------------------------------------------------  void LLAgent::sendAgentSetAppearance()  { -	if (!isAgentAvatarValid()) return; - -	if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))  +	if (gAgentQueryManager.mNumPendingQueries > 0)   	{  		return;  	} -	if (!gAgentWearables.changeInProgress()) +	if (!isAgentAvatarValid() || (getRegion() && getRegion()->getCentralBakeVersion())) return; + +	// At this point we have a complete appearance to send and are in a non-baking region. +	// DRANO FIXME +	//gAgentAvatarp->setIsUsingServerBakes(FALSE); +	S32 sb_count, host_count, both_count, neither_count; +	gAgentAvatarp->bakedTextureOriginCounts(sb_count, host_count, both_count, neither_count); +	if (both_count != 0 || neither_count != 0)  	{ -		// Change is fully resolved, can close some open phases. -		gAgentAvatarp->getPhases().stopPhase("process_initial_wearables_update"); -		gAgentAvatarp->getPhases().stopPhase("wear_inventory_category"); +		llwarns << "bad bake texture state " << sb_count << "," << host_count << "," << both_count << "," << neither_count << llendl; +	} +	if (sb_count != 0 && host_count == 0) +	{ +		gAgentAvatarp->setIsUsingServerBakes(true); +	} +	else if (sb_count == 0 && host_count != 0) +	{ +		gAgentAvatarp->setIsUsingServerBakes(false); +	} +	else if (sb_count + host_count > 0) +	{ +		llwarns << "unclear baked texture state, not sending appearance" << llendl; +		return;  	} -	gAgentAvatarp->sendAppearanceChangeMetrics(); -	LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL; + +	LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;  	//dumpAvatarTEs( "sendAgentSetAppearance()" );  	LLMessageSystem* msg = gMessageSystem; @@ -4241,7 +4332,7 @@ void LLAgent::sendAgentSetAppearance()  	// NOTE -- when we start correcting all of the other Havok geometry   	// to compensate for the COLLISION_TOLERANCE ugliness we will have   	// to tweak this number again -	const LLVector3 body_size = gAgentAvatarp->mBodySize; +	const LLVector3 body_size = gAgentAvatarp->mBodySize + gAgentAvatarp->mAvatarOffset;  	msg->addVector3Fast(_PREHASH_Size, body_size);	  	// To guard against out of order packets @@ -4255,7 +4346,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)) @@ -4266,19 +4357,30 @@ void LLAgent::sendAgentSetAppearance()  		// IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures  		if (!gAgentAvatarp->isTextureDefined(texture_index, 0))  		{ +			LL_DEBUGS("Avatar") << "texture not current for baked " << (S32)baked_index << " local " << (S32)texture_index << llendl;  			textures_current = FALSE;  			break;  		}  	}  	// only update cache entries if we have all our baked textures + +	// FIXME DRANO need additional check for not in appearance editing +	// mode, if still using local composites need to set using local +	// composites to false, and update mesh textures.  	if (textures_current)  	{ -		LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL; +		bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"); +		std::string dump_prefix = gAgentAvatarp->getFullname() + "_sent_appearance"; +		if (enable_verbose_dumps) +		{ +			dumpSentAppearance(dump_prefix); +		} +		LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL;  		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; @@ -4287,7 +4389,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); @@ -4323,7 +4425,7 @@ void LLAgent::sendAgentSetAppearance()  		}  	} -//	llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl; +	//llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;  	sendReliableMessage();  } diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index daa15b0c1a..f5f26f69d8 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -33,7 +33,8 @@  #include "llagentdata.h" 			// gAgentID, gAgentSessionID  #include "llcharacter.h"  #include "llcoordframe.h"			// for mFrameAgent -#include "llvoavatardefines.h" +#include "llavatarappearancedefines.h" +#include "llpermissionsflags.h"  #include <boost/function.hpp>  #include <boost/shared_ptr.hpp> @@ -608,6 +609,7 @@ private:  	void            handleTeleportFinished();  	void            handleTeleportFailed(); +	void			handleServerBakeRegionTransition(const LLUUID& region_id);  	//--------------------------------------------------------------------  	// Teleport State @@ -842,6 +844,7 @@ private:  public:  	void			sendMessage(); // Send message to this agent's region  	void			sendReliableMessage(); +	void 			dumpSentAppearance(const std::string& dump_prefix);  	void			sendAgentSetAppearance();  	void 			sendAgentDataUpdateRequest();  	void 			sendAgentUserInfoRequest(); @@ -900,7 +903,7 @@ private:  	S32				mNumPendingQueries;  	S32				mWearablesCacheQueryID;  	U32				mUpdateSerialNum; -	S32		    	mActiveCacheQueries[LLVOAvatarDefines::BAKED_NUM_INDICES]; +	S32		    	mActiveCacheQueries[LLAvatarAppearanceDefines::BAKED_NUM_INDICES];  };  extern LLAgentQueryManager gAgentQueryManager; diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 9025c7af8b..0896aa5972 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -50,7 +50,7 @@  #include "llwindow.h"  #include "llworld.h" -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines;  extern LLMenuBarGL* gMenuBarView; @@ -594,7 +594,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; @@ -689,17 +688,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; @@ -1079,8 +1067,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)) @@ -1433,7 +1421,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; @@ -1457,7 +1445,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(); ) @@ -1658,7 +1646,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;  		calcCameraMinDistance(obj_min_dist);  		F32 current_distance = llmax(0.001f, camera_offset_dir.magVec()); @@ -1685,7 +1672,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; @@ -1820,7 +1807,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; @@ -2257,7 +2243,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)  //-----------------------------------------------------------------------------  void LLAgentCamera::changeCameraToCustomizeAvatar()  { -	if (LLViewerJoystick::getInstance()->getOverrideCamera()) +	if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid())  	{  		return;  	} @@ -2281,29 +2267,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()) -		{ -			// 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); -			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(); +		if (turn_motion) +		{ +			// delay camera animation long enough to play through turn animation +			setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);  		}  	} diff --git a/indra/newview/llagentpilot.cpp b/indra/newview/llagentpilot.cpp index 734c502fcf..c7872fc5f6 100644 --- a/indra/newview/llagentpilot.cpp +++ b/indra/newview/llagentpilot.cpp @@ -139,7 +139,7 @@ void LLAgentPilot::loadXML(const std::string& filename)  	mActions.reset();  	LLSD record; -	while (!file.eof() && LLSDSerialize::fromXML(record, file)) +	while (!file.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(record, file))  	{  		Action action;  		action.mTime = record["time"].asReal(); diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index e441f21f90..c88694ef76 100644..100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -47,7 +47,7 @@  #include "lltooldraganddrop.h"  #include "llviewerregion.h"  #include "llvoavatarself.h" -#include "llwearable.h" +#include "llviewerwearable.h"  #include "llwearablelist.h"  #include <boost/scoped_ptr.hpp> @@ -56,24 +56,21 @@ LLAgentWearables gAgentWearables;  BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE; -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); +}  /////////////////////////////////////////////////////////////////////////////// @@ -82,7 +79,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; @@ -119,7 +116,7 @@ void LLAgentWearables::dump()  		llinfos << "Type: " << i << " count " << count << llendl;  		for (U32 j=0; j<count; j++)  		{ -			LLWearable* wearable = getWearable((LLWearableType::EType)i,j); +			LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)i,j);  			if (wearable == NULL)  			{  				llinfos << "    " << j << " NULL wearable" << llendl; @@ -159,6 +156,7 @@ struct LLAgentDumper  };  LLAgentWearables::LLAgentWearables() : +	LLWearableData(),  	mWearablesLoaded(FALSE)  ,	mCOFChangeInProgress(false)  { @@ -182,12 +180,11 @@ void LLAgentWearables::initClass()  }  void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar) -{  -	if (avatar) -	{ -		avatar->outputRezTiming("Sending wearables request"); -		sendAgentWearablesRequest(); -	} +{ +	llassert(avatar); +	avatar->outputRezTiming("Sending wearables request"); +	sendAgentWearablesRequest(); +	setAvatarAppearance(avatar);  }  // wearables @@ -213,12 +210,13 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal   * @param todo Bitmask of actions to take on completion.   */  LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback( -	LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo) : +	LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLViewerWearable* wearable, U32 todo, const std::string description) :  	mType(type),  	mIndex(index),	  	mWearable(wearable),  	mTodo(todo), -	mCB(cb) +	mCB(cb), +	mDescription(description)  {  	llinfos << "constructor" << llendl;  } @@ -258,14 +256,14 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i  	}  	if (mTodo & CALL_WEARITEM)  	{ -		LLAppearanceMgr::instance().addCOFItemLink(inv_item, true); +		LLAppearanceMgr::instance().addCOFItemLink(inv_item, true, NULL, mDescription);  	}  }  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; @@ -312,7 +310,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()) @@ -354,7 +352,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; @@ -382,14 +380,14 @@ void LLAgentWearables::sendAgentWearablesUpdate()  void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update,  									const std::string new_name)  { -	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 @@ -458,6 +456,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32  void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,  									  const U32 index,  									  const std::string& new_name, +									  const std::string& description,  									  BOOL save_in_lost_and_found)  {  	if (!isWearableCopyable(type, index)) @@ -465,7 +464,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,  		llwarns << "LLAgent::saveWearableAs() not copyable." << llendl;  		return;  	} -	LLWearable* old_wearable = getWearable(type, index); +	LLViewerWearable* old_wearable = getViewerWearable(type, index);  	if (!old_wearable)  	{  		llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl; @@ -480,7 +479,7 @@ void 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<LLInventoryCallback> cb = @@ -489,7 +488,9 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,  			type,  			index,  			new_wearable, -			addWearableToAgentInventoryCallback::CALL_WEARITEM); +			addWearableToAgentInventoryCallback::CALL_WEARITEM, +			description +			);  	LLUUID category_id;  	if (save_in_lost_and_found)  	{ @@ -518,7 +519,7 @@ void 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)  	{ @@ -553,13 +554,13 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string&  			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) @@ -640,14 +641,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; @@ -657,14 +658,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; @@ -674,13 +675,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; @@ -699,215 +700,55 @@ void LLAgentWearables::sendAgentWearablesRequest()  	gAgent.sendReliableMessage();  } -// static -BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type) -{ -	return (gAgentWearables.getWearableCount(type) > 0); -} - -LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) -{ -	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 LLAgentWearables::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable) +LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 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->setLabelUpdated(); -		wearableUpdated(wearable); -		checkWearableAgainstInventory(wearable); -	} +	return dynamic_cast<LLViewerWearable*> (getWearable(type, index));  } -U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable *wearable) +const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const  { -	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; -	} -	return MAX_CLOTHING_PER_TYPE; +	return dynamic_cast<const LLViewerWearable*> (getWearable(type, index));  } -void LLAgentWearables::wearableUpdated(LLWearable *wearable) +// static +BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)  { -	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); -	} - +	return (gAgentWearables.getWearableCount(type) > 0);  } -void LLAgentWearables::popWearable(LLWearable *wearable) +// virtual +void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed)  { -	if (wearable == NULL) +	if (isAgentAvatarValid())  	{ -		// nothing to do here. move along. -		return; +		const BOOL upload_result = removed; +		gAgentAvatarp->wearableUpdated(wearable->getType(), upload_result);  	} -	U32 index = getWearableIndex(wearable); -	LLWearableType::EType type = wearable->getType(); +	LLWearableData::wearableUpdated(wearable, removed); -	if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type)) +	if (!removed)  	{ -		popWearable(type, index); -	} -} +		LLViewerWearable* viewer_wearable = dynamic_cast<LLViewerWearable*>(wearable); +		viewer_wearable->refreshName(); -void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index) -{ -	LLWearable *wearable = getWearable(type, index); -	if (wearable) -	{ -		mWearableDatas[type].erase(mWearableDatas[type].begin() + index); -		if (isAgentAvatarValid()) +		// 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 )  		{ -		gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE); +			wearable->setDefinitionVersion(22); +			U32 index = getWearableIndex(wearable); +			llinfos << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << llendl; +			saveWearable(wearable->getType(),index,TRUE);  		} -		wearable->setLabelUpdated(); -	} -} -U32	LLAgentWearables::getWearableIndex(const LLWearable *wearable) const -{ -	if (wearable == NULL) -	{ -		return MAX_CLOTHING_PER_TYPE; +		checkWearableAgainstInventory(viewer_wearable);  	} - -	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 -{ -	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  {  	return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end(); @@ -920,7 +761,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 @@ -929,7 +770,7 @@ const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32  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 @@ -955,8 +796,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs  	if (isAgentAvatarValid())  	{ -		//gAgentAvatarp->clearPhases(); // reset phase timers for outfit loading. -		gAgentAvatarp->getPhases().startPhase("process_initial_wearables_update"); +		gAgentAvatarp->startPhase("process_initial_wearables_update");  		gAgentAvatarp->outputRezTiming("Received initial wearables update");  	} @@ -1012,7 +852,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  			{ @@ -1058,7 +898,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); @@ -1093,9 +933,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; @@ -1125,10 +965,10 @@ public:  		llinfos << "All items created" << llendl;  		LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;  		LLAppearanceMgr::instance().linkAll(LLAppearanceMgr::instance().getCOF(), -												mItemsToLink, -												link_waiter); +											mItemsToLink, +											link_waiter);  	} -	void addPendingWearable(LLWearable *wearable) +	void addPendingWearable(LLViewerWearable *wearable)  	{  		if (!wearable)  		{ @@ -1163,7 +1003,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);  			} @@ -1176,7 +1016,7 @@ public:  private:  	LLInventoryModel::item_array_t mItemsToLink; -	std::vector<LLWearable*> mWearablesAwaitingItems; +	std::vector<LLViewerWearable*> mWearablesAwaitingItems;  };  void LLAgentWearables::createStandardWearables() @@ -1208,7 +1048,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; @@ -1267,7 +1107,7 @@ void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)  void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb, -												   LLWearable* wearable, +												   LLViewerWearable* wearable,  												   const LLUUID& category_id,  												   BOOL notify)  { @@ -1305,7 +1145,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)  		{ @@ -1360,10 +1200,10 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo  	//LLAgentDumper dumper("removeWearable");  	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)  			{ @@ -1371,11 +1211,11 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo  				old_wearable->removeFromAvatar(TRUE);  			}  		} -		mWearableDatas[type].clear(); +		clearWearableType(type);  	}  	else  	{ -		LLWearable* old_wearable = getWearable(type, index); +		LLViewerWearable* old_wearable = getViewerWearable(type, index);  		//queryWearableCache(); // moved below  		if (old_wearable) @@ -1394,7 +1234,7 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo  // 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; @@ -1419,7 +1259,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<LLInventoryItem> new_item = items[i];  		llassert(new_wearable); @@ -1439,8 +1279,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  			{  				pushWearable(type,new_wearable);  			} -			wearableUpdated(new_wearable); -			checkWearableAgainstInventory(new_wearable); +			const BOOL removed = FALSE; +			wearableUpdated(new_wearable, removed);  		}  	} @@ -1476,7 +1316,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())) @@ -1491,7 +1331,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(); @@ -1517,7 +1357,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()); @@ -1553,16 +1393,17 @@ 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();  	if (do_append && getWearableItemID(type,0).notNull())  	{  		new_wearable->setItemID(new_item->getUUID()); -		mWearableDatas[type].push_back(new_wearable); +		const bool trigger_updated = false; +		pushWearable(type, new_wearable, trigger_updated);  		llinfos << "Added additional wearable for type " << type -				<< " size is now " << mWearableDatas[type].size() << llendl; +				<< " size is now " << getWearableCount(type) << llendl;  		checkWearableAgainstInventory(new_wearable);  	}  	else @@ -1570,7 +1411,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)  		{ @@ -1585,7 +1426,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; @@ -1597,7 +1438,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n  void LLAgentWearables::queryWearableCache()  { -	if (!areWearablesLoaded()) +	if (!areWearablesLoaded() || (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()))  	{  		return;  	} @@ -1626,7 +1467,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); @@ -1645,53 +1486,21 @@ void LLAgentWearables::queryWearableCache()  			gAgentAvatarp->outputRezTiming("Fetching textures from cache");  		} -		LL_INFOS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL; +		LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL;  		gMessageSystem->sendReliable(gAgent.getRegion()->getHost());  		gAgentQueryManager.mNumPendingQueries++;  		gAgentQueryManager.mWearablesCacheQueryID++;  	}  } -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++) -	{ -		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; -			} -		} -	} -	if (hash_computed) +	// Add some garbage into the hash so that it becomes invalid. +	if (isAgentAvatarValid())  	{ -		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); +		hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);  	} - -	return hash_id;  }  // User has picked "remove from avatar" from a menu. @@ -1715,7 +1524,7 @@ void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &ty  	}  } -// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to +// Combines userRemoveMulipleAttachments() and userAttachMultipleAttachments() logic to  // get attachments into desired state with minimal number of adds/removes.  void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)  { @@ -1811,31 +1620,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)  {  	// Build a compound message to send all the objects that need to be rezzed. @@ -1900,7 +1684,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; @@ -1928,7 +1712,7 @@ void LLAgentWearables::updateWearablesLoaded()  	}  } -bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const +bool LLAgentWearables::canWearableBeRemoved(const LLViewerWearable* wearable) const  {  	if (!wearable) return false; @@ -1943,7 +1727,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)  			{ @@ -1958,28 +1742,39 @@ 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; +	if (closer_to_body) +	{ +		LLViewerWearable* bottom_wearable = dynamic_cast<LLViewerWearable*>( getBottomWearable(type) ); +		if (bottom_wearable->getAssetID() == asset_id) +		{ +			return false; +		} +	} +	else // !closer_to_body +	{ +		LLViewerWearable* top_wearable = dynamic_cast<LLViewerWearable*>( getTopWearable(type) ); +		if (top_wearable->getAssetID() == asset_id) +		{ +			return false; +		} +	} -	for (U32 i = 0; i < wearable_vec.size(); ++i) +	for (U32 i = 0; i < wearable_count; ++i)  	{ -		LLWearable* wearable = wearable_vec[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);  		return true;  	} @@ -1991,10 +1786,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<LLInventoryCallback> cb = wear ? new LLWearAndEditCallback : NULL; +	LLPointer<LLInventoryCallback> cb = wear ? new LLBoostFuncInventoryCallback(wear_and_edit_cb) : NULL;  	LLUUID folder_id;  	if (parent_id.notNull()) @@ -2024,7 +1819,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; diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 5932be21c6..5be4648636 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<LLAgentWearables> +class LLAgentWearables : public LLInitClass<LLAgentWearables>, public LLWearableData  {  	//--------------------------------------------------------------------  	// Constructors / destructors / Initializers @@ -79,10 +79,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); @@ -92,52 +92,38 @@ public:  public:  	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<LLInventoryCallback> 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(); @@ -172,15 +158,14 @@ 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 @@ -198,7 +183,7 @@ private:  	// Save Wearables  	//--------------------------------------------------------------------  public:	 -	void			saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found); +	void			saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, const std::string& description, 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(); @@ -215,7 +200,6 @@ public:  	static void 	userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);  	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; @@ -245,10 +229,6 @@ private:  	// Member variables  	//--------------------------------------------------------------------  private: -	typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts) -	typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t;	// wearable "categories" arranged by wearable type -	wearableentry_map_t mWearableDatas; -  	static BOOL		mInitialWearablesUpdateReceived;  	BOOL			mWearablesLoaded;  	std::set<LLUUID>	mItemsAwaitingWearableUpdate; @@ -289,15 +269,17 @@ private:  		addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,  											LLWearableType::EType type,  											U32 index, -											LLWearable* wearable, -											U32 todo = CALL_NONE); +											LLViewerWearable* wearable, +											U32 todo = CALL_NONE, +											const std::string description = "");  		virtual void fire(const LLUUID& inv_item);  	private:  		LLWearableType::EType mType;  		U32 mIndex; -		LLWearable* mWearable; +		LLViewerWearable* mWearable;  		U32 mTodo;  		LLPointer<LLRefCount> mCB; +		std::string mDescription;  	};  }; // LLAgentWearables diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index e31e39dca2..2d2d730396 100644 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -35,61 +35,52 @@  #include "llvoavatarself.h" -class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback +void order_my_outfits_cb()  { -public: -	LLOrderMyOutfitsOnDestroy() {}; - -	virtual ~LLOrderMyOutfitsOnDestroy() +	if (!LLApp::isRunning())  	{ -		if (!LLApp::isRunning()) -		{ -			llwarns << "called during shutdown, skipping" << llendl; -			return; -		} +		llwarns << "called during shutdown, skipping" << llendl; +		return; +	} -		const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); -		if (my_outfits_id.isNull()) return; - -		LLInventoryModel::cat_array_t* cats; -		LLInventoryModel::item_array_t* items; -		gInventory.getDirectDescendentsOf(my_outfits_id, cats, items); -		if (!cats) return; +	const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); +	if (my_outfits_id.isNull()) return; -		//My Outfits should at least contain saved initial outfit and one another outfit -		if (cats->size() < 2) -		{ -			llwarning("My Outfits category was not populated properly", 0); -			return; -		} +	LLInventoryModel::cat_array_t* cats; +	LLInventoryModel::item_array_t* items; +	gInventory.getDirectDescendentsOf(my_outfits_id, cats, items); +	if (!cats) return; -		llinfos << "Starting updating My Outfits with wearables ordering information" << llendl; +	//My Outfits should at least contain saved initial outfit and one another outfit +	if (cats->size() < 2) +	{ +		llwarning("My Outfits category was not populated properly", 0); +		return; +	} -		for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin(); -			outfit_iter != cats->end(); ++outfit_iter) -		{ -			const LLUUID& cat_id = (*outfit_iter)->getUUID(); -			if (cat_id.isNull()) continue; +	llinfos << "Starting updating My Outfits with wearables ordering information" << llendl; -			// saved initial outfit already contains wearables ordering information -			if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue; +	for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin(); +		 outfit_iter != cats->end(); ++outfit_iter) +	{ +		const LLUUID& cat_id = (*outfit_iter)->getUUID(); +		if (cat_id.isNull()) continue; -			LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id); -		} +		// saved initial outfit already contains wearables ordering information +		if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue; -		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)  {  	if (isAgentAvatarValid())  	{ -		gAgentAvatarp->getPhases().startPhase("initial_wearables_fetch"); +		gAgentAvatarp->startPhase("initial_wearables_fetch");  		gAgentAvatarp->outputRezTiming("Initial wearables fetch started");  	}  } @@ -108,7 +99,7 @@ void LLInitialWearablesFetch::done()  	doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this));  	if (isAgentAvatarValid())  	{ -		gAgentAvatarp->getPhases().stopPhase("initial_wearables_fetch"); +		gAgentAvatarp->stopPhase("initial_wearables_fetch");  		gAgentAvatarp->outputRezTiming("Initial wearables fetch done");  	}  } @@ -563,7 +554,7 @@ void LLLibraryOutfitsFetch::contentsDone()  	LLInventoryModel::cat_array_t cat_array;  	LLInventoryModel::item_array_t wearable_array; -	LLPointer<LLOrderMyOutfitsOnDestroy> order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy; +	LLPointer<LLInventoryCallback> 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 a28b77b1fc..05dfac4e42 100644 --- a/indra/newview/llappearance.h +++ b/indra/newview/llappearance.h @@ -38,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<LLVOAvatarDefines::TEX_NUM_INDICES; i++ ) mTextures[i].setNull(); } +	void	clear()										{ mParamMap.clear(); for( S32 i=0; i<LLAvatarAppearanceDefines::TEX_NUM_INDICES; i++ ) mTextures[i].setNull(); }  	typedef std::map<S32, F32> 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 769b4eafe1..652f199e28 100644..100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -26,6 +26,7 @@  #include "llviewerprecompiledheaders.h" +#include <boost/lexical_cast.hpp>  #include "llaccordionctrltab.h"  #include "llagent.h"  #include "llagentcamera.h" @@ -49,6 +50,13 @@  #include "llvoavatarself.h"  #include "llviewerregion.h"  #include "llwearablelist.h" +#include "llsdutil.h" +#include "llsdserialize.h" + +#if LL_MSVC +// disable boost::lexical_cast warning +#pragma warning (disable:4702) +#endif  std::string self_av_string()  { @@ -155,71 +163,342 @@ LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string  	}  } -class LLWearInventoryCategoryCallback : public LLInventoryCallback +// We want this to be much lower (e.g. 15.0 is usually fine), bumping +// up for now until we can diagnose some cases of very slow response +// to requests. +const F32 DEFAULT_RETRY_AFTER_INTERVAL = 300.0; + +// Given the current back-end problems, retrying is causing too many +// duplicate items. Bump this back to 2 once they are resolved (or can +// leave at 0 if the operations become actually reliable). +const S32 DEFAULT_MAX_RETRIES = 0; + +class LLCallAfterInventoryBatchMgr: public LLEventTimer   {  public: -	LLWearInventoryCategoryCallback(const LLUUID& cat_id, bool append) -	{ -		mCatID = cat_id; -		mAppend = 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 = DEFAULT_RETRY_AFTER_INTERVAL, +								 S32 max_retries = DEFAULT_MAX_RETRIES +		): +		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(5.0) +	{ +		if (!mTrackingPhase.empty()) +		{ +			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()); +		} +	} -		LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; +	// Request or re-request operation for specified item. +	void addItem(const LLUUID& item_id) +	{ +		LL_DEBUGS("Avatar") << "item_id " << item_id << llendl; -		selfStartPhase("wear_inventory_category_callback"); +		if (!requestOperation(item_id)) +		{ +			LL_DEBUGS("Avatar") << "item_id " << item_id << " requestOperation false, skipping" << llendl; +			return; +		} + +		mPendingRequests++; +		// On a re-request, this will reset the timer. +		mWaitTimes[item_id] = LLTimer(); +		if (mRetryCounts.find(item_id) == mRetryCounts.end()) +		{ +			mRetryCounts[item_id] = 0; +		} +		else +		{ +			mRetryCounts[item_id]++; +		}  	} -	void fire(const LLUUID& item_id) + +	virtual bool requestOperation(const LLUUID& item_id) = 0; + +	void onOp(const LLUUID& src_id, const LLUUID& dst_id, LLTimer timestamp)  	{ -		/* -		 * 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; +		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateLateOpRate")) +		{ +			llwarns << "Simulating late operation by punting handling to later" << llendl; +			doAfterInterval(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,src_id,dst_id,timestamp), +							mRetryAfter); +			return; +		} +		mPendingRequests--; +		F32 elapsed = timestamp.getElapsedTimeF32(); +		LL_DEBUGS("Avatar") << "op done, src_id " << src_id << " dst_id " << dst_id << " after " << elapsed << " seconds" << llendl; +		if (mWaitTimes.find(src_id) == mWaitTimes.end()) +		{ +			// No longer waiting for this item - either serviced +			// already or gave up after too many retries. +			llwarns << "duplicate or late operation, src_id " << src_id << "dst_id " << dst_id +					<< " elapsed " << elapsed << " after end " << (S32) mCompletionOrFailureCalled << llendl; +		} +		mTimeStats.push(elapsed); +		mWaitTimes.erase(src_id); +		if (mWaitTimes.empty() && !mCompletionOrFailureCalled) +		{ +			onCompletionOrFailure(); +		}  	} -protected: -	~LLWearInventoryCategoryCallback() +	void onCompletionOrFailure()  	{ -		LL_INFOS("Avatar") << self_av_string() << "done all inventory callbacks" << LL_ENDL; +		assert (!mCompletionOrFailureCalled); +		mCompletionOrFailureCalled = true; -		selfStopPhase("wear_inventory_category_callback"); - -		// 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() ) +		// Will never call onCompletion() if any item has been flagged as +		// a failure - otherwise could wind up with corrupted +		// outfit, involuntary nudity, etc. +		reportStats(); +		if (!mTrackingPhase.empty())  		{ -			LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend); +			selfStopPhase(mTrackingPhase); +		} +		if (!mFailCount) +		{ +			onCompletion();  		}  		else  		{ -			llwarns << self_av_string() << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl; +			onFailure();  		}  	} -private: -	LLUUID mCatID; -	bool mAppend; -}; +	void onFailure() +	{ +		llinfos << "failed" << llendl; +		mOnFailureFunc(); +	} +	void onCompletion() +	{ +		llinfos << "done" << llendl; +		mOnCompletionFunc(); +	} +	 +	// virtual +	// Will be deleted after returning true - only safe to do this if all callbacks have fired. +	BOOL tick() +	{ +		// mPendingRequests will be zero if all requests have been +		// responded to.  mWaitTimes.empty() will be true if we have +		// received at least one reply for each UUID.  If requests +		// have been dropped and retried, these will not necessarily +		// be the same.  Only safe to return true if all requests have +		// been serviced, since it will result in this object being +		// deleted. +		bool all_done = (mPendingRequests==0); -//Inventory callback updating "dirty" state when destroyed -class LLUpdateDirtyState: public LLInventoryCallback +		if (!mWaitTimes.empty()) +		{ +			llwarns << "still waiting on " << mWaitTimes.size() << " items" << llendl; +			for (std::map<LLUUID,LLTimer>::iterator it = mWaitTimes.begin(); +				 it != mWaitTimes.end();) +			{ +				// Use a copy of iterator because it may be erased/invalidated. +				std::map<LLUUID,LLTimer>::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<LLUUID,LLTimer> mWaitTimes; +	std::map<LLUUID,S32> 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; +}; + +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 = DEFAULT_RETRY_AFTER_INTERVAL, +								 S32 max_retries = DEFAULT_MAX_RETRIES +		): +		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)  	{ -		if (LLAppearanceMgr::instanceExists()) +		LLViewerInventoryItem *item = gInventory.getItem(item_id); +		llassert(item); +		LL_DEBUGS("Avatar") << "copying item " << item_id << llendl; +		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))  		{ -			LLAppearanceMgr::getInstance()->updateIsDirty(); +			LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl; +			return true;  		} +		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 = DEFAULT_RETRY_AFTER_INTERVAL, +								 S32 max_retries = DEFAULT_MAX_RETRIES +		): +		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) +		{ +			if (item->getParentUUID() == mDstCatID) +			{ +				LL_DEBUGS("Avatar") << "item " << item_id << " name " << item->getName() << " is already a child of " << mDstCatID << llendl; +				return false; +			} +			LL_DEBUGS("Avatar") << "linking item " << item_id << " name " << item->getName() << " to " << mDstCatID << llendl; +			// create an inventory item link. +			if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate")) +			{ +				LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl; +				return true; +			} +			link_inventory_item(gAgent.getID(), +								item->getLinkedUUID(), +								mDstCatID, +								item->getName(), +								item->getActualDescription(), +								LLAssetType::AT_LINK, +								new LLBoostFuncInventoryCallback( +									boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer()))); +			return true; +		} +		else +		{ +			// create a base outfit link if appropriate. +			LLViewerInventoryCategory *catp = gInventory.getCategory(item_id); +			if (!catp) +			{ +				llwarns << "link request failed, 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) +			{ +				if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate")) +				{ +					LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl; +					return true; +				} +				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), @@ -278,7 +557,7 @@ struct LLFoundData  	std::string mName;  	LLAssetType::EType mAssetType;  	LLWearableType::EType mWearableType; -	LLWearable* mWearable; +	LLViewerWearable* mWearable;  	bool mIsReplacement;  }; @@ -302,7 +581,7 @@ public:  	void recoverMissingWearable(LLWearableType::EType type);  	void clearCOFLinksForMissingWearables(); -	void onWearableAssetFetch(LLWearable *wearable); +	void onWearableAssetFetch(LLViewerWearable *wearable);  	void onAllComplete();  	typedef std::list<LLFoundData> found_list_t; @@ -328,7 +607,7 @@ private:  	typedef std::set<LLWearableHoldingPattern*> type_set_hp;  	static type_set_hp sActiveHoldingPatterns;  	bool mIsMostRecent; -	std::set<LLWearable*> mLateArrivals; +	std::set<LLViewerWearable*> mLateArrivals;  	bool mIsAllComplete;  }; @@ -559,100 +838,72 @@ 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) -	{ -		if (!mHolder->isMostRecent()) -		{ -			llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; -			// runway skip here? -		} -		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; +	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) -		{ -			gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); +	if (linked_item) +	{ +		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; -}; +	else +	{ +		llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl; +	} +} -class RecoveredItemCB: public LLInventoryCallback +void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)  { -public: -	RecoveredItemCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder): -		mHolder(holder), -		mWearable(wearable), -		mType(type) +	if (!holder->isMostRecent())  	{ +		// runway skip here? +		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;  	} -	void fire(const LLUUID& item_id) -	{ -		if (!mHolder->isMostRecent()) -		{ -			// runway skip here? -			llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; -		} -		LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << mType << LL_ENDL; -		LLViewerInventoryItem *itemp = gInventory.getItem(item_id); -		mWearable->setItemID(item_id); -		LLPointer<LLInventoryCallback> 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); -		} +	LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL; +	LLViewerInventoryItem *itemp = gInventory.getItem(item_id); +	wearable->setItemID(item_id); +	LLPointer<LLInventoryCallback> 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);  	} -private: -	LLWearableHoldingPattern* mHolder; -	LLWearable *mWearable; -	LLWearableType::EType mType; -}; +}  void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)  { @@ -666,11 +917,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<LLInventoryCallback> cb = new RecoveredItemCB(type,wearable,this); +	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this));  	create_inventory_item(gAgent.getID(),  						  gAgent.getSessionID(), @@ -699,7 +950,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);  		}  	}  } @@ -773,11 +1024,11 @@ void LLWearableHoldingPattern::handleLateArrivals()  		 iter != getFoundList().end(); ++iter)  	{  		LLFoundData& data = *iter; -		for (std::set<LLWearable*>::iterator wear_it = mLateArrivals.begin(); +		for (std::set<LLViewerWearable*>::iterator wear_it = mLateArrivals.begin();  			 wear_it != mLateArrivals.end();  			 ++wear_it)  		{ -			LLWearable *wearable = *wear_it; +			LLViewerWearable *wearable = *wear_it;  			if(wearable->getAssetID() == data.mAssetID)  			{ @@ -813,7 +1064,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<LLFoundData>::iterator clobber_ator = iter;  			++iter;  			getFoundList().erase(clobber_ator); @@ -837,7 +1088,7 @@ void LLWearableHoldingPattern::resetTime(F32 timeout)  	mWaitTime.setTimerExpirySec(timeout);  } -void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) +void LLWearableHoldingPattern::onWearableAssetFetch(LLViewerWearable *wearable)  {  	if (!isMostRecent())  	{ @@ -888,7 +1139,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); @@ -927,6 +1178,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()  { @@ -995,6 +1258,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<LLInventoryCallback> cb)  {  	if (item_id_to_wear.isNull()) return false; @@ -1014,8 +1289,8 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up  	if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))  	{ -		LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(replace); -		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb); +		LLPointer<LLInventoryCallback> 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())) @@ -1041,7 +1316,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);  		}  @@ -1051,7 +1326,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; @@ -1149,11 +1424,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. @@ -1197,13 +1474,13 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL  		{  			case LLAssetType::AT_LINK:  			{ -				//LLInventoryItem::getDescription() is used for a new description  +				//getActualDescription() is used for a new description   				//to propagate ordering information saved in descriptions of links  				link_inventory_item(gAgent.getID(),  									item->getLinkedUUID(),  									dst_id,  									item->getName(), -									item->LLInventoryItem::getDescription(), +									item->getActualDescription(),  									LLAssetType::AT_LINK, cb);  				break;  			} @@ -1383,7 +1660,7 @@ void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)  	}  } -void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_links) +void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_links, LLInventoryModel::item_array_t* keep_items)  {  	LLInventoryModel::cat_array_t cats;  	LLInventoryModel::item_array_t items; @@ -1396,8 +1673,19 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin  			continue;  		if (item->getIsLinkType())  		{ +#if 0 +			if (keep_items && keep_items->find(item) != LLInventoryModel::item_array_t::FAIL) +			{ +				llinfos << "preserved item" << llendl; +			} +			else +			{ +				gInventory.purgeObject(item->getUUID()); +			} +#else  			gInventory.purgeObject(item->getUUID());  		} +#endif  	}  } @@ -1437,7 +1725,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,  							item->getLinkedUUID(),  							cat_uuid,  							item->getName(), -							item->LLInventoryItem::getDescription(), +							item->getActualDescription(),  							LLAssetType::AT_LINK,  							cb); @@ -1508,40 +1796,31 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)  	getDescendentsOfAssetType(category, gest_items, LLAssetType::AT_GESTURE, false);  	removeDuplicateItems(gest_items); -	// Remove current COF contents. -	bool keep_outfit_links = append; -	purgeCategory(cof, keep_outfit_links); -	gInventory.notifyObservers(); -  	// Create links to new COF contents. -	LL_DEBUGS("Avatar") << self_av_string() << "creating LLUpdateAppearanceOnDestroy" << LL_ENDL; -	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(!append); - -#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); +	LLInventoryModel::item_array_t all_items; +	all_items += body_items; +	all_items += wear_items; +	all_items += obj_items; +	all_items += gest_items; -#ifndef LL_RELEASE_FOR_DOWNLOAD -	LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL; -#endif -	linkAll(cof, obj_items, link_waiter); - -#ifndef LL_RELEASE_FOR_DOWNLOAD -	LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL; -#endif -	linkAll(cof, gest_items, link_waiter); +	// Will link all the above items. +	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; +	linkAll(cof,all_items,link_waiter);  	// Add link to outfit if category is an outfit.   	if (!append)  	{  		createBaseOutfitLink(category, link_waiter);  	} + +	// 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, &all_items); +	gInventory.notifyObservers(); +  	LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;  } @@ -1577,7 +1856,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo  {  	lldebugs << "updateAgentWearables()" << llendl;  	LLInventoryItem::item_array_t items; -	LLDynamicArray< LLWearable* > wearables; +	LLDynamicArray< LLViewerWearable* > wearables;  	// For each wearable type, find the wearables of that type.  	for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ ) @@ -1586,7 +1865,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); @@ -1622,7 +1901,7 @@ static void remove_non_link_items(LLInventoryModel::item_array_t &items)  }  //a predicate for sorting inventory items by actual descriptions -bool sort_by_description(const LLInventoryItem* item1, const LLInventoryItem* item2) +bool sort_by_actual_description(const LLInventoryItem* item1, const LLInventoryItem* item2)  {  	if (!item1 || !item2)   	{ @@ -1630,7 +1909,7 @@ bool sort_by_description(const LLInventoryItem* item1, const LLInventoryItem* it  		return true;  	} -	return item1->LLInventoryItem::getDescription() < item2->LLInventoryItem::getDescription(); +	return item1->getActualDescription() < item2->getActualDescription();  }  void item_array_diff(LLInventoryModel::item_array_t& full_list, @@ -1712,11 +1991,10 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)  		return;  	} -	LLVOAvatar::ScopedPhaseSetter(gAgentAvatarp,"update_appearance_from_cof"); -	  	BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF); +	selfStartPhase("update_appearance_from_cof"); -	LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; +	LL_DEBUGS("Avatar") << self_av_string() << "starting" << LL_ENDL;  	//checking integrity of the COF in terms of ordering of wearables,   	//checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state) @@ -1730,9 +2008,18 @@ 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; +	bool follow_folder_links = false;  	LLUUID current_outfit_id = getCOF();  	// Find all the wearables that are in the COF's subtree. @@ -1820,6 +2107,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); @@ -1954,22 +2242,15 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap  			pid,  			LLFolderType::FT_NONE,  			name); -		LLPointer<LLInventoryCallback> 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();  	} @@ -1986,7 +2267,13 @@ 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; @@ -2053,10 +2340,11 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor  class LLDeferredCOFLinkObserver: public LLInventoryObserver  {  public: -	LLDeferredCOFLinkObserver(const LLUUID& item_id, bool do_update, LLPointer<LLInventoryCallback> cb = NULL): +	LLDeferredCOFLinkObserver(const LLUUID& item_id, bool do_update, LLPointer<LLInventoryCallback> cb = NULL, std::string description = ""):  		mItemID(item_id),  		mDoUpdate(do_update), -		mCallback(cb) +		mCallback(cb), +		mDescription(description)  	{  	} @@ -2078,28 +2366,49 @@ public:  private:  	const LLUUID mItemID;  	bool mDoUpdate; +	std::string mDescription;  	LLPointer<LLInventoryCallback> mCallback;  };  // BAP - note that this runs asynchronously if the item is not already loaded from inventory.  // Dangerous if caller assumes link will exist after calling the function. -void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPointer<LLInventoryCallback> cb) +void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPointer<LLInventoryCallback> cb, const std::string description)  {  	const LLInventoryItem *item = gInventory.getItem(item_id);  	if (!item)  	{ -		LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, do_update, cb); +		LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, do_update, cb, description);  		gInventory.addObserver(observer);  	}  	else  	{ -		addCOFItemLink(item, do_update, cb); +		addCOFItemLink(item, do_update, cb, description); +	} +} + +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( gAgentCamera.cameraCustomizeAvatar() ) +	{ +		// If we're in appearance editing mode, the current tab may need to be refreshed +		LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance")); +		if (panel) +		{ +			panel->showDefaultSubpart(); +		}  	}  } -void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer<LLInventoryCallback> cb) +void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer<LLInventoryCallback> cb, const std::string description)  {		 +	std::string link_description = description;  	const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item);  	if (!vitem)  	{ @@ -2161,37 +2470,106 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update  	{  		if(do_update && cb.isNull())  		{ -			cb = new ModifiedCOFCallback; +			cb = new LLBoostFuncInventoryCallback(modified_cof_cb); +		} +		if (vitem->getIsLinkType()) +		{ +			link_description = vitem->getActualDescription();  		} -		const std::string description = vitem->getIsLinkType() ? vitem->getDescription() : "";  		link_inventory_item( gAgent.getID(),  							 vitem->getLinkedUUID(),  							 getCOF(),  							 vitem->getName(), -							 description, +							 link_description,  							 LLAssetType::AT_LINK,  							 cb);  	}  	return;  } -// BAP remove ensemble code for 2.1? -void LLAppearanceMgr::addEnsembleLink( LLInventoryCategory* cat, bool do_update ) +LLInventoryModel::item_array_t LLAppearanceMgr::findCOFItemLinks(const LLUUID& item_id)  { -#if SUPPORT_ENSEMBLES -	// BAP add check for already in COF. -	LLPointer<LLInventoryCallback> cb = do_update ? new ModifiedCOFCallback : 0; -	link_inventory_item( gAgent.getID(), -						 cat->getLinkedUUID(), -						 getCOF(), -						 cat->getName(), -						 cat->getDescription(), -						 LLAssetType::AT_LINK_FOLDER, -						 cb); -#endif + +	LLInventoryModel::item_array_t result; +	const LLViewerInventoryItem *vitem = +		dynamic_cast<const LLViewerInventoryItem*>(gInventory.getItem(item_id)); + +	if (vitem) +	{ +		LLInventoryModel::cat_array_t cat_array; +		LLInventoryModel::item_array_t item_array; +		gInventory.collectDescendents(LLAppearanceMgr::getCOF(), +									  cat_array, +									  item_array, +									  LLInventoryModel::EXCLUDE_TRASH); +		for (S32 i=0; i<item_array.count(); i++) +		{ +			const LLViewerInventoryItem* inv_item = item_array.get(i).get(); +			if (inv_item->getLinkedUUID() == vitem->getLinkedUUID()) +			{ +				result.put(item_array.get(i)); +			} +		} +	} +	return result;  } -void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update) +void LLAppearanceMgr::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(getCOF(), +									dummy, +									clothing_items, +									LLInventoryModel::EXCLUDE_TRASH, +									is_clothing, +									false); +	uuid_vec_t item_ids; +	for (LLInventoryModel::item_array_t::iterator it = clothing_items.begin(); +		it != clothing_items.end(); ++it) +	{ +		item_ids.push_back((*it).get()->getLinkedUUID()); +	} + +	// Take them off by removing from COF. +	removeItemsFromAvatar(item_ids); +} + +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); @@ -2209,13 +2587,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; @@ -2231,11 +2605,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) @@ -2303,7 +2672,7 @@ void LLAppearanceMgr::updateIsDirty()  			if (item1->getLinkedUUID() != item2->getLinkedUUID() ||   				item1->getName() != item2->getName() || -				item1->LLInventoryItem::getDescription() != item2->LLInventoryItem::getDescription()) +				item1->getActualDescription() != item2->getActualDescription())  			{  				mOutfitIsDirty = true;  				return; @@ -2372,7 +2741,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); @@ -2426,6 +2795,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()) @@ -2446,8 +2825,8 @@ bool LLAppearanceMgr::updateBaseOutfit()  	// in a Base Outfit we do not remove items, only links  	purgeCategory(base_outfit_id, false); - -	LLPointer<LLInventoryCallback> dirty_state_updater = new LLUpdateDirtyState(); +	LLPointer<LLInventoryCallback> 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); @@ -2504,8 +2883,8 @@ struct WearablesOrderComparator  			return true;  		} -		const std::string& desc1 = item1->LLInventoryItem::getDescription(); -		const std::string& desc2 = item2->LLInventoryItem::getDescription(); +		const std::string& desc1 = item1->getActualDescription(); +		const std::string& desc2 = item2->getActualDescription();  		bool item1_valid = (desc1.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc1[0]);  		bool item2_valid = (desc2.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc2[0]); @@ -2563,7 +2942,7 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base  			if (!item) continue;  			std::string new_order_str = build_order_string((LLWearableType::EType)type, i); -			if (new_order_str == item->LLInventoryItem::getDescription()) continue; +			if (new_order_str == item->getActualDescription()) continue;  			item->setDescription(new_order_str);  			item->setComplete(TRUE); @@ -2578,52 +2957,424 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base  	if (inventory_changed) gInventory.notifyObservers();  } +// This is intended for use with HTTP Clients/Responders, but is not +// specifically coupled with those classes. +class LLHTTPRetryPolicy: public LLThreadSafeRefCount +{ +public: +	LLHTTPRetryPolicy() {} +	virtual ~LLHTTPRetryPolicy() {} +	virtual bool shouldRetry(U32 status, F32& seconds_to_wait) = 0; +}; + +// Example of simplest possible policy, not necessarily recommended. +class LLAlwaysRetryImmediatelyPolicy: public LLHTTPRetryPolicy +{ +public: +	LLAlwaysRetryImmediatelyPolicy() {} +	bool shouldRetry(U32 status, F32& seconds_to_wait) +	{ +		seconds_to_wait = 0.0; +		return true; +	} +}; + +// 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. +}; -class LLShowCreatedOutfit: public LLInventoryCallback +class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder  {  public: -	LLShowCreatedOutfit(LLUUID& folder_id, bool show_panel = true): mFolderID(folder_id), mShowPanel(show_panel) -	{} +	RequestAgentUpdateAppearanceResponder() +	{ +		mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10); +	} -	virtual ~LLShowCreatedOutfit() +	virtual ~RequestAgentUpdateAppearanceResponder()  	{ -		if (!LLApp::isRunning()) +	} + +	// Successful completion. +	/* virtual */ void result(const LLSD& content) +	{ +		LL_DEBUGS("Avatar") << "content: " << ll_pretty_print_sd(content) << LL_ENDL; +		if (content["success"].asBoolean())  		{ -			llwarns << "called during shutdown, skipping" << llendl; -			return; +			LL_DEBUGS("Avatar") << "OK" << LL_ENDL; +			if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) +			{ +				dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_ok", content); +			}  		} +		else +		{ +			onFailure(200); +		} +	} -		LLSD key; +	// Error +	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content) +	{ +		llwarns << "appearance update request failed, status: " << status << " reason: " << reason << " code: " << content["code"].asInteger() << " error: \"" << content["error"].asString() << "\"" << llendl; +		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) +		{ +			dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_error", content); +			debugCOF(content); -		//EXT-7727. For new accounts LLShowCreatedOutfit is created during login process -		// add may be processed after login process is finished -		if (mShowPanel) +		} +		onFailure(status); +	}	 + +	void onFailure(U32 status) +	{ +		F32 seconds_to_wait; +		if (mRetryPolicy->shouldRetry(status,seconds_to_wait)) +		{ +			llinfos << "retrying" << llendl; +			doAfterInterval(boost::bind(&LLAppearanceMgr::requestServerAppearanceUpdate, +										LLAppearanceMgr::getInstance(), +										LLCurl::ResponderPtr(this)), +							seconds_to_wait); +		} +		else +		{ +			llwarns << "giving up after too many retries" << llendl; +		} +	}	 + +	void dumpContents(const std::string outprefix, const LLSD& content) +	{ +		std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml"); +		std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); +		std::ofstream ofs(fullpath.c_str(), std::ios_base::out); +		ofs << LLSDOStreamer<LLSDXMLFormatter>(content, LLSDFormatter::OPTIONS_PRETTY); +		LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL; +	} + +	void debugCOF(const LLSD& content) +	{ +		LL_DEBUGS("Avatar") << "AIS COF, version found: " << content["expected"].asInteger() << llendl; +		std::set<LLUUID> ais_items, local_items; +		const LLSD& cof_raw = content["cof_raw"]; +		for (LLSD::array_const_iterator it = cof_raw.beginArray(); +			 it != cof_raw.endArray(); ++it) +		{ +			const LLSD& item = *it; +			if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF()) +			{ +				ais_items.insert(item["item_id"].asUUID()); +				if (item["type"].asInteger() == 24) // link +				{ +					LL_DEBUGS("Avatar") << "Link: item_id: " << item["item_id"].asUUID() +										<< " linked_item_id: " << item["asset_id"].asUUID() +										<< " name: " << item["name"].asString() +										<< llendl;  +				} +				else if (item["type"].asInteger() == 25) // folder link +				{ +					LL_DEBUGS("Avatar") << "Folder link: item_id: " << item["item_id"].asUUID() +										<< " linked_item_id: " << item["asset_id"].asUUID() +										<< " name: " << item["name"].asString() +										<< llendl;  +					 +				} +				else +				{ +					LL_DEBUGS("Avatar") << "Other: item_id: " << item["item_id"].asUUID() +										<< " linked_item_id: " << item["asset_id"].asUUID() +										<< " name: " << item["name"].asString() +										<< llendl;  +				} +			} +		} +		LL_DEBUGS("Avatar") << llendl; +		LL_DEBUGS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger() << llendl; +		LLInventoryModel::cat_array_t cat_array; +		LLInventoryModel::item_array_t item_array; +		gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(), +									  cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH); +		for (S32 i=0; i<item_array.count(); i++) +		{ +			const LLViewerInventoryItem* inv_item = item_array.get(i).get(); +			local_items.insert(inv_item->getUUID()); +			LL_DEBUGS("Avatar") << "item_id: " << inv_item->getUUID() +								<< " linked_item_id: " << inv_item->getLinkedUUID() +								<< " name: " << inv_item->getName() +								<< llendl; +		} +		LL_DEBUGS("Avatar") << llendl; +		for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it) +		{ +			if (ais_items.find(*it) == ais_items.end()) +			{ +				LL_DEBUGS("Avatar") << "LOCAL ONLY: " << *it << llendl; +			} +		} +		for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)  		{ -			LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key); +			if (local_items.find(*it) == local_items.end()) +			{ +				LL_DEBUGS("Avatar") << "AIS ONLY: " << *it << llendl; +			} +		} +	} + +	LLPointer<LLHTTPRetryPolicy> mRetryPolicy; +}; +LLSD LLAppearanceMgr::dumpCOF() const +{ +	LLSD links = LLSD::emptyArray(); +	LLMD5 md5; +	 +	LLInventoryModel::cat_array_t cat_array; +	LLInventoryModel::item_array_t item_array; +	gInventory.collectDescendents(getCOF(),cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH); +	for (S32 i=0; i<item_array.count(); i++) +	{ +		const LLViewerInventoryItem* inv_item = item_array.get(i).get(); +		LLSD item; +		LLUUID item_id(inv_item->getUUID()); +		md5.update((unsigned char*)item_id.mData, 16); +		item["description"] = inv_item->getActualDescription(); +		md5.update(inv_item->getActualDescription()); +		item["asset_type"] = inv_item->getActualType(); +		LLUUID linked_id(inv_item->getLinkedUUID()); +		item["linked_id"] = linked_id; +		md5.update((unsigned char*)linked_id.mData, 16); + +		if (LLAssetType::AT_LINK == inv_item->getActualType()) +		{ +			const LLViewerInventoryItem* linked_item = inv_item->getLinkedItem(); +			if (NULL == linked_item) +			{ +				llwarns << "Broken link for item '" << inv_item->getName() +						<< "' (" << inv_item->getUUID() +						<< ") during requestServerAppearanceUpdate" << llendl; +				continue; +			} +			// Some assets may be 'hidden' and show up as null in the viewer. +			//if (linked_item->getAssetUUID().isNull()) +			//{ +			//	llwarns << "Broken link (null asset) for item '" << inv_item->getName() +			//			<< "' (" << inv_item->getUUID() +			//			<< ") during requestServerAppearanceUpdate" << llendl; +			//	continue; +			//} +			LLUUID linked_asset_id(linked_item->getAssetUUID()); +			md5.update((unsigned char*)linked_asset_id.mData, 16); +			U32 flags = linked_item->getFlags(); +			md5.update(boost::lexical_cast<std::string>(flags)); +		} +		else if (LLAssetType::AT_LINK_FOLDER != inv_item->getActualType()) +		{ +			llwarns << "Non-link item '" << inv_item->getName() +					<< "' (" << inv_item->getUUID() +					<< ") type " << (S32) inv_item->getActualType() +					<< " during requestServerAppearanceUpdate" << llendl; +			continue;  		} -		LLOutfitsList *outfits_list = -			dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab")); -		if (outfits_list) +		links.append(item); +	} +	LLSD result = LLSD::emptyMap(); +	result["cof_contents"] = links; +	char cof_md5sum[MD5HEX_STR_SIZE]; +	md5.finalize(); +	md5.hex_digest(cof_md5sum); +	result["cof_md5sum"] = std::string(cof_md5sum); +	return result; +} + +void LLAppearanceMgr::requestServerAppearanceUpdate(LLCurl::ResponderPtr responder_ptr) +{ +	if (gAgentAvatarp->isEditingAppearance())  +	{ +		// don't send out appearance updates if in appearance editing mode +		return; +	} + +	if (!gAgent.getRegion()) +	{ +		llwarns << "Region not set, cannot request server appearance update" << llendl; +		return; +	} +	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(); +	if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate")) +	{ +		body = dumpCOF(); +	} +	else +	{ +		body["cof_version"] = cof_version; +		if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))  		{ -			outfits_list->setSelectedOutfitByUUID(mFolderID); +			body["cof_version"] = cof_version+999;  		} +	} +	LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << llendl; +	 +	//LLCurl::ResponderPtr responder_ptr; +	if (!responder_ptr.get()) +	{ +		responder_ptr = new RequestAgentUpdateAppearanceResponder; +	} +	LLHTTPClient::post(url, body, responder_ptr); +	llassert(cof_version >= gAgentAvatarp->mLastUpdateRequestCOFVersion); +	gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version; +} -		LLAppearanceMgr::getInstance()->updateIsDirty(); -		gAgentWearables.notifyLoadingFinished(); // New outfit is saved. -		LLAppearanceMgr::getInstance()->updatePanelOutfitName(""); +class LLIncrementCofVersionResponder : public LLHTTPClient::Responder +{ +public: +	LLIncrementCofVersionResponder() : LLHTTPClient::Responder() +	{ +		mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 16.0, 2.0, 5); +	} + +	virtual ~LLIncrementCofVersionResponder() +	{  	} -	virtual void fire(const LLUUID&) -	{} +	virtual void result(const LLSD &pContent) +	{ +		llinfos << "Successfully incremented agent's COF." << llendl; +		S32 new_version = pContent["category"]["version"].asInteger(); -private: -	LLUUID mFolderID; -	bool mShowPanel; +		// cof_version should have increased +		llassert(new_version > gAgentAvatarp->mLastUpdateRequestCOFVersion); + +		gAgentAvatarp->mLastUpdateRequestCOFVersion = new_version; +	} +	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& content) +	{ +		llwarns << "While attempting to increment the agent's cof we got an error with [status:" +				<< pStatus << "]: " << content << llendl; +		F32 seconds_to_wait; +		if (mRetryPolicy->shouldRetry(pStatus,seconds_to_wait)) +		{ +			llinfos << "retrying" << llendl; +			doAfterInterval(boost::bind(&LLAppearanceMgr::incrementCofVersion, +										LLAppearanceMgr::getInstance(), +										LLHTTPClient::ResponderPtr(this)), +										seconds_to_wait); +		} +		else +		{ +			llwarns << "giving up after too many retries" << llendl; +		} +	} + +	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;  }; +void LLAppearanceMgr::incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr) +{ +	// If we don't have a region, report it as an error +	if (gAgent.getRegion() == NULL) +	{ +		llwarns << "Region not set, cannot request cof_version increment" << llendl; +		return; +	} + +	std::string url = gAgent.getRegion()->getCapability("IncrementCofVersion"); +	if (url.empty()) +	{ +		llwarns << "No cap for IncrementCofVersion." << llendl; +		return; +	} + +	llinfos << "Requesting cof_version be incremented via capability to: " +			<< url << llendl; +	LLSD headers; +	LLSD body = LLSD::emptyMap(); + +	if (!responder_ptr.get()) +	{ +		responder_ptr = LLHTTPClient::ResponderPtr(new LLIncrementCofVersionResponder()); +	} + +	LLHTTPClient::get(url, body, responder_ptr, headers, 30.0f); +} + +std::string LLAppearanceMgr::getAppearanceServiceURL() const +{ +	if (gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride").empty()) +	{ +		return mAppearanceServiceURL; +	} +	return gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride"); +} + +void show_created_outfit(LLUUID& folder_id, bool show_panel = true) +{ +	if (!LLApp::isRunning()) +	{ +		llwarns << "called during shutdown, skipping" << llendl; +		return; +	} +	 +	LLSD key; +	 +	//EXT-7727. For new accounts inventory callback is created during login process +	// and may be processed after login process is finished +	if (show_panel) +	{ +		LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key); +		 +	} +	LLOutfitsList *outfits_list = +		dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab")); +	if (outfits_list) +	{ +		outfits_list->setSelectedOutfitByUUID(folder_id); +	} +	 +	LLAppearanceMgr::getInstance()->updateIsDirty(); +	gAgentWearables.notifyLoadingFinished(); // New outfit is saved. +	LLAppearanceMgr::getInstance()->updatePanelOutfitName(""); +} +  LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)  {  	if (!isAgentAvatarValid()) return LLUUID::null; @@ -2639,7 +3390,8 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, b  	updateClothingOrderingInfo(); -	LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id,show_panel); +	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(no_op_inventory_func, +																		 boost::bind(show_created_outfit,folder_id,show_panel));  	shallowCopyCategoryContents(getCOF(),folder_id, cb);  	createBaseOutfitLink(folder_id, cb); @@ -2656,33 +3408,26 @@ void LLAppearanceMgr::wearBaseOutfit()  	updateCOF(base_outfit_id);  } -void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) +void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)  { -	LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove); -	if (!item_to_remove) return; - -	switch (item_to_remove->getType()) +	if (ids_to_remove.empty())  	{ -		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); -			} -			break; -		case LLAssetType::AT_OBJECT: -			LLVOAvatarSelf::detachAttachmentIntoInventory(item_to_remove->getLinkedUUID()); -		default: -			break; +		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); +		removeCOFItemLinks(linked_item_id);  	} +	updateAppearanceFromCOF(); +} -	// *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); +void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) +{ +	LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove); +	removeCOFItemLinks(linked_item_id); +	updateAppearanceFromCOF();  }  bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body) @@ -2711,8 +3456,8 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b  	closer_to_body ? --it : ++it;  	LLViewerInventoryItem* swap_item = *it;  	if (!swap_item) return false; -	std::string tmp = swap_item->LLInventoryItem::getDescription(); -	swap_item->setDescription(item->LLInventoryItem::getDescription()); +	std::string tmp = swap_item->getActualDescription(); +	swap_item->setDescription(item->getActualDescription());  	item->setDescription(tmp); @@ -2745,7 +3490,7 @@ void LLAppearanceMgr::sortItemsByActualDescription(LLInventoryModel::item_array_  {  	if (items.size() < 2) return; -	std::sort(items.begin(), items.end(), sort_by_description); +	std::sort(items.begin(), items.end(), sort_by_actual_description);  }  //#define DUMP_CAT_VERBOSE @@ -2811,7 +3556,7 @@ LLAppearanceMgr::~LLAppearanceMgr()  void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)  { -	llinfos << "setAttachmentInvLinkEnable => " << (int) val << llendl; +	LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << llendl;  	mAttachmentInvLinkEnabled = val;  } @@ -2855,7 +3600,7 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)  	   if (mAttachmentInvLinkEnabled)  	   { -		   LLAppearanceMgr::removeCOFItemLinks(item_id, false); +		   LLAppearanceMgr::removeCOFItemLinks(item_id);  	   }  	   else  	   { @@ -2949,9 +3694,9 @@ public:  	}  	virtual void done()  	{ -		// What we do here is get the complete information on the items in -		// the library, and set up an observer that will wait for that to -		// happen. +		// What we do here is get the complete information on the +		// items in the requested category, and set up an observer +		// that will wait for that to happen.  		LLInventoryModel::cat_array_t cat_array;  		LLInventoryModel::item_array_t item_array;  		gInventory.collectDescendents(mComplete.front(), @@ -2964,9 +3709,8 @@ public:  			llwarns << "Nothing fetched in category " << mComplete.front()  					<< llendl;  			gInventory.removeObserver(this); +			doOnIdleOneTime(mCallable); -			// lets notify observers that loading is finished. -			gAgentWearables.notifyLoadingFinished();  			delete this;  			return;  		} diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index c1d561781d..46252afbde 100644..100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -35,7 +35,6 @@  #include "llinventoryobserver.h"  #include "llviewerinventory.h" -class LLWearable;  class LLWearableHoldingPattern;  class LLInventoryCallback;  class LLOutfitUnLockTimer; @@ -93,6 +92,10 @@ public:  	// Find the Current Outfit folder.  	const LLUUID getCOF() const; +	S32 getCOFVersion() const; + +	// Debugging - get truncated LLSD summary of COF contents. +	LLSD dumpCOF() const;  	// Finds the folder link to the currently worn outfit  	const LLViewerInventoryItem *getBaseOutfitLink(); @@ -107,6 +110,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<LLInventoryCallback> link_waiter);  	void updateAgentWearables(LLWearableHoldingPattern* holder, bool append); @@ -126,15 +130,17 @@ public:  				 LLPointer<LLInventoryCallback> cb);  	// Add COF link to individual item. -	void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL); -	void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL); +	void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = ""); +	void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = ""); -	// Remove COF entries -	void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true); -	void removeCOFLinksOfType(LLWearableType::EType type, bool do_update = true); +	// Find COF entries referencing the given item. +	LLInventoryModel::item_array_t findCOFItemLinks(const LLUUID& item_id); -	// Add COF link to ensemble folder. -	void addEnsembleLink(LLInventoryCategory* item, bool do_update = true); +	// Remove COF entries +	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; } @@ -162,6 +168,7 @@ 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); @@ -182,6 +189,20 @@ public:  	bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; } +	void requestServerAppearanceUpdate(LLCurl::ResponderPtr responder_ptr = NULL); + +	void incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr = NULL); + +	// *HACK Remove this after server side texture baking is deployed on all sims. +	void incrementCofVersionLegacy(); + +	void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; } +	std::string getAppearanceServiceURL() const; + +private: +	std::string		mAppearanceServiceURL; +	 +  protected:  	LLAppearanceMgr();  	~LLAppearanceMgr(); @@ -201,9 +222,7 @@ private:  								   LLInventoryModel::item_array_t& gest_items,  								   bool follow_folder_links); -	void purgeCategory(const LLUUID& category, bool keep_outfit_links); -	void purgeBaseOutfitLink(const LLUUID& category); - +	void purgeCategory(const LLUUID& category, bool keep_outfit_links, LLInventoryModel::item_array_t* keep_items = NULL);  	static void onOutfitRename(const LLSD& notification, const LLSD& response);  	void setOutfitLocked(bool locked); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d5c5921ea3..f0481db89b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -292,6 +292,10 @@ LLTimer gLogoutTimer;  static const F32 LOGOUT_REQUEST_TIME = 6.f;  // this will be cut short by the LogoutReply msg.  F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME; + +S32 gPendingMetricsUploads = 0; + +  BOOL				gDisconnected = FALSE;  // used to restore texture state after a mode switch @@ -682,6 +686,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()  {	  	// @@ -693,6 +706,10 @@ bool LLAppViewer::init()  	//  	LLFastTimer::reset(); +	// initialize LLWearableType translation bridge. +	// Memory will be cleaned up in ::cleanupClass() +	LLWearableType::initClass(new LLUITranslationBridge()); +  	// initialize SSE options  	LLVector4a::initClass(); @@ -786,7 +803,7 @@ bool LLAppViewer::init()  		LLUIImageList::getInstance(),  		ui_audio_callback,  		deferred_ui_audio_callback, -		&LLUI::sGLScaleFactor); +		&LLUI::getScaleFactor());  	LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;  	// NOW LLUI::getLanguage() should work. gDirUtilp must know the language @@ -1775,6 +1792,8 @@ bool LLAppViewer::cleanup()  	llinfos << "Cleaning up Objects" << llendflush;  	LLViewerObject::cleanupVOClasses(); + +	LLAvatarAppearance::cleanupClass();  	LLPostProcess::cleanupClass(); @@ -2014,6 +2033,8 @@ bool LLAppViewer::cleanup()  	llinfos << "Cleaning up LLProxy." << llendl;  	LLProxy::cleanupClass(); +	LLWearableType::cleanupClass(); +  	LLMainLoopRepeater::instance().stop();  	//release all private memory pools. @@ -3573,6 +3594,12 @@ void LLAppViewer::requestQuit()  	// Try to send metrics back to the grid  	metricsSend(!gDisconnected); + +	// Try to send last batch of avatar rez metrics. +	if (!gDisconnected && isAgentAvatarValid()) +	{ +		gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. +	}  	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);  	effectp->setPositionGlobal(gAgent.getPositionGlobal()); @@ -4360,7 +4387,6 @@ void LLAppViewer::idle()  			// The 5-second interval is nice for this purpose.  If the object debug  			// bit moves or is disabled, please give this a suitable home.  			LLViewerAssetStatsFF::record_fps_main(gFPSClamped); -			LLViewerAssetStatsFF::record_avatar_stats();  		}  	} @@ -4676,6 +4702,13 @@ void LLAppViewer::idleShutdown()  		return;  	} +	if (gPendingMetricsUploads > 0 +		&& gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME +		&& !logoutRequestSent()) +	{ +		return; +	} +  	// All floaters are closed.  Tell server we want to quit.  	if( !logoutRequestSent() )  	{ diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 7563d672e3..08039100b3 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -342,6 +342,8 @@ extern LLFrameTimer gLoggedInTime;  extern F32 gLogoutMaxTime;  extern LLTimer gLogoutTimer; +extern S32 gPendingMetricsUploads; +  extern F32 gSimLastTime;   extern F32 gSimFrames; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 8326be433e..82b93b52a2 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -92,7 +92,7 @@ void nvapi_error(NvAPI_Status status)  	llwarns << szDesc << llendl;  	//should always trigger when asserts are enabled -	llassert(status == NVAPI_OK); +	//llassert(status == NVAPI_OK);  }  // Create app mutex creates a unique global windows object.  diff --git a/indra/newview/llassetuploadqueue.cpp b/indra/newview/llassetuploadqueue.cpp index f943759bb8..4bdb690225 100644 --- a/indra/newview/llassetuploadqueue.cpp +++ b/indra/newview/llassetuploadqueue.cpp @@ -69,10 +69,11 @@ public:  		delete mData;     	} -	virtual void error(U32 statusNum, const std::string& reason) +	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)     	{ -		llwarns << "Error: " << reason << llendl; -		LLUpdateTaskInventoryResponder::error(statusNum, reason); +		llwarns << "LLAssetUploadChainResponder Error [status:"  +				<< statusNum << "]: " << content << llendl; +		LLUpdateTaskInventoryResponder::errorWithContent(statusNum, reason, content);     		LLAssetUploadQueue *queue = mSupplier->get();     		if (queue)  		{ diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 7b2c536f5a..2564802387 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -48,8 +48,8 @@  #include "llviewercontrol.h"  #include "llviewerobjectlist.h"  #include "llviewermenufile.h" +#include "llviewertexlayer.h"  #include "llviewerwindow.h" -#include "lltexlayer.h"  #include "lltrans.h"  // library includes @@ -225,10 +225,10 @@ LLAssetUploadResponder::~LLAssetUploadResponder()  }  // virtual -void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason) +void LLAssetUploadResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)  { -	llinfos << "LLAssetUploadResponder::error " << statusNum  -			<< " reason: " << reason << llendl; +	llinfos << "LLAssetUploadResponder::error [status:"  +			<< statusNum << "]: " << content << llendl;  	LLSD args;  	switch(statusNum)  	{ @@ -340,9 +340,9 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(  }  // virtual -void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason) +void LLNewAgentInventoryResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)  { -	LLAssetUploadResponder::error(statusNum, reason); +	LLAssetUploadResponder::errorWithContent(statusNum, reason, content);  	//LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE);  } @@ -456,7 +456,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; @@ -477,22 +477,23 @@ 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()  	}  } -void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason) +void LLSendTexLayerResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)  { -	llinfos << "status: " << statusNum << " reason: " << reason << llendl; +	llinfos << "LLSendTexLayerResponder error [status:" +			<< statusNum << "]: " << content << 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 381b919c4a..a6d1016136 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -42,7 +42,7 @@ public:  							LLAssetType::EType asset_type);  	~LLAssetUploadResponder(); -    virtual void error(U32 statusNum, const std::string& reason); +    virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);  	virtual void result(const LLSD& content);  	virtual void uploadUpload(const LLSD& content);  	virtual void uploadComplete(const LLSD& content); @@ -67,7 +67,7 @@ public:  		const LLSD& post_data,  		const std::string& file_name,  		LLAssetType::EType asset_type); -    virtual void error(U32 statusNum, const std::string& reason); +    virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);  	virtual void uploadComplete(const LLSD& content);  	virtual void uploadFailure(const LLSD& content);  }; @@ -122,7 +122,7 @@ public:  	~LLSendTexLayerResponder();  	virtual void uploadComplete(const LLSD& content); -	virtual void error(U32 statusNum, const std::string& reason); +	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);  	LLBakedUploadData * mBakedUploadData;  }; diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 714bde6f37..f34ad23769 100755 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -39,6 +39,8 @@  #include "lluictrlfactory.h"  #include "llagentdata.h"  #include "llfloaterimsession.h" +#include "llviewertexture.h" +#include "llavatarappearancedefines.h"  // library includes  #include "llavatarnamecache.h" diff --git a/indra/newview/llbuycurrencyhtml.cpp b/indra/newview/llbuycurrencyhtml.cpp index e5a9be0203..459123a5d8 100644 --- a/indra/newview/llbuycurrencyhtml.cpp +++ b/indra/newview/llbuycurrencyhtml.cpp @@ -61,6 +61,10 @@ public:  		if ( params.size() >= 3 )  		{  			result_code = params[ 2 ].asInteger(); +			if ( result_code != 0 ) +			{ +				LL_WARNS("LLBuyCurrency") << "Received nonzero result code: " << result_code << LL_ENDL ; +			}  		};  		// open the legacy XUI based currency floater diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp index 357a6582d1..79ec43dfe9 100644 --- a/indra/newview/llcallbacklist.cpp +++ b/indra/newview/llcallbacklist.cpp @@ -27,6 +27,7 @@  #include "llviewerprecompiledheaders.h"  #include "llcallbacklist.h" +#include "lleventtimer.h"  // Library includes  #include "llerror.h" @@ -180,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 97f3bfd9ee..0516c9cdb4 100644 --- a/indra/newview/llcallbacklist.h +++ b/indra/newview/llcallbacklist.h @@ -61,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 30306b230f..14583e402d 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -184,7 +184,8 @@ LLVector3d LLAvatarTracker::getGlobalPos()  		global_pos = object->getPositionGlobal();  		// HACK - for making the tracker point above the avatar's head  		// rather than its groin -		global_pos.mdV[VZ] += 0.7f * ((LLVOAvatar *)object)->mBodySize.mV[VZ]; +		LLVOAvatar* av = (LLVOAvatar*)object; +		global_pos.mdV[VZ] += 0.7f * (av->mBodySize.mV[VZ] + av->mAvatarOffset.mV[VZ]);  		mTrackingData->mGlobalPositionEstimate = global_pos;  	} diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 53926c1fef..0f138873ac 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -408,16 +408,7 @@ public:  		S32 user_name_width = user_name_rect.getWidth();  		S32 time_box_width = time_box->getRect().getWidth(); -		if (time_box->getVisible() && user_name_width <= mMinUserNameWidth) -		{ -			time_box->setVisible(FALSE); - -			user_name_rect.mRight += time_box_width; -			user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight()); -			user_name->setRect(user_name_rect); -		} - -		if (!time_box->getVisible() && user_name_width > mMinUserNameWidth + time_box_width) +		if (!time_box->getVisible() && user_name_width > mMinUserNameWidth)  		{  			user_name_rect.mRight -= time_box_width;  			user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight()); diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index b221daf936..88884042d4 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -174,6 +174,7 @@ void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)  	if("close all" == action)  	{  		LLNotificationWellWindow::getInstance()->closeAll(); +		LLIMWellWindow::getInstance()->closeAll();  	}  } @@ -429,14 +430,12 @@ void LLChicletPanel::onMessageCountChanged(const LLSD& data)  {      // *TODO : we either suppress this method or return a value. Right now, it servers no purpose.      /* -	LLUUID session_id = data["session_id"].asUUID(); -	S32 unread = data["participant_unread"].asInteger(); -	LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id); -	if (im_floater && im_floater->getVisible() && im_floater->hasFocus()) -	{ -		unread = 0; -	} +	//LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id); +	//if (im_floater && im_floater->getVisible() && im_floater->hasFocus()) +	//{ +	//	unread = 0; +	//}      */  } diff --git a/indra/newview/llclassifiedstatsresponder.cpp b/indra/newview/llclassifiedstatsresponder.cpp index b4da31895f..e3cd83e174 100644 --- a/indra/newview/llclassifiedstatsresponder.cpp +++ b/indra/newview/llclassifiedstatsresponder.cpp @@ -62,8 +62,7 @@ void LLClassifiedStatsResponder::result(const LLSD& content)  }  /*virtual*/ -void LLClassifiedStatsResponder::error(U32 status, const std::string& reason) +void LLClassifiedStatsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	llinfos << "LLClassifiedStatsResponder::error(" -		<< status << ": " << reason << ")" << llendl; +	llinfos << "LLClassifiedStatsResponder::error [status:" << status << "]: " << content << llendl;  } diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h index 3db1868cb2..06dcb62fd0 100644 --- a/indra/newview/llclassifiedstatsresponder.h +++ b/indra/newview/llclassifiedstatsresponder.h @@ -39,7 +39,7 @@ public:  	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 void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  protected:  	LLUUID mClassifiedID; diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index e9c7a3fa03..e86d6930e8 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -139,8 +139,7 @@ protected:  	{  		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; -		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1); -		registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, mUUIDs)); +		registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));  		return createFromFile("menu_cof_attachment.xml");  	} @@ -173,9 +172,8 @@ protected:  		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;  		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;  		LLUUID selected_id = mUUIDs.back(); -		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1); -		registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs)); +		registrar.add("Clothing.TakeOff", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));  		registrar.add("Clothing.Replace", boost::bind(replaceWearable, selected_id));  		registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));  		registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id)); diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 5b942f283a..f1f7da5fd1 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -241,8 +241,8 @@ void LLColorSwatchCtrl::draw()  	{  		if (!mFallbackImageName.empty())  		{ -			LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, TRUE,  -				LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +			LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, FTT_LOCAL_FILE, TRUE,  +				LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);  			if( fallback_image->getComponents() == 4 )  			{	  				gl_rect_2d_checkerboard( interior ); diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 4f5f9e22b6..4588424474 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -161,18 +161,6 @@ BOOL LLFloaterScriptQueue::start()  {  	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()); diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 956abcd586..b6c53e5e30 100755 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -120,7 +120,7 @@ void LLConversationViewSession::setFlashState(bool flash_state)  void LLConversationViewSession::startFlashing()  { -	if (mFlashStateOn && !mFlashStarted) +	if (isInVisibleChain() && mFlashStateOn && !mFlashStarted)  	{  		mFlashStarted = true;  		mFlashTimer->startFlashing(); diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index 1e03582a29..d7d9f82910 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -327,6 +327,8 @@ BOOL LLDirPicker::getDir(std::string* filename)  		return FALSE;  	} +#if !LL_MESA_HEADLESS +  	if (mFilePicker)  	{  		GtkWindow* picker = mFilePicker->buildFilePicker(false, true, @@ -340,6 +342,8 @@ BOOL LLDirPicker::getDir(std::string* filename)  		   return (!mFilePicker->getFirstFile().empty());  		}  	} +#endif // !LL_MESA_HEADLESS +  	return FALSE;  } diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp index be20adeb8a..82affcf068 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.cpp +++ b/indra/newview/lldonotdisturbnotificationstorage.cpp @@ -132,6 +132,8 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()  {  	LLFastTimer _(FTM_LOAD_DND_NOTIFICATIONS); +	LL_INFOS("LLDoNotDisturbNotificationStorage") << "start loading notifications" << LL_ENDL; +  	LLSD input;  	if (!readNotifications(input) ||input.isUndefined())  	{ @@ -225,6 +227,8 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()      //writes out empty .xml file (since LLCommunicationChannel::mHistory is empty)  	saveNotifications(); + +	LL_INFOS("LLDoNotDisturbNotificationStorage") << "finished loading notifications" << LL_ENDL;  }  void LLDoNotDisturbNotificationStorage::updateNotifications() diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 4b0d3b361d..bb1d263670 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -511,7 +511,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; @@ -1237,7 +1236,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(); diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 1b0b11298c..e8d43c8631 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -153,7 +153,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) ;  		} diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 9bc32fddbd..0adb42428d 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -69,7 +69,8 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :  	sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");  	sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");  	mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga",  -													TRUE, LLViewerTexture::BOOST_UI,  +													FTT_LOCAL_FILE, +													TRUE, LLGLTexture::BOOST_UI,   													LLViewerTexture::FETCHED_TEXTURE,  													format, int_format,  													LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb")); @@ -78,7 +79,8 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :  	mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);  	m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c",  -													TRUE, LLViewerTexture::BOOST_UI,  +													FTT_LOCAL_FILE, +													TRUE, LLGLTexture::BOOST_UI,   													LLViewerTexture::FETCHED_TEXTURE,  													format, int_format,  													LLUUID("38b86f85-2575-52a9-a531-23108d8da837")); @@ -86,7 +88,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);  } @@ -170,7 +172,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  	} diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 4f6eaa5a5b..5ddc15df42 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -66,11 +66,11 @@ LLVector3 LLDrawPoolWater::sLightDir;  LLDrawPoolWater::LLDrawPoolWater() :  	LLFacePool(POOL_WATER)  { -	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI); +	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);  	gGL.getTexUnit(0)->bind(mHBTex[0]) ;  	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI); +	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);  	gGL.getTexUnit(0)->bind(mHBTex[1]);  	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index fa42b157a7..29ad4f34d2 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -107,7 +107,7 @@ void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum  	{  		setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);  	} -	createGLTexture(0, raw_image, 0, TRUE, LLViewerTexture::DYNAMIC_TEX); +	createGLTexture(0, raw_image, 0, TRUE, LLGLTexture::DYNAMIC_TEX);  	setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);  	mGLTexturep->setGLTextureCreated(false);  } diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index c51e7d1e1a..d287ae6eeb 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -72,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; } diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp index 7ed22d68f6..2669b0340f 100644 --- a/indra/newview/llestateinfomodel.cpp +++ b/indra/newview/llestateinfomodel.cpp @@ -65,12 +65,12 @@ void LLEstateInfoModel::sendEstateInfo()  	}  } -bool LLEstateInfoModel::getUseFixedSun()			const {	return mFlags & REGION_FLAGS_SUN_FIXED;				} -bool LLEstateInfoModel::getIsExternallyVisible()	const {	return mFlags & REGION_FLAGS_EXTERNALLY_VISIBLE;	} -bool LLEstateInfoModel::getAllowDirectTeleport()	const {	return mFlags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT;	} -bool LLEstateInfoModel::getDenyAnonymous()			const {	return mFlags & REGION_FLAGS_DENY_ANONYMOUS; 		} -bool LLEstateInfoModel::getDenyAgeUnverified()		const {	return mFlags & REGION_FLAGS_DENY_AGEUNVERIFIED;	} -bool LLEstateInfoModel::getAllowVoiceChat()			const {	return mFlags & REGION_FLAGS_ALLOW_VOICE;			} +bool LLEstateInfoModel::getUseFixedSun()			const {	return getFlag(REGION_FLAGS_SUN_FIXED);				} +bool LLEstateInfoModel::getIsExternallyVisible()	const {	return getFlag(REGION_FLAGS_EXTERNALLY_VISIBLE);	} +bool LLEstateInfoModel::getAllowDirectTeleport()	const {	return getFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT);	} +bool LLEstateInfoModel::getDenyAnonymous()			const {	return getFlag(REGION_FLAGS_DENY_ANONYMOUS); 		} +bool LLEstateInfoModel::getDenyAgeUnverified()		const {	return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED);	} +bool LLEstateInfoModel::getAllowVoiceChat()			const {	return getFlag(REGION_FLAGS_ALLOW_VOICE);			}  void LLEstateInfoModel::setUseFixedSun(bool val)			{ setFlag(REGION_FLAGS_SUN_FIXED, 				val);	}  void LLEstateInfoModel::setIsExternallyVisible(bool val)	{ setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE,		val);	} @@ -122,9 +122,9 @@ public:  	}  	// if we get an error response -	virtual void error(U32 status, const std::string& reason) +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ -		llwarns << "Failed to commit estate info (" << status << "): " << reason << llendl; +		llwarns << "Failed to commit estate info [status:" << status << "]: " << content << llendl;  	}  }; @@ -199,18 +199,6 @@ void LLEstateInfoModel::commitEstateInfoDataserver()  	gAgent.sendMessage();  } -void LLEstateInfoModel::setFlag(U32 flag, bool val) -{ -	if (val) -	{ -		mFlags |= flag; -	} -	else -	{ -		mFlags &= ~flag; -	} -} -  std::string LLEstateInfoModel::getInfoDump()  {  	LLSD dump; diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h index 56391eda91..538f2f7c75 100644 --- a/indra/newview/llestateinfomodel.h +++ b/indra/newview/llestateinfomodel.h @@ -85,19 +85,38 @@ protected:  private:  	bool commitEstateInfoCaps();  	void commitEstateInfoDataserver(); -	U32  getFlags() const { return mFlags; } -	void setFlag(U32 flag, bool val); +	inline bool getFlag(U64 flag) const; +	inline void setFlag(U64 flag, bool val); +	U64  getFlags() const { return mFlags; }  	std::string getInfoDump();  	// estate info  	std::string	mName;			/// estate name  	LLUUID		mOwnerID;		/// estate owner id  	U32			mID;			/// estate id -	U32			mFlags;			/// estate flags +	U64			mFlags;			/// estate flags  	F32			mSunHour;		/// estate sun hour  	update_signal_t mUpdateSignal; /// emitted when we receive update from sim  	update_signal_t mCommitSignal; /// emitted when our update gets applied to sim  }; +inline bool LLEstateInfoModel::getFlag(U64 flag) const +{ +	return ((mFlags & flag) != 0); +} + +inline void LLEstateInfoModel::setFlag(U64 flag, bool val) +{ +	if (val) +	{ +		mFlags |= flag; +	} +	else +	{ +		mFlags &= ~flag; +	} +} + +  #endif // LL_LLESTATEINFOMODEL_H diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index 2c786b7f8b..e0f7223a8c 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -62,7 +62,7 @@ namespace  		void handleMessage(const LLSD& content); -		virtual	void error(U32 status, const std::string& reason); +		virtual	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  		virtual	void result(const LLSD&	content);  		virtual void completedRaw(U32 status, @@ -187,7 +187,7 @@ namespace  	}  	//virtual -	void LLEventPollResponder::error(U32 status, const	std::string& reason) +	void LLEventPollResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{  		if (mDone) return; @@ -207,13 +207,13 @@ namespace  										+ mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC  									, this); -			llwarns << "Unexpected HTTP error.  status: " << status << ", reason: " << reason << llendl; +			llwarns << "LLEventPollResponder error [status:" << status << "]: " << content << llendl;  		}  		else  		{ -			llwarns <<	"LLEventPollResponder::error: <" << mCount << "> got " -					<<	status << ": " << reason -					<<	(mDone ? " -- done"	: "") << llendl; +			llwarns << "LLEventPollResponder error <" << mCount  +					<< "> [status:" << status << "]: " << content +					<< (mDone ? " -- done" : "") << llendl;  			stop();  			// At this point we have given up and the viewer will not receive HTTP messages from the simulator. diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 28e4b32793..281f852b0a 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -555,8 +555,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; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 4dfb93f1bc..fbf72b1a85 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -368,7 +368,7 @@ void LLFastTimerView::draw()  	S32 left, top, right, bottom;  	S32 x, y, barw, barh, dx, dy; -	S32 texth, textw; +	S32 texth;  	LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("Rounded_Square");  	// Draw the window background @@ -399,7 +399,6 @@ void LLFastTimerView::draw()  		tdesc = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]);  		LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -		textw = LLFontGL::getFontMonospace()->getWidth(tdesc);  		x = xleft, y -= (texth + 2);  		tdesc = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]); @@ -526,8 +525,6 @@ void LLFastTimerView::draw()  			y -= (texth + 2); -			textw = dx + LLFontGL::getFontMonospace()->getWidth(idp->getName()) + 40; -  			if (idp->getCollapsed())   			{  				it.skipDescendants(); @@ -1073,7 +1070,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t  	{ //read base log into memory  		S32 i = 0;  		std::ifstream is(base.c_str()); -		while (!is.eof() && LLSDSerialize::fromXML(cur, is)) +		while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))  		{  			base_data[i++] = cur;  		} @@ -1086,7 +1083,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t  	{ //read current log into memory  		S32 i = 0;  		std::ifstream is(target.c_str()); -		while (!is.eof() && LLSDSerialize::fromXML(cur, is)) +		while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))  		{  			cur_data[i++] = cur; @@ -1377,7 +1374,7 @@ LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is)  	stats_map_t time_stats;  	stats_map_t sample_stats; -	while (!is.eof() && LLSDSerialize::fromXML(cur, is)) +	while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))  	{  		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)  		{ diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index e30dd51acb..6d90667194 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -1649,7 +1649,6 @@ void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array  	gInventory.notifyObservers();  } -  // See also LLInventorySort where landmarks in the Favorites folder are sorted.  class LLViewerInventoryItemSort  { diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index e000adc4aa..f06e9b9b64 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -161,7 +161,7 @@ private:  	boost::signals2::connection mEndDragConnection;  }; - +/*  class AddFavoriteLandmarkCallback : public LLInventoryCallback  {  public: @@ -173,7 +173,7 @@ private:  	LLUUID mTargetLandmarkId;  }; - +*/  /**   * Class to store sorting order of favorites landmarks in a local file. EXT-3985.   * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix. @@ -272,5 +272,4 @@ private:  	};  }; -  #endif // LL_LLFAVORITESBARCTRL_H diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 4bf5b26b3b..d13f85baa2 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -1103,6 +1103,7 @@ void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer  GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context)  { +#ifndef LL_MESA_HEADLESS  	if (LLWindowSDL::ll_try_gtk_init())  	{  		GtkWidget *win = NULL; @@ -1174,6 +1175,9 @@ GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::stri  	{  		return NULL;  	} +#else +	return NULL; +#endif //LL_MESA_HEADLESS  }  static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter, @@ -1473,7 +1477,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename  	return FALSE;  } -BOOL LLFilePicker::getOpenFile( ELoadFilter filter ) +BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )  {  	// if local file browsing is turned off, return without opening dialog  	// (Even though this is a stub, I think we still should not return anything at all) @@ -1494,7 +1498,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )  	default: break;  	}  	mFiles.push_back(filename); -	llinfos << "getOpenFile: Will try to open file: " << hackyfilename << llendl; +	llinfos << "getOpenFile: Will try to open file: " << filename << llendl;  	return TRUE;  } diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index a5ee4607a1..caad0afec0 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -270,9 +270,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; diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp index 2939d31087..3c40e2d4bc 100644 --- a/indra/newview/llfloaterauction.cpp +++ b/indra/newview/llfloaterauction.cpp @@ -38,6 +38,7 @@  #include "message.h"  #include "llagent.h" +#include "llassetstorage.h"  #include "llcombobox.h"  #include "llestateinfomodel.h"  #include "llmimetypes.h" diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index f7dd4a4a6b..3e0e82b579 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -483,8 +483,7 @@ public:  		}  		else  		{ -			llinfos << "avatar picker failed " << status -					<< " reason " << reason << llendl; +			llwarns << "avatar picker failed [status:" << status << "]: " << content << llendl;  		}  	} diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index 4e10b4fc2c..048837acfe 100644 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -32,12 +32,13 @@  #include "llagent.h"  #include "llagentwearables.h" +#include "llviewerwearable.h"  #include "lltexturectrl.h"  #include "lluictrlfactory.h"  #include "llviewerobjectlist.h"  #include "llvoavatarself.h" -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines;  LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLSD& id)    : LLFloater(id), @@ -53,7 +54,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<LLTextureCtrl>(tex_name);  	}  	mTitle = getTitle(); @@ -75,13 +76,13 @@ static void update_texture_ctrl(LLVOAvatar* avatarp,  								 ETextureIndex te)  {  	LLUUID id = IMG_DEFAULT_AVATAR; -	const LLVOAvatarDictionary::TextureEntry* tex_entry = LLVOAvatarDictionary::getInstance()->getTexture(te); +	const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);  	if (tex_entry->mIsLocalTexture)  	{  		if (avatarp->isSelf())  		{  			const LLWearableType::EType wearable_type = tex_entry->mWearableType; -			LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0); +			LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);  			if (wearable)  			{  				LLLocalTextureObject *lto = wearable->getLocalTextureObject(te); @@ -163,17 +164,17 @@ void LLFloaterAvatarTextures::onClickDump(void* data)  			const LLTextureEntry* te = avatarp->getTE(i);  			if (!te) continue; -			const LLVOAvatarDictionary::TextureEntry* tex_entry = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)(i)); +			const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)(i));  			if (!tex_entry)  				continue;  			if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i))  			{  				LLUUID id = IMG_DEFAULT_AVATAR; -				LLWearableType::EType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType((ETextureIndex)i); +				LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType((ETextureIndex)i);  				if (avatarp->isSelf())  				{ -					LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0); +					LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);  					if (wearable)  					{  						LLLocalTextureObject *lto = wearable->getLocalTextureObject(i); diff --git a/indra/newview/llfloateravatartextures.h b/indra/newview/llfloateravatartextures.h index 85ff545855..02474a10e1 100644 --- a/indra/newview/llfloateravatartextures.h +++ b/indra/newview/llfloateravatartextures.h @@ -30,7 +30,7 @@  #include "llfloater.h"  #include "lluuid.h"  #include "llstring.h" -#include "llvoavatardefines.h" +#include "llavatarappearancedefines.h"  class LLTextureCtrl; @@ -51,7 +51,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/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index fffd724b22..aa6ace2a61 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -40,6 +40,7 @@  #include "llcheckboxctrl.h"  #include "llinventorydefines.h"  #include "llinventoryfunctions.h" +#include "llinventoryicon.h"  #include "llinventorymodel.h"	// for gInventory  #include "llfirstuse.h"  #include "llfloaterreg.h" diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 8223e89b64..42857b2aa2 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -538,7 +538,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()  	LLTextBox* resellable_clause = getChild<LLTextBox>("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"));  		} @@ -551,7 +551,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()  	LLTextBox* changeable_clause = getChild<LLTextBox>("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/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 62848586cd..f2deb6a805 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -1102,12 +1102,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/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index 38abdcc830..fe6223fbf5 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -164,9 +164,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; @@ -210,7 +210,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; @@ -231,13 +231,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. @@ -341,6 +351,7 @@ void LLFloaterGodTools::sendGodUpdateRegionInfo()  		LLMessageSystem *msg = gMessageSystem;  		LLPanelRegionTools *rtool = god_tools->mPanelRegionTools; +		U64 region_flags = computeRegionFlags();  		msg->newMessage("GodUpdateRegionInfo");  		msg->nextBlockFast(_PREHASH_AgentData);  		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); @@ -349,11 +360,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();  	} @@ -434,7 +448,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(); @@ -562,9 +576,9 @@ S32 LLPanelRegionTools::getGridPosY() const  	return getChild<LLUICtrl>("gridposy")->getValue().asInteger();  } -U32 LLPanelRegionTools::getRegionFlags() const +U64 LLPanelRegionTools::getRegionFlags() const  { -	U32 flags = 0x0; +	U64 flags = 0x0;  	flags = getChild<LLUICtrl>("check prelude")->getValue().asBoolean()    					? set_prelude_flags(flags)  					: unset_prelude_flags(flags); @@ -601,9 +615,9 @@ U32 LLPanelRegionTools::getRegionFlags() const  	return flags;  } -U32 LLPanelRegionTools::getRegionFlagsMask() const +U64 LLPanelRegionTools::getRegionFlagsMask() const  { -	U32 flags = 0xffffffff; +	U64 flags = 0xFFFFFFFFFFFFFFFFULL;  	flags = getChild<LLUICtrl>("check prelude")->getValue().asBoolean()  				? set_prelude_flags(flags)  				: unset_prelude_flags(flags); @@ -684,7 +698,7 @@ void LLPanelRegionTools::setParentEstateID(U32 id)  	getChild<LLUICtrl>("parentestate")->setValue((S32)id);  } -void LLPanelRegionTools::setCheckFlags(U32 flags) +void LLPanelRegionTools::setCheckFlags(U64 flags)  {  	getChild<LLUICtrl>("check prelude")->setValue(is_prelude(flags) ? TRUE : FALSE);  	getChild<LLUICtrl>("check fixed sun")->setValue(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE); @@ -943,7 +957,7 @@ void LLPanelObjectTools::refresh()  } -U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const +U64 LLPanelObjectTools::computeRegionFlags(U64 flags) const  {  	if (getChild<LLUICtrl>("disable scripts")->getValue().asBoolean())  	{ @@ -973,7 +987,7 @@ U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const  } -void LLPanelObjectTools::setCheckFlags(U32 flags) +void LLPanelObjectTools::setCheckFlags(U64 flags)  {  	getChild<LLUICtrl>("disable scripts")->setValue(flags & REGION_FLAGS_SKIP_SCRIPTS ? TRUE : FALSE);  	getChild<LLUICtrl>("disable collisions")->setValue(flags & REGION_FLAGS_SKIP_COLLISIONS ? TRUE : FALSE); diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h index 1aa8b838fb..cbaeee7051 100644 --- a/indra/newview/llfloatergodtools.h +++ b/indra/newview/llfloatergodtools.h @@ -98,7 +98,7 @@ private:  	~LLFloaterGodTools();  protected: -	U32 computeRegionFlags() const; +	U64 computeRegionFlags() const;  protected: @@ -147,8 +147,8 @@ public:  	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; @@ -160,7 +160,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); @@ -168,7 +168,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(); @@ -218,10 +218,10 @@ 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);  	void onChangeAnything();  	void onApplyChanges(); diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 2575f6f817..52e678ce24 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -593,7 +593,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)  	{ @@ -612,9 +612,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<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));  	mTargetMesh->setTestTexture(mTextureName);  	mTargetMesh->setVisible(TRUE, FALSE);  	mCameraDistance = distance; @@ -631,7 +631,7 @@ void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name)  {  	if (mDummyAvatar)  	{ -		LLViewerJointMesh *mesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name); +		LLViewerJointMesh *mesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));  		// clear out existing test mesh  		if (mesh)  		{ diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 5e0cd8ef78..58817485fb 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -585,6 +585,28 @@ void LLFloaterIMContainer::returnFloaterToHost()  	floater->onTearOffClicked();  } +void LLFloaterIMContainer::setMinimized(BOOL b) +{ +	bool was_minimized = isMinimized(); +	LLMultiFloater::setMinimized(b); + +	//Switching from minimized to un-minimized +	if(was_minimized && !b) +	{ +		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession); + +		if(session_floater && !session_floater->isTornOff()) +		{ +			//When in DND mode, remove stored IM notifications +			//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal +			if(gAgent.isDoNotDisturb() && mSelectedSession.notNull()) +			{ +				LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSelectedSession); +			} +		} +	} +} +  void LLFloaterIMContainer::setVisible(BOOL visible)  {	LLFloaterIMNearbyChat* nearby_chat;  	if (visible) @@ -597,10 +619,21 @@ void LLFloaterIMContainer::setVisible(BOOL visible)  			// *TODO: find a way to move this to XML as a default panel or something like that  			LLSD name("nearby_chat");  			LLFloaterReg::toggleInstanceOrBringToFront(name); -            setSelectedSession(LLUUID(NULL)); +            selectConversationPair(LLUUID(NULL), false, false);  		}  		openNearbyChat(); -        selectConversationPair(getSelectedSession(), false, false); +		flashConversationItemWidget(mSelectedSession,false); + +		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession); +		if(session_floater && !session_floater->isMinimized()) +		{ +			//When in DND mode, remove stored IM notifications +			//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal +			if(gAgent.isDoNotDisturb() && mSelectedSession.notNull()) +			{ +				LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSelectedSession); +			} +		}  	}  	nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); @@ -626,6 +659,12 @@ void LLFloaterIMContainer::setVisible(BOOL visible)  	LLMultiFloater::setVisible(visible);  } +void LLFloaterIMContainer::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key) +{ +	LLMultiFloater::setVisibleAndFrontmost(take_focus, key); +    selectConversationPair(getSelectedSession(), false, take_focus); +} +  void LLFloaterIMContainer::updateResizeLimits()  {  	LLMultiFloater::updateResizeLimits(); @@ -1331,7 +1370,10 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)      selectConversationPair(session_id, true);      LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id); -    session_floater->restoreFloater(); +    if (session_floater) +    { +        session_floater->restoreFloater(); +    }  }  void LLFloaterIMContainer::clearAllFlashStates() @@ -1380,13 +1422,6 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool      		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);      		mConversationsRoot->scrollToShowSelection();      	} - -        //When in DND mode, remove stored IM notifications -        //Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal -        if(gAgent.isDoNotDisturb() && session_id.notNull()) -        { -            LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, session_id); -        }      }      /* floater processing */ @@ -1411,14 +1446,19 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool  			{  				showStub(true);  			} + +			//When in DND mode, remove stored IM notifications +			//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal +			if(gAgent.isDoNotDisturb() && session_id.notNull()) +			{ +				LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, session_id); +			}  		}  		// Set the focus on the selected floater -		if (!session_floater->hasFocus()) +		if (!session_floater->hasFocus() && !session_floater->isMinimized())  		{ -			BOOL is_minimized = session_floater->isMinimized();  			session_floater->setFocus(focus_floater); -			session_floater->setMinimized(is_minimized);  		}  	}  	flashConversationItemWidget(session_id,false); @@ -1963,10 +2003,13 @@ bool LLFloaterIMContainer::selectNextorPreviousConversation(bool select_next, bo  void LLFloaterIMContainer::expandConversation()  { -	LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession())); -	if (widget) +	if(!mConversationsPane->isCollapsed())  	{ -		widget->setOpen(!widget->isOpen()); +		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession())); +		if (widget) +		{ +			widget->setOpen(!widget->isOpen()); +		}  	}  } @@ -1974,8 +2017,11 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)  {  	// Always unminimize before trying to close.  	// Most of the time the user will never see this state. -	setMinimized(FALSE); - +	if(isMinimized()) +	{ +		LLMultiFloater::setMinimized(FALSE); +	} +	  	LLFloater::closeFloater(app_quitting);  } diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 2cbc1e99f9..e39d20ec35 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -59,7 +59,9 @@ public:  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key);  	/*virtual*/ void draw(); +	/*virtual*/ void setMinimized(BOOL b);  	/*virtual*/ void setVisible(BOOL visible); +	/*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());  	/*virtual*/ void updateResizeLimits();  	void onCloseFloater(LLUUID& id); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index b287950c21..49f36a2f32 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -264,7 +264,7 @@ void LLFloaterIMNearbyChat::setVisibleAndFrontmost(BOOL take_focus, const LLSD&  	if(!isTornOff() && matchesKey(key))  	{ -		LLFloaterIMContainer::getInstance()->selectConversationPair(mSessionID, true, false); +		LLFloaterIMContainer::getInstance()->selectConversationPair(mSessionID, true, take_focus);  	}  } @@ -283,6 +283,11 @@ void LLFloaterIMNearbyChat::onTearOffClicked()  void LLFloaterIMNearbyChat::onOpen(const LLSD& key)  {  	LLFloaterIMSessionTab::onOpen(key); +	if(!isMessagePaneExpanded()) +	{ +		restoreFloater(); +		onCollapseToLine(this); +	}  	showTranslationCheckbox(LLTranslate::isTranslationConfigured());  } @@ -322,10 +327,7 @@ void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)  void LLFloaterIMNearbyChat::show()  { -	if (isChatMultiTab()) -	{  		openFloater(getKey()); -	}  }  bool LLFloaterIMNearbyChat::isChatVisible() const @@ -480,11 +482,14 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke()  		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))  		{  			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); -			mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part +			if (!rest_of_match.empty()) +			{ +				mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part -			// Select to end of line, starting from the character -			// after the last one the user typed. -			mInputEditor->selectNext(rest_of_match, false); +				// Select to end of line, starting from the character +				// after the last one the user typed. +				mInputEditor->selectNext(rest_of_match, false); +			}  		}  		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))  		{ @@ -741,15 +746,14 @@ void LLFloaterIMNearbyChat::startChat(const char* line)  	{  		if(!nearby_chat->isTornOff())  		{ -			nearby_chat->show(); +			LLFloaterIMContainer::getInstance()->selectConversation(LLUUID(NULL));  		}  		if(nearby_chat->isMinimized())  		{  			nearby_chat->setMinimized(false);  		} -		nearby_chat->setVisible(TRUE); +		nearby_chat->show();  		nearby_chat->setFocus(TRUE); -		nearby_chat->mInputEditor->setFocus(TRUE);  		if (line)  		{ diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index 7afcf288ce..9ce5e12897 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -559,9 +559,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,      LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); -	if(( nearby_chat->hasFocus() -        || im_box->hasFocus() -		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT +	if((  ( chat_msg.mSourceType == CHAT_SOURCE_AGENT  			&& gSavedSettings.getBOOL("UseChatBubbles") )  		|| mChannel.isDead()  		|| !mChannel.get()->getShowToasts() ) @@ -606,17 +604,20 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,  			toast_msg = chat_msg.mText;  		} -		//Don't show nearby toast, if conversation is visible but not focused -		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(LLUUID()); -		if (session_floater && session_floater->isMessagePaneExpanded() -		    && session_floater->isInVisibleChain() && !session_floater->isMinimized() -		    && !(session_floater->getHost() && session_floater->getHost()->isMinimized())) +		//Don't show nearby toast, if conversation is visible and selected +		if ((nearby_chat->hasFocus()) || +		    ((im_box->getSelectedSession().isNull() && +				((LLFloater::isVisible(im_box) && !im_box->isMinimized() && im_box->isFrontmost()) +						|| (LLFloater::isVisible(nearby_chat) && !nearby_chat->isMinimized() && nearby_chat->isFrontmost())))))  		{ -			return; +			if(nearby_chat->isMessagePaneExpanded()) +			{ +				return; +			}  		}          //Will show toast when chat preference is set         -        if((gSavedSettings.getString("NotificationNearbyChatOptions") == "toast") || !session_floater->isMessagePaneExpanded()) +        if((gSavedSettings.getString("NotificationNearbyChatOptions") == "toast") || !nearby_chat->isMessagePaneExpanded())          {              // Add a nearby chat toast.              LLUUID id; diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 73adfd0eda..8ec85e1160 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -39,6 +39,7 @@  #include "llchannelmanager.h"  #include "llchiclet.h"  #include "llchicletbar.h" +#include "lldonotdisturbnotificationstorage.h"  #include "llfloaterreg.h"  #include "llfloateravatarpicker.h"  #include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container @@ -618,6 +619,8 @@ void LLFloaterIMSession::onClose(bool app_quitting)  	// Last change:  	// EXT-3516 X Button should end IM session, _ button should hide  	gIMMgr->leaveSession(mSessionID); +    // *TODO: Study why we need to restore the floater before we close it. +    // Might be because we want to save some state data in some clean open state.  	LLFloaterIMSessionTab::restoreFloater();  	// Clean up the conversation *after* the session has been ended  	LLFloaterIMSessionTab::onClose(app_quitting); @@ -643,6 +646,23 @@ void LLFloaterIMSession::setDocked(bool docked, bool pop_on_undock)  	}  } +void LLFloaterIMSession::setMinimized(BOOL b) +{ +	bool wasMinimized = isMinimized(); +	LLFloaterIMSessionTab::setMinimized(b); + +	//Switching from minimized state to un-minimized state +	if(wasMinimized && !b) +	{ +		//When in DND mode, remove stored IM notifications +		//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal +		if(gAgent.isDoNotDisturb()) +		{ +			LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSessionID); +		} +	} +} +  void LLFloaterIMSession::setVisible(BOOL visible)  {  	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> @@ -711,6 +731,18 @@ BOOL LLFloaterIMSession::getVisible()  	return visible;  } +void LLFloaterIMSession::setFocus(BOOL focus) +{ +	LLFloaterIMSessionTab::setFocus(focus); + +	//When in DND mode, remove stored IM notifications +	//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal +	if(focus && gAgent.isDoNotDisturb()) +	{ +		LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSessionID); +	} +} +  //static  bool LLFloaterIMSession::toggle(const LLUUID& session_id)  { @@ -1123,9 +1155,10 @@ public:  		mSessionID = session_id;  	} -	void error(U32 statusNum, const std::string& reason) +	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)  	{ -		llinfos << "Error inviting all agents to session" << llendl; +		llwarns << "Error inviting all agents to session [status:"  +				<< statusNum << "]: " << content << llendl;  		//throw something back to the viewer here?  	} diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index cb330bca0f..a0e0171b34 100644 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -65,8 +65,10 @@ public:  	// LLView overrides  	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void setMinimized(BOOL b);  	/*virtual*/ void setVisible(BOOL visible);  	/*virtual*/ BOOL getVisible(); +	/*virtual*/ void setFocus(BOOL focus);  	// Check typing timeout timer.  	/*virtual*/ void draw(); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index eab2ce7798..ce6e639305 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -64,6 +64,8 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)    , mHasVisibleBeenInitialized(false)    , mIsParticipantListExpanded(true)    , mChatLayoutPanel(NULL) +  , mInputPanels(NULL) +  , mChatLayoutPanelHeight(0)  {      setAutoFocus(FALSE);  	mSession = LLIMModel::getInstance()->findIMSession(mSessionID); @@ -132,6 +134,12 @@ void LLFloaterIMSessionTab::setVisible(BOOL visible)  			LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true);  		}  		LLFloaterIMSessionTab::addToHost(mSessionID); +		LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(mSessionID); + +		if (conversp && conversp->isNearbyChat() && gSavedPerAccountSettings.getBOOL("NearbyChatIsNotCollapsed")) +		{ +			onCollapseToLine(this); +		}  		mInputButtonPanel->setVisible(isTornOff());  	} @@ -259,13 +267,15 @@ BOOL LLFloaterIMSessionTab::postBuild()  	mInputEditor = getChild<LLChatEntry>("chat_editor");  	mChatLayoutPanel = getChild<LLLayoutPanel>("chat_layout_panel"); +	mInputPanels = getChild<LLLayoutStack>("input_panels");  	mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatLayoutPanel, this));  	mInputEditor->setCommitOnFocusLost( FALSE );  	mInputEditor->setPassDelete(TRUE);  	mInputEditor->setFont(LLViewerChat::getChatFont()); -	mInputEditorPad = mChatLayoutPanel->getRect().getHeight() - mInputEditor->getRect().getHeight(); +	mChatLayoutPanelHeight = mChatLayoutPanel->getRect().getHeight(); +	mInputEditorPad = mChatLayoutPanelHeight - mInputEditor->getRect().getHeight();  	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE); @@ -356,7 +366,7 @@ void LLFloaterIMSessionTab::draw()  		// Restart the refresh timer  		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);  	} -	 +  	LLTransientDockableFloater::draw();  } @@ -698,10 +708,12 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()  			&& !mIsP2PChat;  	mParticipantListAndHistoryStack->collapsePanel(mParticipantListPanel, !is_participant_list_visible); +    mParticipantListPanel->setVisible(is_participant_list_visible);  	// Display collapse image (<<) if the floater is hosted  	// or if it is torn off but has an open control panel.  	bool is_expanded = is_not_torn_off || is_participant_list_visible; +      	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));  	mExpandCollapseBtn->setToolTip(  			is_not_torn_off? @@ -741,9 +753,7 @@ void LLFloaterIMSessionTab::forceReshape()  void LLFloaterIMSessionTab::reshapeChatLayoutPanel()  { -	LLRect chat_layout_panel_rect = mChatLayoutPanel->getRect(); -	LLRect input_rect = mInputEditor->getRect(); -	mChatLayoutPanel->reshape(chat_layout_panel_rect.getWidth(), input_rect.getHeight() + mInputEditorPad, FALSE); +	mChatLayoutPanel->reshape(mChatLayoutPanel->getRect().getWidth(), mInputEditor->getRect().getHeight() + mInputEditorPad, FALSE);  }  void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show) @@ -818,14 +828,15 @@ void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)  	{  		if (!self->mIsP2PChat)  		{ +            // The state must toggle the collapsed state of the panel              bool should_be_expanded = self->mParticipantListPanel->isCollapsed(); -			// Expand/collapse the participant list panel -            self->mParticipantListAndHistoryStack->collapsePanel(self->mParticipantListPanel, !should_be_expanded); -            self->mParticipantListPanel->setVisible(should_be_expanded); +			// Update the expand/collapse flag of the participant list panel and save it              gSavedSettings.setBOOL("IMShowControlPanel", should_be_expanded);              self->mIsParticipantListExpanded = should_be_expanded; -			self->mExpandCollapseBtn->setImageOverlay(self->getString(should_be_expanded ? "collapse_icon" : "expand_icon")); +             +            // Refresh for immediate feedback +            self->refreshConversation();  		}  	} @@ -841,6 +852,7 @@ void LLFloaterIMSessionTab::onCollapseToLine(LLFloaterIMSessionTab* self)  		self->mExpandCollapseLineBtn->setImageOverlay(self->getString(expand ? "collapseline_icon" : "expandline_icon"));  		self->mContentPanel->setVisible(!expand);  		self->mToolbarPanel->setVisible(!expand); +		self->mInputEditor->enableSingleLineMode(expand);  		self->reshapeFloater(expand);  		self->setMessagePaneExpanded(!expand);  	} @@ -853,20 +865,20 @@ void LLFloaterIMSessionTab::reshapeFloater(bool collapse)  	if(collapse)  	{  		mFloaterHeight = floater_rect.getHeight(); -		S32 height = mContentPanel->getRect().getHeight() + mToolbarPanel->getRect().getHeight(); +		S32 height = mContentPanel->getRect().getHeight() + mToolbarPanel->getRect().getHeight() +			+ mChatLayoutPanel->getRect().getHeight() - mChatLayoutPanelHeight + 2;  		floater_rect.mTop -= height; -		enableResizeCtrls(true, true, false);  	}  	else  	{  		floater_rect.mTop = floater_rect.mBottom + mFloaterHeight; -		enableResizeCtrls(true, true, true); -  	} +	enableResizeCtrls(true, true, !collapse); + +	saveCollapsedState();  	setShape(floater_rect, true);  	mBodyStack->updateLayout(); -  }  void LLFloaterIMSessionTab::restoreFloater() @@ -885,6 +897,7 @@ void LLFloaterIMSessionTab::restoreFloater()  		mBodyStack->updateLayout();  		mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon"));  		setMessagePaneExpanded(true); +		saveCollapsedState();  		enableResizeCtrls(true, true, true);  	}  } @@ -1060,6 +1073,14 @@ LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem()  	return conversationItem;  } +void LLFloaterIMSessionTab::saveCollapsedState() +{ +	LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(mSessionID); +	if(conversp->isNearbyChat()) +	{ +		gSavedPerAccountSettings.setBOOL("NearbyChatIsNotCollapsed", isMessagePaneExpanded()); +	} +}  BOOL LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask )  {  	if(mask == MASK_ALT) diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index f0899a3c09..302d5a8066 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -101,6 +101,7 @@ public:  	bool isMessagePaneExpanded(){return mMessagePaneExpanded;}  	void setMessagePaneExpanded(bool expanded){mMessagePaneExpanded = expanded;}  	void restoreFloater(); +	void saveCollapsedState();  protected: @@ -174,17 +175,14 @@ protected:  	LLChatHistory* mChatHistory;  	LLChatEntry* mInputEditor;  	LLLayoutPanel * mChatLayoutPanel; -	int mInputEditorPad; // padding between input field and chat history - +	LLLayoutStack * mInputPanels; +	  	LLButton* mExpandCollapseLineBtn;  	LLButton* mExpandCollapseBtn;  	LLButton* mTearOffBtn;  	LLButton* mCloseBtn;  	LLButton* mGearBtn; -	S32 mFloaterHeight; - -  private:  	// Handling selection and contextual menu      void doToSelected(const LLSD& userdata); @@ -208,6 +206,10 @@ private:      bool mHasVisibleBeenInitialized;  	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called. + +	S32 mInputEditorPad; +	S32 mChatLayoutPanelHeight; +	S32 mFloaterHeight;  }; diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index a4ca014fa9..d4355007c1 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -557,7 +557,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;  		} @@ -2120,7 +2120,7 @@ void LLPanelLandOptions::refreshSearch()  			LLViewerParcelMgr::isParcelModifiableByAgent(  				parcel, GP_LAND_FIND_PLACES)  			&& 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 @@ -2873,7 +2873,7 @@ void LLPanelLandCovenant::refresh()  	LLTextBox* resellable_clause = getChild<LLTextBox>("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"));  		} @@ -2886,7 +2886,7 @@ void LLPanelLandCovenant::refresh()  	LLTextBox* changeable_clause = getChild<LLTextBox>("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/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ea839e6f5a..100f1d580b 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -760,7 +760,6 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)  void LLFloaterModelPreview::draw()  {  	LLFloater::draw(); -	LLRect r = getRect();  	mModelPreview->update(); @@ -1684,7 +1683,6 @@ bool LLModelLoader::doLoadModel()  						//If no skeleton, do a breadth-first search to get at specific joints  						bool rootNode = false; -						bool skeletonWithNoRootNode = false;  						//Need to test for a skeleton that does not have a root node  						//This occurs when your instance controller does not have an associated scene  @@ -1695,10 +1693,6 @@ bool LLModelLoader::doLoadModel()  							{  								rootNode = true;  							} -							else  -							{ -								skeletonWithNoRootNode = true; -							}  						}  						if ( !pSkeleton || !rootNode ) @@ -2502,7 +2496,7 @@ void LLModelLoader::loadTextures()  				if(!material.mDiffuseMapFilename.empty())  				{  					material.mDiffuseMap =  -						LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW); +						LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW);  					material.mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE);  					material.mDiffuseMap->forceToSaveRawImage(0, F32_MAX);  					mNumOfFetchingTextures++ ; @@ -5020,16 +5014,9 @@ BOOL LLModelPreview::render()  	bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean();	  	bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean(); -	bool resetJoints = false;  	if ( upload_joints != mLastJointUpdate )  	{ -		if ( mLastJointUpdate ) -		{ -			resetJoints = true; -		} -  		mLastJointUpdate = upload_joints; -  	}  	for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index a28af2101b..bbf88060c1 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -558,7 +558,7 @@ void LLFloaterPreference::apply()  	LLViewerMedia::setCookiesEnabled(getChild<LLUICtrl>("cookies_enabled")->getValue()); -	if (hasChild("web_proxy_enabled") &&hasChild("web_proxy_editor") && hasChild("web_proxy_port")) +	if (hasChild("web_proxy_enabled", TRUE) &&hasChild("web_proxy_editor", TRUE) && hasChild("web_proxy_port", TRUE))  	{  		bool proxy_enable = getChild<LLUICtrl>("web_proxy_enabled")->getValue();  		std::string proxy_address = getChild<LLUICtrl>("web_proxy_editor")->getValue(); @@ -1582,7 +1582,7 @@ void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name)  {  	std::string ctrl_name = name.asString(); -	if ((ctrl_name =="" )|| !hasChild(ctrl_name, true)) +	if ((ctrl_name =="" )|| !hasChild(ctrl_name, TRUE))  		return;  	LLTextBox* text_box = getChild<LLTextBox>(name.asString()); @@ -1819,7 +1819,7 @@ LLPanelPreference::LLPanelPreference()  BOOL LLPanelPreference::postBuild()  {  	////////////////////// PanelGeneral /////////////////// -	if (hasChild("display_names_check")) +	if (hasChild("display_names_check", TRUE))  	{  		BOOL use_people_api = gSavedSettings.getBOOL("UsePeopleAPI");  		LLCheckBoxCtrl* ctrl_display_name = getChild<LLCheckBoxCtrl>("display_names_check"); @@ -1831,7 +1831,7 @@ BOOL LLPanelPreference::postBuild()  	}  	////////////////////// PanelVoice /////////////////// -	if (hasChild("voice_unavailable")) +	if (hasChild("voice_unavailable", TRUE))  	{  		BOOL voice_disabled = gSavedSettings.getBOOL("CmdLineDisableVoice");  		getChildView("voice_unavailable")->setVisible( voice_disabled); @@ -1840,7 +1840,7 @@ BOOL LLPanelPreference::postBuild()  	//////////////////////PanelSkins /////////////////// -	if (hasChild("skin_selection")) +	if (hasChild("skin_selection", TRUE))  	{  		LLFloaterPreference::refreshSkin(this); @@ -1854,28 +1854,28 @@ BOOL LLPanelPreference::postBuild()  	}  	//////////////////////PanelPrivacy /////////////////// -	if (hasChild("media_enabled")) +	if (hasChild("media_enabled", TRUE))  	{  		bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");  		getChild<LLCheckBoxCtrl>("media_enabled")->set(media_enabled);  		getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(media_enabled);  	} -	if (hasChild("music_enabled")) +	if (hasChild("music_enabled", TRUE))  	{  		getChild<LLCheckBoxCtrl>("music_enabled")->set(gSavedSettings.getBOOL("AudioStreamingMusic"));  	} -	if (hasChild("voice_call_friends_only_check")) +	if (hasChild("voice_call_friends_only_check", TRUE))  	{  		getChild<LLCheckBoxCtrl>("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2));  	} -	if (hasChild("favorites_on_login_check")) +	if (hasChild("favorites_on_login_check", TRUE))  	{  		getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&showFavoritesOnLoginWarning, _1, _2));  	}  	//////////////////////PanelAdvanced /////////////////// -	if (hasChild("modifier_combo")) +	if (hasChild("modifier_combo", TRUE))  	{  		//localizing if push2talk button is set to middle mouse  		if (MIDDLE_MOUSE_CV == getChild<LLUICtrl>("modifier_combo")->getValue().asString()) @@ -1885,7 +1885,7 @@ BOOL LLPanelPreference::postBuild()  	}  	//////////////////////PanelSetup /////////////////// -	if (hasChild("max_bandwidth")) +	if (hasChild("max_bandwidth"), TRUE)  	{  		mBandWidthUpdater = new LLPanelPreference::Updater(boost::bind(&handleBandwidthChanged, _1), BANDWIDTH_UPDATER_TIMEOUT);  		gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&LLPanelPreference::Updater::update, mBandWidthUpdater, _2)); diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp index c7fab2573f..3a7ca17b73 100644 --- a/indra/newview/llfloaterregiondebugconsole.cpp +++ b/indra/newview/llfloaterregiondebugconsole.cpp @@ -75,7 +75,7 @@ namespace  	{  	public:  		/* virtual */ -		void error(U32 status, const std::string& reason) +		void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  		{  			sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);  		} diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index e6b76159a1..50c013a49d 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -318,7 +318,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)  	// extract message  	std::string sim_name;  	std::string sim_type = LLTrans::getString("land_type_unknown"); -	U32 region_flags; +	U64 region_flags;  	U8 agent_limit;  	F32 object_bonus_factor;  	U8 sim_access; @@ -328,7 +328,6 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)  	BOOL use_estate_sun;  	F32 sun_hour;  	msg->getString("RegionInfo", "SimName", sim_name); -	msg->getU32("RegionInfo", "RegionFlags", region_flags);  	msg->getU8("RegionInfo", "MaxAgents", agent_limit);  	msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor);  	msg->getU8("RegionInfo", "SimAccess", sim_access); @@ -347,6 +346,17 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)  		LLTrans::findString(sim_type, sim_type); // try localizing sim product name  	} +	if (msg->has(_PREHASH_RegionInfo3)) +	{ +		msg->getU64("RegionInfo3", "RegionFlagsExtended", region_flags); +	} +	else +	{ +		U32 flags = 0; +		msg->getU32("RegionInfo", "RegionFlags", flags); +		region_flags = flags; +	} +  	// GENERAL PANEL  	panel = tab->getChild<LLPanel>("General");  	panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name)); @@ -378,9 +388,9 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)  	panel = tab->getChild<LLPanel>("Debug");  	panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name) ); -	panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_SCRIPTS)) ); -	panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_COLLISIONS)) ); -	panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_PHYSICS)) ); +	panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_SCRIPTS) ? TRUE : FALSE )) ); +	panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_COLLISIONS) ? TRUE : FALSE )) ); +	panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_PHYSICS) ? TRUE : FALSE )) );  	panel->setCtrlsEnabled(allow_modify);  	// TERRAIN PANEL @@ -748,9 +758,10 @@ class ConsoleRequestResponder : public LLHTTPClient::Responder  {  public:  	/*virtual*/ -	void error(U32 status, const std::string& reason) +	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ -		llwarns << "requesting mesh_rez_enabled failed" << llendl; +		llwarns << "ConsoleRequestResponder error requesting mesh_rez_enabled [status:" +				<< status << "]: " << content << llendl;  	}  }; @@ -760,9 +771,10 @@ class ConsoleUpdateResponder : public LLHTTPClient::Responder  {  public:  	/* virtual */ -	void error(U32 status, const std::string& reason) +	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ -		llwarns << "Updating mesh enabled region setting failed" << llendl; +		llwarns << "ConsoleRequestResponder error updating mesh enabled region setting [status:" +				<< status << "]: " << content << llendl;  	}  }; @@ -2239,10 +2251,10 @@ public:  	}  	// if we get an error response -	virtual void error(U32 status, const std::string& reason) +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ -		llinfos << "LLEstateChangeInfoResponder::error " -			<< status << ": " << reason << llendl; +		llinfos << "LLEstateChangeInfoResponder::error [status:" +			<< status << "]: " << content << llendl;  	}  private:  	LLHandle<LLPanel> mpPanel; @@ -2318,7 +2330,7 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)  	LLTextBox* resellable_clause = getChild<LLTextBox>("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"));  		} @@ -2331,7 +2343,7 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)  	LLTextBox* changeable_clause = getChild<LLTextBox>("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/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 0e4c7406c5..35b63c5480 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -111,9 +111,6 @@ LLFloaterReporter::LLFloaterReporter(const LLSD& key)  // static  void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)  { -	U32 region_flags; -	msg->getU32("RegionInfo", "RegionFlags", region_flags); -	  	if ( LLFloaterReg::instanceVisible("reporter") )  	{  		LLNotificationsUtil::add("HelpReportAbuseEmailLL"); @@ -713,7 +710,7 @@ class LLUserReportResponder : public LLHTTPClient::Responder  public:  	LLUserReportResponder(): LLHTTPClient::Responder()  {} -	void error(U32 status, const std::string& reason) +	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{  		// *TODO do some user messaging here  		LLUploadDialog::modalUploadFinished(); @@ -783,8 +780,8 @@ void LLFloaterReporter::takeScreenshot()  	// store in the image list so it doesn't try to fetch from the server  	LLPointer<LLViewerFetchedTexture> image_in_list =  -		LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::FETCHED_TEXTURE); -	image_in_list->createGLTexture(0, raw, 0, TRUE, LLViewerTexture::OTHER); +		LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid); +	image_in_list->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER);  	// the texture picker then uses that texture  	LLTexturePicker* texture = getChild<LLTextureCtrl>("screenshot"); @@ -831,12 +828,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,  		return;  	} -	EReportType report_type = UNKNOWN_REPORT; -	if (data->mPreferredLocation == LLResourceData::INVALID_LOCATION) -	{ -		report_type = COMPLAINT_REPORT; -	} -	else  +	if (data->mPreferredLocation != LLResourceData::INVALID_LOCATION)  	{  		llwarns << "Unknown report type : " << data->mPreferredLocation << llendl;  	} diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp index b691db1049..6c17f62c1e 100644 --- a/indra/newview/llfloaterscriptdebug.cpp +++ b/indra/newview/llfloaterscriptdebug.cpp @@ -105,7 +105,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", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI));  		floater_label = llformat("%s(%.0f, %.0f, %.0f)",  						user_name.c_str(),  						objectp->getPositionRegion().mV[VX], diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 8d8bba7b17..13cb3c2eb0 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -221,9 +221,9 @@ void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content)  	}  } -void fetchScriptLimitsRegionInfoResponder::error(U32 status, const std::string& reason) +void fetchScriptLimitsRegionInfoResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	llwarns << "Error from responder " << reason << llendl; +	llwarns << "fetchScriptLimitsRegionInfoResponder error [status:" << status << "]: " << content << llendl;  }  void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref) @@ -308,9 +308,9 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)  	}  } -void fetchScriptLimitsRegionSummaryResponder::error(U32 status, const std::string& reason) +void fetchScriptLimitsRegionSummaryResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	llwarns << "Error from responder " << reason << llendl; +	llwarns << "fetchScriptLimitsRegionSummaryResponder error [status:" << status << "]: " << content << llendl;  }  void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref) @@ -417,9 +417,9 @@ result (map)  	}  } -void fetchScriptLimitsRegionDetailsResponder::error(U32 status, const std::string& reason) +void fetchScriptLimitsRegionDetailsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	llwarns << "Error from responder " << reason << llendl; +	llwarns << "fetchScriptLimitsRegionDetailsResponder error [status:" << status << "]: " << content << llendl;  }  void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref) @@ -513,9 +513,9 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)  	}  } -void fetchScriptLimitsAttachmentInfoResponder::error(U32 status, const std::string& reason) +void fetchScriptLimitsAttachmentInfoResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	llwarns << "Error from responder " << reason << llendl; +	llwarns << "fetchScriptLimitsAttachmentInfoResponder error [status:" << status << "]: " << content << llendl;  }  ///---------------------------------------------------------------------------- diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h index 9bcfa5fe14..f8732ef94b 100644 --- a/indra/newview/llfloaterscriptlimits.h +++ b/indra/newview/llfloaterscriptlimits.h @@ -89,7 +89,7 @@ class fetchScriptLimitsRegionInfoResponder: public LLHTTPClient::Responder  		fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {};  		void result(const LLSD& content); -		void error(U32 status, const std::string& reason); +		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  	public:  	protected:  		LLSD mInfo; @@ -101,7 +101,7 @@ class fetchScriptLimitsRegionSummaryResponder: public LLHTTPClient::Responder  		fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {};  		void result(const LLSD& content); -		void error(U32 status, const std::string& reason); +		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  	public:  	protected:  		LLSD mInfo; @@ -113,7 +113,7 @@ class fetchScriptLimitsRegionDetailsResponder: public LLHTTPClient::Responder  		fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {};  		void result(const LLSD& content); -		void error(U32 status, const std::string& reason); +		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  	public:  	protected:  		LLSD mInfo; @@ -125,7 +125,7 @@ class fetchScriptLimitsAttachmentInfoResponder: public LLHTTPClient::Responder  		fetchScriptLimitsAttachmentInfoResponder() {};  		void result(const LLSD& content); -		void error(U32 status, const std::string& reason); +		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  	public:  	protected:  }; diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp index 96b5c6b09b..5f9556a870 100644 --- a/indra/newview/llfloatersidepanelcontainer.cpp +++ b/indra/newview/llfloatersidepanelcontainer.cpp @@ -28,10 +28,13 @@  #include "llfloaterreg.h"  #include "llfloatersidepanelcontainer.h" +#include "llpaneleditwearable.h"  // newview includes  #include "llsidetraypanelcontainer.h"  #include "lltransientfloatermgr.h" +#include "llpaneloutfitedit.h" +#include "llsidepanelappearance.h"  //static  const std::string LLFloaterSidePanelContainer::sMainPanelName("main_panel"); @@ -54,6 +57,27 @@ void LLFloaterSidePanelContainer::onOpen(const LLSD& key)  	getChild<LLPanel>(sMainPanelName)->onOpen(key);  } +void LLFloaterSidePanelContainer::onClickCloseBtn() +{ +	LLPanelOutfitEdit* panel_outfit_edit = +		dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfit_edit")); +	if (panel_outfit_edit) +	{ +		LLFloater *parent = gFloaterView->getParentFloater(panel_outfit_edit); +		if (parent == this ) +		{ +			LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance*>(getPanel("appearance")); +			if ( panel_appearance ) +			{ +				panel_appearance->getWearable()->onClose(); +				panel_appearance->showOutfitsInventoryPanel(); +			} +		} +	} +	 +	LLFloater::onClickCloseBtn(); +} +  LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_name, const LLSD& params)  {  	LLView* view = findChildView(panel_name, true); diff --git a/indra/newview/llfloatersidepanelcontainer.h b/indra/newview/llfloatersidepanelcontainer.h index 10d85867ce..491723471f 100644 --- a/indra/newview/llfloatersidepanelcontainer.h +++ b/indra/newview/llfloatersidepanelcontainer.h @@ -51,6 +51,8 @@ public:  	/*virtual*/ void onOpen(const LLSD& key); +	/*virtual*/ void onClickCloseBtn(); +  	LLPanel* openChildPanel(const std::string& panel_name, const LLSD& params);  	static void showPanel(const std::string& floater_name, const LLSD& key); diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 15e0b89f6c..0106a1615d 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -855,7 +855,6 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID)  		LLPanel* panel = LLUICtrlFactory::create<LLPanel>(panel_params);	// create a new panel  		panel->buildFromFile(path);										// build it -		LLRect new_size = panel->getRect();								// get its rectangle  		panel->setOrigin(2,2);											// reset its origin point so it's not offset by -left or other XUI attributes  		(*floaterp)->setTitle(path);									// use the file name as its title, since panels have no guaranteed meaningful name attribute  		panel->setUseBoundingRect(TRUE);								// enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements) diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index a4dfd94496..5c6ce9d311 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -521,7 +521,7 @@ public:  	void fire(const LLUUID& inv_item_id)  	{  		LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); - +		  		if (item)  			LLFriendCardsManager::instance().extractAvatarID(item->getCreatorUUID());  	} @@ -557,7 +557,7 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)  		lldebugs << "Sent create_inventory_item for " << avatarID << ", " << name << llendl;  		// TODO: mantipov: Is CreateFriendCardCallback really needed? Probably not -		LLPointer<LLInventoryCallback> cb = new CreateFriendCardCallback(); +		LLPointer<LLInventoryCallback> cb = new CreateFriendCardCallback;  		create_inventory_callingcard(avatarID, findFriendAllSubfolderUUIDImpl(), cb);  	} diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index f307505ff8..9aa86297fc 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -338,7 +338,7 @@ void LLGestureMgr::deactivateGesture(const LLUUID& item_id)  	gAgent.sendReliableMessage(); -	LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id, false); +	LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id);  	notifyObservers();  } diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 1208c9378e..60fa53f491 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -79,10 +79,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/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp index 188c4bcf25..2d0fc26c2a 100644 --- a/indra/newview/llgroupiconctrl.cpp +++ b/indra/newview/llgroupiconctrl.cpp @@ -29,6 +29,7 @@  #include "llgroupiconctrl.h"  #include "llagent.h" +#include "llviewertexture.h"  /*  #include "llavatarconstants.h"  #include "llcallingcard.h" // for LLAvatarTracker diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 81eb1d397e..cbd844cdac 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -1847,14 +1847,15 @@ public:  		GroupMemberDataResponder() {}  		virtual ~GroupMemberDataResponder() {}  		virtual void result(const LLSD& pContent); -		virtual void error(U32 pStatus, const std::string& pReason); +		virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);  private:  		LLSD mMemberData;  }; -void GroupMemberDataResponder::error(U32 pStatus, const std::string& pReason) +void GroupMemberDataResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)  { -	LL_WARNS("GrpMgr") << "Error receiving group member data." << LL_ENDL; +	LL_WARNS("GrpMgr") << "Error receiving group member data [status:"  +		<< pStatus << "]: " << pContent << LL_ENDL;  }  void GroupMemberDataResponder::result(const LLSD& content) diff --git a/indra/newview/llhomelocationresponder.cpp b/indra/newview/llhomelocationresponder.cpp index 4850d18d99..37428c4a44 100644 --- a/indra/newview/llhomelocationresponder.cpp +++ b/indra/newview/llhomelocationresponder.cpp @@ -97,7 +97,7 @@ void LLHomeLocationResponder::result( const LLSD& content )    }  } -void LLHomeLocationResponder::error( U32 status, const std::string& reason ) +void LLHomeLocationResponder::errorWithContent( U32 status, const std::string& reason, const LLSD& content )  { -  llinfos << "received error(" << reason  << ")" << llendl; +	llwarns << "LLHomeLocationResponder error [status:" << status << "]: " << content << llendl;  } diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h index d640b9c894..9bf4b12c4e 100644 --- a/indra/newview/llhomelocationresponder.h +++ b/indra/newview/llhomelocationresponder.h @@ -36,7 +36,7 @@  class LLHomeLocationResponder : public LLHTTPClient::Responder  {  	virtual void result( const LLSD& content ); -	virtual void error( U32 status, const std::string& reason ); +	virtual void errorWithContent( U32 status, const std::string& reason, const LLSD& content );  };  #endif diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index bc3b220dc0..9dde65ceb6 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -636,7 +636,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/llhudtext.cpp b/indra/newview/llhudtext.cpp index 579b6008ae..3c6bcd9829 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -186,11 +186,8 @@ void LLHUDText::renderText()  		LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);  	} -	LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight());  	LLVector3 width_vec = mWidth * x_pixel_vec;  	LLVector3 height_vec = mHeight * y_pixel_vec; -	LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec; -	LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec;  	mRadius = (width_vec + height_vec).magVec() * 0.5f; @@ -440,7 +437,7 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)  	LLVector3 x_pixel_vec;  	LLVector3 y_pixel_vec;  	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); -	LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec); +//	LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);  //	if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen)  //	{  //		// bubble off-screen, so find a spot for it along screen edge diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index c64ecdc47a..59272d721f 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -394,9 +394,10 @@ public:  		mSessionID = session_id;  	} -	void error(U32 statusNum, const std::string& reason) +	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)  	{ -		llinfos << "Error inviting all agents to session" << llendl; +		llwarns << "Error inviting all agents to session [status:"  +				<< statusNum << "]: " << content << llendl;  		//throw something back to the viewer here?  	} diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 8c862548bb..2c20409381 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -160,163 +160,157 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,  void on_new_message(const LLSD& msg)  { -    std::string action; +    std::string user_preferences;      LLUUID participant_id = msg["from_id"].asUUID();      LLUUID session_id = msg["session_id"].asUUID();      LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); -    //  determine action for this session +    // do not show notification which goes from agent +    if (gAgent.getID() == participant_id) +    { +        return; +    } + +    // determine state of conversations floater +    enum {CLOSED, NOT_ON_TOP, ON_TOP, ON_TOP_AND_ITEM_IS_SELECTED} conversations_floater_status; + + + +    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); +	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); + +	if (!LLFloater::isVisible(im_box) || im_box->isMinimized()) +	{ +		conversations_floater_status = CLOSED; +	} +	else if (!im_box->hasFocus() && +			    !(session_floater && LLFloater::isVisible(session_floater) +	            && !session_floater->isMinimized() && session_floater->hasFocus())) +	{ +		conversations_floater_status = NOT_ON_TOP; +	} +	else if (im_box->getSelectedSession() != session_id) +	{ +		conversations_floater_status = ON_TOP; +    } +	else +	{ +		conversations_floater_status = ON_TOP_AND_ITEM_IS_SELECTED; +	} +    //  determine user prefs for this session      if (session_id.isNull())      { -        action = gSavedSettings.getString("NotificationNearbyChatOptions"); +    	user_preferences = gSavedSettings.getString("NotificationNearbyChatOptions");      }      else if(session->isP2PSessionType())      {          if (LLAvatarTracker::instance().isBuddy(participant_id))          { -            action = gSavedSettings.getString("NotificationFriendIMOptions"); +        	user_preferences = gSavedSettings.getString("NotificationFriendIMOptions");          }          else          { -            action = gSavedSettings.getString("NotificationNonFriendIMOptions"); +        	user_preferences = gSavedSettings.getString("NotificationNonFriendIMOptions");          }      }      else if(session->isAdHocSessionType())      { -        action = gSavedSettings.getString("NotificationConferenceIMOptions"); +    	user_preferences = gSavedSettings.getString("NotificationConferenceIMOptions");      }      else if(session->isGroupSessionType())      { -        action = gSavedSettings.getString("NotificationGroupChatOptions"); +    	user_preferences = gSavedSettings.getString("NotificationGroupChatOptions");      } -    // do not show notification which goes from agent -    if (gAgent.getID() == participant_id) -    { -        return; -    } - -    // execution of the action - -    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); -	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); -	 -	if (im_box->isFrontmost() && im_box->getSelectedSession() == session_id -		&& !(session_floater->getHost() ? im_box->isMinimized() : session_floater->isMinimized())) -	{ -		return; -	} -	 -    //session floater not focused (visible or not) -    bool session_floater_not_focused = session_floater && !session_floater->hasFocus(); - -    //conv. floater is closed -    bool conversation_floater_is_closed = -    		!(  im_box -    		    && im_box->isInVisibleChain() -                && !im_box->isMinimized()); - -    //conversation floater not focused (visible or not) -    bool conversation_floater_not_focused = -    		conversation_floater_is_closed || !im_box->hasFocus(); -    // sess. floater is open -    bool session_floater_is_open = -            session_floater -            && session_floater->isInVisibleChain() -            && !session_floater->isMinimized() -            && !(session_floater->getHost() && session_floater->getHost()->isMinimized()); - -    bool conversation_floater_collapsed = !session_floater->isMessagePaneExpanded(); -    if (("toast" == action && !session_floater_is_open) || conversation_floater_collapsed) -    { -        //User is not focused on conversation containing the message -        if(session_floater_not_focused || conversation_floater_collapsed) -        { -        	if(!LLMuteList::getInstance()->isMuted(participant_id)) -        	{ -        		im_box->flashConversationItemWidget(session_id, true); -        	} -            //The conversation floater isn't focused/open -            if(conversation_floater_not_focused || conversation_floater_collapsed) -            { -            	if(!LLMuteList::getInstance()->isMuted(participant_id)  -                    && !gAgent.isDoNotDisturb()) -            	{ -            		gToolBarView->flashCommand(LLCommandId("chat"), true); -            	} - -                //Show IM toasts (upper right toasts) -                // Skip toasting for system messages and for nearby chat -                if(session_id.notNull() && participant_id.notNull()) -                { -                    LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); -                } -            } -		} -    } +    // actions: -    else if ("flash" == action) +    // 0. nothing - exit +    if (("none" == user_preferences || +    		ON_TOP_AND_ITEM_IS_SELECTED == conversations_floater_status) +    	    && session_floater->isMessagePaneExpanded())      { -    	if (!gAgent.isDoNotDisturb()) -    	{ -			im_box->flashConversationItemWidget(session_id, true); -			if(conversation_floater_not_focused) -			{ -				//User is not focused on conversation containing the message -				gToolBarView->flashCommand(LLCommandId("chat"), true); -			} -		} -		else if(session_id.notNull() && participant_id.notNull()) -		{ -			//If a DND message, allow notification to be stored so upon DND exit  -			//useMostItrusiveIMNotification will be called to notify user a message exists -			LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); -		} +    	return;      } -    else if("openconversations" == action) +    // 1. open floater and [optional] surface it +    if ("openconversations" == user_preferences && +    		(CLOSED == conversations_floater_status +    				|| NOT_ON_TOP == conversations_floater_status))      { -        //User is not focused on conversation containing the message -        if(session_floater_not_focused) +    	if(!gAgent.isDoNotDisturb())          { -            //Flash line item -            im_box->flashConversationItemWidget(session_id, true); - -            if(!gAgent.isDoNotDisturb()) -            { -				//Surface conversations floater -				LLFloaterReg::showInstance("im_container"); -				im_box->collapseMessagesPane(false); -				if (session_floater) +			// Open conversations floater +			LLFloaterReg::showInstance("im_container"); +			im_box->collapseMessagesPane(false); +			if (session_floater) +			{ +				if (session_floater->getHost())  				{ -					if (session_floater->getHost()) +					if (NULL != im_box && im_box->isMinimized())  					{ -						if (NULL != im_box && im_box->isMinimized()) -						{ -							LLFloater::onClickMinimize(im_box); -						} +						LLFloater::onClickMinimize(im_box);  					} -					else +				} +				else +				{ +					if (session_floater->isMinimized())  					{ -						if (session_floater->isMinimized()) -						{ -							LLFloater::onClickMinimize(session_floater); -						} +						LLFloater::onClickMinimize(session_floater);  					}  				}  			} - -            //If in DND mode, allow notification to be stored so upon DND exit  +		} +        else +        { +            //If in DND mode, allow notification to be stored so upon DND exit              //useMostItrusiveIMNotification will be called to notify user a message exists -            if(session_id.notNull()  -                && participant_id.notNull() -                && gAgent.isDoNotDisturb() -				&& !session_floater_is_open) +            if(session_id.notNull() +               && participant_id.notNull() +		       && !session_floater->isShown())              {                  LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); -			} -		} +	        } +        } +    } + +    // 2. Flash line item +    if ("openconversations" == user_preferences +    		|| ON_TOP == conversations_floater_status +    		|| ("toast" == user_preferences && ON_TOP != conversations_floater_status) +    		|| ("flash" == user_preferences && CLOSED == conversations_floater_status)) +    { +    	if(!LLMuteList::getInstance()->isMuted(participant_id)) +    	{ +    		im_box->flashConversationItemWidget(session_id, true); +    	} +    } + +    // 3. Flash FUI button +    if (("toast" == user_preferences || "flash" == user_preferences) && +    		(CLOSED == conversations_floater_status +    		    || NOT_ON_TOP == conversations_floater_status)) +    { +    	if(!LLMuteList::getInstance()->isMuted(participant_id) +            && !gAgent.isDoNotDisturb()) +    	{ +    		gToolBarView->flashCommand(LLCommandId("chat"), true); +    	} +    } + +    // 4. Toast +    if ((("toast" == user_preferences) && +    		(CLOSED == conversations_floater_status +    		    || NOT_ON_TOP == conversations_floater_status)) +    		    || !session_floater->isMessagePaneExpanded()) + +    { +        //Show IM toasts (upper right toasts) +        // Skip toasting for system messages and for nearby chat +        if(session_id.notNull() && participant_id.notNull()) +        { +            LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); +        }      }  } @@ -1406,7 +1400,7 @@ public:  		mAgents = agents_to_invite;  	} -	virtual void error(U32 statusNum, const std::string& reason) +	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)  	{  		//try an "old school" way.  		if ( statusNum == 400 ) @@ -1418,6 +1412,9 @@ public:  				mAgents);  		} +		llwarns << "LLStartConferenceChatResponder error [status:" +				<< statusNum << "]: " << content << llendl; +  		//else throw an error back to the client?  		//in theory we should have just have these error strings  		//etc. set up in this file as opposed to the IMMgr, @@ -1563,8 +1560,10 @@ public:  		}  	} -	void error(U32 statusNum, const std::string& reason) -	{		 +	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content) +	{ +		llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:" +				<< statusNum << "]: " << content << llendl;  		//throw something back to the viewer here?  		if ( gIMMgr )  		{ @@ -2852,6 +2851,8 @@ LLUUID LLIMMgr::addSession(  	//we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions  	if (!new_session) return session_id; +    llinfos << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << llendl; +      	//Per Plan's suggestion commented "explicit offline status warning" out to make Dessie happier (see EXT-3609)  	//*TODO After February 2010 remove this commented out line if no one will be missing that warning  	//noteOfflineUsers(session_id, floater, ids); @@ -2887,6 +2888,8 @@ void LLIMMgr::removeSession(const LLUUID& session_id)  	LLIMModel::getInstance()->clearSession(session_id); +    llinfos << "LLIMMgr::removeSession, session removed, session id = " << session_id << llendl; +  	notifyObserverSessionRemoved(session_id);  } @@ -2904,7 +2907,6 @@ void LLIMMgr::inviteToSession(  	// voice invite question is different from default only for group call (EXT-7118)  	std::string question_type = "VoiceInviteQuestionDefault"; -	BOOL ad_hoc_invite = FALSE;  	BOOL voice_invite = FALSE;  	bool is_linden = LLMuteList::getInstance()->isLinden(caller_name); @@ -2927,13 +2929,11 @@ void LLIMMgr::inviteToSession(  		//else it's an ad-hoc  		//and a voice ad-hoc  		notify_box_type = "VoiceInviteAdHoc"; -		ad_hoc_invite = TRUE;  		voice_invite = TRUE;  	}  	else if ( inv_type == INVITATION_TYPE_IMMEDIATE )  	{  		notify_box_type = "InviteAdHoc"; -		ad_hoc_invite = TRUE;  	}  	LLSD payload; @@ -3518,10 +3518,9 @@ public:  			}  			std::string buffer = saved + message; -			BOOL is_this_agent = FALSE;  			if(from_id == gAgentID)  			{ -				is_this_agent = TRUE; +				return;  			}  			gIMMgr->addMessage(  				session_id, diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 1e15dc832c..9c6db3676f 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -292,6 +292,11 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data)  	delete mPropertiesRequest;  	mPropertiesRequest = NULL;  } +/* +prep# +			virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content) +				llwarns << "MuteVoiceResponder error [status:" << status << "]: " << content << llendl; +	*/  void LLInspectAvatar::updateVolumeSlider()  { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0ee78d57bd..a5043a30ac 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -51,6 +51,7 @@  #include "llclipboard.h"  #include "llinventorydefines.h"  #include "llinventoryfunctions.h" +#include "llinventoryicon.h"  #include "llinventorymodel.h"  #include "llinventorymodelbackgroundfetch.h"  #include "llinventorypanel.h" @@ -96,8 +97,6 @@ struct LLMoveInv  using namespace LLOldEvents;  // Function declarations -void remove_inventory_category_from_avatar(LLInventoryCategory* category); -void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);  bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);  bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);  void teleport_via_landmark(const LLUUID& asset_id); @@ -1545,7 +1544,7 @@ LLUIImagePtr LLItemBridge::getIcon() const  										mIsLink);  	} -	return LLInventoryIcon::getIcon(LLInventoryIcon::ICONNAME_OBJECT); +	return LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_OBJECT);  }  LLUIImagePtr LLItemBridge::getIconOverlay() const @@ -2649,7 +2648,6 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,  	if(drop && accept)  	{  		it = inventory_objects.begin(); -		LLInventoryObject::object_list_t::iterator first_it = inventory_objects.begin();  		LLMoveInv* move_inv = new LLMoveInv;  		move_inv->mObjectID = object_id;  		move_inv->mCategoryID = category_id; @@ -2926,7 +2924,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)  		LLViewerInventoryCategory* cat = getCategory();  		if(!cat) return; -		remove_inventory_category_from_avatar ( cat ); +		LLAppearanceMgr::instance().takeOffOutfit( cat->getLinkedUUID() );  		return;  	}  	else if ("purge" == action) @@ -5236,7 +5234,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<LLInventoryCallback> cb = new RezAttachmentCallback(0); +			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));  			copy_inventory_item(  				gAgent.getID(),  				item->getPermissions().getOwner(), @@ -5253,11 +5251,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 LLItemBridge::performAction(model, action);  } @@ -5549,120 +5543,6 @@ LLWearableBridge::LLWearableBridge(LLInventoryPanel* inventory,  	mInvType = inv_type;  } -void remove_inventory_category_from_avatar( LLInventoryCategory* category ) -{ -	if(!category) return; -	lldebugs << "remove_inventory_category_from_avatar( " << category->getName() -			 << " )" << llendl; - - -	if (gAgentCamera.cameraCustomizeAvatar()) -	{ -		// switching to outfit editor should automagically save any currently edited wearable -		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit")); -	} - -	remove_inventory_category_from_avatar_step2(TRUE, category->getUUID() ); -} - -struct OnRemoveStruct -{ -	LLUUID mUUID; -	OnRemoveStruct(const LLUUID& uuid): -		mUUID(uuid) -	{ -	} -}; - -void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id) -{ - -	// Find all the wearables that are in the category's subtree. -	lldebugs << "remove_inventory_category_from_avatar_step2()" << llendl; -	if(proceed) -	{ -		LLInventoryModel::cat_array_t cat_array; -		LLInventoryModel::item_array_t item_array; -		LLFindWearables is_wearable; -		gInventory.collectDescendentsIf(category_id, -										cat_array, -										item_array, -										LLInventoryModel::EXCLUDE_TRASH, -										is_wearable); -		S32 i; -		S32 wearable_count = item_array.count(); - -		LLInventoryModel::cat_array_t	obj_cat_array; -		LLInventoryModel::item_array_t	obj_item_array; -		LLIsType is_object( LLAssetType::AT_OBJECT ); -		gInventory.collectDescendentsIf(category_id, -										obj_cat_array, -										obj_item_array, -										LLInventoryModel::EXCLUDE_TRASH, -										is_object); -		S32 obj_count = obj_item_array.count(); - -		// Find all gestures in this folder -		LLInventoryModel::cat_array_t	gest_cat_array; -		LLInventoryModel::item_array_t	gest_item_array; -		LLIsType is_gesture( LLAssetType::AT_GESTURE ); -		gInventory.collectDescendentsIf(category_id, -										gest_cat_array, -										gest_item_array, -										LLInventoryModel::EXCLUDE_TRASH, -										is_gesture); -		S32 gest_count = gest_item_array.count(); - -		if (wearable_count > 0)	//Loop through wearables.  If worn, remove. -		{ -			for(i = 0; i  < wearable_count; ++i) -			{ -				LLViewerInventoryItem *item = item_array.get(i); -				if (item->getType() == LLAssetType::AT_BODYPART) -					continue; -				if (gAgent.isTeen() && item->isWearableType() && -					(item->getWearableType() == LLWearableType::WT_UNDERPANTS || item->getWearableType() == LLWearableType::WT_UNDERSHIRT)) -					continue; -				if (get_is_item_worn(item->getUUID())) -				{ -					LLWearableList::instance().getAsset(item->getAssetUUID(), -														item->getName(), -														item->getType(), -														LLWearableBridge::onRemoveFromAvatarArrived, -														new OnRemoveStruct(item->getLinkedUUID())); -				} -			} -		} - -		if (obj_count > 0) -		{ -			for(i = 0; i  < obj_count; ++i) -			{ -				LLViewerInventoryItem *obj_item = obj_item_array.get(i); -				if (get_is_item_worn(obj_item->getUUID())) -				{ -					LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID()); -				} -			} -		} - -		if (gest_count > 0) -		{ -			for(i = 0; i  < gest_count; ++i) -			{ -				LLViewerInventoryItem *gest_item = gest_item_array.get(i); -				if (get_is_item_worn(gest_item->getUUID())) -				{ -					LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() ); -					gInventory.updateItem( gest_item ); -					gInventory.notifyObservers(); -				} - -			} -		} -	} -} -  BOOL LLWearableBridge::renameItem(const std::string& new_name)  {  	if (get_is_item_worn(mUUID)) @@ -5873,7 +5753,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) @@ -5899,7 +5779,7 @@ void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userda  // 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) @@ -5959,95 +5839,12 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data)  	return FALSE;  } -// static -void LLWearableBridge::onRemoveFromAvatar(void* user_data) -{ -	LLWearableBridge* self = (LLWearableBridge*)user_data; -	if(!self) return; -	if(get_is_item_worn(self->mUUID)) -	{ -		LLViewerInventoryItem* item = self->getItem(); -		if (item) -		{ -			LLUUID parent_id = item->getParentUUID(); -			LLWearableList::instance().getAsset(item->getAssetUUID(), -												item->getName(), -												item->getType(), -												onRemoveFromAvatarArrived, -												new OnRemoveStruct(LLUUID(self->mUUID))); -		} -	} -} - -// static -void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable, -												 void* userdata) -{ -	OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata; -	const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID); -	if(wearable) -	{ -		if( get_is_item_worn( item_id ) ) -		{ -			LLWearableType::EType type = wearable->getType(); - -			if( !(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES ) ) //&& -				//!((!gAgent.isTeen()) && ( type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT )) ) -			{ -				bool do_remove_all = false; -				U32 index = gAgentWearables.getWearableIndex(wearable); -				gAgentWearables.removeWearable( type, do_remove_all, index ); -			} -		} -	} - -	// Find and remove this item from the COF. -	LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false); -	gInventory.notifyObservers(); - -	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) -	{ -		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())); -	} -} -  void LLWearableBridge::removeFromAvatar()  { +	llwarns << "safe to remove?" << llendl;  	if (get_is_item_worn(mUUID))  	{ -		LLViewerInventoryItem* item = getItem(); -		removeItemFromAvatar(item); +		LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);  	}  } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 5c6cf0f0f0..517153e171 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -34,7 +34,7 @@  #include "llinventoryobserver.h"  #include "llinventorypanel.h"  #include "llviewercontrol.h" -#include "llwearable.h" +#include "llviewerwearable.h"  #include "lltooldraganddrop.h"  class LLInventoryFilter; @@ -509,10 +509,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 @@ -520,9 +520,6 @@ 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();  	void			removeFromAvatar();  protected: diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 34734d57c5..02a2475cfd 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -25,6 +25,8 @@   */  #include "llviewerprecompiledheaders.h" + +#include "linden_common.h"  #include "llinventoryicon.h"  #include "lldictionary.h" @@ -41,7 +43,7 @@ struct IconEntry : public LLDictionaryEntry  };  class LLIconDictionary : public LLSingleton<LLIconDictionary>, -						 public LLDictionary<LLInventoryIcon::EIconName, IconEntry> +						 public LLDictionary<LLInventoryType::EIconName, IconEntry>  {  public:  	LLIconDictionary(); @@ -49,48 +51,48 @@ public:  LLIconDictionary::LLIconDictionary()  { -	addEntry(LLInventoryIcon::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture")); -	addEntry(LLInventoryIcon::ICONNAME_SOUND, 					new IconEntry("Inv_Sound")); -	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard")); -	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard")); -	addEntry(LLInventoryIcon::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark")); -	addEntry(LLInventoryIcon::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark")); -	addEntry(LLInventoryIcon::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing")); -	addEntry(LLInventoryIcon::ICONNAME_OBJECT, 					new IconEntry("Inv_Object")); -	addEntry(LLInventoryIcon::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi")); -	addEntry(LLInventoryIcon::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin")); -	addEntry(LLInventoryIcon::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot")); - -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye")); - -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo")); -	addEntry(LLInventoryIcon::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation")); -	addEntry(LLInventoryIcon::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture")); - -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, 		new IconEntry("Inv_Physics")); - -	addEntry(LLInventoryIcon::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem")); -	addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkFolder")); -	addEntry(LLInventoryIcon::ICONNAME_MESH,	 				new IconEntry("Inv_Mesh")); - -	addEntry(LLInventoryIcon::ICONNAME_INVALID, 				new IconEntry("Inv_Invalid")); - -	addEntry(LLInventoryIcon::ICONNAME_NONE, 					new IconEntry("NONE")); +	addEntry(LLInventoryType::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture")); +	addEntry(LLInventoryType::ICONNAME_SOUND, 					new IconEntry("Inv_Sound")); +	addEntry(LLInventoryType::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard")); +	addEntry(LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard")); +	addEntry(LLInventoryType::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark")); +	addEntry(LLInventoryType::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark")); +	addEntry(LLInventoryType::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing")); +	addEntry(LLInventoryType::ICONNAME_OBJECT, 					new IconEntry("Inv_Object")); +	addEntry(LLInventoryType::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi")); +	addEntry(LLInventoryType::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard")); +	addEntry(LLInventoryType::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin")); +	addEntry(LLInventoryType::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot")); + +	addEntry(LLInventoryType::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape")); +	addEntry(LLInventoryType::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin")); +	addEntry(LLInventoryType::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair")); +	addEntry(LLInventoryType::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye")); + +	addEntry(LLInventoryType::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha")); +	addEntry(LLInventoryType::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo")); +	addEntry(LLInventoryType::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation")); +	addEntry(LLInventoryType::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture")); + +	addEntry(LLInventoryType::ICONNAME_CLOTHING_PHYSICS, 		new IconEntry("Inv_Physics")); + +	addEntry(LLInventoryType::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem")); +	addEntry(LLInventoryType::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkFolder")); +	addEntry(LLInventoryType::ICONNAME_MESH,	 				new IconEntry("Inv_Mesh")); + +	addEntry(LLInventoryType::ICONNAME_INVALID, 				new IconEntry("Inv_Invalid")); + +	addEntry(LLInventoryType::ICONNAME_NONE, 					new IconEntry("NONE"));  }  LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type, @@ -102,7 +104,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 +114,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 +172,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 5c8acf9e85..2197c53bb8 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/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp index 3e0849a795..0601796436 100644 --- a/indra/newview/llinventorylistitem.cpp +++ b/indra/newview/llinventorylistitem.cpp @@ -37,6 +37,7 @@  #include "lltextutil.h"  // newview +#include "llinventoryicon.h"  #include "llinventorymodel.h"  #include "llviewerinventory.h" @@ -230,7 +231,7 @@ const std::string& LLPanelInventoryListItemBase::getDescription() const  	{  		return LLStringUtil::null;  	} -	return inv_item->getDescription(); +	return inv_item->getActualDescription();  }  time_t LLPanelInventoryListItemBase::getCreationDate() const diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index e7d59d92d9..935fe2b4d0 100644..100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -460,9 +460,10 @@ public:  	{  	} -	virtual void error(U32 status, const std::string& reason) +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ -		LL_WARNS("InvAPI") << "CreateInventoryCategory failed.   status = " << status << ", reasion = \"" << reason << "\"" << LL_ENDL; +		LL_WARNS("InvAPI") << "CreateInventoryCategory failed [status:" +				<< status << "]: " << content << LL_ENDL;  	}  	virtual void result(const LLSD& content) @@ -1410,7 +1411,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) @@ -1443,10 +1443,6 @@ void  LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)  		{  			folder_id = titem->getParentUUID();  		} -		else -		{ -			all_one_folder = false; -		}  	}  	U32 changes = 0x0; @@ -1460,10 +1456,9 @@ void  LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)  }  //If we get back an error (not found, etc...), handle it here -void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::string& reason) +void LLInventoryModel::fetchInventoryResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	llinfos << "fetchInventory::error " -		<< status << ": " << reason << llendl; +	llwarns << "fetchInventory error [status:" << status << "]: " << content << llendl;  	gInventory.notifyObservers();  } @@ -1996,8 +1991,9 @@ bool LLInventoryModel::loadSkeleton(  		{  			LLViewerInventoryCategory* cat = (*invalid_cat_it).get();  			cat->setVersion(NO_VERSION); -			llinfos << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl; +			LL_DEBUGS("Inventory") << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl;  		} +		LL_INFOS("Inventory") << "Invalidated " << invalid_categories.size() << " categories due to invalid descendents cache" << llendl;  		// At this point, we need to set the known descendents for each  		// category which successfully cached so that we do not @@ -2534,7 +2530,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) @@ -2566,10 +2561,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account)  		{  			folder_id = titem->getParentUUID();  		} -		else -		{ -			all_one_folder = false; -		}  	}  	if(account)  	{ @@ -3295,8 +3286,71 @@ void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, c  	}  } +//* @param[in] items vector of items in order to be saved. +/* +void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items) +{ +	int sortField = 0; + +	// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field +	for (item_array_t::const_iterator i = items.begin(); i != items.end(); ++i) +	{ +		LLViewerInventoryItem* item = *i; + +		item->setSortField(++sortField); +		item->setComplete(TRUE); +		item->updateServer(FALSE); + +		updateItem(item); +		// Tell the parent folder to refresh its sort order. +		addChangedMask(LLInventoryObserver::SORT, item->getParentUUID()); +	} +	notifyObservers(); +} +*/ +// See also LLInventorySort where landmarks in the Favorites folder are sorted. +class LLViewerInventoryItemSort +{ +public: +	bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b) +	{ +		return a->getSortField() < b->getSortField(); +	} +}; + +/** + * Sorts passed items by LLViewerInventoryItem sort field. + * + * @param[in, out] items - array of items, not sorted. + */ +//static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items) +//{ +//	static LLViewerInventoryItemSort sort_functor; +//	std::sort(items.begin(), items.end(), sort_functor); +//} + +// * @param source_item_id - LLUUID of the source item to be moved into new position +// * @param target_item_id - LLUUID of the target item before which source item should be placed. +/* +void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id) +{ +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items; +	LLIsType is_type(LLAssetType::AT_LANDMARK); +	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); +	gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type); + +	// ensure items are sorted properly before changing order. EXT-3498 +	rearrange_item_order_by_sort_field(items); + +	// update order +	updateItemsOrder(items, source_item_id, target_item_id); + +	saveItemsOrder(items); +} +*/  //----------------------------------------------------------------------------  // *NOTE: DEBUG functionality diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 503de627a0..8aac879a93 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -84,7 +84,7 @@ public:  	public:  		fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};  		void result(const LLSD& content);			 -		void error(U32 status, const std::string& reason); +		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  	protected:  		LLSD mRequestSD;  	}; @@ -231,7 +231,8 @@ public:  	// Returns the uuid of the category that specifies 'type' as what it   	// defaults to containing. The category is not necessarily only for that type.   	//    NOTE: If create_folder is true, this will create a new inventory category  -	//    on the fly if one does not exist.  +	//    on the fly if one does not exist. *NOTE: if find_in_library is true it  +	//    will search in the user's library folder instead of "My Inventory"  	const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type,   										 bool create_folder = true);  	//    will search in the user's library folder instead of "My Inventory" @@ -363,6 +364,12 @@ public:  	// Returns end() of the vector if not found.  	static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id); + +	// Rearranges Landmarks inside Favorites folder. +	// Moves source landmark before target one. +	void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id); +	//void saveItemsOrder(const LLInventoryModel::item_array_t& items); +  	//--------------------------------------------------------------------  	// Creation  	//-------------------------------------------------------------------- diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index f4d0110b0f..f2b39e7186 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -183,7 +183,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *)  void LLInventoryModelBackgroundFetch::backgroundFetch()  { -	if (mBackgroundFetchActive && gAgent.getRegion()) +	if (mBackgroundFetchActive && gAgent.getRegion() && gAgent.getRegion()->capabilitiesReceived())  	{  		// If we'll be using the capability, we'll be sending batches and the background thing isn't as important.  		if (gSavedSettings.getBOOL("UseHTTPInventory"))  @@ -366,7 +366,7 @@ 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); +	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  };  void LLInventoryModelFetchItemResponder::result( const LLSD& content ) @@ -375,9 +375,9 @@ void LLInventoryModelFetchItemResponder::result( const LLSD& content )  	LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);  } -void LLInventoryModelFetchItemResponder::error( U32 status, const std::string& reason ) +void LLInventoryModelFetchItemResponder::errorWithContent( U32 status, const std::string& reason, const LLSD& content )  { -	LLInventoryModel::fetchInventoryResponder::error(status, reason); +	LLInventoryModel::fetchInventoryResponder::errorWithContent(status, reason, content);  	LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);  } @@ -391,7 +391,7 @@ public:  	{};  	//LLInventoryModelFetchDescendentsResponder() {};  	void result(const LLSD& content); -	void error(U32 status, const std::string& reason); +	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  protected:  	BOOL getIsRecursive(const LLUUID& cat_id) const;  private: @@ -529,12 +529,12 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)  }  // If we get back an error (not found, etc...), handle it here. -void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason) +void LLInventoryModelFetchDescendentsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  {  	LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); -	llinfos << "LLInventoryModelFetchDescendentsResponder::error " -		<< status << ": " << reason << llendl; +	llinfos << "LLInventoryModelFetchDescendentsResponder::error [status:" +			<< status << "]: " << content << llendl;  	fetcher->incrFetchCount(-1); @@ -564,7 +564,6 @@ BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat  {  	return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());  } -  // Bundle up a bunch of requests to send all at once.  // static     void LLInventoryModelBackgroundFetch::bulkFetch() @@ -687,20 +686,23 @@ void LLInventoryModelBackgroundFetch::bulkFetch()  	{  		if (folder_count)  		{ -			std::string url = region->getCapability("FetchInventoryDescendents2");    -			mFetchCount++; -			if (folder_request_body["folders"].size()) -			{ -				LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); -				LLHTTPClient::post(url, folder_request_body, fetcher, 300.0); -			} -			if (folder_request_body_lib["folders"].size()) +			std::string url = region->getCapability("FetchInventoryDescendents2");   			 +			if ( !url.empty() )  			{ -				std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); +				mFetchCount++; +				if (folder_request_body["folders"].size()) +				{ +					LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); +					LLHTTPClient::post(url, folder_request_body, fetcher, 300.0); +				} +				if (folder_request_body_lib["folders"].size()) +				{ +					std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); -				LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); -				LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0); -			} +					LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); +					LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0); +				} +			}					  		}  		if (item_count)  		{ diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index fabcd50c7d..cf1fd4c0d0 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -401,8 +401,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(); @@ -437,7 +435,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) @@ -456,7 +453,6 @@ void LLInventoryPanel::modelChanged(U32 mask)  		// Destroy and regenerate the UI.  		if (mask & LLInventoryObserver::REBUILD)  		{ -			handled = true;  			if (model_item && view_item && viewmodel_item)  			{  				const LLUUID& idp = viewmodel_item->getUUID(); @@ -500,8 +496,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. diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 97ba5b634a..25df4889b0 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -53,7 +53,7 @@  #include "llviewerobject.h"  #include "llface.h"  #include "llvoavatarself.h" -#include "llwearable.h" +#include "llviewerwearable.h"  #include "llagentwearables.h"  #include "lltexlayerparams.h"  #include "llvovolume.h" @@ -195,7 +195,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)  					mLastModified = new_last_modified;  					LLPointer<LLViewerFetchedTexture> texture = new LLViewerFetchedTexture -						("file://"+mFilename, mWorldID, LL_LOCAL_USE_MIPMAPS); +						("file://"+mFilename, FTT_LOCAL_FILE, mWorldID, LL_LOCAL_USE_MIPMAPS);  					texture->createGLTexture(LL_LOCAL_DISCARD_LEVEL, raw_image);  					texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image); @@ -437,8 +437,8 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)  					LLFace* face = object->mDrawable->getFace(face_iter);  					if (face && face->getTexture() && face->getTexture()->getID() == old_id)  					{ -						object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture -							(new_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); +						object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture( +							new_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));  						update_obj = true;  					} @@ -481,7 +481,7 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp  	U32 count = gAgentWearables.getWearableCount(type);  	for(U32 wearable_iter = 0; wearable_iter < count; wearable_iter++)  	{ -		LLWearable* wearable = gAgentWearables.getWearable(type, wearable_iter); +		LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_iter);  		if (wearable)  		{  			std::vector<LLLocalTextureObject*> texture_list = wearable->getLocalTextureListSeq(); @@ -493,11 +493,11 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp  				if (lto && lto->getID() == old_id)  				{  					U32 local_texlayer_index = 0; /* can't keep that as static const, gives errors, so i'm leaving this var here */ -					LLVOAvatarDefines::EBakedTextureIndex baked_texind = +					LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind =  						lto->getTexLayer(local_texlayer_index)->getTexLayerSet()->getBakedTexIndex(); -					LLVOAvatarDefines::ETextureIndex reg_texind = getTexIndex(type, baked_texind); -					if (reg_texind != LLVOAvatarDefines::TEX_NUM_INDICES) +					LLAvatarAppearanceDefines::ETextureIndex reg_texind = getTexIndex(type, baked_texind); +					if (reg_texind != LLAvatarAppearanceDefines::TEX_NUM_INDICES)  					{  						U32 index = gAgentWearables.getWearableIndex(wearable);  						gAgentAvatarp->setLocalTexture(reg_texind, gTextureList.getImage(new_id), FALSE, index); @@ -513,10 +513,10 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp  	}  } -LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex( -	LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind) +LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex( +	LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind)  { -	LLVOAvatarDefines::ETextureIndex result = LLVOAvatarDefines::TEX_NUM_INDICES; // using as a default/fail return. +	LLAvatarAppearanceDefines::ETextureIndex result = LLAvatarAppearanceDefines::TEX_NUM_INDICES; // using as a default/fail return.  	switch(type)  	{ @@ -524,32 +524,32 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		{  			switch(baked_texind)  			{ -				case LLVOAvatarDefines::BAKED_EYES: +				case LLAvatarAppearanceDefines::BAKED_EYES:  				{ -					result = LLVOAvatarDefines::TEX_EYES_ALPHA; +					result = LLAvatarAppearanceDefines::TEX_EYES_ALPHA;  					break;  				} -				case LLVOAvatarDefines::BAKED_HAIR: +				case LLAvatarAppearanceDefines::BAKED_HAIR:  				{ -					result = LLVOAvatarDefines::TEX_HAIR_ALPHA; +					result = LLAvatarAppearanceDefines::TEX_HAIR_ALPHA;  					break;  				} -				case LLVOAvatarDefines::BAKED_HEAD: +				case LLAvatarAppearanceDefines::BAKED_HEAD:  				{ -					result = LLVOAvatarDefines::TEX_HEAD_ALPHA; +					result = LLAvatarAppearanceDefines::TEX_HEAD_ALPHA;  					break;  				} -				case LLVOAvatarDefines::BAKED_LOWER: +				case LLAvatarAppearanceDefines::BAKED_LOWER:  				{ -					result = LLVOAvatarDefines::TEX_LOWER_ALPHA; +					result = LLAvatarAppearanceDefines::TEX_LOWER_ALPHA;  					break;  				} -				case LLVOAvatarDefines::BAKED_UPPER: +				case LLAvatarAppearanceDefines::BAKED_UPPER:  				{ -					result = LLVOAvatarDefines::TEX_UPPER_ALPHA; +					result = LLAvatarAppearanceDefines::TEX_UPPER_ALPHA;  					break;  				} @@ -565,9 +565,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		case LLWearableType::WT_EYES:  		{ -			if (baked_texind == LLVOAvatarDefines::BAKED_EYES) +			if (baked_texind == LLAvatarAppearanceDefines::BAKED_EYES)  			{ -				result = LLVOAvatarDefines::TEX_EYES_IRIS; +				result = LLAvatarAppearanceDefines::TEX_EYES_IRIS;  			}  			break; @@ -575,9 +575,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		case LLWearableType::WT_GLOVES:  		{ -			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) +			if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)  			{ -				result = LLVOAvatarDefines::TEX_UPPER_GLOVES; +				result = LLAvatarAppearanceDefines::TEX_UPPER_GLOVES;  			}  			break; @@ -585,13 +585,13 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		case LLWearableType::WT_JACKET:  		{ -			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) +			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)  			{ -				result = LLVOAvatarDefines::TEX_LOWER_JACKET; +				result = LLAvatarAppearanceDefines::TEX_LOWER_JACKET;  			} -			else if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) +			else if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)  			{ -				result = LLVOAvatarDefines::TEX_UPPER_JACKET; +				result = LLAvatarAppearanceDefines::TEX_UPPER_JACKET;  			}  			break; @@ -599,9 +599,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		case LLWearableType::WT_PANTS:  		{ -			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) +			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)  			{ -				result = LLVOAvatarDefines::TEX_LOWER_PANTS; +				result = LLAvatarAppearanceDefines::TEX_LOWER_PANTS;  			}  			break; @@ -609,9 +609,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		case LLWearableType::WT_SHIRT:  		{ -			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) +			if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)  			{ -				result = LLVOAvatarDefines::TEX_UPPER_SHIRT; +				result = LLAvatarAppearanceDefines::TEX_UPPER_SHIRT;  			}  			break; @@ -619,9 +619,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		case LLWearableType::WT_SHOES:  		{ -			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) +			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)  			{ -				result = LLVOAvatarDefines::TEX_LOWER_SHOES; +				result = LLAvatarAppearanceDefines::TEX_LOWER_SHOES;  			}  			break; @@ -631,20 +631,20 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		{  			switch(baked_texind)  			{ -				case LLVOAvatarDefines::BAKED_HEAD: +				case LLAvatarAppearanceDefines::BAKED_HEAD:  				{ -					result = LLVOAvatarDefines::TEX_HEAD_BODYPAINT; +					result = LLAvatarAppearanceDefines::TEX_HEAD_BODYPAINT;  					break;  				} -				case LLVOAvatarDefines::BAKED_LOWER: +				case LLAvatarAppearanceDefines::BAKED_LOWER:  				{ -					result = LLVOAvatarDefines::TEX_LOWER_BODYPAINT; +					result = LLAvatarAppearanceDefines::TEX_LOWER_BODYPAINT;  					break;  				} -				case LLVOAvatarDefines::BAKED_UPPER: +				case LLAvatarAppearanceDefines::BAKED_UPPER:  				{ -					result = LLVOAvatarDefines::TEX_UPPER_BODYPAINT; +					result = LLAvatarAppearanceDefines::TEX_UPPER_BODYPAINT;  					break;  				} @@ -659,9 +659,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		case LLWearableType::WT_SKIRT:  		{ -			if (baked_texind == LLVOAvatarDefines::BAKED_SKIRT) +			if (baked_texind == LLAvatarAppearanceDefines::BAKED_SKIRT)  			{ -				result = LLVOAvatarDefines::TEX_SKIRT; +				result = LLAvatarAppearanceDefines::TEX_SKIRT;  			}  			break; @@ -669,9 +669,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		case LLWearableType::WT_SOCKS:  		{ -			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) +			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)  			{ -				result = LLVOAvatarDefines::TEX_LOWER_SOCKS; +				result = LLAvatarAppearanceDefines::TEX_LOWER_SOCKS;  			}  			break; @@ -681,20 +681,20 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		{  			switch(baked_texind)  			{ -				case LLVOAvatarDefines::BAKED_HEAD: +				case LLAvatarAppearanceDefines::BAKED_HEAD:  				{ -					result = LLVOAvatarDefines::TEX_HEAD_TATTOO; +					result = LLAvatarAppearanceDefines::TEX_HEAD_TATTOO;  					break;  				} -				case LLVOAvatarDefines::BAKED_LOWER: +				case LLAvatarAppearanceDefines::BAKED_LOWER:  				{ -					result = LLVOAvatarDefines::TEX_LOWER_TATTOO; +					result = LLAvatarAppearanceDefines::TEX_LOWER_TATTOO;  					break;  				} -				case LLVOAvatarDefines::BAKED_UPPER: +				case LLAvatarAppearanceDefines::BAKED_UPPER:  				{ -					result = LLVOAvatarDefines::TEX_UPPER_TATTOO; +					result = LLAvatarAppearanceDefines::TEX_UPPER_TATTOO;  					break;  				} @@ -709,9 +709,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		case LLWearableType::WT_UNDERPANTS:  		{ -			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER) +			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)  			{ -				result = LLVOAvatarDefines::TEX_LOWER_UNDERPANTS; +				result = LLAvatarAppearanceDefines::TEX_LOWER_UNDERPANTS;  			}  			break; @@ -719,9 +719,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(  		case LLWearableType::WT_UNDERSHIRT:  		{ -			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER) +			if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)  			{ -				result = LLVOAvatarDefines::TEX_UPPER_UNDERSHIRT; +				result = LLAvatarAppearanceDefines::TEX_UPPER_UNDERSHIRT;  			}  			break; diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index 7a23c7ef6e..580b6dfa7e 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -28,11 +28,14 @@  #ifndef LL_LOCALBITMAPS_H  #define LL_LOCALBITMAPS_H +#include "llavatarappearancedefines.h"  #include "lleventtimer.h" +#include "llimage.h" +#include "llpointer.h"  #include "llwearabletype.h" -#include "llvoavatardefines.h"  class LLScrollListCtrl; +class LLViewerObject;  class LLLocalBitmap  { @@ -63,7 +66,7 @@ class LLLocalBitmap  		void updateUserPrims(LLUUID old_id, LLUUID new_id);  		void updateUserSculpts(LLUUID old_id, LLUUID new_id);  		void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type); -		LLVOAvatarDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind); +		LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind);  	private: /* private enums */  		enum ELinkStatus diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 8d9d70b50e..5022dba934 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -1217,11 +1217,11 @@ void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)  	case SCRIPTS_ICON:  	{  		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/llmanip.cpp b/indra/newview/llmanip.cpp index 9ec5d7c20c..a7d6cb5eac 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -53,7 +53,7 @@  #include "llresmgr.h"  #include "pipeline.h"  #include "llglheaders.h" - +#include "lluiimage.h"  // Local constants...  const S32 VERTICAL_OFFSET = 50; diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 826e8d560a..d79f1040bb 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -1689,7 +1689,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/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 00a0bf8894..ae0884ac5d 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -1191,9 +1191,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] )  	{ @@ -1210,8 +1207,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/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 362308c176..b62db70ec8 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -485,7 +485,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; @@ -702,11 +701,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); @@ -716,8 +710,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) ;					  				} @@ -753,7 +745,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()) @@ -775,11 +766,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(); @@ -1310,7 +1296,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)  					{ @@ -1319,7 +1304,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; @@ -1542,7 +1526,6 @@ void LLManipTranslate::renderSnapGuides()  		float a = line_alpha; -		LLColor4 col = LLUIColorTable::instance().getColor("SilhouetteChildColor");  		{  			//draw grid behind objects  			LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 99b4707158..2075aeed63 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -119,8 +119,8 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :  	if(!getDecoupleTextureSize())  	{ -		S32 screen_width = llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]); -		S32 screen_height = llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]); +		S32 screen_width = llround((F32)getRect().getWidth() * LLUI::getScaleFactor().mV[VX]); +		S32 screen_height = llround((F32)getRect().getHeight() * LLUI::getScaleFactor().mV[VY]);  		setTextureSize(screen_width, screen_height);  	} @@ -469,8 +469,8 @@ void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )  {  	if(!getDecoupleTextureSize())  	{ -		S32 screen_width = llround((F32)width * LLUI::sGLScaleFactor.mV[VX]); -		S32 screen_height = llround((F32)height * LLUI::sGLScaleFactor.mV[VY]); +		S32 screen_width = llround((F32)width * LLUI::getScaleFactor().mV[VX]); +		S32 screen_height = llround((F32)height * LLUI::getScaleFactor().mV[VY]);  		// when floater is minimized, these sizes are negative  		if ( screen_height > 0 && screen_width > 0 ) @@ -667,7 +667,7 @@ bool LLMediaCtrl::ensureMediaSourceExists()  			mMediaSource->addObserver( this );  			mMediaSource->setBackgroundColor( getBackgroundColor() );  			mMediaSource->setTrustedBrowser(mTrusted); -			mMediaSource->setPageZoomFactor( LLUI::sGLScaleFactor.mV[ VX ] ); +			mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );  			if(mClearCache)  			{ @@ -750,7 +750,7 @@ void LLMediaCtrl::draw()  	{  		gGL.pushUIMatrix();  		{ -			mMediaSource->setPageZoomFactor( LLUI::sGLScaleFactor.mV[ VX ] ); +			mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );  			// scale texture to fit the space using texture coords  			gGL.getTexUnit(0)->bind(media_texture); @@ -864,14 +864,14 @@ void LLMediaCtrl::convertInputCoords(S32& x, S32& y)  		coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL();  	} -	x = llround((F32)x * LLUI::sGLScaleFactor.mV[VX]); +	x = llround((F32)x * LLUI::getScaleFactor().mV[VX]);  	if ( ! coords_opengl )  	{ -		y = llround((F32)(y) * LLUI::sGLScaleFactor.mV[VY]); +		y = llround((F32)(y) * LLUI::getScaleFactor().mV[VY]);  	}  	else  	{ -		y = llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]); +		y = llround((F32)(getRect().getHeight() - y) * LLUI::getScaleFactor().mV[VY]);  	};  } diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index 31038b4aac..e3b46d5d2f 100644 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -564,7 +564,7 @@ LLMediaDataClient::Responder::Responder(const request_ptr_t &request)  }  /*virtual*/ -void LLMediaDataClient::Responder::error(U32 status, const std::string& reason) +void LLMediaDataClient::Responder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  {  	mRequest->stopTracking(); @@ -596,8 +596,8 @@ void LLMediaDataClient::Responder::error(U32 status, const std::string& reason)  	}  	else   	{ -		std::string msg = boost::lexical_cast<std::string>(status) + ": " + reason; -		LL_WARNS("LLMediaDataClient") << *mRequest << " http error(" << msg << ")" << LL_ENDL; +		LL_WARNS("LLMediaDataClient") << *mRequest << " http error [status:"  +				<< status << "]:" << content << ")" << LL_ENDL;  	}  } @@ -1003,7 +1003,7 @@ LLMediaDataClient::Responder *LLObjectMediaNavigateClient::RequestNavigate::crea  }  /*virtual*/ -void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string& reason) +void LLObjectMediaNavigateClient::Responder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  {  	getRequest()->stopTracking(); @@ -1017,7 +1017,7 @@ void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string  	// class  	if (status == HTTP_SERVICE_UNAVAILABLE)  	{ -		LLMediaDataClient::Responder::error(status, reason); +		LLMediaDataClient::Responder::errorWithContent(status, reason, content);  	}  	else  	{ diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h index ab90915c55..89e20a28d0 100644 --- a/indra/newview/llmediadataclient.h +++ b/indra/newview/llmediadataclient.h @@ -195,7 +195,7 @@ protected:  	public:  		Responder(const request_ptr_t &request);  		//If we get back an error (not found, etc...), handle it here -		virtual void error(U32 status, const std::string& reason); +		virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  		//If we get back a normal response, handle it here.	 Default just logs it.  		virtual void result(const LLSD& content); @@ -400,7 +400,7 @@ protected:      public:          Responder(const request_ptr_t &request)              : LLMediaDataClient::Responder(request) {} -		virtual void error(U32 status, const std::string& reason); +		virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);          virtual void result(const LLSD &content);      private:          void mediaNavigateBounceBack(); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 1223615079..17311dd75e 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3222,6 +3222,7 @@ void LLPhysicsDecomp::doDecomposition()  		param_map[params[i].mName] = params+i;  	} +	U32 ret = LLCD_OK;  	//set parameter values  	for (decomp_params::iterator iter = mCurRequest->mParams.begin(); iter != mCurRequest->mParams.end(); ++iter)  	{ @@ -3235,7 +3236,6 @@ void LLPhysicsDecomp::doDecomposition()  			continue;  		} -		U32 ret = LLCD_OK;  		if (param->mType == LLCDParam::LLCD_FLOAT)  		{ @@ -3254,8 +3254,6 @@ void LLPhysicsDecomp::doDecomposition()  	mCurRequest->setStatusMessage("Executing."); -	LLCDResult ret = LLCD_OK; -	  	if (LLConvexDecomposition::getInstance() != NULL)  	{  		ret = LLConvexDecomposition::getInstance()->executeStage(stage); diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp index eaa044cb59..252d1b78ea 100644 --- a/indra/newview/llmorphview.cpp +++ b/indra/newview/llmorphview.cpp @@ -99,8 +99,6 @@ void	LLMorphView::initialize()  //-----------------------------------------------------------------------------  void	LLMorphView::shutdown()  { -	LLVOAvatarSelf::onCustomizeEnd(); -  	if (isAgentAvatarValid())  	{  		gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE ); diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 1bda7640bd..dea90b9042 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -150,7 +150,7 @@ void LLNetMap::draw()  	static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white);  	static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white);  	static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); -	static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white); +	//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);  	static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);  	static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp index b6184f09bf..2923221c90 100644 --- a/indra/newview/llnotificationstorage.cpp +++ b/indra/newview/llnotificationstorage.cpp @@ -105,6 +105,8 @@ bool LLNotificationStorage::writeNotifications(const LLSD& pNotificationData) co  bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const  { +	LL_INFOS("LLNotificationStorage") << "starting read '" << mFileName << "'" << LL_ENDL; +  	bool didFileRead;  	pNotificationData.clear(); @@ -126,6 +128,8 @@ bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const  		}  	} +	LL_INFOS("LLNotificationStorage") << "ending read '" << mFileName << "'" << LL_ENDL; +  	return didFileRead;  } diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h index a346909027..0682af1278 100644 --- a/indra/newview/lloutputmonitorctrl.h +++ b/indra/newview/lloutputmonitorctrl.h @@ -31,7 +31,7 @@  #include "../llui/llview.h"  #include "llmutelist.h"  #include "llspeakingindicatormanager.h" -#include "../llui/lluiimage.h" +//#include "../llui/lluiimage.h"  class LLTextBox;  class LLUICtrlFactory; diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 6889b98ab1..862e4be203 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -55,6 +55,7 @@  #include "lltrans.h"  #include "llscrollcontainer.h"  #include "llstatusbar.h" +#include "llviewertexture.h"  const S32 MINIMUM_PRICE_FOR_LISTING = 50;	// L$ diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index 77e1487f38..1a427338e5 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -78,8 +78,6 @@ const char* LLPanelContents::PERMS_ANYONE_CONTROL_KEY = "perms_anyone_control";  BOOL LLPanelContents::postBuild()  { -	LLRect rect = this->getRect(); -  	setMouseOpaque(FALSE);  	childSetAction("button new script",&LLPanelContents::onClickNewScript, this); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 6b9edcb07c..e71dba5cae 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" @@ -52,6 +52,7 @@  #include "lltexturectrl.h"  #include "lltextureentry.h"  #include "llviewercontrol.h"    // gSavedSettings +#include "llviewerregion.h"  #include "llviewertexturelist.h"  #include "llagentcamera.h"  #include "llmorphview.h" @@ -104,7 +105,7 @@ enum ESubpart {          SUBPART_PHYSICS_ADVANCED,   }; -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines;  typedef std::vector<ESubpart> subpart_vec_t; @@ -718,8 +719,8 @@ BOOL LLPanelEditWearable::postBuild()          mBtnBack = getChild<LLButton>("back_btn");          mBackBtnLabel = mBtnBack->getLabelUnselected();          mBtnBack->setLabel(LLStringUtil::null); -        // handled at appearance panel level? -        //mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this)); + +        mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this));          mNameEditor = getChild<LLLineEditor>("description"); @@ -762,11 +763,11 @@ BOOL LLPanelEditWearable::postBuild()          mWearablePtr = NULL; -        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");          // configure tab expanded callbacks          for (U32 type_index = 0; type_index < (U32)LLWearableType::WT_COUNT; ++type_index) @@ -856,6 +857,14 @@ void LLPanelEditWearable::draw()          LLPanel::draw();  } +void LLPanelEditWearable::onClose() +{ +	if ( isDirty() ) +	{ +		revertChanges(); +	} +} +  void LLPanelEditWearable::setVisible(BOOL visible)  {          if (!visible) @@ -865,13 +874,22 @@ void LLPanelEditWearable::setVisible(BOOL visible)          LLPanel::setVisible(visible);  } -void LLPanelEditWearable::setWearable(LLWearable *wearable, BOOL disable_camera_switch) +void LLPanelEditWearable::setWearable(LLViewerWearable *wearable, BOOL disable_camera_switch)  {          showWearable(mWearablePtr, FALSE, disable_camera_switch);          mWearablePtr = wearable;          showWearable(mWearablePtr, TRUE, disable_camera_switch);  } +//static  +void LLPanelEditWearable::onBackButtonClicked(void* userdata) +{ +    LLPanelEditWearable *panel = (LLPanelEditWearable*) userdata; +	if ( panel->isDirty() ) +	{ +		LLAppearanceMgr::instance().setOutfitDirty( true );		 +	} +}  //static   void LLPanelEditWearable::onRevertButtonClicked(void* userdata) @@ -922,7 +940,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); @@ -1007,13 +1025,11 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)                  return;          bool is_modifiable = false; -        bool is_copyable   = false;          if(mWearableItem)          {                  const LLPermissions& perm = mWearableItem->getPermissions();                  is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID()); -                is_copyable = perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID());          }          if (is_modifiable) @@ -1030,6 +1046,11 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)          }  } +void LLPanelEditWearable::incrementCofVersionLegacy() +{ + +} +  void LLPanelEditWearable::saveChanges(bool force_save_as)  {          if (!mWearablePtr || !isDirty()) @@ -1041,17 +1062,50 @@ void LLPanelEditWearable::saveChanges(bool force_save_as)          U32 index = gAgentWearables.getWearableIndex(mWearablePtr);          std::string new_name = mNameEditor->getText(); + +		// Find an existing link to this wearable's inventory item, if any, and its description field. +		LLInventoryItem *link_item = NULL; +		std::string description; +		LLInventoryModel::item_array_t links = +			LLAppearanceMgr::instance().findCOFItemLinks(mWearablePtr->getItemID()); +		if (links.size()>0) +		{ +			link_item = links.get(0).get(); +			if (link_item && link_item->getIsLinkType()) +			{ +				description = link_item->getActualDescription(); +			} +		} +          if (force_save_as)          {                  // the name of the wearable has changed, re-save wearable with new name -                LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(),false); -                gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, FALSE); +                LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID()); +			gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, description, FALSE);                  mNameEditor->setText(mWearableItem->getName());          }          else          { +			// Make another copy of this link, with the same +			// description.  This is needed to bump the COF +			// version so texture baking service knows appearance has changed. +			if (link_item) +			{ +				// Create new link +				link_inventory_item( gAgent.getID(), +									 link_item->getLinkedUUID(), +									 LLAppearanceMgr::instance().getCOF(), +									 link_item->getName(), +									 description, +									 LLAssetType::AT_LINK, +									 NULL); +				// Remove old link +				gInventory.purgeObject(link_item->getUUID()); +			}                  gAgentWearables.saveWearable(mWearablePtr->getType(), index, TRUE, new_name);          } + +	  }  void LLPanelEditWearable::revertChanges() @@ -1069,7 +1123,7 @@ void LLPanelEditWearable::revertChanges()          gAgentAvatarp->wearableUpdated(mWearablePtr->getType(), FALSE);  } -void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch) +void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BOOL disable_camera_switch)  {          if (!wearable)          { @@ -1440,12 +1494,11 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value          {                  panel_list->clearPanels();                  value_map_t::iterator end = sorted_params.end(); -                S32 height = 0;                  for(value_map_t::iterator it = sorted_params.begin(); it != end; ++it)                  {                          LLPanel::Params p;                          p.name("LLScrollingPanelParam"); -                        LLWearable *wearable = this->getWearable(); +                        LLViewerWearable *wearable = this->getWearable();                          LLScrollingPanelParamBase *panel_param = NULL;                          if (wearable && wearable->getType() == LLWearableType::WT_PHYSICS) // Hack to show a different panel for physics.  Should generalize this later.                          { @@ -1455,7 +1508,7 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value                          {                                  panel_param = new LLScrollingPanelParam( p, NULL, (*it).second, TRUE, this->getWearable(), jointp);                          } -                        height = panel_list->addPanel( panel_param ); +                        panel_list->addPanel( panel_param );                  }          }  } @@ -1505,7 +1558,7 @@ void LLPanelEditWearable::updateVerbs()          }  } -void LLPanelEditWearable::configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name) +void LLPanelEditWearable::configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name)  {          LLCheckBoxCtrl* checkbox = mPanelAlpha->getChild<LLCheckBoxCtrl>(name);          checkbox->setCommitCallback(boost::bind(&LLPanelEditWearable::onInvisibilityCommit, this, checkbox, te)); @@ -1513,7 +1566,7 @@ void LLPanelEditWearable::configureAlphaCheckbox(LLVOAvatarDefines::ETextureInde          mAlphaCheckbox2Index[name] = te;  } -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; @@ -1557,7 +1610,7 @@ void LLPanelEditWearable::updateAlphaCheckboxes()          for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin();                  iter != mAlphaCheckbox2Index.end(); ++iter )          { -                LLVOAvatarDefines::ETextureIndex te = (LLVOAvatarDefines::ETextureIndex)iter->second; +                LLAvatarAppearanceDefines::ETextureIndex te = (LLAvatarAppearanceDefines::ETextureIndex)iter->second;                  LLCheckBoxCtrl* ctrl = mPanelAlpha->getChild<LLCheckBoxCtrl>(iter->first);                  if (ctrl)                  { @@ -1575,7 +1628,7 @@ void LLPanelEditWearable::initPreviousAlphaTextures()          initPreviousAlphaTextureEntry(TEX_LOWER_ALPHA);  } -void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te) +void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te)  {          LLLocalTextureObject *lto = getWearable()->getLocalTextureObject(te);          if (lto) diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 692a7ce90f..6533d55f2f 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; @@ -54,12 +54,13 @@ public:  	/*virtual*/ BOOL 		postBuild();  	/*virtual*/ BOOL		isDirty() const;	// LLUICtrl  	/*virtual*/ void		draw();	 +				void		onClose();  	// changes camera angle to default for selected subpart  	void				changeCamera(U8 subpart); -	LLWearable* 		getWearable() { return mWearablePtr; } -	void				setWearable(LLWearable *wearable, BOOL disable_camera_switch = FALSE); +	LLViewerWearable*	getWearable() { return mWearablePtr; } +	void				setWearable(LLViewerWearable *wearable, BOOL disable_camera_switch = FALSE);  	void				saveChanges(bool force_save_as = false);  	void				revertChanges(); @@ -70,17 +71,17 @@ public:  	void 				updateScrollingPanelList();  	static void			onRevertButtonClicked(void* userdata); +	static void			onBackButtonClicked(void* userdata);   	void				onCommitSexChange();  	void				onSaveAsButtonClicked();  	void				saveAsCallback(const LLSD& notification, const LLSD& response);  	virtual void		setVisible(BOOL visible); -  private:  	typedef std::map<F32, LLViewerVisualParam*> value_map_t; -	void				showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch = FALSE); +	void				showWearable(LLViewerWearable* wearable, BOOL show, BOOL disable_camera_switch = FALSE);  	void				updateScrollingPanelUI();  	LLPanel*			getPanel(LLWearableType::EType type);  	void				getSortedParams(value_map_t &sorted_params, const std::string &edit_group); @@ -94,17 +95,17 @@ private:  	void				toggleTypeSpecificControls(LLWearableType::EType type);  	void				updateTypeSpecificControls(LLWearableType::EType type); -	//alpha mask checkboxes -	void configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name); -	void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLVOAvatarDefines::ETextureIndex te); +	// alpha mask checkboxes +	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);  	// callback for HeightUnits parameter.  	bool changeHeightUnits(const LLSD& new_value); -	// updates current metric and replacemet metric label text +	// updates current metric and replacement metric label text  	void updateMetricLayout(BOOL new_value);  	// updates avatar height label @@ -114,8 +115,11 @@ private:  	void setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel); +	// *HACK Remove this when serverside texture baking is available on all regions. +	void incrementCofVersionLegacy(); +  	// the pointer to the wearable we're editing. NULL means we're not editing a wearable. -	LLWearable *mWearablePtr; +	LLViewerWearable *mWearablePtr;  	LLViewerInventoryItem* mWearableItem;  	// these are constant no matter what wearable we're editing @@ -128,7 +132,7 @@ private:  	LLTextBox *mTxtAvatarHeight; -	// localized and parametrized strings that used to build avatar_height_label +	// localized and parameterized strings that used to build avatar_height_label  	std::string mMeters;  	std::string mFeet;  	std::string mHeigth; @@ -151,7 +155,7 @@ private:  	LLPanel *mPanelEyes;  	LLPanel *mPanelHair; -	//clothes +	// clothes  	LLPanel *mPanelShirt;  	LLPanel *mPanelPants;  	LLPanel *mPanelShoes; @@ -165,10 +169,10 @@ private:  	LLPanel *mPanelTattoo;  	LLPanel *mPanelPhysics; -	typedef std::map<std::string, LLVOAvatarDefines::ETextureIndex> string_texture_index_map_t; +	typedef std::map<std::string, LLAvatarAppearanceDefines::ETextureIndex> string_texture_index_map_t;  	string_texture_index_map_t mAlphaCheckbox2Index; -	typedef std::map<LLVOAvatarDefines::ETextureIndex, LLUUID> s32_uuid_map_t; +	typedef std::map<LLAvatarAppearanceDefines::ETextureIndex, LLUUID> s32_uuid_map_t;  	s32_uuid_map_t mPreviousAlphaTexture;  }; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 202be9671b..445c0d811f 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -84,7 +84,6 @@ BOOL	LLPanelFace::postBuild()  	childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);  	childSetAction("button align",&LLPanelFace::onClickAutoFix,this); -	LLRect	rect = this->getRect();  	LLTextureCtrl*	mTextureCtrl;  	LLColorSwatchCtrl*	mColorSwatch; diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 37755fb851..c927aeacb3 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -1383,13 +1383,11 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,  	S32 cur_land_tax;  	S32 cur_group_tax;  	S32 cur_parcel_dir_fee; -	S32 cur_total_tax;  	S32 proj_object_tax;  	S32 proj_light_tax;  	S32 proj_land_tax;  	S32 proj_group_tax;  	S32 proj_parcel_dir_fee; -	S32 proj_total_tax;  	S32	non_exempt_members;  	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_IntervalDays, interval_days ); @@ -1413,8 +1411,6 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,  	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_LastTaxDate, last_stipend_date);  	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_TaxDate, next_stipend_date); -	cur_total_tax = cur_object_tax + cur_light_tax + cur_land_tax + cur_group_tax +  cur_parcel_dir_fee; -	proj_total_tax = proj_object_tax + proj_light_tax + proj_land_tax + proj_group_tax + proj_parcel_dir_fee;  	if (interval_days != mImplementationp->mIntervalLength ||   		current_interval != mImplementationp->mCurrentInterval) diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 93b108efcc..522ba5afae 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -35,6 +35,7 @@  #include "llviewerinventory.h"  #include "llinventorydefines.h"  #include "llinventoryfunctions.h" +#include "llinventoryicon.h"  #include "llinventorymodel.h"  #include "llfloaterinventory.h"  #include "llagent.h" diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp index 04c1a86f69..5321ebc777 100644 --- a/indra/newview/llpanelland.cpp +++ b/indra/newview/llpanelland.cpp @@ -166,7 +166,7 @@ void LLPanelLandInfo::refresh()  		getChildView("button abandon land")->setEnabled(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))  		{  			getChildView("button subdivide land")->setEnabled(owner_divide || manager_divideable || gAgent.isGodlike());  		} diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp index c57746ec00..5c9b968ac9 100644 --- a/indra/newview/llpanellandmarkinfo.cpp +++ b/indra/newview/llpanellandmarkinfo.cpp @@ -209,24 +209,6 @@ void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)  		mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));  	} -	S32 region_x; -	S32 region_y; -	S32 region_z; - -	// If the region position is zero, grab position from the global -	if(mPosRegion.isExactlyZero()) -	{ -		region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS; -		region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS; -		region_z = llround(parcel_data.global_z); -	} -	else -	{ -		region_x = llround(mPosRegion.mV[VX]); -		region_y = llround(mPosRegion.mV[VY]); -		region_z = llround(mPosRegion.mV[VZ]); -	} -  	LLSD info;  	info["update_verbs"] = true;  	info["global_x"] = parcel_data.global_x; diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index d87b565b32..25ef9a3d6a 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -439,10 +439,9 @@ void LLPanelObject::getState( )  	mCtrlRotY->setEnabled( enable_rotate );  	mCtrlRotZ->setEnabled( enable_rotate ); -	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(); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 7555ac7b2c..d7130820ab 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -47,6 +47,7 @@  #include "llfolderview.h"  #include "llinventorybridge.h"  #include "llinventorydefines.h" +#include "llinventoryicon.h"  #include "llinventoryfilter.h"  #include "llinventoryfunctions.h"  #include "llpreviewanim.h" diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index e641370d2e..131e8e9359 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -365,10 +365,8 @@ void LLPanelPermissions::refresh()  	// Update creator text field  	getChildView("Creator:")->setEnabled(TRUE); -	BOOL creators_identical;  	std::string creator_name; -	creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, -																	  creator_name); +	LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name);  	getChild<LLUICtrl>("Creator Name")->setValue(creator_name);  	getChildView("Creator Name")->setEnabled(TRUE); diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 83b70d9f29..5d9971c16c 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -568,7 +568,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,  		mTerraformLimitsText->setText(parcel->getAllowTerraform() ? on : off); -		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) +		if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))  		{  			mSubdivideText->setText(getString("can_change"));  		} @@ -576,7 +576,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,  		{  			mSubdivideText->setText(getString("can_not_change"));  		} -		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) +		if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))  		{  			mResaleText->setText(getString("can_not_resell"));  		} diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 343c140bbb..9dd665198f 100644 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -417,11 +417,11 @@ void LLPanelTopInfoBar::onParcelIconClick(EParcelIcon icon)  	case SCRIPTS_ICON:  	{  		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/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 13b746dbab..02d363d795 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -252,10 +252,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/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 3b9934d4be..aa3ed22bee 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -77,11 +77,7 @@ private:  	{  		uuid_vec_t selected_uuids;  		mPanelWearing->getSelectedItemsUUIDs(selected_uuids); - -		for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it) -		{ -				LLAppearanceMgr::instance().removeItemFromAvatar(*it); -		} +		LLAppearanceMgr::instance().removeItemsFromAvatar(selected_uuids);  	}  	LLToggleableMenu*		mMenu; @@ -97,12 +93,11 @@ protected:  	{  		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; -		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1); -  		registrar.add("Wearing.Edit", boost::bind(&edit_outfit)); -		registrar.add("Wearing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs)); -		registrar.add("Wearing.Detach", boost::bind(handleMultiple, take_off, mUUIDs)); - +		registrar.add("Wearing.TakeOff", +					  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs)); +		registrar.add("Wearing.Detach",  +					  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));  		LLContextMenu* menu = createFromFile("menu_wearing_tab.xml");  		updateMenuItemsVisibility(menu); diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp index 2dd01e931e..c277359133 100644 --- a/indra/newview/llpathfindingmanager.cpp +++ b/indra/newview/llpathfindingmanager.cpp @@ -108,7 +108,7 @@ public:  	virtual ~NavMeshStatusResponder();  	virtual void result(const LLSD &pContent); -	virtual void error(U32 pStatus, const std::string& pReason); +	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);  protected: @@ -130,7 +130,7 @@ public:  	virtual ~NavMeshResponder();  	virtual void result(const LLSD &pContent); -	virtual void error(U32 pStatus, const std::string& pReason); +	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);  protected: @@ -151,7 +151,7 @@ public:  	virtual ~AgentStateResponder();  	virtual void result(const LLSD &pContent); -	virtual void error(U32 pStatus, const std::string& pReason); +	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);  protected: @@ -170,7 +170,7 @@ public:  	virtual ~NavMeshRebakeResponder();  	virtual void result(const LLSD &pContent); -	virtual void error(U32 pStatus, const std::string& pReason); +	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);  protected: @@ -190,9 +190,11 @@ public:  	virtual ~LinksetsResponder();  	void handleObjectLinksetsResult(const LLSD &pContent); -	void handleObjectLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL); +	void handleObjectLinksetsError(U32 pStatus, const std::string &pReason,  +								   const LLSD& pContent, const std::string &pURL);  	void handleTerrainLinksetsResult(const LLSD &pContent); -	void handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL); +	void handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, +									const LLSD& pContent, const std::string &pURL);  protected: @@ -230,7 +232,7 @@ public:  	virtual ~ObjectLinksetsResponder();  	virtual void result(const LLSD &pContent); -	virtual void error(U32 pStatus, const std::string &pReason); +	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);  protected: @@ -250,7 +252,7 @@ public:  	virtual ~TerrainLinksetsResponder();  	virtual void result(const LLSD &pContent); -	virtual void error(U32 pStatus, const std::string &pReason); +	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);  protected: @@ -270,7 +272,7 @@ public:  	virtual ~CharactersResponder();  	virtual void result(const LLSD &pContent); -	virtual void error(U32 pStatus, const std::string &pReason); +	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);  protected: @@ -800,9 +802,9 @@ void NavMeshStatusResponder::result(const LLSD &pContent)  	LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);  } -void NavMeshStatusResponder::error(U32 pStatus, const std::string& pReason) +void NavMeshStatusResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)  { -	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; +	llwarns << "NavMeshStatusResponder error [status:" << pStatus << "]: " << pContent << llendl;  	LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID);  	LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);  } @@ -828,9 +830,9 @@ void NavMeshResponder::result(const LLSD &pContent)  	mNavMeshPtr->handleNavMeshResult(pContent, mNavMeshVersion);  } -void NavMeshResponder::error(U32 pStatus, const std::string& pReason) +void NavMeshResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)  { -	mNavMeshPtr->handleNavMeshError(pStatus, pReason, mCapabilityURL, mNavMeshVersion); +	mNavMeshPtr->handleNavMeshError(pStatus, pReason, pContent, mCapabilityURL, mNavMeshVersion);  }  //--------------------------------------------------------------------------- @@ -855,9 +857,9 @@ void AgentStateResponder::result(const LLSD &pContent)  	LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion);  } -void AgentStateResponder::error(U32 pStatus, const std::string &pReason) +void AgentStateResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)  { -	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; +	llwarns << "AgentStateResponder error [status:" << pStatus << "]: " << pContent << llendl;  	LLPathfindingManager::getInstance()->handleAgentState(FALSE);  } @@ -881,9 +883,9 @@ void NavMeshRebakeResponder::result(const LLSD &pContent)  	mRebakeNavMeshCallback(true);  } -void NavMeshRebakeResponder::error(U32 pStatus, const std::string &pReason) +void NavMeshRebakeResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)  { -	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; +	llwarns << "NavMeshRebakeResponder error [status:" << pStatus << "]: " << pContent << llendl;  	mRebakeNavMeshCallback(false);  } @@ -916,9 +918,11 @@ void LinksetsResponder::handleObjectLinksetsResult(const LLSD &pContent)  	}  } -void LinksetsResponder::handleObjectLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL) +void LinksetsResponder::handleObjectLinksetsError(U32 pStatus, const std::string &pReason, +												 const LLSD& pContent, const std::string &pURL)  { -	llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; +	llwarns << "LinksetsResponder object linksets error with request to URL '" << pURL << "' [status:" +			<< pStatus << "]: " << pContent << llendl;  	mObjectMessagingState = kReceivedError;  	if (mTerrainMessagingState != kWaiting)  	{ @@ -937,8 +941,11 @@ void LinksetsResponder::handleTerrainLinksetsResult(const LLSD &pContent)  	}  } -void LinksetsResponder::handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL) +void LinksetsResponder::handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, +												   const LLSD& pContent, const std::string &pURL)  { +	llwarns << "LinksetsResponder terrain linksets error with request to URL '" << pURL << "' [status:" +			<< pStatus << "]: " << pContent << llendl;  	mTerrainMessagingState = kReceivedError;  	if (mObjectMessagingState != kWaiting)  	{ @@ -988,9 +995,9 @@ void ObjectLinksetsResponder::result(const LLSD &pContent)  	mLinksetsResponsderPtr->handleObjectLinksetsResult(pContent);  } -void ObjectLinksetsResponder::error(U32 pStatus, const std::string &pReason) +void ObjectLinksetsResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)  { -	mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, mCapabilityURL); +	mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, pContent, mCapabilityURL);  }  //--------------------------------------------------------------------------- @@ -1013,9 +1020,9 @@ void TerrainLinksetsResponder::result(const LLSD &pContent)  	mLinksetsResponsderPtr->handleTerrainLinksetsResult(pContent);  } -void TerrainLinksetsResponder::error(U32 pStatus, const std::string &pReason) +void TerrainLinksetsResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)  { -	mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, mCapabilityURL); +	mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, pContent, mCapabilityURL);  }  //--------------------------------------------------------------------------- @@ -1040,9 +1047,9 @@ void CharactersResponder::result(const LLSD &pContent)  	mCharactersCallback(mRequestId, LLPathfindingManager::kRequestCompleted, characterListPtr);  } -void CharactersResponder::error(U32 pStatus, const std::string &pReason) +void CharactersResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)  { -	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; +	llwarns << "CharactersResponder error [status:" << pStatus << "]: " << pContent << llendl;  	LLPathfindingObjectListPtr characterListPtr =  LLPathfindingObjectListPtr(new LLPathfindingCharacterList());  	mCharactersCallback(mRequestId, LLPathfindingManager::kRequestError, characterListPtr); diff --git a/indra/newview/llpathfindingnavmesh.cpp b/indra/newview/llpathfindingnavmesh.cpp index e01dd3a152..0c23e5ac92 100644 --- a/indra/newview/llpathfindingnavmesh.cpp +++ b/indra/newview/llpathfindingnavmesh.cpp @@ -184,9 +184,10 @@ void LLPathfindingNavMesh::handleNavMeshError()  	setRequestStatus(kNavMeshRequestError);  } -void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion) +void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const LLSD& pContent, const std::string &pURL, U32 pNavMeshVersion)  { -	llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl; +	llwarns << "LLPathfindingNavMesh error with request to URL '" << pURL << "' [status:" +			<< pStatus << "]: " << pContent << llendl;  	if (mNavMeshStatus.getVersion() == pNavMeshVersion)  	{  		handleNavMeshError(); diff --git a/indra/newview/llpathfindingnavmesh.h b/indra/newview/llpathfindingnavmesh.h index 7a844f54ce..b872ccad7c 100644 --- a/indra/newview/llpathfindingnavmesh.h +++ b/indra/newview/llpathfindingnavmesh.h @@ -74,7 +74,7 @@ public:  	void handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion);  	void handleNavMeshNotEnabled();  	void handleNavMeshError(); -	void handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion); +	void handleNavMeshError(U32 pStatus, const std::string &pReason, const LLSD& pContent, const std::string &pURL, U32 pNavMeshVersion);  protected: diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp index 11c12e6c10..666f10df96 100644 --- a/indra/newview/llpersistentnotificationstorage.cpp +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -87,6 +87,8 @@ void LLPersistentNotificationStorage::loadNotifications()  {  	LLFastTimer _(FTM_LOAD_NOTIFICATIONS); +	LL_INFOS("LLPersistentNotificationStorage") << "start loading notifications" << LL_ENDL; +  	LLNotifications::instance().getChannel("Persistent")->  		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1)); @@ -129,6 +131,8 @@ void LLPersistentNotificationStorage::loadNotifications()  			notification_channel->hideToast(notification->getID());  		}  	} + +	LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;  }  bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload) diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index cb6989c9dd..3ee0746412 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -166,7 +166,7 @@ protected:  		} -        void setParamValue(LLViewerVisualParam *param, +        void setParamValue(const LLViewerVisualParam *param,                             const F32 new_value_local,                                                     F32 behavior_maxeffect); @@ -428,14 +428,13 @@ 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); -        return velocity_local; +	const LLVector3 velocity_world = positionchange_world; +	const F32 velocity_local = toLocal(velocity_world); +	return velocity_local;  }  F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local) @@ -673,12 +672,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);  			}  		} @@ -758,7 +755,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/llpipelinelistener.cpp b/indra/newview/llpipelinelistener.cpp new file mode 100644 index 0000000000..20759239bf --- /dev/null +++ b/indra/newview/llpipelinelistener.cpp @@ -0,0 +1,216 @@ +/** + * @file   llpipelinelistener.h + * @author Don Kjer + * @date   2012-07-09 + * @brief  Implementation for LLPipelineListener + *  + * $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$ + */ + +// Precompiled header +#include "llviewerprecompiledheaders.h" + +#include "llpipelinelistener.h" + +#include "pipeline.h" +#include "stringize.h" +#include <sstream> +#include "llviewermenu.h" + + +namespace { +	// Render Types +	void toggle_render_types_wrapper(LLSD const& request) +	{ +		for (LLSD::array_const_iterator iter = request["types"].beginArray(); +			iter != request["types"].endArray(); +			++iter) +		{ +			U32 render_type = render_type_from_string( iter->asString() ); +			if ( render_type != 0 ) +			{ +				LLPipeline::toggleRenderTypeControl( (void*) render_type ); +			} +		} +	} + +	void has_render_type_wrapper(LLSD const& request) +	{ +		LLEventAPI::Response response(LLSD(), request); +		U32 render_type = render_type_from_string( request["type"].asString() ); +		if ( render_type != 0 ) +		{ +			response["value"] = LLPipeline::hasRenderTypeControl( (void*) render_type ); +		} +		else +		{ +			response.error(STRINGIZE("unknown type '" << request["type"].asString() << "'")); +		} +	} + +	void disable_all_render_types_wrapper(LLSD const& request) +	{ +		gPipeline.clearAllRenderTypes(); +	} + +	void enable_all_render_types_wrapper(LLSD const& request) +	{ +		gPipeline.setAllRenderTypes(); +	} + +	// Render Features +	void toggle_render_features_wrapper(LLSD const& request) +	{ +		for (LLSD::array_const_iterator iter = request["features"].beginArray(); +			iter != request["features"].endArray(); +			++iter) +		{ +			U32 render_feature = feature_from_string( iter->asString() ); +			if ( render_feature != 0 ) +			{ +				LLPipeline::toggleRenderDebugControl( (void*) render_feature ); +			} +		} +	} + +	void has_render_feature_wrapper(LLSD const& request) +	{ +		LLEventAPI::Response response(LLSD(), request); +		U32 render_feature = feature_from_string( request["feature"].asString() ); +		if ( render_feature != 0 ) +		{ +			response["value"] = gPipeline.hasRenderDebugFeatureMask(render_feature); +		} +		else +		{ +			response.error(STRINGIZE("unknown feature '" << request["feature"].asString() << "'")); +		} +	} + +	void disable_all_render_features_wrapper(LLSD const& request) +	{ +		gPipeline.clearAllRenderDebugFeatures(); +	} + +	void enable_all_render_features_wrapper(LLSD const& request) +	{ +		gPipeline.setAllRenderDebugFeatures(); +	} + +	// Render Info Displays +	void toggle_info_displays_wrapper(LLSD const& request) +	{ +		for (LLSD::array_const_iterator iter = request["displays"].beginArray(); +			iter != request["displays"].endArray(); +			++iter) +		{ +			U32 info_display = info_display_from_string( iter->asString() ); +			if ( info_display != 0 ) +			{ +				LLPipeline::toggleRenderDebug( (void*) info_display ); +			} +		} +	} + +	void has_info_display_wrapper(LLSD const& request) +	{ +		LLEventAPI::Response response(LLSD(), request); +		U32 info_display = info_display_from_string( request["display"].asString() ); +		if ( info_display != 0 ) +		{ +			response["value"] = gPipeline.hasRenderDebugMask(info_display); +		} +		else +		{ +			response.error(STRINGIZE("unknown display '" << request["display"].asString() << "'")); +		} +	} + +	void disable_all_info_displays_wrapper(LLSD const& request) +	{ +		gPipeline.clearAllRenderDebugDisplays(); +	} + +	void enable_all_info_displays_wrapper(LLSD const& request) +	{ +		gPipeline.setAllRenderDebugDisplays(); +	} + +} + + +LLPipelineListener::LLPipelineListener(): +	LLEventAPI("LLPipeline", +			   "API to te rendering pipeline.") +{ +	// Render Types +	add("toggleRenderTypes", +		"Toggle rendering [\"types\"]:\n" +		"See: llviewermenu.cpp:render_type_from_string for list of available types.", +		&toggle_render_types_wrapper); +	add("hasRenderType", +		"Check if rendering [\"type\"] is enabled:\n" +		"See: llviewermenu.cpp:render_type_from_string for list of available types.", +		&has_render_type_wrapper, +		LLSDMap("reply", LLSD())); +	add("disableAllRenderTypes", +		"Turn off all rendering types.", +		&disable_all_render_types_wrapper); +	add("enableAllRenderTypes", +		"Turn on all rendering types.", +		&enable_all_render_types_wrapper); + +	// Render Features +	add("toggleRenderFeatures", +		"Toggle rendering [\"features\"]:\n" +		"See: llviewermenu.cpp:feature_from_string for list of available features.", +		&toggle_render_features_wrapper); +	add("hasRenderFeature", +		"Check if rendering [\"feature\"] is enabled:\n" +		"See: llviewermenu.cpp:render_feature_from_string for list of available features.", +		&has_render_feature_wrapper, +		LLSDMap("reply", LLSD())); +	add("disableAllRenderFeatures", +		"Turn off all rendering features.", +		&disable_all_render_features_wrapper); +	add("enableAllRenderFeatures", +		"Turn on all rendering features.", +		&enable_all_render_features_wrapper); + +	// Render Info Displays +	add("toggleRenderInfoDisplays", +		"Toggle info [\"displays\"]:\n" +		"See: llviewermenu.cpp:info_display_from_string for list of available displays.", +		&toggle_info_displays_wrapper); +	add("hasRenderInfoDisplay", +		"Check if info [\"display\"] is enabled:\n" +		"See: llviewermenu.cpp:info_display_from_string for list of available displays.", +		&has_info_display_wrapper, +		LLSDMap("reply", LLSD())); +	add("disableAllRenderInfoDisplays", +		"Turn off all info displays.", +		&disable_all_info_displays_wrapper); +	add("enableAllRenderInfoDisplays", +		"Turn on all info displays.", +		&enable_all_info_displays_wrapper); +} + diff --git a/indra/newview/llpipelinelistener.h b/indra/newview/llpipelinelistener.h new file mode 100644 index 0000000000..da1898e57b --- /dev/null +++ b/indra/newview/llpipelinelistener.h @@ -0,0 +1,41 @@ +/** + * @file   llpipelinelistener.h + * @author Don Kjer + * @date   2012-07-09 + * @brief  Wrap subset of LLPipeline API in event API + *  + * $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$ + */ + +#if ! defined(LL_LLPIPELINELISTENER_H) +#define LL_LLPIPELINELISTENER_H + +#include "lleventapi.h" + +/// Listen on an LLEventPump with specified name for LLPipeline request events. +class LLPipelineListener: public LLEventAPI +{ +public: +	LLPipelineListener(); +}; + +#endif /* ! defined(LL_LLPIPELINELISTENER_H) */ diff --git a/indra/newview/llpostcard.cpp b/indra/newview/llpostcard.cpp index 4f2d6da7e5..aebe636f59 100644 --- a/indra/newview/llpostcard.cpp +++ b/indra/newview/llpostcard.cpp @@ -35,6 +35,7 @@  #include "message.h"  #include "llagent.h" +#include "llassetstorage.h"  #include "llassetuploadresponders.h"  /////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 3ff5a05d81..91a98792eb 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -70,7 +70,7 @@ LLPreviewTexture::LLPreviewTexture(const LLSD& key)  	  mAspectRatio(0.f),  	  mPreviewToSave(FALSE),  	  mImage(NULL), -	  mImageOldBoostLevel(LLViewerTexture::BOOST_NONE) +	  mImageOldBoostLevel(LLGLTexture::BOOST_NONE)  {  	updateImageID();  	if (key.has("save_as")) @@ -468,9 +468,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, FTT_DEFAULT, 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/llproductinforequest.cpp b/indra/newview/llproductinforequest.cpp index 93bf8b2328..1390000fc5 100644 --- a/indra/newview/llproductinforequest.cpp +++ b/indra/newview/llproductinforequest.cpp @@ -43,10 +43,10 @@ public:  	}  	//If we get back an error (not found, etc...), handle it here -	virtual void error(U32 status, const std::string& reason) +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ -		llwarns << "LLProductInfoRequest::error(" -		<< status << ": " << reason << ")" << llendl; +		llwarns << "LLProductInfoRequest error [status:" +				<< status << ":] " << content << llendl;  	}  }; diff --git a/indra/newview/llregioninfomodel.cpp b/indra/newview/llregioninfomodel.cpp index 698c4f9bb9..590e246482 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 89efd82767..d22a0de463 100644 --- a/indra/newview/llregioninfomodel.h +++ b/indra/newview/llregioninfomodel.h @@ -52,7 +52,7 @@ public:  	U8			mSimAccess;  	U8			mAgentLimit; -	U32			mRegionFlags; +	U64			mRegionFlags;  	U32			mEstateID;  	U32			mParentEstateID; diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp index 3862dac340..500dec7ee5 100644 --- a/indra/newview/llremoteparcelrequest.cpp +++ b/indra/newview/llremoteparcelrequest.cpp @@ -62,10 +62,10 @@ void LLRemoteParcelRequestResponder::result(const LLSD& content)  //If we get back an error (not found, etc...), handle it here  //virtual -void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason) +void LLRemoteParcelRequestResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	llinfos << "LLRemoteParcelRequest::error(" -		<< status << ": " << reason << ")" << llendl; +	llwarns << "LLRemoteParcelRequest error [status:" +			<< status << "]: " << content << llendl;  	// Panel inspecting the information may be closed and destroyed  	// before this response is received. diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h index 74cf1616df..b87056573b 100644 --- a/indra/newview/llremoteparcelrequest.h +++ b/indra/newview/llremoteparcelrequest.h @@ -44,7 +44,7 @@ public:  	/*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*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  protected:  	LLHandle<LLRemoteParcelInfoObserver> mObserverHandle; diff --git a/indra/newview/llsaveoutfitcombobtn.cpp b/indra/newview/llsaveoutfitcombobtn.cpp index cbad85cfd3..32295cd96f 100644 --- a/indra/newview/llsaveoutfitcombobtn.cpp +++ b/indra/newview/llsaveoutfitcombobtn.cpp @@ -76,8 +76,8 @@ void LLSaveOutfitComboBtn::saveOutfit(bool as_new)  	if (panel_outfits_inventory)  	{  		panel_outfits_inventory->onSave(); -	} - +	} 	 +      	//*TODO how to get to know when base outfit is updated or new outfit is created?  } diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 154555b261..168a941ec3 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -730,7 +730,6 @@ void LLScreenChannel::showToastsTop()  	LLRect	toast_rect;	  	S32		top = channel_rect.mTop; -	S32		toast_margin = 0;  	std::vector<ToastElem>::reverse_iterator it;  	updateRect(); @@ -753,7 +752,7 @@ void LLScreenChannel::showToastsTop()  			}  			top = toast->getRect().mBottom - toast->getTopPad(); -			toast_margin = gSavedSettings.getS32("ToastGap"); +			gSavedSettings.getS32("ToastGap");  		}  		LLToast* toast = it->getToast(); diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp index 05b82ba967..a7e24b86b1 100644 --- a/indra/newview/llscrollingpanelparam.cpp +++ b/indra/newview/llscrollingpanelparam.cpp @@ -267,7 +267,7 @@ void LLScrollingPanelParam::onHintHeldDown( LLVisualParamHint* hint )  				&& new_percent < slider->getMaxValue())  			{  				mWearable->setVisualParamWeight( hint->getVisualParam()->getID(), new_weight, FALSE); -				mWearable->writeToAvatar(); +				mWearable->writeToAvatar(gAgentAvatarp);  				gAgentAvatarp->updateVisualParams();  				slider->setValue( weightToPercent( new_weight ) ); @@ -300,7 +300,7 @@ void LLScrollingPanelParam::onHintMinMouseUp( void* userdata )  				&& new_percent < slider->getMaxValue())  			{  				self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE); -				self->mWearable->writeToAvatar(); +				self->mWearable->writeToAvatar(gAgentAvatarp);  				slider->setValue( self->weightToPercent( new_weight ) );  			}  		} @@ -334,7 +334,7 @@ void LLScrollingPanelParam::onHintMaxMouseUp( void* userdata )  					&& new_percent < slider->getMaxValue())  				{  					self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE); -					self->mWearable->writeToAvatar(); +					self->mWearable->writeToAvatar(gAgentAvatarp);  					slider->setValue( self->weightToPercent( new_weight ) );  				}  			} diff --git a/indra/newview/llscrollingpanelparambase.cpp b/indra/newview/llscrollingpanelparambase.cpp index 62e3039d2f..8e083ddb6c 100644 --- a/indra/newview/llscrollingpanelparambase.cpp +++ b/indra/newview/llscrollingpanelparambase.cpp @@ -94,7 +94,7 @@ void LLScrollingPanelParamBase::onSliderMoved(LLUICtrl* ctrl, void* userdata)  	if (current_weight != new_weight )  	{  		self->mWearable->setVisualParamWeight( param->getID(), new_weight, FALSE ); -		self->mWearable->writeToAvatar(); +		self->mWearable->writeToAvatar(gAgentAvatarp);  		gAgentAvatarp->updateVisualParams();  	}  } diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index 30400a4c6a..928d26646b 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -1239,7 +1239,6 @@ void LLSecAPIBasicHandler::_readProtectedData()  									llifstream::binary);  	if (!protected_data_stream.fail()) { -		int offset;  		U8 salt[STORE_SALT_SIZE];  		U8 buffer[BUFFER_READ_SIZE];  		U8 decrypted_buffer[BUFFER_READ_SIZE]; @@ -1250,7 +1249,6 @@ void LLSecAPIBasicHandler::_readProtectedData()  		// read in the salt and key  		protected_data_stream.read((char *)salt, STORE_SALT_SIZE); -		offset = 0;  		if (protected_data_stream.gcount() < STORE_SALT_SIZE)  		{  			throw LLProtectedDataException("Config file too short."); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 343316d30a..4681efd3e5 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1180,7 +1180,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &  	if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount())  	{  		//LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject()); -		LLBBox bbox = mSavedSelectionBBox;  		mGridOrigin = mSavedSelectionBBox.getCenterAgent();  		mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f; @@ -1198,7 +1197,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &  	else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull())  	{  		mGridRotation = first_grid_object->getRenderRotation(); -		LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition();  		LLVector4a min_extents(F32_MAX);  		LLVector4a max_extents(-F32_MAX); @@ -1605,7 +1603,7 @@ 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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));  			}  			return true;  		} @@ -1771,7 +1769,7 @@ BOOL LLSelectMgr::selectionRevertTextures()  					}  					else  					{ -						object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); +						object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));  					}  				}  			} @@ -5185,7 +5183,7 @@ void LLSelectMgr::updateSilhouettes()  	if (!mSilhouetteImagep)  	{ -		mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", TRUE, LLViewerTexture::BOOST_UI); +		mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI);  	}  	mHighlightedObjects->cleanupNodes(); diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index adb97ac800..74fa5a87bb 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -47,7 +47,7 @@  #include "llviewercontrol.h"  #include "llviewerregion.h"  #include "llvoavatarself.h" -#include "llwearable.h" +#include "llviewerwearable.h"  static LLRegisterPanelClassWrapper<LLSidepanelAppearance> t_appearance("sidepanel_appearance"); @@ -198,7 +198,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)  		if (is_outfit_edit_visible || is_wearable_edit_visible)  		{ -			const LLWearable *wearable_ptr = mEditWearable->getWearable(); +			const LLViewerWearable *wearable_ptr = mEditWearable->getWearable();  			if (!wearable_ptr)  			{  				llwarns << "Visibility change to invalid wearable" << llendl; @@ -206,12 +206,9 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)  			}  			// Disable camera switch is currently just for WT_PHYSICS type since we don't want to freeze the avatar  			// when editing its physics. -			const BOOL disable_camera_motion = LLWearableType::getDisableCameraSwitch(wearable_ptr->getType()); -			if (!gAgentCamera.cameraCustomizeAvatar() &&  -				!disable_camera_motion && -				gSavedSettings.getBOOL("AppearanceCameraMovement")) +			if (!gAgentCamera.cameraCustomizeAvatar())  			{ -				gAgentCamera.changeCameraToCustomizeAvatar(); +				LLVOAvatarSelf::onCustomizeStart(LLWearableType::getDisableCameraSwitch(wearable_ptr->getType()));  			}  			if (is_wearable_edit_visible)  			{ @@ -234,7 +231,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)  		{  			gAgentCamera.changeCameraToDefault();  			gAgentCamera.resetView(); -		} +		}	  	}  } @@ -283,7 +280,7 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked()  {  	if (gAgentWearables.areWearablesLoaded())  	{ -		gAgentCamera.changeCameraToCustomizeAvatar(); +		LLVOAvatarSelf::onCustomizeStart();  	}  } @@ -329,7 +326,7 @@ void LLSidepanelAppearance::showOutfitEditPanel()  	toggleOutfitEditPanel(TRUE);  } -void LLSidepanelAppearance::showWearableEditPanel(LLWearable *wearable /* = NULL*/, BOOL disable_camera_switch) +void LLSidepanelAppearance::showWearableEditPanel(LLViewerWearable *wearable /* = NULL*/, BOOL disable_camera_switch)  {  	toggleMyOutfitsPanel(FALSE);  	toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode @@ -371,19 +368,19 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_cam  	if (visible)  	{  		mOutfitEdit->onOpen(LLSD()); -		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) -		{ -			gAgentCamera.changeCameraToCustomizeAvatar(); -		} +		LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);  	} -	else if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) +	else   	{ -		gAgentCamera.changeCameraToDefault(); -		gAgentCamera.resetView(); +		if (!disable_camera_switch)   // if we're just switching between outfit and wearable editing, don't end customization. +		{ +			LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch); +			LLAppearanceMgr::getInstance()->updateIsDirty(); +		}  	}  } -void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable, BOOL disable_camera_switch) +void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearable *wearable, BOOL disable_camera_switch)  {  	if (!mEditWearable || mEditWearable->getVisible() == visible)  	{ @@ -393,7 +390,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we  	if (!wearable)  	{ -		wearable = gAgentWearables.getWearable(LLWearableType::WT_SHAPE, 0); +		wearable = gAgentWearables.getViewerWearable(LLWearableType::WT_SHAPE, 0);  	}  	if (!wearable)  	{ @@ -405,10 +402,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we  	if (visible)  	{ -		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) -		{ -			gAgentCamera.changeCameraToCustomizeAvatar(); -		} +		LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);  		mEditWearable->setWearable(wearable, disable_camera_switch);  		mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency  	} @@ -416,10 +410,10 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we  	{  		// Save changes if closing.  		mEditWearable->saveChanges(); -		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) +		LLAppearanceMgr::getInstance()->updateIsDirty(); +		if (!disable_camera_switch)   // if we're just switching between outfit and wearable editing, don't end customization.  		{ -			gAgentCamera.changeCameraToDefault(); -			gAgentCamera.resetView(); +			LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch);  		}  	}  } @@ -453,13 +447,12 @@ void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name)  }  //static -void LLSidepanelAppearance::editWearable(LLWearable *wearable, LLView *data, BOOL disable_camera_switch) +void LLSidepanelAppearance::editWearable(LLViewerWearable *wearable, LLView *data, BOOL disable_camera_switch)  {  	LLFloaterSidePanelContainer::showPanel("appearance", LLSD());  	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(data);  	if (panel)  	{ -		panel->showOutfitsInventoryPanel();  		panel->showWearableEditPanel(wearable, disable_camera_switch);  	}  } diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 6dd3520266..762f557a80 100644 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -36,7 +36,7 @@  class LLFilterEditor;  class LLCurrentlyWornFetchObserver;  class LLPanelEditWearable; -class LLWearable; +class LLViewerWearable;  class LLPanelOutfitsInventory;  class LLSidepanelAppearance : public LLPanel @@ -47,11 +47,11 @@ public:  	virtual ~LLSidepanelAppearance();  	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void onOpen(const LLSD& key); +	/*virtual*/ void onOpen(const LLSD& key);	  	void refreshCurrentOutfitName(const std::string& name = ""); -	static void editWearable(LLWearable *wearable, LLView *data, BOOL disable_camera_switch = FALSE); +	static void editWearable(LLViewerWearable *wearable, LLView *data, BOOL disable_camera_switch = FALSE);  	void fetchInventory();  	void inventoryFetched(); @@ -59,11 +59,12 @@ public:  	void showOutfitsInventoryPanel();  	void showOutfitEditPanel(); -	void showWearableEditPanel(LLWearable *wearable = NULL, BOOL disable_camera_switch = FALSE); +	void showWearableEditPanel(LLViewerWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);  	void setWearablesLoading(bool val);  	void showDefaultSubpart();  	void updateScrollingPanelList();  	void updateToVisibility( const LLSD& new_visibility ); +	LLPanelEditWearable* getWearable(){ return mEditWearable; }  private:  	void onFilterEdit(const std::string& search_string); @@ -74,7 +75,7 @@ private:  	void toggleMyOutfitsPanel(BOOL visible);  	void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE); -	void toggleWearableEditPanel(BOOL visible, LLWearable* wearable = NULL, BOOL disable_camera_switch = FALSE); +	void toggleWearableEditPanel(BOOL visible, LLViewerWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);  	LLFilterEditor*			mFilterEditor;  	LLPanelOutfitsInventory* mPanelOutfitsInventory; diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 5532bdc71a..ad7c939728 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -370,10 +370,8 @@ void LLSidepanelTaskInfo::refresh()  	// Update creator text field  	getChildView("Creator:")->setEnabled(TRUE); -	BOOL creators_identical;  	std::string creator_name; -	creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, -																	  creator_name); +	LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name);  	getChild<LLUICtrl>("Creator Name")->setValue(creator_name);  	getChildView("Creator Name")->setEnabled(TRUE); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 3ed6e24498..f85e855fd3 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3544,9 +3544,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); @@ -3998,7 +3998,7 @@ void renderAgentTarget(LLVOAvatar* avatar)  	{  		renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));  		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f)); -		renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f)); +		renderCrossHairs(avatar->mRoot->getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));  		renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));  	}  } @@ -4062,9 +4062,6 @@ public:  			return;  		} -		LLVector4a nodeCenter = group->mBounds[0]; -		LLVector4a octCenter = group->mOctreeNode->getCenter(); -  		group->rebuildGeom();  		group->rebuildMesh(); @@ -4539,9 +4536,6 @@ public:  	virtual bool check(LLDrawable* drawable)  	{	 -		LLVector3 local_start = mStart; -		LLVector3 local_end = mEnd; -  		if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())  		{  			return false; diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 8783d99b11..a4582071e8 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -853,7 +853,10 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)  		}  	}  } - +/*prep# +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content) +		llwarns << "ModerationResponder error [status:" << status << "]: " << content << llendl; +		*/  void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)  {  	LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 37e6ded986..8b71f1067f 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -316,7 +316,6 @@ bool idle_startup()  {  	const F32 PRECACHING_DELAY = gSavedSettings.getF32("PrecachingDelay");  	static LLTimer timeout; -	static S32 timeout_count = 0;  	static LLTimer login_time; @@ -332,7 +331,6 @@ bool idle_startup()  	// last location by default  	static S32  agent_location_id = START_LOCATION_ID_LAST; -	static S32  location_which = START_LOCATION_ID_LAST;  	static bool show_connect_box = true; @@ -744,8 +742,6 @@ bool idle_startup()  		gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); -		timeout_count = 0; -  		// Login screen needs menus for preferences, but we can enter  		// this startup phase more than once.  		if (gLoginMenuBarView == NULL) @@ -772,10 +768,6 @@ bool idle_startup()  				gUserCredential = gLoginHandler.initializeLoginInfo();                   				display_startup();  			}      -			if (gHeadlessClient) -			{ -				LL_WARNS("AppInit") << "Waiting at connection box in headless client.  Did you mean to add autologin params?" << LL_ENDL; -			}  			// Make sure the process dialog doesn't hide things  			display_startup();  			gViewerWindow->setShowProgress(FALSE); @@ -993,15 +985,12 @@ bool idle_startup()  		  {  		  case LLSLURL::LOCATION:  		    agent_location_id = START_LOCATION_ID_URL; -		    location_which = START_LOCATION_ID_LAST;  		    break;  		  case LLSLURL::LAST_LOCATION:  		    agent_location_id = START_LOCATION_ID_LAST; -		    location_which = START_LOCATION_ID_LAST;  		    break;  		  default:  		    agent_location_id = START_LOCATION_ID_HOME; -		    location_which = START_LOCATION_ID_HOME;  		    break;  		  } @@ -1254,6 +1243,9 @@ bool idle_startup()  		LLPostProcess::initClass();  		display_startup(); +		LLAvatarAppearance::initClass(); +		display_startup(); +  		LLViewerObject::initVOClasses();  		display_startup(); @@ -2588,12 +2580,17 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,  	}  	else  	{ +		// FIXME SH-3860 - this creates a race condition, where COF +		// changes (base outfit link added) after appearance update +		// request has been submitted.  		sWearablesLoadedCon = gAgentWearables.addLoadedCallback(LLStartUp::saveInitialOutfit);  		bool do_copy = true;  		bool do_append = false;  		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); -		LLAppearanceMgr::instance().wearInventoryCategory(cat, do_copy, do_append); +		// Need to fetch cof contents before we can wear. +		callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(), +							   boost::bind(&LLAppearanceMgr::wearInventoryCategory, LLAppearanceMgr::getInstance(), cat, do_copy, do_append));  		lldebugs << "initial outfit category id: " << cat_id << llendl;  	} @@ -3455,6 +3452,14 @@ bool process_login_success_response()  	} +	// 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()) +	{ +		LLAppearanceMgr::instance().setAppearanceServiceURL(agent_appearance_url); +	} +  	// Set the location of the snapshot sharing config endpoint  	std::string snapshot_config_url = response["snapshot_config_url"];  	if(!snapshot_config_url.empty()) @@ -3499,13 +3504,6 @@ bool process_login_success_response()  void transition_back_to_login_panel(const std::string& emsg)  { -	if (gHeadlessClient && gSavedSettings.getBOOL("AutoLogin")) -	{ -		LL_WARNS("AppInit") << "Failed to login!" << LL_ENDL; -		LL_WARNS("AppInit") << emsg << LL_ENDL; -		exit(0); -	} -  	// Bounce back to the login screen.  	reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );  	gSavedSettings.setBOOL("AutoLogin", FALSE); diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index ec11a23eb8..93c7f54101 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -1246,8 +1246,6 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y,  		y_end = tex_width;  	} -	LLVector3d origin_global = from_region_handle(getRegion()->getHandle()); -  	// OK, for now, just have the composition value equal the height at the point.  	LLVector3 location;  	LLColor4U coloru; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 007eb8e33f..e2d0fdf357 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -571,8 +571,8 @@ void LLFloaterTexturePicker::draw()  		mTexturep = NULL;  		if(mImageAssetID.notNull())  		{ -			mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES); -			mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); +			mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID); +			mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);  		}  		if (mTentativeLabel) @@ -1442,9 +1442,9 @@ void LLTextureCtrl::draw()  	}  	else if (!mImageAssetID.isNull())  	{ -		LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES,LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +		LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES,LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); -		texture->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); +		texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW);  		texture->forceToSaveRawImage(0) ;  		mTexturep = texture; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 7de66b139f..be5fde9e2b 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -389,7 +389,8 @@ public:  	virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);  protected: -	LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host, +	LLTextureFetchWorker(LLTextureFetch* fetcher, FTType f_type, +						 const std::string& url, const LLUUID& id, const LLHost& host,  						 F32 priority, S32 discard, S32 size);  private: @@ -501,11 +502,13 @@ private:  	};  	static const char* sStateDescs[];  	e_state mState; +	void setState(e_state new_state);  	e_write_to_cache_state mWriteToCacheState;  	LLTextureFetch* mFetcher;  	LLPointer<LLImageFormatted> mFormattedImage;  	LLPointer<LLImageRaw> mRawImage;  	LLPointer<LLImageRaw> mAuxImage; +	FTType mFTType;  	LLUUID mID;  	LLHost mHost;  	std::string mUrl; @@ -827,6 +830,7 @@ volatile bool LLTextureFetch::svMetricsDataBreak(true);	// Start with a data bre  // called from MAIN THREAD  LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, +										   FTType f_type, // Fetched image type  										   const std::string& url, // Optional URL  										   const LLUUID& id,	// Image UUID  										   const LLHost& host,	// Simulator host @@ -838,6 +842,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,  	  mState(INIT),  	  mWriteToCacheState(NOT_WRITE),  	  mFetcher(fetcher), +	  mFTType(f_type),  	  mID(id),  	  mHost(host),  	  mUrl(url), @@ -1024,7 +1029,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)  	mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE);  	if ((prioritize && mState == INIT) || mState == DONE)  	{ -		mState = INIT; +		setState(INIT);  		U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;  		setPriority(work_priority);  	} @@ -1088,12 +1093,14 @@ bool LLTextureFetchWorker::doWork(S32 param)  	{  		if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)  		{ +			LL_DEBUGS("Texture") << mID << " abort: mImagePriority < F_ALMOST_ZERO" << llendl;  			return true; // abort  		}  	}  	if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)  	{  		//nowhere to get data, abort. +		LL_WARNS("Texture") << mID << " abort, nowhere to get data" << llendl;  		return true ;  	} @@ -1136,7 +1143,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		clearPackets(); // TODO: Shouldn't be necessary  		mCacheReadHandle = LLTextureCache::nullHandle();  		mCacheWriteHandle = LLTextureCache::nullHandle(); -		mState = LOAD_FROM_TEXTURE_CACHE; +		setState(LOAD_FROM_TEXTURE_CACHE);  		mInCache = FALSE;  		mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE  		LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority) @@ -1153,7 +1160,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			S32 size = mDesiredSize - offset;  			if (size <= 0)  			{ -				mState = CACHE_POST; +				setState(CACHE_POST);  				return false;  			}  			mFileSize = 0; @@ -1171,6 +1178,8 @@ bool LLTextureFetchWorker::doWork(S32 param)  																		  offset, size, responder);  				mCacheReadTimer.reset();  			} +/* SH-3980 - disabling caching of server bakes until we can fix the blurring problems */ +/*			else if ((mUrl.empty()||mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache()) */  			else if (mUrl.empty() && mFetcher->canLoadFromCache())  			{  				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it @@ -1183,18 +1192,13 @@ bool LLTextureFetchWorker::doWork(S32 param)  			}  			else if(!mUrl.empty() && mCanUseHTTP)  			{ -				if (!(mUrl.compare(0, 7, "http://") == 0)) -				{ -					// *TODO:?remove this warning -					llwarns << "Unknown URL Type: " << mUrl << llendl; -				}  				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -				mState = WAIT_HTTP_RESOURCE; +				setState(WAIT_HTTP_RESOURCE);  			}  			else  			{  				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -				mState = LOAD_FROM_NETWORK; +				setState(LOAD_FROM_NETWORK);  			}  		} @@ -1204,7 +1208,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			if (mFetcher->mTextureCache->readComplete(mCacheReadHandle, false))  			{  				mCacheReadHandle = LLTextureCache::nullHandle(); -				mState = CACHE_POST; +				setState(CACHE_POST);  				// fall through  			}  			else @@ -1212,6 +1216,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				//  				//This should never happen  				// +				LL_DEBUGS("Texture") << mID << " this should never happen" << llendl;  				return false;  			}  		} @@ -1230,7 +1235,12 @@ bool LLTextureFetchWorker::doWork(S32 param)  			// we have enough data, decode it  			llassert_always(mFormattedImage->getDataSize() > 0);  			mLoadedDiscard = mDesiredDiscard; -			mState = DECODE_IMAGE; +			if (mLoadedDiscard < 0) +			{ +				LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard +									<< ", should be >=0" << llendl; +			} +			setState(DECODE_IMAGE);  			mInCache = TRUE;  			mWriteToCacheState = NOT_WRITE ;  			LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() @@ -1243,13 +1253,14 @@ bool LLTextureFetchWorker::doWork(S32 param)  			if (mUrl.compare(0, 7, "file://") == 0)  			{  				// failed to load local file, we're done. +				LL_WARNS("Texture") << mID << ": abort, failed to load local file " << mUrl << LL_ENDL;  				return true;  			}  			// need more data  			else  			{  				LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL; -				mState = LOAD_FROM_NETWORK; +				setState(LOAD_FROM_NETWORK);  			}  			// fall through @@ -1290,9 +1301,15 @@ bool LLTextureFetchWorker::doWork(S32 param)  				mCanUseHTTP = false;  			}  		} +#if 0 /* SH-3980 - disabling caching of server bakes until we can fix the blurring problems */ +		if (mFTType == FTT_SERVER_BAKE) +		{ +			mWriteToCacheState = CAN_WRITE; +		} +#endif  		if (mCanUseHTTP && !mUrl.empty())  		{ -			mState = WAIT_HTTP_RESOURCE; +			setState(WAIT_HTTP_RESOURCE);  			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  			if(mWriteToCacheState != NOT_WRITE)  			{ @@ -1322,6 +1339,8 @@ bool LLTextureFetchWorker::doWork(S32 param)  			//mFetcher->addToNetworkQueue(this);  			//recordTextureStart(false);  			//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); + +			LL_DEBUGS("Texture") << mID << " does this happen?" << llendl;  			return false;  		}  	} @@ -1340,10 +1359,16 @@ bool LLTextureFetchWorker::doWork(S32 param)  			{  				// processSimulatorPackets() failed  // 				llwarns << "processSimulatorPackets() failed to load buffer" << llendl; +				LL_WARNS("Texture") << mID << " processSimulatorPackets() failed to load buffer" << llendl;  				return true; // failed  			}  			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -			mState = DECODE_IMAGE; +			if (mLoadedDiscard < 0) +			{ +				LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard +									<< ", should be >=0" << llendl; +			} +			setState(DECODE_IMAGE);  			mWriteToCacheState = SHOULD_WRITE;  			recordTextureDone(false);  		} @@ -1367,14 +1392,14 @@ bool LLTextureFetchWorker::doWork(S32 param)  		// Otherwise, advance into the HTTP states.  		if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore())  		{ -			mState = WAIT_HTTP_RESOURCE2; +			setState(WAIT_HTTP_RESOURCE2);  			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);  			mFetcher->addHttpWaiter(this->mID);  			++mResourceWaitCount;  			return false;  		} -		mState = SEND_HTTP_REQ; +		setState(SEND_HTTP_REQ);  		// *NOTE:  You must invoke releaseHttpSemaphore() if you transition  		// to a state other than SEND_HTTP_REQ or WAIT_HTTP_REQ or abort  		// the request. @@ -1391,6 +1416,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		if (! mCanUseHTTP)  		{  			releaseHttpSemaphore(); +			LL_WARNS("Texture") << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << llendl;  			return true; // abort  		} @@ -1407,13 +1433,19 @@ bool LLTextureFetchWorker::doWork(S32 param)  					// We already have all the data, just decode it  					mLoadedDiscard = mFormattedImage->getDiscardLevel();  					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -					mState = DECODE_IMAGE; +					if (mLoadedDiscard < 0) +					{ +						LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard +											<< ", should be >=0" << llendl; +					} +					setState(DECODE_IMAGE);  					releaseHttpSemaphore();  					return false;  				}  				else  				{  					releaseHttpSemaphore(); +					LL_WARNS("Texture") << mID << " SEND_HTTP_REQ abort: cur_size " << cur_size << " <=0" << llendl;  					return true; // abort.  				}  			} @@ -1471,7 +1503,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		mFetcher->addToHTTPQueue(mID);  		recordTextureStart(true);  		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); -		mState = WAIT_HTTP_REQ;	 +		setState(WAIT_HTTP_REQ);	  		// fall through  	} @@ -1489,8 +1521,9 @@ bool LLTextureFetchWorker::doWork(S32 param)  				{  					if(mWriteToCacheState == NOT_WRITE) //map tiles  					{ -						mState = DONE; +						setState(DONE);  						releaseHttpSemaphore(); +						LL_DEBUGS("Texture") << mID << " abort: WAIT_HTTP_REQ not found" << llendl;  						return true; // failed, means no map tile on the empty region.  					} @@ -1499,7 +1532,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  					// roll back to try UDP  					if (mCanUseNET)  					{ -						mState = INIT; +						setState(INIT);  						mCanUseHTTP = false;  						mUrl.clear();  						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); @@ -1530,15 +1563,21 @@ bool LLTextureFetchWorker::doWork(S32 param)  					// Use available data  					mLoadedDiscard = mFormattedImage->getDiscardLevel();  					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -					mState = DECODE_IMAGE; +					if (mLoadedDiscard < 0) +					{ +						LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard +											<< ", should be >=0" << llendl; +					} +					setState(DECODE_IMAGE);  					releaseHttpSemaphore();  					return false;   				}  				// Fail harder  				resetFormattedData(); -				mState = DONE; +				setState(DONE);  				releaseHttpSemaphore(); +				LL_WARNS("Texture") << mID << " abort: fail harder" << llendl;  				return true; // failed  			} @@ -1547,6 +1586,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			// next time the texture is requested, even if the data have already been fetched.  			if(mWriteToCacheState != NOT_WRITE)  			{ +				// Why do we want to keep url if NOT_WRITE - is this a proxy for map tiles?  				mUrl.clear();  			} @@ -1560,7 +1600,8 @@ bool LLTextureFetchWorker::doWork(S32 param)  				}  				// abort. -				mState = DONE; +				setState(DONE); +				LL_WARNS("Texture") << mID << " abort: no data received" << llendl;  				releaseHttpSemaphore();  				return true;  			} @@ -1578,7 +1619,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				{  					LL_WARNS("Texture") << "Partial HTTP response produces break in image data for texture "  										<< mID << ".  Aborting load."  << LL_ENDL; -					mState = DONE; +					setState(DONE);  					releaseHttpSemaphore();  					return true;  				} @@ -1626,7 +1667,12 @@ bool LLTextureFetchWorker::doWork(S32 param)  			mHttpReplyOffset = 0;  			mLoadedDiscard = mRequestedDiscard; -			mState = DECODE_IMAGE; +			if (mLoadedDiscard < 0) +			{ +				LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard +									<< ", should be >=0" << llendl; +			} +			setState(DECODE_IMAGE);  			if (mWriteToCacheState != NOT_WRITE)  			{  				mWriteToCacheState = SHOULD_WRITE ; @@ -1657,31 +1703,34 @@ bool LLTextureFetchWorker::doWork(S32 param)  		if (textures_decode_disabled)  		{  			// for debug use, don't decode -			mState = DONE; +			setState(DONE);  			return true;  		}  		if (mDesiredDiscard < 0)  		{  			// We aborted, don't decode -			mState = DONE; +			setState(DONE); +			LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: desired discard " << mDesiredDiscard << "<0" << llendl;  			return true;  		}  		if (mFormattedImage->getDataSize() <= 0)  		{ -			//llerrs << "Decode entered with invalid mFormattedImage. ID = " << mID << llendl; +			llwarns << "Decode entered with invalid mFormattedImage. ID = " << mID << llendl;  			//abort, don't decode -			mState = DONE; +			setState(DONE); +			LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: (mFormattedImage->getDataSize() <= 0)" << llendl;  			return true;  		}  		if (mLoadedDiscard < 0)  		{ -			//llerrs << "Decode entered with invalid mLoadedDiscard. ID = " << mID << llendl; +			llwarns << "Decode entered with invalid mLoadedDiscard. ID = " << mID << llendl;  			//abort, don't decode -			mState = DONE; +			setState(DONE); +			LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: mLoadedDiscard < 0" << llendl;  			return true;  		} @@ -1691,7 +1740,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		S32 discard = mHaveAllData ? 0 : mLoadedDiscard;  		U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;  		mDecoded  = FALSE; -		mState = DECODE_IMAGE_UPDATE; +		setState(DECODE_IMAGE_UPDATE);  		LL_DEBUGS("Texture") << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard  				<< " All Data: " << mHaveAllData << LL_ENDL;  		mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux, @@ -1719,13 +1768,13 @@ bool LLTextureFetchWorker::doWork(S32 param)  					mFormattedImage = NULL;  					++mRetryAttempt;  					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -					mState = INIT; +					setState(INIT);  					return false;  				}  				else  				{  // 					llwarns << "UNABLE TO LOAD TEXTURE: " << mID << " RETRIES: " << mRetryAttempt << llendl; -					mState = DONE; // failed +					setState(DONE); // failed  				}  			}  			else @@ -1734,7 +1783,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				LL_DEBUGS("Texture") << mID << ": Decoded. Discard: " << mDecodedDiscard  						<< " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL;  				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -				mState = WRITE_TO_CACHE; +				setState(WRITE_TO_CACHE);  			}  			// fall through  		} @@ -1750,7 +1799,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		{  			// If we're in a local cache or we didn't actually receive any new data,  			// or we failed to load anything, skip -			mState = DONE; +			setState(DONE);  			return false;  		}  		S32 datasize = mFormattedImage->getDataSize(); @@ -1769,7 +1818,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it  		U32 cache_priority = mWorkPriority;  		mWritten = FALSE; -		mState = WAIT_ON_WRITE; +		setState(WAIT_ON_WRITE);  		++mCacheWriteCount;  		CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID);  		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority, @@ -1782,7 +1831,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  	{  		if (writeToCacheComplete())  		{ -			mState = DONE; +			setState(DONE);  			// fall through  		}  		else @@ -1803,7 +1852,10 @@ bool LLTextureFetchWorker::doWork(S32 param)  		if (mDecodedDiscard >= 0 && mDesiredDiscard < mDecodedDiscard)  		{  			// More data was requested, return to INIT -			mState = INIT; +			setState(INIT); +			LL_DEBUGS("Texture") << mID << " more data requested, returning to INIT: "  +								 << " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard +								 << "<" << " mDecodedDiscard " << mDecodedDiscard << llendl;  			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  			return false;  		} @@ -1843,10 +1895,10 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe  	bool partial = false;  	LLCore::HttpStatus status(response->getStatus()); -	lldebugs << "HTTP COMPLETE: " << mID -			 << " status: " << status.toHex() -			 << " '" << status.toString() << "'" -			 << llendl; +	LL_DEBUGS("Texture") << "HTTP COMPLETE: " << mID +						 << " status: " << status.toHex() +						 << " '" << status.toString() << "'" +						 << llendl;  //	unsigned int offset(0), length(0), full_length(0);  //	response->getRange(&offset, &length, &full_length);  // 	llwarns << "HTTP COMPLETE: " << mID << " handle: " << handle @@ -2401,7 +2453,7 @@ LLTextureFetch::~LLTextureFetch()  	// ~LLQueuedThread() called here  } -bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, +bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,  								   S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)  {  	if(mFetcherLocked) @@ -2430,6 +2482,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con  	std::string exten = gDirUtilp->getExtension(url);  	if (!url.empty() && (!exten.empty() && LLImageBase::getCodecFromExtension(exten) != IMG_CODEC_J2C))  	{ +		LL_DEBUGS("Texture") << "full request for " << id << " exten is not J2C: " << exten << llendl;  		// Only do partial requests for J2C at the moment  		desired_size = MAX_IMAGE_DATA_SIZE;  		desired_discard = 0; @@ -2472,7 +2525,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con  		worker->setCanUseHTTP(can_use_http) ;  		if (!worker->haveWork())  		{ -			worker->mState = LLTextureFetchWorker::INIT; +			worker->setState(LLTextureFetchWorker::INIT);  			worker->unlockWorkMutex();									// -Mw  			worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); @@ -2484,7 +2537,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con  	}  	else  	{ -		worker = new LLTextureFetchWorker(this, url, id, host, priority, desired_discard, desired_size); +		worker = new LLTextureFetchWorker(this, f_type, url, id, host, priority, desired_discard, desired_size);  		lockQueue();													// +Mfq  		mRequestMap[id] = worker;  		unlockQueue();													// -Mfq @@ -2496,7 +2549,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con  		worker->unlockWorkMutex();										// -Mw  	} -// 	llinfos << "REQUESTED: " << id << " Discard: " << desired_discard << llendl; + 	LL_DEBUGS("Texture") << "REQUESTED: " << id << " Discard: " << desired_discard << " size " << desired_size << llendl;  	return true;  } @@ -3165,6 +3218,30 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)  	return true;  } +void LLTextureFetchWorker::setState(e_state new_state) +{ +	static const char* e_state_name[] = +	{ +		"INVALID", +		"INIT", +		"LOAD_FROM_TEXTURE_CACHE", +		"CACHE_POST", +		"LOAD_FROM_NETWORK", +		"LOAD_FROM_SIMULATOR", +		"WAIT_HTTP_RESOURCE", +		"WAIT_HTTP_RESOURCE2", +		"SEND_HTTP_REQ", +		"WAIT_HTTP_REQ", +		"DECODE_IMAGE", +		"DECODE_IMAGE_UPDATE", +		"WRITE_TO_CACHE", +		"WAIT_ON_WRITE", +		"DONE" +	}; +	LL_DEBUGS("Texture") << "id: " << mID << " FTType: " << mFTType << " disc: " << mDesiredDiscard << " sz: " << mDesiredSize << " state: " << e_state_name[mState] << " => " << e_state_name[new_state] << llendl; +	mState = new_state; +} +  // Threads:  T*  bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,  										U16 data_size, U8* data) @@ -3221,7 +3298,7 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8  	llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);  	res = worker->insertPacket(0, data, data_size);  	worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); -	worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR; +	worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);  	worker->unlockWorkMutex();											// -Mw  	return res;  } @@ -3271,7 +3348,7 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1  		(worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))  	{  		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); -		worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR; +		worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);  	}  	else  	{ @@ -3534,7 +3611,7 @@ void LLTextureFetch::releaseHttpWaiters()  			break;  		} -		worker->mState = LLTextureFetchWorker::SEND_HTTP_REQ; +		worker->setState(LLTextureFetchWorker::SEND_HTTP_REQ);  		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);  		worker->unlockWorkMutex();										// -Mw diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 5ea3c14e1a..902a3d7a25 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -44,8 +44,8 @@  #include "httpoptions.h"  #include "httpheaders.h"  #include "httphandler.h" +#include "llviewertexture.h" -class LLViewerTexture;  class LLTextureFetchWorker;  class LLImageDecodeThread;  class LLHost; @@ -77,7 +77,7 @@ public:  	void shutDownImageDecodeThread();  	// Threads:  T* (but Tmain mostly) -	bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, +	bool createRequest(FTType f_type, 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);  	// Requests that a fetch operation be deleted from the queue. diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 16c42dbd43..e80136b286 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -40,7 +40,7 @@  #include "lltooltip.h"  #include "llappviewer.h"  #include "llselectmgr.h" -#include "lltexlayer.h" +#include "llviewertexlayer.h"  #include "lltexturecache.h"  #include "lltexturefetch.h"  #include "llviewercontrol.h" @@ -170,7 +170,7 @@ void LLTextureBar::draw()  	{  		color = LLColor4::green4;  	} -	else if (mImagep->getBoostLevel() > LLViewerTexture::BOOST_NONE) +	else if (mImagep->getBoostLevel() > LLGLTexture::BOOST_NONE)  	{  		color = LLColor4::magenta;  	} @@ -420,14 +420,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 = 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/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index 4dc0d424ac..beb45e8179 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -33,6 +33,7 @@  #include "llbutton.h"  #include "lliconctrl.h"  #include "llinventoryfunctions.h" +#include "llinventoryicon.h"  #include "llnotifications.h"  #include "llviewertexteditor.h" diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 4ef5ad845c..8bfde2bcf1 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -207,8 +207,6 @@ void LLToastNotifyPanel::adjustPanelForScriptNotice(S32 button_panel_width, S32  void LLToastNotifyPanel::adjustPanelForTipNotice()  { -	LLRect info_rect = mInfoPanel->getRect(); -	LLRect this_rect = getRect();  	//we don't need display ControlPanel for tips because they doesn't contain any buttons.   	mControlPanel->setVisible(FALSE);  	reshape(getRect().getWidth(), mInfoPanel->getRect().getHeight()); diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp index aba43a9715..08d82ea9cb 100644 --- a/indra/newview/lltoolbrush.cpp +++ b/indra/newview/lltoolbrush.cpp @@ -657,7 +657,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/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 923fbecb1a..5270c3d33f 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -471,7 +471,7 @@ BOOL LLToolCompCreate::handleMouseDown(S32 x, S32 y, MASK mask)  	mObjectPlacedOnMouseDown = TRUE; -	return TRUE; +	return handled;  }  void LLToolCompCreate::pickCallback(const LLPickInfo& pick_info) diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 94c97158a8..e085834326 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1247,7 +1247,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();  	//} @@ -1741,7 +1741,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(  	{  		if(mSource == SOURCE_LIBRARY)  		{ -			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0); +			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));  			copy_inventory_item(  				gAgent.getID(),  				item->getPermissions().getOwner(), @@ -2094,7 +2094,7 @@ EAcceptance LLToolDragAndDrop::dad3dActivateGesture(  			{  				// create item based on that one, and put it on if that  				// was a success. -				LLPointer<LLInventoryCallback> cb = new ActivateGestureCallback(); +				LLPointer<LLInventoryCallback> 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 a754d8ee7e..857b0f0714 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -314,8 +314,6 @@ 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); @@ -323,19 +321,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/lltoolgun.cpp b/indra/newview/lltoolgun.cpp index 857d105361..c1735adc9c 100644 --- a/indra/newview/lltoolgun.cpp +++ b/indra/newview/lltoolgun.cpp @@ -42,7 +42,7 @@  #include "llhudmanager.h"  #include "lltoolmgr.h"  #include "lltoolgrab.h" - +#include "lluiimage.h"  // Linden library includes  #include "llwindow.h"			// setMouseClipping() diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 0d5daf129f..148e5a015b 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -34,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" diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index f24891baf6..fc9a316759 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -791,14 +791,10 @@ BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)  	LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();  	LLUUID owner; -	S32 width = 0; -	S32 height = 0;  	if ( hover_parcel )  	{  		owner = hover_parcel->getOwnerID(); -		width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth()); -		height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight());  	}  	// Line: "Land" @@ -1593,9 +1589,6 @@ BOOL LLToolPie::handleRightClickPick()  	// didn't click in any UI object, so must have clicked in the world  	LLViewerObject *object = mPick.getObject(); -	LLViewerObject *parent = NULL; -	if(object) -		parent = object->getRootEdit();  	// Can't ignore children here.  	LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE); diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index 93ba3b2558..641fbc5042 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -182,7 +182,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();  	} @@ -485,7 +485,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/lluploadfloaterobservers.cpp b/indra/newview/lluploadfloaterobservers.cpp index 5a6a17fbca..1d777b3f7f 100644 --- a/indra/newview/lluploadfloaterobservers.cpp +++ b/indra/newview/lluploadfloaterobservers.cpp @@ -33,9 +33,10 @@ LLUploadModelPremissionsResponder::LLUploadModelPremissionsResponder(const LLHan  {  } -void LLUploadModelPremissionsResponder::error(U32 status, const std::string& reason) +void LLUploadModelPremissionsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	llwarns << "LLUploadModelPremissionsResponder::error("<< status << ": " << reason << ")" << llendl; +	llwarns << "LLUploadModelPremissionsResponder error [status:" +			<< status << "]: " << content << llendl;  	LLUploadPermissionsObserver* observer = mObserverHandle.get(); diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h index 79aad282d7..b43ddb44d9 100644 --- a/indra/newview/lluploadfloaterobservers.h +++ b/indra/newview/lluploadfloaterobservers.h @@ -86,7 +86,7 @@ public:  	LLUploadModelPremissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer); -	void error(U32 status, const std::string& reason); +	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  	void result(const LLSD& content); diff --git a/indra/newview/llurlhistory.cpp b/indra/newview/llurlhistory.cpp index edec30f8c4..dd17068be5 100644 --- a/indra/newview/llurlhistory.cpp +++ b/indra/newview/llurlhistory.cpp @@ -112,8 +112,6 @@ void LLURLHistory::addURL(const std::string& collection, const std::string& url)  // static  void LLURLHistory::removeURL(const std::string& collection, const std::string& url)  { -	LLSD::array_iterator iter = sHistorySD[collection].beginArray(); -	LLSD::array_iterator end = sHistorySD[collection].endArray();  	for(int index = 0; index < sHistorySD[collection].size(); index++)  	{  		if(sHistorySD[collection].get(index).asString() == url) diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 4c59fd0371..aaa81c57d4 100644..100755 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -160,9 +160,7 @@ LLViewerAssetStats::LLViewerAssetStats()  LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src)  	: mRegionHandle(src.mRegionHandle), -	  mResetTimestamp(src.mResetTimestamp), -	  mPhaseStats(src.mPhaseStats), -	  mAvatarRezStates(src.mAvatarRezStates) +	  mResetTimestamp(src.mResetTimestamp)  {  	const PerRegionContainer::const_iterator it_end(src.mRegionStats.end());  	for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it) @@ -258,17 +256,6 @@ LLViewerAssetStats::recordFPS(F32 fps)  	mCurRegionStats->mFPS.record(fps);  } -void -LLViewerAssetStats::recordAvatarStats() -{ -	std::vector<S32> rez_counts; -	LLVOAvatar::getNearbyRezzedStats(rez_counts); -	mAvatarRezStates = rez_counts; -	mPhaseStats.clear(); -	mPhaseStats["cloud"] = LLViewerStats::PhaseMap::getPhaseStats("cloud"); -	mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray"); -} -  LLSD  LLViewerAssetStats::asLLSD(bool compact_output)  { @@ -299,11 +286,6 @@ LLViewerAssetStats::asLLSD(bool compact_output)  	static const LLSD::String max_tag("max");  	static const LLSD::String mean_tag("mean"); -	// Avatar sub-tags -	static const LLSD::String avatar_tag("avatar"); -	static const LLSD::String avatar_nearby_tag("nearby"); -	static const LLSD::String avatar_phase_stats_tag("phase_stats"); -	  	const duration_t now = LLViewerAssetStatsFF::get_timestamp();  	mCurRegionStats->accumulateTime(now); @@ -362,16 +344,6 @@ LLViewerAssetStats::asLLSD(bool compact_output)  	LLSD ret = LLSD::emptyMap();  	ret["regions"] = regions;  	ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6); -	LLSD avatar_info; -	avatar_info[avatar_nearby_tag] = LLSD::emptyArray(); -	for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat) -	{ -		std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat); -		avatar_info[avatar_nearby_tag][rez_status_name] = mAvatarRezStates[rez_stat]; -	} -	avatar_info[avatar_phase_stats_tag]["cloud"] = mPhaseStats["cloud"].getData(); -	avatar_info[avatar_phase_stats_tag]["cloud-or-gray"] = mPhaseStats["cloud-or-gray"].getData(); -	ret[avatar_tag] = avatar_info;  	return ret;  } @@ -470,15 +442,6 @@ record_fps_main(F32 fps)  	gViewerAssetStatsMain->recordFPS(fps);  } -void -record_avatar_stats() -{ -	if (! gViewerAssetStatsMain) -		return; - -	gViewerAssetStatsMain->recordAvatarStats(); -} -  // 'thread1' - should be for TextureFetch thread  void diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 8319752230..e4581d2120 100644..100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -256,10 +256,6 @@ protected:  	// Time of last reset  	duration_t mResetTimestamp; - -	// Nearby avatar stats -	std::vector<S32> mAvatarRezStates; -	LLViewerStats::phase_stats_t mPhaseStats;  }; @@ -318,8 +314,6 @@ void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_t  void record_fps_main(F32 fps); -void record_avatar_stats(); -  /**   * Region context, event and duration loggers for Thread 1.   */ diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp index db7dc3fea6..3975292ed3 100644 --- a/indra/newview/llviewerattachmenu.cpp +++ b/indra/newview/llviewerattachmenu.cpp @@ -121,7 +121,7 @@ void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::strin  		else if(item && item->isFinished())  		{  			// must be in library. copy it to our inventory and put it on. -			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp); +			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp));  			copy_inventory_item(gAgent.getID(),  								item->getPermissions().getOwner(),  								item->getUUID(), diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index a437a8b3b5..b5aa0ac92a 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -136,9 +136,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; @@ -318,7 +315,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; @@ -326,7 +323,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/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 40577118ba..cf59e67955 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1424,7 +1424,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); @@ -1462,10 +1462,10 @@ void render_ui_2d()  				LLUI::sDirtyRect = last_rect;  				last_rect = t_rect; -				last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::sGLScaleFactor.mV[0]); -				last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::sGLScaleFactor.mV[0]); -				last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::sGLScaleFactor.mV[1]); -				last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::sGLScaleFactor.mV[1]); +				last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]); +				last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]); +				last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]); +				last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]);  				LLRect clip_rect(last_rect); diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp index 6bd5631df6..f81206ffec 100644 --- a/indra/newview/llviewerdisplayname.cpp +++ b/indra/newview/llviewerdisplayname.cpp @@ -60,8 +60,10 @@ class LLSetDisplayNameResponder : public LLHTTPClient::Responder  {  public:  	// only care about errors -	/*virtual*/ void error(U32 status, const std::string& reason) +	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ +		llwarns << "LLSetDisplayNameResponder error [status:" +				<< status << "]: " << content << llendl;  		LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());  		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();  	} diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index a187318eb7..fff9821e86 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -64,6 +64,11 @@  #include "llavatarnamecache.h"  #include "llavataractions.h"  #include "lllogininstance.h" +#include "llfavoritesbar.h" + +// Two do-nothing ops for use in callbacks. +void no_op_inventory_func(const LLUUID&) {}  +void no_op() {}  ///----------------------------------------------------------------------------  /// Helper class to store special inventory item names and their localized values. @@ -588,7 +593,7 @@ void LLViewerInventoryCategory::copyViewerCategory(const LLViewerInventoryCatego  {  	copyCategory(other);  	mOwnerID = other->mOwnerID; -	mVersion = other->mVersion; +	setVersion(other->getVersion());  	mDescendentCount = other->mDescendentCount;  	mDescendentsRequested = other->mDescendentsRequested;  } @@ -656,9 +661,19 @@ void LLViewerInventoryCategory::removeFromServer( void )  	gAgent.sendReliableMessage();  } +S32 LLViewerInventoryCategory::getVersion() const +{ +	return mVersion; +} + +void LLViewerInventoryCategory::setVersion(S32 version) +{ +	mVersion = version; +} +  bool LLViewerInventoryCategory::fetch()  { -	if((VERSION_UNKNOWN == mVersion) +	if((VERSION_UNKNOWN == getVersion())  	   && mDescendentsRequested.hasExpired())	//Expired check prevents multiple downloads.  	{  		LL_DEBUGS("InventoryFetch") << "Fetching category children: " << mName << ", UUID: " << mUUID << LL_ENDL; @@ -949,46 +964,7 @@ void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id)  	}  } -void WearOnAvatarCallback::fire(const LLUUID& inv_item) -{ -	if (inv_item.isNull()) -		return; - -	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<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance")); -		if (panel) -		{ -			panel->showDefaultSubpart(); -		} -	} -} - -RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp) -{ -	mAttach = attachmentp; -} -RezAttachmentCallback::~RezAttachmentCallback() -{ -} - -void RezAttachmentCallback::fire(const LLUUID& inv_item) +void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp)  {  	if (inv_item.isNull())  		return; @@ -996,11 +972,11 @@ void RezAttachmentCallback::fire(const LLUUID& inv_item)  	LLViewerInventoryItem *item = gInventory.getItem(inv_item);  	if (item)  	{ -		rez_attachment(item, mAttach); +		rez_attachment(item, attachmentp);  	}  } -void ActivateGestureCallback::fire(const LLUUID& inv_item) +void activate_gesture_cb(const LLUUID& inv_item)  {  	if (inv_item.isNull())  		return; @@ -1013,7 +989,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; @@ -1031,7 +1007,6 @@ void CreateGestureCallback::fire(const LLUUID& inv_item)  } -  LLInventoryCallbackManager gInventoryCallbacks;  void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id, @@ -1157,6 +1132,11 @@ void link_inventory_item(  		}  	} +#if 1 // debugging stuff +	LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id); +	lldebugs << "cat: " << cat << llendl; +	 +#endif  	LLMessageSystem* msg = gMessageSystem;  	msg->newMessageFast(_PREHASH_LinkInventoryItem);  	msg->nextBlock(_PREHASH_AgentData); @@ -1283,7 +1263,7 @@ void create_new_item(const std::string& name,  	if (inv_type == LLInventoryType::IT_GESTURE)  	{ -		LLPointer<LLInventoryCallback> cb = new CreateGestureCallback(); +		LLPointer<LLInventoryCallback> 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); @@ -1444,6 +1424,28 @@ const std::string& LLViewerInventoryItem::getName() const  	return  LLInventoryItem::getName();  } +S32 LLViewerInventoryItem::getSortField() const +{ +	return LLFavoritesOrderStorage::instance().getSortIndex(mUUID); +} + +//void LLViewerInventoryItem::setSortField(S32 sortField) +//{ +//	LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField); +//	getSLURL(); +//} + +void LLViewerInventoryItem::getSLURL() +{ +	LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID); +} + +const LLPermissions& LLViewerInventoryItem::getPermissions() const +{ +	// Use the actual permissions of the symlink, not its parent. +	return LLInventoryItem::getPermissions();	 +} +  const LLUUID& LLViewerInventoryItem::getCreatorUUID() const  {  	if (const LLViewerInventoryItem *linked_item = getLinkedItem()) @@ -1514,6 +1516,17 @@ LLWearableType::EType LLViewerInventoryItem::getWearableType() const  	return LLWearableType::EType(getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK);  } + +time_t LLViewerInventoryItem::getCreationDate() const +{ +	return LLInventoryItem::getCreationDate(); +} + +U32 LLViewerInventoryItem::getCRC32() const +{ +	return LLInventoryItem::getCRC32();	 +} +  // *TODO: mantipov: should be removed with LMSortPrefix patch in llinventorymodel.cpp, EXT-3985  static char getSeparator() { return '@'; }  BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName) diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 3cf03c3bc5..61b1b8d846 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -35,6 +35,7 @@  #include <boost/signals2.hpp>	// boost::signals2::trackable  class LLInventoryPanel; +class LLFolderView;  class LLFolderBridge;  class LLViewerInventoryCategory; @@ -60,6 +61,10 @@ public:  	virtual const LLUUID& getAssetUUID() const;  	virtual const LLUUID& getProtectedAssetUUID() const; // returns LLUUID::null if current agent does not have permission to expose this asset's UUID to the user  	virtual const std::string& getName() const; +	virtual S32 getSortField() const; +	//virtual void setSortField(S32 sortField); +	virtual void getSLURL(); //Caches SLURL for landmark. //*TODO: Find a better way to do it and remove this method from here. +	virtual const LLPermissions& getPermissions() const;  	virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied  	virtual const LLUUID& getCreatorUUID() const;  	virtual const std::string& getDescription() const; @@ -68,11 +73,8 @@ public:  	virtual bool isWearableType() const;  	virtual LLWearableType::EType getWearableType() const;  	virtual U32 getFlags() const; - -    using LLInventoryItem::getPermissions; -	using LLInventoryItem::getCreationDate; -	using LLInventoryItem::setCreationDate; -	using LLInventoryItem::getCRC32; +	virtual time_t getCreationDate() const; +	virtual U32 getCRC32() const; // really more of a checksum.  	static BOOL extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName); @@ -204,13 +206,13 @@ public:  	// Version handling  	enum { VERSION_UNKNOWN = -1, VERSION_INITIAL = 1 }; -	S32 getVersion() const { return mVersion; } -	void setVersion(S32 version) { mVersion = version; } +	S32 getVersion() const; +	void setVersion(S32 version);  	// Returns true if a fetch was issued.  	bool fetch(); -	// used to help make cacheing more robust - for example, if +	// used to help make caching more robust - for example, if  	// someone is getting 4 packets but logs out after 3. the viewer  	// may never know the cache is wrong.  	enum { DESCENDENT_COUNT_UNKNOWN = -1 }; @@ -218,7 +220,7 @@ public:  	void setDescendentCount(S32 descendents) { mDescendentCount = descendents; }  	// file handling on the viewer. These are not meant for anything -	// other than cacheing. +	// other than caching.  	bool exportFileLocal(LLFILE* fp) const;  	bool importFileLocal(LLFILE* fp);  	void determineFolderType(); @@ -241,47 +243,60 @@ public:  	virtual void fire(const LLUUID& inv_item) = 0;  }; -class WearOnAvatarCallback : public LLInventoryCallback +class LLViewerJointAttachment; + +void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp); + +void activate_gesture_cb(const LLUUID& inv_item); + +void create_gesture_cb(const LLUUID& inv_item); + +class AddFavoriteLandmarkCallback : public LLInventoryCallback  {  public: -	WearOnAvatarCallback(bool do_replace = false) : mReplace(do_replace) {} -	 +	AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {} +	void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; } + +private:  	void fire(const LLUUID& inv_item); -protected: -	bool mReplace; +	LLUUID mTargetLandmarkId;  }; -class ModifiedCOFCallback : public LLInventoryCallback -{ -	void fire(const LLUUID& inv_item); -}; +typedef boost::function<void(const LLUUID&)> inventory_func_type; +void no_op_inventory_func(const LLUUID&); // A do-nothing inventory_func -class LLViewerJointAttachment; +typedef boost::function<void()> nullary_func_type; +void no_op(); // A do-nothing nullary func. -class RezAttachmentCallback : public LLInventoryCallback +// Shim between inventory callback and boost function/callable +class LLBoostFuncInventoryCallback: public LLInventoryCallback  {  public: -	RezAttachmentCallback(LLViewerJointAttachment *attachmentp); -	void fire(const LLUUID& inv_item); -protected: -	~RezAttachmentCallback(); +	LLBoostFuncInventoryCallback(inventory_func_type fire_func, +								 nullary_func_type destroy_func = no_op): +		mFireFunc(fire_func), +		mDestroyFunc(destroy_func) +	{ +	} -private: -	LLViewerJointAttachment* mAttach; -}; +	// virtual +	void fire(const LLUUID& item_id) +	{ +		mFireFunc(item_id); +	} -class ActivateGestureCallback : public LLInventoryCallback -{ -public: -	void fire(const LLUUID& inv_item); -}; +	// virtual +	~LLBoostFuncInventoryCallback() +	{ +		mDestroyFunc(); +	} +	 -class CreateGestureCallback : public LLInventoryCallback -{ -public: -	void fire(const LLUUID& inv_item); +private: +	inventory_func_type mFireFunc; +	nullary_func_type mDestroyFunc;  };  // misc functions diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index a907f102f8..e46299f9d2 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<LLAvatarJoint*>(*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<LLViewerJointMesh*>::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 76e3833acb..fd262b6e80 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<LLViewerJointMesh*> 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 5d1aa870a3..64454a03d1 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; sj<mNumSkinJoints; sj++) -	{ -		LLSkinJoint &js = mSkinJoints[sj]; - -		if (js.mJoint != current_joint) -		{ -			continue; -		} - -		// we've found a skinjoint for this joint.. - -		// is the last joint in the array our parent? -		if(mMesh->mJointRenderData.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; @@ -475,21 +201,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<LLViewerTexLayerSet*>(mLayerSet);  	if (mTestImageName)  	{  		gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName); @@ -558,11 +270,11 @@ 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  		{ diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index dd5dae1dc1..0db2836e15 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -1,6 +1,6 @@  /**    * @file llviewerjointmesh.h - * @brief Implementation of LLViewerJointMesh class + * @brief Declaration of LLViewerJointMesh class   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code @@ -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<LLViewerTexture>	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/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index 4543a1ba9a..297906803b 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -406,11 +406,9 @@ void LLViewerMediaFocus::update()  	LLViewerObject *viewer_object = getFocusedObject();  	S32 face = mFocusedObjectFace;  	LLVector3 normal = mFocusedObjectNormal; -	bool focus = true;  	if(!media_impl || !viewer_object)  	{ -		focus = false;  		media_impl = getHoverMediaImpl();  		viewer_object = getHoverObject();  		face = mHoverObjectFace; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 66db0ac8f3..beca08203f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -125,7 +125,7 @@  #include "llpathfindingmanager.h"  #include "boost/unordered_map.hpp" -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines;  typedef LLPointer<LLViewerObject> LLViewerObjectPtr; @@ -1577,11 +1577,26 @@ class LLAdvancedEnableGrabBakedTexture : public view_listener_t  /////////////////////// +class LLAdvancedEnableAppearanceToXML : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"); +	} +}; +  class LLAdvancedAppearanceToXML : public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ -		LLVOAvatar::dumpArchetypeXML(NULL); +		std::string emptyname; +		LLVOAvatar* avatar = +			find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); +		if (!avatar) +		{ +			avatar = gAgentAvatarp; +		} +		avatar->dumpArchetypeXML(emptyname);  		return true;  	}  }; @@ -2827,7 +2842,7 @@ class LLSelfRemoveAllAttachments : public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ -		LLAgentWearables::userRemoveAllAttachments(); +		LLAppearanceMgr::instance().removeAllAttachmentsFromAvatar();  		return true;  	}  }; @@ -6437,23 +6452,21 @@ class LLAttachmentDetachFromPoint : public view_listener_t  {  	bool handleEvent(const LLSD& user_data)  	{ +		uuid_vec_t ids_to_remove;  		const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL);  		if (attachment->getNumObjects() > 0)  		{ -			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++)  			{  				LLViewerObject *attached_object = (*iter); -				gMessageSystem->nextBlockFast(_PREHASH_ObjectData); -				gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); +				ids_to_remove.push_back(attached_object->getAttachmentItemID());  			} -			gMessageSystem->sendReliable( gAgent.getRegionHost() ); +		} +		if (!ids_to_remove.empty()) +		{ +			LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove);  		}  		return true;  	} @@ -6526,17 +6539,8 @@ class LLAttachmentDetach : public view_listener_t  			return true;  		} -		// 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;  	}  }; @@ -7391,7 +7395,7 @@ void handle_grab_baked_texture(void* data)  	if(folder_id.notNull())  	{  		std::string name; -		name = "Baked " + LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture"; +		name = "Baked " + LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";  		LLUUID item_id;  		item_id.generate(); @@ -7650,6 +7654,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) @@ -7932,7 +7940,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); @@ -7942,8 +7950,8 @@ class LLEditTakeOff : public view_listener_t  			{  				// MULTI-WEARABLES: assuming user wanted to remove top shirt.  				U32 wearable_index = gAgentWearables.getWearableCount(type) - 1; -				LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,wearable_index)); -				LLWearableBridge::removeItemFromAvatar(item); +				LLUUID item_id = gAgentWearables.getWearableItemID(type,wearable_index); +				LLAppearanceMgr::instance().removeItemFromAvatar(item_id);  			}  		} @@ -8283,8 +8291,6 @@ void initialize_menus()  	view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts"); - -	commit.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::showAgentInventory));  	enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));  	// Agent @@ -8503,6 +8509,7 @@ void initialize_menus()  	// Advanced > Character > Character Tests  	view_listener_t::addMenu(new LLAdvancedAppearanceToXML(), "Advanced.AppearanceToXML"); +	view_listener_t::addMenu(new LLAdvancedEnableAppearanceToXML(), "Advanced.EnableAppearanceToXML");  	view_listener_t::addMenu(new LLAdvancedToggleCharacterGeometry(), "Advanced.ToggleCharacterGeometry");  	view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale"); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 01534503f3..143420e227 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -138,6 +138,11 @@ bool handle_go_to();  // Export to XML or Collada  void handle_export_selected( void * ); +// Convert strings to internal types +U32 render_type_from_string(std::string render_type); +U32 feature_from_string(std::string feature); +U32 info_display_from_string(std::string info_display); +  class LLViewerMenuHolderGL : public LLMenuHolderGL  {  public: diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index b915cfe324..fbdb991484 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -633,7 +633,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(); @@ -662,7 +661,6 @@ bool join_group_response(const LLSD& notification, const LLSD& response)  		}  		else  		{ -			delete_context_data = FALSE;  			LLSD args;  			args["NAME"] = name;  			LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification["payload"]); @@ -675,7 +673,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 @@ -3444,7 +3441,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  	LLColor4	color(1.0f, 1.0f, 1.0f, 1.0f);  	LLUUID		from_id;  	LLUUID		owner_id; -	BOOL		is_owned_by_me = FALSE;  	LLViewerObject*	chatter;  	msg->getString("ChatData", "FromName", from_name); @@ -3529,13 +3525,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  				gAgent.heardChat(chat.mFromID);  			}  		} - -		is_owned_by_me = chatter->permYouOwner();  	}  	if (is_audible)  	{ -		BOOL visible_in_chat_bubble = FALSE; +		//BOOL visible_in_chat_bubble = FALSE;  		color.setVec(1.f,1.f,1.f,1.f);  		msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg); @@ -3618,7 +3612,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  			if (!is_muted && !is_do_not_disturb)  			{ -				visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles"); +				//visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");  				std::string formated_msg = "";  				LLViewerChat::formatChatMsg(chat, formated_msg);  				LLChat chat_bubble = chat; @@ -4951,9 +4945,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) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b1a60197a2..fcf5af76ff 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3266,14 +3266,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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED);  	}  	if (boost_children) @@ -4016,7 +4016,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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);  //	}  } @@ -4034,15 +4034,15 @@ void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)  	}  } - -S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host) +S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)  { +	const LLUUID& uuid = image->getID();  	S32 retval = 0;  	if (uuid != getTE(te)->getID() ||  		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] = image;  		setChanged(TEXTURE);  		if (mDrawable.notNull())  		{ @@ -4065,7 +4065,9 @@ void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)  S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)  {  	// Invalid host == get from the agent's sim -	return setTETextureCore(te, uuid, LLHost::invalid); +	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture( +		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid); +	return setTETextureCore(te,image);  } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 97cf0a4850..728d279c39 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -301,7 +301,7 @@ public:  	/*virtual*/	void	setNumTEs(const U8 num_tes);  	/*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, LLViewerTexture *image);  	/*virtual*/ S32		setTEColor(const U8 te, const LLColor3 &color);  	/*virtual*/ S32		setTEColor(const U8 te, const LLColor4 &color);  	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 6d4de05ffe..fa79ac07e6 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -283,7 +283,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  {  	LLFastTimer t(FTM_PROCESS_OBJECTS);	 -	LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();  	LLViewerObject *objectp;  	S32			num_objects;  	U32			local_id; @@ -302,6 +301,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  	{  		//llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl;  		gTerseObjectUpdates += num_objects; +		/*  		S32 size;  		if (mesgsys->getReceiveCompressedSize())  		{ @@ -311,10 +311,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())  		{ @@ -325,7 +327,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;  	} @@ -687,12 +690,12 @@ public:  		}  	} -	void error(U32 statusNum, const std::string& reason) +	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)  	{  		llwarns  			<< "Transport error requesting object cost " -			<< "HTTP status: " << statusNum << ", reason: " -			<< reason << "." << llendl; +			<< "[status: " << statusNum << "]: " +			<< content << llendl;  		// TODO*: Error message to user  		// For now just clear the request from the pending list @@ -776,12 +779,12 @@ public:  		}  	} -	void error(U32 statusNum, const std::string& reason) +	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)  	{  		llwarns  			<< "Transport error requesting object physics flags " -			<< "HTTP status: " << statusNum << ", reason: " -			<< reason << "." << llendl; +			<< "[status: " << statusNum << "]: " +			<< content << llendl;  		// TODO*: Error message to user  		// For now just clear the request from the pending list diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 90fbc41daa..386b2fd400 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -85,7 +85,6 @@ void LLViewerParcelMedia::update(LLParcel* parcel)  			}  			// we're in a parcel -			bool new_parcel = false;  			S32 parcelid = parcel->getLocalID();						  			LLUUID regionid = gAgent.getRegion()->getRegionID(); @@ -94,7 +93,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 77e382b8c7..4cdb568d17 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -696,8 +696,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();  } @@ -2057,7 +2057,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; @@ -2302,7 +2302,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/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e4234a538d..b8b53aa6e4 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -142,7 +142,8 @@ public:  	LLUUID mCacheID;  	CapabilityMap mCapabilities; -	 +	CapabilityMap mSecondCapabilitiesTracker;  +  	LLEventPoll* mEventPoll;  	S32 mSeedCapMaxAttempts; @@ -209,9 +210,9 @@ public:  	virtual ~BaseCapabilitiesComplete()  	{ } -    void error(U32 statusNum, const std::string& reason) +    void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)      { -		LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL; +		LL_WARNS2("AppInit", "Capabilities") << "[status:" << statusNum << ":] " << content << LL_ENDL;  		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);  		if (regionp)  		{ @@ -219,7 +220,7 @@ public:  		}      } -    void result(const LLSD& content) +   void result(const LLSD& content)      {  		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);  		if(!regionp) //region was removed @@ -237,6 +238,7 @@ public:  		for(iter = content.beginMap(); iter != content.endMap(); ++iter)  		{  			regionp->setCapability(iter->first, iter->second); +			  			LL_DEBUGS2("AppInit", "Capabilities") << "got capability for "   				<< iter->first << LL_ENDL; @@ -265,6 +267,62 @@ private:  	S32 mID;  }; +class BaseCapabilitiesCompleteTracker :  public LLHTTPClient::Responder +{ +	LOG_CLASS(BaseCapabilitiesCompleteTracker); +public: +	BaseCapabilitiesCompleteTracker( U64 region_handle) +	: mRegionHandle(region_handle) +	{ } +	 +	virtual ~BaseCapabilitiesCompleteTracker() +	{ } + +	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content) +	{ +		llwarns << "BaseCapabilitiesCompleteTracker error [status:" +				<< statusNum << "]: " << content << llendl; +	} + +	void result(const LLSD& content) +	{ +		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); +		if( !regionp )  +		{ +			return ; +		}		 +		LLSD::map_const_iterator iter; +		for(iter = content.beginMap(); iter != content.endMap(); ++iter) +		{ +			regionp->setCapabilityDebug(iter->first, iter->second);	 +			//llinfos<<"BaseCapabilitiesCompleteTracker New Caps "<<iter->first<<" "<< iter->second<<llendl; +		} +		 +		if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() ) +		{ +			llinfos<<"BaseCapabilitiesCompleteTracker "<<"Sim sent duplicate seed caps that differs in size - most likely content."<<llendl;			 +			//todo#add cap debug versus original check? +			/*CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin(); +			while (iter!=regionp->getRegionImpl()->mCapabilities.end() ) +			{ +				llinfos<<"BaseCapabilitiesCompleteTracker Original "<<iter->first<<" "<< iter->second<<llendl; +				++iter; +			} +			*/ +			regionp->getRegionImplNC()->mSecondCapabilitiesTracker.clear(); +		} + +	} + +	static BaseCapabilitiesCompleteTracker* build( U64 region_handle ) +	{ +		return new BaseCapabilitiesCompleteTracker( region_handle ); +	} + +private: +	U64 mRegionHandle;	 +}; +  LLViewerRegion::LLViewerRegion(const U64 &handle,  							   const LLHost &host, @@ -278,9 +336,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"), @@ -453,18 +513,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); @@ -477,10 +525,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;  } @@ -573,7 +621,7 @@ std::string LLViewerRegion::getLocalizedSimProductName() const  }  // static -std::string LLViewerRegion::regionFlagsToString(U32 flags) +std::string LLViewerRegion::regionFlagsToString(U64 flags)  {  	std::string result; @@ -1388,7 +1436,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; @@ -1397,7 +1446,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); @@ -1406,7 +1454,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); @@ -1445,6 +1506,8 @@ void LLViewerRegion::unpackRegionHandshake()  		mProductName = productName;  	} + +	mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking");  	LLVLComposition *compp = getComposition();  	if (compp)  	{ @@ -1524,11 +1587,12 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("EventQueueGet");  	if (gSavedSettings.getBOOL("UseHTTPInventory")) -	{ +	{	  		capabilityNames.append("FetchLib2");  		capabilityNames.append("FetchLibDescendents2");  		capabilityNames.append("FetchInventory2");  		capabilityNames.append("FetchInventoryDescendents2"); +		capabilityNames.append("IncrementCOFVersion");  	}  	capabilityNames.append("GetDisplayNames"); @@ -1542,7 +1606,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("LandResources");  	capabilityNames.append("MapLayer");  	capabilityNames.append("MapLayerGod"); -	capabilityNames.append("MeshUploadFlag"); +	capabilityNames.append("MeshUploadFlag");	  	capabilityNames.append("NavMeshGenerationStatus");  	capabilityNames.append("NewFileAgentInventory");  	capabilityNames.append("ObjectMedia"); @@ -1571,6 +1635,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("UntrustedSimulatorMessage");  	capabilityNames.append("UpdateAgentInformation");  	capabilityNames.append("UpdateAgentLanguage"); +	capabilityNames.append("UpdateAvatarAppearance");  	capabilityNames.append("UpdateGestureAgentInventory");  	capabilityNames.append("UpdateGestureTaskInventory");  	capabilityNames.append("UpdateNotecardAgentInventory"); @@ -1581,7 +1646,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("ViewerMetrics");  	capabilityNames.append("ViewerStartAuction");  	capabilityNames.append("ViewerStats"); -	 +  	// Please add new capabilities alphabetically to reduce  	// merge conflicts.  } @@ -1589,8 +1654,14 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  void LLViewerRegion::setSeedCapability(const std::string& url)  {  	if (getCapability("Seed") == url) -    { -		// llwarns << "Ignoring duplicate seed capability" << llendl; +    {	 +		//llwarns << "Ignoring duplicate seed capability" << llendl; +		//Instead of just returning we build up a second set of seed caps and compare them  +		//to the "original" seed cap received and determine why there is problem! +		LLSD capabilityNames = LLSD::emptyArray(); +		mImpl->buildCapabilityNames( capabilityNames ); +		LLHTTPClient::post( url, capabilityNames, BaseCapabilitiesCompleteTracker::build(getHandle() ), +							LLSD(), CAP_REQUEST_TIMEOUT );  		return;      } @@ -1663,9 +1734,9 @@ public:      { } -    void error(U32 statusNum, const std::string& reason) +    void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)      { -		LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL; +		LL_WARNS2("AppInit", "SimulatorFeatures") << "[status:" << statusNum << "]: " << content << LL_ENDL;  		retry();      } @@ -1726,6 +1797,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u  	}  } +void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::string& url) +{ +	mImpl->mSecondCapabilitiesTracker[name] = url; +} +  bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)  {  	return name == "EventQueueGet" || name == "UntrustedSimulatorMessage"; @@ -1733,6 +1809,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())  	{ @@ -1792,7 +1873,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<LLBBox>& boxes) const @@ -1800,7 +1881,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)) );  } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index c9fffaf30e..b5fe4677b7 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -109,13 +109,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; @@ -156,8 +156,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; } @@ -195,7 +202,7 @@ 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); @@ -234,6 +241,7 @@ public:  	void failedSeedCapability();  	S32 getNumSeedCapRetries();  	void setCapability(const std::string& name, const std::string& url); +	void setCapabilityDebug(const std::string& name, const std::string& url);  	// implements LLCapabilityProvider      virtual std::string getCapability(const std::string& name) const; @@ -278,6 +286,8 @@ public:  	F32 getLandHeightRegion(const LLVector3& region_pos); +	U8 getCentralBakeVersion() { return mCentralBakeVersion; } +  	void getInfo(LLSD& info);  	bool meshRezEnabled() const; @@ -330,7 +340,9 @@ public:  	void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );  	void getNeighboringRegionsStatus( std::vector<S32>& regions ); -	 +	const LLViewerRegionImpl * getRegionImpl() const { return mImpl; } +	LLViewerRegionImpl * getRegionImplNC() { return mImpl; } +  public:  	struct CompareDistance  	{ @@ -345,7 +357,6 @@ public:  protected:  	void disconnectAllNeighbors();  	void initStats(); -	void setFlags(BOOL b, U32 flags);  public:  	LLWind  mWind; @@ -390,11 +401,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; @@ -423,6 +436,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.h b/indra/newview/llviewershadermgr.h index d6dd645e8c..e3d28f2f5c 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -229,7 +229,6 @@ extern LLGLSLShader			gSplatTextureRectProgram;  extern LLGLSLShader			gGlowCombineFXAAProgram;  extern LLGLSLShader			gDebugProgram;  extern LLGLSLShader			gClipProgram; -extern LLGLSLShader			gAlphaMaskProgram;  //output tex0[tc0] + tex1[tc1]  extern LLGLSLShader			gTwoTextureAddProgram; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 35839ae459..35bba4184e 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -752,25 +752,6 @@ void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name)  	timer.unpause();  } -void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name) -{ -	phase_map_t::iterator iter = mPhaseMap.find(phase_name); -	if (iter != mPhaseMap.end()) -	{ -		if (iter->second.getStarted()) -		{ -			// Going from started to paused state - record stats. -			recordPhaseStat(phase_name,iter->second.getElapsedTimeF32()); -		} -		lldebugs << "stopPhase " << phase_name << llendl; -		iter->second.pause(); -	} -	else -	{ -		lldebugs << "stopPhase " << phase_name << " is not started, no-op" << llendl; -	} -} -  void LLViewerStats::PhaseMap::stopAllPhases()  {  	for (phase_map_t::iterator iter = mPhaseMap.begin(); @@ -814,6 +795,19 @@ LLViewerStats::PhaseMap::PhaseMap()  {  } + +void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name) +{ +	phase_map_t::iterator iter = mPhaseMap.find(phase_name); +	if (iter != mPhaseMap.end()) +	{ +		if (iter->second.getStarted()) +		{ +			// Going from started to stopped state - record stats. +			iter->second.stop(); +		} +	} +}  // static  LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)  { @@ -833,3 +827,18 @@ void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32  	stats.push(value);  } + +bool LLViewerStats::PhaseMap::getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed) +{ +	phase_map_t::iterator iter = mPhaseMap.find(phase_name); +	if (iter != mPhaseMap.end()) +	{ +		elapsed =  iter->second.getElapsedTimeF32(); +		completed = !iter->second.getStarted(); +		return true; +	} +	else +	{ +		return false; +	} +} diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index e02a4ccdc7..6b2461be41 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -289,6 +289,7 @@ public:  	public:  		PhaseMap();  		LLFrameTimer& 	getPhaseTimer(const std::string& phase_name); +		bool 			getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed);  		void			startPhase(const std::string& phase_name);  		void			stopPhase(const std::string& phase_name);  		void			stopAllPhases(); @@ -296,8 +297,11 @@ public:  		LLSD			dumpPhases();  		static StatsAccumulator& getPhaseStats(const std::string& phase_name);  		static void recordPhaseStat(const std::string& phase_name, F32 value); +		phase_map_t::iterator begin() { return mPhaseMap.begin(); } +		phase_map_t::iterator end() { return mPhaseMap.end(); }  	}; +  private:  	F64	mStats[ST_COUNT]; diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp new file mode 100755 index 0000000000..777e1f9c76 --- /dev/null +++ b/indra/newview/llviewertexlayer.cpp @@ -0,0 +1,748 @@ +/**  + * @file llviewertexlayer.cpp + * @brief Viewer texture layer. 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$ + */ + +#include "llviewerprecompiledheaders.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" + +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.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(); +	LL_DEBUGS("Avatar") << "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<LLImageRaw> 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<LLImageRaw> 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<LLImageJ2C> 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<LLImageJ2C> integrity_test = new LLImageJ2C; +			S32 file_size = 0; +			LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE); +			file_size = file.getSize(); +			U8* data = integrity_test->allocateData(file_size); +			file.read(data, 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); +} + +// virtual +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<LLVOAvatarSelf*> (mAvatarAppearance); +} + +const LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() const +{ +	return dynamic_cast<const LLVOAvatarSelf*> (mAvatarAppearance); +} + +LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() +{ +	return dynamic_cast<LLViewerTexLayerSetBuffer*> (getComposite()); +} + +const LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() const +{ +	return dynamic_cast<const LLViewerTexLayerSetBuffer*> (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 0000000000..959c883da8 --- /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<LLViewerTexLayerSet*> (mTexLayerSet); } +	const LLViewerTexLayerSet*	getViewerTexLayerSet() const +		{ return dynamic_cast<const LLViewerTexLayerSet*> (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/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 122d8f4a96..8036a4e258 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -1052,8 +1052,6 @@ void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end)  {  	LLWString text = getWText(); -	LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get()  ); -  	// Start with i just after the first embedded item  	for(S32 idx = start; idx < end; idx++ )  	{ diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 634ff1392e..2b343a2646 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -58,6 +58,7 @@  #include "lltextureatlas.h"  #include "lltextureatlasmanager.h"  #include "lltextureentry.h" +#include "lltexturemanagerbridge.h"  #include "llmediaentry.h"  #include "llvovolume.h"  #include "llviewermedia.h" @@ -231,7 +232,7 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(BOOL usemipma  	if(generate_gl_tex)  	{  		tex->generateGLTexture() ; -		tex->setCategory(LLViewerTexture::LOCAL) ; +		tex->setCategory(LLGLTexture::LOCAL) ;  	}  	return tex ;  } @@ -241,14 +242,14 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID&  	if(generate_gl_tex)  	{  		tex->generateGLTexture() ; -		tex->setCategory(LLViewerTexture::LOCAL) ; +		tex->setCategory(LLGLTexture::LOCAL) ;  	}  	return tex ;  }  LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps)   {  	LLPointer<LLViewerTexture> tex = new LLViewerTexture(raw, usemipmaps) ; -	tex->setCategory(LLViewerTexture::LOCAL) ; +	tex->setCategory(LLGLTexture::LOCAL) ;  	return tex ;  }  LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex)  @@ -257,13 +258,14 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid  	if(generate_gl_tex)  	{  		tex->generateGLTexture() ; -		tex->setCategory(LLViewerTexture::LOCAL) ; +		tex->setCategory(LLGLTexture::LOCAL) ;  	}  	return tex ;  }  LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(  	                                               const LLUUID &image_id,											        +												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority,  												   S8 texture_type, @@ -271,11 +273,12 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(  												   LLGLenum primary_format,  												   LLHost request_from_host)  { -	return gTextureList.getImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ; +	return gTextureList.getImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;  }  LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( -	                                               const std::string& filename,												    +	                                               const std::string& filename, +												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority,  												   S8 texture_type, @@ -283,11 +286,12 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(  												   LLGLenum primary_format,   												   const LLUUID& force_id)  { -	return gTextureList.getImageFromFile(filename, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ; +	return gTextureList.getImageFromFile(filename, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;  }  //static  -LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,									  +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url, +									 FTType f_type,  									 BOOL usemipmaps,  									 LLViewerTexture::EBoostLevel boost_priority,  									 S8 texture_type, @@ -296,14 +300,34 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const s  									 const LLUUID& force_id  									 )  { -	return gTextureList.getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ; +	return gTextureList.getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;  } -LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, LLHost host)  +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host)   { -	return gTextureList.getImageFromHost(image_id, host) ; +	return gTextureList.getImageFromHost(image_id, f_type, host) ;  } +// Create a bridge to the viewer texture manager. +class LLViewerTextureManagerBridge : public LLTextureManagerBridge +{ +	/*virtual*/ LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) +	{ +		return LLViewerTextureManager::getLocalTexture(usemipmaps, generate_gl_tex); +	} + +	/*virtual*/ LLPointer<LLGLTexture> getLocalTexture(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()  {  	{ @@ -349,12 +373,12 @@ 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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);  	LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ;  	image_raw = new LLImageRaw(32,32,3); @@ -373,6 +397,9 @@ void LLViewerTextureManager::init()  	LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);  	LLViewerTexture::initClass() ; +	 +	// Create a texture manager bridge. +	gTextureManagerBridgep = new LLViewerTextureManagerBridge;  	if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))  	{ @@ -389,6 +416,7 @@ void LLViewerTextureManager::cleanup()  {  	stop_glerror(); +	delete gTextureManagerBridgep;  	LLImageGL::sDefaultGLTexture = NULL ;  	LLViewerTexture::sNullImagep = NULL;  	LLViewerTexture::sBlackImagep = NULL; @@ -416,25 +444,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; @@ -571,70 +580,54 @@ 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++;  }  LLViewerTexture::~LLViewerTexture()  { +	// LL_DEBUGS("Avatar") << mID << llendl;  	cleanup();  	sImageCount--;  } +// virtual  void LLViewerTexture::init(bool firstinit)  { -	mBoostLevel = LLViewerTexture::BOOST_NONE;  	mSelectedTime = 0.f; - -	mFullWidth = 0; -	mFullHeight = 0; -	mTexelsPerImage = 0 ; -	mUseMipMaps = FALSE ; -	mComponents = 0 ; - -	mTextureState = NO_DELETE ; -	mDontDiscard = FALSE;  	mMaxVirtualSize = 0.f; -	mNeedsGLTexture = FALSE ;  	mMaxVirtualSizeResetInterval = 1;  	mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;  	mAdditionalDecodePriority = 0.f ;	 @@ -655,19 +648,12 @@ 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 @@ -690,10 +676,8 @@ void LLViewerTexture::setBoostLevel(S32 level)  	{  		mSelectedTime = gFrameTimeSeconds;  	} -  } -  bool LLViewerTexture::bindDefaultImage(S32 stage)   {  	if (stage < 0) return false; @@ -886,294 +870,18 @@ void LLViewerTexture::reorganizeVolumeList()  	mVolumeList.erase(mVolumeList.begin() + mNumVolumes, mVolumeList.end());  } - -  //virtual  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)  {  	//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) -{ -	llassert(mGLTexturep.notNull()) ; - -	return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ; -} - -BOOL LLViewerTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) -{ -	llassert(mGLTexturep.notNull()) ; - -	return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ; -} - -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 ; @@ -1197,25 +905,32 @@ void LLViewerTexture::updateBindStatsForTester()  //start of LLViewerFetchedTexture  //---------------------------------------------------------------------------------------------- -LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps) +LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps)  	: LLViewerTexture(id, usemipmaps),  	mTargetHost(host)  {  	init(TRUE) ; +	mFTType = f_type; +	if (mFTType == FTT_HOST_BAKE) +	{ +		mCanUseHTTP = false; +	}  	generateGLTexture() ;  } -LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps) +LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps)  	: LLViewerTexture(raw, usemipmaps)  {  	init(TRUE) ; +	mFTType = f_type;  } -LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps) +LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps)  	: LLViewerTexture(id, usemipmaps),  	mUrl(url)  {  	init(TRUE) ; +	mFTType = f_type;  	generateGLTexture() ;  } @@ -1281,6 +996,8 @@ void LLViewerFetchedTexture::init(bool firstinit)  	mLastCallBackActiveTime = 0.f;  	mInDebug = FALSE; + +	mFTType = FTT_UNKNOWN;  }  LLViewerFetchedTexture::~LLViewerFetchedTexture() @@ -1301,6 +1018,11 @@ S8 LLViewerFetchedTexture::getType() const  	return LLViewerTexture::FETCHED_TEXTURE ;  } +FTType LLViewerFetchedTexture::getFTType() const +{ +	return mFTType; +} +  void LLViewerFetchedTexture::cleanup()  {  	for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); @@ -1345,6 +1067,7 @@ void LLViewerFetchedTexture::loadFromFastCache()  		{   			//discard all oversized textures.  			destroyRawImage(); +			llwarns << "oversized, setting as missing" << llendl;  			setIsMissingAsset();  			mRawDiscardLevel = INVALID_DISCARD_LEVEL ;  		} @@ -1454,7 +1177,8 @@ void LLViewerFetchedTexture::destroyTexture()  	{  		return ;  	} -	 + +	//LL_DEBUGS("Avatar") << mID << llendl;  	destroyGLTexture() ;  	mFullyLoaded = FALSE ;  } @@ -1615,6 +1339,7 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)  		// An inappropriately-sized image was uploaded (through a non standard client)  		// We treat these images as missing assets which causes them to  		// be renderd as 'missing image' and to stop requesting data +		llwarns << "!size_ok, setting as missing" << llendl;  		setIsMissingAsset();  		destroyRawImage();  		return FALSE; @@ -1762,7 +1487,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;  	} @@ -2073,6 +1798,7 @@ bool LLViewerFetchedTexture::updateFetch()  				{   					//discard all oversized textures.  					destroyRawImage(); +					llwarns << "oversize, setting as missing" << llendl;  					setIsMissingAsset();  					mRawDiscardLevel = INVALID_DISCARD_LEVEL ;  					mIsFetching = FALSE ; @@ -2102,6 +1828,10 @@ bool LLViewerFetchedTexture::updateFetch()  				// We finished but received no data  				if (current_discard < 0)  				{ +					llwarns << "!mIsFetching, setting as missing, decode_priority " << decode_priority +							<< " mRawDiscardLevel " << mRawDiscardLevel +							<< " current_discard " << current_discard +							<< llendl;  					setIsMissingAsset();  					desired_discard = -1;  				} @@ -2169,7 +1899,7 @@ bool LLViewerFetchedTexture::updateFetch()  		// Load the texture progressively: we try not to rush to the desired discard too fast.  		// If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps  		// This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around -		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); @@ -2217,7 +1947,7 @@ bool LLViewerFetchedTexture::updateFetch()  		// bypass texturefetch directly by pulling from LLTextureCache  		bool fetch_request_created = false; -		fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), decode_priority, +		fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,  																			  w, h, c, desired_discard, needsAux(), mCanUseHTTP);  		if (fetch_request_created) @@ -2234,11 +1964,13 @@ bool LLViewerFetchedTexture::updateFetch()  	}  	else if (mHasFetcher && !mIsFetching)  	{ -		// Only delete requests that haven't receeived any network data for a while +		// Only delete requests that haven't received any network data +		// for a while.  Note - this is the normal mechanism for +		// deleting requests, not just a place to handle timeouts.  		const F32 FETCH_IDLE_TIME = 5.f;  		if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)  		{ -// 			llinfos << "Deleting request: " << getID() << " Discard: " << current_discard << " <= min:" << mMinDiscardLevel << " or priority == 0: " << decode_priority << llendl; + 			LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << llendl;  			LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);  			mHasFetcher = FALSE;  		} @@ -2286,8 +2018,10 @@ void LLViewerFetchedTexture::setIsMissingAsset()  	}  	else  	{ -		//it is normal no map tile on an empty region. -		//llwarns << mUrl << ": Marking image as missing" << llendl; +		// This may or may not be an error - it is normal to have no +		// map tile on an empty region, but bad if we're failing on a +		// server bake texture. +		llwarns << mUrl << ": Marking image as missing" << llendl;  	}  	if (mHasFetcher)  	{ @@ -2420,7 +2154,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)  		{ @@ -2878,7 +2612,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 ;  		}		 @@ -3206,14 +2940,14 @@ BOOL LLViewerFetchedTexture::insertToAtlas()  //----------------------------------------------------------------------------------------------  //start of LLViewerLODTexture  //---------------------------------------------------------------------------------------------- -LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps) -	: LLViewerFetchedTexture(id, host, usemipmaps) +LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps) +	: LLViewerFetchedTexture(id, f_type, host, usemipmaps)  {  	init(TRUE) ;  } -LLViewerLODTexture::LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps) -	: LLViewerFetchedTexture(url, id, usemipmaps) +LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps) +	: LLViewerFetchedTexture(url, f_type, id, usemipmaps)  {  	init(TRUE) ;  } @@ -3255,7 +2989,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)); @@ -3305,7 +3039,7 @@ void LLViewerLODTexture::processTextureStats()  				mCalculatedDiscardLevel = discard_level;  			}  		} -		if (mBoostLevel < LLViewerTexture::BOOST_SCULPTED) +		if (mBoostLevel < LLGLTexture::BOOST_SCULPTED)  		{  			discard_level += sDesiredDiscardBias;  			discard_level *= sDesiredDiscardScale; // scale @@ -3331,7 +3065,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)  		{  			if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage)  			{ @@ -3474,7 +3208,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL  	setMediaImpl() ; -	setCategory(LLViewerTexture::MEDIA) ; +	setCategory(LLGLTexture::MEDIA) ;  	LLViewerTexture* tex = gTextureList.findImage(mID) ;  	if(tex) //this media is a parcel media for tex. diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 2eaa0ac92d..2ec26af3c0 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -27,7 +27,7 @@  #ifndef LL_LLVIEWERTEXTURE_H					  #define LL_LLVIEWERTEXTURE_H -#include "lltexture.h" +#include "llgltexture.h"  #include "lltimer.h"  #include "llframetimer.h"  #include "llhost.h" @@ -88,16 +88,11 @@ 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,		  		MEDIA_TEXTURE,  		DYNAMIC_TEXTURE, @@ -107,42 +102,6 @@ public:  		INVALID_TEXTURE_TYPE  	}; -	enum EBoostLevel -	{ -		BOOST_NONE 			= 0, -		BOOST_AVATAR_BAKED	, -		BOOST_AVATAR		, -		BOOST_CLOUDS		, -		BOOST_SCULPTED      , -		 -		BOOST_HIGH 			= 10, -		BOOST_SELECTED		,		 -		BOOST_BUMP          , -		BOOST_TERRAIN		, // has to be high priority for minimap / low detail		 -		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<LLFace*> ll_face_list_t;  	typedef std::vector<LLVOVolume*> ll_volume_list_t; @@ -168,8 +127,7 @@ public:  	/*virtual*/ bool bindDefaultImage(const S32 stage = 0) ;  	/*virtual*/ void forceImmediateUpdate() ; -	const LLUUID& getID() const { return mID; } -	 +	/*virtual*/ const LLUUID& getID() const { return mID; }  	void setBoostLevel(S32 level);  	S32  getBoostLevel() { return mBoostLevel; } @@ -177,13 +135,12 @@ public:  	void resetTextureStats();	  	void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;}  	void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;} +	S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; }  	virtual F32  getMaxVirtualSize() ;  	LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} -	S32 getFullWidth() const { return mFullWidth; } -	S32 getFullHeight() const { return mFullHeight; }	  	/*virtual*/ void setKnownDrawSize(S32 width, S32 height);  	virtual void addFace(LLFace* facep) ; @@ -196,60 +153,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       setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height); -	void       setGLTextureCreated (bool initialized); -	void       setCategory(S32 category) ; - -	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;} @@ -262,36 +167,22 @@ 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  	F32 mSelectedTime;				// time texture was last selected -	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<LLImageGL> 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 ; @@ -303,17 +194,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;	 @@ -353,6 +233,16 @@ public:  }; +enum FTType +{ +	FTT_UNKNOWN = -1, +	FTT_DEFAULT = 0, // standard texture fetched by id. +	FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there. +	FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host. +	FTT_MAP_TILE, // tiles are fetched from map server directly. +	FTT_LOCAL_FILE // fetch directly from a local file. +}; +  //  //textures are managed in gTextureList.  //raw image data is fetched from remote or local cache @@ -366,9 +256,9 @@ class LLViewerFetchedTexture : public LLViewerTexture  protected:  	/*virtual*/ ~LLViewerFetchedTexture();  public: -	LLViewerFetchedTexture(const LLUUID& id, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE); -	LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps); -	LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps = TRUE); +	LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE); +	LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps); +	LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);  public:  	static F32 maxDecodePriority(); @@ -393,6 +283,7 @@ public:  public:  	/*virtual*/ S8 getType() const ; +	FTType getFTType() const;  	/*virtual*/ void forceImmediateUpdate() ;  	/*virtual*/ void dump() ; @@ -428,6 +319,7 @@ public:  	// the priority list, and cause horrible things to happen.  	void setDecodePriority(F32 priority = -1.0f);  	F32 getDecodePriority() const { return mDecodePriority; }; +	F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; };  	void setAdditionalDecodePriority(F32 priority) ; @@ -509,7 +401,7 @@ protected:  	S32 getCurrentDiscardLevelForFetching() ;  private: -	void init(bool firstinit) ; +	void init(bool firstinit) ;	  	void cleanup() ;  	void saveRawImage() ; @@ -556,7 +448,8 @@ protected:  	S8  mHasFetcher;				// We've made a fecth request  	S8  mIsFetching;				// Fetch request is active  	bool mCanUseHTTP ;              //This texture can be fetched through http if true. -	 + +	FTType mFTType; // What category of image is this - map tile, server bake, etc?  	mutable S8 mIsMissingAsset;		// True if we know that there is no image asset with this image id in the database.		  	typedef std::list<LLLoadedCallbackEntry*> callback_list_t; @@ -616,8 +509,8 @@ protected:  	/*virtual*/ ~LLViewerLODTexture(){}  public: -	LLViewerLODTexture(const LLUUID& id, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE); -	LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps = TRUE); +	LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE); +	LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);  	/*virtual*/ S8 getType() const;  	// Process image stats to determine priority/quality requirements. @@ -731,8 +624,9 @@ public:  	static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;  	static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,									  +									 FTType f_type = FTT_DEFAULT,  									 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, @@ -740,8 +634,9 @@ public:  									 );  	static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename,									  +									 FTType f_type = FTT_LOCAL_FILE,  									 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, @@ -749,15 +644,16 @@ public:  									 );  	static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url,									  +									 FTType f_type,  									 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,  									 const LLUUID& force_id = LLUUID::null  									 ); -	static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) ; +	static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ;  	static void init() ;  	static void cleanup() ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index b9f5c432d0..d2af48f528 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -112,10 +112,10 @@ void LLViewerTextureList::doPreloadImages()  	llassert_always(mUUIDMap.empty()) ;  	// Set the "missing asset" image -	LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI); +	LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);  	// Set the "white" image -	LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI); +	LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);  	LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();  	LLUIImageList* image_list = LLUIImageList::getInstance(); @@ -130,33 +130,33 @@ void LLViewerTextureList::doPreloadImages()  	//uv_test->setMipFilterNearest(TRUE, TRUE);  	// prefetch specific UUIDs -	LLViewerTextureManager::getFetchedTexture(IMG_SHOT, TRUE); -	LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF, TRUE); -	LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); +	LLViewerTextureManager::getFetchedTexture(IMG_SHOT); +	LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF); +	LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);  	if (image)   	{  		image->setAddressMode(LLTexUnit::TAM_WRAP);  		mImagePreloads.insert(image);  	} -	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); +	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);  	if (image)   	{  		image->setAddressMode(LLTexUnit::TAM_WRAP);	  		mImagePreloads.insert(image);  	} -	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); +	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);  	if (image)   	{  		image->setAddressMode(LLTexUnit::TAM_WRAP);  		mImagePreloads.insert(image);  	} -	image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); +	image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);  	if (image)   	{  		image->setAddressMode(LLTexUnit::TAM_WRAP);	  		mImagePreloads.insert(image);  	} -	image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, +	image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,  		0,0,LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"));  	if (image)   	{ @@ -198,7 +198,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, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type);  			if (image)  			{  				image->addTextureStats((F32)pixel_area); @@ -228,7 +228,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  		} @@ -322,7 +324,8 @@ void LLViewerTextureList::restoreGL()  /////////////////////////////////////////////////////////////////////////////// -LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,												    +LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename, +												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority,  												   S8 texture_type, @@ -339,15 +342,16 @@ 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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);  	}  	std::string url = "file://" + full_path; -	return getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id); +	return getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);  }  LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& url, +												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority,  												   S8 texture_type, @@ -372,16 +376,33 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&  	}  	LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id); -	 + +	if (!imagep.isNull()) +	{ +		LLViewerFetchedTexture *texture = imagep.get(); +		if (texture->getUrl().empty()) +		{ +			llwarns << "Requested texture " << new_id << " already exists but does not have a URL" << llendl; +		} +		else if (texture->getUrl() != url) +		{ +			// This is not an error as long as the images really match - +			// e.g. could be two avatars wearing the same outfit. +			LL_DEBUGS("Avatar") << "Requested texture " << new_id +								<< " already exists with a different url, requested: " << url +								<< " current: " << texture->getUrl() << llendl; +		} +		 +	}  	if (imagep.isNull())  	{  		switch(texture_type)  		{  		case LLViewerTexture::FETCHED_TEXTURE: -			imagep = new LLViewerFetchedTexture(url, new_id, usemipmaps); +			imagep = new LLViewerFetchedTexture(url, f_type, new_id, usemipmaps);  			break ;  		case LLViewerTexture::LOD_TEXTURE: -			imagep = new LLViewerLODTexture(url, new_id, usemipmaps); +			imagep = new LLViewerLODTexture(url, f_type, new_id, usemipmaps);  			break ;  		default:  			llerrs << "Invalid texture type " << texture_type << llendl ; @@ -411,7 +432,8 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&  } -LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,											        +LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, +												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority,  												   S8 texture_type, @@ -430,14 +452,34 @@ 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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI));  	}  	LLPointer<LLViewerFetchedTexture> imagep = findImage(image_id); -	 +	if (!imagep.isNull()) +	{ +		LLViewerFetchedTexture *texture = imagep.get(); +		if (request_from_host.isOk() && +			!texture->getTargetHost().isOk()) +		{ +			llwarns << "Requested texture " << image_id << " already exists but does not have a host" << llendl; +		} +		else if (request_from_host.isOk() && +				 texture->getTargetHost().isOk() && +				 request_from_host != texture->getTargetHost()) +		{ +			llwarns << "Requested texture " << image_id << " already exists with a different target host, requested: "  +					<< request_from_host << " current: " << texture->getTargetHost() << llendl; +		} +		if (f_type != FTT_DEFAULT && imagep->getFTType() != f_type) +		{ +			llwarns << "FTType mismatch: requested " << f_type << " image has " << imagep->getFTType() << llendl; +		} +		 +	}  	if (imagep.isNull())  	{ -		imagep = createImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ; +		imagep = createImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;  	}  	imagep->setGLTextureCreated(true); @@ -446,7 +488,8 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,  }  //when this function is called, there is no such texture in the gTextureList with image_id. -LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,											        +LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, +												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority,  												   S8 texture_type, @@ -460,10 +503,10 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,  	switch(texture_type)  	{  	case LLViewerTexture::FETCHED_TEXTURE: -		imagep = new LLViewerFetchedTexture(image_id, request_from_host, usemipmaps); +		imagep = new LLViewerFetchedTexture(image_id, f_type, request_from_host, usemipmaps);  		break ;  	case LLViewerTexture::LOD_TEXTURE: -		imagep = new LLViewerLODTexture(image_id, request_from_host, usemipmaps); +		imagep = new LLViewerLODTexture(image_id, f_type, request_from_host, usemipmaps);  		break ;  	default:  		llerrs << "Invalid texture type " << texture_type << llendl ; @@ -1353,7 +1396,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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);  	if (!image)  	{  		delete [] data; @@ -1425,7 +1468,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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);  	if (!image)  	{  		delete [] data; @@ -1456,6 +1499,7 @@ void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **  	LLViewerFetchedTexture* image = gTextureList.findImage( image_id );  	if( image )  	{ +		llwarns << "not in db" << llendl;  		image->setIsMissingAsset();  	}  } @@ -1525,22 +1569,22 @@ 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); +	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, FTT_LOCAL_FILE, MIPMAP_NO, boost_priority);  	return loadUIImage(imagep, name, use_mips, scale_rect, clip_rect);  }  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); +	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, MIPMAP_NO, boost_priority);  	return loadUIImage(imagep, id.asString(), use_mips, scale_rect, clip_rect);  } @@ -1563,7 +1607,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 3dda973d3f..136042620d 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -130,8 +130,9 @@ private:  	void removeImageFromList(LLViewerFetchedTexture *image);  	LLViewerFetchedTexture * getImage(const LLUUID &image_id,									  +									 FTType f_type = FTT_DEFAULT,  									 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, @@ -139,8 +140,9 @@ private:  									 );  	LLViewerFetchedTexture * getImageFromFile(const std::string& filename,									  +									 FTType f_type = FTT_LOCAL_FILE,  									 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, @@ -148,8 +150,9 @@ private:  									 );  	LLViewerFetchedTexture* getImageFromUrl(const std::string& url, +									 FTType f_type,  									 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, @@ -157,8 +160,9 @@ private:  									 );  	LLViewerFetchedTexture* createImage(const LLUUID &image_id, +									 FTType f_type,  									 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, @@ -167,8 +171,8 @@ 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); }	 +	LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, FTType f_type, LLHost host) +	{ return getImage(image_id, f_type, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }	  public:  	typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t;	 @@ -233,11 +237,11 @@ private:  	LLPointer<LLUIImage> 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<LLUIImage> 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<LLUIImage> 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 0000000000..e8425dc76a --- /dev/null +++ b/indra/newview/llviewerwearable.cpp @@ -0,0 +1,656 @@ +/**  + * @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 "llfloatersidepanelcontainer.h" +#include "llnotificationsutil.h" +#include "llsidepanelappearance.h" +#include "lltextureentry.h" +#include "llviewertexlayer.h" +#include "llvoavatarself.h" +#include "llavatarappearancedefines.h" +#include "llviewerwearable.h" +#include "llviewercontrol.h" +#include "llviewerregion.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  ) +			{ +				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 +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<LLVOAvatarSelf*>(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, FTT_DEFAULT, 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 ); +	}	 +	 +//	if( upload_bake ) +//	{ +//		gAgent.sendAgentSetAppearance(); +//	} +} + + +// 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(gAgentCamera.cameraCustomizeAvatar()) +	{ +		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit")); +	} + +	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<LLViewerFetchedTexture*> (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<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance")); +	if( panel ) +	{ +		panel->updateScrollingPanelList(); +	} +} + +void LLViewerWearable::saveValues() +{ +	LLWearable::saveValues(); + +	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance")); +	if( panel ) +	{ +		panel->updateScrollingPanelList(); +	} +} + +// 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 0000000000..65566f23a5 --- /dev/null +++ b/indra/newview/llviewerwearable.h @@ -0,0 +1,104 @@ +/**  + * @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 LLViewerWearableList +	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*/ 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). +	/*virtual*/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 6dcdd006d7..0ac59f4d7a 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -383,7 +383,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]));  			} @@ -1573,6 +1573,16 @@ LLViewerWindow::LLViewerWindow(const Params& p)  	LLViewerWindow::sMovieBaseName = "SLmovie";  	resetSnapshotLoc(); + +	/* +	LLWindowCallbacks* callbacks, +	const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, +	BOOL fullscreen,  +	BOOL clearBg, +	BOOL disable_vsync, +	BOOL ignore_pixel_depth, +	U32 fsaa_samples) +	*/  	// create window  	mWindow = LLWindowManager::createWindow(this,  		p.title, p.name, p.x, p.y, p.width, p.height, 0, @@ -2147,7 +2157,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)  		calcDisplayScale(); -		BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor; +		BOOL display_scale_changed = mDisplayScale != LLUI::getScaleFactor();  		LLUI::setScaleFactor(mDisplayScale);  		// update our window rectangle @@ -2353,7 +2363,7 @@ void LLViewerWindow::draw()  		// scale view by UI global scale factor and aspect ratio correction factor  		gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); -		LLVector2 old_scale_factor = LLUI::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(); @@ -2367,7 +2377,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 @@ -2415,7 +2425,7 @@ void LLViewerWindow::draw()  				LLFontGL::HCENTER, LLFontGL::TOP);  		} -		LLUI::sGLScaleFactor = old_scale_factor; +		LLUI::setScaleFactor(old_scale_factor);  	}  	LLUI::popMatrix();  	gGL.popMatrix(); @@ -3218,8 +3228,8 @@ void LLViewerWindow::updateLayout()  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; @@ -4789,7 +4799,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)  		gResizeScreenTexture = TRUE;  		gWindowResized = TRUE; -		if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) +		if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())  		{  			LLVisualParamHint::requestHintUpdates();  		} diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index abb5153480..94760e3c83 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -223,7 +223,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;  		} @@ -240,7 +240,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;  		} @@ -376,9 +376,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,  	LLPointer<LLImageRaw> 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); @@ -413,11 +410,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++)  			{ @@ -461,7 +453,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/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d295fc60cd..0475e9fc89 100644..100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -24,18 +24,13 @@   * $/LicenseInfo$   */ -#if LL_MSVC -// disable warning about boost::lexical_cast returning uninitialized data -// when it fails to parse the string -#pragma warning (disable:4701) -#endif -  #include "llviewerprecompiledheaders.h"  #include "llvoavatar.h"  #include <stdio.h>  #include <ctype.h> +#include <sstream>  #include "llaudioengine.h"  #include "noise.h" @@ -53,6 +48,7 @@  #include "llcallingcard.h"		// IDEVO for LLAvatarTracker  #include "lldrawpoolavatar.h"  #include "lldriverparam.h" +#include "llpolyskeletaldistortion.h"  #include "lleditingmotion.h"  #include "llemote.h"  //#include "llfirstuse.h" @@ -78,15 +74,16 @@  #include "llselectmgr.h"  #include "llsprite.h"  #include "lltargetingmotion.h" -#include "lltexlayer.h"  #include "lltoolmorph.h"  #include "llviewercamera.h" +#include "llviewertexlayer.h"  #include "llviewertexturelist.h"  #include "llviewermenu.h"  #include "llviewerobjectlist.h"  #include "llviewerparcelmgr.h"  #include "llviewershadermgr.h"  #include "llviewerstats.h" +#include "llviewerwearable.h"  #include "llvoavatarself.h"  #include "llvovolume.h"  #include "llworld.h" @@ -103,22 +100,17 @@  #include "lldebugmessagebox.h"  #include "llsdutil.h" +#include "llsdserialize.h"  extern F32 SPEED_ADJUST_MAX;  extern F32 SPEED_ADJUST_MAX_SEC;  extern F32 ANIM_SPEED_MAX;  extern F32 ANIM_SPEED_MIN; -#if LL_MSVC -// disable boost::lexical_cast warning -#pragma warning (disable:4702) -#endif - -#include <boost/lexical_cast.hpp>  // #define OUTPUT_BREAST_DATA -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines;  //-----------------------------------------------------------------------------  // Global constants @@ -139,7 +131,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; @@ -196,8 +187,6 @@ const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f;  const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;  const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f; -const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0); -  enum ERenderName  {  	RENDER_NAME_NEVER, @@ -244,6 +233,24 @@ struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarColli  							scale;  }; +struct LLAppearanceMessageContents +{ +	LLAppearanceMessageContents(): +		mAppearanceVersion(-1), +		mParamAppearanceVersion(-1), +		mCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) +	{ +	} +	LLTEContents mTEContents; +	S32 mAppearanceVersion; +	S32 mParamAppearanceVersion; +	S32 mCOFVersion; +	// For future use: +	//U32 appearance_flags = 0; +	std::vector<F32> mParamWeights; +	std::vector<LLVisualParam*> mParams; +}; +  struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>  	{  	Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> >	bone; @@ -255,6 +262,8 @@ struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoi  	{}  }; +	 +  struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo>  {  	LLVOAvatarBoneInfo()  @@ -284,6 +293,8 @@ struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo  	Mandatory<LLVOAvatarChildJoint>	skeleton_root;  }; + +  //-----------------------------------------------------------------------------  // class LLBodyNoiseMotion  //----------------------------------------------------------------------------- @@ -605,11 +616,7 @@ private:  //-----------------------------------------------------------------------------  // Static Data  //----------------------------------------------------------------------------- -LLXmlTree LLVOAvatar::sXMLTree; -LLXMLNodePtr 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 = 12;  F32 LLVOAvatar::sRenderDistance = 256.f; @@ -656,15 +663,13 @@ static F32 calc_bouncy_animation(F32 x);  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),  	mLastSkeletonSerialNum( 0 ), -	mHeadOffset(),  	mIsSitting(FALSE),  	mTimeVisible(),  	mTyping(FALSE), @@ -675,7 +680,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mBelowWater(FALSE),  	mLastAppearanceBlendTime(0.f),  	mAppearanceAnimating(FALSE), -	mNameString(), +    mNameIsSet(false),  	mTitle(),  	mNameAway(false),  	mNameDoNotDisturb(false), @@ -689,9 +694,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), @@ -699,12 +701,15 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mFullyLoaded(FALSE),  	mPreviousFullyLoaded(FALSE),  	mFullyLoadedInitialized(FALSE), -	mSupportsAlphaLayers(FALSE),  	mLoadedCallbacksPaused(FALSE),  	mHasPelvisOffset( FALSE ),  	mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")), -	mLastRezzedStatus(-1) - +	mLastRezzedStatus(-1), +	mIsEditingAppearance(FALSE), +	mUseLocalAppearance(FALSE), +	mUseServerBakes(FALSE), // FIXME DRANO consider using boost::optional, defaulting to unknown. +	mLastUpdateRequestCOFVersion(-1), +	mLastUpdateReceivedCOFVersion(-1)  {  	//VTResume();  // VTune @@ -716,28 +721,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; @@ -824,50 +811,13 @@ LLVOAvatar::~LLVOAvatar()  		debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");  		} +	logPendingPhases(); +	  	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<LLViewerJoint*>::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;  	mAnimationSources.clear(); @@ -912,7 +862,7 @@ BOOL LLVOAvatar::isFullyTextured() const  {  	for (S32 i = 0; i < 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. @@ -921,19 +871,19 @@ BOOL LLVOAvatar::isFullyTextured() const  		{  			continue; // nonexistent LOD OK.  		} -		std::vector<LLViewerJointMesh*>::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.  			} @@ -952,6 +902,7 @@ BOOL LLVOAvatar::hasGray() const  S32 LLVOAvatar::getRezzedStatus() const  {  	if (getIsCloud()) return 0; +	if (isFullyTextured() && allBakedTexturesCompletelyDownloaded()) return 3;  	if (isFullyTextured()) return 2;  	llassert(hasGray());  	return 1; // gray @@ -1007,7 +958,7 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)  void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)  {  	counts.clear(); -	counts.resize(3); +	counts.resize(4);  	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();  		 iter != LLCharacter::sInstances.end(); ++iter)  	{ @@ -1025,6 +976,7 @@ std::string LLVOAvatar::rezStatusToString(S32 rez_status)  	if (rez_status==0) return "cloud";  	if (rez_status==1) return "gray";  	if (rez_status==2) return "textured"; +	if (rez_status==3) return "textured_and_downloaded";  	return "unknown";  } @@ -1086,15 +1038,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(); @@ -1115,7 +1067,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();  } @@ -1142,7 +1094,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<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); @@ -1151,7 +1103,7 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)  			LLVOAvatar* inst = (LLVOAvatar*) *iter;  			inst->deleteLayerSetCaches(clearAll);  		} -		LLTexLayerSet::sHasCaches = FALSE; +		LLViewerTexLayerSet::sHasCaches = FALSE;  	}  	LLVOAvatarSelf::deleteScratchTextures();  	LLTexLayerStaticImageList::getInstance()->deleteCachedImages(); @@ -1164,97 +1116,6 @@ 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; -	} - -	//------------------------------------------------------------------------- -	// <linden_avatar version="1.0"> (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; -	} - -	// 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"); @@ -1271,85 +1132,12 @@ void LLVOAvatar::initClass()  void LLVOAvatar::cleanupClass()  { -	deleteAndClear(sAvatarXmlInfo); -	sSkeletonXMLTree = NULL; -	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<std::string>(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<LLViewerJointMesh* >::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  	//-------------------------------------------------------------------------  	if (LLCharacter::sInstances.size() == 1) @@ -1407,10 +1195,9 @@ void LLVOAvatar::initInstance(void)  		registerMotion( ANIM_AGENT_SIT_FEMALE,				LLKeyframeMotion::create );  		registerMotion( ANIM_AGENT_TARGET,					LLTargetingMotion::create );  		registerMotion( ANIM_AGENT_WALK_ADJUST,				LLWalkAdjustMotion::create ); -		  	} -	 -	buildCharacter(); + +	LLAvatarAppearance::initInstance();  	// preload specific motions here  	createMotion( ANIM_AGENT_CUSTOMIZE); @@ -1419,7 +1206,30 @@ void LLVOAvatar::initInstance(void)  	//VTPause();  // VTune  	mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->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 @@ -1494,7 +1304,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)  	float max_attachment_span = get_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++) @@ -1732,149 +1542,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  	return hit;  } -//----------------------------------------------------------------------------- -// parseSkeletonFile() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename) -{ -	//------------------------------------------------------------------------- -	// parse the file -	//------------------------------------------------------------------------- - -	LLXMLNodePtr skeleton_xml; -	BOOL parsesuccess = LLXMLNode::parseFile(filename, skeleton_xml, NULL); - -	if (!parsesuccess || skeleton_xml.isNull()) -	{ -		llerrs << "Can't parse skeleton file: " << filename << llendl; -		return FALSE; -	} - -	// Process XML data -	if (sAvatarSkeletonInfo) -	{ //this can happen if a login attempt failed -		delete sAvatarSkeletonInfo; -	} -	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo; - -	LLXUIParser parser; -	parser.readXUI(skeleton_xml, *sAvatarSkeletonInfo, filename); -	if (!sAvatarSkeletonInfo->validateBlock()) -	{ -		llerrs << "Error parsing skeleton XML file: " << filename << llendl; -	} - -	if( !skeleton_xml->hasName( "linden_skeleton" ) ) -	{ -		llerrs << "Invalid avatar skeleton file header: " << filename << llendl; -		return FALSE; -	} - -	if (sAvatarSkeletonInfo->version() != "1.0") -	{ -		llerrs << "Invalid avatar skeleton file version: " << sAvatarSkeletonInfo->version() << " in file: " << filename << llendl; -		return FALSE; -	} - -	return TRUE; -} - -//----------------------------------------------------------------------------- -// setupBone() -//----------------------------------------------------------- -BOOL LLVOAvatar::setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num) -{ -	LLViewerJoint* joint = NULL; -	if (info.bone.isChosen()) -	{ -		joint = (LLViewerJoint*)getCharacterJoint(joint_num); -		if (!joint) -		{ -			llwarns << "Too many bones" << llendl; -			return FALSE; -		} -		joint->setName( info.bone().name ); -		joint->setPosition(info.bone().pos); -		joint->setRotation(mayaQ(info.bone().rot().mV[VX], info.bone().rot().mV[VY], info.bone().rot().mV[VZ], LLQuaternion::XYZ)); -		joint->setScale(info.bone().scale); -		joint->setSkinOffset( info.bone().pivot ); -		joint_num++; - -		for (LLInitParam::ParamIterator<LLVOAvatarChildJoint>::const_iterator child_it = info.bone().children.begin(), -				end_it = info.bone().children.end(); -			child_it != end_it; -			++child_it) -		{ -			if (!setupBone(*child_it, joint, volume_num, joint_num)) -			{ -				return FALSE; -			} -	} -	} -	else // collision volume -	{ -		if (volume_num >= (S32)mNumCollisionVolumes) -		{ -			llwarns << "Too many bones" << llendl; -			return FALSE; -		} -		joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]); -		joint->setName( info.collision_volume.name); -		joint->setPosition(info.collision_volume.pos); -		joint->setRotation(mayaQ(info.collision_volume.rot().mV[VX], info.collision_volume.rot().mV[VY], info.collision_volume.rot().mV[VZ], LLQuaternion::XYZ)); -		joint->setScale(info.collision_volume.scale); -		volume_num++; -	} - -	// add to parent -	if (parent) -	{ -		parent->addChild( joint ); -	} - -	joint->setDefaultFromCurrentXform(); -	return TRUE; -} - -//----------------------------------------------------------------------------- -// buildSkeleton() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info) -{ -	//------------------------------------------------------------------------- -	// allocate joints -	//------------------------------------------------------------------------- -	if (!allocateCharacterJoints(info->num_bones)) -	{ -		llerrs << "Can't allocate " << info->num_bones() << " joints" << llendl; -		return FALSE; -	} -	 -	//------------------------------------------------------------------------- -	// allocate volumes -	//------------------------------------------------------------------------- -	if (info->num_collision_volumes) -	{ -		if (!allocateCollisionVolumes(info->num_collision_volumes)) -		{ -			llerrs << "Can't allocate " << info->num_collision_volumes() << " collision volumes" << llendl; -			return FALSE; -		} -	} - -	S32 current_joint_num = 0; -	S32 current_volume_num = 0; - -	if (!setupBone(info->skeleton_root, NULL, current_volume_num, current_joint_num)) -	{ -			llerrs << "Error parsing bone in skeleton file" << llendl; -			return FALSE; -		} - -	return TRUE; -} -  LLVOAvatar* LLVOAvatar::asAvatar()  {  	return this; @@ -1906,114 +1574,15 @@ void LLVOAvatar::startDefaultMotions()  // LLVOAvatar::buildCharacter()  // Deferred initialization and rebuild of the avatar.  //----------------------------------------------------------------------------- +// virtual  void LLVOAvatar::buildCharacter()  { -	//------------------------------------------------------------------------- -	// 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<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin(); -		 jointIter != mMeshLOD.end(); ++jointIter) -	{ -		LLViewerJoint* joint = (LLViewerJoint*) *jointIter; -		for (std::vector<LLViewerJointMesh*>::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(); - -// 	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  	//-------------------------------------------------------------------------  	updateHeadOffset(); @@ -2065,11 +1634,11 @@ void LLVOAvatar::releaseMeshData()  	//llinfos << "Releasing" << llendl;  	// cleanup mesh data -	for (std::vector<LLViewerJoint*>::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);  	} @@ -2158,7 +1727,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  			{ @@ -2232,7 +1805,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(); @@ -2253,72 +1830,6 @@ 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, @@ -2326,7 +1837,6 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,  									 U32 block_num, const EObjectUpdateType update_type,  									 LLDataPacker *dp)  { -	LLVector3 old_vel = getVelocity();  	const BOOL has_name = !getNVPair("FirstName");  	// Do base class updates... @@ -2354,20 +1864,50 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,  	return retval;  } -// virtual -S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) +LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUUID& uuid)  { -	// The core setTETexture() method requests images, so we need -	// to redirect certain avatar texture requests to different sims. -	if (isIndexBakedTexture((ETextureIndex)te)) +	LLViewerFetchedTexture *result = NULL; + +	if (uuid == IMG_DEFAULT_AVATAR || +		uuid == IMG_DEFAULT || +		uuid == IMG_INVISIBLE)  	{ -		LLHost target_host = getObjectHost(); -		return setTETextureCore(te, uuid, target_host); +		// Should already exist, don't need to find it on sim or baked-texture host. +		result = gTextureList.findImage(uuid);  	} -	else + +	if (!result) +	{ +		const std::string url = getImageURL(te,uuid); +		if (!url.empty()) +		{ +			LL_DEBUGS("Avatar") << avString() << "from URL " << url << llendl; +			result = LLViewerTextureManager::getFetchedTextureFromUrl( +				url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid); +		} +		else +		{ +			LL_DEBUGS("Avatar") << avString() << "from host " << uuid << llendl; +			LLHost host = getObjectHost(); +			result = LLViewerTextureManager::getFetchedTexture( +				uuid, FTT_HOST_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); +		} +	} +	return result; +} + +// virtual +S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) +{ +	if (!isIndexBakedTexture((ETextureIndex)te))  	{ -		return setTETextureCore(te, uuid, LLHost::invalid); +		// Sim still sends some uuids for non-baked slots sometimes - ignore. +		return LLViewerObject::setTETexture(te, LLUUID::null);  	} + +	LLViewerFetchedTexture *image = getBakedTextureImage(te,uuid); +	llassert(image); +	return setTETextureCore(te, image);  }  static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Avatar Update"); @@ -2413,7 +1953,8 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  		return;  	}	 - 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) +	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)) +		&& !(gSavedSettings.getBOOL("DisableAllRenderTypes")))  	{  		return;  	} @@ -2478,7 +2019,7 @@ void 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);  	static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false); @@ -2597,11 +2138,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 ); @@ -3096,8 +2637,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  	}  	// Rebuild name tag if state change detected -	if (mNameString.empty() -		|| (mNameString.size() == 2 && mNameString[0] == 10 && mNameString[1] == 10) // *TODO : find out why mNameString is sometimes "" +	if (!mNameIsSet  		|| new_name  		|| (!title && !mTitle.empty())  		|| (title && mTitle != title->getString()) @@ -3207,8 +2747,6 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);  		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); -		char line[MAX_STRING];		/* Flawfinder: ignore */ -		line[0] = '\0';  		std::deque<LLChat>::iterator chat_iter = mChats.begin();  		mNameText->clearString(); @@ -3292,17 +2830,16 @@ void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color,  	{  		mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font);  	} -	mNameString += line; -	mNameString += '\n'; +    mNameIsSet |= !line.empty();  }  void LLVOAvatar::clearNameTag()  { -	mNameString.clear(); +    mNameIsSet = false;  	if (mNameText)  	{  		mNameText->setLabel(""); -		mNameText->setString( "" ); +		mNameText->setString("");  	}  	mTimeVisible.reset();  } @@ -3336,7 +2873,7 @@ void LLVOAvatar::invalidateNameTags()  // Compute name tag position during idle update  void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)  { -	LLQuaternion root_rot = mRoot.getWorldRotation(); +	LLQuaternion root_rot = mRoot->getWorldRotation();  	LLQuaternion inv_root_rot = ~root_rot;  	LLVector3 pixel_right_vec;  	LLVector3 pixel_up_vec; @@ -3355,7 +2892,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)  	local_camera_up.scaleVec(avatar_ellipsoid);  	local_camera_at.scaleVec(avatar_ellipsoid); -	LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot.getLastWorldPosition()) * inv_root_rot; +	LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot->getLastWorldPosition()) * inv_root_rot;  	if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD)  	{ @@ -3364,7 +2901,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)  	mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f)); -	LLVector3 name_position = mRoot.getLastWorldPosition() + (mCurRootToHeadOffset * root_rot); +	LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);  	name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));	  	name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET; @@ -3425,13 +2962,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 @@ -3452,6 +2989,47 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  {  	// clear debug text  	mDebugText.clear(); + +	if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) +	{ +		S32 central_bake_version = -1; +		if (getRegion()) +		{ +			central_bake_version = getRegion()->getCentralBakeVersion(); +		} +		bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded(); +		bool all_local_downloaded = allLocalTexturesCompletelyDownloaded(); +		std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d", +										  isSelf() ? (all_local_downloaded ? "L" : "l") : "-", +										  all_baked_downloaded ? "B" : "b", +										  mUseLocalAppearance, mIsEditingAppearance, +										  mUseServerBakes, central_bake_version); +		std::string origin_string = bakedTextureOriginInfo(); +		debug_line += " [" + origin_string + "]"; +		S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion(); +		S32 last_request_cof_version = mLastUpdateRequestCOFVersion; +		S32 last_received_cof_version = mLastUpdateReceivedCOFVersion; +		if (isSelf()) +		{ +			debug_line += llformat(" - cof: %d req: %d rcv:%d", +								   curr_cof_version, last_request_cof_version, last_received_cof_version); +			if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure")) +			{ +				debug_line += " FORCING ERRS"; +			} +		} +		else +		{ +			debug_line += llformat(" - cof rcv:%d", last_received_cof_version); +		} +		addDebugText(debug_line); +	} +	if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) +	{ +		if (!mBakedTextureDebugText.empty()) +			addDebugText(mBakedTextureDebugText); +	} +				   	if (LLVOAvatar::sShowAnimationDebug)  	{  		for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); @@ -3588,8 +3166,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  	xyVel.mV[VZ] = 0.0f;  	speed = xyVel.length(); -	BOOL throttle = TRUE; -  	if (!(mIsSitting && getParent()))  	{  		//-------------------------------------------------------------------- @@ -3600,11 +3176,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() );  		}  		//-------------------------------------------------------------------- @@ -3629,6 +3204,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  		}  		root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition()); +		root_pos.mdV[VZ] += getVisualParamWeight(AVATAR_HOVER); +  		resolveHeightGlobal(root_pos, ground_under_pelvis, normal);  		F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);				 @@ -3647,10 +3224,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				  		} @@ -3711,7 +3288,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); @@ -3720,7 +3297,7 @@ 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 ); +			LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV );  			static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow");  			static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast"); @@ -3806,14 +3383,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());  	}  	//------------------------------------------------------------------------- @@ -3909,7 +3486,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  		}  	} -	mRoot.updateWorldMatrixChildren(); +	mRoot->updateWorldMatrixChildren();  	if (!mDebugText.size() && mText.notNull())  	{ @@ -3933,7 +3510,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()) @@ -3971,8 +3548,8 @@ void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount,  void LLVOAvatar::postPelvisSetRecalc( void )  {	  	computeBodySize();  -	mRoot.touch(); -	mRoot.updateWorldMatrixChildren();	 +	mRoot->touch(); +	mRoot->updateWorldMatrixChildren();	  	dirtyMesh();  	updateHeadOffset();  } @@ -4120,7 +3697,7 @@ void LLVOAvatar::updateVisibility()  // private  bool LLVOAvatar::shouldAlphaMask()  { -	const bool should_alpha_mask = mSupportsAlphaLayers && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked +	const bool should_alpha_mask = !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked  							&& !LLDrawPoolAvatar::sSkipTransparent;  	return should_alpha_mask; @@ -4159,19 +3736,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; @@ -4288,19 +3890,31 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  			{  				if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy)  				{ -					num_indices += mMeshLOD[MESH_ID_HEAD]->render(mAdjustedPixelArea, TRUE, mIsDummy); +					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); +				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); +				LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); +				if (lower_mesh) +				{ +					num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +				}  				first_pass = FALSE;  			}  		} @@ -4333,7 +3947,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);  	} @@ -4347,16 +3965,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) -			&& 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) @@ -4400,8 +4025,16 @@ U32 LLVOAvatar::renderRigid()  	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) @@ -4448,11 +4081,224 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)  	return 6;  } -//------------------------------------------------------------------------ -// LLVOAvatar::updateTextures() -//------------------------------------------------------------------------ +bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const +{ +	for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it) +	{ +		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it); +		if (imagep && imagep->getDiscardLevel()!=0) +		{ +			return false; +		} +	} +	return true; +} + +bool LLVOAvatar::allLocalTexturesCompletelyDownloaded() const +{ +	std::set<LLUUID> local_ids; +	collectLocalTextureUUIDs(local_ids); +	return allTexturesCompletelyDownloaded(local_ids); +} + +bool LLVOAvatar::allBakedTexturesCompletelyDownloaded() const +{ +	std::set<LLUUID> baked_ids; +	collectBakedTextureUUIDs(baked_ids); +	return allTexturesCompletelyDownloaded(baked_ids); +} + +void LLVOAvatar::bakedTextureOriginCounts(S32 &sb_count, // server-bake, has origin URL. +										  S32 &host_count, // host-based bake, has host. +										  S32 &both_count, // error - both host and URL set. +										  S32 &neither_count) // error - neither set. +{ +	sb_count = host_count = both_count = neither_count = 0; +	 +	std::set<LLUUID> baked_ids; +	collectBakedTextureUUIDs(baked_ids); +	for (std::set<LLUUID>::const_iterator it = baked_ids.begin(); it != baked_ids.end(); ++it) +	{ +		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it); +		bool has_url = false, has_host = false; +		if (!imagep->getUrl().empty()) +		{ +			has_url = true; +		} +		if (imagep->getTargetHost().isOk()) +		{ +			has_host = true; +		} +		if (has_url && !has_host) sb_count++; +		else if (has_host && !has_url) host_count++; +		else if (has_host && has_url) both_count++; +		else if (!has_host && !has_url) neither_count++; +	} +} + +std::string LLVOAvatar::bakedTextureOriginInfo() +{ +	std::string result; +	 +	std::set<LLUUID> baked_ids; +	collectBakedTextureUUIDs(baked_ids); +	for (U32 i = 0; i < mBakedTextureDatas.size(); i++) +	{ +		ETextureIndex texture_index = mBakedTextureDatas[i].mTextureIndex; +		LLViewerFetchedTexture *imagep = +			LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE); +		if (!imagep || +			imagep->getID() == IMG_DEFAULT || +			imagep->getID() == IMG_DEFAULT_AVATAR) +			 +		{ +			result += "-"; +		} +		else +		{ +			bool has_url = false, has_host = false; +			if (!imagep->getUrl().empty()) +			{ +				has_url = true; +			} +			if (imagep->getTargetHost().isOk()) +			{ +				has_host = true; +			} +			S32 discard = imagep->getDiscardLevel(); +			if (has_url && !has_host) result += discard ? "u" : "U"; // server-bake texture with url  +			else if (has_host && !has_url) result += discard ? "h" : "H"; // old-style texture on sim +			else if (has_host && has_url) result += discard ? "x" : "X"; // both origins? +			else if (!has_host && !has_url) result += discard ? "n" : "N"; // no origin? +			if (discard != 0) +			{ +				result += llformat("(%d/%d)",discard,imagep->getDesiredDiscardLevel()); +			} +		} + +	} +	return result; +} + +S32 LLVOAvatar::totalTextureMemForUUIDS(std::set<LLUUID>& ids) +{ +	S32 result = 0; +	for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it) +	{ +		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it); +		if (imagep) +		{ +			result += imagep->getTextureMemory(); +		} +	} +	return result; +} +	 +void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const +{ +	for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) +	{ +		LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index); +		U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); + +		LLViewerFetchedTexture *imagep = NULL; +		for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++) +		{ +			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE); +			if (imagep) +			{ +				const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index); +				if (texture_dict->mIsLocalTexture) +				{ +					ids.insert(imagep->getID()); +				} +			} +		} +	} +	ids.erase(IMG_DEFAULT); +	ids.erase(IMG_DEFAULT_AVATAR); +	ids.erase(IMG_INVISIBLE); +} + +void LLVOAvatar::collectBakedTextureUUIDs(std::set<LLUUID>& ids) const +{ +	for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) +	{ +		LLViewerFetchedTexture *imagep = NULL; +		if (isIndexBakedTexture((ETextureIndex) texture_index)) +		{ +			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE); +			if (imagep) +			{ +				ids.insert(imagep->getID()); +			} +		} +	} +	ids.erase(IMG_DEFAULT); +	ids.erase(IMG_DEFAULT_AVATAR); +	ids.erase(IMG_INVISIBLE); +} + +void LLVOAvatar::collectTextureUUIDs(std::set<LLUUID>& ids) +{ +	collectLocalTextureUUIDs(ids); +	collectBakedTextureUUIDs(ids); +} + +void LLVOAvatar::releaseOldTextures() +{ +	S32 current_texture_mem = 0; +	 +	// Any textures that we used to be using but are no longer using should no longer be flagged as "NO_DELETE" +	std::set<LLUUID> baked_texture_ids; +	collectBakedTextureUUIDs(baked_texture_ids); +	S32 new_baked_mem = totalTextureMemForUUIDS(baked_texture_ids); + +	std::set<LLUUID> local_texture_ids; +	collectLocalTextureUUIDs(local_texture_ids); +	//S32 new_local_mem = totalTextureMemForUUIDS(local_texture_ids); + +	std::set<LLUUID> new_texture_ids; +	new_texture_ids.insert(baked_texture_ids.begin(),baked_texture_ids.end()); +	new_texture_ids.insert(local_texture_ids.begin(),local_texture_ids.end()); +	S32 new_total_mem = totalTextureMemForUUIDS(new_texture_ids); + +	//S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs); +	//LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << llendl;   +	if (!isSelf() && new_total_mem > new_baked_mem) +	{ +			llwarns << "extra local textures stored for non-self av" << llendl; +	} +	for (std::set<LLUUID>::iterator it = mTextureIDs.begin(); it != mTextureIDs.end(); ++it) +	{ +		if (new_texture_ids.find(*it) == new_texture_ids.end()) +		{ +			LLViewerFetchedTexture *imagep = gTextureList.findImage(*it); +			if (imagep) +			{ +				current_texture_mem += imagep->getTextureMemory(); +				if (imagep->getTextureState() == LLGLTexture::NO_DELETE) +				{ +					// This will allow the texture to be deleted if not in use. +					imagep->forceActive(); + +					// This resets the clock to texture being flagged +					// as unused, preventing the texture from being +					// deleted immediately. If other avatars or +					// objects are using it, it can still be flagged +					// no-delete by them. +					imagep->forceUpdateBindStats(); +				} +			} +		} +	} +	mTextureIDs = new_texture_ids; +} +  void LLVOAvatar::updateTextures()  { +	releaseOldTextures(); +	  	BOOL render_avatar = TRUE;  	if (mIsDummy) @@ -4495,7 +4341,7 @@ 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); @@ -4518,11 +4364,11 @@ void LLVOAvatar::updateTextures()  			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);  			if (imagep)  			{ -				const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->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)  				{ -					addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); +					addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, mBakedTextureDatas[baked_index].mIsUsed);  				}  			}  		} @@ -4534,6 +4380,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 " @@ -4554,7 +4401,7 @@ void LLVOAvatar::updateTextures()  void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture* imagep, -									   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index ) +									   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)  {  	// No local texture stats for non-self avatars  	return; @@ -4628,7 +4475,6 @@ 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.  	imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);  	imagep->resetMaxVirtualSizeResetCounter() ; @@ -4637,7 +4483,7 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel  	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) ;  	} @@ -4670,6 +4516,30 @@ void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te)  	setTE(index, te);  } +const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid) +{ +	llassert(isIndexBakedTexture(ETextureIndex(te))); +	std::string url = ""; +	if (isUsingServerBakes()) +	{ +		const std::string& appearance_service_url = LLAppearanceMgr::instance().getAppearanceServiceURL(); +		if (appearance_service_url.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 = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString(); +			//llinfos << "baked texture url: " << url << llendl; +		} +	} +	return url; +} +  //-----------------------------------------------------------------------------  // resolveHeight()  //----------------------------------------------------------------------------- @@ -5011,48 +4881,6 @@ void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id)  }  //----------------------------------------------------------------------------- -// getVolumePos() -//----------------------------------------------------------------------------- -LLVector3 LLVOAvatar::getVolumePos(S32 joint_index, LLVector3& volume_offset) -{ -	if (joint_index > mNumCollisionVolumes) -	{ -		return LLVector3::zero; -	} - -	return mCollisionVolumes[joint_index].getVolumePos(volume_offset); -} - -//----------------------------------------------------------------------------- -// findCollisionVolume() -//----------------------------------------------------------------------------- -LLJoint* LLVOAvatar::findCollisionVolume(U32 volume_id) -{ -	if ((S32)volume_id > mNumCollisionVolumes) -	{ -		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()  //-----------------------------------------------------------------------------  void LLVOAvatar::addDebugText(const std::string& text) @@ -5081,7 +4909,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 @@ -5097,10 +4925,12 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )  //-----------------------------------------------------------------------------  void LLVOAvatar::resetJointPositions( void )  { -	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)  	{ -		mSkeleton[i].restoreOldXform(); -		mSkeleton[i].setId( LLUUID::null ); +		(*iter)->restoreOldXform(); +		(*iter)->setId( LLUUID::null );  	}  	mHasPelvisOffset = false;  	mPelvisFixup	 = mLastPelvisFixup; @@ -5110,7 +4940,7 @@ void LLVOAvatar::resetJointPositions( void )  //-----------------------------------------------------------------------------  void LLVOAvatar::resetSpecificJointPosition( const std::string& name )  { -	LLJoint* pJoint = mRoot.findJoint( name ); +	LLJoint* pJoint = mRoot->findJoint( name );  	if ( pJoint  && pJoint->doesJointNeedToBeReset() )  	{ @@ -5132,16 +4962,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(); @@ -5240,23 +5071,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() @@ -5274,61 +5088,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() @@ -5340,215 +5099,24 @@ void LLVOAvatar::requestStopMotion( LLMotion* motion )  }  //----------------------------------------------------------------------------- -// 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 : <skeleton> -	if( !loadSkeletonNode() ) -	{ -		llwarns << "avatar file: loadNodeSkeleton() failed" << llendl; -		return FALSE; -	} -	 -	// avatar_lad.xml : <mesh> -	if( !loadMeshNodes() ) -	{ -		llwarns << "avatar file: loadNodeMesh() failed" << llendl; -		return FALSE; -	} -	 -	// avatar_lad.xml : <global_color> -	if( sAvatarXmlInfo->mTexSkinColorInfo ) -	{ -		mTexSkinColor = new LLTexGlobalColor( this ); -		if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) ) -		{ -			llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl; -			return FALSE; -		} -	} -	else -	{ -		llwarns << "<global_color> 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 << "<global_color> 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 << "<global_color> name=\"eye_color\" not found" << llendl; -		return FALSE; -	} -	 -	// avatar_lad.xml : <layer_set> -	if (sAvatarXmlInfo->mLayerInfoList.empty()) -	{ -		llwarns << "avatar file: missing <layer_set> node" << llendl; -		return FALSE; -	} - -	if (sAvatarXmlInfo->mMorphMaskInfoList.empty()) -	{ -		llwarns << "avatar file: missing <morph_masks> node" << llendl; -		return FALSE; -	} - -	// avatar_lad.xml : <morph_masks> -	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 : <driver_parameters> -	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 <skeleton> node from XML tree  //----------------------------------------------------------------------------- +//virtual  BOOL LLVOAvatar::loadSkeletonNode ()  { -	mRoot.addChild( &mSkeleton[0] ); - -	for (std::vector<LLViewerJoint *>::iterator iter = mMeshLOD.begin(); -		 iter != mMeshLOD.end();  -		 ++iter) -	{ -		LLViewerJoint *joint = (LLViewerJoint *) *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]); - -	LLViewerJoint *skull = (LLViewerJoint*)mRoot.findJoint("mSkull"); -	if (skull) -	{ -		skull->addChild(mMeshLOD[MESH_ID_HAIR] ); -	} - -	LLViewerJoint *eyeL = (LLViewerJoint*)mRoot.findJoint("mEyeLeft"); -	if (eyeL) +	if (!LLAvatarAppearance::loadSkeletonNode())  	{ -		eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] ); -	} - -	LLViewerJoint *eyeR = (LLViewerJoint*)mRoot.findJoint("mEyeRight"); -	if (eyeR) -	{ -		eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] ); +		return FALSE;  	} -	// 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; @@ -5621,144 +5189,6 @@ BOOL LLVOAvatar::loadSkeletonNode ()  }  //----------------------------------------------------------------------------- -// loadMeshNodes(): loads <mesh> 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: <mesh> 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()  //-----------------------------------------------------------------------------  void LLVOAvatar::updateVisualParams() @@ -5771,7 +5201,7 @@ void LLVOAvatar::updateVisualParams()  	{  		computeBodySize();  		mLastSkeletonSerialNum = mSkeletonSerialNum; -		mRoot.updateWorldMatrixChildren(); +		mRoot->updateWorldMatrixChildren();  	}  	dirtyMesh(); @@ -5858,7 +5288,12 @@ BOOL LLVOAvatar::updateJointLODs()  		}  		// now select meshes to render based on adjusted pixel area -		BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE); +		LLViewerJoint* root = dynamic_cast<LLViewerJoint*>(mRoot); +		BOOL res = FALSE; +		if (root) +		{ +			res = root->updateLOD(mAdjustedPixelArea, TRUE); +		}   		if (res)  		{  			sNumLODChangesThisFrame++; @@ -5947,6 +5382,15 @@ void LLVOAvatar::dirtyMesh(S32 priority)  {  	mDirtyMesh = llmax(mDirtyMesh, priority);  } + +//----------------------------------------------------------------------------- +// getViewerJoint() +//----------------------------------------------------------------------------- +LLViewerJoint*	LLVOAvatar::getViewerJoint(S32 idx) +{ +	return dynamic_cast<LLViewerJoint*>(mMeshLOD[idx]); +} +  //-----------------------------------------------------------------------------  // hideSkirt()  //----------------------------------------------------------------------------- @@ -6253,9 +5697,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); @@ -6301,10 +5745,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); @@ -6352,26 +5796,53 @@ S32 LLVOAvatar::getAttachmentCount()  	return count;  } -LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const +BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const  { -	if (color_name=="skin_color" && mTexSkinColor) -	{ -		return mTexSkinColor->getColor(); -	} -	else if(color_name=="hair_color" && mTexHairColor) +	if (mIsDummy) return TRUE; + +	if (isSelf())  	{ -		return mTexHairColor->getColor(); +		return LLAvatarAppearance::isWearingWearableType(type);  	} -	if(color_name=="eye_color" && mTexEyeColor) + +	switch(type)  	{ -		return mTexEyeColor->getColor(); +		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  	} -	else + +	/* 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)  	{ -		return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color +		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second; +		if (texture_dict->mWearableType == type) +		{ +			// Thus, you must check to see if the corresponding baked texture is defined. +			// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing +			// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that +			// gets baked into a texture that always exists (upper or lower). +			if (texture_dict->mIsUsedByBakedTexture) +			{ +				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; +				return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex); +			} +			return FALSE; +		}  	} +	return FALSE;  } + +  // virtual  void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )  { @@ -6381,6 +5852,7 @@ void LLVOAvatar::invalidateAll()  {  } +// virtual  void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake )  {  	if (global_color == mTexSkinColor) @@ -6399,9 +5871,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 ); +				}  			}  		}  	}  @@ -6444,42 +5922,167 @@ BOOL LLVOAvatar::getIsCloud() const  void LLVOAvatar::updateRezzedStatusTimers()  { -	// State machine for rezzed status. Statuses are 0 = cloud, 1 = gray, 2 = textured. -	// Purpose is to collect time data for each period of cloud or cloud+gray. +	// State machine for rezzed status. Statuses are -1 on startup, 0 +	// = cloud, 1 = gray, 2 = textured, 3 = textured_and_downloaded. +	// Purpose is to collect time data for each it takes avatar to reach +	// various loading landmarks: gray, textured (partial), textured fully. +  	S32 rez_status = getRezzedStatus();  	if (rez_status != mLastRezzedStatus)  	{  		LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL; -		bool is_cloud_or_gray = (rez_status==0 || rez_status==1); -		bool was_cloud_or_gray = (mLastRezzedStatus==0 || mLastRezzedStatus==1); -		bool is_cloud = (rez_status==0); -		bool was_cloud = (mLastRezzedStatus==0); -		// Non-cloud to cloud -		if (is_cloud && !was_cloud) +		if (mLastRezzedStatus == -1 && rez_status != -1) +		{ +			// First time initialization, start all timers. +			for (S32 i = 1; i < 4; i++) +			{ +				startPhase("load_" + LLVOAvatar::rezStatusToString(i)); +				startPhase("first_load_" + LLVOAvatar::rezStatusToString(i)); +			} +		} +		if (rez_status < mLastRezzedStatus) +		{ +			// load level has decreased. start phase timers for higher load levels. +			for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++) +			{ +				startPhase("load_" + LLVOAvatar::rezStatusToString(i)); +			} +		} +		else if (rez_status > mLastRezzedStatus) +		{ +			// load level has increased. stop phase timers for lower and equal load levels. +			for (S32 i = llmax(mLastRezzedStatus+1,1); i <= rez_status; i++) +			{ +				stopPhase("load_" + LLVOAvatar::rezStatusToString(i)); +				stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false); +			} +			if (rez_status == 3) +			{ +				// "fully loaded", mark any pending appearance change complete. +				selfStopPhase("update_appearance_from_cof"); +				selfStopPhase("wear_inventory_category", false); +				selfStopPhase("process_initial_wearables_update", false); +			} +		} + +		mLastRezzedStatus = rez_status; +	} +} + +void LLVOAvatar::clearPhases() +{ +	getPhases().clearPhases(); +} + +void LLVOAvatar::startPhase(const std::string& phase_name) +{ +	F32 elapsed; +	bool completed; +	if (getPhases().getPhaseValues(phase_name, elapsed, completed)) +	{ +		if (!completed) +		{ +			LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << llendl; +			return; +		} +	} +	LL_DEBUGS("Avatar") << "started phase " << phase_name << llendl; +	getPhases().startPhase(phase_name); +} + +void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check) +{ +	F32 elapsed; +	bool completed; +	if (getPhases().getPhaseValues(phase_name, elapsed, completed)) +	{ +		if (!completed)  		{ -			// start cloud timer. -			getPhases().startPhase("cloud"); +			getPhases().stopPhase(phase_name); +			completed = true; +			logMetricsTimerRecord(phase_name, elapsed, completed); +			LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << llendl;  		} -		else if (was_cloud && !is_cloud) +		else  		{ -			// stop cloud timer, which will capture stats. -			getPhases().stopPhase("cloud"); +			if (err_check) +			{ +				LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << llendl; +			}  		} +	} +	else +	{ +		if (err_check) +		{ +			LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << llendl; +		} +	} +} -		// Non-cloud-or-gray to cloud-or-gray -		if (is_cloud_or_gray && !was_cloud_or_gray) +void LLVOAvatar::logPendingPhases() +{ +	for (LLViewerStats::phase_map_t::iterator it = getPhases().begin(); +		 it != getPhases().end(); +		 ++it) +	{ +		const std::string& phase_name = it->first; +		F32 elapsed; +		bool completed; +		if (getPhases().getPhaseValues(phase_name, elapsed, completed))  		{ -			// start cloud-or-gray timer. -			getPhases().startPhase("cloud-or-gray"); +			if (!completed) +			{ +				logMetricsTimerRecord(phase_name, elapsed, completed); +			}  		} -		else if (was_cloud_or_gray && !is_cloud_or_gray) +	} +} + +//static +void LLVOAvatar::logPendingPhasesAllAvatars() +{ +	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); +		 iter != LLCharacter::sInstances.end(); ++iter) +	{ +		LLVOAvatar* inst = (LLVOAvatar*) *iter; +		if( inst->isDead() )  		{ -			// stop cloud-or-gray timer, which will capture stats. -			getPhases().stopPhase("cloud-or-gray"); +			continue;  		} -		 -		mLastRezzedStatus = rez_status; +		inst->logPendingPhases(); +	} +} + +void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed) +{ +	LLSD record; +	record["timer_name"] = phase_name; +	record["avatar_id"] = getID(); +	record["elapsed"] = elapsed; +	record["completed"] = completed; +	U32 grid_x(0), grid_y(0); +	if (getRegion()) +	{ +		record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion()); +		grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y); +	} +	record["grid_x"] = LLSD::Integer(grid_x); +	record["grid_y"] = LLSD::Integer(grid_y); +	record["is_using_server_bakes"] = ((bool) isUsingServerBakes()); +	record["is_self"] = isSelf(); +	 + +#if 0 // verbose logging +	std::ostringstream ostr; +	ostr << LLSDNotationStreamer(record); +	LL_DEBUGS("Avatar") << "record\n" << ostr.str() << llendl; +#endif + +	if (isAgentAvatarValid()) +	{ +		gAgentAvatarp->addMetricsTimerRecord(record);  	}  } @@ -6576,24 +6179,49 @@ LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const  	return mMotionController.findMotion(id);  } +// This is a semi-deprecated debugging tool - meshes will not show as +// colorized if using deferred rendering. +void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color) +{ +	if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) +	{ +		avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); +		avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end(); +		for (; iter != end; ++iter) +		{ +			LLAvatarJointMesh* mesh = (*iter); +			if (mesh) +			{ +				{ +					mesh->setColor(color); +				} +			} +		} +	} +} +  //-----------------------------------------------------------------------------  // updateMeshTextures()  // Uses the current TE values to set the meshes' and layersets' textures.  //----------------------------------------------------------------------------- +// virtual  void LLVOAvatar::updateMeshTextures()  { -    // llinfos << "updateMeshTextures" << llendl; +	static S32 update_counter = 0; +	mBakedTextureDebugText.clear(); +	  	// if user has never specified a texture, assign the default  	for (U32 i=0; i < getNumTEs(); i++)  	{  		const LLViewerTexture* te_image = getImage(i, 0);  		if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT))  		{ -			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; @@ -6609,71 +6237,97 @@ void LLVOAvatar::updateMeshTextures()  	std::vector<BOOL> use_lkg_baked_layer; // lkg = "last known good"  	use_lkg_baked_layer.resize(mBakedTextureDatas.size(), false); +	mBakedTextureDebugText += llformat("%06d\n",update_counter++); +	mBakedTextureDebugText += "indx layerset linvld ltda ilb ulkg ltid\n";  	for (U32 i=0; i < mBakedTextureDatas.size(); i++)  	{  		is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex); - +		LLViewerTexLayerSet* layerset = NULL; +		bool layerset_invalid = false;  		if (!other_culled)  		{  			// When an avatar is changing clothes and not in Appearance mode, -			// use the last-known good baked texture until it 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);  		} -	} - -	// 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; +		std::string last_id_string; +		if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT_AVATAR) +			last_id_string = "A"; +		else if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT) +			last_id_string = "D"; +		else if (mBakedTextureDatas[i].mLastTextureID == IMG_INVISIBLE) +			last_id_string = "I"; +		else +			last_id_string = "*"; +		bool is_ltda = layerset +			&& layerset->getViewerComposite()->isInitialized() +			&& layerset->isLocalTextureDataAvailable(); +		mBakedTextureDebugText += llformat("%4d   %4s     %4d %4d %4d %4d %4s\n", +										   i, +										   (layerset?"*":"0"), +										   layerset_invalid, +										   is_ltda, +										   is_layer_baked[i], +										   use_lkg_baked_layer[i], +										   last_id_string.c_str());  	}  	for (U32 i=0; i < mBakedTextureDatas.size(); i++)  	{ -		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 ); +			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);  			mBakedTextureDatas[i].mIsUsed = TRUE; -			for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++) + +			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)  			{ -				mBakedTextureDatas[i].mMeshes[k]->setTexture( baked_img ); +				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);	 @@ -6682,40 +6336,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(); @@ -6743,7 +6416,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); @@ -6778,18 +6451,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) +	{ +		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)  	{ -		LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer); -		mBakedTextureDatas[index].mMaskedMorphs.push_front(morph); +		const LLMaskedMorph* maskedMorph = (*iter); +		LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget); +		if (morph_target) +		{ +			morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert); +		}  	}  } +  // returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise -BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index) +BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index)  {  	if (index >= BAKED_NUM_INDICES)  	{ @@ -6800,7 +6485,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(); @@ -6815,23 +6500,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 @@ -6854,7 +6522,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) )) @@ -6870,120 +6538,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 ) @@ -7009,48 +6571,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()  //----------------------------------------------------------------------------- @@ -7131,7 +6651,7 @@ LLBBox LLVOAvatar::getHUDBBox() const  //-----------------------------------------------------------------------------  void LLVOAvatar::onFirstTEMessageReceived()  { -	LL_INFOS("Avatar") << avString() << LL_ENDL; +	LL_DEBUGS("Avatar") << avString() << LL_ENDL;  	if( !mFirstTEMessageReceived )  	{  		mFirstTEMessageReceived = TRUE; @@ -7153,7 +6673,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)) )  				{ @@ -7205,85 +6725,106 @@ bool LLVOAvatar::visualParamWeightsAreDefault()  	return rtn;  } - -//----------------------------------------------------------------------------- -// processAvatarAppearance() -//----------------------------------------------------------------------------- -void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) +void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)  { -	if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages")) +	std::string type_string = "unknown"; +	if (dynamic_cast<LLTexLayerParamAlpha*>(viewer_param)) +		type_string = "param_alpha"; +	if (dynamic_cast<LLTexLayerParamColor*>(viewer_param)) +		type_string = "param_color"; +	if (dynamic_cast<LLDriverParam*>(viewer_param)) +		type_string = "param_driver"; +	if (dynamic_cast<LLPolyMorphTarget*>(viewer_param)) +		type_string = "param_morph"; +	if (dynamic_cast<LLPolySkeletalDistortion*>(viewer_param)) +		type_string = "param_skeleton"; +	S32 wtype = -1; +	LLViewerVisualParam *vparam = dynamic_cast<LLViewerVisualParam*>(viewer_param); +	if (vparam)  	{ -		llwarns << "Blocking AvatarAppearance message" << llendl; -		return; +		wtype = vparam->getWearableType();  	} -	 -	BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; -	mFirstAppearanceMessageReceived = TRUE; +	S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight()); +	apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\"/>\n", +					viewer_param->getID(), viewer_param->getName().c_str(), value, u8_value, type_string.c_str(), +					LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str() +//					param_location_name(vparam->getParamLocation()).c_str() +		); +} -	LL_INFOS("Avatar") << avString() << "processAvatarAppearance start " << mID -			<< " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; +void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, +	const LLAppearanceMessageContents& contents) +{ +	std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml"); +	const std::vector<F32>& params_for_dump = contents.mParamWeights; +	const LLTEContents& tec = contents.mTEContents; -	if( isSelf() ) +	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)  	{ -		llwarns << avString() << "Received AvatarAppearance for self" << llendl; -		if( mFirstTEMessageReceived ) -		{ -//			llinfos << "processAvatarAppearance end  " << mID << llendl; -			return; -		} +		return; +	} +	else +	{ +		LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << llendl;  	} -	ESex old_sex = getSex(); - -//	llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl; -//	dumpAvatarTEs( "PRE  processAvatarAppearance()" ); -	unpackTEMessage(mesgsys, _PREHASH_ObjectData); -//	dumpAvatarTEs( "POST processAvatarAppearance()" ); +	apr_file_printf(file, "<header>\n"); +	apr_file_printf(file, "\t\t<cof_version %i />\n", contents.mCOFVersion); +	apr_file_printf(file, "\t\t<appearance_version %i />\n", contents.mAppearanceVersion); +	apr_file_printf(file, "</header>\n"); -	// prevent the overwriting of valid baked textures with invalid baked textures -	for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++) +	apr_file_printf(file, "\n<params>\n"); +	LLVisualParam* param = getFirstVisualParam(); +	for (S32 i = 0; i < params_for_dump.size(); i++)  	{ -		if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex)  -			&& mBakedTextureDatas[baked_index].mLastTextureIndex != IMG_DEFAULT -			&& baked_index != BAKED_SKIRT) +		while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT  		{ -			setTEImage(mBakedTextureDatas[baked_index].mTextureIndex,  -						LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex,  -																TRUE,  -																LLViewerTexture::BOOST_NONE,  -																LLViewerTexture::LOD_TEXTURE)); +			param = getNextVisualParam();  		} +		LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; +		F32 value = params_for_dump[i]; +		dump_visual_param(file, viewer_param, value); +		param = getNextVisualParam();  	} +	apr_file_printf(file, "</params>\n"); - -	// runway - was -	// if (!is_first_appearance_message ) -	// which means it would be called on second appearance message - probably wrong. -	if (is_first_appearance_message ) +	apr_file_printf(file, "\n<textures>\n"); +	for (U32 i = 0; i < tec.face_count; i++)  	{ -		onFirstTEMessageReceived(); +		std::string uuid_str; +		((LLUUID*)tec.image_data)[i].toString(uuid_str); +		apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str());  	} +	apr_file_printf(file, "</textures>\n"); +} -	setCompositeUpdatesEnabled( FALSE ); -	mMeshTexturesDirty = TRUE; -	gPipeline.markGLRebuild(this); +void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents) +{ +	parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, contents.mTEContents); -	// ! BACKWARDS COMPATIBILITY ! -	// Non-self avatars will no longer have component textures -	if (!isSelf()) +	// Parse the AppearanceData field, if any. +	if (mesgsys->has(_PREHASH_AppearanceData))  	{ -		releaseComponentTextures(); +		U8 av_u8; +		mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0); +		contents.mAppearanceVersion = av_u8; +		LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << llendl; +		mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0); +		// For future use: +		//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);  	} -	 -	// parse visual params + +	// Parse visual params, if any.  	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);  	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; -		BOOL interp_params = FALSE;  		LLVisualParam* param = getFirstVisualParam();  		llassert(param); // if this ever fires, we should do the same as when num_blocks<=1 @@ -7309,21 +6850,9 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  				U8 value;  				mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i);  				F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight()); +				contents.mParamWeights.push_back(newWeight); +				contents.mParams.push_back(param); -				if (is_first_appearance_message || (param->getWeight() != newWeight)) -				{ -					//llinfos << "Received update for param " << param->getDisplayName() << " at value " << newWeight << llendl; -					params_changed = TRUE; -					if(is_first_appearance_message) -					{ -						param->setWeight(newWeight, FALSE); -					} -					else -					{ -						interp_params = TRUE; -						param->setAnimationTarget(newWeight, FALSE); -					} -				}  				param = getNextVisualParam();  			}  		} @@ -7331,7 +6860,210 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  		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)  		{ -			llinfos << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << ").  Processing what we can.  object: " << getID() << llendl; +			LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << ").  Processing what we can.  object: " << getID() << llendl; +		} +	} +	else +	{ +		if (drop_visual_params_debug) +		{ +			llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: "  << getID() << llendl; +		} +		else +		{ +			LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl; +		} +	} + +	LLVisualParam* appearance_version_param = getVisualParam(11000); +	if (appearance_version_param) +	{ +		std::vector<LLVisualParam*>::iterator it = std::find(contents.mParams.begin(), contents.mParams.end(),appearance_version_param); +		if (it != contents.mParams.end()) +		{ +			S32 index = it - contents.mParams.begin(); +			contents.mParamAppearanceVersion = llround(contents.mParamWeights[index]); +			LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << llendl; +		} +	} +} + +bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32& appearance_version) +{ +	appearance_version = -1; +	 +	if ((contents.mAppearanceVersion) >= 0 && +		(contents.mParamAppearanceVersion >= 0) && +		(contents.mAppearanceVersion != contents.mParamAppearanceVersion)) +	{ +		llwarns << "inconsistent appearance_version settings - field: " << +			contents.mAppearanceVersion << ", param: " <<  contents.mParamAppearanceVersion << llendl; +		return false; +	} +	if (contents.mParamAppearanceVersion >= 0) // use visual param if available. +	{ +		appearance_version = contents.mParamAppearanceVersion; +	} +	if (contents.mAppearanceVersion >= 0) +	{ +		appearance_version = contents.mAppearanceVersion; +	} +	if (appearance_version < 0) // still not set, go with 0. +	{ +		appearance_version = 0; +	} +	LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion +						<< " param: " << contents.mParamAppearanceVersion +						<< " final: " << appearance_version << llendl; +	return true; +} + +//----------------------------------------------------------------------------- +// processAvatarAppearance() +//----------------------------------------------------------------------------- +void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) +{ +	LL_DEBUGS("Avatar") << "starts" << llendl; +	 +	bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"); +	std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_"; +	if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages")) +	{ +		llwarns << "Blocking AvatarAppearance message" << llendl; +		return; +	} + +	ESex old_sex = getSex(); + +	LLAppearanceMessageContents contents; +	parseAppearanceMessage(mesgsys, contents); +	if (enable_verbose_dumps) +	{ +		dumpAppearanceMsgParams(dump_prefix + "appearance_msg", contents); +	} + +	S32 appearance_version; +	if (!resolve_appearance_version(contents, appearance_version)) +	{ +		llwarns << "bad appearance version info, discarding" << llendl; +		return; +	} +	S32 this_update_cof_version = contents.mCOFVersion; +	S32 last_update_request_cof_version = mLastUpdateRequestCOFVersion; + +	// Only now that we have result of appearance_version can we decide whether to bail out. +	if( isSelf() ) +	{ +		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)) +		{ +			return; +		} +	} +	else +	{ +		LL_DEBUGS("Avatar") << "appearance message received" << llendl; +	} + +	// 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()) +	{ +		LL_DEBUGS("Avatar") << "ignoring appearance message while in appearance edit" << llendl; +		return; +	} + +	S32 num_params = contents.mParamWeights.size(); +	if (num_params <= 1) +	{ +		// In this case, we have no reliable basis for knowing +		// appearance version, which may cause us to look for baked +		// textures in the wrong place and flag them as missing +		// assets. +		LL_DEBUGS("Avatar") << "ignoring appearance message due to lack of params" << llendl; +		return; +	} + +	mLastUpdateReceivedCOFVersion = this_update_cof_version; +		 +	setIsUsingServerBakes(appearance_version > 0); + +	applyParsedTEMessage(contents.mTEContents); + +	// prevent the overwriting of valid baked textures with invalid baked textures +	for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++) +	{ +		if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex)  +			&& mBakedTextureDatas[baked_index].mLastTextureID != IMG_DEFAULT +			&& baked_index != BAKED_SKIRT) +		{ +			setTEImage(mBakedTextureDatas[baked_index].mTextureIndex,  +				LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); +		} +	} + +	// runway - was +	// if (!is_first_appearance_message ) +	// which means it would be called on second appearance message - probably wrong. +	BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; +	mFirstAppearanceMessageReceived = TRUE; + +	LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID +			<< " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; + +	if (is_first_appearance_message ) +	{ +		onFirstTEMessageReceived(); +	} + +	setCompositeUpdatesEnabled( FALSE ); +	gPipeline.markGLRebuild(this); + +	// Apply visual params +	if( num_params > 1) +	{ +		LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL; +		BOOL params_changed = FALSE; +		BOOL interp_params = FALSE; +		 +		for( S32 i = 0; i < num_params; i++ ) +		{ +			LLVisualParam* param = contents.mParams[i]; +			F32 newWeight = contents.mParamWeights[i]; + +			if (is_first_appearance_message || (param->getWeight() != newWeight)) +			{ +				params_changed = TRUE; +				if(is_first_appearance_message) +				{ +					param->setWeight(newWeight, FALSE); +				} +				else +				{ +					interp_params = TRUE; +					param->setAnimationTarget(newWeight, FALSE); +				} +			} +		} +		const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT +		if (num_params != expected_tweakable_count) +		{ +			LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_params << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << ").  Processing what we can.  object: " << getID() << llendl;  		}  		if (params_changed) @@ -7355,14 +7087,6 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	{  		// 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 @@ -7385,7 +7109,14 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	// If all of the avatars are completely baked, release the global image caches to conserve memory.  	LLVOAvatar::cullAvatarsByPixelArea(); -//	llinfos << "processAvatarAppearance end " << mID << llendl; +	if (isSelf()) +	{ +		mUseLocalAppearance = false; +	} + +	updateMeshTextures(); + +	//if (enable_verbose_dumps) dumpArchetypeXML(dump_prefix + "process_end");  }  // static @@ -7415,6 +7146,7 @@ void LLVOAvatar::getAnimNames( LLDynamicArray<std::string>* names )  	names->put( "enter_away_from_keyboard_state" );  } +// static  void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )  {  	if (!userdata) return; @@ -7433,7 +7165,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture  		{  			if (!aux_src->getData())  			{ -				llerrs << "No auxiliary source data for onBakedTextureMasksLoaded" << llendl; +				llerrs << "No auxiliary source (morph mask) data for image id " << id << llendl;  				return;  			} @@ -7458,12 +7190,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; @@ -7485,7 +7217,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture  			}  			if (!found_texture_id)  			{ -				llinfos << "onBakedTextureMasksLoaded(): unexpected image id: " << id << llendl; +				llinfos << "unexpected image id: " << id << llendl;  			}  			self->dirtyMesh();  		} @@ -7493,7 +7225,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture  		{              // this can happen when someone uses an old baked texture possibly provided by               // viewer-side baked texture caching -			llwarns << "Masks loaded callback but NO aux source!" << llendl; +			llwarns << "Masks loaded callback but NO aux source, id " << id << llendl;  		}  	} @@ -7531,7 +7263,7 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success,  									  LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src,  									  S32 discard_level, BOOL final, void* userdata)  { -	//llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl; +	LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL;  	LLUUID id = src_vi->getID();  	LLUUID *avatar_idp = (LLUUID *)userdata; @@ -7568,17 +7300,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) @@ -7591,9 +7337,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 ); +					}  				}  			}  		} @@ -7602,11 +7354,39 @@ 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)  { +	typedef std::map<std::string,S32> file_num_type; +	static  file_num_type file_nums; +	file_num_type::iterator it = file_nums.find(prefix); +	S32 num = 0; +	if (it != file_nums.end()) +	{ +		num = it->second; +	} +	file_nums[prefix] = num+1; +	std::string outfilename = prefix + " " + llformat("%04d",num) + ".xml"; +	std::replace(outfilename.begin(),outfilename.end(),' ','_'); +	return outfilename; +} + +void 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; -	outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"new archetype.xml"), LL_APR_WB ); +	std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); +	outfile.open(fullpath, LL_APR_WB );  	apr_file_t* file = outfile.getFileHandle();  	if (!file)  	{ @@ -7614,36 +7394,60 @@ void LLVOAvatar::dumpArchetypeXML( void* )  	}  	else  	{ -		llinfos << "xmlfile write handle obtained : " << gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"new archetype.xml") << llendl; +		llinfos << "xmlfile write handle obtained : " << fullpath << llendl;  	}  	apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" );  	apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" );  	apr_file_printf( file, "\n\t<archetype name=\"???\">\n" ); -	// 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<!-- wearable: %s -->\n", wearable_name.c_str() ); - -		for (LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam()) +		for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)  		{ -			LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; -			if( (viewer_param->getWearableType() == type) &&  -				(viewer_param->isTweakable() ) ) +			const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); +			apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() ); + +			for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) +			{ +				LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; +				if( (viewer_param->getWearableType() == type) &&  +					(viewer_param->isTweakable() ) ) +				{ +					dump_visual_param(file, viewer_param, viewer_param->getWeight()); +				} +			} + +			for (U8 te = 0; te < TEX_NUM_INDICES; te++)  			{ -				apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n", -								viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight()); +				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<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str()); +					} +				}  			}  		} +	} +	else  +	{ +		// Just dump all params sequentially. +		for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) +		{ +			LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; +			dump_visual_param(file, viewer_param, viewer_param->getWeight()); +		}  		for (U8 te = 0; te < TEX_NUM_INDICES; te++)  		{ -			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; @@ -7652,14 +7456,18 @@ void LLVOAvatar::dumpArchetypeXML( void* )  				}  			}  		} +  	}  	apr_file_printf( file, "\t</archetype>\n" );  	apr_file_printf( file, "\n</linden_genepool>\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  } @@ -7741,15 +7549,9 @@ void LLVOAvatar::cullAvatarsByPixelArea()  		}  	} -	// runway - this doesn't detect gray/grey state. -	// think we just need to be checking self av since it's the only -	// one with lltexlayer stuff. +	// 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  		{ @@ -7777,501 +7579,44 @@ void LLVOAvatar::startAppearanceAnimation()  	}  } -// 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 <skeleton> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root) -{ -	LLXmlTreeNode* node = root->getChildByName( "skeleton" ); -	if( !node ) -	{ -		llwarns << "avatar file: missing <skeleton>" << 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 <mesh> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root) +//virtual +void LLVOAvatar::bodySizeChanged()  { -	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: <mesh> 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: <mesh> 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: <mesh> 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); +	if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF()) +	{	// notify simulator of change in size +		// but not if we are in the middle of updating appearance +		gAgent.sendAgentSetAppearance();  	} -	return TRUE;  } -//----------------------------------------------------------------------------- -// parseXmlColorNodes(): parses <global_color> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root) +BOOL LLVOAvatar::isUsingServerBakes() const  { -	for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" ); -		 color_node; -		 color_node = root->getNextNamedChild()) +#if 1 +	// Sanity check - visual param for appearance version should match mUseServerBakes +	LLVisualParam* appearance_version_param = getVisualParam(11000); +	llassert(appearance_version_param); +	F32 wt = appearance_version_param->getWeight(); +	F32 expect_wt = mUseServerBakes ? 1.0 : 0.0; +	if (!is_approx_equal(wt,expect_wt))  	{ -		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; -				} -			} -		} +		llwarns << "wt " << wt << " differs from expected " << expect_wt << llendl;  	} -	return TRUE; -} +#endif -//----------------------------------------------------------------------------- -// parseXmlLayerNodes(): parses <layer_set> 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; +	return mUseServerBakes;  } -//----------------------------------------------------------------------------- -// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root) +void LLVOAvatar::setIsUsingServerBakes(BOOL newval)  { -	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; +	mUseServerBakes = newval; +	LLVisualParam* appearance_version_param = getVisualParam(11000); +	llassert(appearance_version_param); +	appearance_version_param->setWeight(newval ? 1.0 : 0.0, false);  } -//----------------------------------------------------------------------------- -// parseXmlDriverNodes(): parses <driver_parameters> 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::removeMissingBakedTextures() +{	  }  //virtual @@ -8447,7 +7792,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)))  		{ @@ -8527,11 +7872,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) @@ -8560,26 +7905,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; @@ -8611,7 +7956,7 @@ 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))   	{ @@ -8629,7 +7974,7 @@ BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index  }  //virtual -BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index) const +BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const  {  	if (isIndexLocalTexture(type))  	{ @@ -8645,9 +7990,11 @@ 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;  } + + diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index c59a3a150c..85f6f25009 100644..100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -25,8 +25,8 @@   * $/LicenseInfo$   */ -#ifndef LL_LLVOAVATAR_H -#define LL_LLVOAVATAR_H +#ifndef LL_VOAVATAR_H +#define LL_VOAVATAR_H  #include <map>  #include <deque> @@ -36,6 +36,7 @@  #include <boost/signals2.hpp>  #include "imageids.h"			// IMG_INVISIBLE +#include "llavatarappearance.h"  #include "llchat.h"  #include "lldrawpoolalpha.h"  #include "llviewerobject.h" @@ -44,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 "llviewerstats.h" @@ -62,13 +64,15 @@ 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;  struct LLVOAvatarBoneInfo;  struct LLVOAvatarChildJoint; +//class LLViewerJoint; +struct LLAppearanceMessageContents;  struct LLVOAvatarSkeletonInfo;  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -76,17 +80,14 @@ struct LLVOAvatarSkeletonInfo;  //   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  class LLVOAvatar : +	public LLAvatarAppearance,  	public LLViewerObject, -	public LLCharacter,  	public boost::signals2::trackable  {  	LOG_CLASS(LLVOAvatar);  public:  	friend class LLVOAvatarSelf; -protected: -	struct LLVOAvatarXmlInfo; -	struct LLMaskedMorph;  /********************************************************************************   **                                                                            ** @@ -111,9 +112,6 @@ public:  	virtual void 		initInstance(); // Called after construction to initialize the class.  protected:  	virtual				~LLVOAvatar(); -	BOOL				loadSkeletonNode(); -	BOOL				loadMeshNodes(); -	virtual BOOL		loadLayersets();  /**                    Initialization   **                                                                            ** @@ -128,31 +126,43 @@ protected:  	// LLViewerObject interface and related  	//--------------------------------------------------------------------  public: -	virtual void			updateGL(); -	virtual	LLVOAvatar*		asAvatar(); -	virtual U32    	 	 	processUpdateMessage(LLMessageSystem *mesgsys, +	/*virtual*/ void			updateGL(); +	/*virtual*/ LLVOAvatar*		asAvatar(); +	virtual U32    	 	 		processUpdateMessage(LLMessageSystem *mesgsys,  													 void **user_data,  													 U32 block_num,  													 const EObjectUpdateType update_type,  													 LLDataPacker *dp); -	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 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. +	S32 						totalTextureMemForUUIDS(std::set<LLUUID>& ids); +	bool 						allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const; +	bool 						allLocalTexturesCompletelyDownloaded() const; +	bool 						allBakedTexturesCompletelyDownloaded() const; +	void 						bakedTextureOriginCounts(S32 &sb_count, S32 &host_count, +														 S32 &both_count, S32 &neither_count); +	std::string 				bakedTextureOriginInfo(); +	void 						collectLocalTextureUUIDs(std::set<LLUUID>& ids) const; +	void 						collectBakedTextureUUIDs(std::set<LLUUID>& ids) const; +	void 						collectTextureUUIDs(std::set<LLUUID>& ids); +	void						releaseOldTextures(); +	/*virtual*/ void   	 	 	updateTextures(); +	LLViewerFetchedTexture*		getBakedTextureImage(const U8 te, const LLUUID& uuid); +	/*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 @@ -173,16 +183,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 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*/ 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 void			stopMotionFromSource(const LLUUID& source_id);  	virtual void			requestStopMotion(LLMotion* motion);  	LLMotion*				findMotion(const LLUUID& id) const; @@ -190,25 +198,18 @@ 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(); @@ -223,14 +224,10 @@ 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  	LL_ALIGN_16(LLVector4a	mImpostorExtents[2]); -private: -	BOOL			mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients -  	//--------------------------------------------------------------------  	// Updates  	//-------------------------------------------------------------------- @@ -293,17 +290,21 @@ public:  	virtual BOOL	getIsCloud() const;  	BOOL			isFullyTextured() const;  	BOOL			hasGray() const;  -	S32				getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = fully textured. +	S32				getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded.  	void			updateRezzedStatusTimers();  	S32				mLastRezzedStatus; -	LLViewerStats::PhaseMap& getPhases() -	{ -		return mPhases; -	} +	 +	void 			startPhase(const std::string& phase_name); +	void 			stopPhase(const std::string& phase_name, bool err_check = true); +	void			clearPhases(); +	void 			logPendingPhases(); +	static void 	logPendingPhasesAllAvatars(); +	void 			logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);  protected: +	LLViewerStats::PhaseMap& getPhases() { return mPhases; }  	BOOL			updateIsFullyLoaded();  	BOOL			processFullyLoadedChange(bool loading);  	void			updateRuthTimer(bool loading); @@ -318,24 +319,6 @@ private:  	LLFrameTimer	mFullyLoadedTimer;  	LLFrameTimer	mRuthTimer; -public: -	class ScopedPhaseSetter -	{ -	public: -		ScopedPhaseSetter(LLVOAvatar *avatarp, std::string phase_name): -			mAvatar(avatarp), mPhaseName(phase_name) -		{ -			if (mAvatar) { mAvatar->getPhases().startPhase(mPhaseName); } -		} -		~ScopedPhaseSetter() -		{ -			if (mAvatar) { mAvatar->getPhases().stopPhase(mPhaseName); } -		} -	private: -		std::string mPhaseName; -		LLVOAvatar* mAvatar; -	}; -  private:  	LLViewerStats::PhaseMap mPhases; @@ -345,20 +328,25 @@ protected:  /**                    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; @@ -367,62 +355,8 @@ public:  	LLVector3			mCurRootToHeadOffset;  	LLVector3			mTargetRootToHeadOffset; -	LLVector3			mHeadOffset; // current head position -	LLViewerJoint		mRoot; - -	typedef std::map<std::string, LLJoint*> joint_map_t; -	joint_map_t			mJointMap; - -protected: -	static BOOL			parseSkeletonFile(const std::string& filename); -	void				buildCharacter(); -	virtual BOOL		loadAvatar(); - -	BOOL				setupBone(const LLVOAvatarChildJoint& 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 LLXMLNodePtr	sSkeletonXMLTree; // avatar skeleton file  /**                    Skeleton   **                                                                            ** @@ -445,7 +379,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 @@ -463,9 +396,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 @@ -548,10 +487,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   **                                                                            ** @@ -566,9 +505,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); @@ -579,6 +518,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); @@ -586,32 +526,20 @@ 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<LLViewerTexLayerSet*>(mBakedTextureDatas[index].mTexLayerSet);	} + -	typedef std::deque<LLMaskedMorph *> 	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<LLViewerJointMesh> mJoints[i]->mMeshParts -		morph_list_t						mMaskedMorphs; -	}; -	typedef std::vector<BakedTextureData> 	bakedtexturedata_vec_t; -	bakedtexturedata_vec_t 					mBakedTextureDatas;  	LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ;   	BOOL mLoadedCallbacksPaused; +	std::set<LLUUID>	mTextureIDs;  	//--------------------------------------------------------------------  	// 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);  	// 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 @@ -619,6 +547,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); @@ -645,13 +574,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 @@ -672,22 +599,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();  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<std::string, LLPolyMesh*> polymesh_map_t; -	polymesh_map_t 									mMeshes; -	std::vector<LLViewerJoint *> 					mMeshLOD; -  	//--------------------------------------------------------------------  	// Destroy invisible mesh  	//-------------------------------------------------------------------- @@ -705,38 +630,42 @@ protected:   **/  public: +	void 			parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg);  	void 			processAvatarAppearance(LLMessageSystem* mesgsys);  	void 			hideSkirt();  	void			startAppearanceAnimation(); +	/*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. +	BOOL				isUsingServerBakes() const; +	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; - -	//-------------------------------------------------------------------- -	// 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 @@ -746,7 +675,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   **                                                                            **   *******************************************************************************/ @@ -756,9 +684,6 @@ public:   **                    WEARABLES   **/ -public: -	virtual BOOL			isWearingWearableType(LLWearableType::EType type ) const; -	  	//--------------------------------------------------------------------  	// Attachments  	//-------------------------------------------------------------------- @@ -768,6 +693,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(); @@ -869,15 +795,6 @@ private:  	F32			mSpeed; // misc. animation repeated state  	//-------------------------------------------------------------------- -	// Collision volumes -	//-------------------------------------------------------------------- -public: -  	S32			mNumCollisionVolumes; -	LLViewerJointCollisionVolume* mCollisionVolumes; -protected: -	BOOL		allocateCollisionVolumes(U32 num); - -	//--------------------------------------------------------------------  	// Dimensions  	//--------------------------------------------------------------------  public: @@ -887,7 +804,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 @@ -907,9 +823,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 @@ -939,7 +855,7 @@ protected:  	static void		getAnimLabels(LLDynamicArray<std::string>* labels);  	static void		getAnimNames(LLDynamicArray<std::string>* names);	  private: -	std::string		mNameString;		// UTF-8 title + name + status +    bool            mNameIsSet;  	std::string  	mTitle;  	bool	  		mNameAway;  	bool	  		mNameDoNotDisturb; @@ -1013,7 +929,9 @@ 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 LLAppearanceMessageContents& contents);  	static void			dumpBakedStatus();  	const std::string 	getBakedStatusForPrintout() const;  	void				dumpAvatarTEs(const std::string& context) const; @@ -1030,6 +948,7 @@ private:  	F32					mMaxPixelArea;  	F32					mAdjustedPixelArea;  	std::string  		mDebugText; +	std::string			mBakedTextureDebugText;  	//-------------------------------------------------------------------- @@ -1043,6 +962,17 @@ protected:  	LLFrameTimer	mRuthDebugTimer; // For tracking how long it takes for av to rez  	LLFrameTimer	mDebugExistenceTimer; // Debugging for how long the avatar has been in memory. +	//-------------------------------------------------------------------- +	// COF monitoring +	//-------------------------------------------------------------------- + +public: +	// COF version of last viewer-initiated appearance update request. For non-self avs, this will remain at default. +	S32 mLastUpdateRequestCOFVersion; + +	// COF version of last appearance message received for this av. +	S32 mLastUpdateReceivedCOFVersion; +  /**                    Diagnostics   **                                                                            **   *******************************************************************************/ @@ -1054,105 +984,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<LLPolyMorphTargetInfo*,BOOL> morph_info_pair_t; -			typedef std::vector<morph_info_pair_t> 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<LLVOAvatarMeshInfo*> mesh_info_list_t; -		mesh_info_list_t mMeshInfoList; - -		typedef std::vector<LLPolySkeletalDistortionInfo*> 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<LLVOAvatarAttachmentInfo*> attachment_info_list_t; -		attachment_info_list_t mAttachmentInfoList; -	 -		LLTexGlobalColorInfo *mTexSkinColorInfo; -		LLTexGlobalColorInfo *mTexHairColorInfo; -		LLTexGlobalColorInfo *mTexEyeColorInfo; - -		typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t; -		layer_info_list_t mLayerInfoList; - -		typedef std::vector<LLDriverParamInfo*> 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<LLVOAvatarMorphInfo*> 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   **                                                                            ** @@ -1162,4 +993,9 @@ protected: // Shared with LLVOAvatarSelf  extern const F32 SELF_ADDITIONAL_PRI;  extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL; -#endif // LL_VO_AVATAR_H +std::string get_sequential_numbered_file_name(const std::string& prefix, +											  const std::string& suffix); +void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value); + +#endif // LL_VOAVATAR_H + diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index e32fd3c3c8..d54eb5f040 100644..100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -55,11 +55,14 @@  #include "llviewerobjectlist.h"  #include "llviewerstats.h"  #include "llviewerregion.h" +#include "llviewertexlayer.h" +#include "llviewerwearable.h"  #include "llappearancemgr.h"  #include "llmeshrepository.h"  #include "llvovolume.h"  #include "llsdutil.h"  #include "llstartup.h" +#include "llsdserialize.h"  #if LL_MSVC  // disable boost::lexical_cast warning @@ -72,24 +75,22 @@ LLPointer<LLVOAvatarSelf> gAgentAvatarp = NULL;  BOOL isAgentAvatarValid()  { -	return (gAgentAvatarp.notNull() && -			(gAgentAvatarp->getRegion() != NULL) && -			(!gAgentAvatarp->isDead())); +	return (gAgentAvatarp.notNull() && gAgentAvatarp->isValid());  }  void selfStartPhase(const std::string& phase_name)  {  	if (isAgentAvatarValid())  	{ -		gAgentAvatarp->getPhases().startPhase(phase_name); +		gAgentAvatarp->startPhase(phase_name);  	}  } -void selfStopPhase(const std::string& phase_name) +void selfStopPhase(const std::string& phase_name, bool err_check)  {  	if (isAgentAvatarValid())  	{ -		gAgentAvatarp->getPhases().stopPhase(phase_name); +		gAgentAvatarp->stopPhase(phase_name, err_check);  	}  } @@ -97,20 +98,11 @@ void selfClearPhases()  {  	if (isAgentAvatarValid())  	{ -		gAgentAvatarp->getPhases().clearPhases(); -		gAgentAvatarp->mLastRezzedStatus = -1; +		gAgentAvatarp->clearPhases();  	}  } -void selfStopAllPhases() -{ -	if (isAgentAvatarValid()) -	{ -		gAgentAvatarp->getPhases().stopAllPhases(); -	} -} - -using namespace LLVOAvatarDefines; +using namespace LLAvatarAppearanceDefines;  /*********************************************************************************   **                                                                             ** @@ -176,6 +168,35 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,  	lldebugs << "Marking avatar as self " << id << llendl;  } +// Called periodically for diagnostics, return true when done. +bool output_self_av_texture_diagnostics() +{ +	if (!isAgentAvatarValid()) +		return true; // done checking + +	gAgentAvatarp->outputRezDiagnostics(); + +	return false; +} + +bool update_avatar_rez_metrics() +{ +	if (!isAgentAvatarValid()) +		return true; +	 +	gAgentAvatarp->updateAvatarRezMetrics(false); +	return false; +} + +bool check_for_unsupported_baked_appearance() +{ +	if (!isAgentAvatarValid()) +		return true; + +	gAgentAvatarp->checkForUnsupportedServerBakeAppearance(); +	return false; +} +  void LLVOAvatarSelf::initInstance()  {  	BOOL status = TRUE; @@ -188,7 +209,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)  		{ @@ -196,7 +217,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; @@ -209,6 +230,10 @@ void LLVOAvatarSelf::initInstance()  		llerrs << "Unable to load user's avatar" << llendl;  		return;  	} + +	//doPeriodically(output_self_av_texture_diagnostics, 30.0); +	doPeriodically(update_avatar_rez_metrics, 5.0); +	doPeriodically(check_for_unsupported_baked_appearance, 120.0);  }  // virtual @@ -249,13 +274,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)  {  	// add special-purpose "screen" joint  	mScreenp = new LLViewerJoint("mScreen", NULL); @@ -341,7 +364,6 @@ BOOL LLVOAvatarSelf::buildMenus()  		}  		else  		{ -			BOOL attachment_found = FALSE;  			for (attachment_map_t::iterator iter = mAttachmentPoints.begin();   				 iter != mAttachmentPoints.end();  				 ++iter) @@ -369,7 +391,6 @@ BOOL LLVOAvatarSelf::buildMenus()  					gAttachPieMenu->addChild(item); -					attachment_found = TRUE;  					break;  				} @@ -382,7 +403,6 @@ BOOL LLVOAvatarSelf::buildMenus()  		}  		else  		{ -			BOOL attachment_found = FALSE;  			for (attachment_map_t::iterator iter = mAttachmentPoints.begin();   				 iter != mAttachmentPoints.end();  				 ++iter) @@ -409,7 +429,6 @@ BOOL LLVOAvatarSelf::buildMenus()  					gDetachPieMenu->addChild(item); -					attachment_found = TRUE;  					break;  				}  			} @@ -583,70 +602,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 << "<layer_set> 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)  { @@ -664,9 +619,15 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)  }  // virtual +BOOL LLVOAvatarSelf::isValid() const +{ +	return ((getRegion() != NULL) && !isDead()); +} + +// virtual  void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  { -	if (isAgentAvatarValid()) +	if (isValid())  	{  		LLVOAvatar::idleUpdate(agent, world, time);  		idleUpdateTractorBeam(); @@ -689,7 +650,7 @@ 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)  	{ @@ -717,20 +678,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); @@ -759,7 +728,7 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation()  		LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type);  		if (wearable)  		{ -			wearable->writeToAvatar(); +			wearable->writeToAvatar(this);  		}  	} @@ -802,18 +771,30 @@ U32  LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,  {  	U32 retval = LLVOAvatar::processUpdateMessage(mesgsys,user_data,block_num,update_type,dp); -	if (mInitialBakesLoaded == false && retval == 0x0) +#if 0 +	// DRANO - it's not clear this does anything useful. If we wait +	// until an appearance message has been received, we already have +	// the texture ids. If we don't wait, we don't yet know where to +	// look for baked textures, because we haven't received the +	// appearance version data from the appearance message. This looks +	// like an old optimization that's incompatible with server-side +	// texture baking. +	 +	// 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();  		// unpack the texture UUIDs to the texture slots -		retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); +		retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);  		// 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; @@ -823,6 +804,7 @@ U32  LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,  		mInitialBakesLoaded = true;  	} +#endif  	return retval;  } @@ -877,11 +859,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(); +		}  	}  } @@ -938,7 +924,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)  void LLVOAvatarSelf::idleUpdateTractorBeam()  {  	// This is only done for yourself (maybe it should be in the agent?) -	if (!needsRenderBeam() || !mIsBuilt) +	if (!needsRenderBeam() || !isBuilt())  	{  		mBeam = NULL;  	} @@ -1051,11 +1037,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. @@ -1063,26 +1044,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;  				} @@ -1246,7 +1228,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;  		} @@ -1287,7 +1269,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; @@ -1295,9 +1277,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);  } @@ -1328,11 +1310,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();  			} @@ -1366,11 +1345,11 @@ BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex  	{  		return FALSE;  	} -	*tex_pp = local_tex_obj->getImage(); +	*tex_pp = dynamic_cast<LLViewerTexture*> (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))  	{ @@ -1386,7 +1365,7 @@ LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLVOAvatarDefines::ETe  	{  		return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);  	} -	return local_tex_obj->getImage(); +	return dynamic_cast<LLViewerFetchedTexture*> (local_tex_obj->getImage());  }  const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) const @@ -1407,29 +1386,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; +			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; @@ -1445,7 +1425,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. @@ -1454,17 +1434,19 @@ 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++)  				{ -					if (getLocalDiscardLevel(*local_tex_iter, wearable_index) > (S32)(desired_tex_discard_level)) +					S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index); +					if ((local_discard_level > (S32)(desired_tex_discard_level)) || +						(local_discard_level < 0 ))  					{  						return FALSE;  					} @@ -1477,6 +1459,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons  	return FALSE;  } +  BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const  {  	const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");  @@ -1484,17 +1467,19 @@ 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++)  			{ -				if (getLocalDiscardLevel(*local_tex_iter, wearable_index) > (S32)(desired_tex_discard_level)) +				S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index); +				if ((local_discard_level > (S32)(desired_tex_discard_level)) || +					(local_discard_level < 0 ))  				{  					return FALSE;  				} @@ -1504,22 +1489,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)  		{ @@ -1546,7 +1531,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))  	{ @@ -1559,7 +1544,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))  	{ @@ -1582,13 +1567,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();  	}  } @@ -1602,8 +1588,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;  		} @@ -1613,22 +1599,23 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const  void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )  { -	if( !layerset || !layerset->getUpdatesEnabled() ) +	LLViewerTexLayerSet *layer_set = dynamic_cast<LLViewerTexLayerSet*>(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();  	}  } @@ -1637,7 +1624,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();  } @@ -1655,17 +1643,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;  } @@ -1676,9 +1666,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);  		}  	}  } @@ -1687,10 +1678,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();  		}  	}  } @@ -1703,11 +1695,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<LLViewerFetchedTexture*>( 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  		{ @@ -1732,7 +1725,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<LLViewerFetchedTexture*>( local_tex_obj->getImage() );  				if (image_gl)  				{  					S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); @@ -1767,8 +1760,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; @@ -1781,10 +1774,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));  		}  	} @@ -1804,16 +1797,13 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te  					local_tex_obj->setDiscard(tex_discard);  					if (isSelf())  					{ -						if (gAgentAvatarp->isUsingBakedTextures()) -					{  						requestLayerSetUpdate(type); -					} -						else -					{ -						LLVisualParamHint::requestHintUpdates(); +						if (isEditingAppearance()) +						{ +							LLVisualParamHint::requestHintUpdates(); +						}  					}  				} -				}  				else  				{					  					tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL); @@ -1826,8 +1816,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); @@ -1846,16 +1837,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); @@ -1878,7 +1869,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const  			}  			else  			{ -				const LLViewerFetchedTexture* image = local_tex_obj->getImage(); +				const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );  				llinfos << "LocTex " << name << ": "  						<< "Discard " << image->getDiscardLevel() << ", " @@ -1955,35 +1946,63 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()  BOOL LLVOAvatarSelf::getIsCloud() const  { +	// Let people know why they're clouded without spamming them into oblivion. +	bool do_warn = false; +	static LLTimer time_since_notice; +	F32 update_freq = 30.0; +	if (time_since_notice.getElapsedTimeF32() > update_freq) +	{ +		time_since_notice.reset(); +		do_warn = true; +	} +	  	// do we have our body parts? -	if (gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE) == 0 || -		gAgentWearables.getWearableCount(LLWearableType::WT_HAIR) == 0 || -		gAgentWearables.getWearableCount(LLWearableType::WT_EYES) == 0 || -		gAgentWearables.getWearableCount(LLWearableType::WT_SKIN) == 0)	 +	S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE); +	S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR); +	S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES); +	S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN); +	if (!shape_count || !hair_count || !eye_count || !skin_count)  	{ -		lldebugs << "No body parts" << llendl; +		if (do_warn) +		{ +			llinfos << "Self is clouded due to missing one or more required body parts: " +					<< (shape_count ? "" : "SHAPE ") +					<< (hair_count ? "" : "HAIR ") +					<< (eye_count ? "" : "EYES ") +					<< (skin_count ? "" : "SKIN ") +					<< llendl; +		}  		return TRUE;  	}  	if (!isTextureDefined(TEX_HAIR, 0))  	{ -		lldebugs << "No hair texture" << llendl; +		if (do_warn) +		{ +			llinfos << "Self is clouded because of no hair texture" << llendl; +		}  		return TRUE;  	}  	if (!mPreviousFullyLoaded)  	{ -		if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet) && +		if (!isLocalTextureDataAvailable(getLayerSet(BAKED_LOWER)) &&  			(!isTextureDefined(TEX_LOWER_BAKED, 0)))  		{ -			lldebugs << "Lower textures not baked" << llendl; +			if (do_warn) +			{ +				llinfos << "Self is clouded because 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; +			if (do_warn) +			{ +				llinfos << "Self is clouded because upper textures not baked" << llendl; +			}  			return TRUE;  		} @@ -2000,7 +2019,11 @@ BOOL LLVOAvatarSelf::getIsCloud() const  			const LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 );  			if (!baked_img || !baked_img->hasGLTexture())  			{ -				lldebugs << "Texture at index " << i << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << llendl; +				if (do_warn) +				{ +					llinfos << "Self is clouded because texture at index " << i +							<< " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << llendl; +				}  				return TRUE;  			}  		} @@ -2051,7 +2074,85 @@ 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::verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const +{ +	std::ostringstream outbuf; +	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) +		{ +			outbuf << "baked_index: " << baked_index << "\n"; +			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second; +			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); +				 local_tex_iter != baked_dict->mLocalTextures.end(); +				 ++local_tex_iter) +			{ +				const ETextureIndex tex_index = *local_tex_iter; +				const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(tex_index)->mName; +				outbuf << "  tex_index " << (S32) tex_index << " name " << tex_name << "\n"; +				const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index); +				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); +				if (wearable_count > 0) +				{ +					for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) +					{ +						outbuf << "    " << LLWearableType::getTypeName(wearable_type) << " " << wearable_index << ":"; +						const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(tex_index, wearable_index); +						if (local_tex_obj) +						{ +							LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() ); +							if (tex_index >= 0 +								&& local_tex_obj->getID() != IMG_DEFAULT_AVATAR +								&& !image->isMissingAsset()) +							{ +								outbuf << " id: " << image->getID() +									   << " refs: " << image->getNumRefs() +									   << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index) +									   << " discard: " << image->getDiscardLevel() +									   << " desired: " << image->getDesiredDiscardLevel() +									   << " decode: " << image->getDecodePriority() +									   << " addl: " << image->getAdditionalDecodePriority() +									   << " ts: " << image->getTextureState() +									   << " bl: " << image->getBoostLevel() +									   << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there. +									   << " cl: " << (image->isFullyLoaded() && image->getDiscardLevel()==0) // "completely loaded" +									   << " mvs: " << image->getMaxVirtualSize() +									   << " mvsc: " << image->getMaxVirtualSizeResetCounter() +									   << " mem: " << image->getTextureMemory(); +							} +						} +						outbuf << "\n"; +					} +				} +			} +			break; +		} +	} +	return outbuf.str(); +} + +void LLVOAvatarSelf::dumpAllTextures() const +{ +	std::string vd_text = "Local textures per baked index and wearable:\n"; +	for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin(); +		 baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end(); +		 ++baked_iter) +	{ +		const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first; +		const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index); +		if (!layerset) continue; +		const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite(); +		if (!layerset_buffer) continue; +		vd_text += verboseDebugDumpLocalTextureDataInfo(layerset); +	} +	LL_DEBUGS("Avatar") << vd_text << llendl; +} + +const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const  {  	std::string text=""; @@ -2059,21 +2160,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)  				{ @@ -2100,14 +2201,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++)  			{ @@ -2119,20 +2220,14 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const  	return text;  } + +#if 0  // Dump avatar metrics data.  LLSD LLVOAvatarSelf::metricsData()  {  	// runway - add region info  	LLSD result;  	result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus()); -	std::vector<S32> rez_counts; -	LLVOAvatar::getNearbyRezzedStats(rez_counts); -	result["nearby"] = LLSD::emptyMap(); -	for (S32 i=0; i<rez_counts.size(); ++i) -	{ -		std::string rez_status_name = LLVOAvatar::rezStatusToString(i); -		result["nearby"][rez_status_name] = rez_counts[i]; -	}  	result["timers"]["debug_existence"] = mDebugExistenceTimer.getElapsedTimeF32();  	result["timers"]["ruth_debug"] = mRuthDebugTimer.getElapsedTimeF32();  	result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32(); @@ -2142,6 +2237,7 @@ LLSD LLVOAvatarSelf::metricsData()  	return result;  } +#endif  class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder  { @@ -2159,6 +2255,7 @@ public:  						   const std::string& reason,  						   const LLSD& content)  	{ +		gPendingMetricsUploads--; // if we add retry, this should be moved to the isGoodStatus case.  		if (isGoodStatus(status))  		{  			LL_DEBUGS("Avatar") << "OK" << LL_ENDL; @@ -2167,16 +2264,11 @@ public:  		else  		{  			LL_WARNS("Avatar") << "Failed " << status << " reason " << reason << LL_ENDL; -			error(status,reason); +			errorWithContent(status,reason,content);  		}  	}  	// virtual -	void error(U32 status_num, const std::string & reason) -	{ -	} - -	// virtual  	void result(const LLSD & content)  	{  		if (mLiveSequence == mExpectedSequence) @@ -2191,19 +2283,121 @@ private:  	volatile bool & mReportingStarted;  }; -void LLVOAvatarSelf::sendAppearanceChangeMetrics() +bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send) +{ +	const F32 AV_METRICS_INTERVAL_QA = 30.0; +	F32 send_period = 300.0; +	if (gSavedSettings.getBOOL("QAModeMetrics")) +	{ +		send_period = AV_METRICS_INTERVAL_QA; +	} + +	if (force_send || mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period) +	{ +		// Stats for completed phases have been getting logged as they +		// complete.  This will give us stats for any timers that +		// haven't finished as of the metric's being sent. +		 +		if (force_send) +		{ +			LLVOAvatar::logPendingPhasesAllAvatars(); +		} +		sendViewerAppearanceChangeMetrics(); +	} + +	return false; +} + +void LLVOAvatarSelf::addMetricsTimerRecord(const LLSD& record) +{ +	mPendingTimerRecords.push_back(record); +} + +bool operator<(const LLSD& a, const LLSD& b) +{ +	std::ostringstream aout, bout; +	aout << LLSDNotationStreamer(a); +	bout << LLSDNotationStreamer(b); +	std::string astring = aout.str(); +	std::string bstring = bout.str(); + +	return astring < bstring; + +} + +// Given a vector of LLSD records, return an LLSD array of bucketed stats for val_field. +LLSD summarize_by_buckets(std::vector<LLSD> in_records, +						  std::vector<std::string> by_fields, +						  std::string val_field) +{ +	LLSD result = LLSD::emptyArray(); +	std::map<LLSD,LLViewerStats::StatsAccumulator> accum; +	for (std::vector<LLSD>::iterator in_record_iter = in_records.begin(); +		 in_record_iter != in_records.end(); ++in_record_iter) +	{ +		LLSD& record = *in_record_iter; +		LLSD key; +		for (std::vector<std::string>::iterator field_iter = by_fields.begin(); +			 field_iter != by_fields.end(); ++field_iter) +		{ +			const std::string& field = *field_iter; +			key[field] = record[field]; +		} +		LLViewerStats::StatsAccumulator& stats = accum[key]; +		F32 value = record[val_field].asReal(); +		stats.push(value); +	} +	for (std::map<LLSD,LLViewerStats::StatsAccumulator>::iterator accum_it = accum.begin(); +		 accum_it != accum.end(); ++accum_it) +	{ +		LLSD out_record = accum_it->first; +		out_record["stats"] = accum_it->second.getData(); +		result.append(out_record); +	} +	return result; +} + +void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()  {  	// gAgentAvatarp->stopAllPhases();  	static volatile bool reporting_started(false);  	static volatile S32 report_sequence(0); -	LLSD msg = metricsData(); +	LLSD msg; // = metricsData();  	msg["message"] = "ViewerAppearanceChangeMetrics";  	msg["session_id"] = gAgentSessionID;  	msg["agent_id"] = gAgentID;  	msg["sequence"] = report_sequence;  	msg["initial"] = !reporting_started;  	msg["break"] = false; +	msg["duration"] = mTimeSinceLastRezMessage.getElapsedTimeF32(); + +	// Status of our own rezzing. +	msg["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus()); + +	// Status of all nearby avs including ourself. +	msg["nearby"] = LLSD::emptyArray(); +	std::vector<S32> rez_counts; +	LLVOAvatar::getNearbyRezzedStats(rez_counts); +	for (S32 rez_stat=0; rez_stat < rez_counts.size(); ++rez_stat) +	{ +		std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat); +		msg["nearby"][rez_status_name] = rez_counts[rez_stat]; +	} + +	//	std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake"); +	std::vector<std::string> by_fields; +	by_fields.push_back("timer_name"); +	by_fields.push_back("completed"); +	by_fields.push_back("grid_x"); +	by_fields.push_back("grid_y"); +	by_fields.push_back("is_using_server_bakes"); +	by_fields.push_back("is_self"); +	by_fields.push_back("central_bake_version"); +	LLSD summary = summarize_by_buckets(mPendingTimerRecords, by_fields, std::string("elapsed")); +	msg["timers"] = summary; + +	mPendingTimerRecords.clear();  	// Update sequence number  	if (S32_MAX == ++report_sequence) @@ -2218,20 +2412,79 @@ void LLVOAvatarSelf::sendAppearanceChangeMetrics()  	}  	if (!caps_url.empty())  	{ +		gPendingMetricsUploads++;  		LLCurlRequest::headers_t headers;  		LLHTTPClient::post(caps_url,  						   msg,  						   new ViewerAppearanceChangeMetricsResponder(report_sequence,  																	  report_sequence,  																	  reporting_started)); +		mTimeSinceLastRezMessage.reset();  	}  } +class CheckAgentAppearanceServiceResponder: public LLHTTPClient::Responder +{ +public: +	CheckAgentAppearanceServiceResponder() +	{ +	} +	 +	virtual ~CheckAgentAppearanceServiceResponder() +	{ +	} + +	/* virtual */ void result(const LLSD& content) +	{ +		LL_DEBUGS("Avatar") << "status OK" << llendl; +	} + +	// Error +	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content) +	{ +		if (isAgentAvatarValid()) +		{ +			LL_DEBUGS("Avatar") << "failed, will rebake [status:" +					<< status << "]: " << content << llendl; +			forceAppearanceUpdate(); +		} +	}	 + +	static void forceAppearanceUpdate() +	{ +		// Trying to rebake immediately after crossing region boundary +		// seems to be failure prone; adding a delay factor. Yes, this +		// fix is ad-hoc and not guaranteed to work in all cases. +		doAfterInterval(boost::bind(&LLVOAvatarSelf::forceBakeAllTextures, +									gAgentAvatarp.get(), true), 5.0); +	} +}; + +void LLVOAvatarSelf::checkForUnsupportedServerBakeAppearance() +{ +	// Need to check only if we have a server baked appearance and are +	// in a non-baking region. +	if (!gAgentAvatarp->isUsingServerBakes()) +		return; +	if (!gAgent.getRegion() || gAgent.getRegion()->getCentralBakeVersion()!=0) +		return; + +	// if baked image service is unknown, need to refresh. +	if (LLAppearanceMgr::instance().getAppearanceServiceURL().empty()) +	{ +		CheckAgentAppearanceServiceResponder::forceAppearanceUpdate(); +	} +	// query baked image service to check status. +	std::string image_url = gAgentAvatarp->getImageURL(TEX_HEAD_BAKED, +													   getTE(TEX_HEAD_BAKED)->getID()); +	LLHTTPClient::head(image_url, new CheckAgentAppearanceServiceResponder); +} +  const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const  {  	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; @@ -2243,7 +2496,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; @@ -2262,19 +2515,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); @@ -2316,26 +2569,34 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const  }  void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTexture* imagep, -										   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index ) +										   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)  {  	if (!isIndexLocalTexture(type)) return; -	if (!covered_by_baked) +	// Sunshine - ignoring covered_by_baked will force local textures +	// to always load.  Fix for SH-4001 and many related issues.  Do +	// not restore this without some more targetted fix for the local +	// textures failing to load issue. +	//if (!covered_by_baked)  	{ -		if (getLocalTextureID(type, index) != IMG_DEFAULT_AVATAR && imagep->getDiscardLevel() != 0) +		if (imagep->getID() != IMG_DEFAULT_AVATAR)  		{ -			F32 desired_pixels; -			desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); -			imagep->setBoostLevel(getAvatarBoostLevel()); - -			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) +			imagep->setNoDelete(); +			if (imagep->getDiscardLevel() != 0)  			{ -				mHasGrey = TRUE; // for statistics gathering +				F32 desired_pixels; +				desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); +				 +				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) +				{ +					mHasGrey = TRUE; // for statistics gathering +				}  			}  		}  		else @@ -2346,10 +2607,10 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe  	}  } -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); @@ -2362,7 +2623,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++)  	{ @@ -2376,9 +2637,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);  } @@ -2391,7 +2652,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )  {  	// Baked textures live on other sims.  	LLHost target_host = getObjectHost();	 -	setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, target_host ) ); +	setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, FTT_HOST_BAKE, target_host ) );  	updateMeshTextures();  	dirtyMesh(); @@ -2400,7 +2661,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. @@ -2465,7 +2726,7 @@ void LLVOAvatarSelf::outputRezDiagnostics() const  	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 < LLVOAvatarDefines::TEX_NUM_INDICES; ++i) +	for (U32 i = 0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)  	{  		std::stringstream out;  		out << "\t\t (" << i << ") "; @@ -2493,27 +2754,29 @@ void LLVOAvatarSelf::outputRezDiagnostics() const  		}  	}  	LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << llendl; -	for (U32 i = 0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i) +	for (U32 i = 0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)  	{  		LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << 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;  		LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl;  	} + +	dumpAllTextures();  }  void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const  { -	LL_INFOS("Avatar") +	LL_DEBUGS("Avatar")  		<< avString()  		<< llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32())  		<< LL_ENDL; @@ -2538,7 +2801,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)  			{ @@ -2552,7 +2816,7 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid  				}  				mInitialBakeIDs[i] = LLUUID::null;  			} -			mBakedTextureDatas[i].mTexLayerSet->cancelUpload(); +			layerset->cancelUpload();  		}  	}  } @@ -2571,17 +2835,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; @@ -2605,15 +2869,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)  { @@ -2622,7 +2877,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) @@ -2654,7 +2909,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; @@ -2664,22 +2919,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: @@ -2687,26 +2942,60 @@ 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() +void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)  { -	// 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 +	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(); // mark all bakes as dirty, request updates +		gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh. +		gAgentAvatarp->updateTextures(); // call updateTextureStats +	}  }  // static -void LLVOAvatarSelf::onCustomizeEnd() +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 (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) +		{ +			gAgentCamera.changeCameraToDefault(); +			gAgentCamera.resetView(); +		} +	 +		LLAppearanceMgr::instance().updateAppearanceFromCOF();	  	}  } @@ -2719,12 +3008,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); @@ -2736,12 +3025,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); @@ -2797,3 +3086,36 @@ void LLVOAvatarSelf::dumpScratchTextureByteCount()  {  	llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl;  } + +void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile) +{ +	apr_file_t* file = outfile.getFileHandle(); +	if (!file) +	{ +		return; +	} + +	 +	apr_file_printf( file, "\n<wearable_info>\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    <wearable type=\"%s\" name=\"%s\"/>\n", +							 type_name.c_str(), wearable->getName().c_str() ); +			LLWearable::visual_param_vec_t v_params; +			wearable->getVisualParams(v_params); +			for (LLWearable::visual_param_vec_t::iterator it = v_params.begin(); +				 it != v_params.end(); ++it) +			{ +				LLVisualParam *param = *it; +				dump_visual_param(file, param, param->getWeight()); +			} +		} +	} +	apr_file_printf( file, "\n</wearable_info>\n" ); +} diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 7bd0c0bf93..3b7b6bac64 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -67,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   **                                                                            ** @@ -97,7 +96,7 @@ public:  				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(); @@ -111,7 +110,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 ); @@ -131,6 +130,7 @@ private:  public:  	/*virtual*/ bool 	isSelf() const { return true; } +	/*virtual*/ BOOL	isValid() const;  	//--------------------------------------------------------------------  	// Updates @@ -177,8 +177,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 @@ -195,32 +195,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); +	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); @@ -233,13 +233,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(); @@ -248,10 +247,11 @@ 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 @@ -265,8 +265,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;  	//-------------------------------------------------------------------- @@ -300,10 +300,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 @@ -340,8 +339,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 @@ -365,6 +364,7 @@ public:  	static void		dumpTotalLocalTextureByteCount();  	void			dumpLocalTextures() const;  	static void		dumpScratchTextureByteCount(); +	void			dumpWearableInfo(LLAPRFile& outfile);  	//--------------------------------------------------------------------  	// Avatar Rez Metrics @@ -372,34 +372,43 @@ 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;  	}; + +	LLTimer					mTimeSinceLastRezMessage; +	bool					updateAvatarRezMetrics(bool force_send); + +	std::vector<LLSD>		mPendingTimerRecords; +	void 					addMetricsTimerRecord(const LLSD& record); +	  	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		verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer +	void					dumpAllTextures() const; +	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 -	LLSD					metricsData(); -	void					sendAppearanceChangeMetrics(); // send data associated with completing a change. +	void					sendViewerAppearanceChangeMetrics(); // send data associated with completing a change. +	void 					checkForUnsupportedServerBakeAppearance();  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 @@ -413,8 +422,7 @@ extern LLPointer<LLVOAvatarSelf> gAgentAvatarp;  BOOL isAgentAvatarValid();  void selfStartPhase(const std::string& phase_name); -void selfStopPhase(const std::string& phase_name); -void selfStopAllPhases(); +void selfStopPhase(const std::string& phase_name, bool err_check = true);  void selfClearPhases();  #endif // LL_VO_AVATARSELF_H diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 4dca87652d..6a25b765cf 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -102,7 +102,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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));  } diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index ceff75a0cc..ac2a34ba1e 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -56,7 +56,8 @@ class LLVoiceCallCapResponder : public LLHTTPClient::Responder  public:  	LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {}; -	virtual void error(U32 status, const std::string& reason);	// called with bad status codes +	// called with bad status codes +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  	virtual void result(const LLSD& content);  private: @@ -64,11 +65,10 @@ private:  }; -void LLVoiceCallCapResponder::error(U32 status, const std::string& reason) +void LLVoiceCallCapResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	LL_WARNS("Voice") << "LLVoiceCallCapResponder::error(" -		<< status << ": " << reason << ")" -		<< LL_ENDL; +	LL_WARNS("Voice") << "LLVoiceCallCapResponder error [status:" +		<< status << "]: " << content << LL_ENDL;  	LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);  	if ( channelp )  	{ diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp index b497f80560..9281334d81 100644 --- a/indra/newview/llvoicevisualizer.cpp +++ b/indra/newview/llvoicevisualizer.cpp @@ -125,7 +125,7 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )  	for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)  	{  		mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime; -		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI); +		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FTT_LOCAL_FILE, FALSE, LLGLTexture::BOOST_UI);  		mSoundSymbol.mWaveActive			[i] = false;  		mSoundSymbol.mWaveOpacity			[i] = 1.0f;  		mSoundSymbol.mWaveExpansion			[i] = 1.0f; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index f3342b7ff1..9b5d981aa5 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -130,17 +130,18 @@ public:  		mRetries = retries;  	} -	virtual void error(U32 status, const std::string& reason) +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ +		LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, " +			<<  ( (mRetries > 0) ? "retrying" : "too many retries (giving up)" ) +			<< status << "]: " << content << LL_ENDL; +  		if ( mRetries > 0 )  		{ -			LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, retrying.  status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL; -			LLVivoxVoiceClient::getInstance()->requestVoiceAccountProvision( -				mRetries - 1); +			LLVivoxVoiceClient::getInstance()->requestVoiceAccountProvision(mRetries - 1);  		}  		else  		{ -			LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, too many retries (giving up).  status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL;  			LLVivoxVoiceClient::getInstance()->giveUp();  		}  	} @@ -199,18 +200,18 @@ class LLVivoxVoiceClientCapResponder : public LLHTTPClient::Responder  public:  	LLVivoxVoiceClientCapResponder(LLVivoxVoiceClient::state requesting_state) : mRequestingState(requesting_state) {}; -	virtual void error(U32 status, const std::string& reason);	// called with bad status codes +	// called with bad status codes +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  	virtual void result(const LLSD& content);  private:  	LLVivoxVoiceClient::state mRequestingState;  // state   }; -void LLVivoxVoiceClientCapResponder::error(U32 status, const std::string& reason) +void LLVivoxVoiceClientCapResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	LL_WARNS("Voice") << "LLVivoxVoiceClientCapResponder::error(" -		<< status << ": " << reason << ")" -		<< LL_ENDL; +	LL_WARNS("Voice") << "LLVivoxVoiceClientCapResponder error [status:" +		<< status << "]: " << content << LL_ENDL;  	LLVivoxVoiceClient::getInstance()->sessionTerminate();  } @@ -1258,7 +1259,7 @@ void LLVivoxVoiceClient::stateMachine()  		//MARK: stateCreatingSessionGroup  		case stateCreatingSessionGroup: -			if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized) +			if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))  			{  				// *TODO: Question: is this the right way out of this state  				setState(stateSessionTerminated); @@ -1274,7 +1275,7 @@ void LLVivoxVoiceClient::stateMachine()  		//MARK: stateRetrievingParcelVoiceInfo  		case stateRetrievingParcelVoiceInfo:   			// wait until parcel voice info is received. -			if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized) +			if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))  			{  				// if a terminate request has been received,  				// bail and go to the stateSessionTerminated @@ -1294,7 +1295,7 @@ void LLVivoxVoiceClient::stateMachine()  			// Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync.  			sendFriendsListUpdates(); -			if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized) +			if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))  			{  				// TODO: Question: Is this the right way out of this state?  				setState(stateSessionTerminated); @@ -1442,7 +1443,7 @@ void LLVivoxVoiceClient::stateMachine()  		//MARK: stateRunning  		case stateRunning:				// steady state  			// Disabling voice or disconnect requested. -			if(!mVoiceEnabled && mIsInitialized || mSessionTerminateRequested) +			if((!mVoiceEnabled && mIsInitialized) || mSessionTerminateRequested)  			{  				leaveAudioSession();  			} @@ -2249,7 +2250,8 @@ void LLVivoxVoiceClient::giveUp()  static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel)  { -	F32 nat[3], nup[3], nl[3], nvel[3]; // the new at, up, left vectors and the  new position and velocity +	F32 nat[3], nup[3], nl[3]; // the new at, up, left vectors and the  new position and velocity +//	F32 nvel[3];   	F64 npos[3];  	// The original XML command was sent like this: @@ -2299,9 +2301,9 @@ static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVe  	npos[1] = pos.mdV[VZ];  	npos[2] = pos.mdV[VY]; -	nvel[0] = vel.mV[VX]; -	nvel[1] = vel.mV[VZ]; -	nvel[2] = vel.mV[VY]; +//	nvel[0] = vel.mV[VX]; +//	nvel[1] = vel.mV[VZ]; +//	nvel[2] = vel.mV[VY];  	for(int i=0;i<3;++i) {  		at.mV[i] = nat[i]; @@ -2671,33 +2673,19 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id)  {  	buddyListEntry *buddy = findBuddy(id); -	// Make sure we don't add a name before it's been looked up. +	// Make sure we don't add a name before it's been looked up in the avatar name cache  	LLAvatarName av_name; -	if(LLAvatarNameCache::get(id, &av_name)) +	if (LLAvatarNameCache::get(id, &av_name))  	{ -		// *NOTE: For now, we feed legacy names to Vivox because I don't know -		// if their service can support a mix of new and old clients with -		// different sorts of names. +		// *NOTE: We feed legacy names to Vivox because we don't know if their service +		// can support a mix of new and old clients with different sorts of names.  		std::string name = av_name.getAccountName(); - -		const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id); -		bool canSeeMeOnline = false; -		if(relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)) -			canSeeMeOnline = true; -		 -		// When we get here, mNeedsSend is true and mInSLFriends is false.  Change them as necessary. -		if(buddy) +		if (buddy)  		{ -			// This buddy is already in both lists. - -			if(name != buddy->mDisplayName) -			{ -				// The buddy is in the list with the wrong name.  Update it with the correct name. -				LL_WARNS("Voice") << "Buddy " << id << " has wrong name (\"" << buddy->mDisplayName << "\" should be \"" << name << "\"), updating."<< LL_ENDL; -				buddy->mDisplayName = name; -				buddy->mNeedsNameUpdate = true;		// This will cause the buddy to be resent. -			} +			// This buddy is already in both lists (vivox buddies and avatar cache). +            // Trust the avatar cache more for the display name (vivox display name are notoriously wrong) +            buddy->mDisplayName = name;  		}  		else  		{ @@ -2706,20 +2694,19 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id)  			buddy->mUUID = id;  		} -		// In all the above cases, the buddy is in the SL friends list (which is how we got here). -		buddy->mInSLFriends = true; -		buddy->mCanSeeMeOnline = canSeeMeOnline; +		const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id); +		buddy->mCanSeeMeOnline = (relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)); +		// In all the above cases, the buddy is in the SL friends list and tha name has been resolved (which is how we got here).  		buddy->mNameResolved = true; -		 +		buddy->mInSLFriends = true;  	}  	else  	{ -		// This name hasn't been looked up yet.  Don't do anything with this buddy list entry until it has. -		if(buddy) +		// This name hasn't been looked up yet in the avatar cache. Don't do anything with this buddy list entry until it has. +		if (buddy)  		{  			buddy->mNameResolved = false;  		} -		  		// Initiate a lookup.  		// The "lookup completed" callback will ensure that the friends list is rechecked after it completes.  		lookupName(id); @@ -2827,13 +2814,12 @@ void LLVivoxVoiceClient::sendFriendsListUpdates()  			{  				std::ostringstream stream; -				if(buddy->mInSLFriends && (!buddy->mInVivoxBuddies || buddy->mNeedsNameUpdate)) +				if(buddy->mInSLFriends && !buddy->mInVivoxBuddies)  				{					  					if(mNumberOfAliases > 0)  					{  						// Add (or update) this entry in the vivox buddy list  						buddy->mInVivoxBuddies = true; -						buddy->mNeedsNameUpdate = false;  						LL_DEBUGS("Voice") << "add/update " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL;  						stream   							<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddySet.1\">" @@ -3954,7 +3940,6 @@ void LLVivoxVoiceClient::messageEvent(  			bool is_do_not_disturb = gAgent.isDoNotDisturb();  			bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat);  			bool is_linden = LLMuteList::getInstance()->isLinden(session->mName); -			bool quiet_chat = false;  			LLChat chat;  			chat.mMuted = is_muted && !is_linden; @@ -3967,7 +3952,6 @@ void LLVivoxVoiceClient::messageEvent(  				if(is_do_not_disturb && !is_linden)  				{ -					quiet_chat = true;  					// TODO: Question: Return do not disturb mode response here?  Or maybe when session is started instead?  				} @@ -5859,7 +5843,6 @@ LLVivoxVoiceClient::buddyListEntry::buddyListEntry(const std::string &uri) :  	mNameResolved = false;  	mInVivoxBuddies = false;  	mInSLFriends = false; -	mNeedsNameUpdate = false;  }  void LLVivoxVoiceClient::processBuddyListEntry(const std::string &uri, const std::string &displayName) @@ -5884,25 +5867,21 @@ LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::stri  	buddyListEntry *result = NULL;  	buddyListMap::iterator iter = mBuddyListMap.find(uri); -	if(iter != mBuddyListMap.end()) +	if (iter != mBuddyListMap.end())  	{  		// Found a matching buddy already in the map.  		LL_DEBUGS("Voice") << "adding existing buddy " << uri << LL_ENDL;  		result = iter->second;  	} -	if(!result) +	if (!result)  	{  		// participant isn't already in one list or the other.  		LL_DEBUGS("Voice") << "adding new buddy " << uri << LL_ENDL;  		result = new buddyListEntry(uri);  		result->mDisplayName = displayName; -		if(IDFromName(uri, result->mUUID))  -		{ -			// Extracted UUID from name successfully. -		} -		else +		if (!IDFromName(uri, result->mUUID))  		{  			LL_DEBUGS("Voice") << "Couldn't find ID for buddy " << uri << " (\"" << displayName << "\")" << LL_ENDL;  		} @@ -7272,7 +7251,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)  void LLVivoxProtocolParser::EndTag(const char *tag)  {  	const std::string& string = textBuffer; -	 +  	responseDepth--;  	if (ignoringTags) @@ -7371,6 +7350,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag)  		}  		else if (!stricmp("Buddy", tag))  		{ +            // NOTE : Vivox does *not* give reliable display name for Buddy tags +            // We don't take those very seriously as a result...  			LLVivoxVoiceClient::getInstance()->processBuddyListEntry(uriString, displayNameString);  		}  		else if (!stricmp("BlockRule", tag)) diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 574027de42..a6f40eb3e9 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -584,7 +584,6 @@ protected:  		bool mNameResolved;  		bool mInSLFriends;  		bool mInVivoxBuddies; -		bool mNeedsNameUpdate;  	};  	typedef std::map<std::string, buddyListEntry*> buddyListMap; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 31358df85f..36793017ed 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -298,7 +298,7 @@ void LLSkyTex::create(const F32 brightness)  void LLSkyTex::createGLImage(S32 which)  {	 -	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLViewerTexture::LOCAL); +	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);  	mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);  } @@ -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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);  	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); -	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI); +	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, 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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);  	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); -	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI); +	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);  	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);  	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);  	mBloomTexturep->setNoDelete() ; diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index cb905d02da..de15f0ef43 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -467,7 +467,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,  	S32 vertex_count = 0;  	S32 i, x, y; -	S32 num_vertices, num_indices; +	S32 num_vertices;  	U32 render_stride = mLastStride;  	S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); @@ -485,7 +485,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,  	if (north_stride == render_stride)  	{  		num_vertices = 2 * length + 1; -		num_indices = length * 6 - 3;  		facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f; @@ -536,7 +535,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,  	{  		// North stride is longer (has less vertices)  		num_vertices = length + length/2 + 1; -		num_indices = half_length*9 - 3;  		facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f; @@ -595,7 +593,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,  		length = patch_size / north_stride;  		half_length = length / 2;  		num_vertices = length + half_length + 1; -		num_indices = 9*half_length - 3;  		facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f; @@ -666,7 +663,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,  {  	S32 i, x, y; -	S32 num_vertices, num_indices; +	S32 num_vertices;  	U32 render_stride = mLastStride;  	S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); @@ -679,7 +676,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,  	if (east_stride == render_stride)  	{  		num_vertices = 2 * length + 1; -		num_indices = length * 6 - 3;  		facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f; @@ -728,7 +724,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,  	{  		// East stride is longer (has less vertices)  		num_vertices = length + half_length + 1; -		num_indices = half_length*9 - 3;  		facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f; @@ -783,7 +778,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,  		length = patch_size / east_stride;  		half_length = length / 2;  		num_vertices = length + length/2 + 1; -		num_indices = 9*(length/2) - 3;  		facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 6687ce432f..145a0380d6 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -316,7 +316,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, FTT_DEFAULT, 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; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c0f80cf855..cac6d4939b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -370,7 +370,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,  		// Unpack texture entry data  		// -		S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); +		S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);  		if (result & teDirtyBits)  		{  			updateTEData(); @@ -747,7 +747,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);  		} @@ -803,7 +803,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()) @@ -1006,7 +1006,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo  	if (is404)  	{ -		setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", TRUE, LLViewerTexture::BOOST_UI)); +		setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI));  		//render prim proxy when mesh loading attempts give up  		volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE); @@ -1090,7 +1090,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, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);  		}  	}  	else @@ -2749,7 +2749,7 @@ void LLVOVolume::updateSpotLightPriority()  	if (mLightTexture.notNull())  	{  		mLightTexture->addTextureStats(mSpotLightPriority); -		mLightTexture->setBoostLevel(LLViewerTexture::BOOST_CLOUDS); +		mLightTexture->setBoostLevel(LLGLTexture::BOOST_CLOUDS);  	}  } diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 7f17fd3e56..4e26587184 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -724,8 +724,8 @@ void LLVOWLSky::updateStarColors()  	const F32 var = 0.15f;  	const F32 min = 0.5f; //0.75f; -	const F32 sunclose_max = 0.6f; -	const F32 sunclose_range = 1 - sunclose_max; +	//const F32 sunclose_max = 0.6f; +	//const F32 sunclose_range = 1 - sunclose_max;  	//F32 below_horizon = - llmin(0.0f, gSky.mVOSkyp->getToSunLast().mV[2]);  	//F32 brightness_factor = llmin(1.0f, below_horizon * 20); @@ -739,14 +739,14 @@ void LLVOWLSky::updateStarColors()  		U32 x;  		for (x = 0; x < getStarsNumVerts(); ++x)  		{ -			F32 sundir_factor = 1; +			//F32 sundir_factor = 1;  			LLVector3 tostar = *v_p;  			tostar.normVec(); -			const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast(); -			if (how_close_to_sun > sunclose_max) -			{ -				sundir_factor = (1 - how_close_to_sun) / sunclose_range; -			} +			//const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast(); +			//if (how_close_to_sun > sunclose_max) +			//{ +			//	sundir_factor = (1 - how_close_to_sun) / sunclose_range; +			//}  			intensity = *(v_i);  			F32 alpha = v_c->mV[VALPHA] + (ll_frand() - 0.5f) * var * intensity;  			if (alpha < min * intensity) diff --git a/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp index 39d366b023..9cc91d2246 100644 --- a/indra/newview/llwaterparamset.cpp +++ b/indra/newview/llwaterparamset.cpp @@ -185,8 +185,6 @@ LLVector3 LLWaterParamSet::getVector3(const std::string& paramName, bool& error)  LLVector2 LLWaterParamSet::getVector2(const std::string& paramName, bool& error)   {  	// test to see if right type -	int ttest; -	ttest = mParamValues.size();  	LLSD cur_val = mParamValues.get(paramName);  	if (!cur_val.isArray() || cur_val.size() != 2)   	{ diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp deleted file mode 100644 index 402504933c..0000000000 --- a/indra/newview/llwearable.cpp +++ /dev/null @@ -1,1285 +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 "llfloatersidepanelcontainer.h" -#include "lllocaltextureobject.h" -#include "llnotificationsutil.h" -#include "llviewertexturelist.h" -#include "llinventorymodel.h" -#include "llinventoryobserver.h" -#include "llsidepanelappearance.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); -} - -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  ) -			{ -				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 ); -	}	 -	 -//	if( upload_bake ) -//	{ -//		gAgent.sendAgentSetAppearance(); -//	} -} - - -// 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()) -	{ -		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit")); -	} - -	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; -} - -std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq() -{ -	std::vector<LLLocalTextureObject*> 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::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<LLDriverParam*>(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<LLDriverParam*>(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<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance")); -	if( panel ) -	{ -		panel->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<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance")); -	if( panel ) -	{ -		panel->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<LLDriverParam*>(param); -			if(driver_param) -			{ -				// parameter is a driver parameter, have it update its  -				driver_param->updateCrossDrivenParams(getType()); -			} -		} -	} -} - - -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/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 92697fb2eb..c196d70617 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -34,6 +34,7 @@  #include "llagentwearables.h"  #include "llappearancemgr.h"  #include "llinventoryfunctions.h" +#include "llinventoryicon.h"  #include "lltransutil.h"  #include "llviewerattachmenu.h"  #include "llvoavatarself.h" @@ -788,23 +789,24 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()  	const uuid_vec_t& ids = mUUIDs;		// selected items IDs  	LLUUID selected_id = ids.front();	// ID of the first selected item -	functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1); -  	// Register handlers common for all wearable types.  	registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, true));  	registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false));  	registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));  	registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));  	registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id)); -	registrar.add("Wearable.TakeOffDetach", boost::bind(handleMultiple, take_off, ids)); +	registrar.add("Wearable.TakeOffDetach",  +				  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));  	// Register handlers for clothing. -	registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, ids)); +	registrar.add("Clothing.TakeOff",  +				  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));  	// Register handlers for body parts.  	// Register handlers for attachments. -	registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, ids)); +	registrar.add("Attachment.Detach",  +				  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));  	registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id));  	registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2)); diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 6f6411ce3c..ef1a953f59 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 ); @@ -237,6 +249,8 @@ LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )  	perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER);  	wearable->setPermissions(perm); +	wearable->setDefinitionVersion(LLWearable::getCurrentDefinitionVersion()); +  	// Description and sale info have default values.  	wearable->setParamsToDefaults();  	wearable->setTexturesToDefaults(); @@ -251,13 +265,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 12d0037aee..d6f0fd09a6 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<LLUUID, LLWearable*> mList; +	std::map<LLUUID, LLViewerWearable*> mList;  };  #endif  // LL_LLWEARABLELIST_H diff --git a/indra/newview/llwebsharing.cpp b/indra/newview/llwebsharing.cpp index 43b1a320c3..3a80051b9b 100644 --- a/indra/newview/llwebsharing.cpp +++ b/indra/newview/llwebsharing.cpp @@ -68,9 +68,9 @@ public:  		}  	} -	virtual void error(U32 status, const std::string& reason) +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ -		LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL; +		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;  	}  	virtual void result(const LLSD& content) @@ -99,7 +99,7 @@ public:  		/// Left empty to override the default LLSD parsing behaviour.  	} -	virtual void error(U32 status, const std::string& reason) +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{  		if (HTTP_UNAUTHORIZED == status)  		{ @@ -108,7 +108,7 @@ public:  		}  		else  		{ -			LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL; +			LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;  			LLWebSharing::instance().retryOpenIDAuth();  		} @@ -152,9 +152,9 @@ public:  		}  	} -	virtual void error(U32 status, const std::string& reason) +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ -		LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL; +		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;  		LLWebSharing::instance().retryOpenIDAuth();  	} @@ -221,9 +221,9 @@ public:  		}  	} -	virtual void error(U32 status, const std::string& reason) +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)  	{ -		LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL; +		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;  	}  	virtual void result(const LLSD& content) diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp index be3e3ff30e..93eba5b604 100644 --- a/indra/newview/llwlhandlers.cpp +++ b/indra/newview/llwlhandlers.cpp @@ -121,9 +121,11 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder()  	LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content);  } -/*virtual*/ void LLEnvironmentRequestResponder::error(U32 status, const std::string& reason) +/*virtual*/ +void LLEnvironmentRequestResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	LL_INFOS("WindlightCaps") << "Got an error, not using region windlight..." << LL_ENDL; +	LL_INFOS("WindlightCaps") << "Got an error, not using region windlight... [status:"  +		<< status << "]: " << content << LL_ENDL;  	LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());  } @@ -190,14 +192,15 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)  		LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);  	}  } -/*virtual*/ void LLEnvironmentApplyResponder::error(U32 status, const std::string& reason) +/*virtual*/ +void LLEnvironmentApplyResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)  { -	std::stringstream msg; -	msg << reason << " (Code " << status << ")"; - -	LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region!  Reason: " << msg << LL_ENDL; +	LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region!  [status:" +		<< status << "]: " << content << LL_ENDL;  	LLSD args(LLSD::emptyMap()); +	std::stringstream msg; +	msg << reason << " (Code " << status << ")";  	args["FAIL_REASON"] = msg.str();  	LLNotificationsUtil::add("WLRegionApplyFail", args);  } diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h index 23558876da..598ce6d52a 100644 --- a/indra/newview/llwlhandlers.h +++ b/indra/newview/llwlhandlers.h @@ -47,7 +47,7 @@ class LLEnvironmentRequestResponder: public LLHTTPClient::Responder  	LOG_CLASS(LLEnvironmentRequestResponder);  public:  	virtual void result(const LLSD& content); -	virtual void error(U32 status, const std::string& reason); +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  private:  	friend class LLEnvironmentRequest; @@ -89,7 +89,8 @@ public:  	 */  	virtual void result(const LLSD& content); -	virtual void error(U32 status, const std::string& reason); // non-200 errors only +	// non-200 errors only +	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);  private:  	friend class LLEnvironmentApply; diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 350ba39b45..5fa380e0e3 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -34,6 +34,7 @@  #include "lluistring.h"  #include "llviewertexturelist.h"  #include "lltrans.h" +#include "llgltexture.h"  // Timers to temporise database requests  const F32 AGENTS_UPDATE_TIMER = 60.0;			// Seconds between 2 agent requests for a region @@ -78,7 +79,7 @@ void LLSimInfo::setLandForSaleImage (LLUUID image_id)  	// Fetch the image  	if (mMapImageID.notNull())  	{ -		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); +		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);  		mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP);  	}  	else @@ -92,13 +93,13 @@ LLPointer<LLViewerFetchedTexture> LLSimInfo::getLandForSaleImage ()  	if (mOverlayImage.isNull() && mMapImageID.notNull())  	{  		// Fetch the image if it hasn't been done yet (unlikely but...) -		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); +		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);  		mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP);  	}  	if (!mOverlayImage.isNull())  	{  		// Boost the fetch level when we try to access that image -		mOverlayImage->setBoostLevel(LLViewerTexture::BOOST_MAP); +		mOverlayImage->setBoostLevel(LLGLTexture::BOOST_MAP);  	}  	return mOverlayImage;  } diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index 73530b9694..d514b2f14c 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -36,6 +36,7 @@  #include "llsingleton.h"  #include "llviewerregion.h"  #include "llviewertexture.h" +#include "llgltexture.h"  // 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  diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 11b2770ec0..1940cf541e 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -421,7 +421,7 @@ void LLWorldMapView::draw()  			{  				// 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])); +				overlayimage->setKnownDrawSize(llround(draw_size * LLUI::getScaleFactor().mV[VX]), llround(draw_size * LLUI::getScaleFactor().mV[VY]));  				// Draw something whenever we have enough info  				if (overlayimage->hasGLTexture())  				{ @@ -1317,7 +1317,7 @@ void LLWorldMapView::drawTrackingCircle( const LLRect& rect, S32 x, S32 y, const  	gGL.matrixMode(LLRender::MM_MODELVIEW);  	gGL.pushMatrix(); -	gGL.translatef((F32)x * LLUI::sGLScaleFactor.mV[VX], (F32)y * LLUI::sGLScaleFactor.mV[VY], 0.f); +	gGL.translatef((F32)x * LLUI::getScaleFactor().mV[VX], (F32)y * LLUI::getScaleFactor().mV[VY], 0.f);  	gl_washer_segment_2d(inner_radius, outer_radius, start_theta, end_theta, 40, color, color);  	gGL.popMatrix(); diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp index 74ed844376..895ccaef5a 100644 --- a/indra/newview/llworldmipmap.cpp +++ b/indra/newview/llworldmipmap.cpp @@ -74,21 +74,21 @@ void LLWorldMipmap::equalizeBoostLevels()  		{  			LLPointer<LLViewerFetchedTexture> 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++;  			} @@ -115,7 +115,7 @@ void LLWorldMipmap::dropBoostLevels()  		for (sublevel_tiles_t::iterator iter = level_mipmap.begin(); iter != level_mipmap.end(); iter++)  		{  			LLPointer<LLViewerFetchedTexture> img = iter->second; -			img->setBoostLevel(LLViewerTexture::BOOST_NONE); +			img->setBoostLevel(LLGLTexture::BOOST_NONE);  		}  	}  } @@ -172,7 +172,7 @@ LLPointer<LLViewerFetchedTexture> 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;  	} @@ -189,8 +189,8 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32  	// END DEBUG  	//LL_INFOS("World Map") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL; -	LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); -	img->setBoostLevel(LLViewerTexture::BOOST_MAP); +	LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +	img->setBoostLevel(LLGLTexture::BOOST_MAP);  	// Return the smart pointer  	return img; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 88bf3062c0..5db3a4e713 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -71,6 +71,7 @@  #include "llhudtext.h"  #include "lllightconstants.h"  #include "llmeshrepository.h" +#include "llpipelinelistener.h"  #include "llresmgr.h"  #include "llselectmgr.h"  #include "llsky.h" @@ -378,6 +379,8 @@ BOOL    LLPipeline::sMemAllocationThrottled = FALSE;  S32		LLPipeline::sVisibleLightCount = 0;  F32		LLPipeline::sMinRenderSize = 0.f; +// EventHost API LLPipeline listener. +static LLPipelineListener sPipelineListener;  static LLCullResult* sCull = NULL; @@ -492,19 +495,29 @@ 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 -	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")) +	if (gSavedSettings.getBOOL("DisableAllRenderTypes")) +	{ +		clearAllRenderTypes(); +	} +	else  	{ -		toggleRenderType(RENDER_TYPE_GROUND); +		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); +		}  	}  	// make sure RenderPerformanceTest persists (hackity hack hack) @@ -5920,7 +5933,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  			if (light->isLightSpotlight() // directional (spot-)light  			    && (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on  			{ -				LLVector3 spotparams = light->getSpotLightParams();  				LLQuaternion quat = light->getRenderRotation();  				LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction  				at_axis *= quat; @@ -6451,6 +6463,22 @@ void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value)  	}  } +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)  { @@ -9084,9 +9112,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) @@ -9312,7 +9337,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 @@ -10417,6 +10442,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 9e113289fc..9706fd569c 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -324,20 +324,28 @@ public:  	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 @@ -634,6 +642,7 @@ protected:  	U32						mRenderDebugFeatureMask;  	U32						mRenderDebugMask; +	std::stack<U32>			mRenderDebugFeatureStack;  	U32						mOldRenderDebugMask; diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index df75f3f697..471a896019 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -135,8 +135,8 @@ TOOLNO                  CURSOR                  "llno.cur"  //  VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,1,1,0 - PRODUCTVERSION 2,1,1,0 + FILEVERSION 3,4,1,264760 + PRODUCTVERSION 3,4,1,264760   FILEFLAGSMASK 0x3fL  #ifdef _DEBUG   FILEFLAGS 0x1L @@ -153,12 +153,12 @@ BEGIN          BEGIN              VALUE "CompanyName", "Linden Lab"              VALUE "FileDescription", "Second Life" -            VALUE "FileVersion", "2.1.1.0" +            VALUE "FileVersion", "3.4.1.264760"              VALUE "InternalName", "Second Life"              VALUE "LegalCopyright", "Copyright � 2001-2010, Linden Research, Inc."              VALUE "OriginalFilename", "SecondLife.exe"              VALUE "ProductName", "Second Life" -            VALUE "ProductVersion", "2.1.1.0" +            VALUE "ProductVersion", "3.4.1.264760"          END      END      BLOCK "VarFileInfo" diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 93c9cb02cb..fcab966dee 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -724,9 +724,6 @@ with the same filename but different name    <texture name="icon_for_sale.tga" file_name="icons/Icon_For_Sale.png" />    <texture name="icon_top_pick.tga" /> -  <texture name="inv_folder_mesh.tga"/> -  <texture name="inv_item_mesh.tga"/> -    <texture name="lag_status_critical.tga" />    <texture name="lag_status_good.tga" />    <texture name="lag_status_warning.tga" /> diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index d8b085063f..2152a9f6e9 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -42,58 +42,55 @@      <floater.string       name="multiple_participants_added"       value="[NAME] were invited to the conversation."/> -     <floater.string +    <floater.string       name="tooltip_to_separate_window"       value="Move this conversation to a separate window"/> -     <floater.string +    <floater.string       name="tooltip_to_main_window"       value="Move this conversation back to main window"/> -  <floater.string +    <floater.string       name="start_call_button_tooltip"       value="Open voice connection"/> -  <floater.string +    <floater.string       name="end_call_button_tooltip"       value="Close voice connection"/> -   <floater.string +    <floater.string       name="expcol_button_not_tearoff_tooltip"       value="Collapse this pane"/> -   <floater.string +    <floater.string       name="expcol_button_tearoff_and_expanded_tooltip"       value="Collapse participant list"/> -   <floater.string +    <floater.string       name="expcol_button_tearoff_and_collapsed_tooltip"       value="Expand participant list"/>      <view -        follows="all" -        layout="topleft" -        name="contents_view" -        top="0" -        left="0" -        height="355" -        width="394"> -   <layout_stack -   animate="false"  -   default_tab_group="2" -   follows="all" -  height="355" -  width="394" -  layout="topleft" -  orientation="vertical" -   name="main_stack" -  tab_group="1" -  top="0" -  left="0"> -   -     <layout_panel -         follows="left|top|right" -         layout="topleft" -         name="toolbar_panel" +     follows="all" +     layout="topleft" +     name="contents_view" +     top="0" +     left="0" +     right="-1" +     bottom="-3"> +        <layout_stack +         animate="false"  +         default_tab_group="2" +         follows="all" +         right="-5" +         bottom="-1"           top="0" -         left="0" -         height="35" -         min_height="35" -         width="394">          -             <menu_button +         left="5" +         border_size="0" +         layout="topleft" +         orientation="vertical" +         name="main_stack" +         tab_group="1"> +            <layout_panel +             auto_resize="false" +             name="toolbar_panel" +             height="35" +             right="-1" +             left="1"> +                <menu_button                   menu_filename="menu_im_session_showmodes.xml"                   follows="top|left"                   height="25" @@ -107,22 +104,22 @@                   tool_tip="View/sort options"                   top="5"                   width="31" /> -             <menu_button -				 menu_filename="menu_im_conversation.xml" -				 follows="top|left" -				 height="25" -				 image_hover_unselected="Toolbar_Middle_Over" -				 image_overlay="OptionsMenu_Off" -				 image_selected="Toolbar_Middle_Selected" -				 image_unselected="Toolbar_Middle_Off" -				 layout="topleft" -			 	 top="5" -			 	 left_pad="2" -				 name="gear_btn" -				 visible="false" -				 tool_tip="Actions on selected person" -				 width="31"/> -             <button +                <menu_button +                 menu_filename="menu_im_conversation.xml" +                 follows="top|left" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="OptionsMenu_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 layout="topleft" +                 top="5" +                 left_pad="2" +                 name="gear_btn" +                 visible="false" +                 tool_tip="Actions on selected person" +                 width="31"/> +                <button                   enabled="false"                   follows="top|left"                   height="25" @@ -136,7 +133,7 @@                   name="add_btn"                   tool_tip="Add someone to this conversation"                   width="31"/> -             <button +                <button                   follows="top|left"                   height="25"                   image_hover_unselected="Toolbar_Middle_Over" @@ -149,19 +146,19 @@                   name="voice_call_btn"                   tool_tip="Open voice connection"                   width="31"/> -              <output_monitor -                  auto_update="true" -                  follows="top|left" -                  draw_border="false" -                  height="16" -                  layout="topleft" -                  top="10" -                  left_pad="10" -                  mouse_opaque="true" -                  name="speaking_indicator" -                  visible="false" -                  width="20" />        -             <button +                <output_monitor +                 auto_update="true" +                 follows="top|left" +                 draw_border="false" +                 height="16" +                 layout="topleft" +                 top="10" +                 left_pad="10" +                 mouse_opaque="true" +                 name="speaking_indicator" +                 visible="false" +                 width="20" /> +                <button                   follows="right|top"                   height="25"                   image_hover_unselected="Toolbar_Middle_Over" @@ -170,232 +167,170 @@                   image_unselected="Toolbar_Middle_Off"                   layout="topleft"                   top="5" -                 left="292" +                 right="-67"                   name="close_btn"                   tool_tip="End this conversation"                   width="31" /> -             <button +                <button                   follows="right|top"                   height="25"                   image_hover_unselected="Toolbar_Middle_Over"                   image_overlay="Conv_toolbar_collapse"                   image_selected="Toolbar_Middle_Selected" -             	 image_unselected="Toolbar_Middle_Off" +                 image_unselected="Toolbar_Middle_Off"                   layout="topleft"                   top="5"                   left_pad="2"                   name="expand_collapse_btn"                   tool_tip="Collapse/Expand this pane"                   width="31" /> -             <button +                <button                   follows="right|top"                   height="25"                   image_hover_unselected="Toolbar_Middle_Over"                   image_overlay="Conv_toolbar_arrow_ne"                   image_selected="Toolbar_Middle_Selected" -             	 image_unselected="Toolbar_Middle_Off" +                 image_unselected="Toolbar_Middle_Off"                   layout="topleft" -                 top="5"                   left_pad="2"                   name="tear_off_btn" +                 top="5"                   width="31" /> -     </layout_panel> -     <layout_panel -      name="body_panel" -      follows="all" -      width="394"  -      height="235"  -      user_resize="false" -      auto_resize="true"> -  <layout_stack -   animate="true"  -   default_tab_group="2" -  follows="all" -  height="275" -  width="394" -  layout="topleft" -  orientation="horizontal" -  name="im_panels" -  tab_group="1" -  top_pad="0" -  left="0"> -    <layout_panel -      name="speakers_list_panel" -      follows="all" -      expanded_min_dim="115" -      min_dim="0" -      width="150"  -      height="275" -      user_resize="true" -      auto_resize="false"> -      </layout_panel> -    <layout_panel -       default_tab_group="3" -       left="0" -       tab_group="2" -       follows="all" -       top="0" -       height="275" -	   width="244" -       layout="topleft" -       user_resize="true" -       auto_resize="true" -       visible="true" -       name="right_part_holder" -       min_width="221"> -        <panel -         name="trnsAndChat_panel" -         follows="all" -         layout="topleft" -         visible="true" -         height="240" -         width="244"> -         <layout_stack -          animate="true"  -          default_tab_group="2" -          follows="all" -          height="240" -          width="244" -          layout="topleft" -          visible="true" -          orientation="vertical" -          name="translate_and_chat_stack" -          tab_group="1" -          left_pad="0" -          top="0" -          left="0"> -            <layout_panel -             auto_resize="false" -             user_resize="false" -             height="26" -             layout="topleft" -             left_delta="0" -             name="translate_chat_checkbox_lp" -             top_delta="0" -             visible="true" -             width="210"> -                <check_box -                 top="10" -                 control_name="TranslateChat" -                 enabled="true" -                 height="16" -                 label="Translate chat" -                 layout="topleft" -                 left="5" -                 name="translate_chat_checkbox" -                 width="230" />              </layout_panel>              <layout_panel -             width="210" -             layout="topleft" -             follows="all" -             left_delta="0" -             top_delta="0" -             bottom="0" -             visible="true" -             user_resize="false" -             auto_resize="true" -             name="chat_holder">       -               <chat_history -                font="SansSerifSmall" -                follows="all" -                visible="true" -                name="chat_history" -                parse_highlights="true" -                parse_urls="true" -                layout="topleft" -                right="-5" -                left="5" -                top="0" -                bottom="1"> -               </chat_history> +             name="body_panel" +             top="1" +             bottom="-1"> +                <layout_stack +                 default_tab_group="2" +                 follows="all" +                 orientation="horizontal" +                 name="im_panels" +                 tab_group="1" +                 top="0" +                 right="-1" +                 bottom="-1" +                 left="0"> +                    <layout_panel +                     name="speakers_list_panel" +                     expanded_min_dim="115" +                     min_dim="0" +                     width="150"  +                     user_resize="true" +                     auto_resize="false"  +                     bottom="-1" /> +                    <layout_panel +                     default_tab_group="3" +                     tab_group="2" +                     name="right_part_holder" +                     min_width="221" +                     bottom="-1"> +                        <layout_stack +                         animate="true"  +                         default_tab_group="2" +                         follows="all" +                         orientation="vertical" +                         name="translate_and_chat_stack" +                         tab_group="1" +                         top="0" +                         left="0" +                         right="-1" +                         bottom="-1"> +                            <layout_panel +                             auto_resize="false" +                             height="26" +                             name="translate_chat_checkbox_lp"> +                                <check_box +                                 top="10" +                                 control_name="TranslateChat" +                                 enabled="true" +                                 height="16" +                                 label="Translate chat" +                                 left="5" +                                 name="translate_chat_checkbox" +                                 width="230" /> +                            </layout_panel> +                            <layout_panel +                             name="chat_holder"> +                                <chat_history +                                 font="SansSerifSmall" +                                 follows="all" +                                 name="chat_history" +                                 parse_highlights="true" +                                 parse_urls="true" +                                 right="-1" +                                 left="5" +                                 top="0" +                                 bottom="-1" /> +                            </layout_panel> +                        </layout_stack> +                    </layout_panel> +                </layout_stack>              </layout_panel> -           </layout_stack> -           </panel> -    </layout_panel> -  </layout_stack> -  </layout_panel> -  <layout_panel -             height="35" -             layout="topleft" -             follows="left|right|bottom" -             left_delta="0" -             right="0" +            <layout_panel               top_delta="0" -             bottom="0" -             visible="true" -             user_resize="false" +             top="0" +             height="26" +             bottom="-1"               auto_resize="false"               name="chat_layout_panel"> -   <layout_stack -   animate="true"  -   default_tab_group="2" -   follows="all" -   height="35" -   right="0" -   layout="topleft" -   orientation="horizontal" -   name="input_panels" -   top_pad="0" -   left="0"> -     <layout_panel -             height="35" -             layout="topleft" -             follows="left|right|bottom" -             left_delta="0" -             top_delta="0" -             bottom="0" -             visible="true" -             user_resize="false" -             auto_resize="true" -             name="input_editor_layout_panel"> -              <chat_editor -             expand_lines_count="5" -             follows="left|right|bottom" -               font="SansSerifSmall" -             visible="true" -             height="20" -             is_expandable="true" -             label="To" -             text_tentative_color="TextFgTentativeColor" -             layout="topleft" -             name="chat_editor" -             max_length="1023" -             spellcheck="true" -             tab_group="3" -             width="160" -             top="6" -             left="5" -             right="-5" -             wrap="true"> -            </chat_editor> +                <layout_stack +                 animate="false" +                 default_tab_group="2" +                 follows="all" +                 orientation="horizontal" +                 name="input_panels" +                 top="0" +                 bottom="-2" +                 left="0" +                 right="-1"> +                    <layout_panel +                     name="input_editor_layout_panel" +                     auto_resize="true" +                     user_resize="false" +                     top="0" +                     bottom="-1"> +                        <chat_editor +                         layout="topleft" +                         expand_lines_count="5" +                         follows="left|right|bottom" +                         font="SansSerifSmall" +                         height="20"     +                         is_expandable="true" +                         text_tentative_color="TextFgTentativeColor" +                         name="chat_editor" +                         max_length="1023" +                         spellcheck="true" +                         tab_group="3" +                         top="1" +                         bottom="-2" +                         left="4" +                         right="-4" +                         wrap="true" /> +                    </layout_panel> +                    <layout_panel +                     auto_resize="false" +                     user_resize="false" +                     name="input_button_layout_panel" +                     width="30" +                     top="0" +                     bottom="-1"> +                        <button +                         layout="topleft" +                         left="1" +                         right="-1" +                         top="1" +                         height="22" +                         follows="left|right|top" +                         image_hover_unselected="Toolbar_Middle_Over" +                         image_overlay="Conv_expand_one_line" +                         image_selected="Toolbar_Middle_Selected" +                         image_unselected="Toolbar_Middle_Off" +                         name="minz_btn" +                         tool_tip="Shows/hides message panel" /> +                    </layout_panel> +                </layout_stack>              </layout_panel> -            <layout_panel              -             height="35" -             layout="topleft" -             follows="left|right|bottom" -             left_delta="0" -             top_delta="0" -             bottom="0" -             width="35" -             visible="true" -             user_resize="false" -             auto_resize="false" -             name="input_button_layout_panel"> -            <button -                 follows="left|right|bottom" -                 height="25" -                 image_hover_unselected="Toolbar_Middle_Over" -                 image_overlay="Conv_expand_one_line" -                 image_selected="Toolbar_Middle_Selected" -                 image_unselected="Toolbar_Middle_Off" -                 layout="topleft" -                 name="minz_btn" -                 tool_tip="Shows/hides message panel" -                 width="28"/> -           </layout_panel> -  </layout_stack> -  </layout_panel> -  </layout_stack> +        </layout_stack>      </view>  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml index b46b62ec4d..46ba4bd29d 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml @@ -79,6 +79,14 @@              <menu_item_call.on_visible               function="IsGodCustomerService"/>          </menu_item_call> +    <menu_item_call +		 label="Dump XML" +         name="Dump XML"> +            <menu_item_call.on_click +             function="Advanced.AppearanceToXML" /> +            <menu_item_call.on_visible +             function="Advanced.EnableAppearanceToXML"/> +    </menu_item_call>  	    <menu_item_call           label="Zoom In"            name="Zoom In"> diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index b8128da358..28e032ce5f 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -123,6 +123,14 @@ name="Edit Outfit">      <menu_item_call.on_visible       function="IsGodCustomerService"/>    </menu_item_call> +    <menu_item_call +		 label="Dump XML" +         name="Dump XML"> +            <menu_item_call.on_click +             function="Advanced.AppearanceToXML" /> +            <menu_item_call.on_visible +             function="Advanced.EnableAppearanceToXML"/> +    </menu_item_call>    <menu_item_separator    layout="topleft" />    <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml index 276b5f106f..e7c2b80da2 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml @@ -79,6 +79,14 @@              <menu_item_call.on_visible               function="IsGodCustomerService"/>          </menu_item_call> +    <menu_item_call +		 label="Dump XML" +         name="Dump XML"> +            <menu_item_call.on_click +             function="Advanced.AppearanceToXML" /> +            <menu_item_call.on_visible +             function="Advanced.EnableAppearanceToXML"/> +    </menu_item_call>  	    <menu_item_call           label="Zoom In"            name="Zoom In"> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index d9bdfece38..c1ff026a74 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -261,4 +261,12 @@              <menu_item_call.on_visible               function="IsGodCustomerService"/>      </menu_item_call> +    <menu_item_call +		 label="Dump XML" +         name="Dump XML"> +            <menu_item_call.on_click +             function="Advanced.AppearanceToXML" /> +            <menu_item_call.on_visible +             function="Advanced.EnableAppearanceToXML"/> +    </menu_item_call>  </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 101e104eab..52c4fb1613 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -180,7 +180,8 @@         name="Set Logging Level"         tear_off="true">          <menu_item_check -          label="Debug"> +         name="Debug" +         label="Debug">            <menu_item_check.on_check              function="Develop.CheckLoggingLevel"              parameter="0" /> @@ -189,7 +190,8 @@             parameter="0" />          </menu_item_check>          <menu_item_check -          label="Info"> +         name="Info" +         label="Info">            <menu_item_check.on_check              function="Develop.CheckLoggingLevel"              parameter="1" /> @@ -198,7 +200,8 @@             parameter="1" />          </menu_item_check>          <menu_item_check -          label="Warning"> +         name="Warning" +         label="Warning">            <menu_item_check.on_check              function="Develop.CheckLoggingLevel"              parameter="2" /> @@ -207,7 +210,8 @@             parameter="2" />          </menu_item_check>          <menu_item_check -          label="Error"> +         name="Error" +         label="Error">            <menu_item_check.on_check              function="Develop.CheckLoggingLevel"              parameter="3" /> @@ -216,7 +220,8 @@             parameter="3" />          </menu_item_check>          <menu_item_check -          label="None"> +         name="None" +         label="None">            <menu_item_check.on_check              function="Develop.CheckLoggingLevel"              parameter="4" /> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 544f06ac0c..a11cd13fdb 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -131,6 +131,7 @@         name="Status"         tear_off="true">          <menu_item_check +         name="Away"           label="Away">            <menu_item_check.on_check             function="View.Status.CheckAway" /> @@ -138,6 +139,7 @@             function="World.SetAway" />          </menu_item_check>          <menu_item_check +         name="Do Not Disturb"           label="Do Not Disturb">            <menu_item_check.on_check             function="View.Status.CheckDoNotDisturb" /> @@ -257,6 +259,7 @@               parameter="speak" />          </menu_item_check>          <menu_item_check +         name="Conversation Log..."           label="Conversation Log...">              <menu_item_check.on_check               function="Floater.Visible" @@ -352,6 +355,7 @@          </menu_item_call>        <menu_item_separator/>        <menu_item_check +       name="Do Not Disturb"         label="Do Not Disturb">          <menu_item_check.on_check           function="View.Status.CheckDoNotDisturb" /> @@ -3051,13 +3055,6 @@                  <menu_item_call.on_click                   function="Advanced.PrintAgentInfo" />              </menu_item_call> -            <menu_item_call -             label="Memory Stats" -             name="Memory Stats" -             shortcut="control|alt|shift|M"> -                <menu_item_call.on_click -                 function="Advanced.PrintTextureMemoryStats" /> -            </menu_item_call>              <menu_item_check               label="Region Debug Console"               name="Region Debug Console" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index c681e39002..105bef7321 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -352,7 +352,7 @@ Save all changes to clothing/body parts?     icon="alertmodal.tga"     name="FriendsAndGroupsOnly"     type="alertmodal"> -    Non-friends won't know that you've choosen to ignore their calls and instant messages. +    Non-friends won't know that you've chosen to ignore their calls and instant messages.      <usetemplate       name="okbutton"       yestext="OK"/> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 3b1cbf6a58..f4473dd0b1 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2989,6 +2989,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].  <string name="Higher">Higher</string>  <string name="Hip Length">Hip Length</string>  <string name="Hip Width">Hip Width</string> +<string name="Hover">Hover</string>  <string name="In">In</string>  <string name="In Shdw Color">Inner Shadow Color</string>  <string name="In Shdw Opacity">Inner Shadow Opacity</string> diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp index 0254c5881f..41cb344808 100644 --- a/indra/newview/tests/llmediadataclient_test.cpp +++ b/indra/newview/tests/llmediadataclient_test.cpp @@ -126,7 +126,9 @@ void LLHTTPClient::post(  	result[LLTextureEntry::OBJECT_ID_KEY] = body[LLTextureEntry::OBJECT_ID_KEY];  	if ( url == FAKE_OBJECT_MEDIA_CAP_URL_503 )  	{ -		responder->error(HTTP_SERVICE_UNAVAILABLE, "fake reason"); +		LLSD content; +		content["reason"] = "fake reason"; +		responder->errorWithContent(HTTP_SERVICE_UNAVAILABLE, "fake reason", content);  		return;  	}  	else if (url == FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR)  diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index f8923b9868..a331d9aa9e 100644..100755 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -37,30 +37,6 @@  #include "llregionhandle.h"  #include "../llvoavatar.h" -void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) -{ -	counts.resize(3); -	counts[0] = 0; -	counts[1] = 0; -	counts[2] = 1; -} - -// static -std::string LLVOAvatar::rezStatusToString(S32 rez_status) -{ -	if (rez_status==0) return "cloud"; -	if (rez_status==1) return "gray"; -	if (rez_status==2) return "textured"; -	return "unknown"; -} - -// static -LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name) -{ -	static LLViewerStats::StatsAccumulator junk; -	return junk; -} -  static const char * all_keys[] =   {  	"duration", @@ -123,31 +99,34 @@ is_empty_map(const LLSD & sd)  {  	return sd.isMap() && 0 == sd.size();  } +#endif +#if 0  static bool  is_single_key_map(const LLSD & sd, const std::string & key)  {  	return sd.isMap() && 1 == sd.size() && sd.has(key);  } +#endif  static bool  is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & key2)  {  	return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2);  } -#endif +#if 0  static bool  is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & key2, const std::string& key3)  {  	return sd.isMap() && 3 == sd.size() && sd.has(key1) && sd.has(key2) && sd.has(key3);  } - +#endif  static bool  is_no_stats_map(const LLSD & sd)  { -	return is_triple_key_map(sd, "duration", "regions", "avatar"); +	return is_double_key_map(sd, "duration", "regions");  }  static bool @@ -258,7 +237,7 @@ namespace tut  		// Once the region is set, we will get a response even with no data collection  		it->setRegion(region1_handle);  		sd_full = it->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_triple_key_map(sd_full, "duration", "regions", "avatar")); +		ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle));  		LLSD sd = sd_full["regions"][0]; @@ -299,7 +278,7 @@ namespace tut  		it->setRegion(region1_handle);  		LLSD sd = it->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); +		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = sd[0]; @@ -324,7 +303,7 @@ namespace tut  		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);  		LLSD sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); +		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = sd["regions"][0]; @@ -364,7 +343,7 @@ namespace tut  		LLSD sd = gViewerAssetStatsThread1->asLLSD(false);  		ensure("Other collector is empty", is_no_stats_map(sd));  		sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); +		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = sd["regions"][0]; @@ -414,7 +393,7 @@ namespace tut  		// std::cout << sd << std::endl; -		ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); +		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));  		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));  		LLSD sd1 = get_region(sd, region1_handle);  		LLSD sd2 = get_region(sd, region2_handle); @@ -437,7 +416,7 @@ namespace tut  		// Reset leaves current region in place  		gViewerAssetStatsMain->reset();  		sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); +		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));  		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));  		sd2 = sd["regions"][0]; @@ -486,7 +465,7 @@ namespace tut  		LLSD sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); +		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));  		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));  		LLSD sd1 = get_region(sd, region1_handle);  		LLSD sd2 = get_region(sd, region2_handle); @@ -509,7 +488,7 @@ namespace tut  		// Reset leaves current region in place  		gViewerAssetStatsMain->reset();  		sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); +		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions"));  		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));  		sd2 = get_region(sd, region2_handle);  		ensure("Region2 is present in results", sd2.isMap()); @@ -555,7 +534,7 @@ namespace tut  		LLSD sd = gViewerAssetStatsThread1->asLLSD(false);  		ensure("Other collector is empty", is_no_stats_map(sd));  		sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); +		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = get_region(sd, region1_handle);  		ensure("Region1 is present in results", sd.isMap()); diff --git a/indra/newview/tests/llviewertexture_stub.cpp b/indra/newview/tests/llviewertexture_stub.cpp new file mode 100644 index 0000000000..889ab9bea5 --- /dev/null +++ b/indra/newview/tests/llviewertexture_stub.cpp @@ -0,0 +1,34 @@ +/**  + * @file llviewertexture_stub.cpp + * @brief  stub class to allow unit testing + * + * $LicenseInfo:firstyear=2012&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 "linden_common.h" +#include "../llviewertexture.h" +#include "../../llrender/llgltexture.h" + +void LLViewerTexture::setBoostLevel(int level) +{ +} + diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp index acc6e814bc..84194adb5d 100644 --- a/indra/newview/tests/llworldmap_test.cpp +++ b/indra/newview/tests/llworldmap_test.cpp @@ -47,9 +47,9 @@  // * A simulator for a class can be implemented here. Please comment and document thoroughly.  // Stub image calls -void LLViewerTexture::setBoostLevel(S32 ) { } -void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { } -LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, BOOL, LLViewerTexture::EBoostLevel, S8, +void LLGLTexture::setBoostLevel(S32 ) { } +void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { } +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, FTType, BOOL, LLGLTexture::EBoostLevel, S8,  																  LLGLint, LLGLenum, LLHost ) { return NULL; }  // Stub related map calls diff --git a/indra/newview/tests/llworldmipmap_test.cpp b/indra/newview/tests/llworldmipmap_test.cpp index e7ef017760..142d75bcfd 100644 --- a/indra/newview/tests/llworldmipmap_test.cpp +++ b/indra/newview/tests/llworldmipmap_test.cpp @@ -42,8 +42,8 @@  // * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)  // * A simulator for a class can be implemented here. Please comment and document thoroughly. -void LLViewerTexture::setBoostLevel(S32 ) { } -LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, BOOL, LLViewerTexture::EBoostLevel, S8,  +void LLGLTexture::setBoostLevel(S32 ) { } +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, FTType, BOOL, LLGLTexture::EBoostLevel, S8,   																		 LLGLint, LLGLenum, const LLUUID& ) { return NULL; }  LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) { } diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index e7108141ee..69248e26bc 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1081,7 +1081,7 @@ class Linux_i686Manifest(LinuxManifest):              self.path("libcrypto.so.*")              self.path("libexpat.so.*")              self.path("libssl.so.1.0.0") -            self.path("libglod.so") +            self.path("libGLOD.so")              self.path("libminizip.so")              self.path("libuuid.so*")              self.path("libSDL-1.2.so.*") diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 816f1d7175..31e1d89c68 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -28,6 +28,10 @@ include_directories(      ${GOOGLEMOCK_INCLUDE_DIRS}      ${TUT_INCLUDE_DIR}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(test_SOURCE_FILES      io.cpp diff --git a/indra/test/io.cpp b/indra/test/io.cpp index ce747f667d..47a67deed0 100644 --- a/indra/test/io.cpp +++ b/indra/test/io.cpp @@ -1140,7 +1140,7 @@ namespace tut  		bool connected = client->blockingConnect(server_host);  		ensure("Connected to server", connected);  		lldebugs << "connected" << llendl; -		F32 elapsed = pump_loop(mPump,0.1f); +		pump_loop(mPump,0.1f);  		count = mPump->runningChains();  		ensure_equals("server chain onboard", count, 2);  		lldebugs << "** Client is connected." << llendl; @@ -1156,20 +1156,20 @@ namespace tut  		chain.clear();  		// pump for a bit and make sure all 3 chains are running -		elapsed = pump_loop(mPump,0.1f); +		pump_loop(mPump,0.1f);  		count = mPump->runningChains();  		ensure_equals("client chain onboard", count, 3);  		lldebugs << "** request should have been sent." << llendl;  		// pump for long enough the the client socket closes, and the  		// server socket should not be closed yet. -		elapsed = pump_loop(mPump,0.2f); +		pump_loop(mPump,0.2f);  		count = mPump->runningChains();  		ensure_equals("client chain timed out ", count, 2);  		lldebugs << "** client chain should be closed." << llendl;  		// At this point, the socket should be closed by the timeout -		elapsed = pump_loop(mPump,1.0f); +		pump_loop(mPump,1.0f);  		count = mPump->runningChains();  		ensure_equals("accepted socked close", count, 1);  		lldebugs << "** Sleeper should have timed out.." << llendl; diff --git a/indra/test/llpermissions_tut.cpp b/indra/test/llpermissions_tut.cpp index bf6766424c..bc2c87ba46 100644 --- a/indra/test/llpermissions_tut.cpp +++ b/indra/test/llpermissions_tut.cpp @@ -407,7 +407,7 @@ namespace tut  		LLFILE* fp = LLFile::fopen("linden_file.dat","w+");  		if(!fp)  		{ -			llerrs << "file coudnt be opened\n" << llendl; +			llerrs << "file couldn't be opened\n" << llendl;  			return;  		}  		LLPermissions perm,perm1; @@ -425,15 +425,15 @@ namespace tut  		perm.initMasks(base, ownerp, everyone, groupp, next); -		perm.exportFile(fp); +		ensure("Permissions export failed", perm.exportFile(fp));  		fclose(fp);	  		fp = LLFile::fopen("linden_file.dat","r+");  		if(!fp)  		{ -			llerrs << "file coudnt be opened\n" << llendl; +			llerrs << "file couldn't be opened\n" << llendl;  			return;  		} -		perm1.importFile(fp); +		ensure("Permissions import failed", perm1.importFile(fp));  		fclose(fp);  		ensure_equals("exportFile()/importFile():failed to export and import the data ", perm1, perm);	  } @@ -461,7 +461,7 @@ namespace tut  		std::istringstream istream(ostream.str());  		perm1.importLegacyStream(istream); -		ensure_equals("exportLegacyStream()/importLegacyStream():failed to export and import the data ", perm1, perm); +		ensure_equals("exportStream()/importStream():failed to export and import the data ", perm1, perm);  	}  	template<> template<> diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp index 09fca2abba..2689eaa15e 100644 --- a/indra/test/llsaleinfo_tut.cpp +++ b/indra/test/llsaleinfo_tut.cpp @@ -154,8 +154,9 @@ namespace tut  		BOOL has_perm_mask = FALSE;  		llsaleinfo1.importLegacyStream(istream, has_perm_mask, perm_mask); -		ensure("importLegacyStream() fn failed ", llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() && -										       llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());		 +		ensure("importStream() fn failed ", +			llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() && +			llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());  	}  	template<> template<> diff --git a/indra/test/llstreamtools_tut.cpp b/indra/test/llstreamtools_tut.cpp index a93f2e8f65..0f6436f0f4 100644 --- a/indra/test/llstreamtools_tut.cpp +++ b/indra/test/llstreamtools_tut.cpp @@ -385,16 +385,15 @@ namespace tut  		std::string expected_result;  		std::string actual_result;  		std::istringstream is; -		bool ret;  		is.clear();  		is.str(str = "  First Second \t \r  \n Third  Fourth-ShouldThisBePartOfFourth  Fifth\n");  		actual_result = ""; -		ret = get_word(actual_result, is); // First +		get_word(actual_result, is); // First  		actual_result = ""; -		ret = get_word(actual_result, is); // Second +		get_word(actual_result, is); // Second  		actual_result = ""; -		ret = get_word(actual_result, is); // Third +		get_word(actual_result, is); // Third  		// the current implementation of get_word seems inconsistent with  		// skip_to_next_word. skip_to_next_word treats any character other @@ -403,22 +402,22 @@ namespace tut  		// carriage  return ('\r'), horizontal tab ('\t'), and vertical tab ('\v')  		// as delimiters   		actual_result = ""; -		ret = get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth +		get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth  		actual_result = ""; -		ret = get_word(actual_result, is); // will copy Fifth +		get_word(actual_result, is); // will copy Fifth  		is.clear();  		is.str(str = "  First Second \t \r  \n Third  Fourth_ShouldThisBePartOfFourth Fifth\n"); -		ret = skip_to_next_word(is);  // should now point to First -		ret = skip_to_next_word(is);  // should now point to Second -		ret = skip_to_next_word(is);  // should now point to Third -		ret = skip_to_next_word(is);  // should now point to Fourth -		ret = skip_to_next_word(is);  // should now point to ShouldThisBePartOfFourth +		skip_to_next_word(is);  // should now point to First +		skip_to_next_word(is);  // should now point to Second +		skip_to_next_word(is);  // should now point to Third +		skip_to_next_word(is);  // should now point to Fourth +		skip_to_next_word(is);  // should now point to ShouldThisBePartOfFourth  		expected_result = "";  		// will copy ShouldThisBePartOfFourth, the fifth word,   		// while using get_word above five times result in getting "Fifth" -		ret = get_word(expected_result, is);  +		get_word(expected_result, is);   		ensure_equals("get_word: skip_to_next_word compatibility", actual_result, expected_result);  	} @@ -480,39 +479,38 @@ namespace tut  		std::string expected_result;  		std::string actual_result;  		std::istringstream is; -		bool ret;  		is.clear();  		is.str(str = "First Second \t \r\n Third  Fourth-ShouldThisBePartOfFourth  IsThisFifth\n");  		actual_result = ""; -		ret = get_line(actual_result, is); +		get_line(actual_result, is);  		expected_result = "First Second \t \r\n";  		ensure_equals("get_line: 1", actual_result, expected_result);  		actual_result = ""; -		ret = get_line(actual_result, is); +		get_line(actual_result, is);  		expected_result = " Third  Fourth-ShouldThisBePartOfFourth  IsThisFifth\n";  		ensure_equals("get_line: 2", actual_result, expected_result);  		is.clear();  		is.str(str = "\nFirst Line.\n\nSecond Line.\n");  		actual_result = ""; -		ret = get_line(actual_result, is); +		get_line(actual_result, is);  		expected_result = "\n";  		ensure_equals("get_line: First char as newline", actual_result, expected_result);  		actual_result = ""; -		ret = get_line(actual_result, is); +		get_line(actual_result, is);  		expected_result = "First Line.\n";  		ensure_equals("get_line: 3", actual_result, expected_result);  		actual_result = ""; -		ret = get_line(actual_result, is); +		get_line(actual_result, is);  		expected_result = "\n";  		ensure_equals("get_line: 4", actual_result, expected_result);  		actual_result = ""; -		ret = get_line(actual_result, is); +		get_line(actual_result, is);  		expected_result = "Second Line.\n";  		ensure_equals("get_line: 5", actual_result, expected_result);  	}	 @@ -544,13 +542,12 @@ namespace tut  		std::string expected_result;  		std::string actual_result;  		std::istringstream is; -		bool ret;  		// need to be check if this test case is wrong or the implementation is wrong.  		is.clear();  		is.str(str = "Should not skip lone \r.\r\n");  		actual_result = ""; -		ret = get_line(actual_result, is); +		get_line(actual_result, is);  		expected_result = "Should not skip lone \r.\r\n";  		ensure_equals("get_line: carriage return skipped even though not followed by newline", actual_result, expected_result);  	} @@ -563,12 +560,11 @@ namespace tut  		std::string expected_result;  		std::string actual_result;  		std::istringstream is; -		bool ret;  		is.clear();  		is.str(str = "\n");  		actual_result = ""; -		ret = get_line(actual_result, is); +		get_line(actual_result, is);  		expected_result = "\n";  		ensure_equals("get_line: Just newline", actual_result, expected_result);  	} @@ -582,36 +578,35 @@ namespace tut  		std::string expected_result;  		std::string actual_result;  		std::istringstream is; -		bool ret;  		is.clear();  		is.str(str = "First Line.\nSecond Line.\n");  		actual_result = ""; -		ret = get_line(actual_result, is, 255); +		get_line(actual_result, is, 255);  		expected_result = "First Line.\n";  		ensure_equals("get_line: Basic Operation", actual_result, expected_result);  		actual_result = ""; -		ret = get_line(actual_result, is, sizeof("Second")-1); +		get_line(actual_result, is, sizeof("Second")-1);  		expected_result = "Second\n";  		ensure_equals("get_line: Insufficient length 1", actual_result, expected_result);  		actual_result = ""; -		ret = get_line(actual_result, is, 255); +		get_line(actual_result, is, 255);  		expected_result = " Line.\n";  		ensure_equals("get_line: Remainder after earlier insufficient length", actual_result, expected_result);  		is.clear();  		is.str(str = "One Line only with no newline with limited length");  		actual_result = ""; -		ret = get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1); +		get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1);  		expected_result = "One Line only with no newline with limited length\n";  		ensure_equals("get_line: No newline with limited length", actual_result, expected_result);  		is.clear();  		is.str(str = "One Line only with no newline");  		actual_result = ""; -		ret = get_line(actual_result, is, 255); +		get_line(actual_result, is, 255);  		expected_result = "One Line only with no newline";  		ensure_equals("get_line: No newline", actual_result, expected_result);  	} diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp index 6e1c82bb24..6c0b70edd2 100644 --- a/indra/test/lltemplatemessagebuilder_tut.cpp +++ b/indra/test/lltemplatemessagebuilder_tut.cpp @@ -937,7 +937,7 @@ namespace tut  		// build message with single block  		LLMessageTemplate messageTemplate = defaultTemplate();  		messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE)); -		U32 outValue, outValue2, inValue = 0xbbbbbbbb; +		U32 outValue, inValue = 0xbbbbbbbb;  		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);  		builder->addU32(_PREHASH_Test0, inValue);  		const U32 bufferSize = 1024; @@ -962,7 +962,6 @@ namespace tut  		memset(buffer, 0xcc, bufferSize);  		reader->getString(_PREHASH_Test1, _PREHASH_Test0, bufferSize,   						  outBuffer); -		outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1);  		ensure_equals("Ensure present value ", outValue, inValue);  		ensure_equals("Ensure unchanged buffer ", strlen(outBuffer), 0);  		delete reader; diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt index 1211bb7e5a..8179be66f5 100644 --- a/indra/test_apps/llplugintest/CMakeLists.txt +++ b/indra/test_apps/llplugintest/CMakeLists.txt @@ -2,7 +2,7 @@  project(llplugintest)  include(00-Common) -include(FindOpenGL) +include(OpenGL)  include(LLCommon)  include(LLPlugin)  include(Linking) @@ -25,6 +25,9 @@ include_directories(      ${LLRENDER_INCLUDE_DIRS}      ${LLWINDOW_INCLUDE_DIRS}  ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  if (DARWIN)      include(CMakeFindFrameworks) diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt index 7720619df3..658f167c2e 100644 --- a/indra/viewer_components/login/CMakeLists.txt +++ b/indra/viewer_components/login/CMakeLists.txt @@ -15,6 +15,10 @@ include_directories(      ${LLMATH_INCLUDE_DIRS}      ${LLXML_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(login_SOURCE_FILES      lllogin.cpp diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index ef82290b47..de7e336341 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -20,6 +20,9 @@ include_directories(      ${LLVFS_INCLUDE_DIRS}      ${CURL_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    )  set(updater_service_SOURCE_FILES      llupdaterservice.cpp diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt index 5329c89554..aa35c3b05e 100644 --- a/indra/win_crash_logger/CMakeLists.txt +++ b/indra/win_crash_logger/CMakeLists.txt @@ -21,6 +21,10 @@ include_directories(      ${LLXML_INCLUDE_DIRS}      ${LLVFS_INCLUDE_DIRS}      ) +include_directories(SYSTEM +    ${LLCOMMON_SYSTEM_INCLUDE_DIRS} +    ${LLXML_SYSTEM_INCLUDE_DIRS} +    )  set(win_crash_logger_SOURCE_FILES      win_crash_logger.cpp  | 
