diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 6a6f7c222..efffa89b0 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -54,6 +54,11 @@ if (WINDOWS) # Remove default /Zm1000 flag that cmake inserts string (REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + if (MSVC11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zm140") + endif (MSVC11) + + # Don't build DLLs. set(BUILD_SHARED_LIBS OFF) @@ -246,30 +251,28 @@ endif (LINUX) if (DARWIN) - add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE) - set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first") + add_definitions(-DLL_DARWIN=1) + 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}") - - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch") - # NOTE: it's critical that the optimization flag is put in front. - # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered. - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}") - elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - # NOTE: it's critical that the optimization flag is put in front. - # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered. - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3") - endif() + set(DARWIN_extra_cstar_flags "-g") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags} -ftemplate-depth=256") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DARWIN_extra_cstar_flags}") + # NOTE: it's critical that the optimization flag is put in front. + # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered. + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_C_FLAGS_RELWITHDEBINFO}") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS SSE3) + set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL -O3) + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -msse3 ${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_C_FLAGS_RELEASE "-O3 -msse3 ${CMAKE_C_FLAGS_RELEASE}") + if (XCODE_VERSION GREATER 4.2) + set(ENABLE_SIGNING TRUE) + set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.") + endif (XCODE_VERSION GREATER 4.2) endif (DARWIN) + if (LINUX OR DARWIN) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") add_definitions(-DLL_GNUC=1) @@ -277,13 +280,11 @@ if (LINUX OR DARWIN) set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor -Woverloaded-virtual") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_definitions(-DLL_CLANG=1) - set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-tautological-compare -Wno-char-subscripts -Wno-gnu -Wno-logical-op-parentheses -Wno-non-virtual-dtor") - set(UNIX_WARNINGS "${UNIX_WARNINGS} -Woverloaded-virtual -Wno-parentheses-equality -Wno-reorder -Wno-unused-function -Wno-unused-value -Wno-unused-variable") + set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-tautological-compare -Wno-char-subscripts -Wno-gnu -Wno-logical-op-parentheses -Wno-logical-not-parentheses -Wno-non-virtual-dtor -Wno-deprecated") + set(UNIX_WARNINGS "${UNIX_WARNINGS} -Woverloaded-virtual -Wno-parentheses-equality -Wno-reorder -Wno-unused-function -Wno-unused-value -Wno-unused-variable -Wno-unused-private-field -Wno-parentheses") set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS}") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") add_definitions(-DLL_ICC=1) - set(UNIX_WARNINGS "-wd327 -wd597 -wd858") - set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS}") endif () if (NOT DISABLE_FATAL_WARNINGS) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 5848b8934..a8df1d307 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -97,24 +97,54 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(DARWIN 1) - if(${CMAKE_GENERATOR} MATCHES "Xcode") - #SDK Compiler and Deployment targets for XCode - if (${XCODE_VERSION} VERSION_LESS 4.0.0) - set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk) - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5) - else (${XCODE_VERSION} VERSION_LESS 4.0.0) - set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk) - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) - endif (${XCODE_VERSION} VERSION_LESS 4.0.0) - else(${CMAKE_GENERATOR} MATCHES "Xcode") - set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk) - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) - endif(${CMAKE_GENERATOR} MATCHES "Xcode") + execute_process( + COMMAND sh -c "xcodebuild -version | grep Xcode | cut -d ' ' -f2 | cut -d'.' -f1-2" + OUTPUT_VARIABLE XCODE_VERSION ) + string(REGEX REPLACE "(\r?\n)+$" "" XCODE_VERSION "${XCODE_VERSION}") + +# # To support a different SDK update these Xcode settings: +# if (XCODE_VERSION GREATER 4.9) # (Which would be 5.0+) +# set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8) +# set(CMAKE_OSX_SYSROOT macosx10.9) +# else (XCODE_VERION GREATER 4.9) +# if (XCODE_VERSION GREATER 4.5) +# set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7) +# set(CMAKE_OSX_SYSROOT macosx10.8) +# else (XCODE_VERSION GREATER 4.5) +# if (XCODE_VERSION GREATER 4.2) +# set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) +# set(CMAKE_OSX_SYSROOT macosx10.7) +# else (XCODE_VERSION GREATER 4.2) +# set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) +# set(CMAKE_OSX_SYSROOT macosx10.7) +# endif (XCODE_VERSION GREATER 4.2) +# endif (XCODE_VERSION GREATER 4.5) +# endif (XCODE_VERSION GREATER 4.9) - set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42") + # Hardcode SDK we build against until we can test and allow newer ones + # as autodetected in the code above + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) + set(CMAKE_OSX_SYSROOT macosx10.6) + + # Support for Unix Makefiles generator + if (CMAKE_GENERATOR STREQUAL "Unix Makefiles") + execute_process(COMMAND xcodebuild -version -sdk "${CMAKE_OSX_SYSROOT}" Path | head -n 1 OUTPUT_VARIABLE CMAKE_OSX_SYSROOT) + string(REGEX REPLACE "(\r?\n)+$" "" CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT}") + endif (CMAKE_GENERATOR STREQUAL "Unix Makefiles") + + # LLVM-GCC has been removed in Xcode5 + if (XCODE_VERSION GREATER 4.9) + set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0") + else (XCODE_VERSION GREATER 4.9) + set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42") + endif (XCODE_VERSION GREATER 4.9) set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym) + message(STATUS "Xcode version: ${XCODE_VERSION}") + message(STATUS "OSX sysroot: ${CMAKE_OSX_SYSROOT}") + message(STATUS "OSX deployment target: ${CMAKE_OSX_DEPLOYMENT_TARGET}") + # Build only for i386 by default, system default on MacOSX 10.6 is x86_64 set(CMAKE_OSX_ARCHITECTURES i386) set(ARCH i386) diff --git a/indra/cwdebug/debug.h b/indra/cwdebug/debug.h index 3c59db690..58e0c6ac9 100644 --- a/indra/cwdebug/debug.h +++ b/indra/cwdebug/debug.h @@ -392,6 +392,40 @@ void InstanceTracker::dump(void) } // namespace debug +template +class AIDebugInstanceCounter +{ + public: + static int sInstanceCount; + + protected: + static void print_count(char const* name, int count, bool destruction); + + AIDebugInstanceCounter() + { + print_count(typeid(T).name(), ++sInstanceCount, false); + } + AIDebugInstanceCounter(AIDebugInstanceCounter const&) + { + print_count(typeid(T).name(), ++sInstanceCount, false); + } + ~AIDebugInstanceCounter() + { + print_count(typeid(T).name(), --sInstanceCount, true); + } +}; + +//static +template +int AIDebugInstanceCounter::sInstanceCount; + +//static +template +void AIDebugInstanceCounter::print_count(char const* name, int count, bool destruction) +{ + Dout(dc::notice, (destruction ? "Destructed " : "Constructing ") << name << ", now " << count << " instance" << ((count == 1) ? "." : "s.")); +} + //! Debugging macro. // // Print "Entering " << \a data to channel \a cntrl and increment diff --git a/indra/develop.py b/indra/develop.py index 4e93c27e9..0c732cc02 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -694,6 +694,8 @@ class CygwinSetup(WindowsSetup): project_name=self.project_name, word_size=self.word_size, ) + if self.word_size == 64: + args["generator"] += r' Win64' #if simple: # return 'cmake %(opts)s "%(dir)s"' % args return ('cmake -G "%(generator)s" ' diff --git a/indra/libndhacd/CMakeLists.txt b/indra/libndhacd/CMakeLists.txt index bcc1973c0..28c4d2f9a 100644 --- a/indra/libndhacd/CMakeLists.txt +++ b/indra/libndhacd/CMakeLists.txt @@ -7,7 +7,7 @@ include(00-Common) include_directories(${LIBS_OPEN_DIR}/libhacd) set (libndhacd_SOURCE_FILES - LLConvexDecomposition.cpp + llconvexdecomposition.cpp nd_hacdConvexDecomposition.cpp nd_hacdStructs.cpp nd_hacdUtils.cpp @@ -16,12 +16,12 @@ set (libndhacd_SOURCE_FILES ) set (libndhacd_HEADER_FILES - LLConvexDecomposition.h + llconvexdecomposition.h ndConvexDecomposition.h nd_hacdConvexDecomposition.h nd_hacdStructs.h nd_StructTracer.h - LLConvexDecompositionStubImpl.h + llconvexdecompositionstubimpl.h nd_EnterExitTracer.h nd_hacdDefines.h nd_hacdUtils.h diff --git a/indra/libndhacd/LLConvexDecomposition.cpp b/indra/libndhacd/llconvexdecomposition.cpp similarity index 96% rename from indra/libndhacd/LLConvexDecomposition.cpp rename to indra/libndhacd/llconvexdecomposition.cpp index 80ec5f435..2c1948629 100644 --- a/indra/libndhacd/LLConvexDecomposition.cpp +++ b/indra/libndhacd/llconvexdecomposition.cpp @@ -1,5 +1,5 @@ /** - * @file LLConvexDecomposition.cpp + * @file llconvexdecomposition.cpp * @author falcon@lindenlab.com * @brief A stub implementation of LLConvexDecomposition interface * @@ -35,7 +35,7 @@ #include "nd_hacdConvexDecomposition.h" -#include "LLConvexDecomposition.h" +#include "llconvexdecomposition.h" /*static */bool LLConvexDecomposition::s_isInitialized = false; diff --git a/indra/libndhacd/LLConvexDecomposition.h b/indra/libndhacd/llconvexdecomposition.h similarity index 99% rename from indra/libndhacd/LLConvexDecomposition.h rename to indra/libndhacd/llconvexdecomposition.h index 2d7f5aa3a..9603c434f 100644 --- a/indra/libndhacd/LLConvexDecomposition.h +++ b/indra/libndhacd/llconvexdecomposition.h @@ -1,5 +1,5 @@ /** - * @file LLConvexDecomposition.cpp + * @file llconvexdecomposition.cpp * @brief LLConvexDecomposition interface definition * * $LicenseInfo:firstyear=2011&license=viewerlgpl$ diff --git a/indra/libndhacd/LLConvexDecompositionStubImpl.cpp b/indra/libndhacd/llconvexdecompositionstubimpl.cpp similarity index 97% rename from indra/libndhacd/LLConvexDecompositionStubImpl.cpp rename to indra/libndhacd/llconvexdecompositionstubimpl.cpp index 018143de1..d91f2ea86 100644 --- a/indra/libndhacd/LLConvexDecompositionStubImpl.cpp +++ b/indra/libndhacd/llconvexdecompositionstubimpl.cpp @@ -1,5 +1,5 @@ /** - * @file LLConvexDecompositionStubImpl.cpp + * @file llconvexdecompositionstubimpl.cpp * @author falcon@lindenlab.com * @brief A stub implementation of LLConvexDecomposition * @@ -28,7 +28,7 @@ #include #include -#include "LLConvexDecompositionStubImpl.h" +#include "llconvexdecompositionstubimpl.h" LLConvexDecomposition* LLConvexDecompositionImpl::getInstance() { diff --git a/indra/libndhacd/LLConvexDecompositionStubImpl.h b/indra/libndhacd/llconvexdecompositionstubimpl.h similarity index 97% rename from indra/libndhacd/LLConvexDecompositionStubImpl.h rename to indra/libndhacd/llconvexdecompositionstubimpl.h index 9599175ef..023bd7c23 100644 --- a/indra/libndhacd/LLConvexDecompositionStubImpl.h +++ b/indra/libndhacd/llconvexdecompositionstubimpl.h @@ -1,5 +1,5 @@ /** - * @file LLConvexDecompositionStubImpl.h + * @file llconvexdecompositionstubimpl.h * @author falcon@lindenlab.com * @brief A stub implementation of LLConvexDecomposition * @@ -29,7 +29,7 @@ #ifndef LL_CONVEX_DECOMP_UTIL_H #define LL_CONVEX_DECOMP_UTIL_H -#include "LLConvexDecomposition.h" +#include "llconvexdecomposition.h" class LLConvexDecompositionImpl : public LLConvexDecomposition { diff --git a/indra/libndhacd/nd_StructTracer.h b/indra/libndhacd/nd_StructTracer.h index 6dbe3ce3e..631bfd788 100644 --- a/indra/libndhacd/nd_StructTracer.h +++ b/indra/libndhacd/nd_StructTracer.h @@ -21,7 +21,7 @@ #include "ndConvexDecomposition.h" -#include "LLConvexDecomposition.h" +#include "llconvexdecomposition.h" #include "nd_hacdStructs.h" namespace ndStructTracer diff --git a/indra/libndhacd/nd_hacdConvexDecomposition.h b/indra/libndhacd/nd_hacdConvexDecomposition.h index e31779c65..6b7c7f952 100644 --- a/indra/libndhacd/nd_hacdConvexDecomposition.h +++ b/indra/libndhacd/nd_hacdConvexDecomposition.h @@ -19,7 +19,7 @@ #ifndef ND_HACD_CONVEXDECOMP_H #define ND_HACD_CONVEXDECOMP_H -#include "LLConvexDecomposition.h" +#include "llconvexdecomposition.h" #include #include diff --git a/indra/libndhacd/nd_hacdStructs.cpp b/indra/libndhacd/nd_hacdStructs.cpp index 4a5c9e6fb..8d3a21462 100644 --- a/indra/libndhacd/nd_hacdStructs.cpp +++ b/indra/libndhacd/nd_hacdStructs.cpp @@ -17,7 +17,6 @@ */ #include "nd_hacdStructs.h" -#include "LLConvexDecomposition.h" void DecompHull::clear() { diff --git a/indra/libndhacd/nd_hacdStructs.h b/indra/libndhacd/nd_hacdStructs.h index 5097b7428..c295fedca 100644 --- a/indra/libndhacd/nd_hacdStructs.h +++ b/indra/libndhacd/nd_hacdStructs.h @@ -21,7 +21,7 @@ #include "nd_hacdDefines.h" #include "hacdHACD.h" -#include "LLConvexDecomposition.h" +#include "llconvexdecomposition.h" #include struct LLCDHull; diff --git a/indra/libndhacd/nd_hacdUtils.h b/indra/libndhacd/nd_hacdUtils.h index e2d80e78d..8a59125ab 100644 --- a/indra/libndhacd/nd_hacdUtils.h +++ b/indra/libndhacd/nd_hacdUtils.h @@ -20,7 +20,6 @@ #define ND_HACD_UTILS_H #include "nd_hacdStructs.h" -#include "LLConvexDecomposition.h" tHACD* init( int nConcavity, int nClusters, int nMaxVerticesPerHull, double dMaxConnectDist, HACDDecoder *aData ); DecompData decompose( tHACD *aHACD ); diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index 6652333ef..8dda476d9 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -29,7 +29,6 @@ set(llcharacter_SOURCE_FILES lljointsolverrp3.cpp llkeyframefallmotion.cpp llkeyframemotion.cpp - llkeyframemotionparam.cpp llkeyframestandmotion.cpp llkeyframewalkmotion.cpp llmotion.cpp @@ -57,7 +56,6 @@ set(llcharacter_HEADER_FILES lljointstate.h llkeyframefallmotion.h llkeyframemotion.h - llkeyframemotionparam.h llkeyframestandmotion.h llkeyframewalkmotion.h llmotion.h diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 888c20cd4..12960ac01 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -136,7 +136,6 @@ LLMotion* LLCharacter::findMotion( const LLUUID &id ) //----------------------------------------------------------------------------- // createMotion() -// NOTE: Always assign the result to a LLPointer! //----------------------------------------------------------------------------- LLMotion* LLCharacter::createMotion( const LLUUID &id ) { @@ -195,11 +194,26 @@ void LLCharacter::updateMotions(e_update_t update_type) { if (update_type == HIDDEN_UPDATE) { + // + // Keep updating avatars that have at least one motion that is synchronized with a still running motion. + // This call tells the other controllers that we are in principle hidden. + // It returns false if we need to keep updating anyway. + if (!mMotionController.hidden(true)) + { + mMotionController.updateMotions(LLCharacter::NORMAL_UPDATE); + return; + } + // LLFastTimer t(FTM_UPDATE_HIDDEN_ANIMATION); mMotionController.updateMotionsMinimal(); } else { + // + // This call tells the other controllers that we are visible and that they need + // to keep updating if they are synchronized with us, even if they are hidden. + mMotionController.hidden(false); + // LLFastTimer t(FTM_UPDATE_ANIMATION); // unpause if the number of outstanding pause requests has dropped to the initial one if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1) @@ -529,3 +543,17 @@ LLAnimPauseRequest LLCharacter::requestPause() return mPauseRequest; } +void LLCharacter::requestPause(std::vector& avatar_pause_handles) +{ + mMotionController.pauseAllMotions(); + avatar_pause_handles.push_back(mPauseRequest); +} + +void LLCharacter::pauseAllSyncedCharacters(std::vector& avatar_pause_handles) +{ + // Pause this avatar. + requestPause(avatar_pause_handles); + // Also pause all avatars with synchronized motions. + mMotionController.pauseAllSyncedCharacters(avatar_pause_handles); +} + diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 2b872effa..f618b446f 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -146,6 +146,7 @@ public: // is this motion active? BOOL isMotionActive( const LLUUID& id ); + bool isMotionActive(U32 bit) const { return mMotionController.isactive(bit); } // Event handler for motion deactivation. // Called when a motion has completely stopped and has been deactivated. @@ -158,6 +159,8 @@ public: void updateMotions(e_update_t update_type); LLAnimPauseRequest requestPause(); + void requestPause(std::vector& avatar_pause_handles); + void pauseAllSyncedCharacters(std::vector& avatar_pause_handles); BOOL areAnimationsPaused() const { return mMotionController.isPaused(); } void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); } void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); } diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index c2a87d80a..d07f37779 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -49,7 +49,7 @@ S32 LLEditingMotion::sHandPosePriority = 3; // LLEditingMotion() // Class Constructor //----------------------------------------------------------------------------- -LLEditingMotion::LLEditingMotion( const LLUUID &id) : LLMotion(id) +LLEditingMotion::LLEditingMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_EDITING) { mCharacter = NULL; @@ -155,7 +155,7 @@ BOOL LLEditingMotion::onActivate() mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); - return TRUE; + return AIMaskedMotion::onActivate(); } //----------------------------------------------------------------------------- @@ -256,12 +256,4 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) return result; } -//----------------------------------------------------------------------------- -// LLEditingMotion::onDeactivate() -//----------------------------------------------------------------------------- -void LLEditingMotion::onDeactivate() -{ -} - - // End diff --git a/indra/llcharacter/lleditingmotion.h b/indra/llcharacter/lleditingmotion.h index 4a83d4b9f..bc95ff682 100644 --- a/indra/llcharacter/lleditingmotion.h +++ b/indra/llcharacter/lleditingmotion.h @@ -49,11 +49,11 @@ // class LLEditingMotion //----------------------------------------------------------------------------- class LLEditingMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLEditingMotion(const LLUUID &id); + LLEditingMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLEditingMotion(); @@ -65,7 +65,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLEditingMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLEditingMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -107,9 +107,6 @@ public: // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); - public: //------------------------------------------------------------------------- // joint states to be animated diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp index 696dba0d9..be6dbb050 100644 --- a/indra/llcharacter/llhandmotion.cpp +++ b/indra/llcharacter/llhandmotion.cpp @@ -61,7 +61,7 @@ const F32 HAND_MORPH_BLEND_TIME = 0.2f; // LLHandMotion() // Class Constructor //----------------------------------------------------------------------------- -LLHandMotion::LLHandMotion(const LLUUID &id) : LLMotion(id) +LLHandMotion::LLHandMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_HAND_MOTION) { mCharacter = NULL; mLastTime = 0.f; @@ -112,7 +112,7 @@ BOOL LLHandMotion::onActivate() mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f); mCharacter->updateVisualParams(); } - return TRUE; + return AIMaskedMotion::onActivate(); } @@ -235,14 +235,6 @@ BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask) return TRUE; } - -//----------------------------------------------------------------------------- -// LLHandMotion::onDeactivate() -//----------------------------------------------------------------------------- -void LLHandMotion::onDeactivate() -{ -} - //----------------------------------------------------------------------------- // LLHandMotion::getHandPoseName() //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llhandmotion.h b/indra/llcharacter/llhandmotion.h index dcf169662..012c3c6be 100644 --- a/indra/llcharacter/llhandmotion.h +++ b/indra/llcharacter/llhandmotion.h @@ -45,7 +45,7 @@ // class LLHandMotion //----------------------------------------------------------------------------- class LLHandMotion : - public LLMotion + public AIMaskedMotion { public: typedef enum e_hand_pose @@ -68,7 +68,7 @@ public: } eHandPose; // Constructor - LLHandMotion(const LLUUID &id); + LLHandMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLHandMotion(); @@ -80,7 +80,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLHandMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLHandMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -122,9 +122,6 @@ public: // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); - virtual BOOL canDeprecate() { return FALSE; } static std::string getHandPoseName(eHandPose pose); diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 0ee378f3b..79912f9d5 100644 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -76,8 +76,8 @@ const F32 EYE_BLINK_TIME_DELTA = 0.005f; // time between one eye starting a blin // LLHeadRotMotion() // Class Constructor //----------------------------------------------------------------------------- -LLHeadRotMotion::LLHeadRotMotion(const LLUUID &id) : - LLMotion(id), +LLHeadRotMotion::LLHeadRotMotion(LLUUID const& id, LLMotionController* controller) : + AIMaskedMotion(id, controller, ANIM_AGENT_HEAD_ROT), mCharacter(NULL), mTorsoJoint(NULL), mHeadJoint(NULL) @@ -104,7 +104,10 @@ LLHeadRotMotion::~LLHeadRotMotion() LLMotion::LLMotionInitStatus LLHeadRotMotion::onInitialize(LLCharacter *character) { if (!character) + { + llwarns << "character is NULL." << llendl; return STATUS_FAILURE; + } mCharacter = character; mPelvisJoint = character->getJoint("mPelvis"); @@ -169,16 +172,6 @@ LLMotion::LLMotionInitStatus LLHeadRotMotion::onInitialize(LLCharacter *characte return STATUS_SUCCESS; } - -//----------------------------------------------------------------------------- -// LLHeadRotMotion::onActivate() -//----------------------------------------------------------------------------- -BOOL LLHeadRotMotion::onActivate() -{ - return TRUE; -} - - //----------------------------------------------------------------------------- // LLHeadRotMotion::onUpdate() //----------------------------------------------------------------------------- @@ -263,19 +256,11 @@ BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask) } -//----------------------------------------------------------------------------- -// LLHeadRotMotion::onDeactivate() -//----------------------------------------------------------------------------- -void LLHeadRotMotion::onDeactivate() -{ -} - - //----------------------------------------------------------------------------- // LLEyeMotion() // Class Constructor //----------------------------------------------------------------------------- -LLEyeMotion::LLEyeMotion(const LLUUID &id) : LLMotion(id) +LLEyeMotion::LLEyeMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_EYE) { mCharacter = NULL; mEyeJitterTime = 0.f; @@ -343,16 +328,6 @@ LLMotion::LLMotionInitStatus LLEyeMotion::onInitialize(LLCharacter *character) return STATUS_SUCCESS; } - -//----------------------------------------------------------------------------- -// LLEyeMotion::onActivate() -//----------------------------------------------------------------------------- -BOOL LLEyeMotion::onActivate() -{ - return TRUE; -} - - //----------------------------------------------------------------------------- // LLEyeMotion::onUpdate() //----------------------------------------------------------------------------- @@ -533,6 +508,8 @@ void LLEyeMotion::onDeactivate() { joint->setRotation(LLQuaternion::DEFAULT); } + + AIMaskedMotion::onDeactivate(); } // End diff --git a/indra/llcharacter/llheadrotmotion.h b/indra/llcharacter/llheadrotmotion.h index 97e61eac1..5fa4610bf 100644 --- a/indra/llcharacter/llheadrotmotion.h +++ b/indra/llcharacter/llheadrotmotion.h @@ -46,11 +46,11 @@ // class LLHeadRotMotion //----------------------------------------------------------------------------- class LLHeadRotMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLHeadRotMotion(const LLUUID &id); + LLHeadRotMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLHeadRotMotion(); @@ -62,7 +62,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLHeadRotMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLHeadRotMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -94,19 +94,11 @@ public: // must return true to indicate success and be available for activation virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); - public: //------------------------------------------------------------------------- // joint states to be animated @@ -129,11 +121,11 @@ public: // class LLEyeMotion //----------------------------------------------------------------------------- class LLEyeMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLEyeMotion(const LLUUID &id); + LLEyeMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLEyeMotion(); @@ -145,7 +137,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create( const LLUUID &id) { return new LLEyeMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLEyeMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -177,11 +169,6 @@ public: // must return true to indicate success and be available for activation virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index fe14c1e44..cb55e6ca7 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -41,7 +41,7 @@ #include "lldarray.h" const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15; -const U32 LL_CHARACTER_MAX_JOINTS = 32; // must be divisible by 4! +const U32 LL_CHARACTER_MAX_JOINTS = 32; // must be divisible by 16! const U32 LL_HAND_JOINT_NUM = 31; const U32 LL_FACE_JOINT_NUM = 30; const S32 LL_CHARACTER_MAX_PRIORITY = 7; diff --git a/indra/llcharacter/llkeyframefallmotion.cpp b/indra/llcharacter/llkeyframefallmotion.cpp index 15ad1b9e9..336d79e65 100644 --- a/indra/llcharacter/llkeyframefallmotion.cpp +++ b/indra/llcharacter/llkeyframefallmotion.cpp @@ -49,7 +49,7 @@ // LLKeyframeFallMotion() // Class Constructor //----------------------------------------------------------------------------- -LLKeyframeFallMotion::LLKeyframeFallMotion(const LLUUID &id) : LLKeyframeMotion(id) +LLKeyframeFallMotion::LLKeyframeFallMotion(LLUUID const& id, LLMotionController* controller) : LLKeyframeMotion(id, controller) { mVelocityZ = 0.f; mCharacter = NULL; diff --git a/indra/llcharacter/llkeyframefallmotion.h b/indra/llcharacter/llkeyframefallmotion.h index 495be977f..0d2553ce3 100644 --- a/indra/llcharacter/llkeyframefallmotion.h +++ b/indra/llcharacter/llkeyframefallmotion.h @@ -47,7 +47,7 @@ class LLKeyframeFallMotion : { public: // Constructor - LLKeyframeFallMotion(const LLUUID &id); + LLKeyframeFallMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLKeyframeFallMotion(); @@ -59,7 +59,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeFallMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLKeyframeFallMotion(id, controller); } public: //------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 98906d3d4..711ac21e5 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -84,38 +84,55 @@ LLKeyframeMotion::JointMotionList::~JointMotionList() for_each(mJointMotionArray.begin(), mJointMotionArray.end(), DeletePointer()); } -U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo() +//Singu: add parameter 'silent'. +U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo(bool silent) const { S32 total_size = sizeof(JointMotionList); for (U32 i = 0; i < getNumJointMotions(); i++) { - LLKeyframeMotion::JointMotion* joint_motion_p = mJointMotionArray[i]; + LLKeyframeMotion::JointMotion const* joint_motion_p = mJointMotionArray[i]; - llinfos << "\tJoint " << joint_motion_p->mJointName << llendl; + if (!silent) + { + llinfos << "\tJoint " << joint_motion_p->mJointName << llendl; + } if (joint_motion_p->mUsage & LLJointState::SCALE) { - llinfos << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at " - << joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << llendl; - + if (!silent) + { + llinfos << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at " + << joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << llendl; + } total_size += joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey); } if (joint_motion_p->mUsage & LLJointState::ROT) { - llinfos << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at " - << joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << llendl; - + if (!silent) + { + llinfos << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at " + << joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << llendl; + } total_size += joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey); } if (joint_motion_p->mUsage & LLJointState::POS) { - llinfos << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at " - << joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << llendl; - + if (!silent) + { + llinfos << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at " + << joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << llendl; + } total_size += joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey); } } - llinfos << "Size: " << total_size << " bytes" << llendl; + //Singu: Also add memory used by the constraints. + S32 constraints_size = mConstraints.size() * sizeof(constraint_list_t::value_type); + total_size += constraints_size; + if (!silent) + { + llinfos << "\t" << mConstraints.size() << " constraints at " << constraints_size << " bytes" << llendl; + llinfos << "Size: " << total_size << " bytes" << llendl; + } return total_size; } @@ -427,9 +444,8 @@ void LLKeyframeMotion::JointMotion::update(LLJointState* joint_state, F32 time, // LLKeyframeMotion() // Class Constructor //----------------------------------------------------------------------------- -LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id) - : LLMotion(id), - mJointMotionList(NULL), +LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id, LLMotionController* controller) + : LLMotion(id, controller), mPelvisp(NULL), mLastSkeletonSerialNum(0), mLastUpdateTime(0.f), @@ -452,9 +468,9 @@ LLKeyframeMotion::~LLKeyframeMotion() //----------------------------------------------------------------------------- // create() //----------------------------------------------------------------------------- -LLMotion *LLKeyframeMotion::create(const LLUUID &id) +LLMotion* LLKeyframeMotion::create(LLUUID const& id, LLMotionController* controller) { - return new LLKeyframeMotion(id); + return new LLKeyframeMotion(id, controller); } //----------------------------------------------------------------------------- @@ -517,6 +533,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact case ASSET_FETCHED: return STATUS_HOLD; case ASSET_FETCH_FAILED: + llwarns << "Trying to initialize a motion that failed to be fetched." << llendl; return STATUS_FAILURE; case ASSET_LOADED: return STATUS_SUCCESS; @@ -526,7 +543,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact break; } - LLKeyframeMotion::JointMotionList* joint_motion_list = LLKeyframeDataCache::getKeyframeData(getID()); + LLKeyframeMotion::JointMotionListPtr joint_motion_list = LLKeyframeDataCache::getKeyframeData(getID()); if(joint_motion_list) { @@ -801,7 +818,44 @@ void LLKeyframeMotion::onDeactivate() //----------------------------------------------------------------------------- // setStopTime() //----------------------------------------------------------------------------- -// time is in seconds since character creation +// +// Consider a looping animation of 20 frames, where the loop in point is at 3 frames +// and the loop out point at 16 frames: +// +// The first 3 frames of the animation would be the "loop in" animation. +// The last 4 frames of the animation would be the "loop out" animation. +// Frames 4 through 15 would be the looping animation frames. +// +// If the animation would not be looping, all frames would just be played once sequentially: +// +// mActivationTimestamp -. +// v +// 0 3 15 16 20 +// | | \| | +// --------------------- +// <--> <-- mLoopInPoint (relative to mActivationTimestamp) +// <--------------> <-- mLoopOutPoint (relative to mActivationTimestamp) +// <----mDuration------> +// +// When looping the animation would repeat frames 3 to 16 (loop) a few times, for example: +// +// 0 3 15 3 15 3 15 3 15 16 20 +// | | loop 1 \| loop 2 \| loop 3 \| loop 4 \| | +// ------------------------------------------------------------ +//LOOP^ ^ LOOP +// IN | <----->| OUT +// start_loop_time loop_fraction_time-' time +// +// The time at which the animation is started corresponds to frame 0 and is stored +// in mActivationTimestamp (in seconds since character creation). +// +// If setStopTime() is called with a time somewhere inside loop 4, +// then 'loop_fraction_time' is the time from the beginning of +// loop 4 till 'time'. Thus 'time - loop_fraction_time' is the first +// frame of loop 4, and '(time - loop_fraction_time) + +// (mJointMotionList->mDuration - mJointMotionList->mLoopInPoint)' +// would correspond to frame 20. +// void LLKeyframeMotion::setStopTime(F32 time) { LLMotion::setStopTime(time); @@ -819,6 +873,8 @@ void LLKeyframeMotion::setStopTime(F32 time) loop_fraction_time = fmod(time - start_loop_time, mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint); } + // This sets mStopTimestamp to the time that corresponds to the end of the animation (ie, frame 20 in the above example) + // minus the ease out duration, so that the animation eases out during the loop out and finishes exactly at the end. mStopTimestamp = llmax(time, (time - loop_fraction_time) + (mJointMotionList->mDuration - mJointMotionList->mLoopInPoint) - getEaseOutDuration()); } @@ -1227,13 +1283,42 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 } } +// Helper class. +template +struct AIAutoDestruct +{ + T* mPtr; + AIAutoDestruct() : mPtr(NULL) { } + ~AIAutoDestruct() { delete mPtr; } + void add(T* ptr) { mPtr = ptr; } +}; + //----------------------------------------------------------------------------- // deserialize() //----------------------------------------------------------------------------- BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) { BOOL old_version = FALSE; - mJointMotionList = new LLKeyframeMotion::JointMotionList; + + // + + // First add a new LLKeyframeMotion::JointMotionList to the cache, then assign a pointer + // to that to mJointMotionList. In LLs code the cache is never deleted again. Now it is + // is deleted when the last mJointMotionList pointer is destructed. + // + // It is possible that we get here for an already added animation, because animations can + // be requested multiple times (we get here from LLKeyframeMotion::onLoadComplete) when + // the animation was still downloading from a previous request for another LLMotionController + // object (avatar). In that case we just overwrite the old data while decoding it again. + mJointMotionList = LLKeyframeDataCache::getKeyframeData(getID()); + bool singu_new_joint_motion_list = !mJointMotionList; + if (singu_new_joint_motion_list) + { + // Create a new JointMotionList. + mJointMotionList = LLKeyframeDataCache::createKeyframeData(getID()); + } + + // //------------------------------------------------------------------------- // get base priority @@ -1396,8 +1481,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } - mJointMotionList->mJointMotionArray.clear(); - mJointMotionList->mJointMotionArray.reserve(num_motions); + if (singu_new_joint_motion_list) + { + mJointMotionList->mJointMotionArray.reserve(num_motions); + } mJointStates.clear(); mJointStates.reserve(num_motions); @@ -1407,8 +1494,19 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) for(U32 i=0; i watcher; + JointMotion* joint_motion = new JointMotion; - mJointMotionList->mJointMotionArray.push_back(joint_motion); + if (singu_new_joint_motion_list) + { + // Pass ownership to mJointMotionList. + mJointMotionList->mJointMotionArray.push_back(joint_motion); + } + else + { + // Just delete this at the end. + watcher.add(joint_motion); + } std::string joint_name; if (!dp.unpackString(joint_name, "joint_name")) @@ -1836,7 +1934,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } - mJointMotionList->mConstraints.push_front(constraintp); + AIAutoDestruct watcher; + if (singu_new_joint_motion_list) + { + mJointMotionList->mConstraints.push_front(constraintp); + } + else + { + watcher.add(constraintp); + } constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte @@ -1876,15 +1982,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (constraintp->mJointStateIndices[i] < 0 ) { llwarns << "No joint index for constraint " << i << llendl; - delete constraintp; return FALSE; } } } } - // *FIX: support cleanup of old keyframe data - LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList); mAssetStatus = ASSET_LOADED; setupPose(); @@ -2226,16 +2329,24 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, //-------------------------------------------------------------------- // LLKeyframeDataCache::dumpDiagInfo() //-------------------------------------------------------------------- -void LLKeyframeDataCache::dumpDiagInfo() +// +// quiet = 0 : print everything in detail. +// 1 : print the UUIDs of all animations in the cache and the total memory usage. +// 2 : only print the total memory usage. +// +void LLKeyframeDataCache::dumpDiagInfo(int quiet) { // keep track of totals U32 total_size = 0; char buf[1024]; /* Flawfinder: ignore */ - llinfos << "-----------------------------------------------------" << llendl; - llinfos << " Global Motion Table (DEBUG only)" << llendl; - llinfos << "-----------------------------------------------------" << llendl; + if (quiet < 2) + { + llinfos << "-----------------------------------------------------" << llendl; + llinfos << " Global Motion Table" << llendl; + llinfos << "-----------------------------------------------------" << llendl; + } // print each loaded mesh, and it's memory usage for (keyframe_data_map_t::iterator map_it = sKeyframeDataMap.begin(); @@ -2243,30 +2354,46 @@ void LLKeyframeDataCache::dumpDiagInfo() { U32 joint_motion_kb; - LLKeyframeMotion::JointMotionList *motion_list_p = map_it->second; + LLKeyframeMotion::JointMotionList const* motion_list_p = map_it->get(); - llinfos << "Motion: " << map_it->first << llendl; + if (quiet < 2) + { + llinfos << "Motion: " << map_it->key() << llendl; + } - joint_motion_kb = motion_list_p->dumpDiagInfo(); - - total_size += joint_motion_kb; + if (motion_list_p) + { + joint_motion_kb = motion_list_p->dumpDiagInfo(quiet); + total_size += joint_motion_kb; + } } - llinfos << "-----------------------------------------------------" << llendl; + if (quiet < 2) + { + llinfos << "-----------------------------------------------------" << llendl; + } llinfos << "Motions\tTotal Size" << llendl; snprintf(buf, sizeof(buf), "%d\t\t%d bytes", (S32)sKeyframeDataMap.size(), total_size ); /* Flawfinder: ignore */ llinfos << buf << llendl; - llinfos << "-----------------------------------------------------" << llendl; + if (quiet < 2) + { + llinfos << "-----------------------------------------------------" << llendl; + } } //-------------------------------------------------------------------- -// LLKeyframeDataCache::addKeyframeData() +// LLKeyframeDataCache::createKeyframeData() //-------------------------------------------------------------------- -void LLKeyframeDataCache::addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList* joint_motion_listp) +// This function replaces LLKeyframeDataCache::addKeyframeData and was rewritten to fix a memory leak (aka, the usage of AICachedPointer). +LLKeyframeMotion::JointMotionListPtr LLKeyframeDataCache::createKeyframeData(LLUUID const& id) { - sKeyframeDataMap[id] = joint_motion_listp; + std::pair result = + sKeyframeDataMap.insert(AICachedPointer(id, new LLKeyframeMotion::JointMotionList, &sKeyframeDataMap)); + llassert(result.second); // id may not already exist in the cache. + return &*result.first; // Construct and return a JointMotionListPt from a pointer to the actually inserted AICachedPointer. } +// //-------------------------------------------------------------------- // LLKeyframeDataCache::removeKeyframeData() @@ -2276,7 +2403,6 @@ void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id) keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id); if (found_data != sKeyframeDataMap.end()) { - delete found_data->second; sKeyframeDataMap.erase(found_data); } } @@ -2284,14 +2410,14 @@ void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id) //-------------------------------------------------------------------- // LLKeyframeDataCache::getKeyframeData() //-------------------------------------------------------------------- -LLKeyframeMotion::JointMotionList* LLKeyframeDataCache::getKeyframeData(const LLUUID& id) +LLKeyframeMotion::JointMotionListPtr LLKeyframeDataCache::getKeyframeData(const LLUUID& id) { keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id); if (found_data == sKeyframeDataMap.end()) { return NULL; } - return found_data->second; + return &*found_data; // Construct and return a JointMotionListPt from a pointer to the found AICachedPointer. } //-------------------------------------------------------------------- @@ -2307,7 +2433,6 @@ LLKeyframeDataCache::~LLKeyframeDataCache() //----------------------------------------------------------------------------- void LLKeyframeDataCache::clear() { - for_each(sKeyframeDataMap.begin(), sKeyframeDataMap.end(), DeletePairedPointer()); sKeyframeDataMap.clear(); } diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 50d9d0504..4c54d5500 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -5,6 +5,7 @@ * $LicenseInfo:firstyear=2001&license=viewergpl$ * * Copyright (c) 2001-2009, Linden Research, Inc. + * AICachedPointer and AICachedPointPtr copyright (c) 2013, Aleric Inglewood. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -48,10 +49,12 @@ #include "v3dmath.h" #include "v3math.h" #include "llbvhconsts.h" +#include class LLKeyframeDataCache; class LLVFS; class LLDataPacker; +class LLMotionController; #define MIN_REQUIRED_PIXEL_AREA_KEYFRAME (40.f) #define MAX_CHAIN_LENGTH (4) @@ -59,6 +62,112 @@ class LLDataPacker; const S32 KEYFRAME_MOTION_VERSION = 1; const S32 KEYFRAME_MOTION_SUBVERSION = 0; +//----------------------------------------------------------------------------- +// + +template +class AICachedPointer; + +template +void intrusive_ptr_add_ref(AICachedPointer const* p); + +template +void intrusive_ptr_release(AICachedPointer const* p); + +template +class AICachedPointer +{ + public: + typedef std::set > container_type; + + private: + KEY mKey; // The unique key. + LLPointer mData; // The actual data pointer. + container_type* mCache; // Pointer to the underlaying cache. + mutable int mRefCount; // Number of AICachedPointerPtr's pointing to this object. + + public: + // Construct a NULL pointer. This is needed when adding a new entry to a std::set, it is always first default constructed. + AICachedPointer(void) : mCache(NULL) { } + + // Copy constructor. This is needed to replace the std::set inserted instance with its actual value. + AICachedPointer(AICachedPointer const& cptr) : mKey(cptr.mKey), mData(cptr.mData), mCache(cptr.mCache), mRefCount(0) { } + + // Construct a AICachedPointer that points to 'ptr' with key 'key'. + AICachedPointer(KEY const& key, T* ptr, container_type* cache) : mKey(key), mData(ptr), mCache(cache), mRefCount(-1) { } + + // Construct a temporary NULL pointer that can be used in a search for a key. + AICachedPointer(KEY const& key) : mKey(key), mCache(NULL) { } + + // Accessors for key and data. + KEY const& key(void) const { return mKey; } + T const* get(void) const { return mData.get(); } + T* get(void) { return mData.get(); } + + // Order only by key. + friend bool operator<(AICachedPointer const& cp1, AICachedPointer const& cp2) { return cp1.mKey < cp2.mKey; } + + private: + friend void intrusive_ptr_add_ref<>(AICachedPointer const* p); + friend void intrusive_ptr_release<>(AICachedPointer const* p); + + private: + AICachedPointer& operator=(AICachedPointer const&); +}; + +template +void intrusive_ptr_add_ref(AICachedPointer const* p) +{ + llassert(p->mCache); + if (p->mCache) + { + p->mRefCount++; + } +} + +template +void intrusive_ptr_release(AICachedPointer const* p) +{ + llassert(p->mCache); + if (p->mCache) + { + if (--p->mRefCount == 0) + { + p->mCache->erase(p->mKey); + } + } +} + +template +class AICachedPointerPtr +{ + private: + boost::intrusive_ptr const> mPtr; + static int sCnt; + + public: + AICachedPointerPtr(void) { ++sCnt; } + AICachedPointerPtr(AICachedPointerPtr const& cpp) : mPtr(cpp.mPtr) { ++sCnt; } + AICachedPointerPtr(AICachedPointer const* cp) : mPtr(cp) { ++sCnt; } + ~AICachedPointerPtr() { --sCnt; } + + typedef boost::intrusive_ptr const> const AICachedPointerPtr::* const bool_type; + operator bool_type() const { return mPtr ? &AICachedPointerPtr::mPtr : NULL; } + + T const* operator->() const { return mPtr->get(); } + T* operator->() { return const_cast&>(*mPtr).get(); } + T const& operator*() const { return *mPtr->get(); } + T& operator*() { return *const_cast&>(*mPtr).get(); } + + AICachedPointerPtr& operator=(AICachedPointerPtr const& cpp) { mPtr = cpp.mPtr; return *this; } +}; + +template +int AICachedPointerPtr::sCnt; + +// +//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // class LLKeyframeMotion //----------------------------------------------------------------------------- @@ -68,7 +177,7 @@ class LLKeyframeMotion : friend class LLKeyframeDataCache; public: // Constructor - LLKeyframeMotion(const LLUUID &id); + LLKeyframeMotion(const LLUUID &id, LLMotionController* controller); // Destructor virtual ~LLKeyframeMotion(); @@ -85,7 +194,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID& id); + static LLMotion* create(LLUUID const& id, LLMotionController* controller); public: //------------------------------------------------------------------------- @@ -158,7 +267,7 @@ public: U32 getFileSize(); BOOL serialize(LLDataPacker& dp) const; BOOL deserialize(LLDataPacker& dp); - BOOL isLoaded() { return mJointMotionList != NULL; } + BOOL isLoaded() { return !!mJointMotionList; } // setters for modifying a keyframe animation @@ -393,7 +502,7 @@ public: //------------------------------------------------------------------------- // JointMotionList //------------------------------------------------------------------------- - class JointMotionList + class JointMotionList : public LLRefCount { public: std::vector mJointMotionArray; @@ -416,19 +525,22 @@ public: public: JointMotionList(); ~JointMotionList(); - U32 dumpDiagInfo(); + U32 dumpDiagInfo(bool silent = false) const; JointMotion* getJointMotion(U32 index) const { llassert(index < mJointMotionArray.size()); return mJointMotionArray[index]; } U32 getNumJointMotions() const { return mJointMotionArray.size(); } }; + // Singu: Type of a pointer to the cached pointer (in LLKeyframeDataCache::sKeyframeDataMap) to a JointMotionList object. + typedef AICachedPointerPtr JointMotionListPtr; + protected: static LLVFS* sVFS; //------------------------------------------------------------------------- // Member Data //------------------------------------------------------------------------- - JointMotionList* mJointMotionList; + JointMotionListPtr mJointMotionList; // singu: automatically clean up cache entry when destructed. std::vector > mJointStates; LLJoint* mPelvisp; LLCharacter* mCharacter; @@ -442,21 +554,24 @@ protected: class LLKeyframeDataCache { -public: - // *FIX: implement this as an actual singleton member of LLKeyframeMotion +private: + friend class LLKeyframeMotion; LLKeyframeDataCache(){}; ~LLKeyframeDataCache(); - typedef std::map keyframe_data_map_t; +public: + typedef AICachedPointer::container_type keyframe_data_map_t; // singu: add automatic cache cleanup. static keyframe_data_map_t sKeyframeDataMap; - static void addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList*); - static LLKeyframeMotion::JointMotionList* getKeyframeData(const LLUUID& id); + // + static LLKeyframeMotion::JointMotionListPtr createKeyframeData(LLUUID const& id); // id may not exist. + static LLKeyframeMotion::JointMotionListPtr getKeyframeData(LLUUID const& id); // id may or may not exists. Returns a NULL pointer when it doesn't exist. + // static void removeKeyframeData(const LLUUID& id); //print out diagnostic info - static void dumpDiagInfo(); + static void dumpDiagInfo(int quiet = 0); // singu: added param 'quiet'. static void clear(); }; diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp deleted file mode 100644 index 4df1ef46b..000000000 --- a/indra/llcharacter/llkeyframemotionparam.cpp +++ /dev/null @@ -1,456 +0,0 @@ -/** - * @file llkeyframemotionparam.cpp - * @brief Implementation of LLKeyframeMotion 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 "llkeyframemotionparam.h" -#include "llcharacter.h" -#include "llmath.h" -#include "m3math.h" -#include "lldir.h" -#include "llanimationstates.h" - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam class -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam() -// Class Constructor -//----------------------------------------------------------------------------- -LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id) -{ - mDefaultKeyframeMotion = NULL; - mCharacter = NULL; - - mEaseInDuration = 0.f; - mEaseOutDuration = 0.f; - mDuration = 0.f; - mPriority = LLJoint::LOW_PRIORITY; -} - - -//----------------------------------------------------------------------------- -// ~LLKeyframeMotionParam() -// Class Destructor -//----------------------------------------------------------------------------- -LLKeyframeMotionParam::~LLKeyframeMotionParam() -{ - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - delete paramMotion.mMotion; - } - motionList.clear(); - } - mParameterizedMotions.clear(); -} - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::onInitialize(LLCharacter *character) -//----------------------------------------------------------------------------- -LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character) -{ - mCharacter = character; - - if (!loadMotions()) - { - return STATUS_FAILURE; - } - - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - LLMotion* motion = paramMotion.mMotion; - motion->onInitialize(character); - - if (motion->getDuration() > mEaseInDuration) - { - mEaseInDuration = motion->getEaseInDuration(); - } - - if (motion->getEaseOutDuration() > mEaseOutDuration) - { - mEaseOutDuration = motion->getEaseOutDuration(); - } - - if (motion->getDuration() > mDuration) - { - mDuration = motion->getDuration(); - } - - if (motion->getPriority() > mPriority) - { - mPriority = motion->getPriority(); - } - - LLPose *pose = motion->getPose(); - - mPoseBlender.addMotion(motion); - for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) - { - LLPose *blendedPose = mPoseBlender.getBlendedPose(); - blendedPose->addJointState(jsp); - } - } - } - - return STATUS_SUCCESS; -} - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::onActivate() -//----------------------------------------------------------------------------- -BOOL LLKeyframeMotionParam::onActivate() -{ - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - paramMotion.mMotion->activate(mActivationTimestamp); - } - } - return TRUE; -} - - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::onUpdate() -//----------------------------------------------------------------------------- -BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) -{ - F32 weightFactor = 1.f / (F32)mParameterizedMotions.size(); - - // zero out all pose weights - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; -// llinfos << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << llendl; - paramMotion.mMotion->getPose()->setWeight(0.f); - } - } - - - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - const std::string& paramName = iter->first; - F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName); - if (NULL == paramValue) // unexpected, but... - { - llwarns << "paramValue == NULL" << llendl; - continue; - } - - // DANGER! Do not modify mParameterizedMotions while using these pointers! - const ParameterizedMotion* firstMotion = NULL; - const ParameterizedMotion* secondMotion = NULL; - - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - paramMotion.mMotion->onUpdate(time, joint_mask); - - F32 distToParam = paramMotion.mParam - *paramValue; - - if ( distToParam <= 0.f) - { - // keep track of the motion closest to the parameter value - firstMotion = ¶mMotion; - } - else - { - // we've passed the parameter value - // so store the first motion we find as the second one we want to blend... - if (firstMotion && !secondMotion ) - { - secondMotion = ¶mMotion; - } - //...or, if we've seen no other motion so far, make sure we blend to this only - else if (!firstMotion) - { - firstMotion = ¶mMotion; - secondMotion = ¶mMotion; - } - } - } - - LLPose *firstPose; - LLPose *secondPose; - - if (firstMotion) - firstPose = firstMotion->mMotion->getPose(); - else - firstPose = NULL; - - if (secondMotion) - secondPose = secondMotion->mMotion->getPose(); - else - secondPose = NULL; - - // now modify weight of the subanim (only if we are blending between two motions) - if (firstMotion && secondMotion) - { - if (firstMotion == secondMotion) - { - firstPose->setWeight(weightFactor); - } - else if (firstMotion->mParam == secondMotion->mParam) - { - firstPose->setWeight(0.5f * weightFactor); - secondPose->setWeight(0.5f * weightFactor); - } - else - { - F32 first_weight = 1.f - - ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) / - (secondMotion->mParam - firstMotion->mParam)); - first_weight = llclamp(first_weight, 0.f, 1.f); - - F32 second_weight = 1.f - first_weight; - - firstPose->setWeight(first_weight * weightFactor); - secondPose->setWeight(second_weight * weightFactor); - -// llinfos << "Parameter " << *paramName << ": " << *paramValue << llendl; -// llinfos << "Weights " << firstPose->getWeight() << " " << secondPose->getWeight() << llendl; - } - } - else if (firstMotion && !secondMotion) - { - firstPose->setWeight(weightFactor); - } - } - - // blend poses - mPoseBlender.blendAndApply(); - - llinfos << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << llendl; - - return TRUE; -} - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::onDeactivate() -//----------------------------------------------------------------------------- -void LLKeyframeMotionParam::onDeactivate() -{ - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - paramMotion.mMotion->onDeactivate(); - } - } -} - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::addKeyframeMotion() -//----------------------------------------------------------------------------- -BOOL LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value) -{ - LLMotion *newMotion = mCharacter->createMotion( id ); - - if (!newMotion) - { - return FALSE; - } - - newMotion->setName(name); - - // now add motion to this list - mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value)); - - return TRUE; -} - - -//----------------------------------------------------------------------------- -// LLKeyframeMotionParam::setDefaultKeyframeMotion() -//----------------------------------------------------------------------------- -void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name) -{ - for (motion_map_t::iterator iter = mParameterizedMotions.begin(); - iter != mParameterizedMotions.end(); ++iter) - { - motion_list_t& motionList = iter->second; - for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) - { - const ParameterizedMotion& paramMotion = *iter2; - if (paramMotion.mMotion->getName() == name) - { - mDefaultKeyframeMotion = paramMotion.mMotion; - } - } - } -} - -//----------------------------------------------------------------------------- -// loadMotions() -//----------------------------------------------------------------------------- -BOOL LLKeyframeMotionParam::loadMotions() -{ - //------------------------------------------------------------------------- - // Load named file by concatenating the character prefix with the motion name. - // Load data into a buffer to be parsed. - //------------------------------------------------------------------------- - //std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix()) - // + "_" + getName() + ".llp"; - //RN: deprecated unused reference to "motion" directory - std::string path; - - - //------------------------------------------------------------------------- - // open the file - //------------------------------------------------------------------------- - S32 fileSize = 0; - LLAPRFile infile(path, LL_APR_R, &fileSize); - apr_file_t* fp = infile.getFileHandle() ; - if (!fp || fileSize == 0) - { - llinfos << "ERROR: can't open: " << path << llendl; - return FALSE; - } - - // allocate a text buffer - try - { - std::vector text(fileSize+1); - - //------------------------------------------------------------------------- - // load data from file into buffer - //------------------------------------------------------------------------- - bool error = false; - char *p = &text[0]; - while ( 1 ) - { - if (apr_file_eof(fp) == APR_EOF) - { - break; - } - if (apr_file_gets(p, 1024, fp) != APR_SUCCESS) - { - error = true; - break; - } - while ( *(++p) ) - ; - } - - //------------------------------------------------------------------------- - // close the file - //------------------------------------------------------------------------- - infile.close(); - - //------------------------------------------------------------------------- - // check for error - //------------------------------------------------------------------------- - llassert( p <= (&text[0] + fileSize) ); - - if ( error ) - { - llinfos << "ERROR: error while reading from " << path << llendl; - return FALSE; - } - - llinfos << "Loading parametric keyframe data for: " << getName() << llendl; - - //------------------------------------------------------------------------- - // parse the text and build keyframe data structures - //------------------------------------------------------------------------- - p = &text[0]; - S32 num; - char strA[80]; /* Flawfinder: ignore */ - char strB[80]; /* Flawfinder: ignore */ - F32 floatA = 0.0f; - - - //------------------------------------------------------------------------- - // get priority - //------------------------------------------------------------------------- - BOOL isFirstMotion = TRUE; - num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */ - - while(1) - { - if (num == 0 || num == EOF) break; - if ((num != 3)) - { - llinfos << "WARNING: can't read parametric motion" << llendl; - return FALSE; - } - - addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA); - if (isFirstMotion) - { - isFirstMotion = FALSE; - setDefaultKeyframeMotion(strA); - } - - p = strstr(p, "\n"); - if (!p) - { - break; - } - - p++; - num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */ - } - - return TRUE; - } - catch(std::bad_alloc) - { - llinfos << "ERROR: Unable to allocate keyframe text buffer." << llendl; - return FALSE; - } -} - -// End diff --git a/indra/llcharacter/llkeyframemotionparam.h b/indra/llcharacter/llkeyframemotionparam.h deleted file mode 100644 index f74aea276..000000000 --- a/indra/llcharacter/llkeyframemotionparam.h +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @file llkeyframemotionparam.h - * @brief Implementation of LLKeframeMotionParam class. - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLKEYFRAMEMOTIONPARAM_H -#define LL_LLKEYFRAMEMOTIONPARAM_H - -//----------------------------------------------------------------------------- -// Header files -//----------------------------------------------------------------------------- - -#include - -#include "llmotion.h" -#include "lljointstate.h" -#include "v3math.h" -#include "llquaternion.h" -#include "linked_lists.h" -#include "llkeyframemotion.h" - -//----------------------------------------------------------------------------- -// class LLKeyframeMotionParam -//----------------------------------------------------------------------------- -class LLKeyframeMotionParam : - public LLMotion -{ -public: - // Constructor - LLKeyframeMotionParam(const LLUUID &id); - - // Destructor - virtual ~LLKeyframeMotionParam(); - -public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- - - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeMotionParam(id); } - -public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- - - // motions must specify whether or not they loop - virtual BOOL getLoop() { - return TRUE; - } - - // motions must report their total duration - virtual F32 getDuration() { - return mDuration; - } - - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { - return mEaseInDuration; - } - - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { - return mEaseOutDuration; - } - - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { - return mPriority; - } - - virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_KEYFRAME; } - - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character); - - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); - - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask); - - // called when a motion is deactivated - virtual void onDeactivate(); - - virtual LLPose* getPose() { return mPoseBlender.getBlendedPose();} - -protected: - //------------------------------------------------------------------------- - // new functions defined by this subclass - //------------------------------------------------------------------------- - struct ParameterizedMotion - { - ParameterizedMotion(LLMotion* motion, F32 param) : mMotion(motion), mParam(param) {} - LLMotion* mMotion; - F32 mParam; - }; - - // add a motion and associated parameter triplet - BOOL addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value); - - // set default motion for LOD and retrieving blend constants - void setDefaultKeyframeMotion(char *); - - BOOL loadMotions(); - -protected: - //------------------------------------------------------------------------- - // Member Data - //------------------------------------------------------------------------- - - struct compare_motions - { - bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const - { - if (a.mParam != b.mParam) - return (a.mParam < b.mParam); - else - return a.mMotion < b.mMotion; - } - }; - - typedef std::set < ParameterizedMotion, compare_motions > motion_list_t; - typedef std::map motion_map_t; - motion_map_t mParameterizedMotions; - LLMotion* mDefaultKeyframeMotion; - LLCharacter* mCharacter; - LLPoseBlender mPoseBlender; - - F32 mEaseInDuration; - F32 mEaseOutDuration; - F32 mDuration; - LLJoint::JointPriority mPriority; - - LLUUID mTransactionID; -}; - -#endif // LL_LLKEYFRAMEMOTIONPARAM_H diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp index 1ae0ddeea..bccc714f1 100644 --- a/indra/llcharacter/llkeyframestandmotion.cpp +++ b/indra/llcharacter/llkeyframestandmotion.cpp @@ -50,7 +50,7 @@ const F32 POSITION_THRESHOLD = 0.1f; // LLKeyframeStandMotion() // Class Constructor //----------------------------------------------------------------------------- -LLKeyframeStandMotion::LLKeyframeStandMotion(const LLUUID &id) : LLKeyframeMotion(id) +LLKeyframeStandMotion::LLKeyframeStandMotion(LLUUID const& id, LLMotionController* controller) : LLKeyframeMotion(id, controller) { mFlipFeet = FALSE; mCharacter = NULL; diff --git a/indra/llcharacter/llkeyframestandmotion.h b/indra/llcharacter/llkeyframestandmotion.h index b0500dc8e..346df97f0 100644 --- a/indra/llcharacter/llkeyframestandmotion.h +++ b/indra/llcharacter/llkeyframestandmotion.h @@ -48,7 +48,7 @@ class LLKeyframeStandMotion : { public: // Constructor - LLKeyframeStandMotion(const LLUUID &id); + LLKeyframeStandMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLKeyframeStandMotion(); @@ -60,7 +60,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeStandMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLKeyframeStandMotion(id, controller); } public: //------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp index f9c2e4766..21d6fce30 100644 --- a/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/indra/llcharacter/llkeyframewalkmotion.cpp @@ -55,8 +55,8 @@ const F32 SPEED_ADJUST_TIME_CONSTANT = 0.1f; // time constant for speed adjustm // LLKeyframeWalkMotion() // Class Constructor //----------------------------------------------------------------------------- -LLKeyframeWalkMotion::LLKeyframeWalkMotion(const LLUUID &id) -: LLKeyframeMotion(id), +LLKeyframeWalkMotion::LLKeyframeWalkMotion(LLUUID const& id, LLMotionController* controller) +: LLKeyframeMotion(id, controller), mCharacter(NULL), mCyclePhase(0.0f), mRealTimeLast(0.0f), @@ -138,8 +138,8 @@ BOOL LLKeyframeWalkMotion::onUpdate(F32 time, U8* joint_mask) // LLWalkAdjustMotion() // Class Constructor //----------------------------------------------------------------------------- -LLWalkAdjustMotion::LLWalkAdjustMotion(const LLUUID &id) : - LLMotion(id), +LLWalkAdjustMotion::LLWalkAdjustMotion(LLUUID const& id, LLMotionController* controller) : + AIMaskedMotion(id, controller, ANIM_AGENT_WALK_ADJUST), mLastTime(0.f), mAnimSpeed(0.f), mAdjustedSpeed(0.f), @@ -193,7 +193,7 @@ BOOL LLWalkAdjustMotion::onActivate() F32 rightAnkleOffset = (mRightAnkleJoint->getWorldPosition() - mCharacter->getCharacterPosition()).magVec(); mAnkleOffset = llmax(leftAnkleOffset, rightAnkleOffset); - return TRUE; + return AIMaskedMotion::onActivate(); } //----------------------------------------------------------------------------- @@ -325,13 +325,14 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask) void LLWalkAdjustMotion::onDeactivate() { mCharacter->removeAnimationData("Walk Speed"); + AIMaskedMotion::onDeactivate(); } //----------------------------------------------------------------------------- // LLFlyAdjustMotion::LLFlyAdjustMotion() //----------------------------------------------------------------------------- -LLFlyAdjustMotion::LLFlyAdjustMotion(const LLUUID &id) - : LLMotion(id), +LLFlyAdjustMotion::LLFlyAdjustMotion(LLUUID const& id, LLMotionController* controller) + : AIMaskedMotion(id, controller, ANIM_AGENT_FLY_ADJUST), mRoll(0.f) { mName = "fly_adjust"; @@ -368,7 +369,7 @@ BOOL LLFlyAdjustMotion::onActivate() mPelvisState->setPosition(LLVector3::zero); mPelvisState->setRotation(LLQuaternion::DEFAULT); mRoll = 0.f; - return TRUE; + return AIMaskedMotion::onActivate(); } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframewalkmotion.h b/indra/llcharacter/llkeyframewalkmotion.h index b507e9423..653c2b539 100644 --- a/indra/llcharacter/llkeyframewalkmotion.h +++ b/indra/llcharacter/llkeyframewalkmotion.h @@ -52,7 +52,7 @@ class LLKeyframeWalkMotion : friend class LLWalkAdjustMotion; public: // Constructor - LLKeyframeWalkMotion(const LLUUID &id); + LLKeyframeWalkMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLKeyframeWalkMotion(); @@ -64,7 +64,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeWalkMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLKeyframeWalkMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -86,11 +86,11 @@ public: S32 mDownFoot; }; -class LLWalkAdjustMotion : public LLMotion +class LLWalkAdjustMotion : public AIMaskedMotion { public: // Constructor - LLWalkAdjustMotion(const LLUUID &id); + LLWalkAdjustMotion(LLUUID const& id, LLMotionController* controller); public: //------------------------------------------------------------------------- @@ -99,7 +99,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLWalkAdjustMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLWalkAdjustMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -136,11 +136,11 @@ public: F32 mAnkleOffset; }; -class LLFlyAdjustMotion : public LLMotion +class LLFlyAdjustMotion : public AIMaskedMotion { public: // Constructor - LLFlyAdjustMotion(const LLUUID &id); + LLFlyAdjustMotion(LLUUID const& id, LLMotionController* controller); public: //------------------------------------------------------------------------- @@ -149,7 +149,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLFlyAdjustMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLFlyAdjustMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -157,7 +157,6 @@ public: //------------------------------------------------------------------------- virtual LLMotionInitStatus onInitialize(LLCharacter *character); virtual BOOL onActivate(); - virtual void onDeactivate() {}; virtual BOOL onUpdate(F32 time, U8* joint_mask); virtual LLJoint::JointPriority getPriority(){return LLJoint::HIGHER_PRIORITY;} virtual BOOL getLoop() { return TRUE; } diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp index ce926a38a..526341d20 100644 --- a/indra/llcharacter/llmotion.cpp +++ b/indra/llcharacter/llmotion.cpp @@ -37,6 +37,125 @@ #include "llmotion.h" #include "llcriticaldamp.h" +#include "llmotioncontroller.h" + +// +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// AISyncClientMotion class +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +AISyncKey* AISyncClientMotion::createSyncKey(AISyncKey const* from_key) const +{ + // The const cast is needed because getDuration() is non-const while it should have been. + AISyncClientMotion* self = const_cast(this); + // Only synchronize motions with the same duration and loop value. + return new AISyncKeyMotion(from_key, self->getDuration(), self->getLoop()); +} + +void AISyncClientMotion::aisync_loading(void) +{ + // Register the motion for (possible) synchronization: this marks the time at which is should have started. + unregister_client(); // In case it is already registered. Getting here means we are being (re)started now, we need to synchronize with other motions that start now. + register_client(); +} + +void AISyncClientMotion::aisync_loaded(void) +{ + AISyncServer* server = this->server(); + if (!server) + { + // Already expired without being synchronized (no other motion was started at the same time). + return; + } + AISyncKey const& key = server->key(); // The allocation of this is owned by server. + // There is no need to resync if there was not another motion started at the same time and the key already expired. + bool need_resync = !(server->never_synced() && key.expired()); + AISyncKey* new_key = NULL; + if (need_resync) + { + // Create a new key using the old start time. + new_key = createSyncKey(&key); + } + server->remove(this); // This resets mServer and might even delete server. + if (need_resync) + { + // Add the client to another server (based on the new key). This takes ownership of the key allocation. + AISyncServerMap::instance().register_client(this, new_key); + } +} + +F32 LLMotion::getRuntime(void) const +{ + llassert(mActive); + return mController->getAnimTime() - mActivationTimestamp; +} + +F32 LLMotion::getAnimTime(void) const +{ + return mController->getAnimTime(); +} + +F32 LLMotion::syncActivationTime(F32 time) +{ + AISyncServer* server = this->server(); + if (!server) + { + register_client(); + server = this->server(); + } + AISyncServer::client_list_t const& clients = server->getClients(); + if (clients.size() > 1) + { + // Look for the client with the smallest runtime. + AISyncClientMotion* motion_with_smallest_runtime = NULL; + F32 runtime = 1e10; + // Run over all motions in this to be synchronized group. + for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client) + { + if ((client->mReadyEvents & 2)) // Is this motion active? Motions that aren't loaded yet are not active. + { + // Currently, if event 2 is set then this is an LLMotion. + llassert(dynamic_cast(client->mClientPtr)); + AISyncClientMotion* motion = static_cast(client->mClientPtr); + // Deactivated motions should have been deregistered, certainly not have event 2 set. + llassert(static_cast(motion)->isActive()); + if (motion->getRuntime() < runtime) + { + // This is a bit fuzzy since theoretically the runtime of all active motions in the list should be the same. + // Just use the smallest value to get rid of some randomness. We might even synchronizing with ourselves + // in which case 'time' would be set to a value such that mActivationTimestamp won't change. + // In practise however, this list will contain only two clients: this, being inactive, and our partner. + runtime = motion->getRuntime(); + motion_with_smallest_runtime = motion; + } + } + } + //----------------------------------------------------------------------------------------- + // Here is where the actual synchronization takes place. + // Current we only synchronize looped motions. + if (getLoop()) + { + if (motion_with_smallest_runtime) + { + // Pretend the motion was started in the past at the same time as the other motion(s). + time = getAnimTime() - runtime; + } + } + //----------------------------------------------------------------------------------------- + } + + return time; +} + +void AISyncClientMotion::deregistered(void) +{ +#ifdef SHOW_ASSERT + mReadyEvents = 0; +#endif +} +// //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -48,10 +167,11 @@ // LLMotion() // Class Constructor //----------------------------------------------------------------------------- -LLMotion::LLMotion( const LLUUID &id ) : +LLMotion::LLMotion(LLUUID const& id, LLMotionController* controller) : mStopped(TRUE), mActive(FALSE), mID(id), + mController(controller), mActivationTimestamp(0.f), mStopTimestamp(0.f), mSendStopTimestamp(F32_MAX), @@ -147,6 +267,19 @@ void LLMotion::activate(F32 time) { mActivationTimestamp = time; mStopped = FALSE; + // + if (mController && !mController->syncing_disabled()) // Avoid being registered when syncing is disabled for this motion. + { + if (mActive) + { + // If the motion is already active then we are being restarted. + // Unregister it first (if it is registered) so that the call to ready will cause it to be registered + // and be synchronized with other motions that are started at this moment. + unregister_client(); + } + ready(6, 2 | (mController->isHidden() ? 0 : 4)); // Signal that mActivationTimestamp is set/valid (2), and that this server has a visible motion (4) (or not). + } + // mActive = TRUE; onActivate(); } @@ -159,6 +292,14 @@ void LLMotion::deactivate() mActive = FALSE; mPose.setWeight(0.f); + // + if (server()) // Only when this motion is already registered. + { + ready(6, 0); // Signal that mActivationTimestamp is no longer valid. + unregister_client(); // No longer running, so no longer a part of this sync group. + } + // + if (mDeactivateCallback) { (*mDeactivateCallback)(mDeactivateCallbackUserData); @@ -174,4 +315,19 @@ BOOL LLMotion::canDeprecate() return TRUE; } +//----------------------------------------------------------------------------- +// AIMaskedMotion +//----------------------------------------------------------------------------- + +BOOL AIMaskedMotion::onActivate() +{ + mController->activated(mMaskBit); + return TRUE; +} + +void AIMaskedMotion::onDeactivate() +{ + mController->deactivated(mMaskBit); +} + // End diff --git a/indra/llcharacter/llmotion.h b/indra/llcharacter/llmotion.h index d6628fd99..a246b08c7 100644 --- a/indra/llcharacter/llmotion.h +++ b/indra/llcharacter/llmotion.h @@ -38,16 +38,85 @@ //----------------------------------------------------------------------------- #include +#include "aisyncclient.h" #include "llerror.h" #include "llpose.h" #include "lluuid.h" class LLCharacter; +class LLMotionController; + +//----------------------------------------------------------------------------- +// class AISync* stuff +//----------------------------------------------------------------------------- + +class AISyncKeyMotion : public AISyncKey +{ + private: + F32 mDuration; + bool mLoop; + + public: + AISyncKeyMotion(AISyncKey const* from_key, F32 duration, bool loop) : AISyncKey(from_key), mDuration(duration), mLoop(loop) { } + + // Virtual functions of AISyncKey. + public: + /*virtual*/ synckeytype_t getkeytype(void) const + { + // Return a unique identifier for this class, where the low 8 bits represent the syncgroup. + return synckeytype_motion; + } + + /*virtual*/ bool equals(AISyncKey const& key) const + { + switch (key.getkeytype()) + { + case synckeytype_motion: + { + // The other key is of the same type. + AISyncKeyMotion const& motion_key = static_cast(key); + return mLoop == motion_key.mLoop && is_approx_equal(mDuration, motion_key.mDuration); + } + default: + // The keys must be in the same syncgroup. + break; + } + return false; + } +}; + +class AISyncClientMotion : public AISyncClient +{ + protected: + // Make sure that clients that are destroyed are first unregistered. + // This is needed, for example, when loading fails or when excess motions are being purged. + /*virtual*/ ~AISyncClientMotion() { unregister_client(); } + + // AISyncClient events. + /*virtual*/ AISyncKey* createSyncKey(AISyncKey const* from_key = NULL) const; + /*virtual*/ void event1_ready(void) { } + /*virtual*/ void event1_not_ready(void) { } + /*virtual*/ void deregistered(void); + + protected: + // This is called when the server sent us a message that it wants us to play this animation, but we can't because it isn't fully downloaded yet. + void aisync_loading(void); + // This is called when that motion is successfully loaded and it has to be re-registered because now the duration etc is known. + void aisync_loaded(void); + + public: + // Virtual functions of AISyncClientMotion. + // These are defined by classes derived from LLMotion (which is derived from this class). + virtual BOOL getLoop() = 0; + virtual F32 getDuration() = 0; + virtual F32 getAnimTime(void) const = 0; + virtual F32 getRuntime(void) const = 0; +}; //----------------------------------------------------------------------------- // class LLMotion //----------------------------------------------------------------------------- -class LLMotion +class LLMotion : public AISyncClientMotion { friend class LLMotionController; @@ -66,7 +135,7 @@ public: }; // Constructor - LLMotion(const LLUUID &id); + LLMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLMotion(); @@ -114,7 +183,22 @@ protected: BOOL isActive() { return mActive; } public: void activate(F32 time); - + + // + // Returns the time that this motion has been running. + virtual F32 getRuntime(void) const; + + // Return the current time (in seconds since creation of the controller). + virtual F32 getAnimTime(void) const; + + // This is called when a motion is to be activated, but might need synchronization. + // It adjusts the start time to match that of other motions in the same synchronization group that were already started. + F32 syncActivationTime(F32 time); + + // Accessor. + LLMotionController* getController(void) const { return mController; } + // + public: //------------------------------------------------------------------------- // animation callbacks to be implemented by subclasses @@ -181,6 +265,9 @@ protected: //------------------------------------------------------------------------- std::string mName; // instance name assigned by motion controller LLUUID mID; + // + LLMotionController* mController; + // F32 mActivationTimestamp; // time when motion was activated F32 mStopTimestamp; // time when motion was told to stop @@ -199,9 +286,9 @@ protected: class LLTestMotion : public LLMotion { public: - LLTestMotion(const LLUUID &id) : LLMotion(id){} + LLTestMotion(LLUUID const& id, LLMotionController* controller) : LLMotion(id, controller){} ~LLTestMotion() {} - static LLMotion *create(const LLUUID& id) { return new LLTestMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLTestMotion(id, controller); } BOOL getLoop() { return FALSE; } F32 getDuration() { return 0.0f; } F32 getEaseInDuration() { return 0.0f; } @@ -223,9 +310,9 @@ public: class LLNullMotion : public LLMotion { public: - LLNullMotion(const LLUUID &id) : LLMotion(id) {} + LLNullMotion(LLUUID const& id, LLMotionController* controller) : LLMotion(id, controller) {} ~LLNullMotion() {} - static LLMotion *create(const LLUUID &id) { return new LLNullMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLNullMotion(id, controller); } // motions must specify whether or not they loop /*virtual*/ BOOL getLoop() { return TRUE; } @@ -266,5 +353,41 @@ public: // called when a motion is deactivated /*virtual*/ void onDeactivate() {} }; + + +//----------------------------------------------------------------------------- +// AIMaskedMotion +//----------------------------------------------------------------------------- + +// These motions have a bit assigned in LLMotionController::mActiveMask +// that is set and uset upon activation/deactivation. + +// This must be in the same order as ANIM_AGENT_BODY_NOISE_ID through ANIM_AGENT_WALK_ADJUST_ID in llvoavatar.cpp. +U32 const ANIM_AGENT_BODY_NOISE = 0x001; +U32 const ANIM_AGENT_BREATHE_ROT = 0x002; +U32 const ANIM_AGENT_PHYSICS_MOTION = 0x004; +U32 const ANIM_AGENT_EDITING = 0x008; +U32 const ANIM_AGENT_EYE = 0x010; +U32 const ANIM_AGENT_FLY_ADJUST = 0x020; +U32 const ANIM_AGENT_HAND_MOTION = 0x040; +U32 const ANIM_AGENT_HEAD_ROT = 0x080; +U32 const ANIM_AGENT_PELVIS_FIX = 0x100; +U32 const ANIM_AGENT_TARGET = 0x200; +U32 const ANIM_AGENT_WALK_ADJUST = 0x400; + +class AIMaskedMotion : public LLMotion +{ +private: + U32 mMaskBit; + +public: + AIMaskedMotion(LLUUID const& id, LLMotionController* controller, U32 mask_bit) : LLMotion(id, controller), mMaskBit(mask_bit) { } + + /*virtual*/ BOOL onActivate(); + /*virtual*/ void onDeactivate(); + + U32 getMaskBit(void) const { return mMaskBit; } +}; + #endif // LL_LLMOTION_H diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 35dcc1057..d12b3ddb6 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -97,7 +97,7 @@ void LLMotionRegistry::markBad( const LLUUID& id ) //----------------------------------------------------------------------------- // createMotion() //----------------------------------------------------------------------------- -LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) +LLMotion* LLMotionRegistry::createMotion(LLUUID const& id, LLMotionController* controller) { LLMotionConstructor constructor = get_if_there(mMotionTable, id, LLMotionConstructor(NULL)); LLMotion* motion = NULL; @@ -105,11 +105,11 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) if ( constructor == NULL ) { // *FIX: need to replace with a better default scheme. RN - motion = LLKeyframeMotion::create(id); + motion = LLKeyframeMotion::create(id, controller); } else { - motion = constructor(id); + motion = constructor(id, controller); } return motion; @@ -126,18 +126,22 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) // Class Constructor //----------------------------------------------------------------------------- LLMotionController::LLMotionController() - : mTimeFactor(sCurrentTimeFactor), + : mIsSelf(FALSE), + mTimeFactor(sCurrentTimeFactor), mCharacter(NULL), - mAnimTime(0.f), + mActiveMask(0), + mDisableSyncing(0), + mHidden(false), + mHaveVisibleSyncedMotions(false), mPrevTimerElapsed(0.f), + mAnimTime(0.f), mLastTime(0.0f), mHasRunOnce(FALSE), mPaused(FALSE), mPauseTime(0.f), mTimeStep(0.f), mTimeStepCount(0), - mLastInterp(0.f), - mIsSelf(FALSE) + mLastInterp(0.f) { } @@ -168,7 +172,15 @@ void LLMotionController::deleteAllMotions() mLoadingMotions.clear(); mLoadedMotions.clear(); mActiveMotions.clear(); - + // + mActiveMask = 0; + for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer()); + mDeprecatedMotions.clear(); + for (motion_map_t::iterator iter = mAllMotions.begin(); iter != mAllMotions.end(); ++iter) + { + iter->second->unregister_client(); + } + // for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer()); mAllMotions.clear(); } @@ -178,26 +190,19 @@ void LLMotionController::deleteAllMotions() //----------------------------------------------------------------------------- void LLMotionController::purgeExcessMotions() { - if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) + // + // The old code attempted to remove non-active motions from mDeprecatedMotions, + // but that is nonsense: there are no motions in mDeprecatedMotions that are not active. + if (mLoadedMotions.size() <= MAX_MOTION_INSTANCES) { - // clean up deprecated motions - for (motion_set_t::iterator deprecated_motion_it = mDeprecatedMotions.begin(); - deprecated_motion_it != mDeprecatedMotions.end(); ) - { - motion_set_t::iterator cur_iter = deprecated_motion_it++; - LLMotion* cur_motionp = *cur_iter; - if (!isMotionActive(cur_motionp)) - { - // Motion is deprecated so we know it's not cannonical, - // we can safely remove the instance - removeMotionInstance(cur_motionp); // modifies mDeprecatedMotions - mDeprecatedMotions.erase(cur_iter); - } - } + // Speed up, no need to create motions_to_kill. + return; } + // std::set motions_to_kill; - if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) + + if (1) // Singu: leave indentation alone... { // too many motions active this frame, kill all blenders mPoseBlender.clearBlenders(); @@ -308,24 +313,44 @@ BOOL LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor c void LLMotionController::removeMotion( const LLUUID& id) { LLMotion* motionp = findMotion(id); - mAllMotions.erase(id); - removeMotionInstance(motionp); + // + // If a motion is erased from mAllMotions, it must be deleted. + if (motionp) + { + mAllMotions.erase(id); + removeMotionInstance(motionp); + delete motionp; + } + // } // removes instance of a motion from all runtime structures, but does // not erase entry by ID, as this could be a duplicate instance -// use removeMotion(id) to remove all references to a given motion by id. +// use removeMotion(id) to remove a reference to a given motion by id +// (that will not remove (active) deprecated motions). void LLMotionController::removeMotionInstance(LLMotion* motionp) { if (motionp) { llassert(findMotion(motionp->getID()) != motionp); - if (motionp->isActive()) - motionp->deactivate(); mLoadingMotions.erase(motionp); mLoadedMotions.erase(motionp); mActiveMotions.remove(motionp); - delete motionp; + // + // Deactivation moved here. Only delete motionp when it is being removed from mDeprecatedMotions. + if (motionp->isActive()) + { + motionp->deactivate(); + // If a motion is deactivated, it must be removed from mDeprecatedMotions if there. + motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp); + if (found_it != mDeprecatedMotions.end()) + { + mDeprecatedMotions.erase(found_it); + // If a motion is erased from mDeprecatedMotions, it must be deleted. + delete motionp; + } + } + // } } @@ -341,7 +366,7 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id ) if (!motion) { // look up constructor and create it - motion = sRegistry.createMotion(id); + motion = sRegistry.createMotion(id, this); if (!motion) { return NULL; @@ -393,6 +418,7 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) if (motion && !mPaused && motion->canDeprecate() + && motion->isActive() // singu: do not deprecate motions that are not active. && motion->getFadeWeight() > 0.01f // not LOD-ed out && (motion->isBlending() || motion->getStopTime() != 0.f)) { @@ -418,7 +444,19 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) } // llinfos << "Starting motion " << name << llendl; - return activateMotionInstance(motion, mAnimTime - start_offset); + // + F32 start_time = mAnimTime - start_offset; + if (!mDisableSyncing) + { + start_time = motion->syncActivationTime(start_time); + } + ++mDisableSyncing; + // + BOOL res = activateMotionInstance(motion, start_time); + // + --mDisableSyncing; + // + return res; } @@ -774,7 +812,19 @@ void LLMotionController::updateLoadingMotions() // this motion should be playing if (!motionp->isStopped()) { - activateMotionInstance(motionp, mAnimTime); + // + F32 start_time = mAnimTime; + if (!mDisableSyncing) + { + motionp->aisync_loaded(); + start_time = motionp->syncActivationTime(start_time); + } + ++mDisableSyncing; + // + activateMotionInstance(motionp, start_time); + // + --mDisableSyncing; + // } } else if (status == LLMotion::STATUS_FAILURE) @@ -782,12 +832,15 @@ void LLMotionController::updateLoadingMotions() llinfos << "Motion " << motionp->getID() << " init failed." << llendl; sRegistry.markBad(motionp->getID()); mLoadingMotions.erase(curiter); - motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp); - if (found_it != mDeprecatedMotions.end()) - { - mDeprecatedMotions.erase(found_it); - } + // Singu note: a motion in mLoadingMotions will not be in mActiveMotions + // and therefore not be in mDeprecatedMotions. So, we don't have to + // check for it's existence there. + llassert(mDeprecatedMotions.find(motionp) == mDeprecatedMotions.end()); mAllMotions.erase(motionp->getID()); + // + // Make sure we're not registered anymore. + motionp->unregister_client(); + // delete motionp; } } @@ -821,8 +874,15 @@ void LLMotionController::updateMotions(bool force_update) { F32 time_interval = fmodf(update_time, mTimeStep); - // always animate *ahead* of actual time - S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1; + // + // This old code is nonsense. + //S32 quantum_count = llmax(0, llround((update_time - time_interval) / mTimeStep)) + 1; + // (update_time - time_interval) / mTimeStep is an integer! We need llround to get rid of floating point errors, not llfloor. + // Moreover, just rounding off to the nearest integer with llround(update_time / mTimeStep) makes a lot more sense: + // it is the best we can do to get as close to what we should draw as possible. + // However, mAnimTime may only be incremented; therefore make sure of that with the llmax. + S32 quantum_count = llmax(llround(update_time / mTimeStep), llceil(mAnimTime / mTimeStep)); + // if (quantum_count == mTimeStepCount) { // we're still in same time quantum as before, so just interpolate and exit @@ -848,7 +908,8 @@ void LLMotionController::updateMotions(bool force_update) } else { - mAnimTime = update_time; + // Singu note: mAnimTime may never be set back in time. + mAnimTime = llmax(mAnimTime, update_time); } } @@ -915,6 +976,12 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) if (mLoadingMotions.find(motion) != mLoadingMotions.end()) { + // + if (!syncing_disabled()) + { + motion->aisync_loading(); + } + // // we want to start this motion, but we can't yet, so flag it as started motion->setStopped(FALSE); // report pending animations as activated @@ -970,18 +1037,16 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) //----------------------------------------------------------------------------- BOOL LLMotionController::deactivateMotionInstance(LLMotion *motion) { - motion->deactivate(); - motion_set_t::iterator found_it = mDeprecatedMotions.find(motion); if (found_it != mDeprecatedMotions.end()) { // deprecated motions need to be completely excised - removeMotionInstance(motion); - mDeprecatedMotions.erase(found_it); + removeMotionInstance(motion); // singu note: this deactivates motion and removes it from mDeprecatedMotions. } else { // for motions that we are keeping, simply remove from active queue + motion->deactivate(); // singu note: moved here from the top of the function. mActiveMotions.remove(motion); } @@ -1049,11 +1114,26 @@ void LLMotionController::dumpMotions() state_string += std::string("L"); if (std::find(mActiveMotions.begin(), mActiveMotions.end(), motion)!=mActiveMotions.end()) state_string += std::string("A"); - if (mDeprecatedMotions.find(motion) != mDeprecatedMotions.end()) - state_string += std::string("D"); + llassert(mDeprecatedMotions.find(motion) == mDeprecatedMotions.end()); // singu: it's impossible that a motion is in mAllMotions and mDeprecatedMotions at the same time. llinfos << gAnimLibrary.animationName(id) << " " << state_string << llendl; - } + // + // Also dump the deprecated motions. + for (motion_set_t::iterator iter = mDeprecatedMotions.begin(); + iter != mDeprecatedMotions.end(); ++iter) + { + std::string state_string; + LLMotion* motion = *iter; + LLUUID id = motion->getID(); + llassert(mLoadingMotions.find(motion) == mLoadingMotions.end()); + if (mLoadedMotions.find(motion) != mLoadedMotions.end()) + state_string += std::string("L"); + if (std::find(mActiveMotions.begin(), mActiveMotions.end(), motion)!=mActiveMotions.end()) + state_string += std::string("A"); + state_string += "D"; + llinfos << gAnimLibrary.animationName(id) << " " << state_string << llendl; + } + // } //----------------------------------------------------------------------------- @@ -1061,11 +1141,11 @@ void LLMotionController::dumpMotions() //----------------------------------------------------------------------------- void LLMotionController::deactivateAllMotions() { - for (motion_map_t::iterator iter = mAllMotions.begin(); - iter != mAllMotions.end(); iter++) + // Singu note: this must run over mActiveMotions: other motions are not active, + // and running over mAllMotions will miss the ones in mDeprecatedMotions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end();) { - LLMotion* motionp = iter->second; - deactivateMotionInstance(motionp); + deactivateMotionInstance(*iter++); // This might invalidate iter by erasing it from mActiveMotions. } } @@ -1086,8 +1166,7 @@ void LLMotionController::flushAllMotions() active_motions.push_back(std::make_pair(motionp->getID(),dtime)); motionp->deactivate(); // don't call deactivateMotionInstance() because we are going to reactivate it } - mActiveMotions.clear(); - + // delete all motion instances deleteAllMotions(); @@ -1096,13 +1175,136 @@ void LLMotionController::flushAllMotions() mCharacter->removeAnimationData("Hand Pose"); // restart motions + // + // Because we called motionp->deactivate() above, instead of deactivateMotionInstance(), + // prevent calling AISyncClientMotion::activateInstance in startMotion below. + disable_syncing(); + // for (std::vector >::iterator iter = active_motions.begin(); iter != active_motions.end(); ++iter) { startMotion(iter->first, iter->second); } + // + enable_syncing(); + // } +// +//----------------------------------------------------------------------------- +// toggle_hidden() +//----------------------------------------------------------------------------- +void LLMotionController::toggle_hidden(void) +{ + mHaveVisibleSyncedMotions = mHidden; // Default is false if we just became invisible (otherwise this value isn't used). + mHidden = !mHidden; + synceventset_t const visible = mHidden ? 0 : 4; + + // Run over all motions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) + { + LLMotion* motionp = *iter; + AISyncServer* server = motionp->server(); + if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. + { + bool visible_before = server->events_with_at_least_one_client_ready() & 4; + server->ready(4, visible, motionp); // Mark that now we are visible or no longer visible. + bool visible_after = server->events_with_at_least_one_client_ready() & 4; + if (visible_after) // Are there any synchronized motions (left) that ARE visible? + { + mHaveVisibleSyncedMotions = true; + } + if (visible_before != visible_after) + { + // The group as a whole now might need to change whether or not it is animated. + AISyncServer::client_list_t const& clients = server->getClients(); + for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client) + { + LLMotion* motion = dynamic_cast(client->mClientPtr); + if (!motion) + { + continue; + } + LLMotionController* controller = motion->getController(); + if (controller == this) + { + continue; + } + if (visible_after) + { + // Us becoming visible means that all synchronized avatars need to be animated again too. + controller->setHaveVisibleSyncedMotions(); + } + else + { + // Us becoming hidden means that all synchronized avatars might stop animating. + controller->refresh_hidden(); // It is extremely unlikely, but harmless, to call this twice on the same controller. + } + } + } + } + } +} + +void LLMotionController::refresh_hidden(void) +{ + mHaveVisibleSyncedMotions = !mHidden; + + // Run over all motions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) + { + LLMotion* motionp = *iter; + AISyncServer* server = motionp->server(); + if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. + { + bool visible_after = server->events_with_at_least_one_client_ready() & 4; + if (visible_after) // Are there any synchronized motions (left) that ARE visible? + { + mHaveVisibleSyncedMotions = true; + } + } + } +} + +void LLMotionController::pauseAllSyncedCharacters(std::vector& avatar_pause_handles) +{ + // Run over all motions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) + { + LLMotion* motionp = *iter; + AISyncServer* server = motionp->server(); + if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. + { + // Run over all clients of the found servers. + AISyncServer::client_list_t const& clients = server->getClients(); + for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client) + { + LLMotion* motion = dynamic_cast(client->mClientPtr); + if (!motion) + { + continue; + } + LLMotionController* controller = motion->getController(); + if (controller == this) + { + continue; + } + controller->requestPause(avatar_pause_handles); + } + } + } +} + +void LLMotionController::requestPause(std::vector& avatar_pause_handles) +{ + if (mCharacter) + { + mCharacter->requestPause(avatar_pause_handles); + } +} + +// + //----------------------------------------------------------------------------- // pause() //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index 2de13aa36..054f1c2f9 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -51,11 +51,14 @@ // This is necessary because llcharacter.h includes this file. //----------------------------------------------------------------------------- class LLCharacter; +class LLMotionController; +class LLPauseRequestHandle; +typedef LLPointer LLAnimPauseRequest; //----------------------------------------------------------------------------- // LLMotionRegistry //----------------------------------------------------------------------------- -typedef LLMotion*(*LLMotionConstructor)(const LLUUID &id); +typedef LLMotion* (*LLMotionConstructor)(LLUUID const& id, LLMotionController*); class LLMotionRegistry { @@ -72,7 +75,7 @@ public: // creates a new instance of a named motion // returns NULL motion is not registered - LLMotion *createMotion( const LLUUID &id ); + LLMotion* createMotion(LLUUID const& id, LLMotionController* controller); // initialization of motion failed, don't try to create this motion again void markBad( const LLUUID& id ); @@ -115,7 +118,6 @@ public: // unregisters a motion with the controller // (actually just forwards call to motion registry) - // returns true if successfull void removeMotion( const LLUUID& id ); // start motion @@ -150,10 +152,20 @@ public: //Flush is a liar. void deactivateAllMotions(); + // + void activated(U32 bit) { mActiveMask |= bit; } + void deactivated(U32 bit) { mActiveMask &= ~bit; } + bool isactive(U32 bit) const { return (mActiveMask & bit) != 0; } + // + // pause and continue all motions void pauseAllMotions(); void unpauseAllMotions(); BOOL isPaused() const { return mPaused; } + // + void requestPause(std::vector& avatar_pause_handles); + void pauseAllSyncedCharacters(std::vector& avatar_pause_handles); + // void setTimeStep(F32 step); @@ -180,7 +192,10 @@ protected: // internal operations act on motion instances directly // as there can be duplicate motions per id during blending overlap void deleteAllMotions(); + // singu: LLMotion needs access to activateMotionInstance. +public: BOOL activateMotionInstance(LLMotion *motion, F32 time); +protected: BOOL deactivateMotionInstance(LLMotion *motion); void deprecateMotionInstance(LLMotion* motion); BOOL stopMotionInstance(LLMotion *motion, BOOL stop_imemdiate); @@ -205,10 +220,13 @@ protected: // Life cycle of an animation: // // Animations are instantiated and immediately put in the mAllMotions map for their entire lifetime. +// Singu note: that is not true, they are moved to mDeprecatedMotions (often) for the last part of their lifetime. // If the animations depend on any asset data, the appropriate data is fetched from the data server, // and the animation is put on the mLoadingMotions list. // Once an animations is loaded, it will be initialized and put on the mLoadedMotions list. // Any animation that is currently playing also sits in the mActiveMotions list. +// Singu note: animations are only put in mDeprecatedMotions if and while they are playing, +// therefore animations in mDeprecatedMotions will be (must be) active and in mActiveMotions. typedef std::map motion_map_t; motion_map_t mAllMotions; @@ -217,7 +235,13 @@ protected: motion_set_t mLoadedMotions; motion_list_t mActiveMotions; motion_set_t mDeprecatedMotions; - + + // + U32 mActiveMask; + int mDisableSyncing; // Set while LLMotion::onActivate (and onDeactivate) are called for this controller. + bool mHidden; // The value of the last call to hidden(). + bool mHaveVisibleSyncedMotions; // Set when we are synchronized with one or more motions of a controller that is not hidden. + // LLFrameTimer mTimer; F32 mPrevTimerElapsed; F32 mAnimTime; @@ -230,6 +254,26 @@ protected: F32 mLastInterp; U8 mJointSignature[2][LL_CHARACTER_MAX_JOINTS]; + + // +public: + // Internal administration for AISync. + void disable_syncing(void) { mDisableSyncing += 100; } + void enable_syncing(void) { mDisableSyncing -= 100; } + bool syncing_disabled(void) const { return mDisableSyncing >= 100; } + + // Accessors needed for synchronization. + F32 getAnimTime(void) const { return mAnimTime; } + bool isHidden(void) const { return mHidden; } + + // Called often. Should return false if we still need to keep updating our motions even if we're not visible. + bool hidden(bool not_visible) { if (mHidden != not_visible) toggle_hidden(); return !mHaveVisibleSyncedMotions; } + +private: + void toggle_hidden(void); + void refresh_hidden(void); + void setHaveVisibleSyncedMotions(void) { mHaveVisibleSyncedMotions = true; } + // }; //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/lltargetingmotion.cpp b/indra/llcharacter/lltargetingmotion.cpp index a330b2265..05b0fdfe8 100644 --- a/indra/llcharacter/lltargetingmotion.cpp +++ b/indra/llcharacter/lltargetingmotion.cpp @@ -52,7 +52,7 @@ const F32 TORSO_ROT_FRACTION = 0.5f; // LLTargetingMotion() // Class Constructor //----------------------------------------------------------------------------- -LLTargetingMotion::LLTargetingMotion(const LLUUID &id) : LLMotion(id) +LLTargetingMotion::LLTargetingMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_TARGET) { mCharacter = NULL; mName = "targeting"; @@ -99,14 +99,6 @@ LLMotion::LLMotionInitStatus LLTargetingMotion::onInitialize(LLCharacter *charac return STATUS_SUCCESS; } -//----------------------------------------------------------------------------- -// LLTargetingMotion::onActivate() -//----------------------------------------------------------------------------- -BOOL LLTargetingMotion::onActivate() -{ - return TRUE; -} - //----------------------------------------------------------------------------- // LLTargetingMotion::onUpdate() //----------------------------------------------------------------------------- @@ -166,12 +158,4 @@ BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask) return result; } -//----------------------------------------------------------------------------- -// LLTargetingMotion::onDeactivate() -//----------------------------------------------------------------------------- -void LLTargetingMotion::onDeactivate() -{ -} - - // End diff --git a/indra/llcharacter/lltargetingmotion.h b/indra/llcharacter/lltargetingmotion.h index 1ec9f80d6..f7b08ee69 100644 --- a/indra/llcharacter/lltargetingmotion.h +++ b/indra/llcharacter/lltargetingmotion.h @@ -48,11 +48,11 @@ // class LLTargetingMotion //----------------------------------------------------------------------------- class LLTargetingMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLTargetingMotion(const LLUUID &id); + LLTargetingMotion(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLTargetingMotion(); @@ -64,7 +64,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLTargetingMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLTargetingMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -96,19 +96,11 @@ public: // must return true to indicate success and be available for activation virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); - public: LLCharacter *mCharacter; diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 31e4fa484..121268ad6 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -20,6 +20,7 @@ set(llcommon_SOURCE_FILES aialert.cpp aifile.cpp aiframetimer.cpp + aisyncclient.cpp aithreadid.cpp imageids.cpp indra_constants.cpp @@ -59,7 +60,6 @@ set(llcommon_SOURCE_FILES llformat.cpp llframetimer.cpp llheartbeat.cpp - llindraconfigfile.cpp llinitparam.cpp llinstancetracker.cpp llliveappconfig.cpp @@ -112,6 +112,7 @@ set(llcommon_HEADER_FILES aifile.h aiframetimer.h airecursive.h + aisyncclient.h aithreadid.h aithreadsafe.h bitpack.h @@ -184,7 +185,6 @@ set(llcommon_HEADER_FILES llheartbeat.h llhttpstatuscodes.h llindexedqueue.h - llindraconfigfile.h llinitparam.h llinstancetracker.h llkeythrottle.h diff --git a/indra/llcommon/aisyncclient.cpp b/indra/llcommon/aisyncclient.cpp new file mode 100644 index 000000000..c62d88efb --- /dev/null +++ b/indra/llcommon/aisyncclient.cpp @@ -0,0 +1,698 @@ +/** + * @file aisyncclient.cpp + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 13/12/2013 + * - Initial version, written by Aleric Inglewood @ SL + */ + +/* + * AISyncClient : the base class of a client object (LLMotion) that needs to be informed + * of the state of other such objects and/or to poll a server object about the state of + * other such objects, in order to be and stay synchronized with those other objects. + * In the case of an LLMotion (animation), all clients would be started and stopped at + * the same time, as long as they are part of the same synchronization group (AISyncServer). + * + * AISyncKey: object that determines what synchronization group a client belongs to. + * When a new client is created, a new AISyncKey is created too, using information from + * the client, the current frame number and the current frame time. If two AISyncKey + * compare equal, using operator==(AISyncKey const& key1, AISyncKey const& key2), + * then the clients that created them need to be synchronized. + * + * AISyncServer: object that represents a group of clients that need to be synchronized: + * it's a wrapper around a std::list with pointers to all the clients + * that need to be synchronized. It also stores the AISyncKey of the first (oldest) client + * that was added. Clients with keys that compare equal to that will be added. + * If a client is added with a synckeytype_t that is larger then it always replaces + * the existing key however. + * + * AISyncServerMap: A wrapper around std::list > + * that stores pointers to all currently existing AISyncServer objects. New entries + * are added at the end, so the oldest key is at the front. + * + * AISyncServerMap list + - - - - - - + - - - - - - + ... The AISyncServerMap is + * | | | a list with refcounted + * V V V pointers to AISyncServers. + * AISyncClient +--> AISyncServer + * | <--- list key ---> AISyncKey Each AISyncServer is a + * DerivedClient . list of normal pointers + * . AISyncClients and one + * <--- . pointer to a AISyncKey. + * Each AISyncClient is the + * base class of a DerivedClient + * and pointers back to the + * server with a refcounted + * pointer. + * + * A new client is passed to the AISyncServerMap to be stored in a new or existing AISyncServer + * object, using the key that the client produces. A boost::intrusive_ptr member + * of the client is set to point to this server. + * + * The lifetime of the server objects is determined by the intrusive_ptr objects that + * point to it: all the clients (which have an externally determined lifetime) and one + * pointer in the AISyncServerMap. However, regularly a check is done on all servers in + * the list to find expired servers: objects with keys older than two frames and older + * than 0.1 seconds; if such a server is found and it has zero or one client, then the + * client is unregistered and the pointer (and thus the server) removed from the + * AISyncServerMap. If it has two or more clients then the entry is kept until both + * clients are removed, which therefore can only be detected in intrusive_ptr_release + * which only has access to the server object. The server then is removed from the list + * by searching through it for the pointer to the server. + */ + +#include "sys.h" +#include "aisyncclient.h" +#include +#include +#include "debug.h" + +bool operator==(AISyncKey const& key1, AISyncKey const& key2) +{ + // Test if these keys match based on time. + if (std::abs((S32)(key1.mStartFrameCount - key2.mStartFrameCount)) > 1 && + std::abs(key1.mFrameTimer.getStartTime() - key2.mFrameTimer.getStartTime()) >= sSyncKeyExpirationTime) + { + return false; + } + // Time matches, let the derived classes determine if they also match otherwise. + return key1.equals(key2); +} + +#ifdef CWDEBUG +struct SyncEventSet { + synceventset_t mBits; + SyncEventSet(synceventset_t bits) : mBits(bits) { } +}; + +std::ostream& operator<<(std::ostream& os, SyncEventSet const& ses) +{ + for (int b = sizeof(ses.mBits) * 8 - 1; b >= 0; --b) + { + int m = 1 << b; + os << ((ses.mBits & m) ? '1' : '0'); + } + return os; +} + +void print_clients(AISyncServer const* server, AISyncServer::client_list_t const& client_list) +{ + Dout(dc::notice, "Clients of server " << server << ": "); + for (AISyncServer::client_list_t::const_iterator iter = client_list.begin(); iter != client_list.end(); ++ iter) + { + llassert(iter->mClientPtr->mReadyEvents == iter->mReadyEvents); + Dout(dc::notice, "-> " << iter->mClientPtr << " : " << SyncEventSet(iter->mReadyEvents)); + } +} +#endif + +void AISyncServerMap::register_client(AISyncClient* client, AISyncKey* new_key) +{ + // client must always be a new client that has to be stored somewhere. + llassert(client->server() == NULL); + // Obviously the client can't be ready for anything when it isn't registered yet. + llassert(!client->mReadyEvents); + + // Find if a server with this key already exists. + AISyncServer* server = NULL; + for (server_list_t::iterator iter = mServers.begin(); iter != mServers.end();) + { + boost::intrusive_ptr& server_ptr = *iter++; // Immediately increment iter because the call to unregister_last_client will erase it. + AISyncKey const& server_key(server_ptr->key()); + if (server_key.is_older_than(*new_key)) // This means that the server key is expired: a new key will never match. + { + if (server_ptr->never_synced()) // This means that it contains one or zero clients and will never contain more. + { + // Get rid of this server. + server_ptr->unregister_last_client(); // This will cause the server to be deleted, and erased from mServers. + } + continue; + } + if (*new_key == server_key) + { + server = server_ptr.get(); + // mServers stores new servers in strict order of the creation time of the keys, + // so once we find a server with a key that is equal, none of the remaining servers + // will have expired if they were never synced and we're done with the loop. + // Servers that synced might have been added later, but we don't unregister + // clients from those anyway because their sync partner might still show up. + break; + } + } + + if (server) + { + // A server already exists. + // Keep the oldest key, unless this new key has a synckeytype_t that is larger! + if (new_key->getkeytype() > server->key().getkeytype()) + { + server->swapkey(new_key); + } + delete new_key; + } + else + { + // Create a new server for this client. Transfers the ownership of the key allocation to the server. + server = new AISyncServer(new_key); + // Add it to mServers, before the last server that is younger then the new key. + server_list_t::iterator where = mServers.end(); // Insert the new server before 'where', + server_list_t::iterator new_where = where; + while (where != mServers.begin()) // unless there exists a server before that + { + --new_where; + if (new_key->getCreationTime() > (*new_where)->key().getCreationTime()) // and the new key is not younger then that, + { + break; + } + where = new_where; // then insert it before that element (etc). + } + // This method causes a single call to intrusive_ptr_add_ref and none to intrusive_ptr_release. + server_ptr_t server_ptr = server; + mServers.insert(where, server_ptr_t())->swap(server_ptr); + } + + // Add the client to the server. + server->add(client); +} + +#ifdef SYNC_TESTSUITE +void AISyncServer::sanity_check(void) const +{ + synceventset_t ready_events = (synceventset_t)-1; // All clients are ready. + client_list_t::const_iterator client_iter = mClients.begin(); + while (client_iter != mClients.end()) + { + ready_events &= client_iter->mReadyEvents; + ++client_iter; + } + synceventset_t pending_events = 0; // At least one client is ready. + client_iter = mClients.begin(); + while (client_iter != mClients.end()) + { + pending_events |= client_iter->mReadyEvents; + ++client_iter; + } + llassert(ready_events == mReadyEvents); + llassert(pending_events == mPendingEvents); +} +#endif + +void AISyncServer::add(AISyncClient* client) +{ +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif + + // The client can't already be ready when it isn't even added to a server yet. + llassert(!client->mReadyEvents); + synceventset_t old_ready_events = mReadyEvents; + // A new client is not ready for anything. + mReadyEvents = 0; + // Set mSynchronized if after adding client we'll have more than 1 client (that prevents the + // server from being deleted unless all clients are actually destructed or explicitly unregistered). + if (!mSynchronized && mClients.size() > 0) + { + mSynchronized = true; + } + // Trigger the existing clients to be not-ready anymore (if we were before). + trigger(old_ready_events); + // Only then add the new client (so that it didn't get not-ready trigger). + mClients.push_back(client); + client->mServer = this; + +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif +} + +void AISyncServer::remove(AISyncClient* client) +{ +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif + + client_list_t::iterator client_iter = mClients.begin(); + synceventset_t remaining_ready_events = (synceventset_t)-1; // All clients are ready. + synceventset_t remaining_pending_events = 0; // At least one client is ready (waiting for the other clients thus). + client_list_t::iterator found_client = mClients.end(); + while (client_iter != mClients.end()) + { + if (client_iter->mClientPtr == client) + { + found_client = client_iter; + } + else + { + remaining_ready_events &= client_iter->mReadyEvents; + remaining_pending_events |= client_iter->mReadyEvents; + } + ++client_iter; + } + llassert(found_client != mClients.end()); + // This must be the same as client->mReadyEvents. + llassert(found_client->mReadyEvents == client->mReadyEvents); + mClients.erase(found_client); + synceventset_t old_ready_events = mReadyEvents; + mReadyEvents = remaining_ready_events; + mPendingEvents = remaining_pending_events; + trigger(old_ready_events); + client->mServer.reset(); + client->deregistered(); + +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif +} + +void AISyncServer::unregister_last_client(void) +{ +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif + + // This function may only be called for servers with exactly one client that was never (potentially) synchronized. + llassert(!mSynchronized && mClients.size() == 1); + AISyncClient* client = mClients.begin()->mClientPtr; + mClients.clear(); + client->mServer.reset(); + llassert(mReadyEvents == client->mReadyEvents); + llassert(mPendingEvents == mReadyEvents); + // No need to update mReadyEvents/mPendingEvents because the server is going to be deleted, + // but inform the client that is no longer has a server. + client->deregistered(); + +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif +} + +void AISyncServer::trigger(synceventset_t old_ready_events) +{ + // If event 1 changed, informat all clients about it. + if (((old_ready_events ^ mReadyEvents) & 1)) + { + for (client_list_t::iterator client_iter = mClients.begin(); client_iter != mClients.end(); ++client_iter) + { + if ((mReadyEvents & 1)) + { + client_iter->mClientPtr->event1_ready(); + } + else + { + client_iter->mClientPtr->event1_not_ready(); + } + } + } +} + +void AISyncServer::ready(synceventset_t events, synceventset_t yesno, AISyncClient* client) +{ +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif + + synceventset_t added_events = events & yesno; + synceventset_t removed_events = events & ~yesno; + + // Run over all clients to find the client and calculate the current state. + synceventset_t remaining_ready_events = (synceventset_t)-1; // All clients are ready. + synceventset_t remaining_pending_events = 0; // At least one client is ready (waiting for the other clients thus). + client_list_t::iterator found_client = mClients.end(); + for (client_list_t::iterator client_iter = mClients.begin(); client_iter != mClients.end(); ++client_iter) + { + if (client_iter->mClientPtr == client) + { + found_client = client_iter; + } + else + { + remaining_ready_events &= client_iter->mReadyEvents; + remaining_pending_events |= client_iter->mReadyEvents; + } + } + + llassert(mReadyEvents == (remaining_ready_events & found_client->mReadyEvents)); + llassert(mPendingEvents == (remaining_pending_events | found_client->mReadyEvents)); + + found_client->mReadyEvents &= ~removed_events; + found_client->mReadyEvents |= added_events; +#ifdef SHOW_ASSERT + client->mReadyEvents = found_client->mReadyEvents; +#endif + + synceventset_t old_ready_events = mReadyEvents; + + mReadyEvents = remaining_ready_events & found_client->mReadyEvents; + mPendingEvents = remaining_pending_events | found_client->mReadyEvents; + + trigger(old_ready_events); + +#ifdef SYNC_TESTSUITE + sanity_check(); +#endif +} + +void intrusive_ptr_add_ref(AISyncServer* server) +{ + server->mRefCount++; +} + +void intrusive_ptr_release(AISyncServer* server) +{ + llassert(server->mRefCount > 0); + server->mRefCount--; + if (server->mRefCount == 0) + { + delete server; + } + else if (server->mRefCount == 1) + { + // If the the last pointer to this server is in the the AISyncServerMap, then delete that too. + AISyncServerMap::instance().remove_server(server); + } +} + +void AISyncServerMap::remove_server(AISyncServer* server) +{ + for (server_list_t::iterator iter = mServers.begin(); iter != mServers.end(); ++iter) + { + if (server == iter->get()) + { + mServers.erase(iter); // This causes server to be deleted too. + return; + } + } + // The server must be found: this function is only called from intrusive_ptr_release for servers + // with just a single server_ptr_t left, which must be the one in mServers (otherwise it wasn't + // even registered properly!) + llassert(false); +} + + +//============================================================================= +// SYNC_TESTSUITE +//============================================================================= + +#ifdef SYNC_TESTSUITE +#include +#include +#include +#include + +//static +U32 LLFrameTimer::sFrameCount; + +double innerloop_count = 0; + +double LLFrameTimer::getCurrentTime() +{ + return innerloop_count * 0.001; +} + +template +class TestsuiteKey : public AISyncKey +{ + private: + int mIndex; + + public: + TestsuiteKey(int index) : mIndex(index) { } + + int getIndex(void) const { return mIndex; } + + // Virtual functions of AISyncKey. + public: + /*virtual*/ synckeytype_t getkeytype(void) const + { + // Return a unique identifier for this class, where the low 8 bits represent the syncgroup. + return synckeytype; + } + + /*virtual*/ bool equals(AISyncKey const& key) const + { + synckeytype_t const theotherkey = (synckeytype_t)(synckeytype ^ 0x100); + switch (key.getkeytype()) + { + case synckeytype: + { + // The other key is of the same type. + TestsuiteKey const& test_key = static_cast const&>(key); + return (mIndex & 1) == (test_key.mIndex & 1); + } + case theotherkey: + { + TestsuiteKey const& test_key = static_cast const&>(key); + return (mIndex & 2) == (test_key.getIndex() & 2); + } + default: + // The keys must be in the same syncgroup. + break; + } + return false; + } +}; + +template +class TestsuiteClient : public AISyncClient +{ + // AISyncClient events. + protected: + /*virtual*/ AISyncKey* createSyncKey(void) const + { + return new TestsuiteKey(mIndex); + } + + private: + int mIndex; + bool mRequestedRegistered; + synceventset_t mRequestedReady; + bool mActualReady1; + + public: + TestsuiteClient() : mIndex(-1), mRequestedRegistered(false), mRequestedReady(0), mActualReady1(false) { } + ~TestsuiteClient() { if (is_registered()) this->ready(mRequestedReady, (synceventset_t)0); } + + void setIndex(int index) { mIndex = index; } + + protected: + /*virtual*/ void event1_ready(void) + { +#ifdef DEBUG_SYNCOUTPUT + Dout(dc::notice, "Calling TestsuiteClient<" << synckeytype << ">::event1_ready() (mIndex = " << mIndex << ") of client " << this); +#endif + llassert(!mActualReady1); + mActualReady1 = true; + } + + /*virtual*/ void event1_not_ready(void) + { +#ifdef DEBUG_SYNCOUTPUT + Dout(dc::notice, "Calling TestsuiteClient<" << synckeytype << ">::event1_not_ready() (mIndex = " << mIndex << ") of client " << this); +#endif + llassert(mActualReady1); + mActualReady1 = false; + } + + // This is called when the server expired and we're the only client on it. + /*virtual*/ void deregistered(void) + { +#ifdef DEBUG_SYNCOUTPUT + DoutEntering(dc::notice, "TestsuiteClient<" << synckeytype << ">::deregistered(), with this = " << this); +#endif + mRequestedRegistered = false; + mRequestedReady = 0; + mActualReady1 = false; + this->mReadyEvents = 0; + } + + private: + bool is_registered(void) const { return this->server(); } + + public: + void change_state(unsigned long r); + bool getRequestedRegistered(void) const { return mRequestedRegistered; } + synceventset_t getRequestedReady(void) const { return mRequestedReady; } +}; + +TestsuiteClient* client1ap; +TestsuiteClient* client1bp; +TestsuiteClient* client2ap; +TestsuiteClient* client2bp; + +int const number_of_clients_per_syncgroup = 8; + +template +void TestsuiteClient::change_state(unsigned long r) +{ + bool change_registered = r & 1; + r >>= 1; + synceventset_t toggle_events = r & 15; + r >>= 4; + if (change_registered) + { + if (mRequestedRegistered && !mRequestedReady) + { + mRequestedRegistered = false; + this->unregister_client(); + } + } + else if (toggle_events) + { + mRequestedReady ^= toggle_events; + mRequestedRegistered = true; + this->ready(toggle_events, mRequestedReady & toggle_events); + } + llassert(mRequestedRegistered == is_registered()); + AISyncServer* server = this->server(); + if (mRequestedRegistered) + { + synceventset_t all_ready = synceventset_t(-1); + synceventset_t any_ready = 0; + int nr = 0; + for (int cl = 0; cl < number_of_clients_per_syncgroup; ++cl) + { + switch ((synckeytype & 0xff)) + { + case syncgroup_test1: + { + if (client1ap[cl].server() == server) + { + if (client1ap[cl].getRequestedRegistered()) + { + ++nr; + all_ready &= client1ap[cl].getRequestedReady(); + any_ready |= client1ap[cl].getRequestedReady(); + } + } + if (client1bp[cl].server() == server) + { + if (client1bp[cl].getRequestedRegistered()) + { + ++nr; + all_ready &= client1bp[cl].getRequestedReady(); + any_ready |= client1bp[cl].getRequestedReady(); + } + } + break; + } + case syncgroup_test2: + { + if (client2ap[cl].server() == server) + { + if (client2ap[cl].getRequestedRegistered()) + { + ++nr; + all_ready &= client2ap[cl].getRequestedReady(); + any_ready |= client2ap[cl].getRequestedReady(); + } + } + if (client2bp[cl].server() == server) + { + if (client2bp[cl].getRequestedRegistered()) + { + ++nr; + all_ready &= client2bp[cl].getRequestedReady(); + any_ready |= client2bp[cl].getRequestedReady(); + } + } + break; + } + } + } + llassert(nr == server->getClients().size()); + llassert(!!(all_ready & 1) == mActualReady1); + llassert(this->server()->events_with_all_clients_ready() == all_ready); + llassert(this->server()->events_with_at_least_one_client_ready() == any_ready); + llassert(nr == 0 || (any_ready & all_ready) == all_ready); + } + llassert(mRequestedReady == this->mReadyEvents); +} + +int main() +{ + Debug(libcw_do.on()); + Debug(dc::notice.on()); + Debug(libcw_do.set_ostream(&std::cout)); + Debug(list_channels_on(libcw_do)); + + unsigned short seed16v[3] = { 0x1234, 0xfedc, 0x7091 }; + + for (int k = 0;; ++k) + { + std::cout << "Loop: " << k << "; SEED: " << std::hex << seed16v[0] << ", " << seed16v[1] << ", " << seed16v[2] << std::dec << std::endl; + ++LLFrameTimer::sFrameCount; + + seed48(seed16v); + seed16v[0] = lrand48() & 0xffff; + seed16v[1] = lrand48() & 0xffff; + seed16v[2] = lrand48() & 0xffff; + + TestsuiteClient client1a[number_of_clients_per_syncgroup]; + TestsuiteClient client1b[number_of_clients_per_syncgroup]; + TestsuiteClient client2a[number_of_clients_per_syncgroup]; + TestsuiteClient client2b[number_of_clients_per_syncgroup]; + client1ap = client1a; + client1bp = client1b; + client2ap = client2a; + client2bp = client2b; + + for (int i = 0; i < number_of_clients_per_syncgroup; ++i) + { + client1a[i].setIndex(i); + client1b[i].setIndex(i); + client2a[i].setIndex(i); + client2b[i].setIndex(i); + } + + for (int j = 0; j < 1000000; ++j) + { + innerloop_count += 1; + +#ifdef DEBUG_SYNCOUTPUT + Dout(dc::notice, "Innerloop: " << j); +#endif + unsigned long r = lrand48(); + synckeytype_t keytype = (r & 1) ? ((r & 2) ? synckeytype_test1a : synckeytype_test1b) : ((r & 2) ? synckeytype_test2a : synckeytype_test2b); + r >>= 2; + int cl = (r & 255) % number_of_clients_per_syncgroup; + r >>= 8; + switch (keytype) + { + case synckeytype_test1a: + client1a[cl].change_state(r); + break; + case synckeytype_test1b: + client1b[cl].change_state(r); + break; + case synckeytype_test2a: + client2a[cl].change_state(r); + break; + case synckeytype_test2b: + client2b[cl].change_state(r); + break; + } + } + } +} + +#endif diff --git a/indra/llcommon/aisyncclient.h b/indra/llcommon/aisyncclient.h new file mode 100644 index 000000000..0f5237f99 --- /dev/null +++ b/indra/llcommon/aisyncclient.h @@ -0,0 +1,304 @@ +/** + * @file aisyncclient.h + * @brief Declaration of AISyncClient. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 12/12/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AI_SYNC_CLIENT_H +#define AI_SYNC_CLIENT_H + +#ifdef SYNC_TESTSUITE +/* + * To compile the testsuite, run: + * + * cd indra/llcommon + * g++ -O3 -DCWDEBUG -DSYNC_TESTSUITE -I. -I../cwdebug aisyncclient.cpp -lcwd + */ + +#include +#include +typedef uint32_t U32; +typedef int32_t S32; +typedef uint64_t U64; +typedef float F32; +typedef double F64; +#define LL_COMMON_API +#define SHOW_ASSERT +#define ASSERT_ONLY_COMMA(...) , __VA_ARGS__ +#define llassert assert + +struct LLFrameTimer +{ + double mStartTime; + double mExpiry; + static double getCurrentTime(void); + static U32 sFrameCount; + static U32 getFrameCount() { return sFrameCount; } + F64 getStartTime() const { return mStartTime; } + void reset(double expiration) { mStartTime = getCurrentTime(); mExpiry = mStartTime + expiration; } + bool hasExpired(void) const { return getCurrentTime() > mExpiry; } +}; + +template +struct LLSingleton +{ + static T sInstance; + static T& instance(void) { return sInstance; } +}; + +template +T LLSingleton::sInstance; + +#else // !SYNC_TESTSUITE +#include "llsingleton.h" +#include "llframetimer.h" +#endif +#include +#include + +//--------------------------------------------------------------------------------------------------------------------- +// Keys with a different syncgroup are never equal (so they are never synchronized). +enum syncgroups +{ +#ifdef SYNC_TESTSUITE + syncgroup_test1, + syncgroup_test2, +#else + syncgroup_motions, // Syncgroup used for animations. +#endif + syncgroup_size +}; + +// Each key type must return a unique identifier that exists of its syncgroup (the least significant 8 bit) plus a few bit to make it unique (bit 9 and higher). +enum synckeytype_t +{ +#ifdef SYNC_TESTSUITE + synckeytype_test1a = 0x000 + syncgroup_test1, + synckeytype_test1b = 0x100 + syncgroup_test1, + synckeytype_test2a = 0x000 + syncgroup_test2, + synckeytype_test2b = 0x100 + syncgroup_test2, +#else + synckeytype_motion = syncgroup_motions // There is currently only one key type in the syncgroup_motions group: AISyncKeyMotion. +#endif +}; + +typedef U32 synceventset_t; // A mask where each bit represents a ready state. + +static F32 const sSyncKeyExpirationTime = 0.25; // In seconds. + +class LL_COMMON_API AISyncKey +{ + private: + LLFrameTimer mFrameTimer; // This timer is started at the moment the sync key is created. + U32 mStartFrameCount; // The frame count at which the timer was started. + + public: + // Constructor. + AISyncKey(AISyncKey const* from_key) : mStartFrameCount(from_key ? from_key->mStartFrameCount : LLFrameTimer::getFrameCount()) + { + if (from_key) + { + mFrameTimer.copy(from_key->mFrameTimer); + } + else + { + mFrameTimer.reset(sSyncKeyExpirationTime); + } + } + + // Destructor. + virtual ~AISyncKey() { } + + // Return true if this key expired. + bool expired(void) const + { + // The key has expired when sSyncKeyExpirationTime seconds have elapsed AND at least two frames have passed. + return mFrameTimer.getFrameCount() > mStartFrameCount + 1 && mFrameTimer.hasExpired(); + } + + // Returns true if this object and key would not compare equal based on time because this object is too old. + bool is_older_than(AISyncKey const& key) const + { + return key.mStartFrameCount > mStartFrameCount + 1 && key.mFrameTimer.getStartTime() > mFrameTimer.getStartTime() + sSyncKeyExpirationTime; + } + + // Return the creation time of this key (in number of seconds since application start). + F64 getCreationTime(void) const { return mFrameTimer.getStartTime(); } + + // Returns true if the two keys match, meaning that they should be synchronized. + friend bool operator==(AISyncKey const& key1, AISyncKey const& key2); + + // Returns an ID that uniquely identifies the derived type. + // Currently the only derived type is AISyncKeyMotion with ID synckeytype_motion. + virtual synckeytype_t getkeytype(void) const = 0; + + // Returns true if the data in the derived objects match, meaning that they should be synchronized. + virtual bool equals(AISyncKey const& key) const = 0; +}; + +// Forward declaration. +class AISyncClient; +class AISyncServer; +LL_COMMON_API extern void intrusive_ptr_add_ref(AISyncServer* server); +LL_COMMON_API extern void intrusive_ptr_release(AISyncServer* server); + +struct LL_COMMON_API AISyncClientData +{ + AISyncClient* mClientPtr; + synceventset_t mReadyEvents; + + AISyncClientData(AISyncClient* client) : mClientPtr(client), mReadyEvents(0) { } +}; + +class LL_COMMON_API AISyncServer +{ + public: + typedef std::list client_list_t; + + private: + int mRefCount; // Number of boost::intrusive_ptr objects pointing to this object. + AISyncKey* mKey; // The key of the first client that was added. + client_list_t mClients; // A list with pointers to all registered clients. + bool mSynchronized; // Set when a server gets more than one client, and not reset anymore after that. + synceventset_t mReadyEvents; // 0xFFFFFFFF bitwise-AND-ed with all clients. + synceventset_t mPendingEvents; // The bitwise-OR of all clients. + + public: + AISyncServer(AISyncKey* key) : mRefCount(0), mKey(key), mSynchronized(false), mReadyEvents((synceventset_t)-1), mPendingEvents(0) { } + ~AISyncServer() { delete mKey; } + + // Add a new client to this server. + void add(AISyncClient* client); + + // Remove a client from this server. + void remove(AISyncClient* client); + + // Return the key associated to this server (which is the key produced by the first client of the largest synckeytype_t that was added). + AISyncKey const& key(void) const { return *mKey; } + // Replace they key with another key (of larger synckeytype_t). + void swapkey(AISyncKey*& key_ptr) { AISyncKey* tmp = key_ptr; key_ptr = mKey; mKey = tmp; } + + // Returns true if this server never had more than one client. + bool never_synced(void) const { return !mSynchronized; } + + // Set readiness of all events at once. + void ready(synceventset_t events, synceventset_t yesno, AISyncClient* client); + + // Unregister the (only) client because it's own its own and will never need synchronization. + void unregister_last_client(void); + + // Return the events that all clients for. + synceventset_t events_with_all_clients_ready(void) const { return mReadyEvents; } + + // Return events that at least one client is ready for. + synceventset_t events_with_at_least_one_client_ready(void) const { return mPendingEvents; } + + // Return a list of all registered clients. + client_list_t const& getClients(void) const { return mClients; } + + private: + // Call event1_ready() or event1_not_ready() on all clients if the least significant bit of mReadyEvents changed. + void trigger(synceventset_t old_ready_events); + +#ifdef SYNC_TESTSUITE + void sanity_check(void) const; +#endif + + private: + friend LL_COMMON_API void intrusive_ptr_add_ref(AISyncServer* server); + friend LL_COMMON_API void intrusive_ptr_release(AISyncServer* server); +}; + +class LL_COMMON_API AISyncServerMap : public LLSingleton +{ + public: + typedef boost::intrusive_ptr server_ptr_t; // The type of a (stored) pointer to the server objects. + typedef std::list server_list_t; // The type of the list with pointers to the server objects. + + private: + server_list_t mServers; // A list with pointers to all server objects. + + public: + // Find or create a server object that the client belongs to and store the client in it. + // If a new server is created, it is stored in mServers. + void register_client(AISyncClient* client, AISyncKey* new_key); + + private: + friend LL_COMMON_API void intrusive_ptr_release(AISyncServer* server); + // Remove a server from the map, only called by intrusive_ptr_release when there is one pointer left; + // therefore, the server should not have any clients. + void remove_server(AISyncServer* server); +}; + +class LL_COMMON_API AISyncClient +{ + private: + friend class AISyncServer; + boost::intrusive_ptr mServer; // The server this client was registered with, or NULL when unregistered. + + public: +#ifdef SHOW_ASSERT + synceventset_t mReadyEvents; + AISyncClient(void) : mReadyEvents(0) { } +#endif + virtual ~AISyncClient() { llassert(!mServer); /* If this fails then you need to add unregister_client() to the top of the destructor of the derived class that implements deregistered(). */ } + virtual AISyncKey* createSyncKey(AISyncKey const* from_key = NULL) const = 0; + + virtual void event1_ready(void) = 0; + virtual void event1_not_ready(void) = 0; + + // Only client. Client was forcefully deregistered from expired server because it was the only client. + virtual void deregistered(void) + { +#ifdef SHOW_ASSERT + mReadyEvents = 0; +#endif + } + + AISyncServer* server(void) const { return mServer.get(); } + + // Add this client to a server with matching sync key. Optionally the server is first created. + void register_client(void) { AISyncServerMap::instance().register_client(this, createSyncKey()); } + + // Remove this client from its server, if any. + void unregister_client(void) { if (mServer) mServer->remove(this); } + + // Call 'ready' when you are ready (or not) to get a call to start(). + // Returns true if that call was made (immediately), otherwise it may happen later. + + // Set readiness of all events at once. + void ready(synceventset_t events, synceventset_t yesno) + { + if (!mServer) + { + register_client(); + } + mServer->ready(events, yesno, this); + } +}; + +#endif diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h index 2813150c5..30bc58dd9 100644 --- a/indra/llcommon/llframetimer.h +++ b/indra/llcommon/llframetimer.h @@ -47,6 +47,10 @@ public: // Create an LLFrameTimer and start it. After creation it is running and in the state expired (hasExpired will return true). LLFrameTimer(void) : mExpiry(0), mRunning(true), mPaused(false) { if (!sGlobalMutex) global_initialization(); setAge(0.0); } + // + void copy(LLFrameTimer const& timer) { mStartTime = timer.mStartTime; mExpiry = timer.mExpiry; mRunning = timer.mRunning; mPaused = timer.mPaused; } + // + // Atomic reads of static variables. // Return the number of seconds since the start of the application. @@ -142,6 +146,9 @@ public: bool hasExpired() const { return getElapsedSeconds() >= mExpiry; } F32 getElapsedTimeF32() const { llassert(mRunning); return mPaused ? (F32)mStartTime : (F32)(getElapsedSeconds() - mStartTime); } bool getStarted() const { return mRunning; } + // + F64 getStartTime() const { llassert(!mPaused); return mStartTime; } + // // return the seconds since epoch when this timer will expire. F64 expiresAt() const; diff --git a/indra/llcommon/llindraconfigfile.cpp b/indra/llcommon/llindraconfigfile.cpp deleted file mode 100644 index f0873450f..000000000 --- a/indra/llcommon/llindraconfigfile.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @file llindraconfigfile.cpp - * - * - * This class is an LLLiveFile that has config info for indra - * Currently only whether it's blacklisted - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llindraconfigfile.h" - -#include "llfile.h" -#include "llsd.h" -#include "llsdserialize.h" -#include "llframetimer.h" - -static std::string sConfigDir = ""; -static const char indraConfigFileName[] = "indra.xml"; - - -LLIndraConfigFile::LLIndraConfigFile() - : LLLiveFile(filename()), - mConfig(LLSD()) -{ -} - -//static -void LLIndraConfigFile::initClass(const std::string& config_dir) -{ - sConfigDir = config_dir; - llinfos << "LLIndraConfigFile::initClass config dir " - << config_dir << "/" << indraConfigFileName << llendl; -} - -LLSD LLIndraConfigFile::getConfig(const std::string& config_name) -{ - if (sConfigDir.empty()) - { - llerrs << "LLIndraConfigFile::initClass() not called" << llendl; - } - - LLFrameTimer::updateFrameTime(); - - static LLIndraConfigFile the_file; - the_file.checkAndReload(); - - return the_file.mConfig[config_name]; -} - -std::string LLIndraConfigFile::filename() -{ - std::ostringstream ostr; - - ostr << sConfigDir - << "/" << indraConfigFileName; - - return ostr.str(); -} - -/* virtual */ -bool LLIndraConfigFile::loadFile() -{ - llinfos << "LLIndraConfigFile::loadFile: reading from " - << filename() << llendl; - - LLSD config; - - { - llifstream file(filename()); - if (file.is_open()) - { - LLSDSerialize::fromXML(config, file); - } - - if (config.isUndefined()) - { - llinfos << "LLIndraConfigFile::loadFile: file missing, ill-formed," - " or simply undefined; not changing the blacklist" << llendl; - return false; - } - } - - if (config.isMap()) - { - mConfig = config; - return true; - } - else - { - llwarns << "LLIndraConfigFile: " << indraConfigFileName << " expects a map; wrong format" << llendl; - return false; - } -} diff --git a/indra/llcommon/llindraconfigfile.h b/indra/llcommon/llindraconfigfile.h deleted file mode 100644 index 17eda906e..000000000 --- a/indra/llcommon/llindraconfigfile.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @file llindraconfigfile.h - * @brief manages configuration file for indra.xml - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLINDRACONFIGFILE_H -#define LL_LLINDRACONFIGFILE_H - -#include "linden_common.h" -#include - -#include "lllivefile.h" -#include "llsd.h" - - -// To use, call LLIndraConfigFile::initClass(config_dir); -// Then whenever getConfig is called, it will check and reload automatically - -class LLIndraConfigFile : public LLLiveFile -{ -public: - LLIndraConfigFile(); - static void initClass(const std::string& config_dir); - static LLSD getConfig(const std::string& config_name); - -private: - static std::string filename(); - -protected: - /* virtual */ bool loadFile(); - LLSD mConfig; -}; - -#endif //LL_LLINDRACONFIGFILE_H diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index 019750efc..b9052f12f 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -965,7 +965,6 @@ P(newAgentInventoryVariablePriceResponder); P(objectCostResponder); P(objectLinksetsResponder); P(physicsFlagsResponder); -P(placeAvatarTeleportResponder); P(productInfoRequestResponder); P(regionResponder); P(remoteParcelRequestResponder); diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 1374a1b93..bd40d8e69 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -237,13 +237,21 @@ void LLHTTPClient::request( req->run(parent, new_parent_state, parent != NULL, true, default_engine); } -void LLHTTPClient::getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) +bool LLHTTPClient::getByteRange(std::string const& url, AIHTTPHeaders& headers, S32 offset, S32 bytes, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - if(offset > 0 || bytes > 0) + try { - headers.addHeader("Range", llformat("bytes=%d-%d", offset, offset + bytes - 1)); + if (offset > 0 || bytes > 0) + { + headers.addHeader("Range", llformat("bytes=%d-%d", offset, offset + bytes - 1)); + } + request(url, HTTP_GET, NULL, responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug)); } - request(url, HTTP_GET, NULL, responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug)); + catch(AICurlNoEasyHandle const&) + { + return false; + } + return true; } void LLHTTPClient::head(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index a366811d6..3bb60b04f 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -133,6 +133,14 @@ public: public: typedef boost::shared_ptr buffer_ptr_t; + /** + * @brief return true if the status code indicates success. + */ + static bool isGoodStatus(U32 status) + { + return((200 <= status) && (status < 300)); + } + protected: ResponderBase(void); virtual ~ResponderBase(); @@ -452,9 +460,9 @@ public: static void head(std::string const& url, ResponderHeadersOnly* responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) { AIHTTPHeaders headers; head(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } - static void getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); - static void getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) - { AIHTTPHeaders headers; getByteRange(url, offset, bytes, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); } + static bool getByteRange(std::string const& url, AIHTTPHeaders& headers, S32 offset, S32 bytes, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); + static bool getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) + { AIHTTPHeaders headers; return getByteRange(url, headers, offset, bytes, responder/*,*/ DEBUG_CURLIO_PARAM(debug)); } static void get(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)); static void get(std::string const& url, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off)) diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 7312209da..3e38db897 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -28,7 +28,7 @@ #include "llmodel.h" #include "llmemory.h" -#include "LLConvexDecomposition.h" +#include "llconvexdecomposition.h" #include "llsdserialize.h" #include "llvector4a.h" #if LL_MSVC @@ -168,6 +168,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source) || !pos_source ) { + llwarns << "Could not find dom sources for basic geo data; invalid model." << llendl; return LLModel::BAD_ELEMENT; } @@ -188,27 +189,78 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa LLVolumeFace::VertexMapData::PointMap point_map; - for (U32 i = 0; i < idx.getCount(); i += idx_stride) + U32 index_count = idx.getCount(); + U32 vertex_count = pos_source ? v.getCount() : 0; + U32 tc_count = tc_source ? tc.getCount() : 0; + U32 norm_count = norm_source ? n.getCount() : 0; + + for (U32 i = 0; i < index_count; i += idx_stride) { LLVolumeFace::VertexData cv; if (pos_source) { + // guard against model data specifiying out of range indices or verts + // + if (((i + pos_offset) > index_count) + || ((idx[i+pos_offset]*3+2) > vertex_count)) + { + llwarns << "Out of range index data; invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } + cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0], v[idx[i+pos_offset]*3+1], v[idx[i+pos_offset]*3+2])); + + if (!cv.getPosition().isFinite3()) + { + llwarns << "Nan positional data, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } if (tc_source) { + // guard against model data specifiying out of range indices or tcs + // + + if (((i + tc_offset) > index_count) + || ((idx[i+tc_offset]*2+1) > tc_count)) + { + llwarns << "Out of range TC indices." << llendl; + return LLModel::BAD_ELEMENT; + } + cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0], tc[idx[i+tc_offset]*2+1]); + + if (!cv.mTexCoord.isFinite()) + { + llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } if (norm_source) { + // guard against model data specifiying out of range indices or norms + // + if (((i + norm_offset) > index_count) + || ((idx[i+norm_offset]*3+2) > norm_count)) + { + llwarns << "Found out of range norm indices, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } + cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0], n[idx[i+norm_offset]*3+1], n[idx[i+norm_offset]*3+2])); + + if (!cv.getNormal().isFinite3()) + { + llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } BOOL found = FALSE; @@ -263,7 +315,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa LLVolumeFace& new_face = *face_list.rbegin(); if (!norm_source) { - //l_aligned_free_16(new_face.mNormals); + //ll_aligned_free_16(new_face.mNormals); new_face.mNormals = NULL; } @@ -335,6 +387,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source)) { + llwarns << "Could not get DOM sources for basic geo data, invalid model." << llendl; return LLModel::BAD_ELEMENT; } @@ -366,6 +419,11 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac LLVolumeFace::VertexMapData::PointMap point_map; + U32 index_count = idx.getCount(); + U32 vertex_count = pos_source ? v.getCount() : 0; + U32 tc_count = tc_source ? tc.getCount() : 0; + U32 norm_count = norm_source ? n.getCount() : 0; + U32 cur_idx = 0; for (U32 i = 0; i < vcount.getCount(); ++i) { //for each polygon @@ -378,22 +436,68 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac if (pos_source) { + // guard against model data specifiying out of range indices or verts + // + if (((cur_idx + pos_offset) > index_count) + || ((idx[cur_idx+pos_offset]*3+2) > vertex_count)) + { + llwarns << "Out of range position indices, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } + cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0], v[idx[cur_idx+pos_offset]*3+1], v[idx[cur_idx+pos_offset]*3+2]); + + if (!cv.getPosition().isFinite3()) + { + llwarns << "Found NaN while loading positions from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } + } if (tc_source) { + // guard against model data specifiying out of range indices or tcs + // + if (((cur_idx + tc_offset) > index_count) + || ((idx[cur_idx+tc_offset]*2+1) > tc_count)) + { + llwarns << "Out of range TC indices, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } + cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0], tc[idx[cur_idx+tc_offset]*2+1]); + + if (!cv.mTexCoord.isFinite()) + { + llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } if (norm_source) { + // guard against model data specifiying out of range indices or norms + // + if (((cur_idx + norm_offset) > index_count) + || ((idx[cur_idx+norm_offset]*3+2) > norm_count)) + { + llwarns << "Out of range norm indices, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } + cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0], n[idx[cur_idx+norm_offset]*3+1], n[idx[cur_idx+norm_offset]*3+2]); + + if (!cv.getNormal().isFinite3()) + { + llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } cur_idx += idx_stride; @@ -560,6 +664,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac domVertices* vertices = (domVertices*) elem.cast(); if (!vertices) { + llwarns << "Could not find vertex source, invalid model." << llendl; return LLModel::BAD_ELEMENT; } domInputLocal_Array& v_inp = vertices->getInput_array(); @@ -573,6 +678,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac domSource* src = (domSource*) elem.cast(); if (!src) { + llwarns << "Could not find DOM source, invalid model." << llendl; return LLModel::BAD_ELEMENT; } v = &(src->getFloat_array()->getValue()); @@ -588,6 +694,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac domSource* src = (domSource*) elem.cast(); if (!src) { + llwarns << "Could not find DOM source, invalid model." << llendl; return LLModel::BAD_ELEMENT; } n = &(src->getFloat_array()->getValue()); @@ -600,6 +707,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac domSource* src = (domSource*) elem.cast(); if (!src) { + llwarns << "Could not find DOM source, invalid model." << llendl; return LLModel::BAD_ELEMENT; } t = &(src->getFloat_array()->getValue()); @@ -634,6 +742,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac vert.getPosition().set(v->get(v_idx), v->get(v_idx+1), v->get(v_idx+2)); + + if (!vert.getPosition().isFinite3()) + { + llwarns << "Found NaN while loading position data from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } //bounds check n and t lookups because some FBX to DAE converters @@ -646,6 +760,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac vert.getNormal().set(n->get(n_idx), n->get(n_idx+1), n->get(n_idx+2)); + + if (!vert.getNormal().isFinite3()) + { + llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } else { @@ -659,6 +779,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount()); vert.mTexCoord.setVec(t->get(t_idx), t->get(t_idx+1)); + + if (!vert.mTexCoord.isFinite()) + { + llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } else { @@ -1591,6 +1717,7 @@ LLSD LLModel::writeModel( mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue(); mdl[model_names[idx]][i]["TexCoord0"] = tc; } + mdl[model_names[idx]][i]["TriangleList"] = indices; if (skinning) diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index fb1673245..6276c0f50 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -921,6 +921,23 @@ void LLLineEditor::addChar(const llwchar uni_char) mText.insert(getCursor(), w_buf); setCursor(getCursor() + 1); + + if (!mReadOnly && mAutoreplaceCallback != NULL) + { + // autoreplace the text, if necessary + S32 replacement_start; + S32 replacement_length; + LLWString replacement_string; + S32 new_cursor_pos = getCursor(); + mAutoreplaceCallback(replacement_start, replacement_length, replacement_string, new_cursor_pos, mText); + + if (replacement_length > 0 || !replacement_string.empty()) + { + mText.erase(replacement_start, replacement_length); + mText.insert(replacement_start, replacement_string); + setCursor(new_cursor_pos); + } + } } else { diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index bc6df16f3..91a7983f4 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -167,6 +167,10 @@ public: virtual BOOL isSpellDirty() const { return mText.getString() != mPrevSpelledText; } // Returns TRUE if user changed value at all virtual void resetSpellDirty() { mPrevSpelledText = mText.getString(); } // Clear dirty state + typedef boost::function autoreplace_callback_t; + autoreplace_callback_t mAutoreplaceCallback; + void setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; } + // assumes UTF8 text virtual void setValue(const LLSD& value ) { setText(value.asString()); } virtual LLSD getValue() const { return LLSD(getText()); } diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index 1289085b7..f611c6594 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -156,8 +156,6 @@ LLDir_Win32::LLDir_Win32() mAppRODataDir = mWorkingDir; -// if (mExecutableDir.find("indra") == std::string::npos) - // *NOTE:Mani - It is a mistake to put viewer specific code in // the LLDir implementation. The references to 'skins' and // 'llplugin' need to go somewhere else. @@ -172,7 +170,18 @@ LLDir_Win32::LLDir_Win32() llinfos << "mAppRODataDir = " << mAppRODataDir << llendl; - mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; + std::string::size_type build_dir_pos = mExecutableDir.rfind("indra" + mDirDelimiter); + if (build_dir_pos != std::string::npos) + { + // ...we're in a dev checkout + mSkinBaseDir = mExecutableDir.substr(0, build_dir_pos) + "indra" + mDirDelimiter + "newview" + mDirDelimiter + "skins"; + llinfos << "Running in dev checkout with mSkinBaseDir " << mSkinBaseDir << llendl; + } + else + { + // ...normal installation running + mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; + } // Build the default cache directory mDefaultCacheDir = buildSLOSCacheDir(); diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 91e4c00cf..fd4411f57 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -3277,7 +3277,7 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async) llinfos << "Opening URL " << escaped_url << llendl; - CFStringRef stringRef = CFStringCreateWithCString(NULL, escaped_url.c_str(), kCFStringEncodingUTF8); + CFStringRef stringRef = CFStringCreateWithBytes(NULL, (UInt8 *)escaped_url.c_str(), strlen(escaped_url.c_str()), kCFStringEncodingUTF8, false); if (stringRef) { // This will succeed if the string is a full URL, including the http:// @@ -3315,6 +3315,21 @@ void LLWindowMacOSX::setTitle(const std::string &title) SetWindowTitleWithCFString(mWindow, title_str); } +// virtual +void LLWindowMacOSX::ShellEx(const std::string& command) +{ + char * path = NULL; + asprintf(&path, "%s %s", (char*)"file://", command.c_str()); + CFURLRef url = CFURLCreateAbsoluteURLWithBytes(NULL, (UInt8 *)path, strlen(path), + kCFURLPOSIXPathStyle, NULL, true); + if (url != NULL) + { + LSOpenCFURLRef(url, NULL); + CFRelease(url); + } + free(path); +} + LLSD LLWindowMacOSX::getNativeKeyData() { LLSD result = LLSD::emptyMap(); diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 7f7181a58..d8d46edb9 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -116,6 +116,7 @@ public: /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); /*virtual*/ void setTitle(const std::string &title); + /*virtual*/ void ShellEx(const std::string& command); static std::vector getDynamicFallbackFontList(); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 008c92e0c..a29c5378e 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3329,9 +3329,9 @@ S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 t return retval; } -void LLWindowWin32::ShellEx(const std::string& command ) +void LLWindowWin32::ShellEx(const std::string& command) { - LLWString url_wstring = utf8str_to_wstring( command ); + LLWString url_wstring = utf8str_to_wstring( "\"" + command + "\"" ); llutf16string url_utf16 = wstring_to_utf16str( url_wstring ); SHELLEXECUTEINFO sei = { sizeof( sei ) }; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 03284d6e0..008e1d420 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -126,6 +126,7 @@ set(viewer_SOURCE_FILES llassetuploadresponders.cpp llattachmentsmgr.cpp llaudiosourcevo.cpp + llautoreplace.cpp llavataractions.cpp llavatarpropertiesprocessor.cpp llbox.cpp @@ -181,6 +182,7 @@ set(viewer_SOURCE_FILES llfloaterabout.cpp llfloateractivespeakers.cpp llfloaterauction.cpp + llfloaterautoreplacesettings.cpp llfloateravatarinfo.cpp llfloateravatarlist.cpp llfloateravatarpicker.cpp @@ -244,7 +246,6 @@ set(viewer_SOURCE_FILES llfloaterpathfindingcharacters.cpp llfloaterpathfindinglinksets.cpp llfloaterpathfindingobjects.cpp - llfloaterpermissionsmgr.cpp llfloaterperms.cpp llfloaterpostcard.cpp llfloaterpostprocess.cpp @@ -252,6 +253,7 @@ set(viewer_SOURCE_FILES llfloaterproperties.cpp llfloaterregiondebugconsole.cpp llfloaterregioninfo.cpp + llfloaterregionrestarting.cpp llfloaterreporter.cpp llfloaterscriptdebug.cpp llfloaterscriptlimits.cpp @@ -646,6 +648,7 @@ set(viewer_HEADER_FILES llassetuploadresponders.h llattachmentsmgr.h llaudiosourcevo.h + llautoreplace.h llavataractions.h llavatarpropertiesprocessor.h llbox.h @@ -701,6 +704,7 @@ set(viewer_HEADER_FILES llfloaterabout.h llfloateractivespeakers.h llfloaterauction.h + llfloaterautoreplacesettings.h llfloateravatarinfo.h llfloateravatarlist.h llfloateravatarpicker.h @@ -764,7 +768,6 @@ set(viewer_HEADER_FILES llfloaterpathfindingcharacters.h llfloaterpathfindinglinksets.h llfloaterpathfindingobjects.h - llfloaterpermissionsmgr.h llfloaterperms.h llfloaterpostcard.h llfloaterpostprocess.h @@ -772,6 +775,7 @@ set(viewer_HEADER_FILES llfloaterproperties.h llfloaterregiondebugconsole.h llfloaterregioninfo.h + llfloaterregionrestarting.h llfloaterreporter.h llfloaterscriptdebug.h llfloaterscriptlimits.h @@ -1140,7 +1144,7 @@ if (DARWIN) # Add resource files to the project. set(viewer_RESOURCE_FILES - ${VIEWER_BRANDING_ID}.icns + ${VIEWER_BRANDING_ID}_icon.icns macview.r gpu_table.txt SecondLife.nib/ @@ -1702,7 +1706,7 @@ if (DARWIN) PROPERTIES OUTPUT_NAME "${product}" MACOSX_BUNDLE_INFO_STRING "A stable third-party Second Life viewer." - MACOSX_BUNDLE_ICON_FILE "${VIEWER_BRANDING_ID}.icns" + MACOSX_BUNDLE_ICON_FILE "${VIEWER_BRANDING_ID}_icon.icns" MACOSX_BUNDLE_GUI_IDENTIFIER "${VIEWER_BRANDING_NAME}" MACOSX_BUNDLE_LONG_VERSION_STRING "${viewer_VERSION}" MACOSX_BUNDLE_BUNDLE_NAME "${VIEWER_BRANDING_NAME}" diff --git a/indra/newview/app_settings/autoreplace.xml b/indra/newview/app_settings/autoreplace.xml new file mode 100644 index 000000000..09d19f7b0 --- /dev/null +++ b/indra/newview/app_settings/autoreplace.xml @@ -0,0 +1,8330 @@ + + + + name + Abbreviations + replacements + + afaic + As far as I am concerned + afaik + As far as I know + afk + away from keyboard + atm + at the moment + bbiab + be back in a bit + bbl + be back later + brb + be right back + btw + by the way + fyi + For your information + fwiw + For what its worth + gtg + got to go + idk + I don't know + iirc + if I recall correctly + imho + in my humble opinion + imo + in my opinion + irl + in real life + np + no problem + nsfw + not safe for work + nvm + nevermind + tc + take care + thx + thanks + ttfn + ta-ta for now + ttyl + talk to you later + ty + thank you + tyvm + thank you very much + wb + welcome back + yw + you're welcome + yvw + you're very welcome + + + + name + Spelling Corrections + replacements + + Amercia + America + Bernouilli + Bernoulli + Blitzkreig + Blitzkrieg + Bonnano + Bonanno + Brasillian + Brazilian + Britian + Britain + Brittish + British + Buddah + Buddha + Buddist + Buddhist + Cambrige + Cambridge + Capetown + Cape Town + Carmalite + Carmelite + Carnagie + Carnegie + Carnagie-Mellon + Carnegie-Mellon + Carnigie + Carnegie + Carnigie-Mellon + Carnegie-Mellon + Carribbean + Caribbean + Carribean + Caribbean + Carthagian + Carthaginian + Cataline + Catiline + Ceasar + Caesar + Celcius + Celsius + Champange + Champagne + Cincinatti + Cincinnati + Cincinnatti + Cincinnati + Conneticut + Connecticut + Dardenelles + Dardanelles + Dravadian + Dravidian + Enlish + English + Europian + European + Europians + Europeans + Eurpean + European + Eurpoean + European + Farenheit + Fahrenheit + Febuary + February + Feburary + February + Flemmish + Flemish + Formalhaut + Fomalhaut + Foundland + Newfoundland + Fransiscan + Franciscan + Fransiscans + Franciscans + Galations + Galatians + Gameboy + Game Boy + Ghandi + Gandhi + Godounov + Godunov + Gothenberg + Gothenburg + Gottleib + Gottlieb + Guaduloupe + Guadalupe + Guadulupe + Guadalupe + Guatamala + Guatemala + Guatamalan + Guatemalan + Guilia + Giulia + Guilio + Giulio + Guiness + Guinness + Guiseppe + Giuseppe + Habsbourg + Habsburg + Hallowean + Halloween + Heidelburg + Heidelberg + Ihaca + Ithaca + Israelies + Israelis + Janurary + January + Januray + January + Japanes + Japanese + Johanine + Johannine + Jospeh + Joseph + Juadaism + Judaism + Juadism + Judaism + Lybia + Libya + Malcom + Malcolm + Massachussets + Massachusetts + Massachussetts + Massachusetts + Mediteranean + Mediterranean + Michagan + Michigan + Misouri + Missouri + Missisipi + Mississippi + Missisippi + Mississippi + Monserrat + Montserrat + Montnana + Montana + Morisette + Morissette + Morrisette + Morissette + Mythraic + Mithraic + Naploeon + Napoleon + Napolean + Napoleon + Napoleonian + Napoleonic + Nazereth + Nazareth + Newyorker + New Yorker + Novermber + November + Nullabour + Nullarbor + Nuremburg + Nuremberg + Palistian + Palestinian + Palistinian + Palestinian + Palistinians + Palestinians + Papanicalou + Papanicolaou + Peloponnes + Peloponnesus + Pennyslvania + Pennsylvania + Pharoah + Pharaoh + Philipines + Philippines + Phillipine + Philippine + Phillipines + Philippines + Phillippines + Philippines + Phonecian + Phoenecian + Portugese + Portuguese + Postdam + Potsdam + Premonasterians + Premonstratensians + Pucini + Puccini + Puertorrican + Puerto Rican + Puertorricans + Puerto Ricans + Queenland + Queensland + Rockerfeller + Rockefeller + Russion + Russian + Sanhedrim + Sanhedrin + Saterday + Saturday + Saterdays + Saturdays + Sionist + Zionist + Sionists + Zionists + Sixtin + Sistine + Skagerak + Skagerrak + Tolkein + Tolkien + Tuscon + Tucson + Ukranian + Ukrainian + UnitesStates + UnitedStates + Yementite + Yemenite + abandonned + abandoned + aberation + aberration + abilties + abilities + abilty + ability + abondon + abandon + abondoned + abandoned + abondoning + abandoning + abondons + abandons + aborigene + aborigine + abortificant + abortifacient + abreviate + abbreviate + abreviated + abbreviated + abreviation + abbreviation + abritrary + arbitrary + absail + abseil + absailing + abseiling + absense + absence + absolutly + absolutely + absorbsion + absorption + absorbtion + absorption + abundacies + abundances + abundancies + abundances + abundunt + abundant + abutts + abuts + acadamy + academy + acadmic + academic + accademic + academic + accademy + academy + acccused + accused + accelleration + acceleration + accension + ascension + acceptence + acceptance + acceptible + acceptable + accessable + accessible + accidentaly + accidentally + accidently + accidentally + acclimitization + acclimatization + accomadate + accommodate + accomadated + accommodated + accomadates + accommodates + accomadating + accommodating + accomadation + accommodation + accomadations + accommodations + accomdate + accommodate + accomodate + accommodate + accomodated + accommodated + accomodates + accommodates + accomodating + accommodating + accomodation + accommodation + accomodations + accommodations + accompanyed + accompanied + accordeon + accordion + accordian + accordion + accoring + according + accoustic + acoustic + accquainted + acquainted + accrediation + accreditation + accredidation + accreditation + accross + across + accussed + accused + acedemic + academic + acheive + achieve + acheived + achieved + acheivement + achievement + acheivements + achievements + acheives + achieves + acheiving + achieving + acheivment + achievement + acheivments + achievements + achievment + achievement + achievments + achievements + achivement + achievement + achivements + achievements + acknowldeged + acknowledged + acknowledgeing + acknowledging + ackward + awkward + acommodate + accommodate + acomplish + accomplish + acomplished + accomplished + acomplishment + accomplishment + acomplishments + accomplishments + acording + according + acordingly + accordingly + acquaintence + acquaintance + acquaintences + acquaintances + acquiantence + acquaintance + acquiantences + acquaintances + acquited + acquitted + activites + activities + activly + actively + actualy + actually + acuracy + accuracy + acused + accused + acustom + accustom + acustommed + accustomed + adavanced + advanced + adbandon + abandon + additinally + additionally + additionaly + additionally + additonal + additional + additonally + additionally + addmission + admission + addopt + adopt + addopted + adopted + addoptive + adoptive + addres + address + addresable + addressable + addresed + addressed + addresing + addressing + addressess + addresses + addtion + addition + addtional + additional + adecuate + adequate + adequit + adequate + adhearing + adhering + adherance + adherence + admendment + amendment + admininistrative + administrative + adminstered + administered + adminstrate + administrate + adminstration + administration + adminstrative + administrative + adminstrator + administrator + admissability + admissibility + admissable + admissible + admited + admitted + admitedly + admittedly + adn + and + adolecent + adolescent + adquire + acquire + adquired + acquired + adquires + acquires + adquiring + acquiring + adres + address + adresable + addressable + adresing + addressing + adress + address + adressable + addressable + adressed + addressed + adressing + addressing + adventrous + adventurous + advertisment + advertisement + advertisments + advertisements + advesary + adversary + adviced + advised + aeriel + aerial + aeriels + aerials + afair + affair + afficianados + aficionados + afficionado + aficionado + afficionados + aficionados + affilate + affiliate + affilliate + affiliate + affort + afford + aforememtioned + aforementioned + againnst + against + agains + against + agaisnt + against + aganist + against + aggaravates + aggravates + aggreed + agreed + aggreement + agreement + aggregious + egregious + aggresive + aggressive + agian + again + agianst + against + agin + again + agina + again + aginst + against + agravate + aggravate + agre + agree + agred + agreed + agreeement + agreement + agreemnt + agreement + agregate + aggregate + agregates + aggregates + agreing + agreeing + agression + aggression + agressive + aggressive + agressively + aggressively + agressor + aggressor + agricuture + agriculture + agrieved + aggrieved + ahev + have + ahppen + happen + ahve + have + aicraft + aircraft + aiport + airport + airbourne + airborne + aircaft + aircraft + aircrafts + aircraft + airporta + airports + airrcraft + aircraft + aisian + asian + albiet + albeit + alchohol + alcohol + alchoholic + alcoholic + alchol + alcohol + alcholic + alcoholic + alcohal + alcohol + alcoholical + alcoholic + aledge + allege + aledged + alleged + aledges + alleges + alege + allege + aleged + alleged + alegience + allegiance + algebraical + algebraic + algorhitms + algorithms + algoritm + algorithm + algoritms + algorithms + alientating + alienating + alledge + allege + alledged + alleged + alledgedly + allegedly + alledges + alleges + allegedely + allegedly + allegedy + allegedly + allegely + allegedly + allegence + allegiance + allegience + allegiance + allign + align + alligned + aligned + alliviate + alleviate + allopone + allophone + allopones + allophones + allready + already + allthough + although + alltime + all-time + alltogether + altogether + almsot + almost + alochol + alcohol + alomst + almost + alot + a lot + alotted + allotted + alowed + allowed + alowing + allowing + alreayd + already + alse + else + alsot + also + alternitives + alternatives + altho + although + althought + although + altough + although + alusion + allusion + alwasy + always + alwyas + always + amalgomated + amalgamated + amatuer + amateur + amature + armature + amendmant + amendment + amerliorate + ameliorate + amke + make + amking + making + ammend + amend + ammended + amended + ammendment + amendment + ammendments + amendments + ammount + amount + ammused + amused + amoung + among + amoungst + amongst + amung + among + amunition + ammunition + analagous + analogous + analitic + analytic + analogeous + analogous + anarchim + anarchism + anarchistm + anarchism + anbd + and + ancestory + ancestry + ancilliary + ancillary + androgenous + androgynous + androgeny + androgyny + anihilation + annihilation + aniversary + anniversary + annoint + anoint + annointed + anointed + annointing + anointing + annoints + anoints + annouced + announced + annualy + annually + annuled + annulled + anohter + another + anomolies + anomalies + anomolous + anomalous + anomoly + anomaly + anonimity + anonymity + anounced + announced + anouncement + announcement + ansalisation + nasalisation + ansalization + nasalization + ansestors + ancestors + antartic + antarctic + anthromorphization + anthropomorphization + anthropolgist + anthropologist + anthropolgy + anthropology + anual + annual + anulled + annulled + anwsered + answered + anyhwere + anywhere + anyother + any other + anytying + anything + aparent + apparent + aparment + apartment + apenines + apennines + aplication + application + aplied + applied + apolegetics + apologetics + apon + apron + apparant + apparent + apparantly + apparently + appart + apart + appartment + apartment + appartments + apartments + appealling + appealing + appeareance + appearance + appearence + appearance + appearences + appearances + apperance + appearance + apperances + appearances + appereance + appearance + appereances + appearances + applicaiton + application + applicaitons + applications + appologies + apologies + appology + apology + apprearance + appearance + apprieciate + appreciate + approachs + approaches + appropiate + appropriate + appropraite + appropriate + appropropiate + appropriate + approproximate + approximate + approxamately + approximately + approxiately + approximately + approximitely + approximately + aprehensive + apprehensive + apropriate + appropriate + aproximate + approximate + aproximately + approximately + aquaduct + aqueduct + aquaintance + acquaintance + aquainted + acquainted + aquiantance + acquaintance + aquire + acquire + aquired + acquired + aquiring + acquiring + aquisition + acquisition + aquitted + acquitted + aranged + arranged + arangement + arrangement + arbitarily + arbitrarily + arbitary + arbitrary + archaelogists + archaeologists + archaelogy + archaeology + archaoelogy + archaeology + archaology + archaeology + archeaologist + archaeologist + archeaologists + archaeologists + archetect + architect + archetects + architects + archetectural + architectural + archetecturally + architecturally + archetecture + architecture + archiac + archaic + archictect + architect + archimedian + archimedean + architecht + architect + architechturally + architecturally + architechture + architecture + architechtures + architectures + architectual + architectural + archtype + archetype + archtypes + archetypes + aready + already + areodynamics + aerodynamics + argubly + arguably + arguement + argument + arguements + arguments + arised + arose + arival + arrival + armamant + armament + armistace + armistice + arogant + arrogant + arogent + arrogant + aroud + around + arrangment + arrangement + arrangments + arrangements + arround + around + artical + article + artice + article + articel + article + artifical + artificial + artifically + artificially + artillary + artillery + arund + around + asetic + ascetic + asfar + as far + asign + assign + aslo + also + asociated + associated + asorbed + absorbed + asphyxation + asphyxiation + assasin + assassin + assasinate + assassinate + assasinated + assassinated + assasinates + assassinates + assasination + assassination + assasinations + assassinations + assasined + assassinated + assasins + assassins + assassintation + assassination + assemple + assemble + assertation + assertion + asside + aside + assisnate + assassinate + assit + assist + assitant + assistant + assocation + association + assoicate + associate + assoicated + associated + assoicates + associates + assosication + assassination + asssassans + assassins + assualt + assault + assualted + assaulted + assymetric + asymmetric + assymetrical + asymmetrical + asteriod + asteroid + asthetic + aesthetic + asthetical + aesthetical + asthetically + aesthetically + asume + assume + aswell + as well + atain + attain + atempting + attempting + atheistical + atheistic + athenean + athenian + atheneans + athenians + athiesm + atheism + athiest + atheist + atorney + attorney + atribute + attribute + atributed + attributed + atributes + attributes + attaindre + attainder + attemp + attempt + attemped + attempted + attemt + attempt + attemted + attempted + attemting + attempting + attemts + attempts + attendence + attendance + attendent + attendant + attendents + attendants + attened + attended + attension + attention + attitide + attitude + attributred + attributed + attrocities + atrocities + audeince + audience + auromated + automated + austrailia + Australia + austrailian + Australian + auther + author + authobiographic + autobiographic + authobiography + autobiography + authorative + authoritative + authorites + authorities + authorithy + authority + authoritiers + authorities + authoritive + authoritative + authrorities + authorities + autochtonous + autochthonous + autoctonous + autochthonous + automaticly + automatically + automibile + automobile + automonomous + autonomous + autor + author + autority + authority + auxilary + auxiliary + auxillaries + auxiliaries + auxillary + auxiliary + auxilliaries + auxiliaries + auxilliary + auxiliary + availabe + available + availablity + availability + availaible + available + availble + available + availiable + available + availible + available + avalable + available + avalance + avalanche + avaliable + available + avation + aviation + avengence + a vengeance + averageed + averaged + avilable + available + awared + awarded + awya + away + baceause + because + backgorund + background + backrounds + backgrounds + bakc + back + banannas + bananas + bandwith + bandwidth + bankrupcy + bankruptcy + banruptcy + bankruptcy + baout + about + basicaly + basically + basicly + basically + bcak + back + beachead + beachhead + beacuse + because + beastiality + bestiality + beatiful + beautiful + beaurocracy + bureaucracy + beaurocratic + bureaucratic + beautyfull + beautiful + becamae + became + becames + becomes + becasue + because + beccause + because + becomeing + becoming + becomming + becoming + becouse + because + becuase + because + bedore + before + befoer + before + beggin + begin + begginer + beginner + begginers + beginners + beggining + beginning + begginings + beginnings + beggins + begins + begining + beginning + beginnig + beginning + behavour + behavior + beleagured + beleaguered + beleif + belief + beleive + believe + beleived + believed + beleives + believes + beleiving + believing + beligum + belgium + belive + believe + belived + believed + belives + believes + belligerant + belligerent + bellweather + bellwether + bemusemnt + bemusement + beneficary + beneficiary + beng + being + benificial + beneficial + benifit + benefit + benifits + benefits + bergamont + bergamot + beseige + besiege + beseiged + besieged + beseiging + besieging + betwen + between + beween + between + bewteen + between + bilateraly + bilaterally + billingualism + bilingualism + binominal + binomial + bizzare + bizarre + blaim + blame + blaimed + blamed + blessure + blessing + bodydbuilder + bodybuilder + bombardement + bombardment + bombarment + bombardment + bondary + boundary + borke + broke + boundry + boundary + bouyancy + buoyancy + bouyant + buoyant + boyant + buoyant + breakthough + breakthrough + breakthroughts + breakthroughs + breif + brief + breifly + briefly + brethen + brethren + bretheren + brethren + briliant + brilliant + brillant + brilliant + brimestone + brimstone + broacasted + broadcast + broadacasting + broadcasting + broady + broadly + buisness + business + buisnessman + businessman + buoancy + buoyancy + burried + buried + busineses + businesses + busness + business + bussiness + business + caculater + calculator + cacuses + caucuses + cahracters + characters + calaber + caliber + calculater + calculator + calculs + calculus + calenders + calendars + caligraphy + calligraphy + caluclate + calculate + caluclated + calculated + caluculate + calculate + caluculated + calculated + calulate + calculate + calulated + calculated + calulater + calculator + camoflage + camouflage + campain + campaign + campains + campaigns + candadate + candidate + candiate + candidate + candidiate + candidate + cannister + canister + cannisters + canisters + cannnot + cannot + cannonical + canonical + cannotation + connotation + cannotations + connotations + cant + can't + caost + coast + caperbility + capability + capible + capable + captial + capital + captued + captured + capturd + captured + carachter + character + caracterized + characterized + carcas + carcass + carefull + careful + careing + caring + carismatic + charismatic + carnege + carnage + carnige + carnage + carniverous + carnivorous + carreer + career + carrers + careers + cartdridge + cartridge + carthographer + cartographer + cartilege + cartilage + cartilidge + cartilage + cartrige + cartridge + casette + cassette + casion + caisson + cassawory + cassowary + cassowarry + cassowary + casulaties + casualties + casulaty + casualty + catagories + categories + catagorized + categorized + catagory + category + catapillar + caterpillar + catapillars + caterpillars + catapiller + caterpillar + catapillers + caterpillars + catepillar + caterpillar + catepillars + caterpillars + catergorize + categorize + catergorized + categorized + caterpilar + caterpillar + caterpilars + caterpillars + caterpiller + caterpillar + caterpillers + caterpillars + cathlic + catholic + catholocism + catholicism + catterpilar + caterpillar + catterpilars + caterpillars + catterpillar + caterpillar + catterpillars + caterpillars + cattleship + battleship + causalities + casualties + cellpading + cellpadding + cementary + cemetery + cemetarey + cemetery + cemetaries + cemeteries + cemetary + cemetery + cencus + census + censur + censor + cententenial + centennial + centruies + centuries + centruy + century + ceratin + certain + cerimonial + ceremonial + cerimonies + ceremonies + cerimonious + ceremonious + cerimony + ceremony + ceromony + ceremony + certainity + certainty + certian + certain + chalenging + challenging + challange + challenge + challanged + challenged + challege + challenge + changable + changeable + charachter + character + charachters + characters + charactersistic + characteristic + charactor + character + charactors + characters + charasmatic + charismatic + charaterized + characterized + chariman + chairman + charistics + characteristics + cheif + chief + cheifs + chiefs + chemcial + chemical + chemcially + chemically + chemestry + chemistry + chemicaly + chemically + childbird + childbirth + childen + children + choosen + chosen + chracter + character + chuch + church + churchs + churches + circulaton + circulation + circumsicion + circumcision + circut + circuit + ciricuit + circuit + ciriculum + curriculum + civillian + civilian + claer + clear + claerer + clearer + claerly + clearly + claimes + claims + clas + class + clasic + classic + clasical + classical + clasically + classically + cleareance + clearance + clera + clear + clincial + clinical + clinicaly + clinically + cmo + com + cmoputer + computer + co-incided + coincided + coctail + cocktail + coform + conform + cognizent + cognizant + coincedentally + coincidentally + colaborations + collaborations + colateral + collateral + colelctive + collective + collaberative + collaborative + collecton + collection + collegue + colleague + collegues + colleagues + collonade + colonnade + collonies + colonies + collony + colony + collosal + colossal + colonizators + colonizers + comander + commander + comando + commando + comandos + commandos + comany + company + comapany + company + comback + comeback + combanations + combinations + combinatins + combinations + combusion + combustion + comdemnation + condemnation + comemmorates + commemorates + comemoretion + commemoration + comision + commission + comisioned + commissioned + comisioner + commissioner + comisioning + commissioning + comisions + commissions + comission + commission + comissioned + commissioned + comissioner + commissioner + comissioning + commissioning + comissions + commissions + comited + committed + comiting + committing + comitted + committed + comittee + committee + comitting + committing + commandoes + commandos + commedic + comedic + commemerative + commemorative + commemmorate + commemorate + commemmorating + commemorating + commerical + commercial + commerically + commercially + commericial + commercial + commericially + commercially + commerorative + commemorative + comming + coming + comminication + communication + commision + commission + commisioned + commissioned + commisioner + commissioner + commisioning + commissioning + commisions + commissions + commited + committed + commitee + committee + commiting + committing + committe + committee + committment + commitment + committments + commitments + commmemorated + commemorated + commongly + commonly + commonweath + commonwealth + commuications + communications + commuinications + communications + communciation + communication + communiation + communication + communites + communities + compability + compatibility + comparision + comparison + comparisions + comparisons + comparitive + comparative + comparitively + comparatively + compatabilities + compatibilities + compatability + compatibility + compatable + compatible + compatablities + compatibilities + compatablity + compatibility + compatiable + compatible + compatiblities + compatibilities + compatiblity + compatibility + compeitions + competitions + compensantion + compensation + competance + competence + competant + competent + competative + competitive + competion + competition + competitiion + competition + competive + competitive + competiveness + competitiveness + comphrehensive + comprehensive + compitent + competent + completedthe + completed the + completelyl + completely + completetion + completion + complier + compiler + componant + component + comprable + comparable + comprimise + compromise + compulsary + compulsory + compulsery + compulsory + computarized + computerized + concensus + consensus + concider + consider + concidered + considered + concidering + considering + conciders + considers + concieted + conceited + concieved + conceived + concious + conscious + conciously + consciously + conciousness + consciousness + condamned + condemned + condemmed + condemned + condidtion + condition + condidtions + conditions + conditionsof + conditions of + conected + connected + conection + connection + conesencus + consensus + confidental + confidential + confidentally + confidentially + confids + confides + configureable + configurable + confortable + comfortable + congradulations + congratulations + congresional + congressional + conived + connived + conjecutre + conjecture + conjuction + conjunction + conotations + connotations + conquerd + conquered + conquerer + conqueror + conquerers + conquerors + conqured + conquered + conscent + consent + consciouness + consciousness + consdider + consider + consdidered + considered + consdiered + considered + consectutive + consecutive + consenquently + consequently + consentrate + concentrate + consentrated + concentrated + consentrates + concentrates + consept + concept + consequentually + consequently + consequeseces + consequences + consern + concern + conserned + concerned + conserning + concerning + conservitive + conservative + consiciousness + consciousness + consicousness + consciousness + considerd + considered + consideres + considered + consious + conscious + consistant + consistent + consistantly + consistently + consituencies + constituencies + consituency + constituency + consituted + constituted + consitution + constitution + consitutional + constitutional + consolodate + consolidate + consolodated + consolidated + consonent + consonant + consonents + consonants + consorcium + consortium + conspiracys + conspiracies + conspiriator + conspirator + constaints + constraints + constanly + constantly + constarnation + consternation + constatn + constant + constinually + continually + constituant + constituent + constituants + constituents + constituion + constitution + constituional + constitutional + consttruction + construction + constuction + construction + consulant + consultant + consumate + consummate + consumated + consummated + contaiminate + contaminate + containes + contains + contamporaries + contemporaries + contamporary + contemporary + contempoary + contemporary + contemporaneus + contemporaneous + contempory + contemporary + contendor + contender + contibute + contribute + contibuted + contributed + contibutes + contributes + contigent + contingent + contined + continued + continous + continuous + continously + continuously + continueing + continuing + contravercial + controversial + contraversy + controversy + contributer + contributor + contributers + contributors + contritutions + contributions + controled + controlled + controling + controlling + controll + control + controlls + controls + controvercial + controversial + controvercy + controversy + controveries + controversies + controversal + controversial + controversey + controversy + controvertial + controversial + controvery + controversy + contruction + construction + conveinent + convenient + convenant + covenant + convential + conventional + convertables + convertibles + convertion + conversion + conveyer + conveyor + conviced + convinced + convienient + convenient + coordiantion + coordination + coorperations + corporations + copmetitors + competitors + coputer + computer + copywrite + copyright + coridal + cordial + cornmitted + committed + corosion + corrosion + corparate + corporate + corperations + corporations + correcters + correctors + correponding + corresponding + correposding + corresponding + correspondant + correspondent + correspondants + correspondents + corridoors + corridors + corrispond + correspond + corrispondant + correspondent + corrispondants + correspondents + corrisponded + corresponded + corrisponding + corresponding + corrisponds + corresponds + costitution + constitution + coucil + council + counries + countries + countains + contains + countires + countries + coururier + courier + coverted + converted + cpoy + copy + creaeted + created + creedence + credence + critereon + criterion + criterias + criteria + criticists + critics + critising + criticising + critisising + criticising + critisism + criticism + critisisms + criticisms + critisize + criticise + critisized + criticised + critisizes + criticises + critisizing + criticising + critized + criticized + critizing + criticizing + crockodiles + crocodiles + crowm + crown + crtical + critical + crticised + criticised + crucifiction + crucifixion + crusies + cruises + crystalisation + crystallisation + culiminating + culminating + cumulatative + cumulative + curch + church + curcuit + circuit + currenly + currently + curriculem + curriculum + cxan + cyan + cyclinder + cylinder + dacquiri + daiquiri + dael + deal + dalmation + dalmatian + damenor + demeanor + dammage + damage + daugher + daughter + debateable + debatable + decendant + descendant + decendants + descendants + decendent + descendant + decendents + descendants + decideable + decidable + decidely + decidedly + decieved + deceived + decison + decision + decomissioned + decommissioned + decomposit + decompose + decomposited + decomposed + decompositing + decomposing + decomposits + decomposes + decress + decrees + decribe + describe + decribed + described + decribes + describes + decribing + describing + dectect + detect + defendent + defendant + defendents + defendants + deffensively + defensively + deffine + define + deffined + defined + definance + defiance + definate + definite + definately + definitely + definatly + definitely + definetly + definitely + definining + defining + definit + definite + definitly + definitely + definiton + definition + defintion + definition + degrate + degrade + delagates + delegates + delapidated + dilapidated + delerious + delirious + delevopment + development + deliberatly + deliberately + delusionally + delusively + demenor + demeanor + demographical + demographic + demolision + demolition + demorcracy + democracy + demostration + demonstration + denegrating + denigrating + densly + densely + deparment + department + deparmental + departmental + deparments + departments + dependance + dependence + dependancy + dependency + dependant + dependent + deram + dream + deriviated + derived + derivitive + derivative + derogitory + derogatory + descendands + descendants + descibed + described + descision + decision + descisions + decisions + descriibes + describes + descripters + descriptors + descripton + description + desctruction + destruction + descuss + discuss + desgined + designed + deside + decide + desigining + designing + desinations + destinations + desintegrated + disintegrated + desintegration + disintegration + desireable + desirable + desitned + destined + desktiop + desktop + desorder + disorder + desoriented + disoriented + desparate + desperate + despict + depict + despiration + desperation + dessicated + desiccated + dessigned + designed + destablized + destabilized + destory + destroy + detailled + detailed + detatched + detached + deteoriated + deteriorated + deteriate + deteriorate + deterioriating + deteriorating + determinining + determining + detremental + detrimental + devasted + devastated + develope + develop + developement + development + developped + developed + develpment + development + devels + delves + devestated + devastated + devestating + devastating + devide + divide + devided + divided + devistating + devastating + devolopement + development + diablical + diabolical + diamons + diamonds + diaster + disaster + dichtomy + dichotomy + diconnects + disconnects + dicover + discover + dicovered + discovered + dicovering + discovering + dicovers + discovers + dicovery + discovery + dicussed + discussed + didnt + didn't + diea + idea + dieing + dying + dieties + deities + diety + deity + diferent + different + diferrent + different + differentiatiations + differentiations + differnt + different + difficulity + difficulty + diffrent + different + dificulties + difficulties + dificulty + difficulty + dimenions + dimensions + dimention + dimension + dimentional + dimensional + dimentions + dimensions + dimesnional + dimensional + diminuitive + diminutive + dimunitive + diminutive + diosese + diocese + diphtong + diphthong + diphtongs + diphthongs + diplomancy + diplomacy + dipthong + diphthong + dipthongs + diphthongs + dirived + derived + disagreeed + disagreed + disapeared + disappeared + disapointing + disappointing + disappearred + disappeared + disaproval + disapproval + disasterous + disastrous + disatisfaction + dissatisfaction + disatisfied + dissatisfied + disatrous + disastrous + discontentment + discontent + discribe + describe + discribed + described + discribes + describes + discribing + describing + disctinction + distinction + disctinctive + distinctive + disemination + dissemination + disenchanged + disenchanted + disiplined + disciplined + disobediance + disobedience + disobediant + disobedient + disolved + dissolved + disover + discover + dispair + despair + disparingly + disparagingly + dispence + dispense + dispenced + dispensed + dispencing + dispensing + dispicable + despicable + dispite + despite + dispostion + disposition + disproportiate + disproportionate + disputandem + disputandum + disricts + districts + dissagreement + disagreement + dissapear + disappear + dissapearance + disappearance + dissapeared + disappeared + dissapearing + disappearing + dissapears + disappears + dissappear + disappear + dissappears + disappears + dissappointed + disappointed + dissarray + disarray + dissobediance + disobedience + dissobediant + disobedient + dissobedience + disobedience + dissobedient + disobedient + distiction + distinction + distingish + distinguish + distingished + distinguished + distingishes + distinguishes + distingishing + distinguishing + distingquished + distinguished + distrubution + distribution + distruction + destruction + distructive + destructive + ditributed + distributed + diversed + diverged + divice + device + divison + division + divisons + divisions + doccument + document + doccumented + documented + doccuments + documents + docrines + doctrines + doctines + doctrines + documenatry + documentary + doens + does + doesnt + doesn't + doign + doing + dominaton + domination + dominent + dominant + dominiant + dominant + donig + doing + dont + don't + dosen't + doesn't + doub + doubt + doulbe + double + dowloads + downloads + dramtic + dramatic + draughtman + draughtsman + dreasm + dreams + driectly + directly + drnik + drink + druming + drumming + drummless + drumless + dupicate + duplicate + durig + during + durring + during + duting + during + dyas + dryas + eahc + each + ealier + earlier + earlies + earliest + earnt + earned + ecclectic + eclectic + eceonomy + economy + ecidious + deciduous + eclispe + eclipse + ecomonic + economic + ect + etc + eearly + early + efel + evil + effeciency + efficiency + effecient + efficient + effeciently + efficiently + efficency + efficiency + efficent + efficient + efficently + efficiently + efford + effort + effords + efforts + effulence + effluence + eigth + eight + eiter + either + elction + election + electic + electric + electon + electron + electrial + electrical + electricly + electrically + electricty + electricity + elementay + elementary + eleminated + eliminated + eleminating + eliminating + eles + eels + eletricity + electricity + elicided + elicited + eligable + eligible + elimentary + elementary + ellected + elected + elphant + elephant + embarass + embarrass + embarassed + embarrassed + embarassing + embarrassing + embarassment + embarrassment + embargos + embargoes + embarras + embarrass + embarrased + embarrassed + embarrasing + embarrassing + embarrasment + embarrassment + embezelled + embezzled + emblamatic + emblematic + eminate + emanate + eminated + emanated + emision + emission + emited + emitted + emiting + emitting + emition + emission + emmediately + immediately + emmigrated + immigrated + emminently + eminently + emmisaries + emissaries + emmisarries + emissaries + emmisarry + emissary + emmisary + emissary + emmision + emission + emmisions + emissions + emmited + emitted + emmiting + emitting + emmitted + emitted + emmitting + emitting + emnity + enmity + emperical + empirical + emphaised + emphasised + emphsis + emphasis + emphysyma + emphysema + emprisoned + imprisoned + enameld + enameled + enchancement + enhancement + encouraing + encouraging + encryptiion + encryption + encylopedia + encyclopedia + endevors + endeavors + endevour + endeavour + endig + ending + endolithes + endoliths + enduce + induce + ened + need + enflamed + inflamed + enforceing + enforcing + engagment + engagement + engeneer + engineer + engeneering + engineering + engieneer + engineer + engieneers + engineers + enlargment + enlargement + enlargments + enlargements + enourmous + enormous + enourmously + enormously + ensconsed + ensconced + entaglements + entanglements + enteratinment + entertainment + enthusiatic + enthusiastic + entitity + entity + entitlied + entitled + entrepeneur + entrepreneur + entrepeneurs + entrepreneurs + enviorment + environment + enviormental + environmental + enviormentally + environmentally + enviorments + environments + enviornment + environment + enviornmental + environmental + enviornmentalist + environmentalist + enviornmentally + environmentally + enviornments + environments + enviroment + environment + enviromental + environmental + enviromentalist + environmentalist + enviromentally + environmentally + enviroments + environments + envolutionary + evolutionary + envrionments + environments + enxt + next + epidsodes + episodes + epsiode + episode + equialent + equivalent + equilibium + equilibrium + equilibrum + equilibrium + equiped + equipped + equippment + equipment + equitorial + equatorial + equivelant + equivalent + equivelent + equivalent + equivilant + equivalent + equivilent + equivalent + equivlalent + equivalent + erally + really + eratic + erratic + eratically + erratically + eraticly + erratically + errupted + erupted + esential + essential + esitmated + estimated + esle + else + especialy + especially + essencial + essential + essense + essence + essentail + essential + essentialy + essentially + essentual + essential + essesital + essential + estabishes + establishes + establising + establishing + ethnocentricm + ethnocentrism + ethose + those + evenhtually + eventually + eventally + eventually + eventhough + even though + eventially + eventually + eventualy + eventually + everthing + everything + everytime + every time + everyting + everything + eveyr + every + evidentally + evidently + exagerate + exaggerate + exagerated + exaggerated + exagerates + exaggerates + exagerating + exaggerating + exagerrate + exaggerate + exagerrated + exaggerated + exagerrates + exaggerates + exagerrating + exaggerating + examinated + examined + exampt + exempt + exapansion + expansion + excact + exact + excange + exchange + excecute + execute + excecuted + executed + excecutes + executes + excecuting + executing + excecution + execution + excedded + exceeded + excelent + excellent + excell + excel + excellance + excellence + excellant + excellent + excells + excels + excercise + exercise + exchanching + exchanging + excisted + existed + exculsivly + exclusively + execising + exercising + exection + execution + exectued + executed + exeedingly + exceedingly + exelent + excellent + exellent + excellent + exemple + example + exept + except + exeptional + exceptional + exerbate + exacerbate + exerbated + exacerbated + exerciese + exercises + exerpt + excerpt + exerpts + excerpts + exersize + exercise + exerternal + external + exhalted + exalted + exhibtion + exhibition + exibition + exhibition + exibitions + exhibitions + exicting + exciting + exinct + extinct + existance + existence + existant + existent + existince + existence + exliled + exiled + exludes + excludes + exmaple + example + exonorate + exonerate + exoskelaton + exoskeleton + expalin + explain + expatriot + expatriate + expeced + expected + expecially + especially + expeditonary + expeditionary + expeiments + experiments + expell + expel + expells + expels + experiance + experience + experianced + experienced + expiditions + expeditions + expierence + experience + explaination + explanation + explaning + explaining + explictly + explicitly + exploititive + exploitative + explotation + exploitation + expropiated + expropriated + expropiation + expropriation + exressed + expressed + extemely + extremely + extention + extension + extentions + extensions + extered + exerted + extermist + extremist + extint + extinct + extradiction + extradition + extraterrestial + extraterrestrial + extraterrestials + extraterrestrials + extravagent + extravagant + extrememly + extremely + extremeophile + extremophile + extremly + extremely + extrordinarily + extraordinarily + extrordinary + extraordinary + eyar + year + eyars + years + eyasr + years + faciliate + facilitate + faciliated + facilitated + faciliates + facilitates + facilites + facilities + facillitate + facilitate + facinated + fascinated + facist + fascist + familes + families + familliar + familiar + famoust + famous + fanatism + fanaticism + fatc + fact + faught + fought + favoutrable + favourable + feasable + feasible + fedreally + federally + feromone + pheromone + fertily + fertility + fianite + finite + fianlly + finally + ficticious + fictitious + fictious + fictitious + fidn + find + fiercly + fiercely + fightings + fighting + filiament + filament + fimilies + families + finacial + financial + finaly + finally + financialy + financially + firends + friends + firts + first + fisionable + fissionable + flamable + flammable + flawess + flawless + fleed + fled + florescent + fluorescent + flourescent + fluorescent + flourine + fluorine + fluorish + flourish + follwoing + following + folowing + following + fomed + formed + fomr + from + fonetic + phonetic + fontrier + fontier + foootball + football + forbad + forbade + forbiden + forbidden + foreward + foreword + forfiet + forfeit + forhead + forehead + foriegn + foreign + formallize + formalize + formallized + formalized + formaly + formally + formelly + formerly + formidible + formidable + formost + foremost + forsaw + foresaw + forseeable + foreseeable + fortelling + foretelling + forunner + forerunner + foucs + focus + foudn + found + fougth + fought + foundaries + foundries + foundary + foundry + fourties + forties + fourty + forty + fouth + fourth + foward + forward + freind + friend + freindly + friendly + frequentily + frequently + frome + from + fromed + formed + froniter + frontier + fucntion + function + fucntioning + functioning + fufill + fulfill + fufilled + fulfilled + fulfiled + fulfilled + fullfill + fulfill + fullfilled + fulfilled + fundametal + fundamental + fundametals + fundamentals + funguses + fungi + funtion + function + furuther + further + futher + further + futhermore + furthermore + galatic + galactic + gallaxies + galaxies + galvinized + galvanized + ganerate + generate + ganes + games + ganster + gangster + garantee + guarantee + garanteed + guaranteed + garantees + guarantees + garnison + garrison + gaurantee + guarantee + gauranteed + guaranteed + gaurantees + guarantees + gaurd + guard + gaurentee + guarantee + gaurenteed + guaranteed + gaurentees + guarantees + geneological + genealogical + geneologies + genealogies + geneology + genealogy + generaly + generally + generatting + generating + genialia + genitalia + geographicial + geographical + geometrician + geometer + geometricians + geometers + gerat + great + glight + flight + gnawwed + gnawed + godess + goddess + godesses + goddesses + gogin + going + goign + going + gonig + going + gouvener + governor + govement + government + govenment + government + govenrment + government + goverance + governance + goverment + government + govermental + governmental + governer + governor + governmnet + government + govorment + government + govormental + governmental + govornment + government + gracefull + graceful + graet + great + grafitti + graffiti + gramatically + grammatically + grammaticaly + grammatically + grammer + grammar + grat + great + gratuitious + gratuitous + greatful + grateful + greatfully + gratefully + greif + grief + gridles + griddles + gropu + group + grwo + grow + guage + gauge + guarentee + guarantee + guarenteed + guaranteed + guarentees + guarantees + guerilla + guerrilla + guerillas + guerrillas + guerrila + guerrilla + guerrilas + guerrillas + guidence + guidance + gunanine + guanine + gurantee + guarantee + guranteed + guaranteed + gurantees + guarantees + guttaral + guttural + gutteral + guttural + habaeus + habeas + habeus + habeas + haemorrage + haemorrhage + haev + have + halp + help + hapen + happen + hapened + happened + hapening + happening + happend + happened + happended + happened + happenned + happened + harased + harassed + harases + harasses + harasment + harassment + harasments + harassments + harassement + harassment + harras + harass + harrased + harassed + harrases + harasses + harrasing + harassing + harrasment + harassment + harrasments + harassments + harrassed + harassed + harrasses + harassed + harrassing + harassing + harrassment + harassment + harrassments + harassments + hasnt + hasn't + haviest + heaviest + headquarer + headquarter + headquater + headquarter + headquatered + headquartered + headquaters + headquarters + healthercare + healthcare + heared + heard + heathy + healthy + heigher + higher + heirarchy + hierarchy + heiroglyphics + hieroglyphics + helment + helmet + helpfull + helpful + helpped + helped + hemmorhage + hemorrhage + herad + heard + heridity + heredity + heroe + hero + heros + heroes + hertiage + heritage + hertzs + hertz + hesistant + hesitant + heterogenous + heterogeneous + hieght + height + hierachical + hierarchical + hierachies + hierarchies + hierachy + hierarchy + hierarcical + hierarchical + hierarcy + hierarchy + hieroglph + hieroglyph + hieroglphs + hieroglyphs + higer + higher + higest + highest + higway + highway + hillarious + hilarious + himselv + himself + hinderance + hindrance + hinderence + hindrance + hindrence + hindrance + hipopotamus + hippopotamus + hismelf + himself + histocompatability + histocompatibility + historicians + historians + hitsingles + hit singles + holliday + holiday + homestate + home state + homogeneize + homogenize + homogeneized + homogenized + honory + honorary + horrifing + horrifying + hosited + hoisted + hospitible + hospitable + hounour + honour + housr + hours + howver + however + hsitorians + historians + hstory + history + hten + then + htere + there + htey + they + htikn + think + hting + thing + htink + think + htis + this + humer + humor + humerous + humorous + huminoid + humanoid + humoural + humoral + humurous + humorous + husban + husband + hvae + have + hvaing + having + hvea + have + hwihc + which + hwile + while + hwole + whole + hydogen + hydrogen + hydropile + hydrophile + hydropilic + hydrophilic + hydropobe + hydrophobe + hydropobic + hydrophobic + hygeine + hygiene + hypocracy + hypocrisy + hypocrasy + hypocrisy + hypocricy + hypocrisy + hypocrit + hypocrite + hypocrits + hypocrites + i + I + iconclastic + iconoclastic + idaeidae + idea + idaes + ideas + idealogies + ideologies + idealogy + ideology + identicial + identical + identifers + identifiers + ideosyncratic + idiosyncratic + idesa + ideas + idiosyncracy + idiosyncrasy + illegimacy + illegitimacy + illegitmate + illegitimate + illess + illness + illiegal + illegal + illution + illusion + ilness + illness + ilogical + illogical + imagenary + imaginary + imagin + imagine + imaginery + imaginary + imcomplete + incomplete + imediately + immediately + imense + immense + immediatley + immediately + immediatly + immediately + immidately + immediately + immidiately + immediately + immitate + imitate + immitated + imitated + immitating + imitating + immitator + imitator + immunosupressant + immunosuppressant + impecabbly + impeccably + impedence + impedance + implamenting + implementing + impliment + implement + implimented + implemented + imploys + employs + importamt + important + imprioned + imprisoned + imprisonned + imprisoned + improvision + improvisation + improvments + improvements + inablility + inability + inaccessable + inaccessible + inadiquate + inadequate + inadquate + inadequate + inadvertant + inadvertent + inadvertantly + inadvertently + inagurated + inaugurated + inaguration + inauguration + inappropiate + inappropriate + inaugures + inaugurates + inbalance + imbalance + inbalanced + imbalanced + inbetween + between + incarcirated + incarcerated + incidentially + incidentally + incidently + incidentally + inclreased + increased + includ + include + includng + including + incompatabilities + incompatibilities + incompatability + incompatibility + incompatable + incompatible + incompatablities + incompatibilities + incompatablity + incompatibility + incompatiblities + incompatibilities + incompatiblity + incompatibility + incompetance + incompetence + incompetant + incompetent + incomptable + incompatible + incomptetent + incompetent + inconsistant + inconsistent + incoroporated + incorporated + incorperation + incorporation + incorportaed + incorporated + incorprates + incorporates + incorruptable + incorruptible + incramentally + incrementally + increadible + incredible + incredable + incredible + inctroduce + introduce + inctroduced + introduced + incuding + including + incunabla + incunabula + indefinately + indefinitely + indefineable + undefinable + indefinitly + indefinitely + indentical + identical + indepedantly + independently + indepedence + independence + independance + independence + independant + independent + independantly + independently + independece + independence + independendet + independent + indespensable + indispensable + indespensible + indispensable + indictement + indictment + indigineous + indigenous + indipendence + independence + indipendent + independent + indipendently + independently + indispensible + indispensable + indisputible + indisputable + indisputibly + indisputably + indite + indict + individualy + individually + indpendent + independent + indpendently + independently + indulgue + indulge + indutrial + industrial + indviduals + individuals + inefficienty + inefficiently + inevatible + inevitable + inevitible + inevitable + inevititably + inevitably + infalability + infallibility + infallable + infallible + infectuous + infectious + infered + inferred + infilitrate + infiltrate + infilitrated + infiltrated + infilitration + infiltration + infinit + infinite + inflamation + inflammation + influencial + influential + influented + influenced + infomation + information + informtion + information + infrantryman + infantryman + infrigement + infringement + ingenius + ingenious + ingreediants + ingredients + inhabitans + inhabitants + inherantly + inherently + inheritence + inheritance + inital + initial + initally + initially + initation + initiation + initiaitive + initiative + inlcuding + including + inmigrant + immigrant + inmigrants + immigrants + innoculated + inoculated + inocence + innocence + inofficial + unofficial + inot + into + inpeach + impeach + inpolite + impolite + inprisonment + imprisonment + inproving + improving + insectiverous + insectivorous + insensative + insensitive + inseperable + inseparable + insistance + insistence + insitution + institution + insitutions + institutions + inspite + in spite + instade + instead + instatance + instance + institue + institute + instuction + instruction + instuments + instruments + instutionalized + institutionalized + instutions + intuitions + insurence + insurance + intelectual + intellectual + inteligence + intelligence + inteligent + intelligent + intenational + international + intented + intended + intepretation + interpretation + intepretator + interpretor + interational + international + interbread + interbreed + interchangable + interchangeable + interchangably + interchangeably + intercontinetal + intercontinental + intered + interred + interelated + interrelated + interferance + interference + interfereing + interfering + intergrated + integrated + intergration + integration + interm + interim + internation + international + interpet + interpret + interrim + interim + interrugum + interregnum + intertaining + entertaining + interupt + interrupt + intervines + intervenes + intevene + intervene + intial + initial + intially + initially + intrduced + introduced + intrest + interest + introdued + introduced + intruduced + introduced + intrument + instrument + intrumental + instrumental + intruments + instruments + intrusted + entrusted + intutive + intuitive + intutively + intuitively + inudstry + industry + inventer + inventor + invertibrates + invertebrates + investingate + investigate + involvment + involvement + irelevent + irrelevant + iresistable + irresistible + iresistably + irresistibly + iresistible + irresistible + iresistibly + irresistibly + iritable + irritable + iritated + irritated + ironicly + ironically + irregardless + regardless + irrelevent + irrelevant + irreplacable + irreplaceable + irresistable + irresistible + irresistably + irresistibly + isnt + isn't + issueing + issuing + itnroduced + introduced + iunior + junior + iwll + will + iwth + with + jaques + jacques + jeapardy + jeopardy + jewllery + jewellery + jouney + journey + journied + journeyed + journies + journeys + jstu + just + jsut + just + judical + judicial + judisuary + judiciary + juducial + judicial + juristiction + jurisdiction + juristictions + jurisdictions + kindergarden + kindergarten + klenex + kleenex + knifes + knives + knive + knife + knowlege + knowledge + knowlegeable + knowledgeable + knwo + know + knwos + knows + konw + know + konws + knows + kwno + know + labatory + laboratory + labratory + laboratory + laguage + language + laguages + languages + larg + large + largst + largest + larrry + larry + lastr + last + lattitude + latitude + launhed + launched + lavae + larvae + layed + laid + lazyness + laziness + leage + league + leanr + learn + leathal + lethal + lefted + left + legitamate + legitimate + legitmate + legitimate + leibnitz + leibniz + lenght + length + leran + learn + lerans + learns + leutenant + lieutenant + levetate + levitate + levetated + levitated + levetates + levitates + levetating + levitating + levle + level + liasion + liaison + liason + liaison + liasons + liaisons + libary + library + libell + libel + libguistic + linguistic + libguistics + linguistics + libitarianisn + libertarianism + lieing + lying + liek + like + liekd + liked + liesure + leisure + lieuenant + lieutenant + lieved + lived + liftime + lifetime + lightyear + light year + lightyears + light years + likelyhood + likelihood + linnaena + linnaean + lippizaner + lipizzaner + liquify + liquefy + liscense + license + lisence + license + lisense + license + listners + listeners + litature + literature + literaly + literally + literture + literature + littel + little + litterally + literally + liuke + like + livley + lively + lmits + limits + loev + love + lonelyness + loneliness + longitudonal + longitudinal + lonley + lonely + lonly + lonely + loosing + losing + lotharingen + lothringen + lsat + last + lukid + likud + lveo + love + lvoe + love + maching + machine + mackeral + mackerel + magasine + magazine + magincian + magician + magnificient + magnificent + magolia + magnolia + mailny + mainly + maintainance + maintenance + maintainence + maintenance + maintance + maintenance + maintenence + maintenance + maintinaing + maintaining + maintioned + mentioned + majoroty + majority + maked + marked + makse + makes + maltesian + Maltese + mamal + mammal + mamalian + mammalian + managable + manageable + managment + management + maneouvre + manoeuvre + maneouvred + manoeuvred + maneouvres + manoeuvres + maneouvring + manoeuvring + manisfestations + manifestations + manoeuverability + maneuverability + manouver + maneuver + manouverability + maneuverability + manouverable + maneuverable + manouvers + maneuvers + mantained + maintained + manuever + maneuver + manuevers + maneuvers + manufacturedd + manufactured + manufature + manufacture + manufatured + manufactured + manufaturing + manufacturing + manuver + maneuver + mariage + marriage + marjority + majority + markes + marks + marketting + marketing + marmelade + marmalade + marrage + marriage + marraige + marriage + marrtyred + martyred + marryied + married + massmedia + mass media + masterbation + masturbation + mataphysical + metaphysical + materalists + materialist + mathamatics + mathematics + mathematican + mathematician + mathematicas + mathematics + matheticians + mathematicians + mathmatically + mathematically + mathmatician + mathematician + mathmaticians + mathematicians + mccarthyst + mccarthyist + mchanics + mechanics + meaninng + meaning + mear + wear + mechandise + merchandise + medacine + medicine + medeival + medieval + medevial + medieval + mediciney + mediciny + medievel + medieval + mediterainnean + mediterranean + meerkrat + meerkat + melieux + milieux + membranaphone + membranophone + memeber + member + menally + mentally + meranda + Miranda + mercentile + mercantile + messanger + messenger + messenging + messaging + metalic + metallic + metalurgic + metallurgic + metalurgical + metallurgical + metalurgy + metallurgy + metamorphysis + metamorphosis + metaphoricial + metaphorical + meterologist + meteorologist + meterology + meteorology + methaphor + metaphor + methaphors + metaphors + micoscopy + microscopy + midwifes + midwives + mileau + milieu + milennia + millennia + milennium + millennium + mileu + milieu + miliary + military + milion + million + miliraty + military + millenia + millennia + millenial + millennial + millenialism + millennialism + millenium + millennium + millepede + millipede + millioniare + millionaire + millitary + military + millon + million + miltary + military + minature + miniature + minerial + mineral + miniscule + minuscule + ministery + ministry + minstries + ministries + minstry + ministry + minumum + minimum + mirrorred + mirrored + miscelaneous + miscellaneous + miscellanious + miscellaneous + miscellanous + miscellaneous + mischeivous + mischievous + mischevious + mischievous + mischievious + mischievous + misdameanor + misdemeanor + misdameanors + misdemeanors + misdemenor + misdemeanor + misdemenors + misdemeanors + misfourtunes + misfortunes + misile + missile + mispell + misspell + mispelled + misspelled + mispelling + misspelling + missen + mizzen + missle + missile + missonary + missionary + misterious + mysterious + mistery + mystery + misteryous + mysterious + mkae + make + mkaes + makes + mkaing + making + mkea + make + moderm + modem + modle + model + moent + moment + moeny + money + mohammedans + muslims + moil + soil + moleclues + molecules + momento + memento + monestaries + monasteries + monestary + monastery + monickers + monikers + monolite + monolithic + montains + mountains + montanous + mountainous + monts + months + montypic + monotypic + moreso + more so + morgage + mortgage + morroccan + moroccan + morrocco + morocco + morroco + morocco + mortage + mortgage + mosture + moisture + motiviated + motivated + mounth + month + movei + movie + movment + movement + mroe + more + mucuous + mucous + muder + murder + mudering + murdering + muhammadan + muslim + multicultralism + multiculturalism + multipled + multiplied + multiplers + multipliers + munbers + numbers + muncipalities + municipalities + muncipality + municipality + munnicipality + municipality + muscels + muscles + muscial + musical + muscician + musician + muscicians + musicians + mutiliated + mutilated + myraid + myriad + mysef + myself + mysogynist + misogynist + mysogyny + misogyny + mysterous + mysterious + naieve + naive + naturaly + naturally + naturely + naturally + naturual + natural + naturually + naturally + neccesarily + necessarily + neccesary + necessary + neccessarily + necessarily + neccessary + necessary + neccessities + necessities + necesarily + necessarily + necesary + necessary + necessiate + necessitate + neglible + negligible + negligable + negligible + negociate + negotiate + negociation + negotiation + negociations + negotiations + negotation + negotiation + neice + niece + neigborhood + neighborhood + neigbour + neighbour + neigbourhood + neighbourhood + neolitic + neolithic + nessasarily + necessarily + nessecary + necessary + nestin + nesting + neverthless + nevertheless + newletters + newsletters + nickle + nickel + nightfa;; + nightfall + nightime + nighttime + nineth + ninth + ninteenth + nineteenth + ninties + 1990s + ninty + ninety + nkow + know + nkwo + know + nmae + name + noncombatents + noncombatants + nonsence + nonsense + nontheless + nonetheless + noone + no one + norhern + northern + northen + northern + northereastern + northeastern + notabley + notably + noteable + notable + noteably + notably + noteriety + notoriety + noth + north + nothern + northern + noticable + noticeable + noticably + noticeably + noticeing + noticing + noticible + noticeable + notwhithstanding + notwithstanding + noveau + nouveau + nowdays + nowadays + nowe + now + nto + not + nucular + nuclear + nuculear + nuclear + nuisanse + nuisance + numberous + numerous + nusance + nuisance + nutritent + nutrient + nutritents + nutrients + nuturing + nurturing + obediance + obedience + obediant + obedient + obession + obsession + obssessed + obsessed + obstacal + obstacle + obstancles + obstacles + obstruced + obstructed + ocasion + occasion + ocasional + occasional + ocasionally + occasionally + ocasionaly + occasionally + ocasioned + occasioned + ocasions + occasions + ocassion + occasion + ocassional + occasional + ocassionally + occasionally + ocassionaly + occasionally + ocassioned + occasioned + ocassions + occasions + occaison + occasion + occassion + occasion + occassional + occasional + occassionally + occasionally + occassionaly + occasionally + occassioned + occasioned + occassions + occasions + occationally + occasionally + occour + occur + occurance + occurrence + occurances + occurrences + occured + occurred + occurence + occurrence + occurences + occurrences + occuring + occurring + occurr + occur + occurrance + occurrence + occurrances + occurrences + octohedra + octahedra + octohedral + octahedral + octohedron + octahedron + ocuntries + countries + ocuntry + country + ocurr + occur + ocurrance + occurrence + ocurred + occurred + ocurrence + occurrence + offcers + officers + offcially + officially + offereings + offerings + offical + official + offically + officially + officals + officials + officaly + officially + officialy + officially + offred + offered + oftenly + often + oging + going + omision + omission + omited + omitted + omiting + omitting + omlette + omelette + ommision + omission + ommited + omitted + ommiting + omitting + ommitted + omitted + ommitting + omitting + omniverous + omnivorous + omniverously + omnivorously + omre + more + onot + note + onxy + onyx + onyl + only + openess + openness + oponent + opponent + oportunity + opportunity + opose + oppose + oposite + opposite + oposition + opposition + oppenly + openly + oppinion + opinion + opponant + opponent + oppononent + opponent + oppositition + opposition + oppossed + opposed + opprotunity + opportunity + opression + oppression + opressive + oppressive + opthalmic + ophthalmic + opthalmologist + ophthalmologist + opthalmology + ophthalmology + opthamologist + ophthalmologist + optmizations + optimizations + optomism + optimism + orded + ordered + organim + organism + organistion + organisation + organiztion + organization + orgin + origin + orginal + original + orginally + originally + orginize + organise + oridinarily + ordinarily + origanaly + originally + originall + original + originaly + originally + originially + originally + originnally + originally + origional + original + orignally + originally + orignially + originally + otehr + other + oublisher + publisher + ouevre + oeuvre + oustanding + outstanding + overshaddowed + overshadowed + overthere + over there + overwelming + overwhelming + overwheliming + overwhelming + owrk + work + owudl + would + oxigen + oxygen + oximoron + oxymoron + p0enis + penis + paide + paid + paitience + patience + palce + place + paleolitic + paleolithic + paliamentarian + parliamentarian + pallete + palette + pamflet + pamphlet + pamplet + pamphlet + pantomine + pantomime + paralel + parallel + paralell + parallel + paralelly + parallelly + paralely + parallelly + parallely + parallelly + paranthesis + parenthesis + paraphenalia + paraphernalia + parellels + parallels + parituclar + particular + parliment + parliament + parrakeets + parakeets + parralel + parallel + parrallel + parallel + parrallell + parallel + parrallelly + parallelly + parrallely + parallelly + partialy + partially + particually + particularly + particualr + particular + particuarly + particularly + particularily + particularly + particulary + particularly + pary + party + pased + passed + pasengers + passengers + passerbys + passersby + pasttime + pastime + pastural + pastoral + paticular + particular + pattented + patented + pavillion + pavilion + payed + paid + pblisher + publisher + pbulisher + publisher + peacefuland + peaceful and + peageant + pageant + peculure + peculiar + pedestrain + pedestrian + peformed + performed + peice + piece + penatly + penalty + penerator + penetrator + penisula + peninsula + penisular + peninsular + penninsula + peninsula + penninsular + peninsular + pennisula + peninsula + pensinula + peninsula + peom + poem + peoms + poems + peopel + people + peotry + poetry + perade + parade + percepted + perceived + percieve + perceive + percieved + perceived + perenially + perennially + perfomance + performance + perfomers + performers + performence + performance + performes + performed + perhasp + perhaps + perheaps + perhaps + perhpas + perhaps + peripathetic + peripatetic + peristent + persistent + perjery + perjury + perjorative + pejorative + permanant + permanent + permenant + permanent + permenantly + permanently + permissable + permissible + perogative + prerogative + peronal + personal + perosnality + personality + perphas + perhaps + perpindicular + perpendicular + perseverence + perseverance + persistance + persistence + persistant + persistent + personel + personnel + personell + personnel + personnell + personnel + persuded + persuaded + persue + pursue + persued + pursued + persuing + pursuing + persuit + pursuit + persuits + pursuits + pertubation + perturbation + pertubations + perturbations + pessiary + pessary + petetion + petition + phenomenom + phenomenon + phenomenonal + phenomenal + phenomenonly + phenomenally + phenomonenon + phenomenon + phenomonon + phenomenon + phenonmena + phenomena + philisopher + philosopher + philisophical + philosophical + philisophy + philosophy + phillosophically + philosophically + philospher + philosopher + philosphies + philosophies + philosphy + philosophy + phongraph + phonograph + phylosophical + philosophical + physicaly + physically + piblisher + publisher + pich + pitch + pilgrimmage + pilgrimage + pilgrimmages + pilgrimages + pinapple + pineapple + pinnaple + pineapple + pinoneered + pioneered + plagarism + plagiarism + planation + plantation + planed + planned + plantiff + plaintiff + plateu + plateau + plausable + plausible + playright + playwright + playwrite + playwright + playwrites + playwrights + pleasent + pleasant + plebicite + plebiscite + plesant + pleasant + poenis + penis + poeoples + peoples + poety + poetry + poisin + poison + polical + political + polinator + pollinator + polinators + pollinators + politican + politician + politicans + politicians + poltical + political + polute + pollute + poluted + polluted + polutes + pollutes + poluting + polluting + polution + pollution + polyphonyic + polyphonic + polysaccaride + polysaccharide + polysaccharid + polysaccharide + pomegranite + pomegranate + pomotion + promotion + poportional + proportional + popoulation + population + popularaty + popularity + populare + popular + populer + popular + portait + portrait + portayed + portrayed + portraing + portraying + portuguease + portuguese + portugues + Portuguese + posess + possess + posessed + possessed + posesses + possesses + posessing + possessing + posession + possession + posessions + possessions + posion + poison + positon + position + possable + possible + possably + possibly + posseses + possesses + possesing + possessing + possesion + possession + possessess + possesses + possibile + possible + possibilty + possibility + possiblility + possibility + possiblilty + possibility + possiblities + possibilities + possiblity + possibility + possition + position + posthomous + posthumous + postion + position + postive + positive + potatos + potatoes + potrait + portrait + potrayed + portrayed + poulations + populations + poverful + powerful + poweful + powerful + powerfull + powerful + ppublisher + publisher + practial + practical + practially + practically + practicaly + practically + practicioner + practitioner + practicioners + practitioners + practicly + practically + practioner + practitioner + practioners + practitioners + prairy + prairie + prarie + prairie + praries + prairies + pratice + practice + preample + preamble + precedessor + predecessor + preceed + precede + preceeded + preceded + preceeding + preceding + preceeds + precedes + precentage + percentage + precice + precise + precisly + precisely + precurser + precursor + predecesors + predecessors + predicatble + predictable + predicitons + predictions + predomiantly + predominately + prefered + preferred + prefering + preferring + preferrably + preferably + pregancies + pregnancies + preiod + period + preliferation + proliferation + premeire + premiere + premeired + premiered + premillenial + premillennial + preminence + preeminence + premission + permission + preocupation + preoccupation + prepair + prepare + prepartion + preparation + prepatory + preparatory + preperation + preparation + preperations + preparations + preriod + period + presedential + presidential + presense + presence + presidenital + presidential + presidental + presidential + presitgious + prestigious + prespective + perspective + prestigeous + prestigious + prestigous + prestigious + presumabely + presumably + presumibly + presumably + pretection + protection + prevelant + prevalent + preverse + perverse + previvous + previous + pricipal + principal + priciple + principle + priestood + priesthood + primarly + primarily + primative + primitive + primatively + primitively + primatives + primitives + primordal + primordial + priveledges + privileges + privelege + privilege + priveleged + privileged + priveleges + privileges + privelige + privilege + priveliged + privileged + priveliges + privileges + privelleges + privileges + privilage + privilege + priviledge + privilege + priviledges + privileges + privledge + privilege + privte + private + probabilaty + probability + probablistic + probabilistic + probablly + probably + probalibity + probability + probaly + probably + probelm + problem + proccess + process + proccessing + processing + procede + proceed + proceded + proceeded + procedes + proceeds + procedger + procedure + proceding + proceeding + procedings + proceedings + proceedure + procedure + proces + process + processer + processor + proclaimation + proclamation + proclamed + proclaimed + proclaming + proclaiming + proclomation + proclamation + profesion + profession + profesor + professor + professer + professor + proffesed + professed + proffesion + profession + proffesional + professional + proffesor + professor + profilic + prolific + progessed + progressed + programable + programmable + progrom + program + progroms + programs + prohabition + prohibition + prologomena + prolegomena + prominance + prominence + prominant + prominent + prominantly + prominently + prominately + prominently + promiscous + promiscuous + promotted + promoted + pronomial + pronominal + pronouced + pronounced + pronounched + pronounced + pronounciation + pronunciation + proove + prove + prooved + proved + prophacy + prophecy + propietary + proprietary + propmted + prompted + propoganda + propaganda + propogate + propagate + propogates + propagates + propogation + propagation + propostion + proposition + propotions + proportions + propper + proper + propperly + properly + proprietory + proprietary + proseletyzing + proselytizing + protaganist + protagonist + protaganists + protagonists + protocal + protocol + protoganist + protagonist + protrayed + portrayed + protruberance + protuberance + protruberances + protuberances + prouncements + pronouncements + provacative + provocative + provded + provided + provicial + provincial + provinicial + provincial + provisiosn + provision + provisonal + provisional + proximty + proximity + pseudononymous + pseudonymous + pseudonyn + pseudonym + psuedo + pseudo + psycology + psychology + psyhic + psychic + pubilsher + publisher + pubisher + publisher + publiaher + publisher + publically + publicly + publicaly + publicly + publicher + publisher + publihser + publisher + publisehr + publisher + publiser + publisher + publisger + publisher + publisheed + published + publisherr + publisher + publishher + publisher + publishor + publisher + publishre + publisher + publissher + publisher + publlisher + publisher + publsiher + publisher + publusher + publisher + puchasing + purchasing + pulisher + publisher + pumkin + pumpkin + puplisher + publisher + puritannical + puritanical + purposedly + purposely + purpotedly + purportedly + pursuade + persuade + pursuaded + persuaded + pursuades + persuades + pususading + persuading + puting + putting + pwoer + power + pyscic + psychic + qtuie + quiet + quantaty + quantity + quantitiy + quantity + quarantaine + quarantine + questonable + questionable + quicklyu + quickly + quinessential + quintessential + quitted + quit + quizes + quizzes + qutie + quiet + rabinnical + rabbinical + racaus + raucous + radiactive + radioactive + radify + ratify + raelly + really + rarified + rarefied + reaccurring + recurring + reacing + reaching + reacll + recall + readmition + readmission + realitvely + relatively + realsitic + realistic + realtions + relations + realy + really + realyl + really + reasearch + research + rebiulding + rebuilding + rebllions + rebellions + rebounce + rebound + reccomend + recommend + reccomendations + recommendations + reccomended + recommended + reccomending + recommending + reccommend + recommend + reccommended + recommended + reccommending + recommending + reccuring + recurring + receeded + receded + receeding + receding + receivedfrom + received from + recepient + recipient + recepients + recipients + receving + receiving + rechargable + rechargeable + reched + reached + recide + reside + recided + resided + recident + resident + recidents + residents + reciding + residing + reciepents + recipients + reciept + receipt + recieve + receive + recieved + received + reciever + receiver + recievers + receivers + recieves + receives + recieving + receiving + recipiant + recipient + recipiants + recipients + recived + received + recivership + receivership + recogise + recognise + recogize + recognize + recomend + recommend + recomended + recommended + recomending + recommending + recomends + recommends + recommedations + recommendations + reconaissance + reconnaissance + reconcilation + reconciliation + reconized + recognized + reconnaisance + reconnaissance + reconnaissence + reconnaissance + recontructed + reconstructed + recordproducer + record producer + recquired + required + recrational + recreational + recrod + record + recuiting + recruiting + recuring + recurring + recurrance + recurrence + rediculous + ridiculous + reedeming + redeeming + reenforced + reinforced + refect + reflect + refedendum + referendum + referal + referral + referece + reference + refereces + references + refered + referred + referemce + reference + referemces + references + referencs + references + referenece + reference + refereneced + referenced + refereneces + references + referiang + referring + refering + referring + refernce + references + refernces + references + referrence + reference + referrences + references + referrs + refers + reffered + referred + refference + reference + reffering + referring + refrence + reference + refrences + references + refrers + refers + refridgeration + refrigeration + refridgerator + refrigerator + refromist + reformist + refusla + refusal + regardes + regards + regluar + regular + reguarly + regularly + regulaion + regulation + regulaotrs + regulators + regularily + regularly + rehersal + rehearsal + reicarnation + reincarnation + reigining + reigning + reknown + renown + reknowned + renowned + rela + real + relaly + really + relatiopnship + relationship + relativly + relatively + relected + reelected + releive + relieve + releived + relieved + releiver + reliever + releses + releases + relevence + relevance + relevent + relevant + reliablity + reliability + relient + reliant + religeous + religious + religous + religious + religously + religiously + relinqushment + relinquishment + relitavely + relatively + relized + realized + relpacement + replacement + remaing + remaining + remeber + remember + rememberable + memorable + rememberance + remembrance + remembrence + remembrance + remenant + remnant + remenicent + reminiscent + reminent + remnant + reminescent + reminiscent + reminscent + reminiscent + reminsicent + reminiscent + rendevous + rendezvous + rendezous + rendezvous + renedered + rende + renewl + renewal + rennovate + renovate + rennovated + renovated + rennovating + renovating + rennovation + renovation + rentors + renters + reoccurrence + recurrence + reorganision + reorganisation + repatition + repetition + repectively + respectively + repeition + repetition + repentence + repentance + repentent + repentant + repeteadly + repeatedly + repetion + repetition + repid + rapid + reponse + response + reponsible + responsible + reportadly + reportedly + represantative + representative + representive + representative + representives + representatives + reproducable + reproducible + reprtoire + repertoire + repsectively + respectively + reptition + repetition + requirment + requirement + requred + required + resaurant + restaurant + resembelance + resemblance + resembes + resembles + resemblence + resemblance + resevoir + reservoir + residental + residential + resignement + resignment + resistable + resistible + resistence + resistance + resistent + resistant + respectivly + respectively + responce + response + responibilities + responsibilities + responisble + responsible + responnsibilty + responsibility + responsability + responsibility + responsibile + responsible + responsibilites + responsibilities + responsiblities + responsibilities + responsiblity + responsibility + ressemblance + resemblance + ressemble + resemble + ressembled + resembled + ressemblence + resemblance + ressembling + resembling + resssurecting + resurrecting + ressurect + resurrect + ressurected + resurrected + ressurection + resurrection + ressurrection + resurrection + restarant + restaurant + restarants + restaurants + restaraunt + restaurant + restaraunteur + restaurateur + restaraunteurs + restaurateurs + restaraunts + restaurants + restauranteurs + restaurateurs + restauration + restoration + restauraunt + restaurant + resteraunt + restaurant + resteraunts + restaurants + resticted + restricted + restraunt + restraint + resturant + restaurant + resturants + restaurants + resturaunt + restaurant + resturaunts + restaurants + resurecting + resurrecting + retalitated + retaliated + retalitation + retaliation + retreive + retrieve + returnd + returned + revaluated + reevaluated + reveiw + review + reveral + reversal + reversable + reversible + revolutionar + revolutionary + rewitten + rewritten + rewriet + rewrite + rference + reference + rferences + references + rhymme + rhyme + rhythem + rhythm + rhythim + rhythm + rhytmic + rhythmic + rigourous + rigorous + rininging + ringing + rised + rose + rococco + rococo + rocord + record + roomate + roommate + rougly + roughly + rucuperate + recuperate + rudimentatry + rudimentary + rulle + rule + runing + running + runnung + running + russina + Russian + rwite + write + rythem + rhythm + rythim + rhythm + rythm + rhythm + rythmic + rhythmic + rythyms + rhythms + sacrafice + sacrifice + sacreligious + sacrilegious + sacrifical + sacrificial + saftey + safety + safty + safety + salery + salary + sanctionning + sanctioning + sandwhich + sandwich + santioned + sanctioned + sargant + sergeant + sargeant + sergeant + satelite + satellite + satelites + satellites + satisfactority + satisfactorily + satric + satiric + satrical + satirical + satrically + satirically + sattelite + satellite + sattelites + satellites + saught + sought + saveing + saving + saxaphone + saxophone + scaleable + scalable + scandanavia + Scandinavia + scaricity + scarcity + scavanged + scavenged + schedual + schedule + scholarhip + scholarship + scholarstic + scholastic + scientfic + scientific + scientifc + scientific + scientis + scientist + scince + science + scinece + science + scirpt + script + scoll + scroll + screenwrighter + screenwriter + scrutinity + scrutiny + scuptures + sculptures + seach + search + seached + searched + seaches + searches + secratary + secretary + secretery + secretary + sedereal + sidereal + seeked + sought + segementation + segmentation + seguoys + segues + seige + siege + seing + seeing + seinor + senior + seldomly + seldom + senarios + scenarios + senstive + sensitive + sensure + censure + seperate + separate + seperated + separated + seperately + separately + seperates + separates + seperating + separating + seperation + separation + seperatism + separatism + seperatist + separatist + sepina + subpoena + sergent + sergeant + settelement + settlement + settlment + settlement + severeal + several + severley + severely + severly + severely + sevice + service + shadasloo + shadaloo + shaddow + shadow + shadoloo + shadaloo + shamen + shaman + sheat + sheath + sheild + shield + sherif + sheriff + shineing + shining + shiped + shipped + shiping + shipping + shopkeeepers + shopkeepers + shorly + shortly + shortwhile + short while + shoudl + should + shoudln + shouldn't + shouldnt + shouldn't + shreak + shriek + shrinked + shrunk + sicne + since + sideral + sidereal + siezure + seizure + siezures + seizures + siginificant + significant + signficant + significant + signficiant + significant + signfies + signifies + signifantly + significantly + significently + significantly + signifigant + significant + signifigantly + significantly + signitories + signatories + signitory + signatory + similarily + similarly + similiar + similar + similiarity + similarity + similiarly + similarly + simmilar + similar + simpley + simply + simplier + simpler + simultanous + simultaneous + simultanously + simultaneously + sincerley + sincerely + singsog + singsong + sinse + since + skateing + skating + slaugterhouses + slaughterhouses + slighly + slightly + slowy + slowly + smae + same + smealting + smelting + smoe + some + sneeks + sneaks + snese + sneeze + socalism + socialism + socities + societies + soem + some + sofware + software + sohw + show + soilders + soldiers + solatary + solitary + soley + solely + soliders + soldiers + soliliquy + soliloquy + soluable + soluble + somene + someone + somtimes + sometimes + somwhere + somewhere + sophicated + sophisticated + sophmore + sophomore + sorceror + sorcerer + sorrounding + surrounding + sotry + story + sotyr + story + soudn + sound + soudns + sounds + sould + could + sountrack + soundtrack + sourth + south + sourthern + southern + souvenier + souvenir + souveniers + souvenirs + soveits + soviets + sovereignity + sovereignty + soverign + sovereign + soverignity + sovereignty + soverignty + sovereignty + spainish + Spanish + speach + speech + specfic + specific + speciallized + specialized + specifiying + specifying + speciman + specimen + spectauclar + spectacular + spectaulars + spectaculars + spectum + spectrum + speices + species + spendour + splendour + spermatozoan + spermatozoon + spoace + space + sponser + sponsor + sponsered + sponsored + spontanous + spontaneous + sponzored + sponsored + spoonfulls + spoonfuls + sppeches + speeches + spreaded + spread + sprech + speech + spred + spread + spriritual + spiritual + spritual + spiritual + sqaure + square + stablility + stability + stainlees + stainless + staion + station + standars + standards + stange + strange + startegic + strategic + startegies + strategies + startegy + strategy + stateman + statesman + statememts + statements + statment + statement + steriods + steroids + sterotypes + stereotypes + stilus + stylus + stingent + stringent + stiring + stirring + stirrs + stirs + stlye + style + stomache + stomach + stong + strong + stopry + story + storeis + stories + storise + stories + stornegst + strongest + stoyr + story + stpo + stop + stradegies + strategies + stradegy + strategy + strat + start + stratagically + strategically + streemlining + streamlining + stregth + strength + strenghen + strengthen + strenghened + strengthened + strenghening + strengthening + strenght + strength + strenghten + strengthen + strenghtened + strengthened + strenghtening + strengthening + strengtened + strengthened + strenous + strenuous + strictist + strictest + strikely + strikingly + strnad + strand + stroy + story + structual + structural + stubborness + stubbornness + stucture + structure + stuctured + structured + studdy + study + studing + studying + stuggling + struggling + sturcture + structure + subcatagories + subcategories + subcatagory + subcategory + subconsiously + subconsciously + subjudgation + subjugation + submachne + submachine + subpecies + subspecies + subsidary + subsidiary + subsiduary + subsidiary + subsquent + subsequent + subsquently + subsequently + substace + substance + substancial + substantial + substatial + substantial + substituded + substituted + substract + subtract + substracted + subtracted + substracting + subtracting + substraction + subtraction + substracts + subtracts + subtances + substances + subterranian + subterranean + suburburban + suburban + succceeded + succeeded + succcesses + successes + succedded + succeeded + succeded + succeeded + succeds + succeeds + succesful + successful + succesfully + successfully + succesfuly + successfully + succesion + succession + succesive + successive + successfull + successful + successully + successfully + succsess + success + succsessfull + successful + suceed + succeed + suceeded + succeeded + suceeding + succeeding + suceeds + succeeds + sucesful + successful + sucesfully + successfully + sucesfuly + successfully + sucesion + succession + sucess + success + sucesses + successes + sucessful + successful + sucessfull + successful + sucessfully + successfully + sucessfuly + successfully + sucession + succession + sucessive + successive + sucessor + successor + sucessot + successor + sucide + suicide + sucidial + suicidal + sufferage + suffrage + sufferred + suffered + sufferring + suffering + sufficent + sufficient + sufficently + sufficiently + sumary + summary + sunglases + sunglasses + suop + soup + superceeded + superseded + superintendant + superintendent + suphisticated + sophisticated + suplimented + supplemented + supose + suppose + suposed + supposed + suposedly + supposedly + suposes + supposes + suposing + supposing + supplamented + supplemented + suppliementing + supplementing + suppoed + supposed + supposingly + supposedly + suppy + supply + supress + suppress + supressed + suppressed + supresses + suppresses + supressing + suppressing + suprise + surprise + suprised + surprised + suprising + surprising + suprisingly + surprisingly + suprize + surprise + suprized + surprised + suprizing + surprising + suprizingly + surprisingly + surfce + surface + surley + surely + suround + surround + surounded + surrounded + surounding + surrounding + suroundings + surroundings + surounds + surrounds + surplanted + supplanted + surpress + suppress + surpressed + suppressed + surprize + surprise + surprized + surprised + surprizing + surprising + surprizingly + surprisingly + surrended + surrendered + surrepetitious + surreptitious + surrepetitiously + surreptitiously + surreptious + surreptitious + surreptiously + surreptitiously + surronded + surrounded + surrouded + surrounded + surrouding + surrounding + surrundering + surrendering + surveilence + surveillance + surveill + surveil + surveyer + surveyor + surviver + survivor + survivers + survivors + survivied + survived + suseptable + susceptible + suseptible + susceptible + suspention + suspension + swaer + swear + swaers + swears + swepth + swept + swiming + swimming + syas + says + symetrical + symmetrical + symetrically + symmetrically + symetry + symmetry + symettric + symmetric + symmetral + symmetric + symmetricaly + symmetrically + synagouge + synagogue + syncronization + synchronization + synonomous + synonymous + synonymns + synonyms + synphony + symphony + syphyllis + syphilis + sypmtoms + symptoms + syrap + syrup + sysmatically + systematically + sytem + system + sytle + style + tabacco + tobacco + tahn + than + taht + that + talekd + talked + targetted + targeted + targetting + targeting + tast + taste + tath + that + tattooes + tattoos + taxanomic + taxonomic + taxanomy + taxonomy + teached + taught + techician + technician + techicians + technicians + techiniques + techniques + technitian + technician + technnology + technology + technolgy + technology + teh + the + tehy + they + telelevision + television + televsion + television + telphony + telephony + temerature + temperature + tempalte + template + tempaltes + templates + temparate + temperate + temperarily + temporarily + temperment + temperament + tempertaure + temperature + temperture + temperature + temprary + temporary + tenacle + tentacle + tenacles + tentacles + tendacy + tendency + tendancies + tendencies + tendancy + tendency + tennisplayer + tennis player + tepmorarily + temporarily + terrestial + terrestrial + terriories + territories + terriory + territory + territorist + terrorist + territoy + territory + terroist + terrorist + testiclular + testicular + tghe + the + thast + that's + theather + theater + theese + these + theif + thief + theives + thieves + themselfs + themselves + themslves + themselves + ther + there + therafter + thereafter + therby + thereby + theri + their + theyre + they're + thgat + that + thge + the + thier + their + thign + thing + thigns + things + thigsn + things + thikn + think + thikning + thinking + thikns + thinks + thiunk + think + thn + then + thna + than + thne + then + thnig + thing + thnigs + things + thoughout + throughout + threatend + threatened + threatning + threatening + threee + three + threshhold + threshold + thrid + third + throrough + thorough + throughly + thoroughly + throught + throat + througout + throughout + thru + through + thsi + this + thsoe + those + thta + that + thyat + that + tiem + time + tihkn + think + tihs + this + timne + time + tiome + time + tje + the + tjhe + the + tjpanishad + upanishad + tkae + take + tkaes + takes + tkaing + taking + tlaking + talking + tobbaco + tobacco + todays + today's + todya + today + toghether + together + toke + took + tolerence + tolerance + tomatos + tomatoes + tommorow + tomorrow + tommorrow + tomorrow + tongiht + tonight + toriodal + toroidal + tormenters + tormentors + tornadoe + tornado + torpeados + torpedoes + torpedos + torpedoes + tothe + to the + toubles + troubles + tounge + tongue + tourch + torch + towords + towards + towrad + toward + tradionally + traditionally + traditionaly + traditionally + traditionnal + traditional + traditition + tradition + tradtionally + traditionally + trafficed + trafficked + trafficing + trafficking + trafic + traffic + trancendent + transcendent + trancending + transcending + tranform + transform + tranformed + transformed + transcendance + transcendence + transcendant + transcendent + transcendentational + transcendental + transcripting + transcribing + transending + transcending + transesxuals + transsexuals + transfered + transferred + transfering + transferring + transformaton + transformation + transistion + transition + translater + translator + translaters + translators + transmissable + transmissible + transporation + transportation + tremelo + tremolo + tremelos + tremolos + triguered + triggered + triology + trilogy + troling + trolling + troup + troupe + troups + troops + truely + truly + trustworthyness + trustworthiness + turnk + trunk + tust + trust + twelth + twelfth + twon + town + twpo + two + tyhat + that + tyhe + they + typcial + typical + typicaly + typically + tyranies + tyrannies + tyrany + tyranny + tyrranies + tyrannies + tyrrany + tyranny + ubiquitious + ubiquitous + ublisher + publisher + uise + use + ultimely + ultimately + unacompanied + unaccompanied + unahppy + unhappy + unanymous + unanimous + unathorised + unauthorised + unavailible + unavailable + unballance + unbalance + unbeknowst + unbeknownst + unbeleivable + unbelievable + uncertainity + uncertainty + unchallengable + unchallengeable + unchangable + unchangeable + uncompetive + uncompetitive + unconcious + unconscious + unconciousness + unconsciousness + unconfortability + discomfort + uncontitutional + unconstitutional + unconvential + unconventional + undecideable + undecidable + understoon + understood + undesireable + undesirable + undetecable + undetectable + undoubtely + undoubtedly + undreground + underground + uneccesary + unnecessary + unecessary + unnecessary + unequalities + inequalities + unforetunately + unfortunately + unforgetable + unforgettable + unforgiveable + unforgivable + unfortunatley + unfortunately + unfortunatly + unfortunately + unfourtunately + unfortunately + unihabited + uninhabited + unilateraly + unilaterally + unilatreal + unilateral + unilatreally + unilaterally + uninterruped + uninterrupted + uninterupted + uninterrupted + univeral + universal + univeristies + universities + univeristy + university + univerity + university + universtiy + university + univesities + universities + univesity + university + unkown + unknown + unlikey + unlikely + unmanouverable + unmaneuverable + unmistakeably + unmistakably + unneccesarily + unnecessarily + unneccesary + unnecessary + unneccessarily + unnecessarily + unneccessary + unnecessary + unnecesarily + unnecessarily + unnecesary + unnecessary + unoffical + unofficial + unoperational + nonoperational + unoticeable + unnoticeable + unplease + displease + unplesant + unpleasant + unprecendented + unprecedented + unprecidented + unprecedented + unrepentent + unrepentant + unrepetant + unrepentant + unrepetent + unrepentant + unsed + unused + unsubstanciated + unsubstantiated + unsuccesful + unsuccessful + unsuccesfully + unsuccessfully + unsuccessfull + unsuccessful + unsucesful + unsuccessful + unsucesfuly + unsuccessfully + unsucessful + unsuccessful + unsucessfull + unsuccessful + unsucessfully + unsuccessfully + unsuprised + unsurprised + unsuprising + unsurprising + unsuprisingly + unsurprisingly + unsuprized + unsurprised + unsuprizing + unsurprising + unsuprizingly + unsurprisingly + unsurprized + unsurprised + unsurprizing + unsurprising + unsurprizingly + unsurprisingly + untill + until + untranslateable + untranslatable + unuseable + unusable + unusuable + unusable + unviersity + university + unwarrented + unwarranted + unweildly + unwieldy + unwieldly + unwieldy + upcomming + upcoming + upgradded + upgraded + upto + up to + usally + usually + useage + usage + usefull + useful + usefuly + usefully + useing + using + usualy + usually + ususally + usually + vaccum + vacuum + vaccume + vacuum + vacinity + vicinity + vaguaries + vagaries + vaieties + varieties + vailidty + validity + valetta + valletta + valuble + valuable + valueable + valuable + varations + variations + varient + variant + variey + variety + varing + varying + varities + varieties + varity + variety + vasall + vassal + vasalls + vassals + vegatarian + vegetarian + vegitable + vegetable + vegitables + vegetables + vegtable + vegetable + vehicule + vehicle + vell + well + venemous + venomous + vengance + vengeance + vengence + vengeance + verfication + verification + verison + version + verisons + versions + vermillion + vermilion + versitilaty + versatility + versitlity + versatility + vetween + between + veyr + very + vigeur + vigor + vigilence + vigilance + vigourous + vigorous + villian + villain + villification + vilification + villify + vilify + villin + villain + vincinity + vicinity + violentce + violence + virtualy + virtually + virutal + virtual + virutally + virtually + visable + visible + visably + visibly + visting + visiting + vistors + visitors + vitories + victories + volcanoe + volcano + voleyball + volleyball + volontary + voluntary + volonteer + volunteer + volonteered + volunteered + volonteering + volunteering + volonteers + volunteers + volounteer + volunteer + volounteered + volunteered + volounteering + volunteering + volounteers + volunteers + volumne + volume + vreity + variety + vrey + very + vriety + variety + vulnerablility + vulnerability + vyer + very + vyre + very + waht + what + wanna + want to + warantee + warranty + wardobe + wardrobe + warrent + warrant + warrriors + warriors + wasnt + wasn't + wass + was + watn + want + wayword + wayward + weaponary + weaponry + weas + was + wehn + when + weild + wield + weilded + wielded + wendsay + Wednesday + wensday + Wednesday + wereabouts + whereabouts + whant + want + whants + wants + whcih + which + wheras + whereas + wherease + whereas + whereever + wherever + whic + which + whihc + which + whith + with + whlch + which + whn + when + wholey + wholly + wholy + holy + whta + what + whther + whether + wich + which + widesread + widespread + wief + wife + wierd + weird + wiew + view + wih + with + wiht + with + wille + will + willingless + willingness + wirting + writing + withdrawl + withdrawal + witheld + withheld + withh + with + withing + within + withold + withhold + witht + with + witn + with + wiull + will + wnat + want + wnated + wanted + wnats + wants + wohle + whole + wokr + work + wokring + working + wonderfull + wonderful + wont + won't + wordlwide + worldwide + workststion + workstation + worls + world + worstened + worsened + woudl + would + wresters + wrestlers + wriet + write + writen + written + wroet + wrote + wrok + work + wroking + working + wtih + with + wupport + support + xenophoby + xenophobia + yaching + yachting + yaer + year + yaerly + yearly + yaers + years + yatch + yacht + yearm + year + yeasr + years + yeild + yield + yeilding + yielding + yera + year + yeras + years + yersa + years + yotube + YouTube + youre + you're + youseff + yousef + youself + yourself + ytou + you + yuo + you + zeebra + zebra + + + + diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index db797127e..52b98e92d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -738,7 +738,7 @@ LiruLegacyLogLaunch Comment - When opening a chat log, open in an external text editor instead of a browser floater(Windows Only). + When opening a chat log, open in an external text editor instead of a browser floater(Windows and Mac Only). Persist 1 Type @@ -834,6 +834,17 @@ Value 0 + LiruMouselookHidesToolbar + + Comment + Whether or not the toolbar will be hidden in mouselook + Persist + 1 + Type + Boolean + Value + 1 + LiruMouselookMenu Comment @@ -893,6 +904,19 @@ Value 0 + LiruRegionRestartMinimized + + Comment + Whether or not to spawn the region restart notice minimized (Useful for sim owners and people who need to pack up before leaving) + Persist + 1 + Type + Boolean + Value + 0 + IsCOA + 1 + LiruScriptErrorsStealFocus Comment @@ -1313,6 +1337,17 @@ This should be as low as possible, but too low may break functionality Value 1 + AnnounceBumps + + Comment + Announce if someone bumps into you. + Persist + 1 + Type + Boolean + Value + 0 + AnnounceSnapshots Comment @@ -2222,6 +2257,17 @@ This should be as low as possible, but too low may break functionality IsCOA 1 + UISndRestart + + Comment + Sound file for region restarting (uuid for sound asset) + Persist + 1 + Type + String + Value + 1e506d0c-4811-bdf3-5ec7-d624284c9040 + UISndSnapshot Comment @@ -2396,6 +2442,17 @@ This should be as low as possible, but too low may break functionality Value 1 + AllowSelectAvatar + + Comment + Allow selecting an avatar that you have modify rights on (via tag) while in edit mode to reposition them + Persist + 1 + Type + Boolean + Value + 0 + AllowTapTapHoldRun Comment @@ -2693,6 +2750,17 @@ This should be as low as possible, but too low may break functionality Value 0 + AutoReplace + + Comment + Replaces keywords with a configured word or phrase + Persist + 1 + Type + Boolean + Value + 0 + AutoAcceptAllNewInventory Comment @@ -7277,6 +7345,17 @@ This should be as low as possible, but too low may break functionality Value 24 + RadarColumnVoiceWidth + + Comment + Width for radar's voice status column + Persist + 1 + Type + S32 + Value + 24 + RadarColumnAgeWidth Comment @@ -7354,6 +7433,17 @@ This should be as low as possible, but too low may break functionality Value 0 + RadarColumnVoiceHidden + + Comment + Hide radar's voice status column + Persist + 1 + Type + Boolean + Value + 0 + RadarColumnAgeHidden Comment @@ -11123,22 +11213,6 @@ This should be as low as possible, but too low may break functionality Value 0 - PermissionsManagerRect - - Comment - Rectangle for permissions manager window - Persist - 1 - Type - Rect - Value - - 0 - 85 - 300 - 0 - - PickerContextOpacity Comment @@ -14559,9 +14633,9 @@ This should be as low as possible, but too low may break functionality ShowChatHistory Comment - + Open local chat window on login Persist - 0 + 1 Type Boolean Value @@ -14570,14 +14644,25 @@ This should be as low as possible, but too low may break functionality ShowCommunicate Comment - + Open communicate window on login Persist - 0 + 1 Type Boolean Value 0 + ShowContacts + + Comment + Open contacts window on login + Persist + 1 + Type + Boolean + Value + 0 + ShowConsoleWindow Comment diff --git a/indra/newview/app_settings/settings_ascent.xml b/indra/newview/app_settings/settings_ascent.xml index f2de17710..8288edc6b 100644 --- a/indra/newview/app_settings/settings_ascent.xml +++ b/indra/newview/app_settings/settings_ascent.xml @@ -91,6 +91,17 @@ Value 1 + AlchemyRegionRestartShake + + Comment + Shake the screen when the region restart floater is displayed + Persist + 1 + Type + Boolean + Value + 0 + AscentPowerfulWizard Comment @@ -741,6 +752,51 @@ Value 0 + ExodusMapRolloverCircleColor + + Comment + Color setting of circle for rollovers on the minimap. + Persist + 1 + Type + Color4 + Value + Value + + 1.0 + 1.0 + 1.0 + 0.05 + + + ExodusMapRolloverColor + + Comment + Color setting for rollovers on the minimap. + Persist + 1 + Type + Color4 + Value + Value + + 0.0 + 1.0 + 1.0 + 1.0 + + + ExodusMinimapAreaEffect + + Comment + Radius of the area of affect for the minimap, adjusted by shift scrolling over the minimap. + Persist + 1 + Type + F32 + Value + 3.5 + OBJExportNotifyFailed Comment @@ -796,5 +852,1001 @@ Value pages/login/ + + ToolbarVisibleAbout + + Comment + Whether or not the button for about is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAboutLand + + Comment + Whether or not the button for about land is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAboutRegion + + Comment + Whether or not the button for region/estate is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleActiveSpeakers + + Comment + Whether or not the button for active speakers is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAlwaysRun + + Comment + Whether or not the button for run is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAnimsExplorer + + Comment + Whether or not the button for anims explorer is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAO + + Comment + Whether or not the button for the AO Floater is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAppearance + + Comment + Whether or not the button for appearance is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAreaSearch + + Comment + Whether or not the button for areasearch is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAssetBlacklist + + Comment + Whether or not the button for asset blacklist is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleAutoReplace + + Comment + Whether or not the button for autoreplace is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleBeacons + + Comment + Whether or not the button for beacons is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleBuild + + Comment + Whether or not the button for build is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleBuyCurrency + + Comment + Whether or not the button for buy currency is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleBuyLand + + Comment + Whether or not the button for buy land is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleCameraControls + + Comment + Whether or not the button for camera controls is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleChatbar + + Comment + Whether or not the button for toggling the chatbar is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleChatHistory + + Comment + Whether or not the button for local chat history is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleCommunicate + + Comment + Whether or not the button for communicate floater is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleCommunicateIM + + Comment + Whether or not the flyout button for communicate is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleComplaintReporter + + Comment + Whether or not the button for abuse report is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleDayCycle + + Comment + Whether or not the button for day cycle editor is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleDebugAvatar + + Comment + Whether or not the button for debug avatar textures is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleDebugConsole + + Comment + Whether or not the button for the debug console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleDebugSettings + + Comment + Whether or not the button for debug settings is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleDisplayName + + Comment + Whether or not the button for display name is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleEditUI + + Comment + Whether or not the button for edit ui is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleEnvSettings + + Comment + Whether or not the button for the environment settings editor is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleFastTimers + + Comment + Whether or not the button for fast timers is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleFly + + Comment + Whether or not the button for fly is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleFontTest + + Comment + Whether or not the button for font test is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleFrameConsole + + Comment + Whether or not the button for the frame console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleFriends + + Comment + Whether or not the button for friends is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleGestures + + Comment + Whether or not the button for gestures is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleGodTools + + Comment + Whether or not the button for god tools is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleGridOptions + + Comment + Whether or not the button for grid options for the build tools is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleGroups + + Comment + Whether or not the button for groups is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleGroupTitles + + Comment + Whether or not the button for group titles is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + + ToolbarVisibleHelpTutorial + + Comment + Whether or not the button for the tutorial is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleHTTPConsole + + Comment + Whether or not the button for the http console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleInspect + + Comment + Whether or not the button for inspect is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleInventory + + Comment + Whether or not the button for inventory is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleInventoryFavs + + Comment + Whether or not the button for favorites is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleInventoryOutfits + + Comment + Whether or not the button for outfits is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleLagMeter + + Comment + Whether or not the button for lag meter is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleLocalAssets + + Comment + Whether or not the button for local textures is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMeanEvents + + Comment + Whether or not the button for bumps, pushes, and hits is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMediaFilter + + Comment + Whether or not the button for media filter is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMediaTicker + + Comment + Whether or not the button for the streaming audio display is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMemLeak + + Comment + Whether or not the button for memory leak is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMessageLog + + Comment + Whether or not the button for message log is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMiniMap + + Comment + Whether or not the button for the mini-map is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleMouselook + + Comment + Whether or not the button for mouselook is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMovementControls + + Comment + Whether or not the button for movement controls is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMuteList + + Comment + Whether or not the button for mute list is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleMyLand + + Comment + Whether or not the button for my land is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleOutbox + + Comment + Whether or not the button for outbox is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleNotificationsConsole + + Comment + Whether or not the button for the notifications console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleOutbox + + Comment + Whether or not the button for the merchant outbox is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleOutfit + + Comment + Whether or not the button for make outfit is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisiblePathfindingCharacters + + Comment + Whether or not the button for pathfinding characters is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisiblePathfindingLinksets + + Comment + Whether or not the button for pathfinding linksets is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisiblePermPrefs + + Comment + Whether or not the button for default upload permissions is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisiblePostProcess + + Comment + Whether or not the button for post-processing effects is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisiblePreferences + + Comment + Whether or not the button for preferences is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleRadar + + Comment + Whether or not the button for the radar is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleRegionDebugConsole + + Comment + Whether or not the button for the region debug console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleScriptErrors + + Comment + Whether or not the button for script errors is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleScriptInfo + + Comment + Whether or not the button for script info is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleSearch + + Comment + Whether or not the button for search is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleSit + + Comment + Whether or not the button for sit is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleSnapshot + + Comment + Whether or not the button for snapshot is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + ToolbarVisibleSoundExplorer + + Comment + Whether or not the button for the sound explorer is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleStatBar + + Comment + Whether or not the button for the statistics bar is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleTeleportHistory + + Comment + Whether or not the button for teleport history is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleTest + + Comment + Whether or not the button for the test floater is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleTextureCategoryConsole + + Comment + Whether or not the button for the texture category console is on the toolbar (requires a relog with AuditTexture true for the button to work) + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleTextureConsole + + Comment + Whether or not the button for the texture console is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleTextureSizeConsole + + Comment + Whether or not the button for the texture size console is on the toolbar (requires a relog with AuditTexture true for the button to work) + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleToolbarPrefs + + Comment + Whether or not the button for the floater to change buttons on the toolbar is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleVelocity + + Comment + Whether or not the button for velocity is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleVoiceEffect + + Comment + Whether or not the button for voice effects is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleWaterSettings + + Comment + Whether or not the button for the water editor is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleWeb + + Comment + Whether or not the button for the web browser is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleWindlight + + Comment + Whether or not the button for the windlight editor is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleWorldMap + + Comment + Whether or not the button for the world map is on the toolbar + Persist + 1 + Type + Boolean + Value + 1 + + + ToolbarVisibleRLVLocks + + Comment + Whether or not the button for RLVa Locks is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleRLVRestrictions + + Comment + Whether or not the button for RLVa Restrictions is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + ToolbarVisibleRLVStrings + + Comment + Whether or not the button for RLVa Strings is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + + diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index b5d15381d..295b4180d 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -406,6 +406,17 @@ Value This is an autoresponse! + AutoresponseOnlyIfAway + + Comment + When true, enabled autoresponses (not busy responses) will only be sent while in away (or Fake Away) mode. Does not apply to autoresponses to muted persons, they don't need to know you're away. + Persist + 1 + Type + Boolean + Value + 0 + BusyModeResponse Comment @@ -723,6 +734,16 @@ Value - + EmergencyTeleportLandmark + + Comment + UUID of the landmark to teleport to in the last twenty seconds before a region will restart, empty is none. + Persist + 1 + Type + String + Value + + diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index 57a5dd60e..dc8f0bc9b 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -37,6 +37,7 @@ #include "llagent.h" #include "llcolorswatch.h" #include "llcombobox.h" +#include "llfloaterautoreplacesettings.h" #include "llradiogroup.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" @@ -88,10 +89,8 @@ LLPrefsAscentChat::LLPrefsAscentChat() childSetEnabled("reset_antispam", started); getChild("reset_antispam")->setCommitCallback(boost::bind(NACLAntiSpamRegistry::purgeAllQueues)); - getChild("enable_as")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitEnableAS, this, _2)); - getChild("antispam_checkbox")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitDialogBlock, this, _1, _2)); - getChild("Group Invites")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitDialogBlock, this, _1, _2)); + getChild("autoreplace")->setCommitCallback(boost::bind(LLFloaterAutoReplaceSettings::showInstance, LLSD())); getChild("KeywordsOn")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitKeywords, this, _1)); getChild("KeywordsList")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitKeywords, this, _1)); getChild("KeywordsSound")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitKeywords, this, _1)); @@ -184,39 +183,6 @@ void LLPrefsAscentChat::onCommitTimeDate(LLUICtrl* ctrl) gSavedSettings.setString("TimestampFormat", timestamp); } -void LLPrefsAscentChat::onCommitEnableAS(const LLSD& value) -{ - bool enabled = value.asBoolean(); - childSetEnabled("spammsg_checkbox", enabled); - childSetEnabled("antispamtime", enabled); - childSetEnabled("antispamamount", enabled); - childSetEnabled("antispamsoundmulti", enabled); - childSetEnabled("antispamsoundpreloadmulti", enabled); - childSetEnabled("antispamnewlines", enabled); - childSetEnabled("Notify On Spam", enabled); -} - -void LLPrefsAscentChat::onCommitDialogBlock(LLUICtrl* ctrl, const LLSD& value) -{ - childSetEnabled("Group Fee Invites", !childGetValue("antispam_checkbox").asBoolean() && !childGetValue("Group Invites").asBoolean()); - bool enabled = value.asBoolean(); - if (ctrl->getName() == "antispam_checkbox") - { - childSetEnabled("Block All Dialogs From", !enabled); - childSetEnabled("Alerts", !enabled); - childSetEnabled("Friendship Offers", !enabled); - childSetEnabled("Group Invites", !enabled); - childSetEnabled("Group Notices", !enabled); - childSetEnabled("Item Offers", !enabled); - childSetEnabled("Scripts", !enabled); - childSetEnabled("Teleport Offers", !enabled); - childSetEnabled("Teleport Requests", !enabled); - childSetEnabled("Except those from:", !enabled); - childSetEnabled("My objects", !enabled); - childSetEnabled("My friends", !enabled); - } -} - void LLPrefsAscentChat::onCommitKeywords(LLUICtrl* ctrl) { if (ctrl->getName() == "KeywordsOn") @@ -392,26 +358,6 @@ void LLPrefsAscentChat::refresh() if (combo = getChild("speaker_namesystem_combobox")) combo->setCurrentByIndex(mSpeakerNames); - //Antispam ------------------------------------------------------------------------ - // sensitivity tuners - childSetEnabled("spammsg_checkbox", mEnableAS); - childSetEnabled("antispamtime", mEnableAS); - childSetEnabled("antispamamount", mEnableAS); - childSetEnabled("antispamsoundmulti", mEnableAS); - childSetEnabled("antispamsoundpreloadmulti", mEnableAS); - childSetEnabled("antispamnewlines", mEnableAS); - childSetEnabled("Notify On Spam", mEnableAS); - // dialog blocking tuners - childSetEnabled("Block All Dialogs From", !mBlockDialogSpam); - childSetEnabled("Alerts", !mBlockDialogSpam); - childSetEnabled("Friendship Offers", !mBlockDialogSpam); - childSetEnabled("Group Invites", !mBlockDialogSpam); - childSetEnabled("Group Fee Invites", !mBlockDialogSpam && !mBlockGroupInviteSpam); - childSetEnabled("Group Notices", !mBlockDialogSpam); - childSetEnabled("Item Offers", !mBlockDialogSpam); - childSetEnabled("Scripts", !mBlockDialogSpam); - childSetEnabled("Teleport Offers", !mBlockDialogSpam); - //Text Options ------------------------------------------------------------------------ combo = getChild("SpellBase"); diff --git a/indra/newview/ascentprefschat.h b/indra/newview/ascentprefschat.h index d3f324a60..bc45d71d7 100644 --- a/indra/newview/ascentprefschat.h +++ b/indra/newview/ascentprefschat.h @@ -52,8 +52,6 @@ protected: void onSpellEditCustom(); void onSpellBaseComboBoxCommit(const LLSD& value); void onCommitTimeDate(LLUICtrl* ctrl); - void onCommitEnableAS(const LLSD& value); - void onCommitDialogBlock(LLUICtrl* ctrl, const LLSD& value); void onCommitKeywords(LLUICtrl* ctrl); private: diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp index c287fea3e..6ae4a634a 100644 --- a/indra/newview/ascentprefssys.cpp +++ b/indra/newview/ascentprefssys.cpp @@ -51,33 +51,30 @@ LLPrefsAscentSys::LLPrefsAscentSys() LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_ascent_system.xml"); //General ----------------------------------------------------------------------------- - getChild("speed_rez_check")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); - getChild("double_click_teleport_check")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); getChild("show_look_at_check")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); - getChild("enable_clouds")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); getChild("power_user_check")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); getChild("power_user_confirm_check")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); //Command Line ------------------------------------------------------------------------ - getChild("chat_cmd_toggle")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLinePos")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineGround")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineHeight")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineTeleportHome")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineRezPlatform")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineCalc")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineClearChat")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineDrawDistance")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdTeleportToCam")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineKeyToName")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineOfferTp")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineMapTo")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("AscentCmdLineTP2")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("SinguCmdLineAway")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); - getChild("SinguCmdLineURL")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); + commit_callback_t lineEditorControl(boost::bind(&LLControlGroup::setString, boost::ref(gSavedSettings), boost::bind(&LLUICtrl::getName, _1), _2)); + getChild("AscentCmdLinePos")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineGround")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineHeight")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineTeleportHome")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineRezPlatform")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineCalc")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineClearChat")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineDrawDistance")->setCommitCallback(lineEditorControl); + getChild("AscentCmdTeleportToCam")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineKeyToName")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineOfferTp")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineMapTo")->setCommitCallback(lineEditorControl); + getChild("AscentCmdLineTP2")->setCommitCallback(lineEditorControl); + getChild("SinguCmdLineAway")->setCommitCallback(lineEditorControl); + getChild("SinguCmdLineURL")->setCommitCallback(lineEditorControl); //Security ---------------------------------------------------------------------------- - getChild("disable_click_sit_check")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); + getChild("UISndRestart")->setCommitCallback(lineEditorControl); //Build ------------------------------------------------------------------------------- getChild("next_owner_copy")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); @@ -101,21 +98,7 @@ void LLPrefsAscentSys::onCommitCheckBox(LLUICtrl* ctrl, const LLSD& value) const std::string name = ctrl->getName(); bool enabled = value.asBoolean(); - if (name == "speed_rez_check") - { - childSetEnabled("speed_rez_interval", enabled); - childSetEnabled("speed_rez_seconds", enabled); - } - else if (name == "double_click_teleport_check") - { - childSetEnabled("center_after_teleport_check", enabled); - childSetEnabled("offset_teleport_check", enabled); - } - else if (name == "enable_clouds") - { - childSetEnabled("enable_classic_clouds", enabled); - } - else if (name == "power_user_check") + if (name == "power_user_check") { childSetEnabled("power_user_confirm_check", enabled); childSetValue("power_user_confirm_check", false); @@ -135,10 +118,6 @@ void LLPrefsAscentSys::onCommitCheckBox(LLUICtrl* ctrl, const LLSD& value) LLFloaterChat::addChat(chat); } } - else if (name == "disable_click_sit_check") - { - childSetEnabled("disable_click_sit_own_check", !enabled); - } else if (name == "next_owner_copy") { if (!enabled) gSavedSettings.setBOOL("NextOwnerTransfer", true); @@ -146,49 +125,6 @@ void LLPrefsAscentSys::onCommitCheckBox(LLUICtrl* ctrl, const LLSD& value) } } -void LLPrefsAscentSys::onCommitCmdLine(LLUICtrl* ctrl, const LLSD& value) -{ - const std::string& name = ctrl->getName(); - if (name == "chat_cmd_toggle") - { - bool enabled = value.asBoolean(); - childSetEnabled("cmd_line_text_2", enabled); - childSetEnabled("cmd_line_text_3", enabled); - childSetEnabled("cmd_line_text_4", enabled); - childSetEnabled("cmd_line_text_5", enabled); - childSetEnabled("cmd_line_text_6", enabled); - childSetEnabled("cmd_line_text_7", enabled); - childSetEnabled("cmd_line_text_8", enabled); - childSetEnabled("cmd_line_text_9", enabled); - childSetEnabled("cmd_line_text_10", enabled); - childSetEnabled("cmd_line_text_11", enabled); - childSetEnabled("cmd_line_text_12", enabled); - childSetEnabled("cmd_line_text_13", enabled); - childSetEnabled("cmd_line_text_15", enabled); - childSetEnabled("AscentCmdLinePos", enabled); - childSetEnabled("AscentCmdLineGround", enabled); - childSetEnabled("AscentCmdLineHeight", enabled); - childSetEnabled("AscentCmdLineTeleportHome", enabled); - childSetEnabled("AscentCmdLineRezPlatform", enabled); - childSetEnabled("AscentPlatformSize", enabled); - childSetEnabled("AscentCmdLineCalc", enabled); - childSetEnabled("AscentCmdLineClearChat", enabled); - childSetEnabled("AscentCmdLineDrawDistance", enabled); - childSetEnabled("AscentCmdTeleportToCam", enabled); - childSetEnabled("AscentCmdLineKeyToName", enabled); - childSetEnabled("AscentCmdLineOfferTp", enabled); - childSetEnabled("AscentCmdLineMapTo", enabled); - childSetEnabled("map_to_keep_pos", enabled); - childSetEnabled("AscentCmdLineTP2", enabled); - childSetEnabled("SinguCmdLineAway", enabled); - childSetEnabled("SinguCmdLineURL", enabled); - } - else - { - gSavedSettings.setString(name, value); // Singu Note: Keep commandline settings using the same name as their settings - } -} - void LLPrefsAscentSys::onCommitComboBox(LLUICtrl* ctrl, const LLSD& value) { gSavedSettings.setString(ctrl->getControlName(), value.asString()); @@ -252,12 +188,16 @@ void LLPrefsAscentSys::refreshValues() mPrivateLookAt = gSavedSettings.getBOOL("PrivateLookAt"); mShowLookAt = gSavedSettings.getBOOL("AscentShowLookAt"); mQuietSnapshotsToDisk = gSavedSettings.getBOOL("QuietSnapshotsToDisk"); + mAnnounceBumps = gSavedSettings.getBOOL("AnnounceBumps"); mDetachBridge = gSavedSettings.getBOOL("SGDetachBridge"); mRevokePermsOnStandUp = gSavedSettings.getBOOL("RevokePermsOnStandUp"); mDisableClickSit = gSavedSettings.getBOOL("DisableClickSit"); mDisableClickSitOtherOwner = gSavedSettings.getBOOL("DisableClickSitOtherOwner"); mDisplayScriptJumps = gSavedSettings.getBOOL("AscentDisplayTotalScriptJumps"); mNumScriptDiff = gSavedSettings.getF32("Ascentnumscriptdiff"); + mRestartMinimized = gSavedSettings.getBOOL("LiruRegionRestartMinimized"); + mRestartSound = gSavedSettings.getString("UISndRestart"); + mLandmark = gSavedPerAccountSettings.getString("EmergencyTeleportLandmark"); //Build ------------------------------------------------------------------------------- mAlpha = gSavedSettings.getF32("EmeraldBuildPrefs_Alpha"); @@ -282,44 +222,12 @@ void LLPrefsAscentSys::refreshValues() void LLPrefsAscentSys::refresh() { //General ----------------------------------------------------------------------------- - childSetEnabled("center_after_teleport_check", mDoubleClickTeleport); - childSetEnabled("offset_teleport_check", mDoubleClickTeleport); childSetValue("power_user_check", mPowerUser); - childSetValue("power_user_confirm_check", mPowerUser); - childSetEnabled("speed_rez_interval", mSpeedRez); - childSetEnabled("speed_rez_seconds", mSpeedRez); - - //Command Line ------------------------------------------------------------------------ - childSetEnabled("cmd_line_text_2", mCmdLine); - childSetEnabled("cmd_line_text_3", mCmdLine); - childSetEnabled("cmd_line_text_4", mCmdLine); - childSetEnabled("cmd_line_text_5", mCmdLine); - childSetEnabled("cmd_line_text_6", mCmdLine); - childSetEnabled("cmd_line_text_7", mCmdLine); - childSetEnabled("cmd_line_text_8", mCmdLine); - childSetEnabled("cmd_line_text_9", mCmdLine); - childSetEnabled("cmd_line_text_10", mCmdLine); - childSetEnabled("cmd_line_text_11", mCmdLine); - childSetEnabled("cmd_line_text_12", mCmdLine); - childSetEnabled("cmd_line_text_13", mCmdLine); - childSetEnabled("cmd_line_text_15", mCmdLine); - childSetEnabled("AscentCmdLinePos", mCmdLine); - childSetEnabled("AscentCmdLineGround", mCmdLine); - childSetEnabled("AscentCmdLineHeight", mCmdLine); - childSetEnabled("AscentCmdLineTeleportHome", mCmdLine); - childSetEnabled("AscentCmdLineRezPlatform", mCmdLine); - childSetEnabled("AscentPlatformSize", mCmdLine); - childSetEnabled("AscentCmdLineCalc", mCmdLine); - childSetEnabled("AscentCmdLineClearChat", mCmdLine); - childSetEnabled("AscentCmdLineDrawDistance", mCmdLine); - childSetEnabled("AscentCmdTeleportToCam", mCmdLine); - childSetEnabled("AscentCmdLineKeyToName", mCmdLine); - childSetEnabled("AscentCmdLineOfferTp", mCmdLine); - childSetEnabled("AscentCmdLineMapTo", mCmdLine); - childSetEnabled("map_to_keep_pos", mCmdLine); - childSetEnabled("AscentCmdLineTP2", mCmdLine); - childSetEnabled("SinguCmdLineAway", mCmdLine); - childSetEnabled("SinguCmdLineURL", mCmdLine); + if (LLUICtrl* ctrl = getChild("power_user_confirm_check")) + { + ctrl->setEnabled(mPowerUser); + ctrl->setValue(mPowerUser); + } //Security ---------------------------------------------------------------------------- childSetValue("AscentCmdLinePos", mCmdLinePos); @@ -338,6 +246,9 @@ void LLPrefsAscentSys::refresh() childSetValue("SinguCmdLineAway", mCmdLineAway); childSetValue("SinguCmdLineURL", mCmdLineURL); + //Security ---------------------------------------------------------------------------- + getChildView("UISndRestart")->setValue(mRestartSound); + //Build ------------------------------------------------------------------------------- childSetValue("alpha", mAlpha); getChild("colorswatch")->setOriginal(mColor); @@ -408,12 +319,16 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("PrivateLookAt", mPrivateLookAt); gSavedSettings.setBOOL("AscentShowLookAt", mShowLookAt); gSavedSettings.setBOOL("QuietSnapshotsToDisk", mQuietSnapshotsToDisk); + gSavedSettings.setBOOL("AnnounceBumps", mAnnounceBumps); gSavedSettings.setBOOL("SGDetachBridge", mDetachBridge); gSavedSettings.setBOOL("RevokePermsOnStandUp", mRevokePermsOnStandUp); gSavedSettings.setBOOL("DisableClickSit", mDisableClickSit); gSavedSettings.setBOOL("DisableClickSitOtherOwner", mDisableClickSitOtherOwner); gSavedSettings.setBOOL("AscentDisplayTotalScriptJumps", mDisplayScriptJumps); gSavedSettings.setF32("Ascentnumscriptdiff", mNumScriptDiff); + gSavedSettings.setBOOL("LiruRegionRestartMinimized", mRestartMinimized); + gSavedSettings.setString("UISndRestart", mRestartSound); + gSavedPerAccountSettings.setString("EmergencyTeleportLandmark", mLandmark); //Build ------------------------------------------------------------------------------- gSavedSettings.setF32("EmeraldBuildPrefs_Alpha", mAlpha); diff --git a/indra/newview/ascentprefssys.h b/indra/newview/ascentprefssys.h index 785d14940..8a8bed9e3 100644 --- a/indra/newview/ascentprefssys.h +++ b/indra/newview/ascentprefssys.h @@ -48,7 +48,6 @@ public: protected: void onCommitCheckBox(LLUICtrl* ctrl, const LLSD& value); - void onCommitCmdLine(LLUICtrl* ctrl, const LLSD& value); void onCommitComboBox(LLUICtrl* ctrl, const LLSD& value); void onCommitTexturePicker(LLUICtrl* ctrl); @@ -103,12 +102,16 @@ private: bool mPrivateLookAt; bool mShowLookAt; bool mQuietSnapshotsToDisk; + bool mAnnounceBumps; bool mDetachBridge; bool mRevokePermsOnStandUp; bool mDisableClickSit; bool mDisableClickSitOtherOwner; bool mDisplayScriptJumps; + bool mRestartMinimized; F32 mNumScriptDiff; + std::string mRestartSound; + std::string mLandmark; //Build ------------------------------------------------------------------------------- F32 mAlpha; diff --git a/indra/newview/ascentprefsvan.cpp b/indra/newview/ascentprefsvan.cpp index 0166c951b..b746c0747 100644 --- a/indra/newview/ascentprefsvan.cpp +++ b/indra/newview/ascentprefsvan.cpp @@ -61,14 +61,7 @@ LLPrefsAscentVan::LLPrefsAscentVan() getChild("tag_spoofing_combobox")->setCommitCallback(boost::bind(&LLPrefsAscentVan::onCommitClientTag, this, _1)); - getChild("show_my_tag_check")->setCommitCallback(boost::bind(&LLPrefsAscentVan::onCommitCheckBox, this, _1, _2)); - getChild("show_self_tag_check")->setCommitCallback(boost::bind(&LLPrefsAscentVan::onCommitCheckBox, this, _1, _2)); - getChild("show_self_tag_color_check")->setCommitCallback(boost::bind(&LLPrefsAscentVan::onCommitCheckBox, this, _1, _2)); - getChild("customize_own_tag_check")->setCommitCallback(boost::bind(&LLPrefsAscentVan::onCommitCheckBox, this, _1, _2)); - getChild("show_friend_tag_check")->setCommitCallback(boost::bind(&LLPrefsAscentVan::onCommitCheckBox, this, _1, _2)); - getChild("use_status_check")->setCommitCallback(boost::bind(&LLPrefsAscentVan::onCommitCheckBox, this, _1, _2)); - - getChild("custom_tag_label_box")->setCommitCallback(boost::bind(&LLPrefsAscentVan::onCommitTextModified, this, _1, _2)); + getChild("custom_tag_label_box")->setCommitCallback(boost::bind(&LLControlGroup::setString, boost::ref(gSavedSettings), "AscentCustomTagLabel", _2)); getChild("update_clientdefs")->setCommitCallback(boost::bind(LLPrefsAscentVan::onManualClientUpdate)); @@ -104,14 +97,6 @@ void LLPrefsAscentVan::onCommitClientTag(LLUICtrl* ctrl) } } -void LLPrefsAscentVan::onCommitTextModified(LLUICtrl* ctrl, const LLSD& value) -{ - if (ctrl->getName() == "custom_tag_label_box") - { - gSavedSettings.setString("AscentCustomTagLabel", value); - } -} - //static void LLPrefsAscentVan::onManualClientUpdate() { @@ -127,29 +112,6 @@ void LLPrefsAscentVan::onManualClientUpdate() LLFloaterChat::addChat(chat); } -void LLPrefsAscentVan::onCommitCheckBox(LLUICtrl* ctrl, const LLSD& value) -{ -// llinfos << "Control named " << ctrl->getControlName() << llendl; - - if (ctrl->getName() == "use_status_check") - { - bool showCustomColors = value.asBoolean(); - childSetEnabled("friends_color_textbox", showCustomColors); - childSetEnabled("friend_color_swatch", showCustomColors || gSavedSettings.getBOOL("ColorFriendChat")); - childSetEnabled("estate_owner_color_swatch", showCustomColors || gSavedSettings.getBOOL("ColorEstateOwnerChat")); - childSetEnabled("linden_color_swatch", showCustomColors || gSavedSettings.getBOOL("ColorLindenChat")); - childSetEnabled("muted_color_swatch", showCustomColors || gSavedSettings.getBOOL("ColorMutedChat")); - } - else if (ctrl->getName() == "customize_own_tag_check") - { - bool showCustomOptions = value.asBoolean(); - childSetEnabled("custom_tag_label_text", showCustomOptions); - childSetEnabled("custom_tag_label_box", showCustomOptions); - childSetEnabled("custom_tag_color_text", showCustomOptions); - childSetEnabled("custom_tag_color_swatch", showCustomOptions); - } -} - // Store current settings for cancel void LLPrefsAscentVan::refreshValues() { diff --git a/indra/newview/ascentprefsvan.h b/indra/newview/ascentprefsvan.h index edbe2cefb..9d5100559 100644 --- a/indra/newview/ascentprefsvan.h +++ b/indra/newview/ascentprefsvan.h @@ -48,8 +48,6 @@ public: protected: void onCommitClientTag(LLUICtrl* ctrl); - void onCommitCheckBox(LLUICtrl* ctrl, const LLSD& value); - void onCommitTextModified(LLUICtrl* ctrl, const LLSD& value); static void onManualClientUpdate(); private: diff --git a/indra/newview/chatbar_as_cmdline.h b/indra/newview/chatbar_as_cmdline.h index 3e1d37532..3a7de8140 100644 --- a/indra/newview/chatbar_as_cmdline.h +++ b/indra/newview/chatbar_as_cmdline.h @@ -29,8 +29,11 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#include "llviewerprecompiledheaders.h" +#ifndef MS_CHATBARCMDLINE_H +#define MS_CHATBARCMDLINE_H #include "llchatbar.h" bool cmd_line_chat(std::string revised_text, EChatType type); + +#endif \ No newline at end of file diff --git a/indra/newview/generichandlers.h b/indra/newview/generichandlers.h index 2a1210b57..456d9aa53 100644 --- a/indra/newview/generichandlers.h +++ b/indra/newview/generichandlers.h @@ -22,6 +22,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef SG_GENERICHANDLERS_H +#define SG_GENERICHANDLERS_H + class GenericHandlers { public: @@ -29,3 +32,5 @@ public: }; extern GenericHandlers *gGenericHandlers; + +#endif // SG_GENERIC_HANDLERS \ No newline at end of file diff --git a/indra/newview/jcfloaterareasearch.h b/indra/newview/jcfloaterareasearch.h index abf2bd592..71cd1c7af 100644 --- a/indra/newview/jcfloaterareasearch.h +++ b/indra/newview/jcfloaterareasearch.h @@ -31,6 +31,9 @@ * Modified, debugged, optimized and improved by Henri Beauchamp Feb 2010. */ +#ifndef JC_FLOATERAREASEARCH_H +#define JC_FLOATERAREASEARCH_H + #include "llfloater.h" #include "lluuid.h" #include "llstring.h" @@ -90,3 +93,5 @@ private: std::string mFilterStrings[LIST_OBJECT_COUNT]; }; + +#endif \ No newline at end of file diff --git a/indra/newview/lggdicdownload.h b/indra/newview/lggdicdownload.h index 75f3053e9..d9edb8deb 100644 --- a/indra/newview/lggdicdownload.h +++ b/indra/newview/lggdicdownload.h @@ -28,6 +28,8 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef LGG_DICDOWNLOAD_H +#define LGG_DICDOWNLOAD_H class LggDicDownload { @@ -35,3 +37,4 @@ class LggDicDownload static void show( BOOL showw , std::vector shortNames, std::vector longNames, void * data); }; +#endif \ No newline at end of file diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 45fa8dcd7..67c44f5ab 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1507,8 +1507,6 @@ bool LLAppViewer::cleanup() llinfos << "HUD Objects cleaned up" << llendflush; } - LLKeyframeDataCache::clear(); - // End TransferManager before deleting systems it depends on (Audio, VFS, AssetStorage) #if 0 // this seems to get us stuck in an infinite loop... gTransferManager.cleanup(); diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp new file mode 100644 index 000000000..2e8926f45 --- /dev/null +++ b/indra/newview/llautoreplace.cpp @@ -0,0 +1,802 @@ +/** + * @file llautoreplace.cpp + * @brief Auto Replace Manager + * + * $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; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llautoreplace.h" +#include "llsdserialize.h" +#include "llboost.h" +#include "llcontrol.h" +#include "llviewercontrol.h" +#include "llnotificationsutil.h" + +const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml"; + +void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text) +{ + // make sure these returned values are cleared in case there is no replacement + replacement_start = 0; + replacement_length = 0; + replacement_string.clear(); + + static LLCachedControl perform_autoreplace(gSavedSettings, "AutoReplace", 0); + if (perform_autoreplace) + { + S32 word_end = cursor_pos - 1; + + bool at_space = (input_text[word_end] == ' '); + bool have_word = (LLWStringUtil::isPartOfWord(input_text[word_end])); + + if (at_space || have_word) + { + if (at_space && word_end > 0) + { + // find out if this space immediately follows a word + word_end--; + have_word = (LLWStringUtil::isPartOfWord(input_text[word_end])); + } + if (have_word) + { + // word_end points to the end of a word, now find the start of the word + std::string word; + S32 word_start = word_end; + for (S32 back_one = word_start - 1; + back_one >= 0 && LLWStringUtil::isPartOfWord(input_text[back_one]); + back_one-- + ) + { + word_start--; // walk word_start back to the beginning of the word + } + LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL; + std::string str_text = std::string(input_text.begin(), input_text.end()); + std::string last_word = str_text.substr(word_start, word_end - word_start + 1); + std::string replacement_word(mSettings.replaceWord(last_word)); + + if (replacement_word != last_word) + { + // The last word is one for which we have a replacement + if (at_space) + { + // return the replacement string + replacement_start = word_start; + replacement_length = last_word.length(); + replacement_string = utf8str_to_wstring(replacement_word); + LLWString old_string = utf8str_to_wstring(last_word); + S32 size_change = replacement_string.size() - old_string.size(); + cursor_pos += size_change; + } + } + } + } + } +} + +std::string LLAutoReplace::getUserSettingsFileName() +{ + std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""); + + if (!path.empty()) + { + path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, SETTINGS_FILE_NAME); + } + return path; +} + +std::string LLAutoReplace::getAppSettingsFileName() +{ + std::string path=gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""); + + if (!path.empty()) + { + path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, SETTINGS_FILE_NAME); + } + else + { + LL_ERRS("AutoReplace") << "Failed to get app settings directory name" << LL_ENDL; + } + return path; +} + +LLAutoReplaceSettings LLAutoReplace::getSettings() +{ + return mSettings; +} + +void LLAutoReplace::setSettings(const LLAutoReplaceSettings& newSettings) +{ + mSettings.set(newSettings); + /// Make the newSettings active and write them to user storage + saveToUserSettings(); +} + +LLAutoReplace::LLAutoReplace() +{ +} + +void LLAutoReplace::initSingleton() +{ + loadFromSettings(); +} + +void LLAutoReplace::loadFromSettings() +{ + std::string filename=getUserSettingsFileName(); + if (filename.empty()) + { + LL_INFOS("AutoReplace") << "no valid user settings directory." << LL_ENDL; + } + if(gDirUtilp->fileExists(filename)) + { + LLSD userSettings; + llifstream file; + file.open(filename.c_str()); + if (file.is_open()) + { + LLSDSerialize::fromXML(userSettings, file); + } + file.close(); + if ( mSettings.setFromLLSD(userSettings) ) + { + LL_INFOS("AutoReplace") << "settings loaded from '" << filename << "'" << LL_ENDL; + } + else + { + LL_WARNS("AutoReplace") << "invalid settings found in '" << filename << "'" << LL_ENDL; + } + } + else // no user settings found, try application settings + { + std::string defaultName = getAppSettingsFileName(); + LL_INFOS("AutoReplace") << " user settings file '" << filename << "' not found"<< LL_ENDL; + + bool gotSettings = false; + if(gDirUtilp->fileExists(defaultName)) + { + LLSD appDefault; + llifstream file; + file.open(defaultName.c_str()); + if (file.is_open()) + { + LLSDSerialize::fromXMLDocument(appDefault, file); + } + file.close(); + + if ( mSettings.setFromLLSD(appDefault) ) + { + LL_INFOS("AutoReplace") << "settings loaded from '" << defaultName.c_str() << "'" << LL_ENDL; + gotSettings = true; + } + else + { + LL_WARNS("AutoReplace") << "invalid settings found in '" << defaultName.c_str() << "'" << LL_ENDL; + } + } + + if ( ! gotSettings ) + { + if (mSettings.setFromLLSD(mSettings.getExampleLLSD())) + { + LL_WARNS("AutoReplace") << "no settings found; loaded example." << LL_ENDL; + } + else + { + LL_WARNS("AutoReplace") << "no settings found and example invalid!" << LL_ENDL; + } + } + } +} + +void LLAutoReplace::saveToUserSettings() +{ + std::string filename=getUserSettingsFileName(); + llofstream file; + file.open(filename.c_str()); + LLSDSerialize::toPrettyXML(mSettings.asLLSD(), file); + file.close(); + LL_INFOS("AutoReplace") << "settings saved to '" << filename << "'" << LL_ENDL; +} + +// ================================================================ +// LLAutoReplaceSettings +// ================================================================ + +const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_NAME = "name"; ///< key for looking up list names +const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_REPLACEMENTS = "replacements"; ///< key for looking up replacement map + +LLAutoReplaceSettings::LLAutoReplaceSettings() +{ +} + +LLAutoReplaceSettings::LLAutoReplaceSettings(const LLAutoReplaceSettings& settings) +{ + // copy all values through fundamental type intermediates for thread safety + mLists = LLSD::emptyArray(); + + for ( LLSD::array_const_iterator list = settings.mLists.beginArray(), listEnd = settings.mLists.endArray(); + list != listEnd; + list++ + ) + { + if ( (*list).isMap() ) // can fail due to LLSD-30: ignore it + { + LLSD listMap = LLSD::emptyMap(); + std::string listName = (*list)[AUTOREPLACE_LIST_NAME]; + listMap[AUTOREPLACE_LIST_NAME] = listName; + listMap[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap(); + + for ( LLSD::map_const_iterator + entry = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(), + entriesEnd = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].endMap(); + entry != entriesEnd; + entry++ + ) + { + std::string keyword = entry->first; + std::string replacement = entry->second.asString(); + listMap[AUTOREPLACE_LIST_REPLACEMENTS].insert(keyword, LLSD(replacement)); + } + + mLists.append(listMap); + } + } +} + +void LLAutoReplaceSettings::set(const LLAutoReplaceSettings& newSettings) +{ + mLists = newSettings.mLists; +} + +bool LLAutoReplaceSettings::setFromLLSD(const LLSD& settingsFromLLSD) +{ + bool settingsValid = true; + + if ( settingsFromLLSD.isArray() ) + { + for ( LLSD::array_const_iterator + list = settingsFromLLSD.beginArray(), + listEnd = settingsFromLLSD.endArray(); + settingsValid && list != listEnd; + list++ + ) + { + if ( (*list).isDefined() ) // can be undef due to LLSD-30: ignore it + { + settingsValid = listIsValid(*list); + } + } + } + else + { + settingsValid = false; + LL_WARNS("AutoReplace") << "settings are not an array" << LL_ENDL; + } + + if ( settingsValid ) + { + mLists = settingsFromLLSD; + } + else + { + LL_WARNS("AutoReplace") << "invalid settings discarded; using hard coded example" << LL_ENDL; + } + + return settingsValid; +} + +bool LLAutoReplaceSettings::listNameMatches( const LLSD& list, const std::string name ) +{ + return list.isMap() + && list.has(AUTOREPLACE_LIST_NAME) + && list[AUTOREPLACE_LIST_NAME].asString() == name; +} + +const LLSD* LLAutoReplaceSettings::getListEntries(std::string listName) +{ + const LLSD* returnedEntries = NULL; + for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray(); + returnedEntries == NULL && list != endList; + list++ + ) + { + const LLSD& thisList = *list; + if ( listNameMatches(thisList, listName) ) + { + returnedEntries = &thisList[AUTOREPLACE_LIST_REPLACEMENTS]; + } + } + return returnedEntries; +} + +std::string LLAutoReplaceSettings::replacementFor(std::string keyword, std::string listName) +{ + std::string replacement; + bool foundList = false; + for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray(); + ! foundList && list != endList; + list++ + ) + { + const LLSD& thisList = *list; + if ( listNameMatches(thisList, listName) ) + { + foundList = true; // whether there is a replacement or not, we're done + if ( thisList.isMap() + && thisList.has(AUTOREPLACE_LIST_REPLACEMENTS) + && thisList[AUTOREPLACE_LIST_REPLACEMENTS].has(keyword) + ) + { + replacement = thisList[AUTOREPLACE_LIST_REPLACEMENTS][keyword].asString(); + LL_DEBUGS("AutoReplace")<<"'"< '"<second.isString() ) + { + listValid = false; + LL_WARNS("AutoReplace") + << "non-string replacement value found in list '" + << list[AUTOREPLACE_LIST_NAME].asString() << "'" + << LL_ENDL; + } + } + } + + return listValid; +} + +const LLSD* LLAutoReplaceSettings::exportList(std::string listName) +{ + const LLSD* exportedList = NULL; + for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray(); + exportedList == NULL && list != listEnd; + list++ + ) + { + if ( listNameMatches(*list, listName) ) + { + const LLSD& namedList = (*list); + exportedList = &namedList; + } + } + return exportedList; +} + +bool LLAutoReplaceSettings::listNameIsUnique(const LLSD& newList) +{ + bool nameIsUnique = true; + // this must always be called with a valid list, so it is safe to assume it has a name + std::string newListName = newList[AUTOREPLACE_LIST_NAME].asString(); + for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray(); + nameIsUnique && list != listEnd; + list++ + ) + { + if ( listNameMatches(*list, newListName) ) + { + LL_WARNS("AutoReplace")<<"duplicate list name '"<= 0) + { + LL_DEBUGS("AutoReplace") << "erase "< autoreplace_enabled(gSavedSettings, "AutoReplace", false); + if ( autoreplace_enabled ) + { + LL_DEBUGS("AutoReplace")<<"checking '"< '" << replacements[currentWord].asString() << "'" + << LL_ENDL; + returnedWord = replacements[currentWord].asString(); + } + } + } + return returnedWord; +} + +bool LLAutoReplaceSettings::addEntryToList(LLWString keyword, LLWString replacement, std::string listName) +{ + bool added = false; + + if ( ! keyword.empty() && ! replacement.empty() ) + { + bool isOneWord = true; + for (size_t character = 0; isOneWord && character < keyword.size(); character++ ) + { + if ( ! LLWStringUtil::isPartOfWord(keyword[character]) ) + { + LL_WARNS("AutoReplace") << "keyword '" << wstring_to_utf8str(keyword) << "' not a single word (len "< replacement test pairs + + /// Get the replacement for the keyword from the specified list + std::string replacementFor(std::string keyword, std::string listName); + + /// Adds a keywword/replacement pair to the named list + bool addEntryToList(LLWString keyword, LLWString replacement, std::string listName); + + /// Removes the keywword and its replacement from the named list + bool removeEntryFromList(std::string keyword, std::string listName); + + /** + * Look for currentWord in the lists in order, returning any substitution found + * If no configured substitution is found, returns currentWord + */ + std::string replaceWord(const std::string currentWord /**< word to search for */ ); + + /// Provides a hard-coded example of settings + LLSD getExampleLLSD(); + + /// Get the actual settings as LLSD + const LLSD& asLLSD(); + ///< @note for use only in AutoReplace::saveToUserSettings + + private: + /// Efficiently and safely compare list names + bool listNameMatches( const LLSD& list, const std::string name ); + + /// The actual llsd data structure + LLSD mLists; + + static const std::string AUTOREPLACE_LIST_NAME; ///< key for looking up list names + static const std::string AUTOREPLACE_LIST_REPLACEMENTS; ///< key for looking up replacement map + + /**< + * LLSD structure of the lists + * - The configuration is an array (mLists), + * - Each entry in the array is a replacement list + * - Each replacement list is a map with three keys: + * @verbatim + * "name" String the name of the list + * "replacements" Map keyword -> replacement pairs + * + * + * + * + * name List 1 + * data + * + * keyword1 replacement1 + * keyword2 replacement2 + * + * + * + * name List 2 + * data + * + * keyword1 replacement1 + * keyword2 replacement2 + * + * + * + * + * @endverbatim + */ +}; + +/** Provides a facility to auto-replace text dynamically as it is entered. + * + * When the end of a word is detected (defined as any punctuation character, + * or any whitespace except newline or return), the preceding word is used + * as a lookup key in an ordered list of maps. If a match is found in any + * map, the replacement start index and length are returned along with the + * new replacement string. + * + * See the autoreplaceCallback method for how to add autoreplace functionality + * to a text entry tool. + */ +class LLAutoReplace : public LLSingleton +{ +public: + /// Callback that provides the hook for use in text entry methods + void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text); + + /// Get a copy of the current settings + LLAutoReplaceSettings getSettings(); + + /// Commit new settings after making changes + void setSettings(const LLAutoReplaceSettings& settings); + +private: + friend class LLSingleton; + LLAutoReplace(); + /*virtual*/ void initSingleton(); + + LLAutoReplaceSettings mSettings; ///< configuration information + + /// Read settings from persistent storage + void loadFromSettings(); + + /// Make the newSettings active and write them to user storage + void saveToUserSettings(); + + /// Compute the user settings file name + std::string getUserSettingsFileName(); + + /// Compute the (read-ony) application settings file name + std::string getAppSettingsFileName(); + + /// basename for the settings files + static const char* SETTINGS_FILE_NAME; +}; + +#endif /* LLAUTOREPLACE_H */ diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 9a31e0d6f..8c38b0597 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -44,6 +44,7 @@ #include "llfocusmgr.h" #include "llagent.h" +#include "llautoreplace.h" #include "llbutton.h" #include "llcombobox.h" #include "llcommandhandler.h" // secondlife:///app/chat/ support @@ -149,6 +150,7 @@ BOOL LLChatBar::postBuild() mInputEditor = findChild("Chat Editor"); if (mInputEditor) { + mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5)); mInputEditor->setKeystrokeCallback(boost::bind(&LLChatBar::onInputEditorKeystroke,this)); mInputEditor->setFocusLostCallback(boost::bind(&LLChatBar::onInputEditorFocusLost)); mInputEditor->setFocusReceivedCallback(boost::bind(&LLChatBar::onInputEditorGainFocus)); diff --git a/indra/newview/lldroptarget.cpp b/indra/newview/lldroptarget.cpp index 22b555228..9e7cc377e 100644 --- a/indra/newview/lldroptarget.cpp +++ b/indra/newview/lldroptarget.cpp @@ -145,6 +145,11 @@ void LLDropTarget::setControlName(const std::string& control_name, LLView* conte else { mControl = gSavedPerAccountSettings.getControl(control_name); + if (!mControl) + { + llerrs << "Could not find control \"" << control_name << "\" in gSavedPerAccountSettings" << llendl; + return; // Though this should never happen. + } const LLUUID id(mControl->getValue().asString()); if (id.isNull()) text = LLTrans::getString("CurrentlyNotSet"); diff --git a/indra/newview/llemote.cpp b/indra/newview/llemote.cpp index c83846215..47bd57969 100644 --- a/indra/newview/llemote.cpp +++ b/indra/newview/llemote.cpp @@ -48,7 +48,7 @@ // LLEmote() // Class Constructor //----------------------------------------------------------------------------- -LLEmote::LLEmote(const LLUUID &id) : LLMotion(id) +LLEmote::LLEmote(LLUUID const& id, LLMotionController* controller) : LLMotion(id, controller) { mCharacter = NULL; diff --git a/indra/newview/llemote.h b/indra/newview/llemote.h index 99d05b9a2..173719121 100644 --- a/indra/newview/llemote.h +++ b/indra/newview/llemote.h @@ -55,7 +55,7 @@ class LLEmote : { public: // Constructor - LLEmote(const LLUUID &id); + LLEmote(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLEmote(); @@ -67,7 +67,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLEmote(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLEmote(id, controller); } public: //------------------------------------------------------------------------- diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 27b0ded9e..f02fece9c 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -50,7 +50,6 @@ #include "llviewerstats.h" #include "llviewerregion.h" #include "sgversion.h" -#include "llviewerbuild.h" #include "lluictrlfactory.h" #include "lluri.h" #include "llweb.h" @@ -141,7 +140,7 @@ LLFloaterAbout::LLFloaterAbout() + " (64 bit)" #endif + llformat(" %d.%d.%d (%d) %s %s (%s)\n", - gVersionMajor, gVersionMinor, gVersionPatch, LL_VIEWER_BUILD, + gVersionMajor, gVersionMinor, gVersionPatch, gVersionBuild, __DATE__, __TIME__, gVersionChannel)); support_widget->appendColoredText(version, FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor")); diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp new file mode 100644 index 000000000..eabd8c13e --- /dev/null +++ b/indra/newview/llfloaterautoreplacesettings.cpp @@ -0,0 +1,632 @@ +/** + * @file llfloaterautoreplacesettings.cpp + * @brief Auto Replace List floater + * + * $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; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterautoreplacesettings.h" + +#include "statemachine/aifilepicker.h" +#include "llscrolllistctrl.h" +#include "lluictrlfactory.h" + +#include "llautoreplace.h" +#include "llsdserialize.h" +#include "llsdutil.h" + +#include + +#include "llnotificationsutil.h" + + +LLFloaterAutoReplaceSettings::LLFloaterAutoReplaceSettings(const LLSD& key) + : LLFloater(/*key*/) + , mSelectedListName("") + , mListNames(NULL) + , mReplacementsList(NULL) + , mKeyword(NULL) + , mPreviousKeyword("") + , mReplacement(NULL) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_autoreplace.xml"); +} + +BOOL LLFloaterAutoReplaceSettings::postBuild(void) +{ + // get copies of the current settings that we will operate on + mEnabled = gSavedSettings.getBOOL("AutoReplace"); + LL_DEBUGS("AutoReplace") << ( mEnabled ? "enabled" : "disabled") << LL_ENDL; + + mSettings = LLAutoReplace::getInstance()->getSettings(); + + // global checkbox for whether or not autoreplace is active + LLUICtrl* enabledCheckbox = getChild("autoreplace_enable"); + enabledCheckbox->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onAutoReplaceToggled, this)); + enabledCheckbox->setValue(LLSD(mEnabled)); + + // top row list creation and deletion + getChild("autoreplace_import_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onImportList,this)); + getChild("autoreplace_export_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onExportList,this)); + getChild("autoreplace_new_list")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onNewList,this)); + getChild("autoreplace_delete_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onDeleteList,this)); + + // the list of keyword->replacement lists + mListNames = getChild("autoreplace_list_name"); + mListNames->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSelectList, this)); + mListNames->setCommitOnSelectionChange(true); + + // list ordering + getChild("autoreplace_list_up")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onListUp,this)); + getChild("autoreplace_list_down")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onListDown,this)); + + // keyword->replacement entry add / delete + getChild("autoreplace_add_entry")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onAddEntry,this)); + getChild("autoreplace_delete_entry")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onDeleteEntry,this)); + + // entry edits + mKeyword = getChild("autoreplace_keyword"); + mReplacement = getChild("autoreplace_replacement"); + getChild("autoreplace_save_entry")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSaveEntry, this)); + + // dialog termination ( Save Changes / Cancel ) + getChild("autoreplace_save_changes")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSaveChanges, this)); + getChild("autoreplace_cancel")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::close, this, false)); + + // the list of keyword->replacement pairs + mReplacementsList = getChild("autoreplace_list_replacements"); + mReplacementsList->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSelectEntry, this)); + mReplacementsList->setCommitOnSelectionChange(true); + + center(); + + mSelectedListName.clear(); + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + + return true; +} + + +void LLFloaterAutoReplaceSettings::updateListNames() +{ + mListNames->deleteAllItems(); // start from scratch + + LLSD listNames = mSettings.getListNames(); // Array of Strings + + for ( LLSD::array_const_iterator entry = listNames.beginArray(), end = listNames.endArray(); + entry != end; + ++entry + ) + { + const std::string& listName = entry->asString(); + mListNames->addSimpleElement(listName); + } + + if (!mSelectedListName.empty()) + { + mListNames->setSelectedByValue( LLSD(mSelectedListName), true ); + } +} + +void LLFloaterAutoReplaceSettings::updateListNamesControls() +{ + if ( mSelectedListName.empty() ) + { + // There is no selected list + + // Disable all controls that operate on the selected list + getChild("autoreplace_export_list")->setEnabled(false); + getChild("autoreplace_delete_list")->setEnabled(false); + getChild("autoreplace_list_up")->setEnabled(false); + getChild("autoreplace_list_down")->setEnabled(false); + + mReplacementsList->deleteAllItems(); + } + else + { + // Enable the controls that operate on the selected list + getChild("autoreplace_export_list")->setEnabled(true); + getChild("autoreplace_delete_list")->setEnabled(true); + getChild("autoreplace_list_up")->setEnabled(!selectedListIsFirst()); + getChild("autoreplace_list_down")->setEnabled(!selectedListIsLast()); + } +} + +void LLFloaterAutoReplaceSettings::onSelectList() +{ + std::string previousSelectedListName = mSelectedListName; + // only one selection allowed + LLSD selected = mListNames->getSelectedValue(); + if (selected.isDefined()) + { + mSelectedListName = selected.asString(); + LL_DEBUGS("AutoReplace")<<"selected list '"<getSelectedValue(); + if (selectedRow.isDefined()) + { + mPreviousKeyword = selectedRow.asString(); + LL_DEBUGS("AutoReplace")<<"selected entry '"<setValue(selectedRow); + std::string replacement = mSettings.replacementFor(mPreviousKeyword, mSelectedListName ); + mReplacement->setValue(replacement); + enableReplacementEntry(); + mReplacement->setFocus(true); + } + else + { + // no entry selection, so the entry panel should be off + disableReplacementEntry(); + LL_DEBUGS("AutoReplace")<<"no row selected"<deleteAllItems(); + + if ( mSelectedListName.empty() ) + { + mReplacementsList->setEnabled(false); + getChild("autoreplace_add_entry")->setEnabled(false); + disableReplacementEntry(); + } + else + { + // Populate the keyword->replacement list from the selected list + const LLSD* mappings = mSettings.getListEntries(mSelectedListName); + for ( LLSD::map_const_iterator entry = mappings->beginMap(), end = mappings->endMap(); + entry != end; + entry++ + ) + { + LLSD row; + row["id"] = entry->first; + row["columns"][0]["column"] = "Keyword"; + row["columns"][0]["value"] = entry->first; + row["columns"][1]["column"] = "Replacement"; + row["columns"][1]["value"] = entry->second; + + mReplacementsList->addElement(row, ADD_BOTTOM); + } + + mReplacementsList->deselectAllItems(false /* don't call commit */); + mReplacementsList->setEnabled(true); + + getChild("autoreplace_add_entry")->setEnabled(true); + disableReplacementEntry(); + } +} + +void LLFloaterAutoReplaceSettings::enableReplacementEntry() +{ + LL_DEBUGS("AutoReplace")<setEnabled(true); + mReplacement->setEnabled(true); + getChild("autoreplace_save_entry")->setEnabled(true); + getChild("autoreplace_delete_entry")->setEnabled(true); +} + +void LLFloaterAutoReplaceSettings::disableReplacementEntry() +{ + LL_DEBUGS("AutoReplace")<clear(); + mKeyword->setEnabled(false); + mReplacement->clear(); + mReplacement->setEnabled(false); + getChild("autoreplace_save_entry")->setEnabled(false); + getChild("autoreplace_delete_entry")->setEnabled(false); +} + +// called when the global settings checkbox is changed +void LLFloaterAutoReplaceSettings::onAutoReplaceToggled() +{ + // set our local copy of the flag, copied to the global preference in onOk + mEnabled = childGetValue("autoreplace_enable").asBoolean(); + LL_DEBUGS("AutoReplace")<< "autoreplace_enable " << ( mEnabled ? "on" : "off" ) << LL_ENDL; +} + +// called when the List Up button is pressed +void LLFloaterAutoReplaceSettings::onListUp() +{ + S32 selectedRow = mListNames->getFirstSelectedIndex(); + LLSD selectedName = mListNames->getSelectedValue().asString(); + + if ( mSettings.increaseListPriority(selectedName) ) + { + updateListNames(); + updateListNamesControls(); + } + else + { + LL_WARNS("AutoReplace") + << "invalid row ("<getFirstSelectedIndex(); + std::string selectedName = mListNames->getSelectedValue().asString(); + + if ( mSettings.decreaseListPriority(selectedName) ) + { + updateListNames(); + updateListNamesControls(); + } + else + { + LL_WARNS("AutoReplace") + << "invalid row ("<getSelectedValue(); + if (selectedRow.isDefined()) + { + std::string keyword = selectedRow.asString(); + mReplacementsList->deleteSelectedItems(); // delete from the control + mSettings.removeEntryFromList(keyword, mSelectedListName); // delete from the local settings copy + disableReplacementEntry(); // no selection active, so turn off the buttons + } +} + +// called when the Import List button is pressed +void LLFloaterAutoReplaceSettings::onImportList() +{ + AIFilePicker* picker = AIFilePicker::create(); + picker->open(FFLOAD_XML, "", "autoreplace"); + picker->run(boost::bind(&LLFloaterAutoReplaceSettings::onImportList_continued, this, picker)); +} + +void LLFloaterAutoReplaceSettings::onImportList_continued(AIFilePicker* picker) +{ + if (picker->hasFilename()) + { + llifstream file; + file.open(picker->getFilename()); + LLSD newList; + if (file.is_open()) + { + LLSDSerialize::fromXMLDocument(newList, file); + } + file.close(); + + switch ( mSettings.addList(newList) ) + { + case LLAutoReplaceSettings::AddListOk: + mSelectedListName = LLAutoReplaceSettings::getListName(newList); + + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + break; + + case LLAutoReplaceSettings::AddListDuplicateName: + { + std::string newName = LLAutoReplaceSettings::getListName(newList); + LL_WARNS("AutoReplace")<<"name '"<getSelectedValue().asString(); + if ( ! listName.empty() ) + { + if ( mSettings.removeReplacementList(listName) ) + { + LL_INFOS("AutoReplace")<<"deleted list '"<deleteSelectedItems(); // remove from the scrolling list + mSelectedListName.clear(); + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + } + else + { + LL_WARNS("AutoReplace")<<"failed to delete list '"<getFirstSelected()->getColumn(0)->getValue().asString(); + std::string listFileName = listName + ".xml"; + AIFilePicker* picker = AIFilePicker::create(); + picker->open(listFileName, FFSAVE_XML, "", "autoreplace"); + picker->run(boost::bind(&LLFloaterAutoReplaceSettings::onExportList_continued, this, picker, mSettings.exportList(listName))); +} +void LLFloaterAutoReplaceSettings::onExportList_continued(AIFilePicker* picker, const LLSD* list) +{ + if (picker->hasFilename()) + { + llofstream file; + file.open(picker->getFilename()); + LLSDSerialize::toPrettyXML(*list, file); + file.close(); + } +} + +void LLFloaterAutoReplaceSettings::onAddEntry() +{ + mPreviousKeyword.clear(); + mReplacementsList->deselectAllItems(false /* don't call commit */); + mKeyword->clear(); + mReplacement->clear(); + enableReplacementEntry(); + mKeyword->setFocus(true); +} + +void LLFloaterAutoReplaceSettings::onSaveEntry() +{ + LL_DEBUGS("AutoReplace")<<"called"<getWText(); + LLWString replacement = mReplacement->getWText(); + if ( mSettings.addEntryToList(keyword, replacement, mSelectedListName) ) + { + // insert the new keyword->replacement pair + LL_INFOS("AutoReplace") + << "list '" << mSelectedListName << "' " + << "added '" << wstring_to_utf8str(keyword) + << "' -> '" << wstring_to_utf8str(replacement) + << "'" << LL_ENDL; + + updateReplacementsList(); + } + else + { + LLNotificationsUtil::add("InvalidAutoReplaceEntry"); + LL_WARNS("AutoReplace")<<"invalid entry " + << "keyword '" << wstring_to_utf8str(keyword) + << "' replacement '" << wstring_to_utf8str(replacement) + << "'" << LL_ENDL; + } +} + +void LLFloaterAutoReplaceSettings::onSaveChanges() +{ + // put our local copy of the settings into the active copy + LLAutoReplace::getInstance()->setSettings( mSettings ); + // save our local copy of the global feature enable/disable value + gSavedSettings.setBOOL("AutoReplace", mEnabled); + close(); +} + +bool LLFloaterAutoReplaceSettings::selectedListIsFirst() +{ + bool isFirst = false; + + if (!mSelectedListName.empty()) + { + LLSD lists = mSettings.getListNames(); // an Array of Strings + LLSD first = lists.get(0); + if ( first.isString() && first.asString() == mSelectedListName ) + { + isFirst = true; + } + } + return isFirst; +} + +bool LLFloaterAutoReplaceSettings::selectedListIsLast() +{ + bool isLast = false; + + if (!mSelectedListName.empty()) + { + LLSD last; + LLSD lists = mSettings.getListNames(); // an Array of Strings + for ( LLSD::array_const_iterator list = lists.beginArray(), listEnd = lists.endArray(); + list != listEnd; + list++ + ) + { + last = *list; + } + if ( last.isString() && last.asString() == mSelectedListName ) + { + isLast = true; + } + } + return isLast; +} + +/* TBD +mOldText = getChild("autoreplace_old_text"); +mNewText = getChild("autoreplace_new_text"); +*/ diff --git a/indra/newview/llfloaterautoreplacesettings.h b/indra/newview/llfloaterautoreplacesettings.h new file mode 100644 index 000000000..c9cc98d9f --- /dev/null +++ b/indra/newview/llfloaterautoreplacesettings.h @@ -0,0 +1,111 @@ +/** + * @file llfloaterautoreplacesettings.h + * @brief Auto Replace List floater + * @copyright Copyright (c) 2011 LordGregGreg Back + * + * $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; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * $/LicenseInfo$ + */ + +#ifndef LLFLOATERAUTOREPLACESETTINGS_H +#define LLFLOATERAUTOREPLACESETTINGS_H + +#include "llfloater.h" +#include "llautoreplace.h" + +class AIFilePicker; +class LLLineEditor; +class LLScrollListCtrl; + +class LLFloaterAutoReplaceSettings : public LLFloater, public LLFloaterSingleton +{ +public: + LLFloaterAutoReplaceSettings(const LLSD& key = LLSD()); + + /*virtual*/ BOOL postBuild(); + +private: + + /** @{ @name Local Copies of Settings + * These are populated in the postBuild method with the values + * current when the floater is instantiated, and then either + * discarded when Cancel is pressed, or copied back to the active + * settings if Ok is pressed. + */ + bool mEnabled; ///< the global preference for AutoReplace + LLAutoReplaceSettings mSettings; ///< settings being modified + /** @} */ + + /// convenience variable - the name of the currently selected list (if any) + std::string mSelectedListName; + /// the scrolling list of list names (one column, no headings, order manually controlled) + LLScrollListCtrl* mListNames; + /// the scroling list of keyword->replacement pairs + LLScrollListCtrl* mReplacementsList; + + /// the keyword for the entry editing pane + LLLineEditor* mKeyword; + /// saved keyword value + std::string mPreviousKeyword; + /// the replacement for the entry editing pane + LLLineEditor* mReplacement; + + /// callback for when the feature enable/disable checkbox changes + void onAutoReplaceToggled(); + /// callback for when an entry in the list of list names is selected + void onSelectList(); + + void onImportList(); + void onImportList_continued(AIFilePicker* picker); + void onExportList(); + void onExportList_continued(AIFilePicker* picker, const LLSD* list); + void onNewList(); + void onDeleteList(); + + void onListUp(); + void onListDown(); + + void onSelectEntry(); + void onAddEntry(); + void onDeleteEntry(); + void onSaveEntry(); + + void onSaveChanges(); + + /// updates the contents of the mListNames + void updateListNames(); + /// updates the controls associated with mListNames (depends on whether a name is selected or not) + void updateListNamesControls(); + /// updates the contents of the mReplacementsList + void updateReplacementsList(); + /// enables the components that should only be active when a keyword is selected + void enableReplacementEntry(); + /// disables the components that should only be active when a keyword is selected + void disableReplacementEntry(); + + /// called from the AddAutoReplaceList notification dialog + bool callbackNewListName(const LLSD& notification, const LLSD& response); + /// called from the RenameAutoReplaceList notification dialog + bool callbackListNameConflict(const LLSD& notification, const LLSD& response); + + bool selectedListIsFirst(); + bool selectedListIsLast(); +}; + +#endif // LLFLOATERAUTOREPLACESETTINGS_H diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 86d87d049..566159cc1 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -16,52 +16,44 @@ #include "llviewerprecompiledheaders.h" +#include "llfloateravatarlist.h" +#include "llaudioengine.h" #include "llavatarconstants.h" #include "llavatarnamecache.h" -#include "llfloateravatarlist.h" #include "llnotificationsutil.h" #include "llradiogroup.h" #include "llscrolllistcolumn.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" -#include "lluictrlfactory.h" -#include "llviewerwindow.h" -#include "llwindow.h" - -#include "llvoavatar.h" -#include "llimview.h" -#include "llfloaterreporter.h" -#include "llagent.h" -#include "llagentcamera.h" -#include "llavataractions.h" -#include "llfloaterregioninfo.h" -#include "llviewerregion.h" -#include "lltracker.h" -#include "llchat.h" -#include "llfloaterchat.h" -#include "llviewermessage.h" -#include "llweb.h" -#include "llviewerobjectlist.h" -#include "llmutelist.h" -#include "llcallbacklist.h" - -#include -#include - -#include -#include -#include -#include - -#include "llworld.h" #include "llsdutil.h" -#include "llaudioengine.h" -#include "llstartup.h" -#include "llviewermenu.h" +#include "lluictrlfactory.h" +#include "llwindow.h" #include "hippogridmanager.h" #include "lfsimfeaturehandler.h" +#include "llagent.h" +#include "llagentcamera.h" +#include "llavataractions.h" +#include "llcallbacklist.h" +#include "llfloaterchat.h" +#include "llfloaterregioninfo.h" +#include "llfloaterreporter.h" +#include "llmutelist.h" +#include "llspeakers.h" +#include "lltracker.h" +#include "llviewermenu.h" +#include "llviewermessage.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" +#include "llvoavatar.h" +#include "llvoiceclient.h" +#include "llworld.h" + +#include +#include +#include // [RLVa:KB] #include "rlvhandler.h" @@ -76,85 +68,48 @@ extern U32 gFrameCount; namespace { -void chat_avatar_status(std::string name, LLUUID key, ERadarStatType type, bool entering) -{ - if(gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) return; //RLVa:LF Don't announce people are around when blind, that cheats the system. - static LLCachedControl radar_chat_alerts(gSavedSettings, "RadarChatAlerts"); - if (!radar_chat_alerts) return; - static LLCachedControl radar_alert_sim(gSavedSettings, "RadarAlertSim"); - static LLCachedControl radar_alert_draw(gSavedSettings, "RadarAlertDraw"); - static LLCachedControl radar_alert_shout_range(gSavedSettings, "RadarAlertShoutRange"); - static LLCachedControl radar_alert_chat_range(gSavedSettings, "RadarAlertChatRange"); - static LLCachedControl radar_alert_age(gSavedSettings, "RadarAlertAge"); - - LLFloaterAvatarList* self = LLFloaterAvatarList::getInstance(); - LLStringUtil::format_map_t args; - args["[NAME]"] = name; - switch(type) + void chat_avatar_status(const std::string& name, const LLUUID& key, ERadarStatType type, bool entering) { - case STAT_TYPE_SIM: - if (radar_alert_sim) - { - args["[RANGE]"] = self->getString("the_sim"); - } - break; + if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) return; // RLVa:LF Don't announce people are around when blind, that cheats the system. + static LLCachedControl radar_chat_alerts(gSavedSettings, "RadarChatAlerts"); + if (!radar_chat_alerts) return; + static LLCachedControl radar_alert_sim(gSavedSettings, "RadarAlertSim"); + static LLCachedControl radar_alert_draw(gSavedSettings, "RadarAlertDraw"); + static LLCachedControl radar_alert_shout_range(gSavedSettings, "RadarAlertShoutRange"); + static LLCachedControl radar_alert_chat_range(gSavedSettings, "RadarAlertChatRange"); + static LLCachedControl radar_alert_age(gSavedSettings, "RadarAlertAge"); - case STAT_TYPE_DRAW: - if (radar_alert_draw) - { - args["[RANGE]"] = self->getString("draw_distance"); - } - break; - - case STAT_TYPE_SHOUTRANGE: - if (radar_alert_shout_range) - { - args["[RANGE]"] = self->getString("shout_range"); - } - break; - - case STAT_TYPE_CHATRANGE: - if (radar_alert_chat_range) - { - args["[RANGE]"] = self->getString("chat_range"); - } - break; - - case STAT_TYPE_AGE: - if (radar_alert_age) - { - LLChat chat; - chat.mFromName = name; - chat.mText = name + " " + self->getString("has_triggered_your_avatar_age_alert") + "."; - chat.mURL = llformat("secondlife:///app/agent/%s/about",key.asString().c_str()); - chat.mSourceType = CHAT_SOURCE_SYSTEM; - LLFloaterChat::addChat(chat); - } - break; - default: - llassert(type); - break; - } - if (args.find("[RANGE]") != args.end()) - { - args["[ACTION]"] = self->getString(entering ? "has_entered" : "has_left"); + LLFloaterAvatarList* self = LLFloaterAvatarList::getInstance(); + LLStringUtil::format_map_t args; LLChat chat; - chat.mText = self->getString("template", args); + switch(type) + { + case STAT_TYPE_SIM: if (radar_alert_sim) args["[RANGE]"] = self->getString("the_sim"); break; + case STAT_TYPE_DRAW: if (radar_alert_draw) args["[RANGE]"] = self->getString("draw_distance"); break; + case STAT_TYPE_SHOUTRANGE: if (radar_alert_shout_range) args["[RANGE]"] = self->getString("shout_range"); break; + case STAT_TYPE_CHATRANGE: if (radar_alert_chat_range) args["[RANGE]"] = self->getString("chat_range"); break; + case STAT_TYPE_AGE: if (radar_alert_age) chat.mText = name + " " + self->getString("has_triggered_your_avatar_age_alert") + "."; break; + default: llassert(type); break; + } + args["[NAME]"] = name; + args["[ACTION]"] = self->getString(entering ? "has_entered" : "has_left"); + if (args.find("[RANGE]") != args.end()) + chat.mText = self->getString("template", args); + else if (chat.mText.empty()) return; chat.mFromName = name; chat.mURL = llformat("secondlife:///app/agent/%s/about",key.asString().c_str()); chat.mSourceType = CHAT_SOURCE_SYSTEM; LLFloaterChat::addChat(chat); } -} - void send_keys_message(const int transact_num, const int num_ids, const std::string ids) + void send_keys_message(const int transact_num, const int num_ids, const std::string& ids) { gMessageSystem->newMessage("ScriptDialogReply"); gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgent.getID()); - gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); gMessageSystem->nextBlock("Data"); - gMessageSystem->addUUID("ObjectID", gAgent.getID()); + gMessageSystem->addUUID("ObjectID", gAgentID); gMessageSystem->addS32("ChatChannel", -777777777); gMessageSystem->addS32("ButtonIndex", 1); gMessageSystem->addString("ButtonLabel", llformat("%d,%d", transact_num, num_ids) + ids); @@ -162,7 +117,7 @@ void chat_avatar_status(std::string name, LLUUID key, ERadarStatType type, bool } } //namespace -LLAvatarListEntry::LLAvatarListEntry(const LLUUID& id, const std::string &name, const LLVector3d &position) : +LLAvatarListEntry::LLAvatarListEntry(const LLUUID& id, const std::string& name, const LLVector3d& position) : mID(id), mName(name), mPosition(position), mMarked(false), mFocused(false), mUpdateTimer(), mFrame(gFrameCount), mStats(), mActivityType(ACTIVITY_NEW), mActivityTimer(), @@ -180,7 +135,7 @@ LLAvatarListEntry::~LLAvatarListEntry() // virtual void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) { - if(type == APT_PROPERTIES) + if (type == APT_PROPERTIES) { LLAvatarPropertiesProcessor::getInstance()->removeObserver(mID, this); const LLAvatarData* pAvatarData = static_cast(data); @@ -213,36 +168,20 @@ void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) } } -void LLAvatarListEntry::setPosition(LLVector3d position, bool this_sim, bool drawn, bool chatrange, bool shoutrange) +void LLAvatarListEntry::setPosition(const LLVector3d& position, bool this_sim, bool drawn, bool chatrange, bool shoutrange) { mPosition = position; - mFrame = gFrameCount; - - if (this_sim != mStats[STAT_TYPE_SIM]) - { - chat_avatar_status(mName, mID, STAT_TYPE_SIM, mStats[STAT_TYPE_SIM] = this_sim); - } - if (drawn != mStats[STAT_TYPE_DRAW]) - { - chat_avatar_status(mName, mID, STAT_TYPE_DRAW, mStats[STAT_TYPE_DRAW] = drawn); - } - if (shoutrange != mStats[STAT_TYPE_SHOUTRANGE]) - { - chat_avatar_status(mName, mID, STAT_TYPE_SHOUTRANGE, mStats[STAT_TYPE_SHOUTRANGE] = shoutrange); - } - if (chatrange != mStats[STAT_TYPE_CHATRANGE]) - { - chat_avatar_status(mName, mID, STAT_TYPE_CHATRANGE, mStats[STAT_TYPE_CHATRANGE] = chatrange); - } - + if (this_sim != mStats[STAT_TYPE_SIM]) chat_avatar_status(mName, mID, STAT_TYPE_SIM, mStats[STAT_TYPE_SIM] = this_sim); + if (drawn != mStats[STAT_TYPE_DRAW]) chat_avatar_status(mName, mID, STAT_TYPE_DRAW, mStats[STAT_TYPE_DRAW] = drawn); + if (shoutrange != mStats[STAT_TYPE_SHOUTRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_SHOUTRANGE, mStats[STAT_TYPE_SHOUTRANGE] = shoutrange); + if (chatrange != mStats[STAT_TYPE_CHATRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_CHATRANGE, mStats[STAT_TYPE_CHATRANGE] = chatrange); mUpdateTimer.start(); } -bool LLAvatarListEntry::getAlive() +bool LLAvatarListEntry::getAlive() const { - U32 current = gFrameCount; - return ((current - mFrame) <= 2); + return ((gFrameCount - mFrame) <= 2); } F32 LLAvatarListEntry::getEntryAgeSeconds() const @@ -266,11 +205,11 @@ void LLAvatarListEntry::setActivity(ACTIVITY_TYPE activity) const LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity() { - if ( mActivityTimer.getElapsedTimeF32() > ACTIVITY_TIMEOUT ) + if (mActivityTimer.getElapsedTimeF32() > ACTIVITY_TIMEOUT) { mActivityType = ACTIVITY_NONE; } - if(isDead())return ACTIVITY_DEAD; + if (isDead()) return ACTIVITY_DEAD; return mActivityType; } @@ -328,15 +267,15 @@ void LLFloaterAvatarList::draw() void LLFloaterAvatarList::onOpen() { - gSavedSettings.setBOOL("ShowRadar", TRUE); + gSavedSettings.setBOOL("ShowRadar", true); } void LLFloaterAvatarList::onClose(bool app_quitting) { - setVisible(FALSE); + setVisible(false); if (!app_quitting) { - gSavedSettings.setBOOL("ShowRadar", FALSE); + gSavedSettings.setBOOL("ShowRadar", false); } if (!gSavedSettings.getBOOL("RadarKeepOpen") || app_quitting) { @@ -438,10 +377,10 @@ BOOL LLFloaterAvatarList::postBuild() childSetAction("track_btn", boost::bind(&LLFloaterAvatarList::onClickTrack, this)); childSetAction("mark_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_toggle_mark, false)); childSetAction("focus_btn", boost::bind(&LLFloaterAvatarList::onClickFocus, this)); - childSetAction("prev_in_list_btn", boost::bind(&LLFloaterAvatarList::focusOnPrev, this, FALSE)); - childSetAction("next_in_list_btn", boost::bind(&LLFloaterAvatarList::focusOnNext, this, FALSE)); - childSetAction("prev_marked_btn", boost::bind(&LLFloaterAvatarList::focusOnPrev, this, TRUE)); - childSetAction("next_marked_btn", boost::bind(&LLFloaterAvatarList::focusOnNext, this, TRUE)); + childSetAction("prev_in_list_btn", boost::bind(&LLFloaterAvatarList::focusOnPrev, this, false)); + childSetAction("next_in_list_btn", boost::bind(&LLFloaterAvatarList::focusOnNext, this, false)); + childSetAction("prev_marked_btn", boost::bind(&LLFloaterAvatarList::focusOnPrev, this, true)); + childSetAction("next_marked_btn", boost::bind(&LLFloaterAvatarList::focusOnNext, this, true)); childSetAction("get_key_btn", boost::bind(&LLFloaterAvatarList::onClickGetKey, this)); @@ -462,13 +401,14 @@ BOOL LLFloaterAvatarList::postBuild() gSavedSettings.getControl("RadarColumnPositionHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); gSavedSettings.getControl("RadarColumnAltitudeHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); gSavedSettings.getControl("RadarColumnActivityHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + gSavedSettings.getControl("RadarColumnVoiceHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); gSavedSettings.getControl("RadarColumnAgeHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); gSavedSettings.getControl("RadarColumnTimeHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); // Get a pointer to the scroll list from the interface mAvatarList = getChild("avatar_list"); - mAvatarList->sortByColumn("distance", TRUE); - mAvatarList->setCommitOnSelectionChange(TRUE); + mAvatarList->sortByColumn("distance", true); + mAvatarList->setCommitOnSelectionChange(true); mAvatarList->setCommitCallback(boost::bind(&LLFloaterAvatarList::onSelectName,this)); mAvatarList->setDoubleClickCallback(boost::bind(&LLFloaterAvatarList::onClickFocus,this)); mAvatarList->setSortChangedCallback(boost::bind(&LLFloaterAvatarList::onAvatarSortingChanged,this)); @@ -483,7 +423,7 @@ BOOL LLFloaterAvatarList::postBuild() else gSavedSettings.getControl("RadarColumnClientHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); - return TRUE; + return true; } void col_helper(const bool hide, LLCachedControl &setting, LLScrollListColumn* col) @@ -518,6 +458,7 @@ void LLFloaterAvatarList::assessColumns() BIND_COLUMN_TO_SETTINGS(LIST_POSITION,Position); BIND_COLUMN_TO_SETTINGS(LIST_ALTITUDE,Altitude); BIND_COLUMN_TO_SETTINGS(LIST_ACTIVITY,Activity); + BIND_COLUMN_TO_SETTINGS(LIST_VOICE,Voice); BIND_COLUMN_TO_SETTINGS(LIST_AGE,Age); BIND_COLUMN_TO_SETTINGS(LIST_TIME,Time); @@ -578,11 +519,6 @@ void LLFloaterAvatarList::updateAvatarList() refreshTracker(); return; } - //moved to pipeline to prevent a crash - //gPipeline.forAllVisibleDrawables(updateParticleActivity); - - - //todo: make this less of a hacked up copypasta from dales 1.18. { std::vector avatar_ids; @@ -593,42 +529,31 @@ void LLFloaterAvatarList::updateAvatarList() static const LLCachedControl radar_range_radius("RadarRangeRadius", 0); LLWorld::instance().getAvatars(&avatar_ids, &positions, mypos, radar_range_radius ? radar_range_radius : F32_MAX); - size_t i; - size_t count = avatar_ids.size(); - static LLCachedControl announce(gSavedSettings, "RadarChatKeys"); std::queue announce_keys; - for (i = 0; i < count; ++i) + for (size_t i = 0, count = avatar_ids.size(); i < count; ++i) { - const LLUUID &avid = avatar_ids[i]; - - static const LLCachedControl namesystem("RadarNameSystem"); + const LLUUID& avid = avatar_ids[i]; std::string name; - if (!LLAvatarNameCache::getPNSName(avid, name, namesystem)) - continue; //prevent (Loading...) - - LLAvatarListEntry* entry = getAvatarEntry(avid); + static const LLCachedControl namesystem("RadarNameSystem"); + if (!LLAvatarNameCache::getPNSName(avid, name, namesystem)) continue; //prevent (Loading...) LLVector3d position = positions[i]; LLVOAvatar* avatarp = gObjectList.findAvatar(avid); - if (avatarp) - { - // Get avatar data - position = gAgent.getPosGlobalFromAgent(avatarp->getCharacterPosition()); - } + if (avatarp) position = gAgent.getPosGlobalFromAgent(avatarp->getCharacterPosition()); + LLAvatarListEntry* entry = getAvatarEntry(avid); if (!entry) { // Avatar not there yet, add it - if(announce && gAgent.getRegion()->pointInRegionGlobal(position)) - announce_keys.push(avid); + if (announce && gAgent.getRegion()->pointInRegionGlobal(position)) announce_keys.push(avid); mAvatars.push_back(LLAvatarListEntryPtr(entry = new LLAvatarListEntry(avid, name, position))); } // Announce position - F32 dist = (F32)(position - mypos).magVec(); + F32 dist((position - mypos).magVec()); entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), avatarp, dist < LFSimFeatureHandler::getInstance()->sayRange(), dist < LFSimFeatureHandler::getInstance()->shoutRange()); // Mark as typing if they are typing @@ -637,43 +562,30 @@ void LLFloaterAvatarList::updateAvatarList() // Set activity for anyone making sounds if (gAudiop) - { - for (LLAudioEngine::source_map::iterator iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter) - { - LLAudioSource* sourcep = iter->second; - if (LLAvatarListEntry* entry = getAvatarEntry(sourcep->getOwnerID())) - { + for (LLAudioEngine::source_map::iterator i = gAudiop->mAllSources.begin(); i != gAudiop->mAllSources.end(); ++i) + if (LLAvatarListEntry* entry = getAvatarEntry((i->second)->getOwnerID())) entry->setActivity(LLAvatarListEntry::ACTIVITY_SOUND); - } - } - } //let us send the keys in a more timely fashion if (announce && !announce_keys.empty()) { // NOTE: This fragment is repeated in sendKey std::ostringstream ids; - int transact_num = (int)gFrameCount; - int num_ids = 0; + U32 transact_num = gFrameCount; + U32 num_ids = 0; while(!announce_keys.empty()) { - LLUUID id = announce_keys.front(); - announce_keys.pop(); - - ids << "," << id.asString(); + ids << "," << announce_keys.front().asString(); ++num_ids; - if (ids.tellp() > 200) { send_keys_message(transact_num, num_ids, ids.str()); - - num_ids = 0; - ids.seekp(0); + ids.seekp(num_ids = 0); ids.str(""); } + announce_keys.pop(); } - if (num_ids > 0) - send_keys_message(transact_num, num_ids, ids.str()); + if (num_ids) send_keys_message(transact_num, num_ids, ids.str()); } } @@ -702,7 +614,7 @@ void LLFloaterAvatarList::expireAvatarList() for(av_list_t::iterator it = mAvatars.begin(); it != mAvatars.end();) { LLAvatarListEntry* entry = it->get(); - if(!entry->isDead()) + if (!entry->isDead()) { entry->getAlive(); ++it; @@ -717,26 +629,25 @@ void LLFloaterAvatarList::expireAvatarList() void LLFloaterAvatarList::updateAvatarSorting() { - if(mDirtyAvatarSorting) + if (mDirtyAvatarSorting) { mDirtyAvatarSorting = false; - if(mAvatars.size() <= 1) //Nothing to sort. - return; + if (mAvatars.size() <= 1) return; // Nothing to sort. + const std::vector list = mAvatarList->getAllData(); av_list_t::iterator insert_it = mAvatars.begin(); - for(std::vector::const_iterator it=list.begin();it!=list.end();++it) + for(std::vector::const_iterator it = list.begin(); it != list.end(); ++it) { av_list_t::iterator av_it = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch((*it)->getUUID())); - if(av_it!=mAvatars.end()) - { - std::iter_swap(insert_it++,av_it); - if(insert_it+1 == mAvatars.end()) //We've ran out of elements to sort - return; - } + if (av_it == mAvatars.end()) continue; + std::iter_swap(insert_it++, av_it); + if (insert_it+1 == mAvatars.end()) return; // We've run out of elements to sort } } } +bool mm_getMarkerColor(const LLUUID&, LLColor4&); + /** * Redraws the avatar list * Only does anything if the avatar list is visible. @@ -760,38 +671,21 @@ void LLFloaterAvatarList::refreshAvatarList() posagent.setVec(gAgent.getPositionAgent()); LLVector3d simpos = mypos - posagent; const S32 width(gAgent.getRegion() ? gAgent.getRegion()->getWidth() : 256); + LLSpeakerMgr& speakermgr = LLActiveSpeakerMgr::instance(); + LLRect screen_rect; + localRectToScreen(getLocalRect(), &screen_rect); + speakermgr.update(!(screen_rect.pointInRect(gViewerWindow->getCurrentMouseX(), gViewerWindow->getCurrentMouseY()) && gMouseIdleTimer.getElapsedTimeF32() < 5.f)); BOOST_FOREACH(av_list_t::value_type& entry, mAvatars) { - LLScrollListItem::Params element; - LLUUID av_id; - std::string av_name; - // Skip if avatar hasn't been around - if (entry->isDead()) - { - continue; - } - - entry->setInList(); - - av_id = entry->getID(); - av_name = entry->getName().c_str(); + if (entry->isDead()) continue; LLVector3d position = entry->getPosition(); - BOOL UnknownAltitude = false; - LLVector3d delta = position - mypos; - F32 distance = (F32)delta.magVec(); - F32 unknownAlt = (gHippoGridManager->getConnectedGrid()->isSecondLife()) ? 1020.f : 0.f; - if (position.mdV[VZ] == unknownAlt) - { - UnknownAltitude = true; - distance = 9000.0; - } + bool UnknownAltitude = position.mdV[VZ] == (gHippoGridManager->getConnectedGrid()->isSecondLife() ? 1020.f : 0.f); + F32 distance = UnknownAltitude ? 9000.0f : (F32)delta.magVec(); delta.mdV[2] = 0.0f; - F32 side_distance = (F32)delta.magVec(); - // HACK: Workaround for an apparent bug: // sometimes avatar entries get stuck, and are registered // by the client as perpetually moving in the same direction. @@ -799,11 +693,11 @@ void LLFloaterAvatarList::refreshAvatarList() //jcool410 -- this fucks up seeing dueds thru minimap data > 1024m away, so, lets just say > 2048m to the side is bad //aka 8 sims - if (side_distance > 2048.0f) - { - continue; - } + if (delta.magVec() > 2048.0) continue; + entry->setInList(); + const LLUUID& av_id = entry->getID(); + LLScrollListItem::Params element; element.value = av_id; LLScrollListCell::Params mark; @@ -819,7 +713,7 @@ void LLFloaterAvatarList::refreshAvatarList() LLScrollListCell::Params name; name.column = "avatar_name"; name.type = "text"; - name.value = av_name; + name.value = entry->getName(); if (entry->isFocused()) { name.font_style = "BOLD"; @@ -830,51 +724,49 @@ void LLFloaterAvatarList::refreshAvatarList() //name.color = gColors.getColor( "MapAvatar" ); LLViewerRegion* parent_estate = LLWorld::getInstance()->getRegionFromPosGlobal(entry->getPosition()); LLUUID estate_owner = LLUUID::null; - if(parent_estate && parent_estate->isAlive()) + if (parent_estate && parent_estate->isAlive()) { estate_owner = parent_estate->getOwner(); } - static const LLCachedControl unselected_color(gColors, "ScrollUnselectedColor",LLColor4(0.f, 0.f, 0.f, 0.8f)); + static const LLCachedControl unselected_color(gColors, "ScrollUnselectedColor", LLColor4(0.f, 0.f, 0.f, 0.8f)); static LLCachedControl sDefaultListText(gColors, "DefaultListText"); static LLCachedControl sRadarTextChatRange(gColors, "RadarTextChatRange"); static LLCachedControl sRadarTextShoutRange(gColors, "RadarTextShoutRange"); static LLCachedControl sRadarTextDrawDist(gColors, "RadarTextDrawDist"); static LLCachedControl sRadarTextYoung(gColors, "RadarTextYoung"); - LLColor4 name_color = sDefaultListText; + static const LLCachedControl ascent_muted_color("AscentMutedColor", LLColor4(0.7f,0.7f,0.7f,1.f)); + LLColor4 color = sDefaultListText; //Lindens are always more Linden than your friend, make that take precedence - if(LLMuteList::getInstance()->isLinden(av_id)) + if (mm_getMarkerColor(av_id, color)) {} + else if (LLMuteList::getInstance()->isLinden(av_id)) { - static const LLCachedControl ascent_linden_color("AscentLindenColor",LLColor4(0.f,0.f,1.f,1.f)); - name_color = ascent_linden_color; + static const LLCachedControl ascent_linden_color("AscentLindenColor", LLColor4(0.f,0.f,1.f,1.f)); + color = ascent_linden_color; } //check if they are an estate owner at their current position - else if(estate_owner.notNull() && av_id == estate_owner) + else if (estate_owner.notNull() && av_id == estate_owner) { - static const LLCachedControl ascent_estate_owner_color("AscentEstateOwnerColor",LLColor4(1.f,0.6f,1.f,1.f)); - name_color = ascent_estate_owner_color; + static const LLCachedControl ascent_estate_owner_color("AscentEstateOwnerColor", LLColor4(1.f,0.6f,1.f,1.f)); + color = ascent_estate_owner_color; } //without these dots, SL would suck. - else if(LLAvatarActions::isFriend(av_id)) + else if (LLAvatarActions::isFriend(av_id)) { - static const LLCachedControl ascent_friend_color("AscentFriendColor",LLColor4(1.f,1.f,0.f,1.f)); - name_color = ascent_friend_color; + static const LLCachedControl ascent_friend_color("AscentFriendColor", LLColor4(1.f,1.f,0.f,1.f)); + color = ascent_friend_color; } //big fat jerkface who is probably a jerk, display them as such. - else if(LLMuteList::getInstance()->isMuted(av_id)) + else if (LLMuteList::getInstance()->isMuted(av_id)) { - static const LLCachedControl ascent_muted_color("AscentMutedColor",LLColor4(0.7f,0.7f,0.7f,1.f)); - name_color = ascent_muted_color; + color = ascent_muted_color; } - - name_color = name_color*0.5f + unselected_color*0.5f; - - name.color = name_color; + name.color = color*0.5f + unselected_color*0.5f; char temp[32]; - LLColor4 color = sDefaultListText; + color = sDefaultListText; LLScrollListCell::Params dist; dist.column = "distance"; dist.type = "text"; @@ -891,32 +783,23 @@ void LLFloaterAvatarList::refreshAvatarList() if (distance <= LFSimFeatureHandler::getInstance()->shoutRange()) { snprintf(temp, sizeof(temp), "%.1f", distance); - if (distance > LFSimFeatureHandler::getInstance()->sayRange()) - { - color = sRadarTextShoutRange; - } - else - { - color = sRadarTextChatRange; - } + color = (distance > LFSimFeatureHandler::getInstance()->sayRange()) ? sRadarTextShoutRange : sRadarTextChatRange; } else { - if (entry->mStats[STAT_TYPE_DRAW]) - { - color = sRadarTextDrawDist; - } + if (entry->mStats[STAT_TYPE_DRAW]) color = sRadarTextDrawDist; snprintf(temp, sizeof(temp), "%d", (S32)distance); } } dist.value = temp; - dist.color = color; + dist.color = color * 0.7f + unselected_color * 0.3f; // Liru: Blend testing! + //dist.color = color; LLScrollListCell::Params pos; - position = position - simpos; + position -= simpos; - S32 x = (S32)position.mdV[VX]; - S32 y = (S32)position.mdV[VY]; + S32 x(position.mdV[VX]); + S32 y(position.mdV[VY]); if (x >= 0 && x <= width && y >= 0 && y <= width) { snprintf(temp, sizeof(temp), "%d, %d", x, y); @@ -959,62 +842,79 @@ void LLFloaterAvatarList::refreshAvatarList() alt.value = temp; LLScrollListCell::Params act; - act.column = "activity"; - act.type = "icon"; - - std::string activity_icon = ""; - std::string activity_tip = ""; - switch(entry->getActivity()) + static const LLCachedControl hide_act("RadarColumnActivityHidden"); + if (!hide_act) { - case LLAvatarListEntry::ACTIVITY_MOVING: + act.column = "activity"; + act.type = "icon"; + switch(entry->getActivity()) { - activity_icon = "inv_item_animation.tga"; - activity_tip = getString("Moving"); + case LLAvatarListEntry::ACTIVITY_MOVING: + act.value = "inv_item_animation.tga"; + act.tool_tip = getString("Moving"); + break; + case LLAvatarListEntry::ACTIVITY_GESTURING: + act.value = "inv_item_gesture.tga"; + act.tool_tip = getString("Playing a gesture"); + break; + case LLAvatarListEntry::ACTIVITY_SOUND: + act.value = "inv_item_sound.tga"; + act.tool_tip = getString("Playing a sound"); + break; + case LLAvatarListEntry::ACTIVITY_REZZING: + act.value = "ff_edit_theirs.tga"; + act.tool_tip = getString("Rezzing objects"); + break; + case LLAvatarListEntry::ACTIVITY_PARTICLES: + act.value = "particles_scan.tga"; + act.tool_tip = getString("Creating particles"); + break; + case LLAvatarListEntry::ACTIVITY_NEW: + act.value = "avatar_new.tga"; + act.tool_tip = getString("Just arrived"); + break; + case LLAvatarListEntry::ACTIVITY_TYPING: + act.value = "avatar_typing.tga"; + act.tool_tip = getString("Typing"); + break; + default: + break; } - break; - case LLAvatarListEntry::ACTIVITY_GESTURING: - { - activity_icon = "inv_item_gesture.tga"; - activity_tip = getString("Playing a gesture"); - } - break; - case LLAvatarListEntry::ACTIVITY_SOUND: - { - activity_icon = "inv_item_sound.tga"; - activity_tip = getString("Playing a sound"); - } - break; - case LLAvatarListEntry::ACTIVITY_REZZING: - { - activity_icon = "ff_edit_theirs.tga"; - activity_tip = getString("Rezzing objects"); - } - break; - case LLAvatarListEntry::ACTIVITY_PARTICLES: - { - activity_icon = "particles_scan.tga"; - activity_tip = getString("Creating particles"); - } - break; - case LLAvatarListEntry::ACTIVITY_NEW: - { - activity_icon = "avatar_new.tga"; - activity_tip = getString("Just arrived"); - } - break; - case LLAvatarListEntry::ACTIVITY_TYPING: - { - activity_icon = "avatar_typing.tga"; - activity_tip = getString("Typing"); - } - break; - default: - break; } - act.value = activity_icon;//icon_image_id; //"icn_active-speakers-dot-lvl0.tga"; - //act.color = icon_color; - act.tool_tip = activity_tip; + LLScrollListCell::Params voice; + static const LLCachedControl hide_voice("RadarColumnVoiceHidden"); + if (!hide_voice) + { + voice.column("voice"); + voice.type("icon"); + // transplant from llparticipantlist.cpp, update accordingly. + if (LLPointer speakerp = speakermgr.findSpeaker(av_id)) + { + if (speakerp->mStatus == LLSpeaker::STATUS_MUTED) + { + voice.value("mute_icon.tga"); + voice.color(speakerp->mModeratorMutedVoice ? ascent_muted_color : LLColor4(1.f, 71.f / 255.f, 71.f / 255.f, 1.f)); + } + else + { + switch(llmin(2, llfloor((speakerp->mSpeechVolume / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f))) + { + case 0: + voice.value("icn_active-speakers-dot-lvl0.tga"); + break; + case 1: + voice.value("icn_active-speakers-dot-lvl1.tga"); + break; + case 2: + voice.value("icn_active-speakers-dot-lvl2.tga"); + break; + } + // non voice speakers have hidden icons, render as transparent + voice.color(speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE ? LLColor4::transparent : speakerp->mDotColor); + } + } + } LLScrollListCell::Params agep; agep.column = "age"; @@ -1049,17 +949,16 @@ void LLFloaterAvatarList::refreshAvatarList() viewer.type = "text"; static const LLCachedControl avatar_name_color(gColors, "AvatarNameColor",LLColor4(0.98f, 0.69f, 0.36f, 1.f)); - LLColor4 client_color(avatar_name_color); - LLVOAvatar* avatarp = gObjectList.findAvatar(av_id); - if(avatarp) + color = avatar_name_color; + if (LLVOAvatar* avatarp = gObjectList.findAvatar(av_id)) { std::string client = SHClientTagMgr::instance().getClientName(avatarp, false); - SHClientTagMgr::instance().getClientColor(avatarp, false, client_color); - if(client == "") + if (client.empty()) { - client_color = unselected_color; + color = unselected_color; client = "?"; } + else SHClientTagMgr::instance().getClientColor(avatarp, false, color); viewer.value = client.c_str(); } else @@ -1067,9 +966,7 @@ void LLFloaterAvatarList::refreshAvatarList() viewer.value = getString("Out Of Range"); } //Blend to make the color show up better - client_color = client_color *.5f + unselected_color * .5f; - - viewer.color = client_color; + viewer.color = color *.5f + unselected_color * .5f; // Add individual column cell params to the item param element.columns.add(mark); @@ -1077,7 +974,8 @@ void LLFloaterAvatarList::refreshAvatarList() element.columns.add(dist); element.columns.add(pos); element.columns.add(alt); - element.columns.add(act); + if (!hide_act) element.columns.add(act); + if (!hide_voice) element.columns.add(voice); element.columns.add(agep); element.columns.add(time); element.columns.add(viewer); @@ -1135,11 +1033,11 @@ void LLFloaterAvatarList::onClickTrack() if (mTracking && mTrackedAvatar == agent_id) { LLTracker::stopTracking(false); - mTracking = FALSE; + mTracking = false; } else { - mTracking = TRUE; + mTracking = true; mTrackedAvatar = agent_id; // trackAvatar only works for friends allowing you to see them on map... // LLTracker::trackAvatar(agent_id, self->mAvatars[agent_id].getName()); @@ -1164,70 +1062,60 @@ void LLFloaterAvatarList::refreshTracker() else { // Tracker stopped. LLTracker::stopTracking(false); - mTracking = FALSE; + mTracking = false; // llinfos << "Tracking stopped." << llendl; } } -void LLFloaterAvatarList::trackAvatar(const LLAvatarListEntry* entry) +void LLFloaterAvatarList::trackAvatar(const LLAvatarListEntry* entry) const { - if(!entry) return; + if (!entry) return; std::string name = entry->getName(); - if (!mUpdate) - { - name += "\n(last known position)"; - } + if (!mUpdate) name += "\n(last known position)"; LLTracker::trackLocation(entry->getPosition(), name, name); } -LLAvatarListEntry * LLFloaterAvatarList::getAvatarEntry(LLUUID avatar) +LLAvatarListEntry* LLFloaterAvatarList::getAvatarEntry(const LLUUID& avatar) const { - if (avatar.isNull()) - { - return NULL; - } - - av_list_t::iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(avatar)); - if(iter != mAvatars.end()) - return iter->get(); - else - return NULL; + if (avatar.isNull()) return NULL; + av_list_t::const_iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(avatar)); + return (iter != mAvatars.end()) ? iter->get() : NULL; } BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) { - LLScrollListItem* item = mAvatarList->getFirstSelected(); - if(item) + if (const LLScrollListItem* item = mAvatarList->getFirstSelected()) { LLUUID agent_id = item->getUUID(); - if (( KEY_RETURN == key ) && (MASK_NONE == mask)) + if (KEY_RETURN == key) { - setFocusAvatar(agent_id); - return TRUE; - } - else if (( KEY_RETURN == key ) && (MASK_CONTROL == mask)) - { - const LLAvatarListEntry* entry = getAvatarEntry(agent_id); - if (entry) + if (MASK_NONE == mask) { -// llinfos << "Trying to teleport to " << entry->getName() << " at " << entry->getPosition() << llendl; - gAgent.teleportViaLocation(entry->getPosition()); + setFocusAvatar(agent_id); + return true; + } + if (MASK_CONTROL == mask) + { + if (const LLAvatarListEntry* entry = getAvatarEntry(agent_id)) + { +// llinfos << "Trying to teleport to " << entry->getName() << " at " << entry->getPosition() << llendl; + gAgent.teleportViaLocation(entry->getPosition()); + } + return true; + } + if (MASK_SHIFT == mask) + { + onClickIM(); + return true; } - return TRUE; } } - - if (( KEY_RETURN == key ) && (MASK_SHIFT == mask)) - { - onClickIM(); - } return LLPanel::handleKeyHere(key, mask); } void LLFloaterAvatarList::onClickFocus() { - LLScrollListItem* item = mAvatarList->getFirstSelected(); - if (item) + if (LLScrollListItem* item = mAvatarList->getFirstSelected()) { setFocusAvatar(item->getUUID()); } @@ -1237,20 +1125,17 @@ void LLFloaterAvatarList::removeFocusFromAll() { BOOST_FOREACH(av_list_t::value_type& entry, mAvatars) { - entry->setFocus(FALSE); + entry->setFocus(false); } } void LLFloaterAvatarList::setFocusAvatar(const LLUUID& id) { + if (!gAgentCamera.lookAtObject(id, false) && !lookAtAvatar(id)) return; av_list_t::iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(id)); - if(iter != mAvatars.end()) - { - if(!gAgentCamera.lookAtObject(id, false)) - return; - removeFocusFromAll(); - (*iter)->setFocus(TRUE); - } + if (iter == mAvatars.end()) return; + removeFocusFromAll(); + (*iter)->setFocus(true); } // Simple function to decrement iterators, wrapping back if needed @@ -1261,7 +1146,7 @@ T prev_iter(const T& cur, const T& begin, const T& end) } template -void decrement_focus_target(T begin, T end, BOOL marked_only) +void decrement_focus_target(T begin, const T& end, bool marked_only) { for (T iter = begin; iter != end; ++iter) { @@ -1284,54 +1169,55 @@ void decrement_focus_target(T begin, T end, BOOL marked_only) } } -void LLFloaterAvatarList::focusOnPrev(BOOL marked_only) +void LLFloaterAvatarList::focusOnPrev(bool marked_only) { updateAvatarSorting(); decrement_focus_target(mAvatars.begin(), mAvatars.end(), marked_only); } -void LLFloaterAvatarList::focusOnNext(BOOL marked_only) +void LLFloaterAvatarList::focusOnNext(bool marked_only) { updateAvatarSorting(); decrement_focus_target(mAvatars.rbegin(), mAvatars.rend(), marked_only); } /*static*/ -void LLFloaterAvatarList::lookAtAvatar(LLUUID &uuid) +bool LLFloaterAvatarList::lookAtAvatar(const LLUUID& uuid) { // twisted laws LLVOAvatar* voavatar = gObjectList.findAvatar(uuid); - if(voavatar && voavatar->isAvatar()) + if (voavatar && voavatar->isAvatar()) { - gAgentCamera.setFocusOnAvatar(FALSE, FALSE); + gAgentCamera.setFocusOnAvatar(false, false); gAgentCamera.changeCameraToThirdPerson(); gAgentCamera.setFocusGlobal(voavatar->getPositionGlobal(),uuid); gAgentCamera.setCameraPosAndFocusGlobal(voavatar->getPositionGlobal() - + LLVector3d(3.5,1.35,0.75) * voavatar->getRotation(), + + LLVector3d(3.5, 1.35, 0.75) * voavatar->getRotation(), voavatar->getPositionGlobal(), - uuid ); + uuid); + return true; } + return false; } void LLFloaterAvatarList::onClickGetKey() { - LLScrollListItem* item = mAvatarList->getFirstSelected(); - - if (NULL == item) return; - - gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(item->getUUID().asString())); + if (LLScrollListItem* item = mAvatarList->getFirstSelected()) + { + gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(item->getUUID().asString())); + } } -void LLFloaterAvatarList::sendKeys() +void LLFloaterAvatarList::sendKeys() const { // This would break for send_keys_btn callback, check this beforehand, if it matters. //static LLCachedControl radar_chat_keys(gSavedSettings, "RadarChatKeys"); //if (radar_chat_keys) return; LLViewerRegion* regionp = gAgent.getRegion(); - if (!regionp) return;//ALWAYS VALIDATE DATA + if (!regionp) return; - static int last_transact_num = 0; - int transact_num = (int)gFrameCount; + static U32 last_transact_num = 0; + U32 transact_num(gFrameCount); if (transact_num > last_transact_num) { @@ -1345,37 +1231,32 @@ void LLFloaterAvatarList::sendKeys() } std::ostringstream ids; - int num_ids = 0; + U32 num_ids = 0; - for (int i = 0; i < regionp->mMapAvatarIDs.count(); ++i) + for (S32 i = 0; i < regionp->mMapAvatarIDs.count(); ++i) { - const LLUUID &id = regionp->mMapAvatarIDs.get(i); - - ids << "," << id; + ids << "," << regionp->mMapAvatarIDs.get(i); ++num_ids; - - if (ids.tellp() > 200) { send_keys_message(transact_num, num_ids, ids.str()); - - num_ids = 0; - ids.seekp(0); + ids.seekp(num_ids = 0); ids.str(""); } } - if (num_ids > 0) - send_keys_message(transact_num, num_ids, ids.str()); + if (num_ids > 0) send_keys_message(transact_num, num_ids, ids.str()); } //static void LLFloaterAvatarList::sound_trigger_hook(LLMessageSystem* msg,void **) { if (!LLFloaterAvatarList::instanceExists()) return; // Don't bother if we're closed. - LLUUID sound_id,owner_id; - msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_SoundID, sound_id); + LLUUID owner_id; msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_OwnerID, owner_id); - if (owner_id == gAgent.getID() && sound_id == LLUUID("76c78607-93f9-f55a-5238-e19b1a181389")) + if (owner_id != gAgentID) return; + LLUUID sound_id; + msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_SoundID, sound_id); + if (sound_id == LLUUID("76c78607-93f9-f55a-5238-e19b1a181389")) { static LLCachedControl on("RadarChatKeys"); static LLCachedControl do_not_ask("RadarChatKeysStopAsking"); @@ -1386,7 +1267,7 @@ void LLFloaterAvatarList::sound_trigger_hook(LLMessageSystem* msg,void **) } } // static -bool LLFloaterAvatarList::onConfirmRadarChatKeys(const LLSD& notification, const LLSD& response ) +bool LLFloaterAvatarList::onConfirmRadarChatKeys(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); if (option == 1) // no @@ -1408,51 +1289,49 @@ bool LLFloaterAvatarList::onConfirmRadarChatKeys(const LLSD& notification, const void send_freeze(const LLUUID& avatar_id, bool freeze) { - U32 flags = 0x0; - if (!freeze) - { - // unfreeze - flags |= 0x1; - } - - LLMessageSystem* msg = gMessageSystem; LLVOAvatar* avatarp = gObjectList.findAvatar(avatar_id); - - if (avatarp && avatarp->getRegion()) + if (!avatarp) return; + if (LLViewerRegion* region = avatarp->getRegion()) { + LLMessageSystem* msg = gMessageSystem; msg->newMessage("FreezeUser"); msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); + msg->addUUID("AgentID", gAgentID); + msg->addUUID("SessionID", gAgentSessionID); msg->nextBlock("Data"); msg->addUUID("TargetID", avatar_id); + U32 flags = 0x0; + if (!freeze) + { + // unfreeze + flags |= 0x1; + } msg->addU32("Flags", flags); - msg->sendReliable( avatarp->getRegion()->getHost()); + msg->sendReliable(region->getHost()); } } void send_eject(const LLUUID& avatar_id, bool ban) -{ - LLMessageSystem* msg = gMessageSystem; +{ LLVOAvatar* avatarp = gObjectList.findAvatar(avatar_id); - - if (avatarp && avatarp->getRegion()) + if (!avatarp) return; + if (LLViewerRegion* region = avatarp->getRegion()) { + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EjectUser"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgentID); + msg->addUUID("SessionID", gAgentSessionID); + msg->nextBlock("Data"); + msg->addUUID("TargetID", avatar_id); U32 flags = 0x0; if (ban) { // eject and add to ban list flags |= 0x1; } - - msg->newMessage("EjectUser"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->nextBlock("Data"); - msg->addUUID("TargetID", avatar_id); msg->addU32("Flags", flags); - msg->sendReliable(avatarp->getRegion()->getHost()); + msg->sendReliable(region->getHost()); } } @@ -1471,8 +1350,8 @@ static void send_estate_message( llinfos << "Sending estate request '" << request << "'" << llendl; msg->newMessage("EstateOwnerMessage"); msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_AgentID, gAgentID); + msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used msg->nextBlock("MethodData"); msg->addString("Method", request); @@ -1480,7 +1359,7 @@ static void send_estate_message( // Agent id msg->nextBlock("ParamList"); - msg->addString("Parameter", gAgent.getID().asString().c_str()); + msg->addString("Parameter", gAgentID.asString().c_str()); // Target msg->nextBlock("ParamList"); @@ -1502,20 +1381,18 @@ static void cmd_ban(const LLAvatarListEntry* entry) { send_eject(entry->getID( static void cmd_estate_eject(const LLAvatarListEntry* entry){ send_estate_message("teleporthomeuser", entry->getID()); } static void cmd_estate_ban(const LLAvatarListEntry* entry) { LLPanelEstateInfo::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, entry->getID()); } -void LLFloaterAvatarList::doCommand(avlist_command_t func, bool single/*=false*/) +void LLFloaterAvatarList::doCommand(avlist_command_t func, bool single/*=false*/) const { uuid_vec_t ids; - if(!single) + if (!single) ids = mAvatarList->getSelectedIDs(); else ids.push_back(getSelectedID()); - for (uuid_vec_t::iterator itr = ids.begin(); itr != ids.end(); ++itr) + for (uuid_vec_t::const_iterator itr = ids.begin(); itr != ids.end(); ++itr) { - LLUUID& avid = *itr; - if(avid.isNull()) - continue; - LLAvatarListEntry* entry = getAvatarEntry(avid); - if (entry != NULL) + const LLUUID& avid = *itr; + if (avid.isNull()) continue; + if (LLAvatarListEntry* entry = getAvatarEntry(avid)) { llinfos << "Executing command on " << entry->getName() << llendl; func(entry); @@ -1523,32 +1400,26 @@ void LLFloaterAvatarList::doCommand(avlist_command_t func, bool single/*=false*/ } } -std::string LLFloaterAvatarList::getSelectedNames(const std::string& separator) +std::string LLFloaterAvatarList::getSelectedNames(const std::string& separator) const { std::string ret; doCommand(boost::bind(&cmd_append_names,_1,boost::ref(ret),separator)); return ret; } -std::string LLFloaterAvatarList::getSelectedName() +std::string LLFloaterAvatarList::getSelectedName() const { - LLUUID id = getSelectedID(); - LLAvatarListEntry* entry = getAvatarEntry(id); - if (entry) - { - return entry->getName(); - } - return ""; + LLAvatarListEntry* entry = getAvatarEntry(getSelectedID()); + return entry ? entry->getName() : ""; } -LLUUID LLFloaterAvatarList::getSelectedID() +LLUUID LLFloaterAvatarList::getSelectedID() const { LLScrollListItem* item = mAvatarList->getFirstSelected(); - if (item) return item->getUUID(); - return LLUUID::null; + return item ? item->getUUID() : LLUUID::null; } -uuid_vec_t LLFloaterAvatarList::getSelectedIDs() +uuid_vec_t LLFloaterAvatarList::getSelectedIDs() const { return mAvatarList->getSelectedIDs(); } @@ -1556,120 +1427,82 @@ uuid_vec_t LLFloaterAvatarList::getSelectedIDs() //static void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& response) { - if(!instanceExists()) - return; - + if (!instanceExists()) return; + LLFloaterAvatarList& inst(instance()); S32 option = LLNotification::getSelectedOption(notification, response); - - if (option == 0) - { - getInstance()->doCommand(cmd_freeze); - } - else if (option == 1) - { - getInstance()->doCommand(cmd_unfreeze); - } + if (option == 0) inst.doCommand(cmd_freeze); + else if (option == 1) inst.doCommand(cmd_unfreeze); } //static void LLFloaterAvatarList::callbackEject(const LLSD& notification, const LLSD& response) { - if(!instanceExists()) - return; - + if (!instanceExists()) return; + LLFloaterAvatarList& inst(instance()); S32 option = LLNotification::getSelectedOption(notification, response); - - if (option == 0) - { - getInstance()->doCommand(cmd_eject); - } - else if (option == 1) - { - getInstance()->doCommand(cmd_ban); - } + if (option == 0) inst.doCommand(cmd_eject); + else if (option == 1) inst.doCommand(cmd_ban); } //static void LLFloaterAvatarList::callbackEjectFromEstate(const LLSD& notification, const LLSD& response) { - if(!instanceExists()) - return; - - S32 option = LLNotification::getSelectedOption(notification, response); - - if (option == 0) - { - getInstance()->doCommand(cmd_estate_eject); - } + if (!instanceExists()) return; + LLFloaterAvatarList& inst(instance()); + if (!LLNotification::getSelectedOption(notification, response)) // if == 0 + inst.doCommand(cmd_estate_eject); } //static void LLFloaterAvatarList::callbackBanFromEstate(const LLSD& notification, const LLSD& response) { - if(!instanceExists()) - return; - - S32 option = LLNotification::getSelectedOption(notification, response); - - if (option == 0) + if (!instanceExists()) return; + LLFloaterAvatarList& inst(instance()); + if (!LLNotification::getSelectedOption(notification, response)) // if == 0 { - getInstance()->doCommand(cmd_estate_eject); //Eject first, just in case. - getInstance()->doCommand(cmd_estate_ban); + inst.doCommand(cmd_estate_eject); //Eject first, just in case. + inst.doCommand(cmd_estate_ban); } } //static -void LLFloaterAvatarList::callbackIdle(void* userdata) +void LLFloaterAvatarList::callbackIdle(void*) { if (instanceExists()) { + LLFloaterAvatarList& inst(instance()); + const U32& rate = inst.mUpdateRate; // Do not update at every frame: this would be insane! - if (gFrameCount % getInstance()->mUpdateRate == 0) - { - getInstance()->updateAvatarList(); - } + if (rate == 0 || (gFrameCount % rate == 0)) + inst.updateAvatarList(); } } void LLFloaterAvatarList::onClickFreeze() { LLSD args; - LLSD payload; args["AVATAR_NAME"] = getSelectedNames(); - LLNotificationsUtil::add("FreezeAvatarFullname", args, payload, callbackFreeze); + LLNotificationsUtil::add("FreezeAvatarFullname", args, LLSD(), callbackFreeze); } void LLFloaterAvatarList::onClickEject() { LLSD args; - LLSD payload; args["AVATAR_NAME"] = getSelectedNames(); - LLNotificationsUtil::add("EjectAvatarFullname", args, payload, callbackEject); + LLNotificationsUtil::add("EjectAvatarFullname", args, LLSD(), callbackEject); } void LLFloaterAvatarList::onClickMute() { uuid_vec_t ids = mAvatarList->getSelectedIDs(); - if (ids.size() > 0) + for (uuid_vec_t::const_iterator itr = ids.begin(); itr != ids.end(); ++itr) { - for (uuid_vec_t::iterator itr = ids.begin(); itr != ids.end(); ++itr) + const LLUUID& agent_id = *itr; + std::string agent_name; + if (gCacheName->getFullName(agent_id, agent_name)) { - LLUUID agent_id = *itr; - - std::string agent_name; - if (gCacheName->getFullName(agent_id, agent_name)) - { - if (LLMuteList::getInstance()->isMuted(agent_id)) - { - LLMute mute(agent_id, agent_name, LLMute::AGENT); - LLMuteList::getInstance()->remove(mute); - } - else - { - LLMute mute(agent_id, agent_name, LLMute::AGENT); - LLMuteList::getInstance()->add(mute); - } - } + LLMute mute(agent_id, agent_name, LLMute::AGENT); + LLMuteList::getInstance()->isMuted(agent_id) ? LLMuteList::getInstance()->remove(mute) : LLMuteList::getInstance()->add(mute); } } } @@ -1677,9 +1510,8 @@ void LLFloaterAvatarList::onClickMute() void LLFloaterAvatarList::onClickEjectFromEstate() { LLSD args; - LLSD payload; args["EVIL_USER"] = getSelectedNames(); - LLNotificationsUtil::add("EstateKickUser", args, payload, callbackEjectFromEstate); + LLNotificationsUtil::add("EstateKickUser", args, LLSD(), callbackEjectFromEstate); } void LLFloaterAvatarList::onClickBanFromEstate() @@ -1687,24 +1519,16 @@ void LLFloaterAvatarList::onClickBanFromEstate() LLSD args; LLSD payload; args["EVIL_USER"] = getSelectedNames(); - LLNotificationsUtil::add("EstateBanUser", args, payload, callbackBanFromEstate); -} - -void LLFloaterAvatarList::onAvatarSortingChanged() -{ - mDirtyAvatarSorting = true; + LLNotificationsUtil::add("EstateBanUser", args, LLSD(), callbackBanFromEstate); } void LLFloaterAvatarList::onSelectName() { - LLScrollListItem* item = mAvatarList->getFirstSelected(); - if (item) + if (LLScrollListItem* item = mAvatarList->getFirstSelected()) { - LLUUID agent_id = item->getUUID(); - LLAvatarListEntry* entry = getAvatarEntry(agent_id); - if (entry) + if (LLAvatarListEntry* entry = getAvatarEntry(item->getUUID())) { - BOOL enabled = entry->mStats[STAT_TYPE_DRAW]; + bool enabled = entry->mStats[STAT_TYPE_DRAW]; childSetEnabled("focus_btn", enabled); childSetEnabled("prev_in_list_btn", enabled); childSetEnabled("next_in_list_btn", enabled); diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index a18b4f9cb..222107c12 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -10,6 +10,10 @@ // Copyright: See COPYING file that comes with this distribution // // + +#ifndef LL_LLFLOATERAVATARLIST_H +#define LL_LLFLOATERAVATARLIST_H + #include "llavatarname.h" #include "llavatarpropertiesprocessor.h" #include "llfloater.h" @@ -76,7 +80,7 @@ enum ACTIVITY_TYPE * Update world position. * Affects age. */ - void setPosition(LLVector3d position, bool this_sim, bool drawn, bool chatrange, bool shoutrange); + void setPosition(const LLVector3d& position, bool this_sim, bool drawn, bool chatrange, bool shoutrange); const LLVector3d& getPosition() const { return mPosition; } @@ -86,7 +90,7 @@ enum ACTIVITY_TYPE * This is only used for determining whether the avatar is still around. * @see getEntryAgeSeconds */ - bool getAlive(); + bool getAlive() const; /** * @brief Returns the age of this entry in seconds @@ -107,14 +111,14 @@ enum ACTIVITY_TYPE void setActivity(ACTIVITY_TYPE activity); /** - * @brief Returns the activity type + * @brief Returns the activity type, updates mActivityType if necessary */ const ACTIVITY_TYPE getActivity(); /** * @brief Sets the 'focus' status on this entry (camera focused on this avatar) */ - void setFocus(BOOL value) { mFocused = value; } + void setFocus(bool value) { mFocused = value; } bool isFocused() const { return mFocused; } @@ -130,7 +134,7 @@ enum ACTIVITY_TYPE bool isInList() const { return mIsInList; } /** * @brief Returns whether the item is dead and shouldn't appear in the list - * @returns TRUE if dead + * @returns true if dead */ bool isDead() const; @@ -207,7 +211,6 @@ public: /*virtual*/ void onOpen(); /*virtual*/ BOOL postBuild(); /*virtual*/ void draw(); - static void createInstance(bool visible); /** * @brief Toggles interface visibility * There is only one instance of the avatar scanner at any time. @@ -234,20 +237,20 @@ public: * @brief Returns the entry for an avatar, if preset * @returns Pointer to avatar entry, NULL if not found. */ - LLAvatarListEntry* getAvatarEntry(LLUUID avatar); + LLAvatarListEntry* getAvatarEntry(const LLUUID& avatar) const; /** * @brief Returns a string with the selected names in the list */ - std::string getSelectedNames(const std::string& separator = ", "); - std::string getSelectedName(); - LLUUID getSelectedID(); - uuid_vec_t getSelectedIDs(); + std::string getSelectedNames(const std::string& separator = ", ") const; + std::string getSelectedName() const; + LLUUID getSelectedID() const; + uuid_vec_t getSelectedIDs() const; - static void lookAtAvatar(LLUUID &uuid); + static bool lookAtAvatar(const LLUUID& uuid); static void sound_trigger_hook(LLMessageSystem* msg,void **); - void sendKeys(); + void sendKeys() const; typedef boost::shared_ptr LLAvatarListEntryPtr; typedef std::vector< LLAvatarListEntryPtr > av_list_t; @@ -264,6 +267,7 @@ public: LIST_POSITION, LIST_ALTITUDE, LIST_ACTIVITY, + LIST_VOICE, LIST_AGE, LIST_TIME, LIST_CLIENT, @@ -285,16 +289,16 @@ public: * @brief Focus camera on previous avatar * @param marked_only Whether to choose only marked avatars */ - void focusOnPrev(BOOL marked_only); + void focusOnPrev(bool marked_only); /** * @brief Focus camera on next avatar * @param marked_only Whether to choose only marked avatars */ - void focusOnNext(BOOL marked_only); + void focusOnNext(bool marked_only); void refreshTracker(); - void trackAvatar(const LLAvatarListEntry* entry); + void trackAvatar(const LLAvatarListEntry* entry) const; /** * @brief Handler for the "refresh" button click. @@ -321,7 +325,8 @@ public: void onClickEject(); void onClickEjectFromEstate(); void onClickBanFromEstate(); - void onAvatarSortingChanged(); + + void onAvatarSortingChanged() { mDirtyAvatarSorting = true; } /** * @brief Called via notification feedback. @@ -335,7 +340,7 @@ public: static void callbackIdle(void *userdata); - void doCommand(avlist_command_t cmd, bool single = false); + void doCommand(avlist_command_t cmd, bool single = false) const; /** * @brief Cleanup avatar list, removing dead entries from it. @@ -355,7 +360,7 @@ private: bool mDirtyAvatarSorting; /** - * @brief TRUE when Updating + * @brief true when Updating */ const LLCachedControl mUpdate; @@ -373,3 +378,5 @@ private: */ LLUUID mFocusedAvatar; }; + +#endif diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index f503fa3ba..718750b5f 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -427,7 +427,7 @@ public: // in case of invalid characters, the avatar picker returns a 400 // just set it to process so it displays 'not found' - if ((200 <= status && status < 300) || status == 400) + if (isGoodStatus(status) || status == 400) { if (LLFloaterAvatarPicker::instanceExists()) { diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 58e27b914..251397fa6 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -375,6 +375,10 @@ BOOL LLFloaterBvhPreview::postBuild() } } + if (motionp && mInWorld) + { + gAgentAvatarp->removeMotion(mMotionID); + } //setEnabled(FALSE); mMotionID.setNull(); mAnimPreview = NULL; diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index eaa563278..348b9235a 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -102,13 +102,6 @@ LLFloaterChat::~LLFloaterChat() // Children all cleaned up by default view destructor. } -void LLFloaterChat::setVisible(BOOL visible) -{ - LLFloater::setVisible( visible ); - - gSavedSettings.setBOOL("ShowChatHistory", visible); -} - void LLFloaterChat::draw() { // enable say and shout only when text available @@ -140,6 +133,11 @@ BOOL LLFloaterChat::postBuild() return TRUE; } +void LLFloaterChat::onOpen() +{ + gSavedSettings.setBOOL("ShowChatHistory", true); +} + // public virtual void LLFloaterChat::onClose(bool app_quitting) { diff --git a/indra/newview/llfloaterchat.h b/indra/newview/llfloaterchat.h index 7eaab1b16..dcad5f632 100644 --- a/indra/newview/llfloaterchat.h +++ b/indra/newview/llfloaterchat.h @@ -59,9 +59,9 @@ public: LLFloaterChat(const LLSD& seed); ~LLFloaterChat(); - virtual void setVisible( BOOL b ); virtual void draw(); virtual BOOL postBuild(); + virtual void onOpen(); virtual void onClose(bool app_quitting); virtual void onFocusReceived(); virtual void handleVisibilityChange(BOOL cur_visibility); diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp index c491f07fe..2e3598d23 100644 --- a/indra/newview/llfloaterchatterbox.cpp +++ b/indra/newview/llfloaterchatterbox.cpp @@ -78,9 +78,14 @@ BOOL LLFloaterMyFriends::postBuild() return TRUE; } +void LLFloaterMyFriends::onOpen() +{ + gSavedSettings.setBOOL("ShowContacts", true); +} void LLFloaterMyFriends::onClose(bool app_quitting) { + if (!app_quitting) gSavedSettings.setBOOL("ShowContacts", false); setVisible(FALSE); } @@ -122,6 +127,7 @@ LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed) : removeFloater(floater_contacts); // reparent to floater view gFloaterView->addChild(floater_contacts); + if (gSavedSettings.getBOOL("ShowContacts")) floater_contacts->open(); } else { @@ -136,11 +142,13 @@ LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed) : removeFloater(floater_chat); // reparent to floater view gFloaterView->addChild(floater_chat); + if (gSavedSettings.getBOOL("ShowChatHistory")) floater_chat->open(); } else { addFloater(floater_chat, FALSE); } + if (gSavedSettings.getBOOL("ShowCommunicate")) open(); // After all floaters have been added, so we may not be hidden anyhow. gSavedSettings.getControl("ShowLocalChatFloaterBar")->getSignal()->connect(boost::bind(handleLocalChatBar, floater_chat, _2)); mTabContainer->lockTabs(); } @@ -228,7 +236,7 @@ void LLFloaterChatterBox::onOpen() void LLFloaterChatterBox::onClose(bool app_quitting) { setVisible(FALSE); - gSavedSettings.setBOOL("ShowCommunicate", FALSE); + if (!app_quitting) gSavedSettings.setBOOL("ShowCommunicate", false); } void LLFloaterChatterBox::setMinimized(BOOL minimized) diff --git a/indra/newview/llfloaterchatterbox.h b/indra/newview/llfloaterchatterbox.h index d3b45576a..70f6314fe 100644 --- a/indra/newview/llfloaterchatterbox.h +++ b/indra/newview/llfloaterchatterbox.h @@ -126,7 +126,8 @@ public: virtual BOOL postBuild(); - void onClose(bool app_quitting); + virtual void onOpen(); + virtual void onClose(bool app_quitting); static void* createFriendsPanel(void* data); static void* createGroupsPanel(void* data); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 4c063e953..8dfa195f4 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2161,7 +2161,7 @@ void LLPanelLandOptions::refreshSearch() bool can_change = LLViewerParcelMgr::isParcelModifiableByAgent( - parcel, GP_LAND_CHANGE_IDENTITY) + parcel, GP_LAND_FIND_PLACES) && region && !(region->getRegionFlag(REGION_FLAGS_BLOCK_PARCEL_SEARCH)); diff --git a/indra/newview/llfloatermessagelog.h b/indra/newview/llfloatermessagelog.h index 1fa01c5af..a17026233 100644 --- a/indra/newview/llfloatermessagelog.h +++ b/indra/newview/llfloatermessagelog.h @@ -1,3 +1,6 @@ +#ifndef LL_LLFLOATERMESSAGELOG_H +#define LL_LLFLOATERMESSAGELOG_H + // #include "llfloater.h" #include "llmessagelog.h" @@ -94,3 +97,5 @@ public: static void onClickFilterMenu(void* user_data); }; // + +#endif \ No newline at end of file diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 4c2e68a6c..159a25a21 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -241,6 +241,22 @@ bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a bool validate_face(const LLVolumeFace& face) { + + for (S32 v = 0; v < face.mNumVertices; v++) + { + if(face.mPositions && !face.mPositions[v].isFinite3()) + { + llwarns << "NaN position data in face found!" << llendl; + return false; + } + + if(face.mNormals && !face.mNormals[v].isFinite3()) + { + llwarns << "NaN normal data in face found!" << llendl; + return false; + } + } + for (S32 i = 0; i < face.mNumIndices; ++i) { if (face.mIndices[i] >= face.mNumVertices) @@ -3807,15 +3823,30 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim U32 triangle_count = 0; - for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) + U32 instanced_triangle_count = 0; + + //get the triangle count for the whole scene + for (LLModelLoader::scene::iterator iter = mBaseScene.begin(), endIter = mBaseScene.end(); iter != endIter; ++iter) { - LLModel* mdl = *iter; - for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance) { - triangle_count += mdl->getVolumeFace(i).mNumIndices/3; + LLModel* mdl = instance->mModel; + if (mdl) + { + instanced_triangle_count += mdl->getNumTriangles(); + } } } + //get the triangle count for the non-instanced set of models + for (U32 i = 0; i < mBaseModel.size(); ++i) + { + triangle_count += mBaseModel[i]->getNumTriangles(); + } + + //get ratio of uninstanced triangles to instanced triangles + F32 triangle_ratio = (F32) triangle_count / (F32) instanced_triangle_count; + U32 base_triangle_count = triangle_count; U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; @@ -3849,6 +3880,8 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim if (which_lod > -1 && which_lod < NUM_LOD) { limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[which_lod]).asInteger(); + //convert from "scene wide" to "non-instanced" triangle limit + limit = (S32) ( (F32) limit*triangle_ratio ); } } else @@ -3953,7 +3986,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim U32 actual_verts = 0; U32 submeshes = 0; - mRequestedTriangleCount[lod] = triangle_count; + mRequestedTriangleCount[lod] = (S32) ( (F32) triangle_count / triangle_ratio ); mRequestedErrorThreshold[lod] = lod_error_threshold; glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode); @@ -4135,28 +4168,36 @@ void LLModelPreview::updateStatusMessages() //initialize total for this lod to 0 total_tris[lod] = total_verts[lod] = total_submeshes[lod] = 0; - for (U32 i = 0; i < mModel[lod].size(); ++i) - { //for each model in the lod - S32 cur_tris = 0; - S32 cur_verts = 0; - S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces(); + for (LLModelLoader::scene::iterator iter = mScene[lod].begin(), endIter = mScene[lod].end(); iter != endIter; ++iter) + { + for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance) + { + LLModel* model = instance->mModel; + if (model) + { + //for each model in the lod + S32 cur_tris = 0; + S32 cur_verts = 0; + S32 cur_submeshes = model->getNumVolumeFaces(); - for (S32 j = 0; j < cur_submeshes; ++j) - { //for each submesh (face), add triangles and vertices to current total - const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j); - cur_tris += face.mNumIndices/3; - cur_verts += face.mNumVertices; + for (S32 j = 0; j < cur_submeshes; ++j) + { //for each submesh (face), add triangles and vertices to current total + const LLVolumeFace& face = model->getVolumeFace(j); + cur_tris += face.mNumIndices/3; + cur_verts += face.mNumVertices; + } + + //add this model to the lod total + total_tris[lod] += cur_tris; + total_verts[lod] += cur_verts; + total_submeshes[lod] += cur_submeshes; + + //store this model's counts to asset data + tris[lod].push_back(cur_tris); + verts[lod].push_back(cur_verts); + submeshes[lod].push_back(cur_submeshes); + } } - - //add this model to the lod total - total_tris[lod] += cur_tris; - total_verts[lod] += cur_verts; - total_submeshes[lod] += cur_submeshes; - - //store this model's counts to asset data - tris[lod].push_back(cur_tris); - verts[lod].push_back(cur_verts); - submeshes[lod].push_back(cur_submeshes); } } @@ -4334,34 +4375,38 @@ void LLModelPreview::updateStatusMessages() } //add up physics triangles etc - S32 start = 0; - S32 end = mModel[LLModel::LOD_PHYSICS].size(); - S32 phys_tris = 0; S32 phys_hulls = 0; S32 phys_points = 0; - for (S32 i = start; i < end; ++i) - { //add up hulls and points and triangles for selected mesh(es) - LLModel* model = mModel[LLModel::LOD_PHYSICS][i]; - S32 cur_submeshes = model->getNumVolumeFaces(); - - LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; - - if (!decomp.empty()) + //get the triangle count for the whole scene + for (LLModelLoader::scene::iterator iter = mScene[LLModel::LOD_PHYSICS].begin(), endIter = mScene[LLModel::LOD_PHYSICS].end(); iter != endIter; ++iter) + { + for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance) { - phys_hulls += decomp.size(); - for (U32 i = 0; i < decomp.size(); ++i) + LLModel* model = instance->mModel; + if (model) { - phys_points += decomp[i].size(); - } - } - else - { //choose physics shape OR decomposition, can't use both - for (S32 j = 0; j < cur_submeshes; ++j) - { //for each submesh (face), add triangles and vertices to current total - const LLVolumeFace& face = model->getVolumeFace(j); - phys_tris += face.mNumIndices/3; + S32 cur_submeshes = model->getNumVolumeFaces(); + + LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; + + if (!decomp.empty()) + { + phys_hulls += decomp.size(); + for (U32 i = 0; i < decomp.size(); ++i) + { + phys_points += decomp[i].size(); + } + } + else + { //choose physics shape OR decomposition, can't use both + for (S32 j = 0; j < cur_submeshes; ++j) + { //for each submesh (face), add triangles and vertices to current total + const LLVolumeFace& face = model->getVolumeFace(j); + phys_tris += face.mNumIndices/3; + } + } } } } @@ -4523,7 +4568,7 @@ void LLModelPreview::updateLodControls(S32 lod) if (!lod_combo) return; S32 lod_mode = lod_combo->getCurrentIndex(); - if (lod_mode == 0) // LoD from file + if (lod_mode == LOD_FROM_FILE) // LoD from file { fmp->mLODMode[lod] = 0; for (U32 i = 0; i < num_file_controls; ++i) @@ -4536,7 +4581,7 @@ void LLModelPreview::updateLodControls(S32 lod) mFMP->childHide(lod_controls[i] + lod_name[lod]); } } - else if (lod_mode == 2) // use LoD above + else if (lod_mode == USE_LOD_ABOVE) // use LoD above { fmp->mLODMode[lod] = 2; for (U32 i = 0; i < num_file_controls; ++i) diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 6ca55bb81..8ac80d41a 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -298,6 +298,15 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex typedef boost::signals2::signal model_loaded_signal_t; typedef boost::signals2::signal model_updated_signal_t; +public: + + typedef enum + { + LOD_FROM_FILE = 0, + GENERATE, + USE_LOD_ABOVE, + } eLoDMode; + public: LLModelPreview(S32 width, S32 height, LLFloater* fmp); virtual ~LLModelPreview(); diff --git a/indra/newview/llfloaterpermissionsmgr.cpp b/indra/newview/llfloaterpermissionsmgr.cpp deleted file mode 100644 index 750cd8bfd..000000000 --- a/indra/newview/llfloaterpermissionsmgr.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file llfloaterpermissionsmgr.cpp - * @brief for user control of script permissions - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloaterpermissionsmgr.h" - -#include "llscrollcontainer.h" -#include "lltextbox.h" -#include "llbutton.h" -#include "llagent.h" -#include "llviewerobjectlist.h" -#include "llviewerregion.h" -#include "llstl.h" - -// constants -const S32 MIN_PERM_MGR_WIDTH = 100; -const S32 MIN_PERM_MGR_HEIGHT = 100; -const S32 VPAD = 8; -const S32 HPAD = 8; -const S32 LINE = 16; - -// statics -LLFloaterPermissionsMgr* LLFloaterPermissionsMgr::sInstance = NULL; - -LLFloaterPermissionsMgr* LLFloaterPermissionsMgr::show() -{ - if (!sInstance) - { - sInstance = new LLFloaterPermissionsMgr(); - - sInstance->open(); /* Flawfinder: ignore */ - gFloaterView->adjustToFitScreen(sInstance, TRUE); - } - else - { - sInstance->open(); /* Flawfinder: ignore */ - } - - return sInstance; -} - -void LLFloaterPermissionsMgr::processPermissionsList(LLMessageSystem* msg, void**) -{ -} - -LLFloaterPermissionsMgr::LLFloaterPermissionsMgr() : - LLFloater(std::string("floater_perm_mgr"), std::string("PermissionsManagerRect"), std::string("Permissions Manager"), - TRUE, MIN_PERM_MGR_WIDTH, MIN_PERM_MGR_HEIGHT) -{ - S32 y = getRect().getHeight() - VPAD - LINE; - LLRect scrollable_container_rect(0, y, getRect().getWidth(), 0); - LLRect permissions_rect(0, 0, getRect().getWidth() - HPAD - HPAD, 0); - mPermissions = new LLPermissionsView(permissions_rect); - mScroller = new LLScrollContainer( - std::string("permissions container"), - scrollable_container_rect, - mPermissions - ); - mScroller->setFollowsAll(); - mScroller->setReserveScrollCorner(TRUE); - addChild(mScroller); -} - -LLFloaterPermissionsMgr::~LLFloaterPermissionsMgr() -{ -} - - -// -// LLPermissionsView -// - -LLPermissionsView::LLPermissionsView(const LLRect &rect) : LLView(std::string("permissions_view"), rect, TRUE, FOLLOWS_NONE) -{ -} - -void LLPermissionsView::clearPermissionsData() -{ - deleteAllChildren(); -} - -void LLPermissionsView::addPermissionsData(const std::string& object_name, const LLUUID& object_id, U32 permissions_flags) -{ - // grow to make room for new element - reshape(getRect().getWidth(), getRect().getHeight() + LINE + VPAD + BTN_HEIGHT + VPAD); - S32 y = getRect().getHeight() - LINE - VPAD; - LLRect label_rect(HPAD, y + LINE, getRect().getWidth(), y); - LLTextBox* text = new LLTextBox(std::string("perm_label"), label_rect, object_name); - text->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM); - addChild(text); - - y -= LINE + VPAD; - - LLRect btn_rect(HPAD, y + BTN_HEIGHT, 120, y); - LLButton* button = new LLButton(std::string("Revoke permissions"), btn_rect, LLStringUtil::null, boost::bind(&LLPermissionsView::revokePermissions, object_id, permissions_flags)); - button->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM); - addChild(button); - - /*btn_rect.set(HPAD + 120 + HPAD, y + BTN_HEIGHT, HPAD + 120 + HPAD + 120, y); - button = new LLButton(std::string("Find in world"), btn_rect, LLStringUtil::null, boost::bind(&LLPermissionsView::findObject, object_id, permissions_flags)); - button->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM); - addChild(button);*/ -} - -void LLPermissionsView::revokePermissions(const LLUUID& object_id, U32 permission_flags) -{ - LLViewerObject* objectp = gObjectList.findObject(object_id); - if (objectp) - { - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_RevokePermissions); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_Data); - msg->addUUIDFast(_PREHASH_ObjectID, object_id); - msg->addU32Fast(_PREHASH_ObjectPermissions, permission_flags); - msg->sendReliable(objectp->getRegion()->getHost()); - } -} - -/*void LLPermissionsView::findObject(const LLUUID& object_id, U32 permission_flags) -{ -}*/ diff --git a/indra/newview/llfloaterpermissionsmgr.h b/indra/newview/llfloaterpermissionsmgr.h deleted file mode 100644 index ac933e3f1..000000000 --- a/indra/newview/llfloaterpermissionsmgr.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file llfloaterpermissionsmgr.h - * @brief for user control of script permissions - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLFLOATERPERMISSIONSMGR_H -#define LL_LLFLOATERPERMISSIONSMGR_H - -#include "llfloater.h" -#include - -class LLScrollContainer; -class LLPermissionsView; - -class LLFloaterPermissionsMgr -: public LLFloater -{ -public: - static LLFloaterPermissionsMgr* show(); - - // Message system callbacks - static void processPermissionsList(LLMessageSystem* msg, void**); - - virtual void onClose(bool app_quitting) { setVisible(FALSE); } - -private: - // Must construct by calling show(). - LLFloaterPermissionsMgr(); - virtual ~LLFloaterPermissionsMgr(); - -public: - LLPermissionsView* mPermissions; - -protected: - LLScrollContainer* mScroller; - - static LLFloaterPermissionsMgr* sInstance; -}; - -class LLPermissionsView : public LLView -{ -public: - LLPermissionsView(const LLRect& rect); - virtual ~LLPermissionsView() {}; - -public: - void clearPermissionsData(); - void addPermissionsData(const std::string& object_name, const LLUUID& object_id, U32 permissions_flags); - - static void revokePermissions(const LLUUID& object_id, U32 permission_flags); - //static void findObject(const LLUUID& object_id, U32 permission_flags); -}; - - -#endif diff --git a/indra/newview/llfloaterregionrestarting.cpp b/indra/newview/llfloaterregionrestarting.cpp new file mode 100644 index 000000000..35af32390 --- /dev/null +++ b/indra/newview/llfloaterregionrestarting.cpp @@ -0,0 +1,196 @@ +/** + * @file llfloaterregionrestarting.cpp + * @brief Shows countdown timer during region restart + * + * $LicenseInfo:firstyear=2006&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 "llfloaterregionrestarting.h" + +#include "lluictrlfactory.h" +#include "llagent.h" +#include "llagentcamera.h" +#include "llenvmanager.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" + +// For emergency teleports +#include "llinventorymodel.h" +void emergency_teleport() +{ + static const LLCachedControl landmark(gSavedPerAccountSettings, "EmergencyTeleportLandmark"); + if (landmark().empty()) return; + const LLUUID id(landmark); + if (id.isNull()) return; + if (LLViewerInventoryItem* item = gInventory.getItem(id)) + gAgent.teleportViaLandmark(item->getAssetUUID()); +} +// + +enum shake_state +{ + SHAKE_START, + SHAKE_LEFT, + SHAKE_UP, + SHAKE_RIGHT, + SHAKE_DOWN, + SHAKE_DONE +}; +static shake_state sShakeState; + +LLFloaterRegionRestarting::LLFloaterRegionRestarting(const LLSD& key) : + LLEventTimer(1) +, mRestartSeconds(NULL) +, mSeconds(key["SECONDS"].asInteger()) +, mShakeIterations() +, mShakeMagnitude() +{ + //buildFromFile("floater_region_restarting.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_restarting.xml"); + + LLStringUtil::format_map_t args; + args["[NAME]"] = key["NAME"].asString(); + getChild("region_name")->setValue(getString("RegionName", args)); + mRestartSeconds = getChild("restart_seconds"); + center(); + + refresh(); + + mRegionChangedConnection = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterRegionRestarting::close, this, false)); + if (mSeconds <= 20) emergency_teleport(); // For emergency teleports +} + +LLFloaterRegionRestarting::~LLFloaterRegionRestarting() +{ + mRegionChangedConnection.disconnect(); +} + +BOOL LLFloaterRegionRestarting::postBuild() +{ + setBackgroundColor(gColors.getColor("NotifyCautionBoxColor")); + sShakeState = SHAKE_START; + return TRUE; +} + +BOOL LLFloaterRegionRestarting::tick() +{ + refresh(); + + return FALSE; +} + +void LLFloaterRegionRestarting::refresh() +{ + LLStringUtil::format_map_t args; + args["[SECONDS]"] = llformat("%d", mSeconds); + mRestartSeconds->setValue(getString("RestartSeconds", args)); + + if (mSeconds == 20) emergency_teleport(); // For emergency teleports + if (!mSeconds) return; // Zero means we're done. + --mSeconds; +} + +void LLFloaterRegionRestarting::draw() +{ + LLFloater::draw(); + + static const LLCachedControl alchemyRegionShake(gSavedSettings, "AlchemyRegionRestartShake", true); + if (!alchemyRegionShake || isMinimized()) // If we're minimized, leave the user alone + return; + + const F32 SHAKE_INTERVAL = 0.025; + const F32 SHAKE_TOTAL_DURATION = 1.8; // the length of the default alert tone for this + const F32 SHAKE_INITIAL_MAGNITUDE = 1.5; + const F32 SHAKE_HORIZONTAL_BIAS = 0.25; + F32 time_shaking; + + if (SHAKE_START == sShakeState) + { + mShakeTimer.setTimerExpirySec(SHAKE_INTERVAL); + sShakeState = SHAKE_LEFT; + mShakeIterations = 0; + mShakeMagnitude = SHAKE_INITIAL_MAGNITUDE; + } + + if (SHAKE_DONE != sShakeState && mShakeTimer.hasExpired()) + { + gAgentCamera.unlockView(); + + switch(sShakeState) + { + case SHAKE_LEFT: + gAgentCamera.setPanLeftKey(mShakeMagnitude * SHAKE_HORIZONTAL_BIAS); + sShakeState = SHAKE_UP; + break; + + case SHAKE_UP: + gAgentCamera.setPanUpKey(mShakeMagnitude); + sShakeState = SHAKE_RIGHT; + break; + + case SHAKE_RIGHT: + gAgentCamera.setPanRightKey(mShakeMagnitude * SHAKE_HORIZONTAL_BIAS); + sShakeState = SHAKE_DOWN; + break; + + case SHAKE_DOWN: + gAgentCamera.setPanDownKey(mShakeMagnitude); + mShakeIterations++; + time_shaking = SHAKE_INTERVAL * (mShakeIterations * 4 /* left, up, right, down */); + if (SHAKE_TOTAL_DURATION <= time_shaking) + { + sShakeState = SHAKE_DONE; + mShakeMagnitude = 0.0; + } + else + { + sShakeState = SHAKE_LEFT; + F32 percent_done_shaking = (SHAKE_TOTAL_DURATION - time_shaking) / SHAKE_TOTAL_DURATION; + mShakeMagnitude = SHAKE_INITIAL_MAGNITUDE * (percent_done_shaking * percent_done_shaking); // exponential decay + } + break; + + default: + break; + } + mShakeTimer.setTimerExpirySec(SHAKE_INTERVAL); + } +} + +void LLFloaterRegionRestarting::onClose(bool app_quitting) +{ + if (sShakeState != SHAKE_DONE && sShakeState != SHAKE_START) // Finish shake if needed + { + gAgentCamera.resetView(TRUE, TRUE); + sShakeState = SHAKE_DONE; + } + LLFloater::onClose(app_quitting); +} + +void LLFloaterRegionRestarting::updateTime(const U32& time) +{ + mSeconds = time; + if (mSeconds <= 20) emergency_teleport(); // For emergency teleports + sShakeState = SHAKE_START; +} diff --git a/indra/newview/llfloaterregionrestarting.h b/indra/newview/llfloaterregionrestarting.h new file mode 100644 index 000000000..ee7cb1d30 --- /dev/null +++ b/indra/newview/llfloaterregionrestarting.h @@ -0,0 +1,59 @@ +/** + * @file llfloaterregionrestarting.h + * @brief Shows countdown timer during region restart + * + * $LicenseInfo:firstyear=2006&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_LLFLOATERREGIONRESTARTING_H +#define LL_LLFLOATERREGIONRESTARTING_H + +#include "llfloater.h" +#include "lleventtimer.h" + +class LLFloaterRegionRestarting : public LLFloater, public LLEventTimer +, public LLFloaterSingleton +{ + friend class LLFloaterReg; + +public: + void updateTime(const U32& time); + + LLFloaterRegionRestarting(const LLSD& key); +private: + virtual ~LLFloaterRegionRestarting(); + virtual BOOL postBuild(); + virtual BOOL tick(); + virtual void refresh(); + virtual void draw(); + virtual void onClose(bool app_quitting); + + class LLTextBox* mRestartSeconds; + U32 mSeconds; + U32 mShakeIterations; + F32 mShakeMagnitude; + LLTimer mShakeTimer; + + boost::signals2::connection mRegionChangedConnection; +}; + +#endif // LL_LLFLOATERREGIONRESTARTING_H diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index d4830adbf..09463f049 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -109,7 +109,7 @@ F32 FALL_TIME = 0.6f; S32 BORDER_WIDTH = 6; const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte -const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512 +const S32 MAX_TEXTURE_SIZE = 1024; //max upload texture size 1024 * 1024 static std::string snapshotKeepAspectName(); @@ -1185,7 +1185,7 @@ LLSnapshotLivePreview::EAspectSizeProblem LLSnapshotLivePreview::generateFormatt if (mSnapshotType == SNAPSHOT_TEXTURE) { // 'scaled' must be a power of two. - scaled->biasedScaleToPowerOfTwo(mWidth, mHeight, 512); + scaled->biasedScaleToPowerOfTwo(mWidth, mHeight, 1024); } else { @@ -2488,8 +2488,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, bool LLSpinCtrl* width_spinner = view->getChild("snapshot_width"); LLSpinCtrl* height_spinner = view->getChild("snapshot_height"); - if (gSavedSettings.getS32("LastSnapshotType") == LLSnapshotLivePreview::SNAPSHOT_TEXTURE || - gSavedSettings.getBOOL("RenderUIInSnapshot") || + if ( gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot")) { // Disable without making label gray. diff --git a/indra/newview/llfloaterteleport.cpp b/indra/newview/llfloaterteleport.cpp deleted file mode 100644 index dd546c5b0..000000000 --- a/indra/newview/llfloaterteleport.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/** - * @file llfloaterteleport.cpp - * @brief floater code for agentd teleports. - * - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ -//Teleport floater used for agent domain TP. URI text floater. -//Copyright International Business Machines Corporation 2008-9 -//Contributed to Linden Research, Inc. under the Second Life Viewer Contribution -//Agreement and licensed as above. -#include "llviewerprecompiledheaders.h" // must be first include - -#include "llfloaterteleport.h" - -#include "llagent.h" //for hack in teleport start -#include "llchat.h" -#include "llcombobox.h" -#include "llfloaterchat.h" -#include "llsdserialize.h" -#include "llsdutil.h" -#include "llsdutil_math.h" -#include "lluictrlfactory.h" // builds floaters from XML -#include "llurlhistory.h" -#include "lluserauth.h" // for saving placeavatarresponder result -#include "llviewercontrol.h" // for gSavedSettings -#include "llviewerdisplay.h" // for gTeleportDisplay -#include "llviewermessage.h" // for send_agent_movement_complete attempt -#include "llviewerregion.h" -#include "llviewerwindow.h" // for hack in teleport start -#include "llvoavatar.h" -#include "llworld.h" -#include "pipeline.h" // for gPipeline - -class AIHTTPTimeoutPolicy; -extern AIHTTPTimeoutPolicy placeAvatarTeleportResponder_timeout; - -// OGPX HTTP responder for PlaceAvatar cap used for Teleport -// very similar to the responder in Login, but not as many fields are returned in the TP version -// OGPX TODO: should this be combined with the Login responder for rez_avatar/place? -// OGPX TODO: mResult should not get replaced in result(), instead -// should replace individual LLSD fields in mResult. -class LLPlaceAvatarTeleportResponder : public LLHTTPClient::ResponderWithResult -{ -public: - LLPlaceAvatarTeleportResponder() - { - } - - ~LLPlaceAvatarTeleportResponder() - { - } - - /*virtual*/ void error(U32 statusNum, const std::string& reason) - { - LL_INFOS("OGPX") << "LLPlaceAvatarTeleportResponder error in TP " - << statusNum << " " << reason << LL_ENDL; - - LLSD args; - args["REASON"] = reason; - - - LLNotificationsUtil::add("CouldNotTeleportReason", args); - - gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); - - } - - /*virtual*/ void result(const LLSD& content) - { - - LLSD result; - result["agent_id"] = content["agent_id"]; // need this for send_complete_agent_movement - result["region_x"] = content["region_x"]; // need these for making the first region - result["region_y"] = content["region_y"]; - result["login"] = "true"; // this gets checked in idle_startup() - result["session_id"] = content["session_id"]; - result["secure_session_id"] = content["secure_session_id"]; - result["circuit_code"] = content["circuit_code"]; - result["sim_port"] = content["sim_port"]; - result["sim_host"] = content["sim_host"]; - result["look_at"] = content["look_at"]; - // maintaining result seed_capability name for compatibility with legacy login - result["seed_capability"] = content["region_seed_capability"]; - result["position"] = content["position"]; // save this for agentmovementcomplete type processing - - // Even though we have the pretty print of the complete content returned, we still find it handy - // when scanning SecondLife.log to have these laid out in this way. So they are still here. - LL_DEBUGS("OGPX") << " Teleport placeAvatar responder " << LL_ENDL; - LL_DEBUGS("OGPX") << "agent_id: " << content["agent_id"] << LL_ENDL; - LL_DEBUGS("OGPX") << "region_x: " << content["region_x"] << LL_ENDL; - LL_DEBUGS("OGPX") << "session_id: " << content["session_id"] << LL_ENDL; - LL_DEBUGS("OGPX") << "sim_port: " << content["sim_port"] << LL_ENDL; - LL_DEBUGS("OGPX") << "sim_host: " << content["sim_host"] << LL_ENDL; - LL_DEBUGS("OGPX") << "look_at: " << content["look_at"] << LL_ENDL; - LL_DEBUGS("OGPX") << "position: " << content["position"] << LL_ENDL; - LL_DEBUGS("OGPX") << "seed_capability: " << content["region_seed_capability"] << LL_ENDL; - - LL_INFOS("OGPX") << " All the LLSD PlaceAvatarTeleportResponder content: \n " << ll_pretty_print_sd(content) << LL_ENDL; // OGPX - - - // check "connect" to make sure place_avatar fully successful - if (!content["connect"].asBoolean()) - { - // place_avatar failed somewhere - LL_INFOS("OGPX") << "TP failed, connect false in TP PlaceAvatarResponder " << LL_ENDL; - - LLSD args; - args["REASON"] = "Place Avatar Failed"; - - //gViewerWindow->alertXml("CouldNotTeleportReason", args); - LLNotificationsUtil::add("CouldNotTeleportReason",args); - - gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); - - return; - } - - - U64 region_handle; - region_handle = to_region_handle_global(content["region_x"].asInteger(), content["region_y"].asInteger()); - - LLHost sim_host; - U32 sim_port = strtoul(result["sim_port"].asString().c_str(), NULL, 10); - sim_host.setHostByName(result["sim_host"].asString().c_str()); - sim_host.setPort(sim_port); - - if (sim_host.isOk()) - { - LLMessageSystem* msg = gMessageSystem; - gMessageSystem->enableCircuit(sim_host, TRUE); - msg->newMessageFast(_PREHASH_UseCircuitCode); - msg->nextBlockFast(_PREHASH_CircuitCode); - msg->addU32Fast(_PREHASH_Code, msg->getOurCircuitCode()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_ID, gAgent.getID()); - msg->sendReliable(sim_host); - } - else - { - LL_INFOS("OGPX") << "TP failed, could not resolve hostname for UDP messages." << LL_ENDL; - LLSD args; - args["REASON"] = "Failed to resolve host."; - //gViewerWindow->alertXml("CouldNotTeleportReason", args); - LLNotificationsUtil::add("CouldNotTeleportReason", args); - gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); - return; - } - - - - - // Viewer trusts the simulator. - LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host); - regionp->setSeedCapability(content["seed_capability"].asString().c_str()); - // process_agent_movement_complete needs the region to still be the old region gAgent.setRegion(regionp); - - // placing these in result so they can be set properly in LLUserAuth result - // ...they are only passed in on login, and not on TP - result["session_id"] = gAgent.getSessionID(); - result["agent_id"] = gAgent.getID(); - result["circuit_code"].asString() = gMessageSystem->mOurCircuitCode; // this is what startup sets, is this proper to do? - - // grab the skeleton and root. - result["inventory-skeleton"] = LLUserAuth::getInstance()->mResult["inventory-skeleton"]; - result["inventory-root"] = LLUserAuth::getInstance()->mResult["inventory-root"]; - - LL_DEBUGS("OGPX") << "session_id: " << result["session_id"] << LL_ENDL; - - - - // results need to be stored so process_agent_movement_complete() can pull them - LLUserAuth::getInstance()->mAuthResponse = LLUserAuth::E_OK; - - // OGPX TODO: This just reeks of causing problems, because we are using - // ... mResult to store things that we get from other caps....So slamming a - // ... completely new result in on teleport is going to cause issues. - // ... It makes changing the things we save in mResult error prone. - // ... Question is, how should we really be storing the seemingly random things - // ... that we get back from (now) various different caps that used to all come back - // ... in the result of XMLRPC authenticate? - LLUserAuth::getInstance()->mResult = result; - - - - // ... new sim not sending me much without sending it CompleteAgentMovement msg. - //gAgent.setTeleportState( LLAgent::TELEPORT_MOVING ); // process_agent_mv_complete looks for TELEPORT_MOVING - LLVector3 position = ll_vector3_from_sd(result["position"]); - gAgent.setHomePosRegion(region_handle, position); // taken from teleport_finish (not sure regular code path gets this) - - send_complete_agent_movement(sim_host); - - // Turn off progress msg (also need to do this in all the possible failure places) - // I think we leave this, as the scene is still changing during the - // processing of agentmovementcomeplete message. TELEPORT_NONE resets it anyway - // gViewerWindow->setShowProgress(FALSE); - - } - - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return placeAvatarTeleportResponder_timeout; } - /*virtual*/ char const* getName(void) const { return "LLPlaceAvatarTeleportResponder"; } -}; - -// Statics -LLFloaterTeleport* LLFloaterTeleport::sInstance = NULL; - -LLFloaterTeleport::LLFloaterTeleport() -: LLFloater("floater_teleport") -{ - if(!sInstance) - { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_teleport.xml"); - - LLComboBox* regioncombo = getChild("teleport_edit"); - regioncombo->setAllowTextEntry(TRUE, 256, FALSE); // URL bar needs to allow user text input - - // iterate on uri list adding to combobox (couldn't figure out how to add them all in one call) - LLSD regionuri_history = LLURLHistory::getURLHistory("regionuri"); - LLSD::array_iterator iter_history = regionuri_history.beginArray(); - LLSD::array_iterator iter_end = regionuri_history.endArray(); - for(; iter_history != iter_end; ++iter_history) - { - regioncombo->addSimpleElement((*iter_history).asString()); - } - - // select which is displayed if we have a current URL. - regioncombo->setSelectedByValue(LLSD(gSavedSettings.getString("CmdLineRegionURI")),TRUE); - - // TODO : decide if 'enter' when selecting something from the combox box should *not* be sent - // to the floater (p.s. and figure out how to change it) - - childSetAction("teleport_btn", onClickTeleport, this); - childSetAction("cancel_btn", onClickCancel, this); - - setDefaultBtn("teleport_btn"); - } - else - { - sInstance->show(NULL); - } -} - -// static -void LLFloaterTeleport::show(void*) -{ - if (!sInstance) - { - sInstance = new LLFloaterTeleport(); - } - - sInstance->open(); -} - -LLFloaterTeleport::~LLFloaterTeleport() -{ - sInstance=NULL; -} - - - -// static -void LLFloaterTeleport::onClickTeleport(void* userdata) -{ - std::string placeAvatarCap = LLAppViewer::instance()->getPlaceAvatarCap(); - LLSD args; - - LLFloaterTeleport* self = (LLFloaterTeleport*)userdata; - std::string text = self->childGetText("teleport_edit"); - if (text.find("://",0) == std::string::npos) - { - // if there is no uri, prepend it with http:// - text = "http://"+text; - LL_DEBUGS("OGPX") << "Teleport URI was prepended, now " << text << LL_ENDL; - } - - LL_DEBUGS("OGPX") << "onClickTeleport! from using place_avatar cap "<< placeAvatarCap << " contains "<< text << LL_ENDL; - LLStringUtil::trim(text); // trim extra spacing - gAgent.setTeleportSourceURL(gSavedSettings.getString("CmdLineRegionURI")); // grab src region name - gSavedSettings.setString("CmdLineRegionURI",text); // save the dst region - args["public_region_seed_capability"] = text; - args["position"] = ll_sd_from_vector3(LLVector3(128, 128, 50)); // default to middle of region above base terrain - LL_INFOS("OGPX") << " args to placeavatar cap " << placeAvatarCap << " on teleport: " << LLSDOStreamer(args) << LL_ENDL; - LLHTTPClient::post(placeAvatarCap, args, new LLPlaceAvatarTeleportResponder()); - gAgent.setTeleportMessage( - LLAgent::sTeleportProgressMessages["requesting"]); - gViewerWindow->setShowProgress(TRUE); - gAgent.teleportCore(); - gAgent.setTeleportState( LLAgent::TELEPORT_PLACE_AVATAR ); // teleportcore() sets tp state to legacy path, so reset. ick! - gTeleportDisplayTimer.reset(); - - - - self->setVisible(FALSE); - if ( LLURLHistory::appendToURLCollection("regionuri",text)) - { - // since URL history only populated on create of sInstance, add to combo list directly - LLComboBox* regioncombo = self->getChild("teleport_edit"); - // BUG : this should add the new item to the combo box, but doesn't - regioncombo->addSimpleElement(text); - } - -} - -void LLFloaterTeleport::onClickCancel(void *userdata) -{ - LLFloaterTeleport* self = (LLFloaterTeleport*)userdata; - LL_INFOS("OGPX") << "Teleport Cancel " << self->getName() << LL_ENDL; - self->setVisible(FALSE); -} diff --git a/indra/newview/llfloaterteleport.h b/indra/newview/llfloaterteleport.h deleted file mode 100644 index 58e907a68..000000000 --- a/indra/newview/llfloaterteleport.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file llfloaterteleport.h - * @brief floater header for agentd teleports. - * - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ -// Teleport floater for agent domain TPs using URIs. -//Copyright International Business Machines Corporation 2008-9 -//Contributed to Linden Research, Inc. under the Second Life Viewer Contribution -//Agreement and licensed as above. -#ifndef LL_FLOATER_TELEPORT_H -#define LL_FLOATER_TELEPORT_H -#include "llfloater.h" - -class LLFloaterTeleport : public LLFloater -{ -public: - LLFloaterTeleport(); - - virtual ~LLFloaterTeleport(); - - // by convention, this shows the floater and does instance management - static void show(void*); - -private: - // when a line editor loses keyboard focus, it is committed. - // commit callbacks are named onCommitWidgetName by convention. - static void onCommitTeleport(LLUICtrl* ctrl, void *userdata); - - // by convention, button callbacks are named onClickButtonLabel - static void onClickTeleport(void* userdata); - static void onClickCancel(void *userdata); - - // no pointers to widgets here - they are referenced by name - - // assuming we just need one, which is typical - static LLFloaterTeleport* sInstance; - -}; -#endif - diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index cc42294fd..bc75b0f7d 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -47,6 +47,7 @@ #include "llviewerregion.h" #include "llviewerwindow.h" #include "llfloaterdirectory.h" +#include "llfloatergroupinfo.h" #include "llgroupactions.h" #include "llnotificationsutil.h" #include "lluictrlfactory.h" @@ -1448,7 +1449,8 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data) gAgent.mGroups.push_back(gd); - LLGroupActions::closeGroup(LLUUID::null); + if (LLFloaterGroupInfo* flooter = LLFloaterGroupInfo::getInstance(LLUUID::null)) + flooter->onClose(false); LLGroupActions::showTab(group_id, "roles_tab"); } else diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index eef650101..9f6acb60b 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -611,8 +611,9 @@ void LLHUDEffectLookAt::update() { if (calcTargetPosition()) { - LLMotion* head_motion = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->findMotion(ANIM_AGENT_HEAD_ROT); - if (!head_motion || head_motion->isStopped()) + //LLMotion* head_motion = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->findMotion(ANIM_AGENT_HEAD_ROT); + //if (!head_motion || head_motion->isStopped()) + // singu: startMotion does basically the same as the above two lines... it starts it, unless it was already started. { ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->startMotion(ANIM_AGENT_HEAD_ROT); } diff --git a/indra/newview/llhudmanager.cpp b/indra/newview/llhudmanager.cpp index cb9a2c1d3..15872a0db 100644 --- a/indra/newview/llhudmanager.cpp +++ b/indra/newview/llhudmanager.cpp @@ -80,14 +80,33 @@ void LLHUDManager::updateEffects() void LLHUDManager::sendEffects() { + static LLCachedControl disable_lookat_effect(gSavedSettings, "PrivateLookAt", false); + static LLCachedControl disable_pointat_effect(gSavedSettings, "DisablePointAtAndBeam", false); + static LLCachedControl broadcast_viewer_effects(gSavedSettings, "BroadcastViewerEffects", true); - if(!gSavedSettings.getBOOL("BroadcastViewerEffects")) - return; - S32 i; for (i = 0; i < mHUDEffects.count(); i++) { LLHUDEffect *hep = mHUDEffects[i]; + if (hep->mType == LLHUDObject::LL_HUD_EFFECT_LOOKAT) + { + if (disable_lookat_effect) + { + continue; + } + } + else if (hep->mType == LLHUDObject::LL_HUD_EFFECT_POINTAT || + hep->mType == LLHUDObject::LL_HUD_EFFECT_BEAM) + { + if (disable_pointat_effect) + { + continue; + } + } + else if (!broadcast_viewer_effects) + { + continue; + } if (hep->isDead()) { llwarns << "Trying to send dead effect!" << llendl; diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index af2659486..7a4b11c86 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -35,6 +35,7 @@ #include "ascentkeyword.h" #include "llagent.h" +#include "llautoreplace.h" #include "llavataractions.h" #include "llavatarnamecache.h" #include "llbutton.h" @@ -60,7 +61,7 @@ #include "llviewerwindow.h" #include "llvoicechannel.h" -#include "boost/algorithm/string.hpp" +#include // [RLVa:KB] - Checked: 2013-05-10 (RLVa-1.4.9) #include "rlvactions.h" @@ -321,6 +322,7 @@ LLFloaterIMPanel::LLFloaterIMPanel( case IM_SESSION_GROUP_START: case IM_SESSION_INVITE: case IM_SESSION_CONFERENCE_START: + mCommitCallbackRegistrar.add("FlipDing", boost::bind(boost::lambda::_1 = !boost::lambda::_1, boost::ref(mDing))); // determine whether it is group or conference session if (gAgent.isInGroup(mSessionUUID)) { @@ -465,6 +467,7 @@ BOOL LLFloaterIMPanel::postBuild() LLAvatarNameCache::get(mOtherParticipantUUID, boost::bind(&LLFloaterIMPanel::onAvatarNameLookup, this, _2)); mInputEditor = getChild("chat_editor"); + mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5)); mInputEditor->setFocusReceivedCallback( boost::bind(&LLFloaterIMPanel::onInputEditorFocusReceived, this) ); mFocusLostSignal = mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMPanel::setTyping, this, false)); mInputEditor->setKeystrokeCallback( boost::bind(&LLFloaterIMPanel::onInputEditorKeystroke, this, _1) ); @@ -551,12 +554,7 @@ void LLFloaterIMPanel::onClickMuteVoice() // virtual void LLFloaterIMPanel::draw() { - LLViewerRegion* region = gAgent.getRegion(); - - bool enable_connect = (region && !region->getCapability("ChatSessionRequest").empty()) - && mSessionInitialized - && LLVoiceClient::getInstance()->voiceEnabled() - && mCallBackEnabled; + bool enable_connect = mSessionInitialized && LLVoiceClient::getInstance()->voiceEnabled() && mCallBackEnabled; // hide/show start call and end call buttons mEndCallBtn->setVisible(LLVoiceClient::getInstance()->voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED); @@ -968,7 +966,7 @@ void copy_profile_uri(const LLUUID& id, bool group = false); void LLFloaterIMPanel::onFlyoutCommit(LLComboBox* flyout, const LLSD& value) { - if (value.isUndefined()) + if (value.isUndefined() || value.asInteger() == 0) { LLAvatarActions::showProfile(mOtherParticipantUUID); return; @@ -999,10 +997,10 @@ void LLFloaterIMPanel::onFlyoutCommit(LLComboBox* flyout, const LLSD& value) void show_log_browser(const std::string& name, const std::string& id) { -#if LL_WINDOWS // Singu TODO: Other platforms? +#if LL_WINDOWS || LL_DARWIN // Singu TODO: Linux? if (gSavedSettings.getBOOL("LiruLegacyLogLaunch")) { - gViewerWindow->getWindow()->ShellEx("\"" + LLLogChat::makeLogFileName(name) + "\""); + gViewerWindow->getWindow()->ShellEx(LLLogChat::makeLogFileName(name)); return; } #endif diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 4d4e7ce8f..4b2466f89 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2112,25 +2112,6 @@ bool LLInventoryModel::loadSkeleton( return rv; } -//OGPX crap. Since this function is actually functionally the same as its LLSD variant.. -// just convert options_t to LLSD and route to the LLSD version. Yuck. -bool LLInventoryModel::loadSkeleton( - const LLInventoryModel::options_t& options, - const LLUUID& owner_id) -{ - LLSD options_list; - for(options_t::const_iterator it = options.begin(); it < options.end(); ++it) - { - LLSD entry; - for(response_t::const_iterator it2 = it->begin(); it2 != it->end(); ++it2) - { - entry[it2->first]=it2->second; - } - options_list.append(entry); - } - return loadSkeleton(options_list,owner_id); -} - // This is a brute force method to rebuild the entire parent-child // relations. The overall operation has O(NlogN) performance, which // should be sufficient for our needs. diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 09a85ba5d..259b08f87 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -409,14 +409,6 @@ public: void addCategory(LLViewerInventoryCategory* category); void addItem(LLViewerInventoryItem* item); - // methods to load up inventory skeleton & meat. These are used - // during authentication. return true if everything parsed. - typedef std::map response_t; - typedef std::vector options_t; - - - //OGPX really screwed with the login process. This is needed until it's all sorted out. - bool loadSkeleton(const options_t& options, const LLUUID& owner_id); /** Mutators ** ** *******************************************************************************/ diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index 32ebb9c40..8dbaa756d 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -37,6 +37,7 @@ #include "aihttpview.h" #include "floaterao.h" #include "floaterlocalassetbrowse.h" +#include "hbfloatergrouptitles.h" #include "jcfloaterareasearch.h" #include "llagentcamera.h" #include "llchatbar.h" @@ -45,6 +46,7 @@ #include "llfasttimerview.h" #include "llfloaterabout.h" #include "llfloateractivespeakers.h" +#include "llfloaterautoreplacesettings.h" #include "llfloateravatarlist.h" #include "llfloaterbeacons.h" #include "llfloaterblacklist.h" @@ -100,7 +102,6 @@ #include "llmakeoutfitdialog.h" #include "llmoveview.h" // LLFloaterMove #include "lltextureview.h" -#include "lltoolbar.h" #include "lltoolgrab.h" #include "lltoolmgr.h" #include "lluictrlfactory.h" @@ -165,22 +166,27 @@ struct MenuFloaterDict : public LLSingleton } registerConsole("velocity", gVelocityBar); registerFloater("about", boost::bind(&LLFloaterAbout::show,(void*)NULL)); - registerFloater("ao", boost::bind(LLFloaterAO::show, (void*)NULL)); registerFloater("always run", boost::bind(toggle_always_run), boost::bind(&LLAgent::getAlwaysRun, &gAgent)); + registerFloater("anims_explorer", boost::bind(LLFloaterExploreAnimations::show)); + registerFloater("ao", boost::bind(LLFloaterAO::show, (void*)NULL)); registerFloater("appearance", boost::bind(LLFloaterCustomize::show)); + registerFloater("asset_blacklist", boost::bind(LLFloaterBlacklist::toggle), boost::bind(LLFloaterBlacklist::visible)); registerFloater("build", boost::bind(toggle_build)); registerFloater("buy currency", boost::bind(LLFloaterBuyCurrency::buyCurrency)); registerFloater("buy land", boost::bind(&LLViewerParcelMgr::startBuyLand, boost::bind(LLViewerParcelMgr::getInstance), false)); registerFloater("chatbar", boost::bind(handle_chat)); registerFloater("complaint reporter", boost::bind(LLFloaterReporter::showFromMenu, COMPLAINT_REPORT)); + registerFloater("DayCycle", boost::bind(LLFloaterDayCycle::show), boost::bind(LLFloaterDayCycle::isOpen)); registerFloater("debug avatar", boost::bind(handle_debug_avatar_textures, (void*)NULL)); registerFloater("debug settings", boost::bind(handle_singleton_toggle, (void*)NULL)); registerFloater("displayname", boost::bind(LLFloaterDisplayName::show)); registerFloater("edit ui", boost::bind(LLFloaterEditUI::show, (void*)NULL)); + registerFloater("EnvSettings", boost::bind(LLFloaterEnvSettings::show), boost::bind(LLFloaterEnvSettings::isOpen)); registerFloater("fly", boost::bind(LLAgent::toggleFlying)); registerFloater("font test", boost::bind(LLFloaterFontTest::show, (void*)NULL)); registerFloater("god tools", boost::bind(LLFloaterGodTools::show, (void*)NULL)); - registerFloater("grid options", boost::bind(LLFloaterBuildOptions::show, (void*)NULL)); + registerFloater("grid options", boost::bind(LLFloaterBuildOptions::show, (void*)NULL)); + registerFloater("group titles", boost::bind(HBFloaterGroupTitles::toggle)); //Singu TODO: Re-implement f1 help. //registerFloater("help f1", boost::bind(/*gViewerHtmlHelp.show*/)); registerFloater("help tutorial", boost::bind(LLFloaterHUD::showHUD)); @@ -194,29 +200,25 @@ struct MenuFloaterDict : public LLSingleton registerFloater("mouselook", boost::bind(toggle_mouselook)); registerFloater("my land", boost::bind(LLFloaterLandHoldings::show, (void*)NULL)); registerFloater("outfit", boost::bind(show_outfit_dialog)); + registerFloater("PostProcess", boost::bind(LLFloaterPostProcess::show)); registerFloater("preferences", boost::bind(LLFloaterPreference::show, (void*)NULL)); + registerFloater("RegionDebugConsole", boost::bind(handle_singleton_toggle, (void*)NULL), boost::bind(LLFloaterRegionDebugConsole::instanceExists)); registerFloater("script errors", boost::bind(LLFloaterScriptDebug::show, LLUUID::null)); registerFloater("search", boost::bind(toggle_search_floater)); + registerFloater("sit", boost::bind(toggle_sit)); registerFloater("snapshot", boost::bind(LLFloaterSnapshot::show, (void*)NULL)); + registerFloater("sound_explorer", boost::bind(LLFloaterExploreSounds::toggle), boost::bind(LLFloaterExploreSounds::visible)); registerFloater("test", boost::bind(LLFloaterTest::show, (void*)NULL)); // Phoenix: Wolfspirit: Enabled Show Floater out of viewer menu - registerFloater("toolbar", boost::bind(toggle_control, "ShowToolBar"), boost::bind(&LLToolBar::getVisible, gToolBar)); - registerFloater("web", boost::bind(LLFloaterWebContent::showInstance, "dict web", LLFloaterWebContent::Params())); - registerFloater("world map", boost::bind(LLFloaterWorldMap::toggle)); - registerFloater("anims_explorer", boost::bind(LLFloaterExploreAnimations::show)); - registerFloater("sound_explorer", boost::bind(LLFloaterExploreSounds::toggle), boost::bind(LLFloaterExploreSounds::visible)); - registerFloater("asset_blacklist", boost::bind(LLFloaterBlacklist::toggle), boost::bind(LLFloaterBlacklist::visible)); - registerFloater("DayCycle", boost::bind(LLFloaterDayCycle::show), boost::bind(LLFloaterDayCycle::isOpen)); - registerFloater("EnvSettings", boost::bind(LLFloaterEnvSettings::show), boost::bind(LLFloaterEnvSettings::isOpen)); - registerFloater("PostProcess", boost::bind(LLFloaterPostProcess::show)); - registerFloater("RegionDebugConsole", boost::bind(handle_singleton_toggle, (void*)NULL), boost::bind(LLFloaterRegionDebugConsole::instanceExists)); registerFloater("WaterSettings", boost::bind(LLFloaterWater::show), boost::bind(LLFloaterWater::isOpen)); + registerFloater("web", boost::bind(LLFloaterWebContent::showInstance, "dict web", LLFloaterWebContent::Params())); registerFloater("Windlight", boost::bind(LLFloaterWindLight::show), boost::bind(LLFloaterWindLight::isOpen)); - registerFloater ("im"); + registerFloater("world map", boost::bind(LLFloaterWorldMap::toggle)); registerFloater ("about land"); registerFloater ("about region"); registerFloater ("active speakers"); registerFloater ("areasearch"); + registerFloater ("autoreplace"); registerFloater ("beacons"); registerFloater ("camera controls"); registerFloater ("chat history"); @@ -224,6 +226,7 @@ struct MenuFloaterDict : public LLSingleton registerFloater ("friends", 0); registerFloater ("gestures"); registerFloater ("groups", 1); + registerFloater ("im"); registerFloater ("lag meter"); registerFloater ("media filter"); registerFloater ("mini map"); @@ -231,14 +234,14 @@ struct MenuFloaterDict : public LLSingleton registerFloater ("mute list"); registerFloater ("notifications console"); registerFloater ("outbox"); + registerFloater ("pathfinding_characters"); + registerFloater ("pathfinding_linksets"); registerFloater ("perm prefs"); registerFloater ("radar"); registerFloater ("script info"); registerFloater ("stat bar"); registerFloater ("teleport history"); registerFloater ("voice effect"); - registerFloater ("pathfinding_characters"); - registerFloater ("pathfinding_linksets"); // [RLVa:LF] registerFloater("rlv restrictions"); registerFloater("rlv locks"); @@ -248,7 +251,7 @@ struct MenuFloaterDict : public LLSingleton template void registerConsole(const std::string& name, T* console) { - registerFloater(name, boost::bind(&T::setVisible, console, boost::bind(&T::getVisible, console)), boost::bind(&T::getVisible, console)); + registerFloater(name, boost::bind(&T::setVisible, console, !boost::bind(&T::getVisible, console)), boost::bind(&T::getVisible, console)); } void registerFloater(const std::string& name, boost::function show, boost::function visible = NULL) { diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 5a55d2562..bb82041fa 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -67,6 +67,7 @@ #include "aicurl.h" #include "boost/lexical_cast.hpp" + #ifndef LL_WINDOWS #include "netdb.h" #endif @@ -239,7 +240,7 @@ public: } } - /*virtual*/ void completedRaw(U32 status, const std::string& reason, + virtual void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); @@ -278,7 +279,7 @@ public: } } - /*virtual*/ void completedRaw(U32 status, const std::string& reason, + virtual void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); @@ -303,10 +304,17 @@ public: ~LLMeshSkinInfoResponder() { - llassert(mProcessed || LLApp::isExiting()); + if (!LLApp::isQuitting() && + !mProcessed && + mMeshID.notNull()) + { // Something went wrong, retry + llwarns << "Timeout or service unavailable, retrying loadMeshSkinInfo() for " << mMeshID << llendl; + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->loadMeshSkinInfo(mMeshID); + } } - /*virtual*/ void completedRaw(U32 status, const std::string& reason, + virtual void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); @@ -331,10 +339,17 @@ public: ~LLMeshDecompositionResponder() { - llassert(mProcessed || LLApp::isExiting()); + if (!LLApp::isQuitting() && + !mProcessed && + mMeshID.notNull()) + { // Something went wrong, retry + llwarns << "Timeout or service unavailable, retrying loadMeshDecomposition() for " << mMeshID << llendl; + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->loadMeshDecomposition(mMeshID); + } } - /*virtual*/ void completedRaw(U32 status, const std::string& reason, + virtual void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); @@ -359,10 +374,17 @@ public: ~LLMeshPhysicsShapeResponder() { - llassert(mProcessed || LLApp::isExiting()); + if (!LLApp::isQuitting() && + !mProcessed && + mMeshID.notNull()) + { // Something went wrong, retry + llwarns << "Timeout or service unavailable, retrying loadMeshPhysicsShape() for " << mMeshID << llendl; + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID); + } } - /*virtual*/ void completedRaw(U32 status, const std::string& reason, + virtual void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); @@ -437,7 +459,7 @@ public: { } - /*virtual*/ void completed(U32 status, + virtual void completed(U32 status, const std::string& reason, const LLSD& content) { @@ -451,7 +473,7 @@ public: LLWholeModelFeeObserver* observer = mObserverHandle.get(); - if (((200 <= status) && (status < 300)) && + if (isGoodStatus(status) && cc["state"].asString() == "upload") { mWholeModelUploadURL = cc["uploader"].asString(); @@ -495,7 +517,7 @@ public: { } - /*virtual*/ void completed(U32 status, + virtual void completed(U32 status, const std::string& reason, const LLSD& content) { @@ -511,7 +533,7 @@ public: // requested "mesh" asset type isn't actually the type // of the resultant object, fix it up here. - if (((200 <= status) && (status < 300)) && + if (isGoodStatus(status) && cc["state"].asString() == "complete") { mModelData["asset_type"] = "object"; @@ -568,6 +590,7 @@ void LLMeshRepoThread::run() mSignal->lock(); while (!LLApp::isQuitting()) { + if (!LLApp::isQuitting()) { static U32 count = 0; @@ -583,50 +606,35 @@ void LLMeshRepoThread::run() while (!mLODReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveLODRequests < (S32)sMaxConcurrentRequests) { + if (mMutex) { mMutex->lock(); LODRequest req = mLODReqQ.front(); mLODReqQ.pop(); LLMeshRepository::sLODProcessing--; mMutex->unlock(); - try + if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit { - fetchMeshLOD(req.mMeshParams, req.mLOD, count); - } - catch(AICurlNoEasyHandle const& error) - { - llwarns << "fetchMeshLOD() failed: " << error.what() << llendl; mMutex->lock(); - LLMeshRepository::sLODProcessing++; mLODReqQ.push(req); mMutex->unlock(); - break; } } } while (!mHeaderReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveHeaderRequests < (S32)sMaxConcurrentRequests) { + if (mMutex) { mMutex->lock(); HeaderRequest req = mHeaderReqQ.front(); mHeaderReqQ.pop(); mMutex->unlock(); - bool success = false; - try - { - success = fetchMeshHeader(req.mMeshParams, count); - } - catch(AICurlNoEasyHandle const& error) - { - llwarns << "fetchMeshHeader() failed: " << error.what() << llendl; - } - if (!success) + if (!fetchMeshHeader(req.mMeshParams, count))//failed, resubmit { mMutex->lock(); mHeaderReqQ.push(req) ; mMutex->unlock(); - break; } } } @@ -636,16 +644,7 @@ void LLMeshRepoThread::run() for (std::set::iterator iter = mSkinRequests.begin(); iter != mSkinRequests.end(); ++iter) { LLUUID mesh_id = *iter; - bool success = false; - try - { - success = fetchMeshSkinInfo(mesh_id); - } - catch(AICurlNoEasyHandle const& error) - { - llwarns << "fetchMeshSkinInfo(" << mesh_id << ") failed: " << error.what() << llendl; - } - if (!success) + if (!fetchMeshSkinInfo(mesh_id)) { incomplete.insert(mesh_id); } @@ -658,16 +657,7 @@ void LLMeshRepoThread::run() for (std::set::iterator iter = mDecompositionRequests.begin(); iter != mDecompositionRequests.end(); ++iter) { LLUUID mesh_id = *iter; - bool success = false; - try - { - success = fetchMeshDecomposition(mesh_id); - } - catch(AICurlNoEasyHandle const& error) - { - llwarns << "fetchMeshDecomposition(" << mesh_id << ") failed: " << error.what() << llendl; - } - if (!success) + if (!fetchMeshDecomposition(mesh_id)) { incomplete.insert(mesh_id); } @@ -680,16 +670,7 @@ void LLMeshRepoThread::run() for (std::set::iterator iter = mPhysicsShapeRequests.begin(); iter != mPhysicsShapeRequests.end(); ++iter) { LLUUID mesh_id = *iter; - bool success = false; - try - { - success = fetchMeshPhysicsShape(mesh_id); - } - catch(AICurlNoEasyHandle const& error) - { - llwarns << "fetchMeshPhysicsShape(" << mesh_id << ") failed: " << error.what() << llendl; - } - if (!success) + if (!fetchMeshPhysicsShape(mesh_id)) { incomplete.insert(mesh_id); } @@ -701,7 +682,11 @@ void LLMeshRepoThread::run() mSignal->wait(); } - mSignal->unlock(); + + if (mSignal->isLocked()) + { //make sure to let go of the mutex associated with the given signal before shutting down + mSignal->unlock(); + } res = LLConvexDecomposition::quitThread(); if (res != LLCD_OK) @@ -734,6 +719,8 @@ void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 } } + + void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) { //could be called from any thread LLMutexLock lock(mMutex); @@ -790,15 +777,21 @@ std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id) bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) { //protected by mMutex + + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) - { - // We have no header info for this mesh, try again later. + { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; } + bool ret = true ; U32 header_size = mMeshHeaderSize[mesh_id]; if (header_size > 0) @@ -820,7 +813,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) U8* buffer = new U8[size]; file.read(buffer, size); - //make sure buffer isn't all 0's (reserved block but not written) + //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) bool zero = true; for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) { @@ -845,9 +838,12 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) { - LLHTTPClient::getByteRange(http_url, offset, size, - new LLMeshSkinInfoResponder(mesh_id, offset, size), headers); - LLMeshRepository::sHTTPRequestCount++; + ret = LLHTTPClient::getByteRange(http_url, headers, offset, size, + new LLMeshSkinInfoResponder(mesh_id, offset, size)); + if (ret) + { + LLMeshRepository::sHTTPRequestCount++; + } } } } @@ -857,22 +853,26 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) } //early out was not hit, effectively fetched - return true; + return ret; } -//return false if failed to get header bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) { //protected by mMutex + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) - { - // We have no header info for this mesh, try again later. + { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; } U32 header_size = mMeshHeaderSize[mesh_id]; + bool ret = true ; if (header_size > 0) { @@ -889,11 +889,12 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesRead += size; + file.seek(offset); U8* buffer = new U8[size]; file.read(buffer, size); - //make sure buffer isn't all 0's (reserved block but not written) + //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) bool zero = true; for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) { @@ -918,10 +919,12 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) { - // This might throw AICurlNoEasyHandle. - LLHTTPClient::getByteRange(http_url, offset, size, - new LLMeshDecompositionResponder(mesh_id, offset, size), headers); - LLMeshRepository::sHTTPRequestCount++; + ret = LLHTTPClient::getByteRange(http_url, headers, offset, size, + new LLMeshDecompositionResponder(mesh_id, offset, size)); + if(ret) + { + LLMeshRepository::sHTTPRequestCount++; + } } } } @@ -931,22 +934,26 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) } //early out was not hit, effectively fetched - return true; + return ret; } -//return false if failed to get header bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) { //protected by mMutex + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) - { - // We have no header info for this mesh, retry later. + { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; } U32 header_size = mMeshHeaderSize[mesh_id]; + bool ret = true ; if (header_size > 0) { @@ -967,7 +974,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) U8* buffer = new U8[size]; file.read(buffer, size); - //make sure buffer isn't all 0's (reserved block but not written) + //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) bool zero = true; for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) { @@ -992,10 +999,13 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) { - // This might throw AICurlNoEasyHandle. - LLHTTPClient::getByteRange(http_url, offset, size, - new LLMeshPhysicsShapeResponder(mesh_id, offset, size), headers); - LLMeshRepository::sHTTPRequestCount++; + ret = LLHTTPClient::getByteRange(http_url, headers, offset, size, + new LLMeshPhysicsShapeResponder(mesh_id, offset, size)); + + if(ret) + { + LLMeshRepository::sHTTPRequestCount++; + } } } else @@ -1009,7 +1019,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) } //early out was not hit, effectively fetched - return true; + return ret; } //static @@ -1056,14 +1066,14 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& c LLMeshRepository::sCacheBytesRead += bytes; file.read(buffer, bytes); if (headerReceived(mesh_params, buffer, bytes)) - { - // Already have header, no need to retry. + { //did not do an HTTP request, return false return true; } } } //either cache entry doesn't exist or is corrupt, request header from simulator + bool retval = true; AIHTTPHeaders headers("Accept", "application/octet-stream"); std::string http_url = constructUrl(mesh_params.getSculptID()); @@ -1072,19 +1082,29 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& c //grab first 4KB if we're going to bother with a fetch. Cache will prevent future fetches if a full mesh fits //within the first 4KB //NOTE -- this will break of headers ever exceed 4KB - // This might throw AICurlNoEasyHandle. - LLHTTPClient::getByteRange(http_url, 0, 4096, new LLMeshHeaderResponder(mesh_params), headers); - LLMeshRepository::sHTTPRequestCount++; + retval = LLHTTPClient::getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params)); + if (retval) + { + LLMeshRepository::sHTTPRequestCount++; + } count++; } - return true; + return retval; } -void LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count) +//return false if failed to get mesh lod. +bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count) { //protected by mMutex + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); + bool retval = true; + LLUUID mesh_id = mesh_params.getSculptID(); U32 header_size = mMeshHeaderSize[mesh_id]; @@ -1108,7 +1128,7 @@ void LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U8* buffer = new U8[size]; file.read(buffer, size); - //make sure buffer isn't all 0's (reserved block but not written) + //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) bool zero = true; for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) { @@ -1120,7 +1140,7 @@ void LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, if (lodReceived(mesh_params, lod, buffer, size)) { delete[] buffer; - return; + return true; } } @@ -1133,10 +1153,13 @@ void LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) { - // This might throw AICurlNoEasyHandle. - LLHTTPClient::getByteRange(constructUrl(mesh_id), offset, size, - new LLMeshLODResponder(mesh_params, lod, offset, size), headers); - LLMeshRepository::sHTTPRequestCount++; + retval = LLHTTPClient::getByteRange(constructUrl(mesh_id), headers, offset, size, + new LLMeshLODResponder(mesh_params, lod, offset, size)); + + if (retval) + { + LLMeshRepository::sHTTPRequestCount++; + } count++; } else @@ -1153,6 +1176,8 @@ void LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, { mHeaderMutex->unlock(); } + + return retval; } bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size) @@ -1199,7 +1224,6 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat mMeshHeader[mesh_id] = header; } - LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. //check for pending requests @@ -1212,10 +1236,8 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat mLODReqQ.push(req); LLMeshRepository::sLODProcessing++; } - - mPendingLOD.erase(iter); // FIRE-7182, only call erase if iter is really valid. + mPendingLOD.erase(iter); } - // mPendingLOD.erase(iter); // avoid crash by moving erase up. } return true; @@ -1375,6 +1397,11 @@ void LLMeshUploadThread::init(LLMeshUploadThread::instance_list& data, LLVector3 mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut") ; } +LLMeshUploadThread::~LLMeshUploadThread() +{ + +} + LLMeshUploadThread::DecompRequest::DecompRequest(LLModel* mdl, LLModel* base_model, LLMeshUploadThread* thread) { mStage = "single_hull"; @@ -1476,18 +1503,18 @@ bool LLMeshUploadThread::run() void LLMeshUploadThread::postRequest(std::string& whole_model_upload_url, AIMeshUpload* state_machine) { - if (!mDoUpload) - { - LLHTTPClient::post(mWholeModelFeeCapability, mModelData, - new LLWholeModelFeeResponder(mModelData, mFeeObserverHandle, whole_model_upload_url)/*,*/ - DEBUG_CURLIO_PARAM(debug_on), keep_alive, state_machine, AIMeshUpload_responderFinished); - } - else + if (mDoUpload) { LLHTTPClient::post(whole_model_upload_url, mBody, new LLWholeModelUploadResponder(mModelData, mUploadObserverHandle)/*,*/ DEBUG_CURLIO_PARAM(debug_off), keep_alive, state_machine, AIMeshUpload_responderFinished); } + else + { + LLHTTPClient::post(mWholeModelFeeCapability, mModelData, + new LLWholeModelFeeResponder(mModelData, mFeeObserverHandle, whole_model_upload_url)/*,*/ + DEBUG_CURLIO_PARAM(debug_on), keep_alive, state_machine, AIMeshUpload_responderFinished); + } } void dump_llsd_to_file(const LLSD& content, std::string filename) @@ -1735,8 +1762,14 @@ void LLMeshUploadThread::generateHulls() } } + void LLMeshRepoThread::notifyLoadedMeshes() -{//called via gMeshRepo.notifyLoadedMeshes(). mMutex already locked +{ + if (!mMutex) + { + return; + } + while (!mLoadedQ.empty()) { mMutex->lock(); @@ -1860,6 +1893,12 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, { mProcessed = true; + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status >= 400) @@ -1877,6 +1916,7 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, } else { + llassert(is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -1917,6 +1957,12 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason { mProcessed = true; + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status >= 400) @@ -1928,12 +1974,13 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason { if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again - llwarns << "Timeout or service unavailable, retrying." << llendl; + llwarns << "Timeout or service unavailable, retrying loadMeshSkinInfo() for " << mMeshID << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshSkinInfo(mMeshID); } else { + llassert(is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -1974,6 +2021,11 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r { mProcessed = true; + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status >= 400) @@ -1985,12 +2037,13 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r { if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again - llwarns << "Timeout or service unavailable, retrying." << llendl; + llwarns << "Timeout or service unavailable, retrying loadMeshDecomposition() for " << mMeshID << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshDecomposition(mMeshID); } else { + llassert(is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -2031,6 +2084,12 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re { mProcessed = true; + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status >= 400) @@ -2042,12 +2101,13 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re { if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again - llwarns << "Timeout or service unavailable, retrying." << llendl; + llwarns << "Timeout or service unavailable, retrying loadMeshPhysicsShape() for " << mMeshID << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID); } else { + llassert(is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -2088,18 +2148,27 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, { mProcessed = true; + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + if (status < 200 || status >= 400) { //llwarns // << "Header responder failed with status: " // << status << ": " << reason << llendl; - // HTTP_SERVICE_UNAVAILABLE (503) or HTTP_INTERNAL_ERROR_*'s. + // 503 (service unavailable) or HTTP_INTERNAL_ERROR_*'s. // can be due to server load and can be retried // TODO*: Add maximum retry logic, exponential backoff // and (somewhat more optional than the others) retries // again after some set period of time + + llassert(status == HTTP_NOT_FOUND || status == HTTP_SERVICE_UNAVAILABLE || status == HTTP_REQUEST_TIME_OUT || is_internal_http_error_that_warrants_a_retry(status)); + if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) { //retry llwarns << "Timeout or service unavailable, retrying." << llendl; @@ -2112,7 +2181,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, } else { - llwarns << "Unhandled status." << llendl; + llwarns << "Unhandled status: " << status << llendl; } } @@ -2401,8 +2470,7 @@ void LLMeshRepository::notifyLoadedMeshes() mDecompThread->notifyCompleted(); if (!mThread->mSignal->tryLock()) - { - // Curl thread is churning, wait for it to go idle. + { //curl thread is churning, wait for it to go idle return; } mThread->mSignal->unlock(); @@ -2414,7 +2482,6 @@ void LLMeshRepository::notifyLoadedMeshes() if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived()) { region_name = gAgent.getRegion()->getName(); - mGetMeshCapability = gAgent.getRegion()->getCapability("GetMesh2"); if (mGetMeshCapability.empty()) { @@ -2772,8 +2839,9 @@ void LLMeshRepository::uploadModel(std::vector& data, LLVector3 llinfos << "unable to upload, fee request failed" << llendl; return; } - AIMeshUpload* uploader = new AIMeshUpload(data, scale, upload_textures, upload_skin, upload_joints, upload_url, do_upload, fee_observer, upload_observer); - uploader->run(NULL, 0, false, true, &gMainThreadEngine); + AIMeshUpload* thread = new AIMeshUpload(data, scale, upload_textures, upload_skin, upload_joints, upload_url, + do_upload, fee_observer, upload_observer); + thread->run(NULL, 0, false, true, &gMainThreadEngine); } S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) @@ -3069,13 +3137,15 @@ bool needTriangles( LLConvexDecomposition *aDC ) void LLPhysicsDecomp::setMeshData(LLCDMeshData& mesh, bool vertex_based) { - LLConvexDecomposition *pDeComp = LLConvexDecomposition::getInstance(); - - if( !pDeComp ) - return; - - if( vertex_based ) - vertex_based = !needTriangles( pDeComp ); + // HACD + if (vertex_based) + { + if (LLConvexDecomposition* pDeComp = LLConvexDecomposition::getInstance()) + vertex_based = !needTriangles(pDeComp); + else + return; + } + // mesh.mVertexBase = mCurRequest->mPositions[0].mV; mesh.mVertexStrideBytes = 12; @@ -3093,7 +3163,10 @@ void LLPhysicsDecomp::setMeshData(LLCDMeshData& mesh, bool vertex_based) if ((vertex_based || mesh.mNumTriangles > 0) && mesh.mNumVertices > 2) { LLCDResult ret = LLCD_OK; - ret = LLConvexDecomposition::getInstance()->setMeshData(&mesh, vertex_based); + if (LLConvexDecomposition::getInstance() != NULL) + { + ret = LLConvexDecomposition::getInstance()->setMeshData(&mesh, vertex_based); + } if (ret) { @@ -3148,6 +3221,7 @@ void LLPhysicsDecomp::doDecomposition() continue; } + if (param->mType == LLCDParam::LLCD_FLOAT) { ret = LLConvexDecomposition::getInstance()->setParam(param->mName, (F32) value.asReal()); @@ -3461,10 +3535,12 @@ void LLPhysicsDecomp::run() } } - mSignal->unlock(); - decomp->quitThread(); + if (mSignal->isLocked()) + { //let go of mSignal's associated mutex + mSignal->unlock(); + } mDone = true; } @@ -3670,4 +3746,3 @@ bool LLMeshRepository::meshRezEnabled() } return false; } - diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 4b535f397..ab9220cdc 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -36,7 +36,7 @@ #define LLCONVEXDECOMPINTER_STATIC 1 -#include "LLConvexDecomposition.h" +#include "llconvexdecomposition.h" #include "lluploadfloaterobservers.h" #include "aistatemachinethread.h" @@ -324,7 +324,7 @@ public: void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count); - void fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count); + bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count); bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size); bool lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size); bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size); @@ -405,10 +405,11 @@ public: #endif void init(instance_list& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool do_upload, LLHandle const& fee_observer, LLHandle const& upload_observer); + ~LLMeshUploadThread(); void postRequest(std::string& url, AIMeshUpload* state_machine); - /*virtual*/ bool run(); + virtual bool run(); void preStart(); void generateHulls(); @@ -504,8 +505,7 @@ public: void uploadModel(std::vector& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true, - LLHandle fee_observer= (LLHandle()), - LLHandle upload_observer = (LLHandle())); + LLHandle fee_observer= (LLHandle()), LLHandle upload_observer = (LLHandle())); S32 getMeshSize(const LLUUID& mesh_id, S32 lod); diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index ce43bd8f8..e81c406a3 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -103,11 +103,15 @@ const S32 CIRCLE_STEPS = 100; const F64 COARSEUPDATE_MAX_Z = 1020.0f; +std::map LLNetMap::mClosestAgentsToCursor; // +static std::map mClosestAgentsAtLastClick; // + LLNetMap::LLNetMap(const std::string& name) : LLPanel(name), mScale(128.f), mObjectMapTPM(1.f), mObjectMapPixels(255.f), + mPickRadius(gSavedSettings, "ExodusMinimapAreaEffect"), // mTargetPan(0.f, 0.f), mCurPan(0.f, 0.f), mStartPan(0.f, 0.f), @@ -215,6 +219,13 @@ std::size_t hash_value(const LLUUID& uuid) return (std::size_t)uuid.getCRC32(); } boost::unordered_map mm_MarkerColors; +bool mm_getMarkerColor(const LLUUID& id, LLColor4& color) +{ + boost::unordered_map::const_iterator it = mm_MarkerColors.find(id); + if (it == mm_MarkerColors.end()) return false; + color = it->second; + return true; +} void LLNetMap::mm_setcolor(LLUUID key,LLColor4 col) { @@ -222,6 +233,10 @@ void LLNetMap::mm_setcolor(LLUUID key,LLColor4 col) } void LLNetMap::draw() { + LLViewerRegion* region = gAgent.getRegion(); + + if (region == NULL) return; + static LLFrameTimer map_timer; static LLUIColor map_track_color = gTrackColor; static const LLCachedControl map_frustum_color(gColors, "NetMapFrustum", LLColor4::white); @@ -262,18 +277,15 @@ void LLNetMap::draw() gGL.loadIdentity(); gGL.loadUIIdentity(); - gGL.scalef(scale.mV[0], scale.mV[1], scale.mV[2]); gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); - { LLLocalClipRect clip(getLocalRect()); { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.matrixMode(LLRender::MM_MODELVIEW); - // Draw background rectangle + // Draw background rectangle. if(isBackgroundVisible()) { LLColor4 background_color = isBackgroundOpaque() ? getBackgroundColor().mV : getTransparentColor().mV; @@ -282,23 +294,22 @@ void LLNetMap::draw() } } - // region 0,0 is in the middle + // Region 0,0 is in the middle. S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPan.mV[VX]); S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPan.mV[VY]); gGL.pushMatrix(); - gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); static LLCachedControl rotate_map("MiniMapRotate", true); if (rotate_map) { - // rotate subsequent draws to agent rotation + // Rotate subsequent draws to agent rotation. rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); gGL.rotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f); } - // figure out where agent is + // Figure out where agent is. static const LLCachedControl this_region_color(gColors, "NetMapThisRegion"); static const LLCachedControl live_region_color(gColors, "NetMapLiveRegion"); static const LLCachedControl dead_region_color(gColors, "NetMapDeadRegion"); @@ -311,13 +322,14 @@ void LLNetMap::draw() iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* regionp = *iter; + // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; - // background region rectangle + // Background region rectangle. F32 bottom = relative_y; F32 left = relative_x; // Aurora Sim @@ -327,19 +339,9 @@ void LLNetMap::draw() F32 right = left + (regionp->getWidth() / REGION_WIDTH_METERS) * mScale ; // Aurora Sim - if (regionp == gAgent.getRegion()) - { - gGL.color4fv(this_region_color().mV); - } - else - { - gGL.color4fv(live_region_color().mV); - } - - if (!regionp->isAlive()) - { - gGL.color4fv(dead_region_color().mV); - } + if (regionp == region) gGL.color4fv(this_region_color().mV); + else if (!regionp->isAlive()) gGL.color4fv(dead_region_color().mV); + else gGL.color4fv(live_region_color().mV); // [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-07-26 (Catznip-3.3) static LLCachedControl s_fUseWorldMapTextures(gSavedSettings, "MiniMapWorldMapTextures"); @@ -445,7 +447,6 @@ void LLNetMap::draw() gObjectList.renderObjectsForMap(*this); mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); - map_timer.reset(); } @@ -530,10 +531,15 @@ void LLNetMap::draw() // Mouse pointer in local coordinates S32 local_mouse_x; S32 local_mouse_y; - //localMouse(&local_mouse_x, &local_mouse_y); + LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y); + + F32 min_pick_dist = mDotRadius * mPickRadius; + mClosestAgentToCursor.setNull(); - F32 closest_dist_squared = F32_MAX; // value will be overridden in the loop + mClosestAgentsToCursor.clear(); + + F32 closest_dist_squared = F32_MAX; F32 min_pick_dist_squared = (mDotRadius * MIN_PICK_SCALE) * (mDotRadius * MIN_PICK_SCALE); LLVector3 pos_map; @@ -564,38 +570,45 @@ void LLNetMap::draw() { pos_map.mV[VZ] = 16000.f; } - if(LLMuteList::getInstance()->isMuted(uuid)) - { - static const LLCachedControl muted_color("AscentMutedColor",LLColor4(0.7f,0.7f,0.7f,1.f)); - color = muted_color; - } - LLViewerRegion* avatar_region = LLWorld::getInstance()->getRegionFromPosGlobal(positions[i]); - LLUUID estate_owner = avatar_region ? avatar_region->getOwner() : LLUUID::null; + if (dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x, local_mouse_y)) < min_pick_dist) + { + mClosestAgentsToCursor[uuid] = positions[i]; + static const LLCachedControl map_avatar_rollover_color(gSavedSettings, "ExodusMapRolloverColor", LLColor4::cyan); + color = map_avatar_rollover_color; + } + else + { - // MOYMOD Minimap custom av colors. - boost::unordered_map::const_iterator it = mm_MarkerColors.find(uuid); - if(it != mm_MarkerColors.end()) - { - color = it->second; - } - //Lindens are always more Linden than your friend, make that take precedence - else if (LLMuteList::getInstance()->isLinden(uuid)) - { - static const LLCachedControl linden_color("AscentLindenColor",LLColor4(0.f,0.f,1.f,1.f)); - color = linden_color; - } - //check if they are an estate owner at their current position - else if (estate_owner.notNull() && uuid == estate_owner) - { - static const LLCachedControl em_color("AscentEstateOwnerColor",LLColor4(1.f,0.6f,1.f,1.f)); - color = em_color; - } - //without these dots, SL would suck. - else if (show_friends && LLAvatarActions::isFriend(uuid)) - { - static const LLCachedControl friend_color("AscentFriendColor",LLColor4(1.f,1.f,0.f,1.f)); - color = friend_color; + if(LLMuteList::getInstance()->isMuted(uuid)) + { + static const LLCachedControl muted_color("AscentMutedColor",LLColor4(0.7f,0.7f,0.7f,1.f)); + color = muted_color; + } + + LLViewerRegion* avatar_region = LLWorld::getInstance()->getRegionFromPosGlobal(positions[i]); + const LLUUID estate_owner = avatar_region ? avatar_region->getOwner() : LLUUID::null; + + // MOYMOD Minimap custom av colors. + if (mm_getMarkerColor(uuid, color)) {} + //Lindens are always more Linden than your friend, make that take precedence + else if (LLMuteList::getInstance()->isLinden(uuid)) + { + static const LLCachedControl linden_color("AscentLindenColor",LLColor4(0.f,0.f,1.f,1.f)); + color = linden_color; + } + //check if they are an estate owner at their current position + else if (estate_owner.notNull() && uuid == estate_owner) + { + static const LLCachedControl em_color("AscentEstateOwnerColor",LLColor4(1.f,0.6f,1.f,1.f)); + color = em_color; + } + //without these dots, SL would suck. + else if (show_friends && LLAvatarActions::isFriend(uuid)) + { + static const LLCachedControl friend_color("AscentFriendColor",LLColor4(1.f,1.f,0.f,1.f)); + color = friend_color; + } } LLWorldMapView::drawAvatar( @@ -603,23 +616,12 @@ void LLNetMap::draw() color, pos_map.mV[VZ], mDotRadius); - F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), - LLVector2(local_mouse_x,local_mouse_y)); - if(dist_to_cursor_squared < min_pick_dist_squared) - { - if (dist_to_cursor_squared < closest_dist_squared) - { - closest_dist_squared = dist_to_cursor_squared; - mClosestAgentToCursor = uuid; - mClosestAgentPosition = positions[i]; - } - } - if (!gmSelected.empty()) if (uuid.notNull()) { bool selected = false; uuid_vec_t::iterator sel_iter = gmSelected.begin(); + for (; sel_iter != gmSelected.end(); sel_iter++) { if(*sel_iter == uuid) @@ -628,6 +630,7 @@ void LLNetMap::draw() break; } } + if (selected) { if( (pos_map.mV[VX] < 0) || @@ -637,13 +640,19 @@ void LLNetMap::draw() { S32 x = llround( pos_map.mV[VX] ); S32 y = llround( pos_map.mV[VY] ); + LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10); - } else - { - LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f); } + else LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f); } } + + F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); + if (dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared) + { + closest_dist_squared = dist_to_cursor_squared; + mClosestAgentToCursor = uuid; + } } // Draw dot for autopilot target @@ -658,24 +667,31 @@ void LLNetMap::draw() { drawTracking( LLAvatarTracker::instance().getGlobalPos(), map_track_color ); } - else if ( LLTracker::TRACKING_LANDMARK == tracking_status - || LLTracker::TRACKING_LOCATION == tracking_status ) + else if ( LLTracker::TRACKING_LANDMARK == tracking_status || + LLTracker::TRACKING_LOCATION == tracking_status ) { drawTracking( LLTracker::getTrackedPositionGlobal(), map_track_color ); } } - // Draw dot for self avatar position - LLVector3d pos_global = gAgent.getPositionGlobal(); - pos_map = globalPosToView(pos_global); + pos_map = globalPosToView(gAgent.getPositionGlobal()); S32 dot_width = llround(mDotRadius * 2.f); LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage; + if (you) { you->draw(llround(pos_map.mV[VX] - mDotRadius), llround(pos_map.mV[VY] - mDotRadius), dot_width, dot_width); + + F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), + LLVector2(local_mouse_x,local_mouse_y)); + + if (dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared) + { + mClosestAgentToCursor = gAgent.getID(); + } } // Draw chat range ring(s) @@ -721,18 +737,25 @@ void LLNetMap::draw() else { gGL.color4fv((map_frustum_rotating_color()).mV); - + // If we don't rotate the map, we have to rotate the frustum. gGL.pushMatrix(); gGL.translatef( ctr_x, ctr_y, 0 ); gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); gGL.begin( LLRender::TRIANGLES ); - gGL.vertex2f( 0, 0 ); + gGL.vertex2f( 0.f, 0.f ); gGL.vertex2f( -half_width_pixels, far_clip_pixels ); gGL.vertex2f( half_width_pixels, far_clip_pixels ); gGL.end(); gGL.popMatrix(); } + + // Draw mouse radius + static const LLCachedControl map_avatar_rollover_color("ExodusMapRolloverCircleColor"); + gGL.color4fv((map_avatar_rollover_color()).mV); + // Todo: Detect if over the window and don't render a circle? + gl_circle_2d(local_mouse_x, local_mouse_y, min_pick_dist, 32, true); + // } gGL.popMatrix(); @@ -764,9 +787,7 @@ void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos) { - LLVector3d camera_position = gAgentCamera.getCameraPositionGlobal(); - - LLVector3d relative_pos_global = global_pos - camera_position; + LLVector3d relative_pos_global = global_pos - gAgentCamera.getCameraPositionGlobal(); LLVector3 pos_local; pos_local.setVec(relative_pos_global); // convert to floats from doubles @@ -862,6 +883,13 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { + // + if (gKeyboard->currentMask(TRUE) & MASK_SHIFT) + { + mPickRadius = llclamp(mPickRadius + (2.5f * clicks), 1.f, 64.f); + return true; + } + // // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks); F32 old_scale = mScale; @@ -881,7 +909,7 @@ BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks) return TRUE; } -BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen ) +BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& tool_tip, LLRect* sticky_rect_screen ) { if (gDisconnected) { @@ -898,41 +926,64 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP; - msg.assign(""); - std::string fullname; - if(mClosestAgentToCursor.notNull() && LLAvatarNameCache::getPNSName(mClosestAgentToCursor, fullname)) + tool_tip.assign(""); + + if (region->mMapAvatarIDs.count()) { - //msg.append(fullname); -// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b - msg.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? fullname : RlvStrings::getAnonym(fullname) ); -// [/RLVa:KB] - msg.append("\n"); - - LLVector3d mypos = gAgent.getPositionGlobal(); - LLVector3d position = mClosestAgentPosition; - - if ( LLFloaterAvatarList::instanceExists() ) + if (mClosestAgentsToCursor.size()) { - if (LLAvatarListEntry *ent = LLFloaterAvatarList::getInstance()->getAvatarEntry(mClosestAgentToCursor)) - position = ent->getPosition(); - } - LLVector3d delta = position - mypos; - F32 distance = (F32)delta.magVec(); + bool single_agent(mClosestAgentsToCursor.size() == 1); // Singu note: For old look, only add the count if we have more than one + if (!single_agent) + tool_tip.append(llformat("Agents under cursor (%d/%d)\n", mClosestAgentsToCursor.size(), region->mMapAvatarIDs.count() + 1)); - msg.append( llformat("\n(Distance: %.02fm)\n\n",distance) ); + LLVector3d myPosition = gAgent.getPositionGlobal(); + + std::map::iterator current = mClosestAgentsToCursor.begin(); + std::map::iterator end = mClosestAgentsToCursor.end(); + for (; current != end; ++current) + { + LLUUID targetUUID = (*current).first; + LLVector3d targetPosition = (*current).second; + + std::string fullName; + if (targetUUID.notNull() && LLAvatarNameCache::getPNSName(targetUUID, fullName)) + { + //tool_tip.append(fullName); +// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b + tool_tip.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? fullName : RlvStrings::getAnonym(fullName) ); +// [/RLVa:KB] + + // Use the radar for positioning, when possible. + if (LLFloaterAvatarList::instanceExists()) + { + if (LLAvatarListEntry* ent = LLFloaterAvatarList::getInstance()->getAvatarEntry(targetUUID)) + targetPosition = ent->getPosition(); + } + // + + LLVector3d delta = targetPosition - myPosition; + F32 distance = (F32)delta.magVec(); + if (single_agent) + tool_tip.append( llformat("\n\n(Distance: %.02fm)\n",distance) ); + else + tool_tip.append(llformat(" (%.02fm)\n", distance)); + } + } + tool_tip.append("\n"); + } } // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-0.2.0b - msg.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? region->getName() : RlvStrings::getString(RLV_STRING_HIDDEN) ); + tool_tip.append((!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC) ? region->getName() : RlvStrings::getString(RLV_STRING_HIDDEN))); // [/RLVa:KB] - //msg.append( region->getName() ); + //tool_tip.append("\n\n" + region->getName()); - msg.append("\n" + region->getHost().getHostName()); - msg.append("\n" + region->getHost().getString()); - msg.append("\n" + getToolTip()); + tool_tip.append("\n" + region->getHost().getHostName()); + tool_tip.append("\n" + region->getHost().getString()); + tool_tip.append("\n" + getToolTip()); } else { - return LLPanel::handleToolTip(x, y, msg, sticky_rect_screen); + return LLPanel::handleToolTip(x, y, tool_tip, sticky_rect_screen); } *sticky_rect_screen = sticky_rect; return TRUE; @@ -1283,9 +1334,11 @@ bool LLNetMap::OverlayToggle::handleEvent(LLPointer event, const LLSD& BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) { + mClosestAgentsAtLastClick = mClosestAgentsToCursor; mClosestAgentAtLastRightClick = mClosestAgentToCursor; if (mPopupMenu) { + // Singu TODO: It'd be spectacular to address multiple avatars from here. mPopupMenu->buildDrawLabels(); mPopupMenu->updateParent(LLMenuGL::sMenuContainer); LLMenuGL::showPopup(this, mPopupMenu, x, y); @@ -1404,58 +1457,50 @@ bool LLNetMap::LLScaleMap::handleEvent(LLPointer event, const LLSD& use } //moymod - minimap color shit -bool LLNetMap::mmsetred::handleEvent(LLPointer event, const LLSD& userdata) +void markMassAgents(const LLColor4& color) { - LLNetMap *self = mPtr; - //if(self->mClosestAgentAtLastRightClick){ - mm_setcolor(self->mClosestAgentAtLastRightClick,LLColor4(1.0,0.0,0.0,1.0)); - //} + std::map::iterator current = mClosestAgentsAtLastClick.begin(); + std::map::iterator end = mClosestAgentsAtLastClick.end(); + for(; current != end; ++current) LLNetMap::mm_setcolor((*current).first, color); +} + +bool LLNetMap::mmsetred::handleEvent(LLPointer, const LLSD&) +{ + markMassAgents(LLColor4::red); return true; +} +bool LLNetMap::mmsetgreen::handleEvent(LLPointer, const LLSD&) +{ + markMassAgents(LLColor4::green); return true; +} +bool LLNetMap::mmsetblue::handleEvent(LLPointer, const LLSD&) +{ + markMassAgents(LLColor4::blue); return true; +} +bool LLNetMap::mmsetyellow::handleEvent(LLPointer, const LLSD&) +{ + markMassAgents(LLColor4::yellow); return true; +} +bool LLNetMap::mmsetcustom::handleEvent(LLPointer, const LLSD&) +{ + markMassAgents(gSavedSettings.getColor4("MoyMiniMapCustomColor")); return true; +} +bool LLNetMap::mmsetunmark::handleEvent(LLPointer, const LLSD&) +{ + std::map::iterator it = mClosestAgentsAtLastClick.begin(); + std::map::iterator end = mClosestAgentsAtLastClick.end(); + for(; it!= end; ++it) mm_MarkerColors.erase((*it).first); return true; } -bool LLNetMap::mmsetgreen::handleEvent(LLPointer event, const LLSD& userdata) +bool LLNetMap::mmenableunmark::handleEvent(LLPointer, const LLSD& userdata) { - LLNetMap *self = mPtr; - //if(self->mClosestAgentAtLastRightClick){ - mm_setcolor(self->mClosestAgentAtLastRightClick,LLColor4(0.0,1.0,0.0,1.0)); - //} - return true; -} -bool LLNetMap::mmsetblue::handleEvent(LLPointer event, const LLSD& userdata) -{ - LLNetMap *self = mPtr; - //if(self->mClosestAgentAtLastRightClick){ - mm_setcolor(self->mClosestAgentAtLastRightClick,LLColor4(0.0,0.0,1.0,1.0)); - //} - return true; -} -bool LLNetMap::mmsetyellow::handleEvent(LLPointer event, const LLSD& userdata) -{ - LLNetMap *self = mPtr; - //if(self->mClosestAgentAtLastRightClick){ - mm_setcolor(self->mClosestAgentAtLastRightClick,LLColor4(1.0,1.0,0.0,1.0)); - //} - return true; -} -bool LLNetMap::mmsetcustom::handleEvent(LLPointer event, const LLSD& userdata) -{ - LLNetMap *self = mPtr; - //if(self->mClosestAgentAtLastRightClick){ - mm_setcolor(self->mClosestAgentAtLastRightClick,gSavedSettings.getColor4("MoyMiniMapCustomColor")); - //} - return true; -} -bool LLNetMap::mmsetunmark::handleEvent(LLPointer event, const LLSD& userdata) -{ - mm_MarkerColors.erase(mPtr->mClosestAgentAtLastRightClick); - return true; -} -bool LLNetMap::mmenableunmark::handleEvent(LLPointer event, const LLSD& userdata) -{ - LLNetMap *self = mPtr; - BOOL enabled = mPtr->mClosestAgentAtLastRightClick.notNull() && mm_MarkerColors.find(mPtr->mClosestAgentAtLastRightClick) != mm_MarkerColors.end(); - self->findControl(userdata["control"].asString())->setValue(enabled); + bool enabled(false); + std::map::iterator it = mClosestAgentsAtLastClick.begin(); + std::map::iterator end = mClosestAgentsAtLastClick.end(); + for(; it != end && !enabled; ++it) enabled = mm_MarkerColors.find((*it).first) != mm_MarkerColors.end(); + mPtr->findControl(userdata["control"].asString())->setValue(enabled); return true; } + bool LLNetMap::LLCenterMap::handleEvent(LLPointer event, const LLSD& userdata) { EMiniMapCenter center = (EMiniMapCenter)userdata.asInteger(); diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 2a4db214d..0b291b5bc 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -132,6 +132,9 @@ private: F32 mObjectMapTPM; // texels per meter on map F32 mObjectMapPixels; // Width of object map in pixels F32 mDotRadius; // Size of avatar markers + // + LLCachedControl mPickRadius; // Size of the rightclick area of affect + // bool mPanning; // map is being dragged LLVector2 mTargetPan; @@ -148,8 +151,9 @@ private: LLPointer mParcelImagep; // [/SL:KB] + static std::map mClosestAgentsToCursor; // + LLUUID mClosestAgentToCursor; - LLVector3d mClosestAgentPosition; LLUUID mClosestAgentAtLastRightClick; static void showAgentProfile(void*); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index b211047bc..db44b78d8 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -98,37 +98,23 @@ std::string USE_TEXTURE; LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit() { - LLComboBox* combobox_matmedia = getChild("combobox matmedia"); - LLComboBox* combobox_mattype = getChild("combobox mattype"); - - LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? - (combobox_mattype ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP; +// + LLRender::eTexIndex channel_to_edit = (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? + (mComboMatType ? (LLRender::eTexIndex)mComboMatType->getCurrentIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP; channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; return channel_to_edit; +// } // Things the UI provides... // -LLUUID LLPanelFace::getCurrentNormalMap() { return getChild("bumpytexture control")->getImageAssetID(); } -LLUUID LLPanelFace::getCurrentSpecularMap() { return getChild("shinytexture control")->getImageAssetID(); } -U32 LLPanelFace::getCurrentShininess() { return getChild("combobox shininess")->getCurrentIndex(); } -U32 LLPanelFace::getCurrentBumpiness() { return getChild("combobox bumpiness")->getCurrentIndex(); } -U8 LLPanelFace::getCurrentDiffuseAlphaMode() { return (U8)getChild("combobox alphamode")->getCurrentIndex(); } -U8 LLPanelFace::getCurrentAlphaMaskCutoff() { return (U8)getChild("maskcutoff")->getValue().asInteger(); } -U8 LLPanelFace::getCurrentEnvIntensity() { return (U8)getChild("environment")->getValue().asInteger(); } -U8 LLPanelFace::getCurrentGlossiness() { return (U8)getChild("glossiness")->getValue().asInteger(); } -F32 LLPanelFace::getCurrentBumpyRot() { return getChild("bumpyRot")->getValue().asReal(); } -F32 LLPanelFace::getCurrentBumpyScaleU() { return getChild("bumpyScaleU")->getValue().asReal(); } -F32 LLPanelFace::getCurrentBumpyScaleV() { return getChild("bumpyScaleV")->getValue().asReal(); } -F32 LLPanelFace::getCurrentBumpyOffsetU() { return getChild("bumpyOffsetU")->getValue().asReal(); } -F32 LLPanelFace::getCurrentBumpyOffsetV() { return getChild("bumpyOffsetV")->getValue().asReal(); } -F32 LLPanelFace::getCurrentShinyRot() { return getChild("shinyRot")->getValue().asReal(); } -F32 LLPanelFace::getCurrentShinyScaleU() { return getChild("shinyScaleU")->getValue().asReal(); } -F32 LLPanelFace::getCurrentShinyScaleV() { return getChild("shinyScaleV")->getValue().asReal(); } -F32 LLPanelFace::getCurrentShinyOffsetU() { return getChild("shinyOffsetU")->getValue().asReal(); } -F32 LLPanelFace::getCurrentShinyOffsetV() { return getChild("shinyOffsetV")->getValue().asReal(); } +// +LLUUID LLPanelFace::getCurrentNormalMap() { return mBumpyTextureCtrl->getImageAssetID(); } +LLUUID LLPanelFace::getCurrentSpecularMap() { return mShinyTextureCtrl->getImageAssetID(); } +U8 LLPanelFace::getCurrentDiffuseAlphaMode() { return (U8)mComboAlpha->getCurrentIndex(); } +// // // Methods @@ -136,55 +122,86 @@ F32 LLPanelFace::getCurrentShinyOffsetV() { return getChild("shinyOf BOOL LLPanelFace::postBuild() { - childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this); - childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); - childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this); - childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("flipTextureScaleU", boost::bind(&LLPanelFace::onCommitFlip, this, true)); - childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("flipTextureScaleV", boost::bind(&LLPanelFace::onCommitFlip, this, false)); - childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this); - childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this); - childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this); + // Media button caching + mMediaInfo = getChildView("media_info"); + mMediaAdd = getChildView("add_media"); + mMediaDelete = getChildView("delete_media"); - childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this); - childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this); - childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterialBumpyRot, this); - childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterialBumpyOffsetX, this); - childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterialBumpyOffsetY, this); - childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterialShinyScaleX, this); - childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterialShinyScaleY, this); - childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterialShinyRot, this); - childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterialShinyOffsetX, this); - childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterialShinyOffsetY, this); - childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this); - childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this); - childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this); + // Label caching + mLabelGlossy = getChildView("label glossy"); + mLabelEnvironment = getChildView("label environment"); + mLabelShinyColor = getChildView("label shinycolor"); + mLabelAlphaMode = getChildView("label alphamode"); + mLabelMaskCutoff = getChildView("label maskcutoff"); + mLabelBumpy = getChildView("label bumpiness"); + mLabelShiny = getChildView("label shininess"); + mLabelColor = getChildView("color label"); + mLabelGlow = getChildView("glow label"); + mLabelTexGen = getChildView("tex gen"); - childSetAction("button align",&LLPanelFace::onClickAutoFix,this); + // UICtrl Caching + mComboShiny = getChild("combobox shininess"); + mComboBumpy = getChild("combobox bumpiness"); + mComboAlpha = getChild("combobox alphamode"); + mCtrlTexScaleU = getChild("TexScaleU"); + mCtrlFlipTexScaleU = getChild("flipTextureScaleU"); + mCtrlTexScaleV = getChild("TexScaleV"); + mCtrlFlipTexScaleV = getChild("flipTextureScaleV"); + mCtrlTexRot = getChild("TexRot"); + mCtrlRpt = getChild("rptctrl"); + mCtrlPlanar = getChild("checkbox planar align"); + mCtrlTexOffsetU = getChild("TexOffsetU"); + mCtrlTexOffsetV = getChild("TexOffsetV"); + mBumpyScaleU = getChild("bumpyScaleU"); + mBumpyScaleV = getChild("bumpyScaleV"); + mBumpyRot = getChild("bumpyRot"); + mBumpyOffsetU = getChild("bumpyOffsetU"); + mBumpyOffsetV = getChild("bumpyOffsetV"); + mShinyScaleU = getChild("shinyScaleU"); + mShinyScaleV = getChild("shinyScaleV"); + mShinyRot = getChild("shinyRot"); + mShinyOffsetU = getChild("shinyOffsetU"); + mShinyOffsetV = getChild("shinyOffsetV"); + mGlossyCtrl = getChild("glossiness"); + mEnvironmentCtrl = getChild("environment"); + mCtrlMaskCutoff = getChild("maskcutoff"); + mCtrlAlign = getChild("button align"); + mCtrlMapsSync = getChild("checkbox maps sync"); + mCtrlCopy = getChild("copytextures"); + mCtrlPaste = getChild("pastetextures"); - childSetCommitCallback("checkbox maps sync", boost::bind(&LLPanelFace::onClickMapsSync, this)); - childSetAction("copytextures",&LLPanelFace::onClickCopy,this); - childSetAction("pastetextures",&LLPanelFace::onClickPaste,this); + mComboShiny->setCommitCallback(boost::bind(&LLPanelFace::sendShiny, this, boost::bind(&LLSD::asInteger, _2))); + mComboBumpy->setCommitCallback(boost::bind(&LLPanelFace::sendBump, this, boost::bind(&LLSD::asInteger, _2))); + mComboAlpha->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlphaMode, this)); + mCtrlTexScaleU->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this)); + mCtrlFlipTexScaleU->setCommitCallback(boost::bind(&LLPanelFace::onCommitFlip, this, true)); + mCtrlTexScaleV->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this)); + mCtrlFlipTexScaleV->setCommitCallback(boost::bind(&LLPanelFace::onCommitFlip, this, false)); + mCtrlTexRot->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this)); + mCtrlRpt->setCommitCallback(boost::bind(&LLPanelFace::onCommitRepeatsPerMeter, this, _1)); + mCtrlPlanar->setCommitCallback(boost::bind(&LLPanelFace::onCommitPlanarAlign, this)); + mCtrlTexOffsetU->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this)); + mCtrlTexOffsetV->setCommitCallback(boost::bind(&LLPanelFace::onCommitTextureInfo, this)); - LLTextureCtrl* mTextureCtrl; - LLTextureCtrl* mShinyTextureCtrl; - LLTextureCtrl* mBumpyTextureCtrl; - LLColorSwatchCtrl* mColorSwatch; - LLColorSwatchCtrl* mShinyColorSwatch; + mBumpyScaleU->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialBumpyScaleX, this, _2)); + mBumpyScaleV->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialBumpyScaleY, this, _2)); + mBumpyRot->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialBumpyRot, this, _2)); + mBumpyOffsetU->setCommitCallback(boost::bind(LLSelectedTEMaterial::setNormalOffsetX, this, _2)); + mBumpyOffsetV->setCommitCallback(boost::bind(LLSelectedTEMaterial::setNormalOffsetY, this, _2)); + mShinyScaleU->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialShinyScaleX, this, _2)); + mShinyScaleV->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialShinyScaleY, this, _2)); + mShinyRot->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialShinyRot, this, _2)); + mShinyOffsetU->setCommitCallback(boost::bind(LLSelectedTEMaterial::setSpecularOffsetX, this, _2)); + mShinyOffsetV->setCommitCallback(boost::bind(LLSelectedTEMaterial::setSpecularOffsetY, this, _2)); + mGlossyCtrl->setCommitCallback(boost::bind(LLSelectedTEMaterial::setSpecularLightExponent, this, boost::bind(&LLSD::asInteger, _2))); + mEnvironmentCtrl->setCommitCallback(boost::bind(LLSelectedTEMaterial::setEnvironmentIntensity, this, boost::bind(&LLSD::asInteger, _2))); + mCtrlMaskCutoff->setCommitCallback(boost::bind(LLSelectedTEMaterial::setAlphaMaskCutoff, this, boost::bind(&LLSD::asInteger, _2))); - LLComboBox* mComboTexGen; - LLComboBox* mComboMatMedia; - LLComboBox* mComboMatType; + mCtrlAlign->setCommitCallback(boost::bind(&LLPanelFace::onClickAutoFix,this)); - LLCheckBoxCtrl *mCheckFullbright; - - LLTextBox* mLabelColorTransp; - LLSpinCtrl* mCtrlColorTransp; // transparency = 1 - alpha - - LLSpinCtrl* mCtrlGlow; + mCtrlMapsSync->setCommitCallback(boost::bind(&LLPanelFace::onClickMapsSync, this)); + mCtrlCopy->setCommitCallback(boost::bind(&LLPanelFace::onClickCopy,this)); + mCtrlPaste->setCommitCallback(boost::bind(&LLPanelFace::onClickPaste,this)); setMouseOpaque(FALSE); @@ -243,7 +260,7 @@ BOOL LLPanelFace::postBuild() mColorSwatch = getChild("colorswatch"); if(mColorSwatch) { - mColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitColor, this, _2)); + mColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::sendColor, this)); mColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelColor, this, _2)); mColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectColor, this, _2)); mColorSwatch->setFollowsTop(); @@ -270,7 +287,7 @@ BOOL LLPanelFace::postBuild() mCtrlColorTransp = getChild("ColorTrans"); if(mCtrlColorTransp) { - mCtrlColorTransp->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlpha, this, _2)); + mCtrlColorTransp->setCommitCallback(boost::bind(&LLPanelFace::sendAlpha, this)); mCtrlColorTransp->setPrecision(0); mCtrlColorTransp->setFollowsTop(); mCtrlColorTransp->setFollowsLeft(); @@ -279,20 +296,20 @@ BOOL LLPanelFace::postBuild() mCheckFullbright = getChild("checkbox fullbright"); if (mCheckFullbright) { - mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright, this); + mCheckFullbright->setCommitCallback(boost::bind(&LLPanelFace::sendFullbright, this)); } mComboTexGen = getChild("combobox texgen"); if(mComboTexGen) { - mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen, this); + mComboTexGen->setCommitCallback(boost::bind(&LLPanelFace::sendTexGen, this)); mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); } mComboMatMedia = getChild("combobox matmedia"); if(mComboMatMedia) { - mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this); + mComboMatMedia->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialsMedia,this)); mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); } @@ -306,7 +323,7 @@ BOOL LLPanelFace::postBuild() mCtrlGlow = getChild("glow"); if(mCtrlGlow) { - mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this); + mCtrlGlow->setCommitCallback(boost::bind(&LLPanelFace::sendGlow, this)); } @@ -317,6 +334,62 @@ BOOL LLPanelFace::postBuild() LLPanelFace::LLPanelFace(const std::string& name) : LLPanel(name), +// + mMediaInfo(NULL), + mMediaAdd(NULL), + mMediaDelete(NULL), + mLabelGlossy(NULL), + mLabelEnvironment(NULL), + mLabelShinyColor(NULL), + mLabelAlphaMode(NULL), + mLabelMaskCutoff(NULL), + mLabelBumpy(NULL), + mLabelShiny(NULL), + mLabelColor(NULL), + mLabelGlow(NULL), + mLabelTexGen(NULL), + mComboShiny(NULL), + mComboBumpy(NULL), + mComboAlpha(NULL), + mCtrlTexScaleU(NULL), + mCtrlFlipTexScaleU(NULL), + mCtrlTexScaleV(NULL), + mCtrlFlipTexScaleV(NULL), + mCtrlTexRot(NULL), + mCtrlRpt(NULL), + mCtrlPlanar(NULL), + mCtrlTexOffsetU(NULL), + mCtrlTexOffsetV(NULL), + mBumpyScaleU(NULL), + mBumpyScaleV(NULL), + mBumpyRot(NULL), + mBumpyOffsetU(NULL), + mBumpyOffsetV(NULL), + mShinyScaleU(NULL), + mShinyScaleV(NULL), + mShinyRot(NULL), + mShinyOffsetU(NULL), + mShinyOffsetV(NULL), + mGlossyCtrl(NULL), + mEnvironmentCtrl(NULL), + mCtrlMaskCutoff(NULL), + mCtrlAlign(NULL), + mCtrlMapsSync(NULL), + mCtrlCopy(NULL), + mCtrlPaste(NULL), + mTextureCtrl(NULL), + mShinyTextureCtrl(NULL), + mBumpyTextureCtrl(NULL), + mColorSwatch(NULL), + mShinyColorSwatch(NULL), + mComboTexGen(NULL), + mComboMatMedia(NULL), + mComboMatType(NULL), + mCheckFullbright(NULL), + mLabelColorTransp(NULL), + mCtrlColorTransp(NULL), // transparency = 1 - alpha + mCtrlGlow(NULL), +// mIsAlpha(false) { USE_TEXTURE = LLTrans::getString("use_texture"); @@ -331,7 +404,6 @@ LLPanelFace::~LLPanelFace() void LLPanelFace::sendTexture() { - LLTextureCtrl* mTextureCtrl = getChild("texture control"); if(!mTextureCtrl) return; if( !mTextureCtrl->getTentative() ) { @@ -348,7 +420,7 @@ void LLPanelFace::sendTexture() void LLPanelFace::sendBump(U32 bumpiness) { - LLTextureCtrl* bumpytexture_ctrl = getChild("bumpytexture control"); + LLTextureCtrl* bumpytexture_ctrl = mBumpyTextureCtrl; if (bumpiness < BUMPY_TEXTURE) { LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL; @@ -376,7 +448,6 @@ void LLPanelFace::sendBump(U32 bumpiness) void LLPanelFace::sendTexGen() { - LLComboBox* mComboTexGen = getChild("combobox texgen"); if(!mComboTexGen)return; U8 tex_gen = (U8) mComboTexGen->getCurrentIndex() << TEM_TEX_GEN_SHIFT; LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen ); @@ -384,7 +455,7 @@ void LLPanelFace::sendTexGen() void LLPanelFace::sendShiny(U32 shininess) { - LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); + LLTextureCtrl* texture_ctrl = mShinyTextureCtrl; if (shininess < SHINY_TEXTURE) { @@ -408,7 +479,6 @@ void LLPanelFace::sendShiny(U32 shininess) void LLPanelFace::sendFullbright() { - LLCheckBoxCtrl* mCheckFullbright = getChild("checkbox fullbright"); if(!mCheckFullbright)return; U8 fullbright = mCheckFullbright->get() ? TEM_FULLBRIGHT_MASK : 0; LLSelectMgr::getInstance()->selectionSetFullbright( fullbright ); @@ -416,7 +486,6 @@ void LLPanelFace::sendFullbright() void LLPanelFace::sendColor() { - LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch"); if(!mColorSwatch)return; LLColor4 color = mColorSwatch->get(); @@ -425,7 +494,6 @@ void LLPanelFace::sendColor() void LLPanelFace::sendAlpha() { - LLSpinCtrl* mCtrlColorTransp = getChild("ColorTrans"); if(!mCtrlColorTransp)return; F32 alpha = (100.f - mCtrlColorTransp->get()) / 100.f; @@ -435,7 +503,6 @@ void LLPanelFace::sendAlpha() void LLPanelFace::sendGlow() { - LLSpinCtrl* mCtrlGlow = getChild("glow"); llassert(mCtrlGlow); if (mCtrlGlow) { @@ -451,12 +518,12 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor { BOOL valid; F32 value; - LLSpinCtrl* ctrlTexScaleS = mPanel->getChild("TexScaleU"); - LLSpinCtrl* ctrlTexScaleT = mPanel->getChild("TexScaleV"); - LLSpinCtrl* ctrlTexOffsetS = mPanel->getChild("TexOffsetU"); - LLSpinCtrl* ctrlTexOffsetT = mPanel->getChild("TexOffsetV"); - LLSpinCtrl* ctrlTexRotation = mPanel->getChild("TexRot"); - LLComboBox* comboTexGen = mPanel->getChild("combobox texgen"); + LLSpinCtrl* ctrlTexScaleS = mPanel->mCtrlTexScaleU; + LLSpinCtrl* ctrlTexScaleT = mPanel->mCtrlTexScaleV; + LLSpinCtrl* ctrlTexOffsetS = mPanel->mCtrlTexOffsetU; + LLSpinCtrl* ctrlTexOffsetT = mPanel->mCtrlTexOffsetV; + LLSpinCtrl* ctrlTexRotation = mPanel->mCtrlTexRot; + LLComboBox* comboTexGen = mPanel->mComboTexGen; llassert(comboTexGen); llassert(object); @@ -634,7 +701,7 @@ struct LLPanelFaceSendFunctor : public LLSelectedObjectFunctor void LLPanelFace::sendTextureInfo() { - if ((bool)childGetValue("checkbox planar align").asBoolean()) + if ((bool)mCtrlPlanar->getValue().asBoolean()) { LLFace* last_face = NULL; bool identical_face = false; @@ -668,17 +735,17 @@ void LLPanelFace::updateUI() BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced(); // only turn on auto-adjust button if there is a media renderer and the media is loaded - getChildView("button align")->setEnabled(editable); + mCtrlAlign->setEnabled(editable); bool enable_material_controls = (!gSavedSettings.getBOOL("FSSynchronizeTextureMaps")); S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME )) && (selected_count == 1); - getChildView("copytextures")->setEnabled(single_volume && editable); - getChildView("pastetextures")->setEnabled(editable); + mCtrlCopy->setEnabled(single_volume && editable); + mCtrlPaste->setEnabled(editable); - LLComboBox* combobox_matmedia = getChild("combobox matmedia"); + LLComboBox* combobox_matmedia = mComboMatMedia; if (combobox_matmedia) { if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL) @@ -686,13 +753,9 @@ void LLPanelFace::updateUI() combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL); } } - else - { - LL_WARNS("Materials") << "failed getChild for 'combobox matmedia'" << LL_ENDL; - } - getChildView("combobox matmedia")->setEnabled(editable); + mComboMatMedia->setEnabled(editable); - LLComboBox* combobox_mattype = getChild("combobox mattype"); + LLComboBox* combobox_mattype = mComboMatType; if (combobox_mattype) { if (combobox_mattype->getCurrentIndex() < MATTYPE_DIFFUSE) @@ -700,11 +763,7 @@ void LLPanelFace::updateUI() combobox_mattype->selectNthItem(MATTYPE_DIFFUSE); } } - else - { - LL_WARNS("Materials") << "failed getChild for 'combobox mattype'" << LL_ENDL; - } - getChildView("combobox mattype")->setEnabled(editable); + mComboMatType->setEnabled(editable); updateVisibility(); @@ -713,11 +772,11 @@ void LLPanelFace::updateUI() bool identical_norm = false; bool identical_spec = false; - LLTextureCtrl* texture_ctrl = getChild("texture control"); + LLTextureCtrl* texture_ctrl = mTextureCtrl; texture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null. - LLTextureCtrl* shinytexture_ctrl = getChild("shinytexture control"); + LLTextureCtrl* shinytexture_ctrl = mShinyTextureCtrl; shinytexture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null. - LLTextureCtrl* bumpytexture_ctrl = getChild("bumpytexture control"); + LLTextureCtrl* bumpytexture_ctrl = mBumpyTextureCtrl; bumpytexture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null. LLUUID id; @@ -726,9 +785,8 @@ void LLPanelFace::updateUI() // Color swatch { - getChildView("color label")->setEnabled(editable); + mLabelColor->setEnabled(editable); } - LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch"); LLColor4 color = LLColor4::white; bool identical_color =false; @@ -746,11 +804,11 @@ void LLPanelFace::updateUI() } // Color transparency - getChildView("color trans")->setEnabled(editable); + mLabelColorTransp->setEnabled(editable); F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; - getChild("ColorTrans")->setValue(editable ? transparency : 0); - getChildView("ColorTrans")->setEnabled(editable); + mCtrlColorTransp->setValue(editable ? transparency : 0); + mCtrlColorTransp->setEnabled(editable); // Specular map LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec); @@ -764,28 +822,26 @@ void LLPanelFace::updateUI() shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE; - LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess"); - if (combobox_shininess) + if (mComboShiny) { - combobox_shininess->selectNthItem((S32)shiny); + mComboShiny->selectNthItem((S32)shiny); } - getChildView("label shininess")->setEnabled(editable); - getChildView("combobox shininess")->setEnabled(editable); + mLabelShiny->setEnabled(editable); + mComboShiny->setEnabled(editable); - getChildView("label glossiness")->setEnabled(editable); - getChildView("glossiness")->setEnabled(editable); + mLabelGlossy->setEnabled(editable); + mGlossyCtrl->setEnabled(editable); - getChildView("label environment")->setEnabled(editable); - getChildView("environment")->setEnabled(editable); - getChildView("label shinycolor")->setEnabled(editable); + mLabelEnvironment->setEnabled(editable); + mEnvironmentCtrl->setEnabled(editable); + mLabelShinyColor->setEnabled(editable); - getChild("combobox shininess")->setTentative(!identical_spec); - getChild("glossiness")->setTentative(!identical_spec); - getChild("environment")->setTentative(!identical_spec); - getChild("shinycolorswatch")->setTentative(!identical_spec); + mComboShiny->setTentative(!identical_spec); + mGlossyCtrl->setTentative(!identical_spec); + mEnvironmentCtrl->setTentative(!identical_spec); + mShinyColorSwatch->setTentative(!identical_spec); - LLColorSwatchCtrl* mShinyColorSwatch = getChild("shinycolorswatch"); if(mShinyColorSwatch) { mShinyColorSwatch->setValid(editable); @@ -800,7 +856,7 @@ void LLPanelFace::updateUI() LLSelectedTE::getBumpmap(bumpy,identical_bumpy); LLUUID norm_map_id = getCurrentNormalMap(); - LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness"); + LLCtrlSelectionInterface* combobox_bumpiness = mComboBumpy; bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE; @@ -808,14 +864,10 @@ void LLPanelFace::updateUI() { combobox_bumpiness->selectNthItem((S32)bumpy); } - else - { - llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl; - } - getChildView("combobox bumpiness")->setEnabled(editable); - getChild("combobox bumpiness")->setTentative(!identical_bumpy); - getChildView("label bumpiness")->setEnabled(editable); + mComboBumpy->setEnabled(editable); + mComboBumpy->setTentative(!identical_bumpy); + mLabelBumpy->setEnabled(editable); } // Texture @@ -850,7 +902,7 @@ void LLPanelFace::updateUI() if(LLViewerMedia::textureHasMedia(id)) { - getChildView("button align")->setEnabled(editable); + mCtrlAlign->setEnabled(editable); } // Diffuse Alpha Mode @@ -865,7 +917,7 @@ void LLPanelFace::updateUI() // LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha); - LLCtrlSelectionInterface* combobox_alphamode = childGetSelectionInterface("combobox alphamode"); + LLCtrlSelectionInterface* combobox_alphamode = mComboAlpha; if (combobox_alphamode) { //it is invalid to have any alpha mode other than blend if transparency is greater than zero ... @@ -877,10 +929,6 @@ void LLPanelFace::updateUI() combobox_alphamode->selectNthItem(alpha_mode); } - else - { - LL_WARNS("Materials") << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL; - } updateAlphaControls(); @@ -891,10 +939,10 @@ void LLPanelFace::updateUI() texture_ctrl->setTentative( FALSE ); texture_ctrl->setEnabled( editable ); texture_ctrl->setImageAssetID( id ); - getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); - getChildView("label alphamode")->setEnabled(editable && mIsAlpha); - getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); - getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + mComboAlpha->setEnabled(editable && mIsAlpha && transparency <= 0.f); + mLabelAlphaMode->setEnabled(editable && mIsAlpha); + mCtrlMaskCutoff->setEnabled(editable && mIsAlpha); + mLabelMaskCutoff->setEnabled(editable && mIsAlpha); } else if (id.isNull()) { @@ -902,10 +950,10 @@ void LLPanelFace::updateUI() texture_ctrl->setTentative( FALSE ); texture_ctrl->setEnabled( FALSE ); texture_ctrl->setImageAssetID( LLUUID::null ); - getChildView("combobox alphamode")->setEnabled( FALSE ); - getChildView("label alphamode")->setEnabled( FALSE ); - getChildView("maskcutoff")->setEnabled( FALSE); - getChildView("label maskcutoff")->setEnabled( FALSE ); + mComboAlpha->setEnabled( FALSE ); + mLabelAlphaMode->setEnabled( FALSE ); + mCtrlMaskCutoff->setEnabled( FALSE); + mLabelMaskCutoff->setEnabled( FALSE ); } else { @@ -913,10 +961,10 @@ void LLPanelFace::updateUI() texture_ctrl->setTentative( TRUE ); texture_ctrl->setEnabled( editable ); texture_ctrl->setImageAssetID( id ); - getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); - getChildView("label alphamode")->setEnabled(editable && mIsAlpha); - getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); - getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + mComboAlpha->setEnabled(editable && mIsAlpha && transparency <= 0.f); + mLabelAlphaMode->setEnabled(editable && mIsAlpha); + mCtrlMaskCutoff->setEnabled(editable && mIsAlpha); + mLabelMaskCutoff->setEnabled(editable && mIsAlpha); } } @@ -969,12 +1017,12 @@ void LLPanelFace::updateUI() bool align_planar = false; bool identical_planar_aligned = false; { - LLCheckBoxCtrl* cb_planar_align = getChild("checkbox planar align"); - align_planar = (cb_planar_align && cb_planar_align->get()); + LLUICtrl* cb_planar_align = mCtrlPlanar; + align_planar = (cb_planar_align && cb_planar_align->getValue().asBoolean()); bool enabled = (editable && isIdenticalPlanarTexgen()); - childSetValue("checkbox planar align", align_planar && enabled); - childSetEnabled("checkbox planar align", enabled); + mCtrlPlanar->setValue(align_planar && enabled); + mCtrlPlanar->setEnabled(enabled); if (align_planar && enabled) { @@ -1026,26 +1074,26 @@ void LLPanelFace::updateUI() spec_scale_s = editable ? spec_scale_s : 1.0f; spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; - getChild("TexScaleU")->setValue(diff_scale_s); - getChild("shinyScaleU")->setValue(spec_scale_s); - getChild("bumpyScaleU")->setValue(norm_scale_s); + mCtrlTexScaleU->setValue(diff_scale_s); + mShinyScaleU->setValue(spec_scale_s); + mBumpyScaleU->setValue(norm_scale_s); - getChildView("TexScaleU")->setEnabled(editable); - getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull() + mCtrlTexScaleU->setEnabled(editable); + mShinyScaleU->setEnabled(editable && specmap_id.notNull() && enable_material_controls); // Materials alignment - getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull() + mBumpyScaleU->setEnabled(editable && normmap_id.notNull() && enable_material_controls); // Materials alignment BOOL diff_scale_tentative = !(identical && identical_diff_scale_s); BOOL norm_scale_tentative = !(identical && identical_norm_scale_s); BOOL spec_scale_tentative = !(identical && identical_spec_scale_s); - getChild("TexScaleU")->setTentative( LLSD(diff_scale_tentative)); - getChild("shinyScaleU")->setTentative(LLSD(spec_scale_tentative)); - getChild("bumpyScaleU")->setTentative(LLSD(norm_scale_tentative)); + mCtrlTexScaleU->setTentative( LLSD(diff_scale_tentative)); + mShinyScaleU->setTentative(LLSD(spec_scale_tentative)); + mBumpyScaleU->setTentative(LLSD(norm_scale_tentative)); // FIRE-11407 - Materials alignment - getChildView("checkbox maps sync")->setEnabled(editable && (specmap_id.notNull() || normmap_id.notNull())); + mCtrlMapsSync->setEnabled(editable && (specmap_id.notNull() || normmap_id.notNull())); // } @@ -1075,19 +1123,19 @@ void LLPanelFace::updateUI() BOOL norm_scale_tentative = !identical_norm_scale_t; BOOL spec_scale_tentative = !identical_spec_scale_t; - getChildView("TexScaleV")->setEnabled(editable); - getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull() + mCtrlTexScaleV->setEnabled(editable); + mShinyScaleV->setEnabled(editable && specmap_id.notNull() && enable_material_controls); // Materials alignment - getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull() + mBumpyScaleV->setEnabled(editable && normmap_id.notNull() && enable_material_controls); // Materials alignment - getChild("TexScaleV")->setValue(diff_scale_t); - getChild("shinyScaleV")->setValue(norm_scale_t); - getChild("bumpyScaleV")->setValue(spec_scale_t); + mCtrlTexScaleV->setValue(diff_scale_t); + mShinyScaleV->setValue(norm_scale_t); + mBumpyScaleV->setValue(spec_scale_t); - getChild("TexScaleV")->setTentative(LLSD(diff_scale_tentative)); - getChild("shinyScaleV")->setTentative(LLSD(norm_scale_tentative)); - getChild("bumpyScaleV")->setTentative(LLSD(spec_scale_tentative)); + mCtrlTexScaleV->setTentative(LLSD(diff_scale_tentative)); + mShinyScaleV->setTentative(LLSD(norm_scale_tentative)); + mBumpyScaleV->setTentative(LLSD(spec_scale_tentative)); } // Texture offset @@ -1108,18 +1156,18 @@ void LLPanelFace::updateUI() BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s); BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s); - getChild("TexOffsetU")->setValue( editable ? diff_offset_s : 0.0f); - getChild("bumpyOffsetU")->setValue(editable ? norm_offset_s : 0.0f); - getChild("shinyOffsetU")->setValue(editable ? spec_offset_s : 0.0f); + mCtrlTexOffsetU->setValue( editable ? diff_offset_s : 0.0f); + mBumpyOffsetU->setValue(editable ? norm_offset_s : 0.0f); + mShinyOffsetU->setValue(editable ? spec_offset_s : 0.0f); - getChild("TexOffsetU")->setTentative(LLSD(diff_offset_u_tentative)); - getChild("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative)); - getChild("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative)); + mCtrlTexOffsetU->setTentative(LLSD(diff_offset_u_tentative)); + mShinyOffsetU->setTentative(LLSD(norm_offset_u_tentative)); + mBumpyOffsetU->setTentative(LLSD(spec_offset_u_tentative)); - getChildView("TexOffsetU")->setEnabled(editable); - getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull() + mCtrlTexOffsetU->setEnabled(editable); + mShinyOffsetU->setEnabled(editable && specmap_id.notNull() && enable_material_controls); // Materials alignment - getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull() + mBumpyOffsetU->setEnabled(editable && normmap_id.notNull() && enable_material_controls); // Materials alignment } @@ -1140,18 +1188,18 @@ void LLPanelFace::updateUI() BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t); BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t); - getChild("TexOffsetV")->setValue( editable ? diff_offset_t : 0.0f); - getChild("bumpyOffsetV")->setValue(editable ? norm_offset_t : 0.0f); - getChild("shinyOffsetV")->setValue(editable ? spec_offset_t : 0.0f); + mCtrlTexOffsetV->setValue( editable ? diff_offset_t : 0.0f); + mBumpyOffsetV->setValue(editable ? norm_offset_t : 0.0f); + mShinyOffsetV->setValue(editable ? spec_offset_t : 0.0f); - getChild("TexOffsetV")->setTentative(LLSD(diff_offset_v_tentative)); - getChild("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative)); - getChild("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative)); + mCtrlTexOffsetV->setTentative(LLSD(diff_offset_v_tentative)); + mShinyOffsetV->setTentative(LLSD(norm_offset_v_tentative)); + mBumpyOffsetV->setTentative(LLSD(spec_offset_v_tentative)); - getChildView("TexOffsetV")->setEnabled(editable); - getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull() + mCtrlTexOffsetV->setEnabled(editable); + mShinyOffsetV->setEnabled(editable && specmap_id.notNull() && enable_material_controls); // Materials alignment - getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull() + mBumpyOffsetV->setEnabled(editable && normmap_id.notNull() && enable_material_controls); // Materials alignment } @@ -1177,47 +1225,44 @@ void LLPanelFace::updateUI() F32 norm_rot_deg = norm_rotation * RAD_TO_DEG; F32 spec_rot_deg = spec_rotation * RAD_TO_DEG; - getChildView("TexRot")->setEnabled(editable); - getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull() + mCtrlTexRot->setEnabled(editable); + mShinyRot->setEnabled(editable && specmap_id.notNull() && enable_material_controls); // Materials alignment - getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull() + mBumpyRot->setEnabled(editable && normmap_id.notNull() && enable_material_controls); // Materials alignment - getChild("TexRot")->setTentative(diff_rot_tentative); - getChild("shinyRot")->setTentative(LLSD(norm_rot_tentative)); - getChild("bumpyRot")->setTentative(LLSD(spec_rot_tentative)); + mCtrlTexRot->setTentative(diff_rot_tentative); + mShinyRot->setTentative(LLSD(norm_rot_tentative)); + mBumpyRot->setTentative(LLSD(spec_rot_tentative)); - getChild("TexRot")->setValue( editable ? diff_rot_deg : 0.0f); - getChild("shinyRot")->setValue(editable ? spec_rot_deg : 0.0f); - getChild("bumpyRot")->setValue(editable ? norm_rot_deg : 0.0f); + mCtrlTexRot->setValue( editable ? diff_rot_deg : 0.0f); + mShinyRot->setValue(editable ? spec_rot_deg : 0.0f); + mBumpyRot->setValue(editable ? norm_rot_deg : 0.0f); } { F32 glow = 0.f; bool identical_glow = false; LLSelectedTE::getGlow(glow,identical_glow); - getChild("glow")->setValue(glow); - getChild("glow")->setTentative(!identical_glow); - getChildView("glow")->setEnabled(editable); - getChildView("glow label")->setEnabled(editable); + mCtrlGlow->setValue(glow); + mCtrlGlow->setTentative(!identical_glow); + mCtrlGlow->setEnabled(editable); + mLabelGlow->setEnabled(editable); } { - LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen"); + LLCtrlSelectionInterface* combobox_texgen = mComboTexGen; if (combobox_texgen) { // Maps from enum to combobox entry index combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1); } - else - { - llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl; - } - getChildView("combobox texgen")->setEnabled(editable); - getChild("combobox texgen")->setTentative(!identical); - getChildView("tex gen")->setEnabled(editable); + mComboTexGen->setEnabled(editable); + mComboTexGen->setTentative(!identical); + mLabelTexGen->setEnabled(editable); + /* Singu Note: Dead code if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR) { // EXP-1507 (change label based on the mapping mode) @@ -1228,6 +1273,7 @@ void LLPanelFace::updateUI() { getChild("rpt")->setValue(getString("string repeats per face")); } + */ } { @@ -1236,9 +1282,9 @@ void LLPanelFace::updateUI() LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright); - getChild("checkbox fullbright")->setValue((S32)(fullbright_flag != 0)); - getChildView("checkbox fullbright")->setEnabled(editable); - getChild("checkbox fullbright")->setTentative(!identical_fullbright); + mCheckFullbright->setValue((S32)(fullbright_flag != 0)); + mCheckFullbright->setEnabled(editable); + mCheckFullbright->setTentative(!identical_fullbright); } @@ -1256,7 +1302,6 @@ void LLPanelFace::updateUI() LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats); LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats); - LLComboBox* mComboTexGen = getChild("combobox texgen"); if (mComboTexGen) { S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; @@ -1300,13 +1345,13 @@ void LLPanelFace::updateUI() BOOL repeats_tentative = !identical_repeats; - getChildView("rptctrl")->setEnabled(identical_planar_texgen ? FALSE : enabled); - getChild("rptctrl")->setValue(editable ? repeats : 1.0f); - getChild("rptctrl")->setTentative(LLSD(repeats_tentative)); + mCtrlRpt->setEnabled(identical_planar_texgen ? FALSE : enabled); + mCtrlRpt->setValue(editable ? repeats : 1.0f); + mCtrlRpt->setTentative(LLSD(repeats_tentative)); // FIRE-11407 - Flip buttons - getChildView("flipTextureScaleU")->setEnabled(enabled); - getChildView("flipTextureScaleV")->setEnabled(enabled); + mCtrlFlipTexScaleU->setEnabled(enabled); + mCtrlFlipTexScaleV->setEnabled(enabled); // } } @@ -1318,11 +1363,11 @@ void LLPanelFace::updateUI() if (material && editable) { - LL_DEBUGS("Materials: OnMatererialsLoaded:") << material->asLLSD() << LL_ENDL; + LL_DEBUGS("Materials: OnMaterialsLoaded:") << material->asLLSD() << LL_ENDL; // Alpha LLCtrlSelectionInterface* combobox_alphamode = - childGetSelectionInterface("combobox alphamode"); + mComboAlpha; if (combobox_alphamode) { U32 alpha_mode = material->getDiffuseAlphaMode(); @@ -1339,18 +1384,14 @@ void LLPanelFace::updateUI() combobox_alphamode->selectNthItem(alpha_mode); } - else - { - llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl; - } - getChild("maskcutoff")->setValue(material->getAlphaMaskCutoff()); + mCtrlMaskCutoff->setValue(material->getAlphaMaskCutoff()); updateAlphaControls(); identical_planar_texgen = isIdenticalPlanarTexgen(); // Shiny (specular) F32 offset_x, offset_y, repeat_x, repeat_y, rot; - LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); + LLTextureCtrl* texture_ctrl = mShinyTextureCtrl; texture_ctrl->setImageAssetID(material->getSpecularID()); if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE)) @@ -1365,13 +1406,13 @@ void LLPanelFace::updateUI() } rot = material->getSpecularRotation(); - getChild("shinyScaleU")->setValue(repeat_x); - getChild("shinyScaleV")->setValue(repeat_y); - getChild("shinyRot")->setValue(rot*RAD_TO_DEG); - getChild("shinyOffsetU")->setValue(offset_x); - getChild("shinyOffsetV")->setValue(offset_y); - getChild("glossiness")->setValue(material->getSpecularLightExponent()); - getChild("environment")->setValue(material->getEnvironmentIntensity()); + mShinyScaleU->setValue(repeat_x); + mShinyScaleV->setValue(repeat_y); + mShinyRot->setValue(rot*RAD_TO_DEG); + mShinyOffsetU->setValue(offset_x); + mShinyOffsetV->setValue(offset_y); + mGlossyCtrl->setValue(material->getSpecularLightExponent()); + mEnvironmentCtrl->setValue(material->getEnvironmentIntensity()); updateShinyControls(!material->getSpecularID().isNull(), true); } @@ -1381,12 +1422,12 @@ void LLPanelFace::updateUI() // if (!material->getSpecularID().isNull()) { - getChild("shinycolorswatch")->setOriginal(material->getSpecularLightColor()); - getChild("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE); + mShinyColorSwatch->setOriginal(material->getSpecularLightColor()); + mShinyColorSwatch->set(material->getSpecularLightColor(),TRUE); } // Bumpy (normal) - texture_ctrl = getChild("bumpytexture control"); + texture_ctrl = mBumpyTextureCtrl; texture_ctrl->setImageAssetID(material->getNormalID()); if (!material->getNormalID().isNull()) @@ -1401,11 +1442,11 @@ void LLPanelFace::updateUI() } rot = material->getNormalRotation(); - getChild("bumpyScaleU")->setValue(repeat_x); - getChild("bumpyScaleV")->setValue(repeat_y); - getChild("bumpyRot")->setValue(rot*RAD_TO_DEG); - getChild("bumpyOffsetU")->setValue(offset_x); - getChild("bumpyOffsetV")->setValue(offset_y); + mBumpyScaleU->setValue(repeat_x); + mBumpyScaleV->setValue(repeat_y); + mBumpyRot->setValue(rot*RAD_TO_DEG); + mBumpyOffsetU->setValue(offset_x); + mBumpyOffsetV->setValue(offset_y); updateBumpyControls(!material->getNormalID().isNull(), true); } @@ -1414,13 +1455,13 @@ void LLPanelFace::updateUI() // Set variable values for numeric expressions LLCalc* calcp = LLCalc::getInstance(); - calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal()); - calcp->setVar(LLCalc::TEX_V_SCALE, childGetValue("TexScaleV").asReal()); - calcp->setVar(LLCalc::TEX_U_OFFSET, childGetValue("TexOffsetU").asReal()); - calcp->setVar(LLCalc::TEX_V_OFFSET, childGetValue("TexOffsetV").asReal()); - calcp->setVar(LLCalc::TEX_ROTATION, childGetValue("TexRot").asReal()); - calcp->setVar(LLCalc::TEX_TRANSPARENCY, childGetValue("ColorTrans").asReal()); - calcp->setVar(LLCalc::TEX_GLOW, childGetValue("glow").asReal()); + calcp->setVar(LLCalc::TEX_U_SCALE, mCtrlTexScaleU->getValue().asReal()); + calcp->setVar(LLCalc::TEX_V_SCALE, mCtrlTexScaleV->getValue().asReal()); + calcp->setVar(LLCalc::TEX_U_OFFSET, mCtrlTexOffsetU->getValue().asReal()); + calcp->setVar(LLCalc::TEX_V_OFFSET, mCtrlTexOffsetV->getValue().asReal()); + calcp->setVar(LLCalc::TEX_ROTATION, mCtrlTexRot->getValue().asReal()); + calcp->setVar(LLCalc::TEX_TRANSPARENCY, mCtrlColorTransp->getValue().asReal()); + calcp->setVar(LLCalc::TEX_GLOW, mCtrlGlow->getValue().asReal()); } else { @@ -1428,27 +1469,28 @@ void LLPanelFace::updateUI() clearCtrls(); // Disable non-UICtrls - LLTextureCtrl* texture_ctrl = getChild("texture control"); + LLTextureCtrl* texture_ctrl = mTextureCtrl; if(texture_ctrl) { texture_ctrl->setImageAssetID( LLUUID::null ); texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl. // texture_ctrl->setValid(FALSE); } - LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch"); if(mColorSwatch) { mColorSwatch->setEnabled( FALSE ); mColorSwatch->setFallbackImageName("locked_image.j2c" ); mColorSwatch->setValid(FALSE); } - getChildView("color trans")->setEnabled(FALSE); + mLabelColorTransp->setEnabled(FALSE); + /* Singu Note: This is missing in xml getChildView("rpt")->setEnabled(FALSE); getChildView("tex offset")->setEnabled(FALSE); - getChildView("tex gen")->setEnabled(FALSE); - getChildView("label shininess")->setEnabled(FALSE); - getChildView("label bumpiness")->setEnabled(FALSE); - getChildView("button align")->setEnabled(FALSE); + */ + mLabelTexGen->setEnabled(FALSE); + mLabelShiny->setEnabled(FALSE); + mLabelBumpy->setEnabled(FALSE); + mCtrlAlign->setEnabled(FALSE); //getChildView("has media")->setEnabled(FALSE); //getChildView("media info set")->setEnabled(FALSE); @@ -1484,19 +1526,9 @@ F32 LLPanelFace::valueGlow(LLViewerObject* object, S32 face) } -void LLPanelFace::onCommitColor(const LLSD& data) -{ - sendColor(); -} - void LLPanelFace::onCommitShinyColor(const LLSD& data) { - LLSelectedTEMaterial::setSpecularLightColor(this, getChild("shinycolorswatch")->get()); -} - -void LLPanelFace::onCommitAlpha(const LLSD& data) -{ - sendAlpha(); + LLSelectedTEMaterial::setSpecularLightColor(this, mShinyColorSwatch->get()); } void LLPanelFace::onCancelColor(const LLSD& data) @@ -1510,25 +1542,23 @@ void LLPanelFace::onSelectColor(const LLSD& data) sendColor(); } -// static -void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitMaterialsMedia() { - LLPanelFace* self = (LLPanelFace*) userdata; // Force to default states to side-step problems with menu contents // and generally reflecting old state when switching tabs or objects // - self->updateShinyControls(false,true); - self->updateBumpyControls(false,true); - self->updateUI(); + updateShinyControls(false,true); + updateBumpyControls(false,true); + updateUI(); } // static void LLPanelFace::updateVisibility() { - LLComboBox* combo_matmedia = getChild("combobox matmedia"); - LLComboBox* combo_mattype = getChild("combobox mattype"); - LLComboBox* combo_shininess = getChild("combobox shininess"); - LLComboBox* combo_bumpiness = getChild("combobox bumpiness"); + LLComboBox* combo_matmedia = mComboMatMedia; + LLComboBox* combo_mattype = mComboMatType; + LLComboBox* combo_shininess = mComboShiny; + LLComboBox* combo_bumpiness = mComboBumpy; if (!combo_mattype || !combo_matmedia || !combo_shininess || !combo_bumpiness) { LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL; @@ -1540,70 +1570,70 @@ void LLPanelFace::updateVisibility() bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled())); bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled(); bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); - getChildView("combobox mattype")->setVisible(!show_media); + mComboMatType->setVisible(!show_media); // FIRE-11407 - Be consistant and hide this with the other controls - //getChildView("rptctrl")->setVisible(true); - getChildView("rptctrl")->setVisible(combo_matmedia->getEnabled()); + //mCtrlRpt->setVisible(true); + mCtrlRpt->setVisible(combo_matmedia->getEnabled()); // and other additions... - getChildView("flipTextureScaleU")->setVisible(combo_matmedia->getEnabled()); - getChildView("flipTextureScaleV")->setVisible(combo_matmedia->getEnabled()); + mCtrlFlipTexScaleU->setVisible(combo_matmedia->getEnabled()); + mCtrlFlipTexScaleV->setVisible(combo_matmedia->getEnabled()); // // Media controls - getChildView("media_info")->setVisible(show_media); - getChildView("add_media")->setVisible(show_media); - getChildView("delete_media")->setVisible(show_media); - getChildView("button align")->setVisible(show_media); + mMediaInfo->setVisible(show_media); + mMediaAdd->setVisible(show_media); + mMediaDelete->setVisible(show_media); + mCtrlAlign->setVisible(show_media); // Diffuse texture controls - getChildView("texture control")->setVisible(show_texture && !show_media); - getChildView("label alphamode")->setVisible(show_texture && !show_media); - getChildView("combobox alphamode")->setVisible(show_texture && !show_media); - getChildView("label maskcutoff")->setVisible(false); - getChildView("maskcutoff")->setVisible(false); + mTextureCtrl->setVisible(show_texture && !show_media); + mLabelAlphaMode->setVisible(show_texture && !show_media); + mComboAlpha->setVisible(show_texture && !show_media); + mLabelMaskCutoff->setVisible(false); + mCtrlMaskCutoff->setVisible(false); if (show_texture && !show_media) { updateAlphaControls(); } - getChildView("TexScaleU")->setVisible(show_texture); - getChildView("TexScaleV")->setVisible(show_texture); - getChildView("TexRot")->setVisible(show_texture); - getChildView("TexOffsetU")->setVisible(show_texture); - getChildView("TexOffsetV")->setVisible(show_texture); + mCtrlTexScaleU->setVisible(show_texture); + mCtrlTexScaleV->setVisible(show_texture); + mCtrlTexRot->setVisible(show_texture); + mCtrlTexOffsetU->setVisible(show_texture); + mCtrlTexOffsetV->setVisible(show_texture); // Specular map controls - getChildView("shinytexture control")->setVisible(show_shininess); - getChildView("combobox shininess")->setVisible(show_shininess); - getChildView("label shininess")->setVisible(show_shininess); - getChildView("label glossiness")->setVisible(false); - getChildView("glossiness")->setVisible(false); - getChildView("label environment")->setVisible(false); - getChildView("environment")->setVisible(false); - getChildView("label shinycolor")->setVisible(false); - getChildView("shinycolorswatch")->setVisible(false); + mShinyTextureCtrl->setVisible(show_shininess); + mComboShiny->setVisible(show_shininess); + mLabelShiny->setVisible(show_shininess); + mLabelGlossy->setVisible(false); + mGlossyCtrl->setVisible(false); + mLabelEnvironment->setVisible(false); + mEnvironmentCtrl->setVisible(false); + mLabelShinyColor->setVisible(false); + mShinyColorSwatch->setVisible(false); if (show_shininess) { updateShinyControls(); } - getChildView("shinyScaleU")->setVisible(show_shininess); - getChildView("shinyScaleV")->setVisible(show_shininess); - getChildView("shinyRot")->setVisible(show_shininess); - getChildView("shinyOffsetU")->setVisible(show_shininess); - getChildView("shinyOffsetV")->setVisible(show_shininess); + mShinyScaleU->setVisible(show_shininess); + mShinyScaleV->setVisible(show_shininess); + mShinyRot->setVisible(show_shininess); + mShinyOffsetU->setVisible(show_shininess); + mShinyOffsetV->setVisible(show_shininess); // Normal map controls if (show_bumpiness) { updateBumpyControls(); } - getChildView("bumpytexture control")->setVisible(show_bumpiness); - getChildView("combobox bumpiness")->setVisible(show_bumpiness); - getChildView("label bumpiness")->setVisible(show_bumpiness); - getChildView("bumpyScaleU")->setVisible(show_bumpiness); - getChildView("bumpyScaleV")->setVisible(show_bumpiness); - getChildView("bumpyRot")->setVisible(show_bumpiness); - getChildView("bumpyOffsetU")->setVisible(show_bumpiness); - getChildView("bumpyOffsetV")->setVisible(show_bumpiness); + mBumpyTextureCtrl->setVisible(show_bumpiness); + mComboBumpy->setVisible(show_bumpiness); + mLabelBumpy->setVisible(show_bumpiness); + mBumpyScaleU->setVisible(show_bumpiness); + mBumpyScaleV->setVisible(show_bumpiness); + mBumpyRot->setVisible(show_bumpiness); + mBumpyOffsetU->setVisible(show_bumpiness); + mBumpyOffsetV->setVisible(show_bumpiness); } void LLPanelFace::onCommitMaterialType() @@ -1616,33 +1646,12 @@ void LLPanelFace::onCommitMaterialType() updateUI(); } -// static -void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - - LLComboBox* mComboBumpiness = self->getChild("combobox bumpiness"); - if(!mComboBumpiness) - return; - - U32 bumpiness = mComboBumpiness->getCurrentIndex(); - - self->sendBump(bumpiness); -} - -// static -void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendTexGen(); -} - void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_shiny_combobox) { - LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); + LLTextureCtrl* texture_ctrl = mShinyTextureCtrl; LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID(); LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL; - LLComboBox* comboShiny = getChild("combobox shininess"); + LLComboBox* comboShiny = mComboShiny; if(mess_with_shiny_combobox) { @@ -1668,28 +1677,28 @@ void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_sh } } - LLComboBox* combo_matmedia = getChild("combobox matmedia"); - LLComboBox* combo_mattype = getChild("combobox mattype"); + LLComboBox* combo_matmedia = mComboMatMedia; + LLComboBox* combo_mattype =mComboMatType; U32 materials_media = combo_matmedia->getCurrentIndex(); U32 material_type = combo_mattype->getCurrentIndex(); bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled(); bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); U32 shiny_value = comboShiny->getCurrentIndex(); bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture - getChildView("label glossiness")->setVisible(show_shinyctrls); - getChildView("glossiness")->setVisible(show_shinyctrls); - getChildView("label environment")->setVisible(show_shinyctrls); - getChildView("environment")->setVisible(show_shinyctrls); - getChildView("label shinycolor")->setVisible(show_shinyctrls); - getChildView("shinycolorswatch")->setVisible(show_shinyctrls); + mLabelGlossy->setVisible(show_shinyctrls); + mGlossyCtrl->setVisible(show_shinyctrls); + mLabelEnvironment->setVisible(show_shinyctrls); + mEnvironmentCtrl->setVisible(show_shinyctrls); + mLabelShinyColor->setVisible(show_shinyctrls); + mShinyColorSwatch->setVisible(show_shinyctrls); } void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_combobox) { - LLTextureCtrl* texture_ctrl = getChild("bumpytexture control"); + LLTextureCtrl* texture_ctrl = mBumpyTextureCtrl; LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; - LLComboBox* comboBumpy = getChild("combobox bumpiness"); + LLComboBox* comboBumpy = mComboBumpy; if (!comboBumpy) { return; @@ -1697,7 +1706,7 @@ void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_co if (mess_with_combobox) { - LLTextureCtrl* texture_ctrl = getChild("bumpytexture control"); + LLTextureCtrl* texture_ctrl = mBumpyTextureCtrl; LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; @@ -1720,25 +1729,9 @@ void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_co } } -// static -void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - - - LLComboBox* mComboShininess = self->getChild("combobox shininess"); - if(!mComboShininess) - return; - - U32 shininess = mComboShininess->getCurrentIndex(); - - self->sendShiny(shininess); -} - -// static void LLPanelFace::updateAlphaControls() { - LLComboBox* comboAlphaMode = getChild("combobox alphamode"); + LLComboBox* comboAlphaMode = mComboAlpha; if (!comboAlphaMode) { return; @@ -1746,14 +1739,14 @@ void LLPanelFace::updateAlphaControls() U32 alpha_value = comboAlphaMode->getCurrentIndex(); bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking - LLComboBox* combobox_matmedia = getChild("combobox matmedia"); + LLComboBox* combobox_matmedia = mComboMatMedia; U32 mat_media = MATMEDIA_MATERIAL; if (combobox_matmedia) { mat_media = combobox_matmedia->getCurrentIndex(); } - LLComboBox* combobox_mattype = getChild("combobox mattype"); + LLComboBox* combobox_mattype = mComboMatType; U32 mat_type = MATTYPE_DIFFUSE; if (combobox_mattype) { @@ -1763,30 +1756,14 @@ void LLPanelFace::updateAlphaControls() show_alphactrls = show_alphactrls && (mat_media == MATMEDIA_MATERIAL); show_alphactrls = show_alphactrls && (mat_type == MATTYPE_DIFFUSE); - getChildView("label maskcutoff")->setVisible(show_alphactrls); - getChildView("maskcutoff")->setVisible(show_alphactrls); + mLabelMaskCutoff->setVisible(show_alphactrls); + mCtrlMaskCutoff->setVisible(show_alphactrls); } -// static -void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitAlphaMode() { - LLPanelFace* self = (LLPanelFace*) userdata; - self->updateAlphaControls(); - LLSelectedTEMaterial::setDiffuseAlphaMode(self,self->getCurrentDiffuseAlphaMode()); -} - -// static -void LLPanelFace::onCommitFullbright(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendFullbright(); -} - -// static -void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendGlow(); + updateAlphaControls(); + LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode()); } // static @@ -1828,7 +1805,7 @@ void LLPanelFace::onSelectTexture(const LLSD& data) LLSelectedTE::getImageFormat(image_format, identical_image_format); LLCtrlSelectionInterface* combobox_alphamode = - childGetSelectionInterface("combobox alphamode"); + mComboAlpha; U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; if (combobox_alphamode) @@ -1879,7 +1856,7 @@ void LLPanelFace::onCancelSpecularTexture(const LLSD& data) U8 shiny = 0; bool identical_shiny = false; LLSelectedTE::getShiny(shiny, identical_shiny); - LLUUID spec_map_id = getChild("shinytexture control")->getImageAssetID(); + LLUUID spec_map_id = mShinyTextureCtrl->getImageAssetID(); shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE; sendShiny(shiny); } @@ -1905,151 +1882,72 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data) sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); } -//static -void LLPanelFace::onCommitMaterialBumpyOffsetX(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitMaterialBumpyScaleX(const LLSD& value) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU()); -} - -//static -void LLPanelFace::onCommitMaterialBumpyOffsetY(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV()); -} - -//static -void LLPanelFace::onCommitMaterialShinyOffsetX(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU()); -} - -//static -void LLPanelFace::onCommitMaterialShinyOffsetY(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV()); -} - -//static -void LLPanelFace::onCommitMaterialBumpyScaleX(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - F32 bumpy_scale_u = self->getCurrentBumpyScaleU(); - if (self->isIdenticalPlanarTexgen()) + F32 bumpy_scale_u = value.asReal(); + if (isIdenticalPlanarTexgen()) { bumpy_scale_u *= 0.5f; } - LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u); + LLSelectedTEMaterial::setNormalRepeatX(this, bumpy_scale_u); } -//static -void LLPanelFace::onCommitMaterialBumpyScaleY(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitMaterialBumpyScaleY(const LLSD& value) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - F32 bumpy_scale_v = self->getCurrentBumpyScaleV(); - if (self->isIdenticalPlanarTexgen()) + F32 bumpy_scale_v = value.asReal(); + if (isIdenticalPlanarTexgen()) { bumpy_scale_v *= 0.5f; } - LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v); + LLSelectedTEMaterial::setNormalRepeatY(this, bumpy_scale_v); } -//static -void LLPanelFace::onCommitMaterialShinyScaleX(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitMaterialShinyScaleX(const LLSD& value) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - F32 shiny_scale_u = self->getCurrentShinyScaleU(); - if (self->isIdenticalPlanarTexgen()) + F32 shiny_scale_u = value.asReal(); + if (isIdenticalPlanarTexgen()) { shiny_scale_u *= 0.5f; } - LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u); + LLSelectedTEMaterial::setSpecularRepeatX(this, shiny_scale_u); } -//static -void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitMaterialShinyScaleY(const LLSD& value) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - F32 shiny_scale_v = self->getCurrentShinyScaleV(); - if (self->isIdenticalPlanarTexgen()) + F32 shiny_scale_v = value.asReal(); + if (isIdenticalPlanarTexgen()) { shiny_scale_v *= 0.5f; } - LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v); + LLSelectedTEMaterial::setSpecularRepeatY(this, shiny_scale_v); } -//static -void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitMaterialBumpyRot(const LLSD& value) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD); + LLSelectedTEMaterial::setNormalRotation(this, value.asReal() * DEG_TO_RAD); } -//static -void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitMaterialShinyRot(const LLSD& value) { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD); + LLSelectedTEMaterial::setSpecularRotation(this, value.asReal() * DEG_TO_RAD); } -//static -void LLPanelFace::onCommitMaterialGloss(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitTextureInfo() { - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - LLSelectedTEMaterial::setSpecularLightExponent(self,self->getCurrentGlossiness()); -} - -//static -void LLPanelFace::onCommitMaterialEnv(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - llassert_always(self); - LLSelectedTEMaterial::setEnvironmentIntensity(self,self->getCurrentEnvIntensity()); -} - -//static -void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff()); -} - -// static -void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata ) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendTextureInfo(); + sendTextureInfo(); // Materials alignment if (gSavedSettings.getBOOL("FSSynchronizeTextureMaps")) { - self->alignMaterialsProperties(); + alignMaterialsProperties(); } // } // Commit the number of repeats per meter -// static -void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* repeats_ctrl) { - LLPanelFace* self = (LLPanelFace*) userdata; - - LLUICtrl* repeats_ctrl = self->getChild("rptctrl"); - LLComboBox* combo_matmedia = self->getChild("combobox matmedia"); - LLComboBox* combo_mattype = self->getChild("combobox mattype"); + LLComboBox* combo_matmedia = mComboMatMedia; + LLComboBox* combo_mattype = mComboMatType; U32 materials_media = combo_matmedia->getCurrentIndex(); @@ -2076,27 +1974,27 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) case MATTYPE_NORMAL: { - LLUICtrl* bumpy_scale_u = self->getChild("bumpyScaleU"); - LLUICtrl* bumpy_scale_v = self->getChild("bumpyScaleV"); + LLUICtrl* bumpy_scale_u = mBumpyScaleU; + LLUICtrl* bumpy_scale_v = mBumpyScaleV; bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); - LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); + LLSelectedTEMaterial::setNormalRepeatX(this,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setNormalRepeatY(this,obj_scale_t * repeats_per_meter); } break; case MATTYPE_SPECULAR: { - LLUICtrl* shiny_scale_u = self->getChild("shinyScaleU"); - LLUICtrl* shiny_scale_v = self->getChild("shinyScaleV"); + LLUICtrl* shiny_scale_u = mShinyScaleU; + LLUICtrl* shiny_scale_v = mShinyScaleV; shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); - LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); + LLSelectedTEMaterial::setSpecularRepeatX(this,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setSpecularRepeatY(this,obj_scale_t * repeats_per_meter); } break; @@ -2148,7 +2046,7 @@ struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor }; }; -void LLPanelFace::onClickAutoFix(void* userdata) +void LLPanelFace::onClickAutoFix() { LLPanelFaceSetMediaFunctor setfunc; LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); @@ -2167,36 +2065,32 @@ void LLPanelFace::setMediaType(const std::string& mime_type) { } -// static -void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitPlanarAlign() { - LLPanelFace* self = (LLPanelFace*) userdata; - self->getState(); - self->sendTextureInfo(); + getState(); + sendTextureInfo(); } void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp) { LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL; - LLComboBox* combo_mattype = getChild("combobox mattype"); + LLComboBox* combo_mattype = mComboMatType; if (!combo_mattype) { return; } U32 mattype = combo_mattype->getCurrentIndex(); - std::string which_control="texture control"; + LLTextureCtrl* texture_ctrl = mTextureCtrl; switch (mattype) { case MATTYPE_SPECULAR: - which_control = "shinytexture control"; + texture_ctrl = mShinyTextureCtrl; break; case MATTYPE_NORMAL: - which_control = "bumpytexture control"; + texture_ctrl = mBumpyTextureCtrl; break; // no default needed } - LL_DEBUGS("Materials") << "control " << which_control << LL_ENDL; - LLTextureCtrl* texture_ctrl = getChild(which_control); if (texture_ctrl) { LLUUID obj_owner_id; @@ -2438,7 +2332,7 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic static LLSD textures; -void LLPanelFace::onClickCopy(void* userdata) +void LLPanelFace::onClickCopy() { LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); if(!objectp) @@ -2472,7 +2366,7 @@ void LLPanelFace::onClickCopy(void* userdata) } } -void LLPanelFace::onClickPaste(void* userdata) +void LLPanelFace::onClickPaste() { LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); if(!objectp) @@ -2524,17 +2418,17 @@ void LLPanelFace::onClickMapsSync() void LLPanelFace::alignMaterialsProperties() { - F32 tex_scale_u = getChildView("TexScaleU")->getValue().asReal(); - F32 tex_scale_v = getChildView("TexScaleV")->getValue().asReal(); - F32 tex_offset_u = getChildView("TexOffsetU")->getValue().asReal(); - F32 tex_offset_v = getChildView("TexOffsetU")->getValue().asReal(); - F32 tex_rot = getChildView("TexRot")->getValue().asReal(); + F32 tex_scale_u = mCtrlTexScaleU->getValue().asReal(); + F32 tex_scale_v = mCtrlTexScaleV->getValue().asReal(); + F32 tex_offset_u = mCtrlTexOffsetU->getValue().asReal(); + F32 tex_offset_v = mCtrlTexOffsetV->getValue().asReal(); + F32 tex_rot = mCtrlTexRot->getValue().asReal(); - childSetValue("shinyScaleU", tex_scale_u); - childSetValue("shinyScaleV", tex_scale_v); - childSetValue("shinyOffsetU", tex_offset_u); - childSetValue("shinyOffsetV", tex_offset_v); - childSetValue("shinyRot", tex_rot); + mShinyScaleU->setValue(tex_scale_u); + mShinyScaleV->setValue(tex_scale_v); + mShinyOffsetU->setValue(tex_offset_u); + mShinyOffsetV->setValue(tex_offset_v); + mShinyRot->setValue(tex_rot); LLSelectedTEMaterial::setSpecularRepeatX(this, tex_scale_u); LLSelectedTEMaterial::setSpecularRepeatY(this, tex_scale_v); @@ -2542,11 +2436,11 @@ void LLPanelFace::alignMaterialsProperties() LLSelectedTEMaterial::setSpecularOffsetY(this, tex_offset_v); LLSelectedTEMaterial::setSpecularRotation(this, tex_rot * DEG_TO_RAD); - childSetValue("bumpyScaleU", tex_scale_u); - childSetValue("bumpyScaleV", tex_scale_v); - childSetValue("bumpyOffsetU", tex_offset_u); - childSetValue("bumpyOffsetV", tex_offset_v); - childSetValue("bumpyRot", tex_rot); + mBumpyScaleU->setValue(tex_scale_u); + mBumpyScaleV->setValue(tex_scale_v); + mBumpyOffsetU->setValue(tex_offset_u); + mBumpyOffsetV->setValue(tex_offset_v); + mBumpyRot->setValue(tex_rot); LLSelectedTEMaterial::setNormalRepeatX(this, tex_scale_u); LLSelectedTEMaterial::setNormalRepeatY(this, tex_scale_v); @@ -2558,25 +2452,25 @@ void LLPanelFace::alignMaterialsProperties() // FIRE-11407 - Flip buttons void LLPanelFace::onCommitFlip(bool flip_x) { - std::string control_name = ""; - S32 mattype(getChild("combobox mattype")->getCurrentIndex()); + S32 mattype(mComboMatType->getCurrentIndex()); + LLUICtrl* spinner = NULL; switch (mattype) { case MATTYPE_DIFFUSE: - control_name = "TexScale"; + spinner = flip_x ? mCtrlTexScaleU : mCtrlTexScaleV; break; case MATTYPE_NORMAL: - control_name = "bumpyScale"; + spinner = flip_x ? mBumpyScaleU : mBumpyScaleV; break; case MATTYPE_SPECULAR: - control_name = "shinyScale"; + spinner = flip_x ? mShinyScaleU : mShinyScaleV; break; default: //llassert(mattype); return; } - if (LLUICtrl* spinner = getChild(control_name + (flip_x ? "U" : "V"))) + if (spinner) { F32 value = -(spinner->getValue().asReal()); spinner->setValue(value); diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 5ac63c20b..0ad383b14 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -145,9 +145,7 @@ protected: void onCommitNormalTexture(const LLSD& data); void onCancelNormalTexture(const LLSD& data); void onSelectNormalTexture(const LLSD& data); - void onCommitColor(const LLSD& data); void onCommitShinyColor(const LLSD& data); - void onCommitAlpha(const LLSD& data); void onCancelColor(const LLSD& data); void onSelectColor(const LLSD& data); @@ -165,39 +163,27 @@ protected: // Callback funcs for individual controls // - static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata); + void onCommitTextureInfo(); - static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata); + void onCommitMaterialBumpyScaleX(const LLSD& value); + void onCommitMaterialBumpyScaleY(const LLSD& value); + void onCommitMaterialBumpyRot(const LLSD& value); - static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata); + void onCommitMaterialShinyScaleX(const LLSD& value); + void onCommitMaterialShinyScaleY(const LLSD& value); + void onCommitMaterialShinyRot(const LLSD& value); - static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); + void onCommitMaterialsMedia(); void onCommitMaterialType(); - static void onCommitBump( LLUICtrl* ctrl, void* userdata); - static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); - static void onCommitShiny( LLUICtrl* ctrl, void* userdata); - static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); - static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); - static void onCommitGlow( LLUICtrl* ctrl, void *userdata); - static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); - static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); - static void onClickAutoFix(void*); + void onCommitAlphaMode(); + void onCommitPlanarAlign(); + void onCommitRepeatsPerMeter(LLUICtrl* repeats_ctrl); + void onClickAutoFix(); static F32 valueGlow(LLViewerObject* object, S32 face); - static void onClickCopy(void*); - static void onClickPaste(void*); + void onClickCopy(); + void onClickPaste(); // Build tool enhancements void onClickMapsSync(); void alignMaterialsProperties(); @@ -212,22 +198,7 @@ private: // LLUUID getCurrentNormalMap(); LLUUID getCurrentSpecularMap(); - U32 getCurrentShininess(); - U32 getCurrentBumpiness(); U8 getCurrentDiffuseAlphaMode(); - U8 getCurrentAlphaMaskCutoff(); - U8 getCurrentEnvIntensity(); - U8 getCurrentGlossiness(); - F32 getCurrentBumpyRot(); - F32 getCurrentBumpyScaleU(); - F32 getCurrentBumpyScaleV(); - F32 getCurrentBumpyOffsetU(); - F32 getCurrentBumpyOffsetV(); - F32 getCurrentShinyRot(); - F32 getCurrentShinyScaleU(); - F32 getCurrentShinyScaleV(); - F32 getCurrentShinyOffsetU(); - F32 getCurrentShinyOffsetV(); // Update visibility of controls to match current UI mode // (e.g. materials vs media editing) @@ -382,6 +353,69 @@ private: data_to_return = data_value; } +// + friend struct LLPanelFaceSetTEFunctor; // Must access some of these + // UI Widgets + LLView* mMediaInfo; + LLView* mMediaAdd; + LLView* mMediaDelete; + LLView* mLabelGlossy; + LLView* mLabelEnvironment; + LLView* mLabelShinyColor; + LLView* mLabelAlphaMode; + LLView* mLabelMaskCutoff; + LLView* mLabelBumpy; + LLView* mLabelShiny; + LLView* mLabelColor; + LLView* mLabelGlow; + LLView* mLabelTexGen; + LLComboBox* mComboShiny; + LLComboBox* mComboBumpy; + LLComboBox* mComboAlpha; + LLSpinCtrl* mCtrlTexScaleU; + LLUICtrl* mCtrlFlipTexScaleU; + LLSpinCtrl* mCtrlTexScaleV; + LLUICtrl* mCtrlFlipTexScaleV; + LLSpinCtrl* mCtrlTexRot; + LLUICtrl* mCtrlRpt; + LLUICtrl* mCtrlPlanar; + LLSpinCtrl* mCtrlTexOffsetU; + LLSpinCtrl* mCtrlTexOffsetV; + LLUICtrl* mBumpyScaleU; + LLUICtrl* mBumpyScaleV; + LLUICtrl* mBumpyRot; + LLUICtrl* mBumpyOffsetU; + LLUICtrl* mBumpyOffsetV; + LLUICtrl* mShinyScaleU; + LLUICtrl* mShinyScaleV; + LLUICtrl* mShinyRot; + LLUICtrl* mShinyOffsetU; + LLUICtrl* mShinyOffsetV; + LLUICtrl* mGlossyCtrl; + LLUICtrl* mEnvironmentCtrl; + LLUICtrl* mCtrlMaskCutoff; + LLUICtrl* mCtrlAlign; + LLUICtrl* mCtrlMapsSync; + LLUICtrl* mCtrlCopy; + LLUICtrl* mCtrlPaste; + LLTextureCtrl* mTextureCtrl; + LLTextureCtrl* mShinyTextureCtrl; + LLTextureCtrl* mBumpyTextureCtrl; + LLColorSwatchCtrl* mColorSwatch; + LLColorSwatchCtrl* mShinyColorSwatch; + + LLComboBox* mComboTexGen; + LLComboBox* mComboMatMedia; + LLComboBox* mComboMatType; + + LLCheckBoxCtrl* mCheckFullbright; + + LLTextBox* mLabelColorTransp; + LLSpinCtrl* mCtrlColorTransp; // transparency = 1 - alpha + + LLSpinCtrl* mCtrlGlow; +// + // Update vis and enabling of specific subsets of controls based on material params // (e.g. hide the spec controls if no spec texture is applied) // diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index a219868d3..e96e4d368 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -62,7 +62,6 @@ #include "llui.h" #include "lluiconstants.h" #include "llurlhistory.h" // OGPX : regionuri text box has a history of region uris (if FN/LN are loaded at startup) -#include "llviewerbuild.h" #include "llviewertexturelist.h" #include "llviewermenu.h" // for handle_preferences() #include "llviewernetwork.h" @@ -254,7 +253,7 @@ LLPanelLogin::LLPanelLogin(const LLRect& rect) gVersionMajor, gVersionMinor, gVersionPatch, - LL_VIEWER_BUILD ); + gVersionBuild ); LLTextBox* channel_text = getChild("channel_text"); channel_text->setTextArg("[CHANNEL]", channel); // though not displayed channel_text->setTextArg("[VERSION]", version); @@ -463,6 +462,7 @@ void LLPanelLogin::giveFocus() { if( sInstance ) { + if (!sInstance->getVisible()) sInstance->setVisible(true); // Grab focus and move cursor to first blank input field std::string username = sInstance->getChild("username_combo")->getValue().asString(); std::string pass = sInstance->getChild("password_edit")->getValue().asString(); diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 6fc0ab438..99ff385ee 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -314,8 +314,8 @@ void LLPhysicsMotion::getString(std::ostringstream &oss) } } -LLPhysicsMotionController::LLPhysicsMotionController(const LLUUID &id) : - LLMotion(id), +LLPhysicsMotionController::LLPhysicsMotionController(LLUUID const& id, LLMotionController* controller) : + AIMaskedMotion(id, controller, ANIM_AGENT_PHYSICS_MOTION), mCharacter(NULL), mIsDefault(true) { @@ -332,15 +332,6 @@ LLPhysicsMotionController::~LLPhysicsMotionController() } } -BOOL LLPhysicsMotionController::onActivate() -{ - return TRUE; -} - -void LLPhysicsMotionController::onDeactivate() -{ -} - LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter *character) { mCharacter = character; @@ -889,4 +880,4 @@ void LLPhysicsMotion::reset() mCharacter->setVisualParamWeight((*iter).mParam,(*iter).mParam->getDefaultWeight()); } } -} \ No newline at end of file +} diff --git a/indra/newview/llphysicsmotion.h b/indra/newview/llphysicsmotion.h index 7412c9d88..2ce79b220 100644 --- a/indra/newview/llphysicsmotion.h +++ b/indra/newview/llphysicsmotion.h @@ -42,14 +42,14 @@ class LLPhysicsMotion; // class LLPhysicsMotion //----------------------------------------------------------------------------- class LLPhysicsMotionController : - public LLMotion + public AIMaskedMotion { public: std::string getString(); // Constructor - LLPhysicsMotionController(const LLUUID &id); + LLPhysicsMotionController(LLUUID const& id, LLMotionController* controller); // Destructor virtual ~LLPhysicsMotionController(); @@ -61,7 +61,7 @@ public: // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLPhysicsMotionController(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLPhysicsMotionController(id, controller); } public: //------------------------------------------------------------------------- @@ -93,19 +93,11 @@ public: // must return true to indicate success and be available for activation virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); - LLCharacter* getCharacter() { return mCharacter; } protected: diff --git a/indra/newview/llprefsvoice.cpp b/indra/newview/llprefsvoice.cpp index 275778de4..86e39d07d 100644 --- a/indra/newview/llprefsvoice.cpp +++ b/indra/newview/llprefsvoice.cpp @@ -53,7 +53,7 @@ public: BOOL handleKeyHere(KEY key, MASK mask); - static void onCancel(void* user_data); + static void start(LLPrefsVoice* p) { (new LLVoiceSetKeyDialog(p))->startModal(); } private: LLPrefsVoice* mParent; @@ -63,8 +63,11 @@ LLVoiceSetKeyDialog::LLVoiceSetKeyDialog(LLPrefsVoice* parent) : LLModalDialog(LLStringUtil::null, 240, 100), mParent(parent) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_select_key.xml"); - childSetAction("Cancel", onCancel, this); - childSetFocus("Cancel"); + if (LLUICtrl* ctrl = findChild("Cancel")) + { + ctrl->setCommitCallback(boost::bind(&LLModalDialog::close, this, false)); + ctrl->setFocus(true); + } gFocusMgr.setKeystrokesOnly(TRUE); } @@ -77,7 +80,7 @@ BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask) { BOOL result = TRUE; - if(key == 'Q' && mask == MASK_CONTROL) + if (key == 'Q' && mask == MASK_CONTROL) { result = FALSE; } @@ -90,13 +93,6 @@ BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask) return result; } -//static -void LLVoiceSetKeyDialog::onCancel(void* user_data) -{ - LLVoiceSetKeyDialog* self = (LLVoiceSetKeyDialog*)user_data; - self->close(); -} - namespace { void* createDevicePanel(void*) @@ -121,20 +117,13 @@ LLPrefsVoice::~LLPrefsVoice() BOOL LLPrefsVoice::postBuild() { - childSetCommitCallback("enable_voice_check", onCommitEnableVoiceChat, this); - childSetAction("set_voice_hotkey_button", onClickSetKey, this); - childSetAction("set_voice_middlemouse_button", onClickSetMiddleMouse, this); + getChild("enable_voice_check")->setCommitCallback(boost::bind(&LLPrefsVoice::onCommitEnableVoiceChat, this, _2)); + getChild("set_voice_hotkey_button")->setCommitCallback(boost::bind(LLVoiceSetKeyDialog::start, this)); + getChild("set_voice_middlemouse_button")->setCommitCallback(boost::bind(&LLView::setValue, getChildView("modifier_combo"), "MiddleMouse")); - BOOL voice_disabled = gSavedSettings.getBOOL("CmdLineDisableVoice"); - childSetVisible("voice_unavailable", voice_disabled); - childSetVisible("enable_voice_check", !voice_disabled); - childSetEnabled("enable_voice_check", !voice_disabled); + getChildView("enable_voice_check")->setValue(!gSavedSettings.getBOOL("CmdLineDisableVoice") && gSavedSettings.getBOOL("EnableVoiceChat")); - bool enable = !voice_disabled && gSavedSettings.getBOOL("EnableVoiceChat"); - childSetValue("enable_voice_check", enable); - onCommitEnableVoiceChat(getChild("enable_voice_check"), this); - - if (LLCheckBoxCtrl* check = getChild("enable_multivoice_check")) + if (LLCheckBoxCtrl* check = findChild("enable_multivoice_check")) { check->setValue(gSavedSettings.getBOOL("VoiceMultiInstance")); check->setLabel(getString("multivoice_label", LLTrans::getDefaultArgs())); @@ -160,7 +149,7 @@ void LLPrefsVoice::apply() gSavedSettings.setBOOL("LipSyncEnabled", childGetValue("enable_lip_sync_check")); gSavedSettings.setBOOL("VoiceMultiInstance", childGetValue("enable_multivoice_check")); - if (LLPanelVoiceDeviceSettings* voice_device_settings = getChild("device_settings_panel")) + if (LLPanelVoiceDeviceSettings* voice_device_settings = findChild("device_settings_panel")) { voice_device_settings->apply(); } @@ -180,7 +169,7 @@ void LLPrefsVoice::apply() void LLPrefsVoice::cancel() { - if (LLPanelVoiceDeviceSettings* voice_device_settings = getChild("device_settings_panel")) + if (LLPanelVoiceDeviceSettings* voice_device_settings = findChild("device_settings_panel")) { voice_device_settings->cancel(); } @@ -188,42 +177,23 @@ void LLPrefsVoice::cancel() void LLPrefsVoice::setKey(KEY key) { - childSetValue("modifier_combo", LLKeyboard::stringFromKey(key)); + getChildView("modifier_combo")->setValue(LLKeyboard::stringFromKey(key)); } -//static -void LLPrefsVoice::onCommitEnableVoiceChat(LLUICtrl* ctrl, void* user_data) +void LLPrefsVoice::onCommitEnableVoiceChat(const LLSD& value) { - LLPrefsVoice* self = (LLPrefsVoice*)user_data; - LLCheckBoxCtrl* enable_voice_chat = (LLCheckBoxCtrl*)ctrl; + bool enable = value.asBoolean(); - bool enable = enable_voice_chat->getValue(); - - self->childSetEnabled("modifier_combo", enable); - self->childSetEnabled("push_to_talk_label", enable); - self->childSetEnabled("voice_call_friends_only_check", enable); - self->childSetEnabled("auto_disengage_mic_check", enable); - self->childSetEnabled("push_to_talk_toggle_check", enable); - self->childSetEnabled("ear_location", enable); - self->childSetEnabled("enable_lip_sync_check", enable); - self->childSetEnabled("set_voice_hotkey_button", enable); - self->childSetEnabled("set_voice_middlemouse_button", enable); - self->childSetEnabled("device_settings_btn", enable); - self->childSetEnabled("device_settings_panel", enable); -} - -//static -void LLPrefsVoice::onClickSetKey(void* user_data) -{ - LLPrefsVoice* self = (LLPrefsVoice*)user_data; - LLVoiceSetKeyDialog* dialog = new LLVoiceSetKeyDialog(self); - dialog->startModal(); -} - -//static -void LLPrefsVoice::onClickSetMiddleMouse(void* user_data) -{ - LLPrefsVoice* self = (LLPrefsVoice*)user_data; - self->childSetValue("modifier_combo", "MiddleMouse"); + getChildView("modifier_combo")->setEnabled(enable); + getChildView("push_to_talk_label")->setEnabled(enable); + getChildView("voice_call_friends_only_check")->setEnabled(enable); + getChildView("auto_disengage_mic_check")->setEnabled(enable); + getChildView("push_to_talk_toggle_check")->setEnabled(enable); + getChildView("ear_location")->setEnabled(enable); + getChildView("enable_lip_sync_check")->setEnabled(enable); + getChildView("set_voice_hotkey_button")->setEnabled(enable); + getChildView("set_voice_middlemouse_button")->setEnabled(enable); + getChildView("device_settings_btn")->setEnabled(enable); + getChildView("device_settings_panel")->setEnabled(enable); } diff --git a/indra/newview/llprefsvoice.h b/indra/newview/llprefsvoice.h index a1cd8c933..70ce6a032 100644 --- a/indra/newview/llprefsvoice.h +++ b/indra/newview/llprefsvoice.h @@ -49,9 +49,7 @@ public: void setKey(KEY key); private: - static void onCommitEnableVoiceChat(LLUICtrl* ctrl, void* user_data); - static void onClickSetKey(void* user_data); - static void onClickSetMiddleMouse(void* user_data); + void onCommitEnableVoiceChat(const LLSD& value); }; #endif // LLPREFSVOICE_H diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 4881139df..976397931 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6506,7 +6506,7 @@ void LLSelectMgr::updateSelectionCenter() mSelectionCenterGlobal.clearVec(); mShowSelection = FALSE; mSelectionBBox = LLBBox(); - mPauseRequest = NULL; + mPauseRequests.clear(); resetAgentHUDZoom(); } @@ -6516,27 +6516,18 @@ void LLSelectMgr::updateSelectionCenter() if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) { - // Singu Note: Chalice Yao's pause agent on attachment selection - if (object->permYouOwner()) + // Freeze avatars with a selected attachment, and all avatars with synchronized motions, if any. + LLVOAvatar* avatar = object->getAvatar(); + // It is possible that 'avatar' is NULL despite this being an attachment because of some race condition. + // In that case just don't freeze the avatar. + if (avatar) { - mPauseRequest = gAgentAvatarp->requestPause(); - } - else if (LLViewerObject* objectp = mSelectedObjects->getPrimaryObject()) - { - while (objectp && !objectp->isAvatar()) - { - objectp = (LLViewerObject*)objectp->getParent(); - } - - if (objectp) - { - mPauseRequest = objectp->asAvatar()->requestPause(); - } + avatar->pauseAllSyncedCharacters(mPauseRequests); } } else { - mPauseRequest = NULL; + mPauseRequests.clear(); } if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid()) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 16c960ba8..145c25005 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -793,7 +793,7 @@ private: LLFrameTimer mEffectsTimer; BOOL mForceSelection; - LLAnimPauseRequest mPauseRequest; + std::vector mPauseRequests; // Selected avatar and all synchronized avatars. friend class LLObjectBackup; }; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index f291de520..2079180fd 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1496,7 +1496,7 @@ bool LLTextureFetchWorker::doWork(S32 param) HTTP_CASE(HTTP_INTERNAL_ERROR_CURL_OTHER) HTTP_CASE(HTTP_INTERNAL_ERROR_OTHER) default: - LL_DEBUGS("TexDebug") << mID << " status = " << mGetStatus << " (??)" << " Failcount = " << mHTTPFailCount << llendl; break; + LL_DEBUGS("TexDebug") << mID << " status = " << mGetStatus << " (?)" << " Failcount = " << mHTTPFailCount << llendl; break; } if (mGetStatus == HTTP_NOT_FOUND || mGetStatus == HTTP_INTERNAL_ERROR_CURL_TIMEOUT || mGetStatus == HTTP_INTERNAL_ERROR_LOW_SPEED) diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index f924b93c2..5612088d8 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -58,24 +58,30 @@ #if LL_DARWIN - #include "llresizehandle.h" - #include "llviewerwindow.h" +#include "llresizehandle.h" +#include "llviewerwindow.h" - // This class draws like an LLResizeHandle but has no interactivity. - // It's just there to provide a cue to the user that the lower right corner of the window functions as a resize handle. - class LLFakeResizeHandle : public LLResizeHandle +// This class draws like an LLResizeHandle but has no interactivity. +// It's just there to provide a cue to the user that the lower right corner of the window functions as a resize handle. +class LLFakeResizeHandle : public LLResizeHandle +{ +public: + LLFakeResizeHandle(const LLResizeHandle::Params& p) : LLResizeHandle(p) {} + + virtual BOOL handleHover(S32 x, S32 y, MASK mask) { return false; } + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return false; } + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) { return false; } + virtual void reshape(S32 width, S32 height, BOOL called_from_parent) { - public: - LLFakeResizeHandle(const LLResizeHandle::Params& p) - : LLResizeHandle(p) - { - } + // Only when running in windowed mode on the Mac, leave room for a resize widget on the right edge of the bar. + if (gViewerWindow->getWindow()->getFullscreen()) + return setVisible(false); - virtual BOOL handleHover(S32 x, S32 y, MASK mask) { return FALSE; }; - virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; }; - virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) { return FALSE; }; - - }; + setVisible(true); + const F32 wide(gViewerWindow->getWindowWidth() + 2); + setRect(LLRect(wide - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, wide, 0)); + } +}; #endif // LL_DARWIN @@ -98,9 +104,6 @@ void show_floater(const std::string& floater_name); LLToolBar::LLToolBar() : LLLayoutPanel() -#if LL_DARWIN - , mResizeHandle(NULL) -#endif // LL_DARWIN { setIsChrome(TRUE); setFocusRoot(TRUE); @@ -130,22 +133,16 @@ BOOL LLToolBar::postBuild() } #if LL_DARWIN - if(mResizeHandle == NULL) - { - LLResizeHandle::Params p; - p.rect(LLRect(0, 0, RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT)); - p.name(std::string("")); - p.min_width(RESIZE_HANDLE_WIDTH); - p.min_height(RESIZE_HANDLE_HEIGHT); - p.corner(LLResizeHandle::RIGHT_BOTTOM); - mResizeHandle = new LLFakeResizeHandle(p); this->addChildInBack(mResizeHandle); - LLLayoutStack* toolbar_stack = getChild("toolbar_stack"); - toolbar_stack->reshape(toolbar_stack->getRect().getWidth() - RESIZE_HANDLE_WIDTH, toolbar_stack->getRect().getHeight()); - } + LLResizeHandle::Params p; + p.rect(LLRect(0, 0, RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT)); + p.name(std::string("")); + p.min_width(RESIZE_HANDLE_WIDTH); + p.min_height(RESIZE_HANDLE_HEIGHT); + p.corner(LLResizeHandle::RIGHT_BOTTOM); + addChildInBack(new LLFakeResizeHandle(p)); + reshape(getRect().getWidth(), getRect().getHeight()); #endif // LL_DARWIN - layoutButtons(); - return TRUE; } @@ -161,18 +158,18 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EAcceptance* accept, std::string& tooltip_msg) { - LLButton* inventory_btn = getChild("inventory_btn"); + LLButton* inventory_btn = mInventoryBtn; if (!inventory_btn || !inventory_btn->getVisible()) return FALSE; LLInventoryView* active_inventory = LLInventoryView::getActiveInventory(); if (active_inventory && active_inventory->getVisible()) { - mInventoryAutoOpen = FALSE; + mInventoryAutoOpenTimer.stop(); } else if (inventory_btn->getRect().pointInRect(x, y)) { - if (mInventoryAutoOpen) + if (mInventoryAutoOpenTimer.getStarted()) { if (!(active_inventory && active_inventory->getVisible()) && mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime) @@ -182,71 +179,35 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, } else { - mInventoryAutoOpen = TRUE; - mInventoryAutoOpenTimer.reset(); + mInventoryAutoOpenTimer.start(); } } return LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); } -void LLToolBar::layoutButtons() -{ -#if LL_DARWIN - const S32 FUDGE_WIDTH_OF_SCREEN = 4; - S32 width = gViewerWindow->getWindowWidth() + FUDGE_WIDTH_OF_SCREEN; - S32 pad = 2; - - // this function may be called before postBuild(), in which case mResizeHandle won't have been set up yet. - if(mResizeHandle != NULL) - { - if(!gViewerWindow->getWindow()->getFullscreen()) - { - // Only when running in windowed mode on the Mac, leave room for a resize widget on the right edge of the bar. - width -= RESIZE_HANDLE_WIDTH; - - LLRect r; - r.mLeft = width - pad; - r.mBottom = 0; - r.mRight = r.mLeft + RESIZE_HANDLE_WIDTH; - r.mTop = r.mBottom + RESIZE_HANDLE_HEIGHT; - mResizeHandle->setRect(r); - mResizeHandle->setVisible(TRUE); - } - else - { - mResizeHandle->setVisible(FALSE); - } - } -#endif // LL_DARWIN -} - - -// virtual -void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - LLPanel::reshape(width, height, called_from_parent); - - layoutButtons(); -} - // Per-frame updates of visibility void LLToolBar::refresh() { - if(!isAgentAvatarValid()) - return; + static const LLCachedControl show_toolbar("ShowToolBar", true); + bool show = show_toolbar; + if (show && gAgentCamera.cameraMouselook()) + { + static const LLCachedControl hidden("LiruMouselookHidesToolbar"); + show = !hidden; + } + setVisible(show); + if (!show) return; // Everything below this point manipulates visible UI, anyway - static LLCachedControl show("ShowToolBar", true); - BOOL mouselook = gAgentCamera.cameraMouselook(); - setVisible(show && !mouselook); + updateCommunicateList(); - static LLCachedControl continue_flying_on_unsit("LiruContinueFlyingOnUnsit"); - bool sitting = !continue_flying_on_unsit && gAgentAvatarp && gAgentAvatarp->isSitting(); + if (!isAgentAvatarValid()) return; - mFlyBtn->setEnabled((gAgent.canFly() || gAgent.getFlying()) && !sitting ); - static LLCachedControl ascent_build_always_enabled("AscentBuildAlwaysEnabled", true); - mBuildBtn->setEnabled((LLViewerParcelMgr::getInstance()->allowAgentBuild() || ascent_build_always_enabled)); + static const LLCachedControl continue_flying_on_unsit("LiruContinueFlyingOnUnsit"); + mFlyBtn->setEnabled((gAgent.canFly() || gAgent.getFlying()) && (continue_flying_on_unsit || !gAgentAvatarp->isSitting())); + static const LLCachedControl ascent_build_always_enabled("AscentBuildAlwaysEnabled", true); + mBuildBtn->setEnabled(ascent_build_always_enabled || LLViewerParcelMgr::getInstance()->allowAgentBuild()); // Check to see if we're in build mode // And not just clicking on a scripted object @@ -268,11 +229,6 @@ void LLToolBar::refresh() mInventoryBtn->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWINV)); } // [/RLVa:KB] - - if (isInVisibleChain() && mCommunicateBtn->getVisible()) - { - updateCommunicateList(); - } } void bold_if_equal(const LLFloater* f1, const LLFloater* f2, LLScrollListItem* itemp) @@ -283,11 +239,13 @@ void bold_if_equal(const LLFloater* f1, const LLFloater* f2, LLScrollListItem* i void LLToolBar::updateCommunicateList() { + if (!mCommunicateBtn->getVisible()) return; + LLSD selected = mCommunicateBtn->getValue(); mCommunicateBtn->removeall(); - LLFloater* frontmost_floater = LLFloaterChatterBox::getInstance()->getActiveFloater(); + const LLFloater* frontmost_floater = LLFloaterChatterBox::getInstance()->getActiveFloater(); bold_if_equal(LLFloaterMyFriends::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterMyFriends::getInstance()->getShortTitle(), LLSD("contacts"), ADD_TOP)); bold_if_equal(LLFloaterChat::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterChat::getInstance()->getShortTitle(), LLSD("local chat"), ADD_TOP)); mCommunicateBtn->addSeparator(ADD_TOP); @@ -300,11 +258,11 @@ void LLToolBar::updateCommunicateList() { if (LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)floater_handle_it->get()) { - S32 count = im_floaterp->getNumUnreadMessages(); + const S32 count = im_floaterp->getNumUnreadMessages(); std::string floater_title; if (count > 0) floater_title = "*"; floater_title.append(im_floaterp->getShortTitle()); - static LLCachedControl show_counts("ShowUnreadIMsCounts", true); + static const LLCachedControl show_counts("ShowUnreadIMsCounts", true); if (show_counts && count > 0) { floater_title += " - "; @@ -323,7 +281,8 @@ void LLToolBar::updateCommunicateList() } } - mCommunicateBtn->setToggleState(gSavedSettings.getBOOL("ShowCommunicate")); + static const LLCachedControl show_comm("ShowCommunicate", true); + mCommunicateBtn->setToggleState(show_comm); if (!selected.isUndefined()) mCommunicateBtn->setValue(selected); } diff --git a/indra/newview/lltoolbar.h b/indra/newview/lltoolbar.h index 23307a78b..958c0b4bc 100644 --- a/indra/newview/lltoolbar.h +++ b/indra/newview/lltoolbar.h @@ -41,10 +41,6 @@ // "Constants" loaded from settings.xml at start time extern S32 TOOL_BAR_HEIGHT; -#if LL_DARWIN - class LLFakeResizeHandle; -#endif // LL_DARWIN - class LLFlyoutButton; class LLToolBar @@ -62,11 +58,6 @@ public: EAcceptance* accept, std::string& tooltip_msg); - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); - - // Move buttons to appropriate locations based on rect. - void layoutButtons(); - // Per-frame refresh call void refresh(); @@ -79,12 +70,8 @@ private: void updateCommunicateList(); private: - BOOL mInventoryAutoOpen; LLFrameTimer mInventoryAutoOpenTimer; S32 mNumUnreadIMs; -#if LL_DARWIN - LLFakeResizeHandle *mResizeHandle; -#endif // LL_DARWIN CachedUICtrl mCommunicateBtn; CachedUICtrl mFlyBtn; diff --git a/indra/newview/llurlhistory.cpp b/indra/newview/llurlhistory.cpp index 876ce02d4..57fc7e3f8 100644 --- a/indra/newview/llurlhistory.cpp +++ b/indra/newview/llurlhistory.cpp @@ -106,39 +106,6 @@ LLSD LLURLHistory::getURLHistory(const std::string& collection) return LLSD(); } -// OGPX : static function that appends unique values to existing collection. -// returns true if appended, else false. -BOOL LLURLHistory::appendToURLCollection(const std::string& collection, const std::string& url) -{ - if (!url.empty()) - { - BOOL found_current_url = FALSE; - // make room for the new url if needed - // always append to the end and remove from the front so you have the most recent. - if (sHistorySD[collection].size() >= MAX_URL_COUNT) - { - sHistorySD[collection].erase(0); - } - - LLSD::array_iterator iter_history = sHistorySD[collection].beginArray(); - LLSD::array_iterator iter_end = sHistorySD[collection].endArray(); - for (; iter_history != iter_end; ++iter_history) - { - if ((*iter_history).asString() == url) - { - found_current_url = TRUE; - } - } - if (!found_current_url ) - { - sHistorySD[collection].append(LLSD(url)); - LLURLHistory::limitSize(collection); - //llinfos << " appending XX" << url << "XX urlcollection: " << LLSDOStreamer(sHistorySD) << llendl; - return TRUE; // value was unique, needed to be inserted - } - } - return FALSE; // value was empty or already in the collection -} // static void LLURLHistory::addURL(const std::string& collection, const std::string& url) { diff --git a/indra/newview/llurlhistory.h b/indra/newview/llurlhistory.h index 1c7e6637c..2b9d41429 100644 --- a/indra/newview/llurlhistory.h +++ b/indra/newview/llurlhistory.h @@ -49,9 +49,6 @@ public: static LLSD getURLHistory(const std::string& collection); static void addURL(const std::string& collection, const std::string& url); - // OGPX appends url to a collection if it doesn't already exist in the collection. - // this is used in the collection of region URIs that are saved per region - static BOOL appendToURLCollection(const std::string& collection, const std::string& url); static void removeURL(const std::string& collection, const std::string& url); static void clear(const std::string& collection); diff --git a/indra/newview/lluserauth.cpp b/indra/newview/lluserauth.cpp index c2f00bb68..21e9835ea 100644 --- a/indra/newview/lluserauth.cpp +++ b/indra/newview/lluserauth.cpp @@ -40,7 +40,6 @@ #include "lldir.h" #include "sgversion.h" #include "llappviewer.h" -#include "llviewerbuild.h" #include "llviewercontrol.h" #include "llxmlrpcresponder.h" #include "llsdutil.h" diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 7a6b74e35..8f7a0ed65 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -96,6 +96,7 @@ void precache_audio() gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTyping"))); gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowClose"))); gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen"))); + gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndRestart"))); } } diff --git a/indra/newview/llviewerbuild.h b/indra/newview/llviewerbuild.h deleted file mode 100644 index b02bdece5..000000000 --- a/indra/newview/llviewerbuild.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file llviewerbuild.h - * @brief Sets viewer build number - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "sgversion.h" - -// Set the build number in indra/llcommon/llversionviewer.h! - -const S32 LL_VIEWER_BUILD = gVersionBuild; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 877bfdce3..483b80ab9 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -870,6 +870,13 @@ void upload_new_resource(const std::string& src_filename, std::string name, asset_type = LLAssetType::AT_ANIMATION; filename = src_filename; } + else if(exten == "lsl" || exten == "gesture" || exten == "notecard") + { + if (exten == "lsl") asset_type = LLAssetType::AT_LSL_TEXT; + else if (exten == "gesture") asset_type = LLAssetType::AT_GESTURE; + else if (exten == "notecard") asset_type = LLAssetType::AT_NOTECARD; + filename = src_filename; + } // else { diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a2adc49a9..dbd630fb9 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -67,6 +67,7 @@ #include "llfloatermute.h" #include "llfloaterpostcard.h" #include "llfloaterpreference.h" +#include "llfloaterregionrestarting.h" #include "llfloaterteleporthistory.h" #include "llgroupactions.h" #include "llhudeffecttrail.h" @@ -2293,9 +2294,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } // These bools are here because they would make mess of logic down below in IM_NOTHING_SPECIAL. - bool is_autorespond = !is_muted && (is_friend || !gSavedPerAccountSettings.getBOOL("AutoresponseAnyoneFriendsOnly")) && gSavedPerAccountSettings.getBOOL("AutoresponseAnyone"); + bool autorespond_status = gAgent.getAFK() || !gSavedPerAccountSettings.getBOOL("AutoresponseOnlyIfAway") || gSavedSettings.getBOOL("FakeAway"); + bool is_autorespond = !is_muted && autorespond_status && (is_friend || !gSavedPerAccountSettings.getBOOL("AutoresponseAnyoneFriendsOnly")) && gSavedPerAccountSettings.getBOOL("AutoresponseAnyone"); bool is_autorespond_muted = is_muted && gSavedPerAccountSettings.getBOOL("AutoresponseMuted"); - bool is_autorespond_nonfriends = !is_friend && !is_muted && gSavedPerAccountSettings.getBOOL("AutoresponseNonFriends"); + bool is_autorespond_nonfriends = !is_friend && !is_muted && autorespond_status && gSavedPerAccountSettings.getBOOL("AutoresponseNonFriends"); LLSD args; switch(dialog) @@ -5772,7 +5774,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data) } } - if (num_blocks) + //if (num_blocks) Singu note: commented out; having blocks or not is totally irrelevant! { avatarp->processAnimationStateChanges(); } @@ -6434,7 +6436,6 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock) std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); LLStringUtil::toLower(regionMaturity); llsdBlock["REGIONMATURITY"] = regionMaturity; - bool returnValue = false; LLNotificationPtr maturityLevelNotification; std::string notifySuffix = "_Notify"; @@ -6583,6 +6584,37 @@ void home_position_set() gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE); } +void update_region_restart(const LLSD& llsdBlock) +{ + U32 seconds; + if (llsdBlock.has("MINUTES")) + { + seconds = 60U * static_cast(llsdBlock["MINUTES"].asInteger()); + } + else + { + seconds = static_cast(llsdBlock["SECONDS"].asInteger()); + } + + LLFloaterRegionRestarting* restarting_floater = LLFloaterRegionRestarting::findInstance(); + + if (restarting_floater) + { + restarting_floater->updateTime(seconds); + if (!restarting_floater->isMinimized()) + restarting_floater->center(); + } + else + { + LLSD params; + params["NAME"] = llsdBlock["NAME"]; + params["SECONDS"] = (LLSD::Integer)seconds; + LLFloaterRegionRestarting::showInstance(params); + if (gSavedSettings.getBOOL("LiruRegionRestartMinimized")) + LLFloaterRegionRestarting::findInstance()->setMinimized(true); + } +} + bool attempt_standard_notification(LLMessageSystem* msgsystem) { // if we have additional alert data @@ -6654,6 +6686,12 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) { LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT); } + else if (notificationID == "RegionRestartMinutes" || notificationID == "RegionRestartSeconds") + { + update_region_restart(llsdBlock); + LLUI::sAudioCallback(LLUUID(gSavedSettings.getString("UISndRestart"))); + return true; // Floater is enough. + } LLNotificationsUtil::add(notificationID, llsdBlock); return true; @@ -6712,7 +6750,6 @@ bool handle_not_age_verified_alert(const std::string &pAlertName) bool handle_special_alerts(const std::string &pAlertName) { bool isHandled = false; - if (LLStringUtil::compareStrings(pAlertName, "NotAgeVerified") == 0) { @@ -6763,17 +6800,27 @@ void process_alert_core(const std::string& message, BOOL modal) S32 mins = 0; LLStringUtil::convertToS32(text.substr(18), mins); args["MINUTES"] = llformat("%d",mins); - LLNotificationsUtil::add("RegionRestartMinutes", args); + update_region_restart(args); + //LLNotificationsUtil::add("RegionRestartMinutes", args); // Floater is enough. + LLUI::sAudioCallback(LLUUID(gSavedSettings.getString("UISndRestart"))); } else if (text.substr(0,17) == "RESTART_X_SECONDS") { S32 secs = 0; LLStringUtil::convertToS32(text.substr(18), secs); args["SECONDS"] = llformat("%d",secs); - LLNotificationsUtil::add("RegionRestartSeconds", args); + update_region_restart(args); + //LLNotificationsUtil::add("RegionRestartSeconds", args); // Floater is enough. + LLUI::sAudioCallback(LLUUID(gSavedSettings.getString("UISndRestart"))); } else { + // *NOTE: If the text from the server ever changes this line will need to be adjusted. + if (text.substr(0, 25) == "Region restart cancelled.") + { + LLFloaterRegionRestarting::hideInstance(); + } + std::string new_msg =LLNotificationTemplates::instance().getGlobalString(text); // [RLVa:KB] - Checked: 2012-02-07 (RLVa-1.4.5) | Added: RLVa-1.4.5 if ( (new_msg == text) && (rlv_handler_t::isEnabled()) ) @@ -6872,6 +6919,32 @@ void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_ } } +void chat_mean_collision(const LLUUID& id, const LLAvatarName& avname, const EMeanCollisionType& type, const F32& mag) +{ + LLStringUtil::format_map_t args; + if (type == MEAN_BUMP) + args["ACT"] = LLTrans::getString("bump"); + else if (type == MEAN_LLPUSHOBJECT) + args["ACT"] = LLTrans::getString("llpushobject"); + else if (type == MEAN_SELECTED_OBJECT_COLLIDE) + args["ACT"] = LLTrans::getString("selected_object_collide"); + else if (type == MEAN_SCRIPTED_OBJECT_COLLIDE) + args["ACT"] = LLTrans::getString("scripted_object_collide"); + else if (type == MEAN_PHYSICAL_OBJECT_COLLIDE) + args["ACT"] = LLTrans::getString("physical_object_collide"); + else + return; // How did we get here? I used to know you so well. + std::string name; + LLAvatarNameCache::getPNSName(avname, name); + args["NAME"] = name; + args["MAG"] = llformat("%f", mag); + LLChat chat(LLTrans::getString("BumpedYou", args)); + chat.mFromName = name; + chat.mURL = llformat("secondlife:///app/agent/%s/about", id.asString().c_str()); + chat.mSourceType = CHAT_SOURCE_SYSTEM; + LLFloaterChat::addChat(chat); +} + void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **user_data) { if (gAgent.inPrelude()) @@ -6901,6 +6974,8 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use msgsystem->getU8Fast(_PREHASH_MeanCollision, _PREHASH_Type, u8type); type = (EMeanCollisionType)u8type; + static const LLCachedControl chat_collision("AnnounceBumps"); + if (chat_collision) LLAvatarNameCache::get(perp, boost::bind(chat_mean_collision, _1, _2, type, mag)); BOOL b_found = FALSE; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 2aa0e3869..21003bcb1 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -514,6 +514,7 @@ public: inline BOOL flagCameraSource() const { return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); } inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); } + inline bool getPhysicsShapeUnknown() const { return mPhysicsShapeUnknown; } U8 getPhysicsShapeType() const; inline F32 getPhysicsGravity() const { return mPhysicsGravity; } inline F32 getPhysicsFriction() const { return mPhysicsFriction; } diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp index b93cd6b2c..e19e58afd 100644 --- a/indra/newview/llviewerobjectbackup.cpp +++ b/indra/newview/llviewerobjectbackup.cpp @@ -44,6 +44,7 @@ #include "llimage.h" #include "llimagej2c.h" #include "lllfsthread.h" +#include "llnotificationsutil.h" #include "llsdserialize.h" #include "llsdutil.h" #include "llsdutil_math.h" @@ -62,8 +63,8 @@ #include "llfloatersnapshot.h" #include "llinventorymodel.h" // gInventory #include "llinventoryfunctions.h" -#include "llnotificationsutil.h" #include "llresourcedata.h" +#include "llmaterialmgr.h" #include "llselectmgr.h" #include "llstatusbar.h" #include "lltexturecache.h" @@ -94,27 +95,9 @@ static LLUUID LL_TEXTURE_INVISIBLE = LLUUID("38b86f85-2575-52a9-a531-23108d8da8 static LLUUID LL_TEXTURE_TRANSPARENT = LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); static LLUUID LL_TEXTURE_MEDIA = LLUUID("8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"); -void setDefaultTextures() -{ - if (!gHippoGridManager->getConnectedGrid()->isSecondLife()) - { - // When not in SL (no texture perm check needed), we can get these - // defaults from the user settings... - LL_TEXTURE_PLYWOOD = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); - LL_TEXTURE_BLANK = LLUUID(gSavedSettings.getString("UIImgWhiteUUID")); - if (gSavedSettings.controlExists("UIImgInvisibleUUID")) - { - // This control only exists in the Cool VL Viewer (added by the - // AllowInvisibleTextureInPicker patch) - LL_TEXTURE_INVISIBLE = LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")); - } - } -} - class importResponder : public LLNewAgentInventoryResponder { public: - importResponder(const LLSD& post_data, const LLUUID& vfile_id, LLAssetType::EType asset_type) : LLNewAgentInventoryResponder(post_data, vfile_id, asset_type) { @@ -136,15 +119,11 @@ public: { gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); gMessageSystem->nextBlockFast(_PREHASH_MoneyData); gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); gAgent.sendReliableMessage(); - -// LLStringUtil::format_map_t args; -// args["[AMOUNT]"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()); -// LLNotifyBox::showXml("UploadPayment", args); } // Actually add the upload to viewer inventory @@ -154,7 +133,7 @@ public: { LLPermissions perm; U32 next_owner_perm; - perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + perm.init(gAgentID, gAgentID, LLUUID::null, LLUUID::null); if (mPostData["inventory_type"].asString() == "snapshot") { next_owner_perm = PERM_ALL; @@ -203,9 +182,11 @@ public: { setImage(image); } + void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) { - if (imageformat == IMG_CODEC_TGA && mFormattedImage->getCodec() == IMG_CODEC_J2C) + if (imageformat == IMG_CODEC_TGA && + mFormattedImage->getCodec() == IMG_CODEC_J2C) { LL_WARNS("ObjectBackup") << "FAILED: texture " << mID << " is formatted as TGA. Not saving." << LL_ENDL; LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_BAD_ENCODING; @@ -236,7 +217,7 @@ public: std::string name; mID.toString(name); name = LLObjectBackup::getInstance()->getfolder() + "//" + name; - LL_INFOS("ObjectBackup") << "Saving to " << name << LL_ENDL; + LL_INFOS("ObjectBackup") << "Saving to " << name << LL_ENDL; if (!mFormattedImage->save(name)) { LL_WARNS("ObjectBackup") << "FAILED to save texture " << mID << LL_ENDL; @@ -257,10 +238,9 @@ public: } } - LLObjectBackup::getInstance()->mNextTextureReady = true; - //JUST SAY NO TO APR DEADLOCKING - //LLObjectBackup::getInstance()->exportNextTexture(); + LLObjectBackup::getInstance()->mCheckNextTexture = true; } + private: LLPointer mFormattedImage; LLUUID mID; @@ -269,13 +249,13 @@ private: LLObjectBackup::LLObjectBackup() : LLFloater(std::string("Object Backup Floater"), std::string("FloaterObjectBackuptRect"), LLStringUtil::null) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_object_backup.xml"); + //buildFromFile("floater_object.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_object_backup.xml", NULL, false); mRunning = false; mTexturesList.clear(); mAssetMap.clear(); - mCurrentAsset = LLUUID::null; + mCurrentAsset.setNull(); mRetexture = false; - close(); } //////////////////////////////////////////////////////////////////////////////// @@ -283,7 +263,9 @@ LLObjectBackup::LLObjectBackup() LLObjectBackup* LLObjectBackup::getInstance() { if (!sInstance) + { sInstance = new LLObjectBackup(); + } return sInstance; } @@ -294,11 +276,6 @@ LLObjectBackup::~LLObjectBackup() sInstance = NULL; } -void LLObjectBackup::draw() -{ - LLFloater::draw(); -} - void LLObjectBackup::show(bool exporting) { // set the title @@ -367,11 +344,11 @@ void LLObjectBackup::updateImportNumbers() void LLObjectBackup::exportObject() { mTexturesList.clear(); + mBadPermsTexturesList.clear(); mLLSD.clear(); mThisGroup.clear(); - setDefaultTextures(); - LLSelectMgr::getInstance()->getSelection()->ref(); + LLSelectMgr::getInstance()->getSelection()->ref(); // Open the file save dialog AIFilePicker* filepicker = AIFilePicker::create(); @@ -384,7 +361,7 @@ void LLObjectBackup::exportObject_continued(AIFilePicker* filepicker) if (!filepicker->hasFilename()) { // User canceled save. - LLSelectMgr::getInstance()->getSelection()->unref(); + LLSelectMgr::getInstance()->getSelection()->unref(); return; } @@ -392,14 +369,32 @@ void LLObjectBackup::exportObject_continued(AIFilePicker* filepicker) mFolder = gDirUtilp->getDirName(mFileName); mNonExportedTextures = TEXTURE_OK; - mExportState = EXPORT_INIT; + mGotExtraPhysics = !gAgent.getRegion()->getCapability("GetObjectPhysicsData").empty(); gIdleCallbacks.addFunction(exportWorker, NULL); } -bool LLObjectBackup::validatePerms(const LLPermissions *item_permissions) +//---------------------------------------------------------------------------// +// Permissions checking functions +//---------------------------------------------------------------------------// + +//static +void LLObjectBackup::setDefaultTextures() { - return item_permissions->allowExportBy(gAgent.getID(), LFSimFeatureHandler::instance().exportPolicy()); + if (LFSimFeatureHandler::instance().exportPolicy() == ep_full_perm) + { + // When not in SL and not in an OpenSIM grid with export permission + // support (i.e. when no texture permission check is needed), we can + // get these defaults from the user settings... + LL_TEXTURE_PLYWOOD = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); + LL_TEXTURE_BLANK = LLUUID(gSavedSettings.getString("UIImgWhiteUUID")); + LL_TEXTURE_INVISIBLE = LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")); + } +} + +bool LLObjectBackup::validatePerms(const LLPermissions* item_permissions) +{ + return item_permissions->allowExportBy(gAgentID, LFSimFeatureHandler::instance().exportPolicy()); } // So far, only Second Life forces TPVs to verify the creator for textures... @@ -411,15 +406,21 @@ bool LLObjectBackup::validatePerms(const LLPermissions *item_permissions) // The "must be creator" stuff also goes against the usage in Linden Lab's own // official viewers, since those allow you to save full perm textures (such as // the textures in the Library), whoever is the actual creator... Go figure ! -LLUUID LLObjectBackup::validateTextureID(LLUUID asset_id) +LLUUID LLObjectBackup::validateTextureID(const LLUUID& asset_id) { if (!gHippoGridManager->getConnectedGrid()->isSecondLife()) { // If we are not in Second Life, don't bother. return asset_id; } - LLUUID texture = LL_TEXTURE_PLYWOOD; - if (asset_id == texture || + + if (mBadPermsTexturesList.count(asset_id)) + { + // We already checked it and know it's bad... + return LL_TEXTURE_PLYWOOD; + } + + if (asset_id == LL_TEXTURE_PLYWOOD || asset_id == LL_TEXTURE_BLANK || asset_id == LL_TEXTURE_INVISIBLE || asset_id == LL_TEXTURE_TRANSPARENT || @@ -428,127 +429,205 @@ LLUUID LLObjectBackup::validateTextureID(LLUUID asset_id) // Allow to export a few default SL textures. return asset_id; } + LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; LLAssetIDMatches asset_id_matches(asset_id); - gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, + gInventory.collectDescendentsIf(LLUUID::null, cats, items, LLInventoryModel::INCLUDE_TRASH, asset_id_matches); - - if (items.count()) + S32 count = items.size(); + if (count > 0) { - for (S32 i = 0; i < items.count(); i++) + for (S32 i = 0; i < count; ++i) { const LLPermissions item_permissions = items[i]->getPermissions(); if (validatePerms(&item_permissions)) { - texture = asset_id; + return asset_id; } } } - if (texture != asset_id) { + mBadPermsTexturesList.insert(asset_id); // Cache bad texture ID mNonExportedTextures |= TEXTURE_BAD_PERM; + LL_WARNS("ObjectBackup") << "Bad permissions for texture ID: " << asset_id + << " - Texture will not be exported." << LL_ENDL; + return LL_TEXTURE_PLYWOOD; } - - return texture; } + +//---------------------------------------------------------------------------// + void LLObjectBackup::exportWorker(void *userdata) { - LLObjectBackup::getInstance()->updateExportNumbers(); + getInstance()->updateExportNumbers(); - switch (LLObjectBackup::getInstance()->mExportState) + switch (getInstance()->mExportState) { case EXPORT_INIT: + { + getInstance()->show(true); + // Fall through to EXPORT_CHECK_PERMS + } + case EXPORT_CHECK_PERMS: + { + struct ff : public LLSelectedNodeFunctor { - LLObjectBackup::getInstance()->show(true); - struct ff : public LLSelectedNodeFunctor + virtual bool apply(LLSelectNode* node) { - virtual bool apply(LLSelectNode* node) - { - return LLObjectBackup::getInstance()->validatePerms(node->mPermissions); - } - } func; + return getInstance()->validatePerms(node->mPermissions); + } + } func; + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (object) + { if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func, false)) { - LLObjectBackup::getInstance()->mExportState = EXPORT_STRUCTURE; + getInstance()->mExportState = EXPORT_FETCH_PHYSICS; } else { - LL_WARNS("ObjectBackup") << "Incorrect permission to export" << LL_ENDL; - LLObjectBackup::getInstance()->mExportState = EXPORT_FAILED; - LLSelectMgr::getInstance()->getSelection()->unref(); + struct vv : public LLSelectedNodeFunctor + { + virtual bool apply(LLSelectNode* node) + { + return node->mValid; + } + } func2; + + if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func2, false)) + { + LL_WARNS("ObjectBackup") << "Incorrect permission to export" << LL_ENDL; + getInstance()->mExportState = EXPORT_FAILED; + LLSelectMgr::getInstance()->getSelection()->unref(); + } + else + { + LL_DEBUGS("ObjectBackup") << "Nodes permissions not yet received, delaying..." + << LL_ENDL; + getInstance()->mExportState = EXPORT_CHECK_PERMS; + } } } - break; - - case EXPORT_STRUCTURE: + else { - struct ff : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - bool is_attachment = object->isAttachment(); - object->boostTexturePriority(TRUE); - LLViewerObject::child_list_t children = object->getChildren(); - children.push_front(object); //push root onto list - LLSD prim_llsd = LLObjectBackup::getInstance()->primsToLLSD(children, is_attachment); - LLSD stuff; - if (is_attachment) - { - stuff["root_position"] = object->getPositionEdit().getValue(); - stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotationEdit()); - } - else - { - stuff["root_position"] = object->getPosition().getValue(); - stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation()); - } - stuff["group_body"] = prim_llsd; - LLObjectBackup::getInstance()->mLLSD["data"].append(stuff); - return true; - } - } func; - - LLObjectBackup::getInstance()->mExportState = EXPORT_LLSD; - LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, false); + LLObjectBackup::getInstance()->mExportState = EXPORT_FAILED; LLSelectMgr::getInstance()->getSelection()->unref(); } break; + } + + case EXPORT_FETCH_PHYSICS: + { + // Don't bother to try and fetch the extra physics flags if we + // don't have sim support for them... + if (!getInstance()->mGotExtraPhysics) + { + getInstance()->mExportState = EXPORT_STRUCTURE; + break; + } + + struct ff : public LLSelectedNodeFunctor + { + virtual bool apply(LLSelectNode* node) + { + LLViewerObject* object = node->getObject(); + return object->getPhysicsShapeUnknown(); + } + } func; + + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (object) + { + if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func, false)) + { + getInstance()->mExportState = EXPORT_STRUCTURE; + } + else + { + LL_DEBUGS("ObjectBackup") << "Nodes physics not yet received, delaying..." + << LL_ENDL; + } + } + else + { + getInstance()->mExportState = EXPORT_FAILED; + LLSelectMgr::getInstance()->getSelection()->unref(); + } + break; + } + + case EXPORT_STRUCTURE: + { + struct ff : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + bool is_attachment = object->isAttachment(); + object->boostTexturePriority(true); + LLViewerObject::child_list_t children = object->getChildren(); + children.push_front(object); //push root onto list + LLSD prim_llsd = LLObjectBackup::getInstance()->primsToLLSD(children, is_attachment); + LLSD stuff; + if (is_attachment) + { + stuff["root_position"] = object->getPositionEdit().getValue(); + stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotationEdit()); + } + else + { + stuff["root_position"] = object->getPosition().getValue(); + stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation()); + } + stuff["group_body"] = prim_llsd; + getInstance()->mLLSD["data"].append(stuff); + return true; + } + } func; + + getInstance()->mExportState = EXPORT_LLSD; + LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, false); + LLSelectMgr::getInstance()->getSelection()->unref(); + break; + } case EXPORT_TEXTURES: - if (LLObjectBackup::getInstance()->mNextTextureReady == false) - return; - - // Ok we got work to do - LLObjectBackup::getInstance()->mNextTextureReady = false; - - if (LLObjectBackup::getInstance()->mTexturesList.empty()) + { + if (!getInstance()->mCheckNextTexture) { - LLObjectBackup::getInstance()->mExportState = EXPORT_DONE; + // The texture is being fetched. Wait till next idle callback. return; } - LLObjectBackup::getInstance()->exportNextTexture(); + if (getInstance()->mTexturesList.empty()) + { + getInstance()->mExportState = EXPORT_DONE; + return; + } + + // Ok, we got work to do... + getInstance()->mCheckNextTexture= false; + getInstance()->exportNextTexture(); break; + } case EXPORT_LLSD: - { - // Create a file stream and write to it - llofstream export_file(LLObjectBackup::getInstance()->mFileName); - LLSDSerialize::toPrettyXML(LLObjectBackup::getInstance()->mLLSD, export_file); - export_file.close(); - LLObjectBackup::getInstance()->mNextTextureReady = true; - LLObjectBackup::getInstance()->mExportState = EXPORT_TEXTURES; - } + { + // Create a file stream and write to it + llofstream export_file(getInstance()->mFileName); + LLSDSerialize::toPrettyXML(getInstance()->mLLSD, export_file); + export_file.close(); + getInstance()->mCheckNextTexture = true; + getInstance()->mExportState = EXPORT_TEXTURES; break; + } case EXPORT_DONE: + { gIdleCallbacks.deleteFunction(exportWorker); if (LLObjectBackup::getInstance()->mNonExportedTextures == LLObjectBackup::TEXTURE_OK) { @@ -559,23 +638,23 @@ void LLObjectBackup::exportWorker(void *userdata) { LL_INFOS("ObjectBackup") << "Export successful but incomplete: some texture(s) not saved." << LL_ENDL; std::string reason; - if (LLObjectBackup::getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_BAD_PERM) + if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_BAD_PERM) { reason += "\nBad permissions/creator."; } - if (LLObjectBackup::getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_MISSING) + if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_MISSING) { reason += "\nMissing texture (retrying after full rezzing might work)."; } - if (LLObjectBackup::getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_BAD_ENCODING) + if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_BAD_ENCODING) { reason += "\nBad texture encoding."; } - if (LLObjectBackup::getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_IS_NULL) + if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_IS_NULL) { reason += "\nNull texture."; } - if (LLObjectBackup::getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_SAVED_FAILED) + if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_SAVED_FAILED) { reason += "\nCould not write to disk."; } @@ -583,15 +662,18 @@ void LLObjectBackup::exportWorker(void *userdata) args["REASON"] = reason; LLNotificationsUtil::add("ExportPartial", args); } - LLObjectBackup::getInstance()->close(); + getInstance()->close(); break; + } case EXPORT_FAILED: + { gIdleCallbacks.deleteFunction(exportWorker); LL_WARNS("ObjectBackup") << "Export process aborted." << LL_ENDL; LLNotificationsUtil::add("ExportFailed"); LLObjectBackup::getInstance()->close(); break; + } } } @@ -600,22 +682,25 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i LLViewerObject* object; LLSD llsd; char localid[16]; + LLUUID t_id; - for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) + for (LLViewerObject::child_list_t::iterator i = child_list.begin(); + i != child_list.end(); ++i) { object = (*i); LLUUID id = object->getID(); LL_INFOS("ObjectBackup") << "Exporting prim " << object->getID().asString() << LL_ENDL; - // Create an LLSD object that represents this prim. It will be injected in to the overall LLSD - // tree structure + // Create an LLSD object that represents this prim. It will be injected + // in to the overall LLSD tree structure LLSD prim_llsd; if (!object->isRoot()) { // Parent id - snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID()); + snprintf(localid, sizeof(localid), "%u", + object->getSubParent()->getLocalID()); prim_llsd["parent"] = localid; } @@ -641,9 +726,27 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i prim_llsd["scale"] = object->getScale().getValue(); // Flags - prim_llsd["shadows"] = FALSE; - prim_llsd["phantom"] = object->flagPhantom(); - prim_llsd["physical"] = object->flagUsePhysics(); + prim_llsd["phantom"] = object->flagPhantom(); // legacy + prim_llsd["physical"] = object->flagUsePhysics(); // legacy + prim_llsd["flags"] = (S32)object->getFlags(); // new way + + // Extra physics flags + if (mGotExtraPhysics) + { + LLSD& physics = prim_llsd["ExtraPhysics"]; + physics["PhysicsShapeType"] = object->getPhysicsShapeType(); + physics["Gravity"] = object->getPhysicsGravity(); + physics["Friction"] = object->getPhysicsFriction(); + physics["Density"] = object->getPhysicsDensity(); + physics["Restitution"] = object->getPhysicsRestitution(); + } + + // Click action + if (S32 action = object->getClickAction()) // Non-zero + prim_llsd["clickaction"] = action; + + // Prim material + prim_llsd["material"] = object->getMaterial(); // Volume params LLVolumeParams params = object->getVolume()->getParams(); @@ -656,124 +759,171 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); prim_llsd["flexible"] = flex->asLLSD(); } + if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT)) { // Light LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT); prim_llsd["light"] = light->asLLSD(); } + if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + // Light image + LLLightImageParams* light_param = (LLLightImageParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + t_id = validateTextureID(light_param->getLightTexture()); + if (mTexturesList.count(t_id) == 0) + { + LL_INFOS("ObjectBackup") << "Found a light texture, adding to list " << t_id << LL_ENDL; + mTexturesList.insert(t_id); + } + prim_llsd["light_texture"] = light_param->asLLSD(); + } + if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) { // Sculpt LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); prim_llsd["sculpt"] = sculpt->asLLSD(); - - LLUUID sculpt_texture = sculpt->getSculptTexture(); - if (sculpt_texture == validateTextureID(sculpt_texture)) + if ((sculpt->getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) { - bool alreadyseen = false; - std::list::iterator iter; - for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) + LLUUID sculpt_texture = sculpt->getSculptTexture(); + if (sculpt_texture == validateTextureID(sculpt_texture)) { - if ((*iter) == sculpt_texture) - alreadyseen = true; + if (mTexturesList.count(sculpt_texture) == 0) + { + LL_INFOS("ObjectBackup") << "Found a sculpt texture, adding to list " << sculpt_texture << LL_ENDL; + mTexturesList.insert(sculpt_texture); + } } - if (alreadyseen == false) + else { - LL_INFOS("ObjectBackup") << "Found a sculpt texture, adding to list " << sculpt_texture << LL_ENDL; - mTexturesList.push_back(sculpt_texture); + LL_WARNS("ObjectBackup") << "Incorrect permission to export a sculpt texture." << LL_ENDL; + getInstance()->mExportState = EXPORT_FAILED; } } - else - { - LL_WARNS("ObjectBackup") << "Incorrect permission to export a sculpt texture." << LL_ENDL; - LLObjectBackup::getInstance()->mExportState = EXPORT_FAILED; - } } - // Textures + // Textures and materials LLSD te_llsd; LLSD this_te_llsd; - LLUUID t_id; - U8 te_count = object->getNumTEs(); - for (U8 i = 0; i < te_count; i++) + LLSD te_mat_llsd; + LLSD this_te_mat_llsd; + bool has_materials = false; + for (U8 i = 0, count = object->getNumTEs(); i < count; ++i) { - bool alreadyseen = false; - t_id = validateTextureID(object->getTE(i)->getID()); - this_te_llsd = object->getTE(i)->asLLSD(); + LLTextureEntry* te = object->getTE(i); + if (!te) continue; // Paranoia + + // Normal texture/diffuse map + t_id = validateTextureID(te->getID()); + this_te_llsd = te->asLLSD(); this_te_llsd["imageid"] = t_id; te_llsd.append(this_te_llsd); // Do not export Linden textures even though they don't taint creation. - if (t_id != LL_TEXTURE_PLYWOOD && + if (t_id != LL_TEXTURE_PLYWOOD && t_id != LL_TEXTURE_BLANK && t_id != LL_TEXTURE_TRANSPARENT && t_id != LL_TEXTURE_INVISIBLE && t_id != LL_TEXTURE_MEDIA) - { - std::list::iterator iter; - for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) + { + if (mTexturesList.count(t_id) == 0) { - if ((*iter) == t_id) - alreadyseen = true; + mTexturesList.insert(t_id); } - if (alreadyseen == false) - mTexturesList.push_back(t_id); + } + + // Materials + LLMaterial* mat = te->getMaterialParams().get(); + if (mat) + { + has_materials = true; + this_te_mat_llsd = mat->asLLSD(); + + t_id = validateTextureID(mat->getNormalID()); + this_te_mat_llsd["NormMap"] = t_id; + if (mTexturesList.count(t_id) == 0) + { + mTexturesList.insert(t_id); + } + + t_id = validateTextureID(mat->getSpecularID()); + this_te_mat_llsd["SpecMap"] = t_id; + if (mTexturesList.count(t_id) == 0) + { + mTexturesList.insert(t_id); + } + + te_mat_llsd.append(this_te_mat_llsd); } } prim_llsd["textures"] = te_llsd; + if (has_materials) + { + prim_llsd["materials"] = te_mat_llsd; + } // The keys in the primitive maps do not have to be localids, they can be any // string. We simply use localids because they are a unique identifier snprintf(localid, sizeof(localid), "%u", object->getLocalID()); llsd[(const char*)localid] = prim_llsd; } + updateExportNumbers(); + return llsd; } void LLObjectBackup::exportNextTexture() { - if (mTexturesList.empty()) - { - LL_INFOS("ObjectBackup") << "Finished exporting textures." << LL_ENDL; - return; - } - LLUUID id; - std::list::iterator iter; - iter = mTexturesList.begin(); - + textures_set_t::iterator iter = mTexturesList.begin(); while (true) { + if (mTexturesList.empty()) + { + mCheckNextTexture = true; + LL_INFOS("ObjectBackup") << "Finished exporting textures." << LL_ENDL; + return; + } if (iter == mTexturesList.end()) { - mNextTextureReady = true; + // Not yet ready, wait and re-check at next idle callback... + mCheckNextTexture = true; return; } - id = (*iter); + id = *iter++; if (id.isNull()) { // NULL texture id: just remove and ignore. - mTexturesList.remove(id); - iter = mTexturesList.begin(); + mTexturesList.erase(id); + LL_DEBUGS("ObjectBackup") << "Null texture UUID found, ignoring." + << LL_ENDL; continue; } LLViewerTexture* imagep = LLViewerTextureManager::findTexture(id); - if (imagep != NULL) + if (imagep) { - S32 cur_discard = imagep->getDiscardLevel(); - if (cur_discard > 0) + if (imagep->getDiscardLevel() > 0) { - if (imagep->getBoostLevel() != LLGLTexture::BOOST_PREVIEW) + // Boost texture loading + imagep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + LL_DEBUGS("ObjectBackup") << "Boosting texture: " << id + << LL_ENDL; + LLViewerFetchedTexture* tex; + tex = LLViewerTextureManager::staticCastToFetchedTexture(imagep); + if (tex && tex->getDesiredDiscardLevel() > 0) { - // we want to force discard 0: this one does this. - imagep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + // Set min discard level to 0 + tex->setMinDiscardLevel(0); + LL_DEBUGS("ObjectBackup") << "Min discard level set to 0 for texture: " + << id << LL_ENDL; } } else { + // Texture is ready ! break; } } @@ -781,13 +931,11 @@ void LLObjectBackup::exportNextTexture() { LL_WARNS("ObjectBackup") << "We *DON'T* have the texture " << id.asString() << LL_ENDL; mNonExportedTextures |= TEXTURE_MISSING; - mTexturesList.remove(id); - return; + mTexturesList.erase(id); } - iter++; } - mTexturesList.remove(id); + mTexturesList.erase(id); LL_INFOS("ObjectBackup") << "Requesting texture " << id << LL_ENDL; LLImageJ2C* mFormattedImage = new LLImageJ2C; @@ -797,20 +945,19 @@ void LLObjectBackup::exportNextTexture() void LLObjectBackup::importObject(bool upload) { + mRetexture = upload; mTexturesList.clear(); mAssetMap.clear(); - mCurrentAsset = LLUUID::null; + mCurrentAsset.setNull(); + mGotExtraPhysics = !gAgent.getRegion()->getCapability("GetObjectPhysicsData").empty(); + setDefaultTextures(); - - mRetexture = upload; - + // Open the file open dialog AIFilePicker* filepicker = AIFilePicker::create(); filepicker->open(FFLOAD_XML, "", "import"); filepicker->run(boost::bind(&LLObjectBackup::importObject_continued, this, filepicker)); - - return; } void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) @@ -826,16 +973,20 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) llifstream import_file(file_name); LLSDSerialize::fromXML(mLLSD, import_file); import_file.close(); + if (!mLLSD.has("data")) + { + LLNotificationsUtil::add("InvalidObjectParams"); + close(); + return; + } + show(false); mAgentPos = gAgent.getPositionAgent(); - mAgentRot = LLQuaternion(gAgent.getAtAxis(), gAgent.getLeftAxis(), gAgent.getUpAxis()); + mAgentRot = LLQuaternion(gAgent.getAtAxis(), gAgent.getLeftAxis(), + gAgent.getUpAxis()); // Get the texture map - - LLSD::map_const_iterator prim_it; - LLSD::array_const_iterator prim_arr_it; - mCurObject = 1; mCurPrim = 1; mObjects = mLLSD["data"].size(); @@ -843,66 +994,101 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) mRezCount = 0; updateImportNumbers(); - for (prim_arr_it = mLLSD["data"].beginArray(); prim_arr_it != mLLSD["data"].endArray(); prim_arr_it++) + for (LLSD::array_const_iterator prim_arr_it = mLLSD["data"].beginArray(), + prim_arr_end = mLLSD["data"].endArray(); + prim_arr_it != prim_arr_end; ++prim_arr_it) { LLSD llsd2 = (*prim_arr_it)["group_body"]; - for (prim_it = llsd2.beginMap(); prim_it != llsd2.endMap(); prim_it++) + for (LLSD::map_const_iterator prim_it = llsd2.beginMap(), + prim_end = llsd2.endMap(); + prim_it != prim_end; ++prim_it) { LLSD prim_llsd = llsd2[prim_it->first]; - LLSD::array_iterator text_it; - std::list::iterator iter; - if (prim_llsd.has("sculpt")) { LLSculptParams sculpt; sculpt.fromLLSD(prim_llsd["sculpt"]); - LLUUID orig = sculpt.getSculptTexture(); - bool alreadyseen = false; - for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) + if ((sculpt.getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) { - if ((*iter) == orig) - alreadyseen = true; - } - if (alreadyseen == false) - { - LL_INFOS("ObjectBackup") << "Found a new SCULPT texture to upload " << orig << LL_ENDL; - mTexturesList.push_back(orig); + LLUUID orig = sculpt.getSculptTexture(); + if (mTexturesList.count(orig) == 0) + { + LL_INFOS("ObjectBackup") << "Found a new SCULPT texture to upload " << orig << LL_ENDL; + mTexturesList.insert(orig); + } } } - LLSD te_llsd = prim_llsd["textures"]; + LLSD& te_llsd = prim_llsd.has("textures") ? prim_llsd["textures"] : prim_llsd["texture"]; // Firestorm's format uses singular "texture" - for (text_it = te_llsd.beginArray(); text_it != te_llsd.endArray(); text_it++) + for (LLSD::array_iterator it = te_llsd.beginArray(); + it != te_llsd.endArray(); ++it) { - LLSD the_te = (*text_it); + LLSD the_te = *it; LLTextureEntry te; te.fromLLSD(the_te); - LLUUID id = te.getID(); - if (id != LL_TEXTURE_PLYWOOD && id != LL_TEXTURE_BLANK && id != LL_TEXTURE_INVISIBLE) // Do not upload the default textures - { - bool alreadyseen = false; + LLUUID t_id = te.getID(); + // Do not upload the default textures + if (t_id != LL_TEXTURE_PLYWOOD && t_id != LL_TEXTURE_BLANK && t_id != LL_TEXTURE_INVISIBLE) // Do not upload the default textures + { + if (mTexturesList.count(t_id) == 0) + { + LL_INFOS("ObjectBackup") << "Found a new texture to upload: "<< t_id << LL_ENDL; + mTexturesList.insert(t_id); + } + } + } - for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) + if (prim_llsd.has("materials")) + { + LLSD mat_llsd = prim_llsd["materials"]; + for (LLSD::array_iterator it = mat_llsd.beginArray(); + it != mat_llsd.endArray(); ++it) + { + LLSD the_mat = *it; + LLMaterial mat; + mat.fromLLSD(the_mat); + + LLUUID t_id = mat.getNormalID(); + if (t_id.notNull() && t_id != LL_TEXTURE_PLYWOOD && + t_id != LL_TEXTURE_BLANK && + t_id != LL_TEXTURE_INVISIBLE) { - if ((*iter) == te.getID()) - alreadyseen = true; + if (mTexturesList.count(t_id) == 0) + { + LL_INFOS("ObjectBackup") << "Found a new normal map to upload: " + << t_id << LL_ENDL; + mTexturesList.insert(t_id); + } } - if (alreadyseen == false) + + t_id = mat.getSpecularID(); + if (t_id.notNull() && t_id != LL_TEXTURE_PLYWOOD && + t_id != LL_TEXTURE_BLANK && + t_id != LL_TEXTURE_INVISIBLE) { - LL_INFOS("ObjectBackup") << "Found a new texture to upload "<< te.getID() << LL_ENDL; - mTexturesList.push_back(te.getID()); + if (mTexturesList.count(t_id) == 0) + { + LL_INFOS("ObjectBackup") << "Found a new specular map to upload: " + << t_id << LL_ENDL; + mTexturesList.insert(t_id); + } } - } + } } } } - if (mRetexture == TRUE) + if (mRetexture) + { uploadNextAsset(); + } else + { importFirstObject(); + } } LLVector3 LLObjectBackup::offsetAgent(LLVector3 offset) @@ -915,7 +1101,6 @@ void LLObjectBackup::rezAgentOffset(LLVector3 offset) // This will break for a sitting agent LLToolPlacer mPlacer; mPlacer.setObjectType(LL_PCODE_CUBE); - //LLVector3 pos = offsetAgent(offset); mPlacer.placeObject((S32)offset.mV[0], (S32)offset.mV[1], MASK_NONE); } @@ -948,10 +1133,12 @@ void LLObjectBackup::importNextObject() mRootRot = ll_quaternion_from_sd((*mGroupPrimImportIter)["root_rotation"]); rezAgentOffset(LLVector3(0.0, 2.0, 0.0)); - // Now we must wait for the callback when ViewerObjectList gets the new objects and we have the correct number selected + // Now we must wait for the callback when ViewerObjectList gets the new + // objects and we have the correct number selected } -// This function takes a pointer to a viewerobject and applies the prim definition that prim_llsd has +// This function takes a pointer to a viewerobject and applies the prim +// definition that prim_llsd has void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) { LLUUID id = object->getID(); @@ -968,6 +1155,16 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) LLSelectMgr::getInstance()->selectionSetObjectDescription(prim_llsd["description"]); } + if (prim_llsd.has("material")) + { + LLSelectMgr::getInstance()->selectionSetMaterial(prim_llsd["material"].asInteger()); + } + + if (prim_llsd.has("clickaction")) + { + LLSelectMgr::getInstance()->selectionSetClickAction(prim_llsd["clickaction"].asInteger()); + } + if (prim_llsd.has("parent")) { //we are not the root node. @@ -985,17 +1182,41 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) object->setScale(prim_llsd["scale"]); - /*if (prim_llsd.has("shadows")) - if (prim_llsd["shadows"].asInteger() == 1) - object->setFlags(FLAGS_CAST_SHADOWS, true);*/ + if (prim_llsd.has("flags")) + { + U32 flags(prim_llsd["flags"].asInteger()); + object->setFlags(flags, true); + } + else // Kept for backward compatibility + { + /*if (prim_llsd.has("shadows")) + if (prim_llsd["shadows"].asInteger() == 1) + object->setFlags(FLAGS_CAST_SHADOWS, true);*/ - if (prim_llsd.has("phantom")) - if (prim_llsd["phantom"].asInteger() == 1) - object->setFlags(FLAGS_PHANTOM, true); + if (prim_llsd.has("phantom") && prim_llsd["phantom"].asInteger() == 1) + { + object->setFlags(FLAGS_PHANTOM, true); + } - if (prim_llsd.has("physical")) - if (prim_llsd["physical"].asInteger() == 1) + if (prim_llsd.has("physical") && + prim_llsd["physical"].asInteger() == 1) + { object->setFlags(FLAGS_USE_PHYSICS, true); + } + } + + if (mGotExtraPhysics && prim_llsd.has("ExtraPhysics")) + { + const LLSD& physics = prim_llsd["ExtraPhysics"]; + object->setPhysicsShapeType(physics["PhysicsShapeType"].asInteger()); + F32 gravity = physics.has("Gravity") ? physics["Gravity"].asReal() + : physics["GravityMultiplier"].asReal(); + object->setPhysicsGravity(gravity); + object->setPhysicsFriction(physics["Friction"].asReal()); + object->setPhysicsDensity(physics["Density"].asReal()); + object->setPhysicsRestitution(physics["Restitution"].asReal()); + object->updateFlags(true); + } // Volume params LLVolumeParams volume_params = object->getVolume()->getParams(); @@ -1009,10 +1230,10 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) // TODO: check if map is valid and only set texture if map is valid and changes - if (mAssetMap[sculpt.getSculptTexture()].notNull()) + if (mAssetMap.count(sculpt.getSculptTexture())) { - LLUUID replacment = mAssetMap[sculpt.getSculptTexture()]; - sculpt.setSculptTexture(replacment); + LLUUID replacement = mAssetMap[sculpt.getSculptTexture()]; + sculpt.setSculptTexture(replacement); } object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt, true); @@ -1024,6 +1245,13 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) light.fromLLSD(prim_llsd["light"]); object->setParameterEntry(LLNetworkData::PARAMS_LIGHT, light, true); } + if (prim_llsd.has("light_texture")) + { + // Light image + LLLightImageParams lightimg; + lightimg.fromLLSD(prim_llsd["light_texture"]); + object->setParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE, lightimg, true); + } if (prim_llsd.has("flexible")) { @@ -1033,31 +1261,56 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) } // Textures - LL_INFOS("ObjectBackup") << "Processing textures for prim" << LL_ENDL; - LLSD te_llsd = prim_llsd["textures"]; - LLSD::array_iterator text_it; + LL_INFOS("ObjectBackup") << "Processing textures for prim" << id << LL_ENDL; + LLSD& te_llsd = prim_llsd.has("textures") ? prim_llsd["textures"] : prim_llsd["texture"]; // Firestorm's format uses singular "texture" U8 i = 0; - - for (text_it = te_llsd.beginArray(); text_it != te_llsd.endArray(); text_it++) + for (LLSD::array_iterator it = te_llsd.beginArray(); + it != te_llsd.endArray(); ++it) { - LLSD the_te = (*text_it); + LLSD the_te = *it; LLTextureEntry te; te.fromLLSD(the_te); - - if (mAssetMap[te.getID()].notNull()) + LLUUID t_id = te.getID(); + if (mAssetMap.count(t_id)) { - LLUUID replacment = mAssetMap[te.getID()]; - te.setID(replacment); + LLUUID replacement = mAssetMap[t_id]; + te.setID(replacement); } object->setTE(i++, te); } - LL_INFOS("ObjectBackup") << "Textures done !" << LL_ENDL; - //bump the iterator now so the callbacks hook together nicely - //if (mPrimImportIter != mThisGroup.endMap()) - // mPrimImportIter++; + // Materials + if (prim_llsd.has("materials")) + { + LL_INFOS("ObjectBackup") << "Processing materials for prim " << id << LL_ENDL; + te_llsd = prim_llsd["materials"]; + i = 0; + for (LLSD::array_iterator it = te_llsd.beginArray(); + it != te_llsd.endArray(); ++it) + { + LLSD the_mat = *it; + LLMaterialPtr mat = new LLMaterial(the_mat); + + LLUUID t_id = mat->getNormalID(); + if (id.notNull() && mAssetMap.count(t_id)) + { + LLUUID replacement = mAssetMap[t_id]; + mat->setNormalID(replacement); + } + + t_id = mat->getSpecularID(); + if (id.notNull() && mAssetMap.count(t_id)) + { + LLUUID replacement = mAssetMap[t_id]; + mat->setSpecularID(replacement); + } + + LLMaterialMgr::getInstance()->put(id, i++, *mat); + } + LL_INFOS("ObjectBackup") << "Materials done !" << LL_ENDL; + } object->sendRotationUpdate(); object->sendTEUpdate(); @@ -1070,16 +1323,14 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) // This is fired when the update packet is processed so we know the prim settings have stuck void LLObjectBackup::primUpdate(LLViewerObject* object) { - if (!mRunning) - return; - - if (object != NULL) - if (object->mID != mExpectingUpdate) + if (!mRunning || (object != NULL && object->mID != mExpectingUpdate)) + { return; + } - mCurPrim++; + ++mCurPrim; updateImportNumbers(); - mPrimImportIter++; + ++mPrimImportIter; LLUUID x; mExpectingUpdate = x.null; @@ -1099,8 +1350,8 @@ void LLObjectBackup::primUpdate(LLViewerObject* object) root->setRotation(mRootRot); } - mCurObject++; - mGroupPrimImportIter++; + ++mCurObject; + ++mGroupPrimImportIter; if (mGroupPrimImportIter != mLLSD["data"].endArray()) { importNextObject(); @@ -1117,6 +1368,8 @@ void LLObjectBackup::primUpdate(LLViewerObject* object) if (mToSelect.empty()) { LL_WARNS("ObjectBackup") << "error: ran out of objects to mod." << LL_ENDL; + mRunning = false; + close(); return; } @@ -1124,7 +1377,7 @@ void LLObjectBackup::primUpdate(LLViewerObject* object) { //rezAgentOffset(LLVector3(1.0, 0.0, 0.0)); LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; - mProcessIter++; + ++mProcessIter; xmlToPrim(prim_llsd, *mProcessIter); } } @@ -1134,10 +1387,10 @@ bool LLObjectBackup::newPrim(LLViewerObject* pobject) { if (mRunning) { - mRezCount++; + ++mRezCount; mToSelect.push_back(pobject); updateImportNumbers(); - mPrimImportIter++; + ++mPrimImportIter; pobject->setPosition(offsetAgent(LLVector3(0.0, 1.0, 0.0))); LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); @@ -1149,8 +1402,8 @@ bool LLObjectBackup::newPrim(LLViewerObject* pobject) else { LL_INFOS("ObjectBackup") << "All prims rezzed, moving to build stage" << LL_ENDL; - // Deselecting is required to ensure that the first child prim - // in the link set (which is also the last rezzed prim and thus + // Deselecting is required to ensure that the first child prim in + // the link set (which is also the last rezzed prim and thus // currently selected) will be properly renamed and desced. LLSelectMgr::getInstance()->deselectAll(); mPrimImportIter = mThisGroup.beginMap(); @@ -1164,17 +1417,22 @@ bool LLObjectBackup::newPrim(LLViewerObject* pobject) void LLObjectBackup::updateMap(LLUUID uploaded_asset) { - if (mCurrentAsset.isNull()) - return; + if (mCurrentAsset.notNull()) + { + LL_INFOS("ObjectBackup") << "Mapping " << mCurrentAsset << " to " << uploaded_asset << LL_ENDL; - LL_INFOS("ObjectBackup") << "Mapping " << mCurrentAsset << " to " << uploaded_asset << LL_ENDL; - mAssetMap.insert(std::pair(mCurrentAsset, uploaded_asset)); + mAssetMap[mCurrentAsset] = uploaded_asset; + } } -void myupload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, - std::string name, std::string desc, S32 compression_info, +void myupload_new_resource(const LLTransactionID &tid, + LLAssetType::EType asset_type, + std::string name, + std::string desc, + S32 compression_info, LLFolderType::EType destination_folder_type, - LLInventoryType::EType inv_type, U32 next_owner_perm, + LLInventoryType::EType inv_type, + U32 next_owner_perm, const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, void *userdata) @@ -1195,7 +1453,9 @@ void myupload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ if (!url.empty()) { LLSD body; - body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(asset_type) : destination_folder_type); + body["folder_id"] = gInventory.findCategoryUUIDForType(destination_folder_type == LLFolderType::FT_NONE ? + LLFolderType::assetTypeToFolderType(asset_type) : + destination_folder_type); body["asset_type"] = LLAssetType::lookup(asset_type); body["inventory_type"] = LLInventoryType::lookup(inv_type); body["name"] = name; @@ -1204,7 +1464,6 @@ void myupload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ std::ostringstream llsdxml; LLSDSerialize::toXML(body, llsdxml); LL_DEBUGS("ObjectBackup") << "posting body to capability: " << llsdxml.str() << LL_ENDL; - //LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type)); LLHTTPClient::post(url, body, new importResponder(body, uuid, asset_type)); } else @@ -1218,19 +1477,18 @@ void LLObjectBackup::uploadNextAsset() if (mTexturesList.empty()) { LL_INFOS("ObjectBackup") << "Texture list is empty, moving to rez stage." << LL_ENDL; - mCurrentAsset = LLUUID::null; + mCurrentAsset.setNull(); importFirstObject(); return; } updateImportNumbers(); - std::list::iterator iter; - iter = mTexturesList.begin(); + textures_set_t::iterator iter = mTexturesList.begin(); LLUUID id = *iter; - mTexturesList.pop_front(); + mTexturesList.erase(iter); - LL_INFOS("ObjectBackup") << "Got texture ID " << id << ": trying to upload" << LL_ENDL; + LL_INFOS("ObjectBackup") << "Got texture ID " << id << ": trying to upload..." << LL_ENDL; mCurrentAsset = id; std::string struid; @@ -1265,6 +1523,7 @@ void LLObjectBackup::uploadNextAsset() } myupload_new_resource(tid, LLAssetType::AT_TEXTURE, struid, struid, 0, - LLFolderType::FT_TEXTURE, LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE), + LLFolderType::FT_TEXTURE, + LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE), 0x0, "Uploaded texture", NULL, NULL); } diff --git a/indra/newview/llviewerobjectbackup.h b/indra/newview/llviewerobjectbackup.h index 27ae4f2f9..2b29d91fd 100644 --- a/indra/newview/llviewerobjectbackup.h +++ b/indra/newview/llviewerobjectbackup.h @@ -27,10 +27,18 @@ * $/LicenseInfo$ */ +#ifndef LL_LLVIEWEROBJECTBACKUP_H +#define LL_LLVIEWEROBJECTBACKUP_H + +#include "boost/unordered_map.hpp" +#include "boost/unordered_set.hpp" + #include "llviewerinventory.h" enum export_states { EXPORT_INIT, + EXPORT_CHECK_PERMS, + EXPORT_FETCH_PHYSICS, EXPORT_STRUCTURE, EXPORT_TEXTURES, EXPORT_LLSD, @@ -45,17 +53,17 @@ public: // Floater stuff virtual void show(bool exporting); - virtual void draw(); virtual void onClose(bool app_quitting); // Static accessor static LLObjectBackup* getInstance(); + static bool instanceExists() { return sInstance != NULL; } // Export idle callback static void exportWorker(void *userdata); // Import entry point - void importObject(bool upload=FALSE); + void importObject(bool upload = false); void importObject_continued(AIFilePicker* filepicker); // Export entry point @@ -69,7 +77,7 @@ public: void uploadNextAsset(); // Folder public geter - std::string getfolder() { return mFolder; }; + std::string getfolder() { return mFolder; } // Prim updated callback void primUpdate(LLViewerObject* object); @@ -84,8 +92,11 @@ public: static const U32 TEXTURE_IS_NULL = 0x08; static const U32 TEXTURE_SAVED_FAILED = 0x10; - // Is ready for next texture? - bool mNextTextureReady; + // Set when the region supports the extra physics flags + bool mGotExtraPhysics; + + // Are we ready to check for next texture? + bool mCheckNextTexture; // Export state machine enum export_states mExportState; @@ -93,23 +104,24 @@ public: // Export result flags for textures. U32 mNonExportedTextures; + static void setDefaultTextures(); + // Is exporting these objects allowed bool validatePerms(const LLPermissions* item_permissions); private: - // Static singleton stuff - LLObjectBackup(); - static LLObjectBackup* sInstance; + LLObjectBackup(); // Update the floater with status numbers void updateImportNumbers(); void updateExportNumbers(); // Permissions stuff. - LLUUID validateTextureID(LLUUID asset_id); + LLUUID validateTextureID(const LLUUID& asset_id); // Convert a selection list of objects to LLSD - LLSD primsToLLSD(LLViewerObject::child_list_t child_list, bool is_attachment); + LLSD primsToLLSD(LLViewerObject::child_list_t child_list, + bool is_attachment); // Start the import process void importFirstObject(); @@ -123,19 +135,18 @@ private: // Apply LLSD to object void xmlToPrim(LLSD prim_llsd, LLViewerObject* pobject); - // Rez a prim at a given position (note not agent offset X/Y screen for raycast) + // Rez a prim at a given position void rezAgentOffset(LLVector3 offset); // Get an offset from the agent based on rotation and current pos LLVector3 offsetAgent(LLVector3 offset); +private: + static LLObjectBackup* sInstance; + // Are we active flag bool mRunning; - // File and folder name control - std::string mFileName; - std::string mFolder; - // True if we need to rebase the assets bool mRetexture; @@ -148,26 +159,6 @@ private: // No prims rezed U32 mRezCount; - // Rebase map - std::map mAssetMap; - - // Export texture list - std::list mTexturesList; - - // Import object tracking - std::vector mToSelect; - std::vector::iterator mProcessIter; - - // Working LLSD holders - LLUUID mCurrentAsset; - LLSD mLLSD; - LLSD mThisGroup; - LLUUID mExpectingUpdate; - - // Working llsd itterators for objects and linksets - LLSD::map_const_iterator mPrimImportIter; - LLSD::array_const_iterator mGroupPrimImportIter; - // Root pos and rotation and central root pos for link set LLVector3 mRootPos; LLQuaternion mRootRot; @@ -177,5 +168,31 @@ private: // Agent inital pos and rot when starting import LLVector3 mAgentPos; LLQuaternion mAgentRot; + // Rebase map + boost::unordered_map mAssetMap; + + // Export texture list + typedef boost::unordered_set textures_set_t; + textures_set_t mTexturesList; + textures_set_t mBadPermsTexturesList; + + // Import object tracking + std::vector mToSelect; + std::vector::iterator mProcessIter; + + // File and folder name control + std::string mFileName; + std::string mFolder; + + // Working LLSD holders + LLUUID mCurrentAsset; + LLUUID mExpectingUpdate; + LLSD mLLSD; + LLSD mThisGroup; + + // Working llsd itterators for objects and linksets + LLSD::map_const_iterator mPrimImportIter; + LLSD::array_const_iterator mGroupPrimImportIter; }; +#endif \ No newline at end of file diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 6a77426b9..977d8fede 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -2228,7 +2228,7 @@ bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const void LLViewerParcelMgr::startBuyLand(BOOL is_for_group) { // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) - if (RlvActions::isRlvEnabled() && RlvActions::canShowLocation()) + if (RlvActions::isRlvEnabled() && !RlvActions::canShowLocation()) return; // [/RLVa:KB] if (selectionEmpty()) selectParcelAt(gAgent.getPositionGlobal()); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 57e63be70..82a70f65e 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -1667,7 +1667,7 @@ LLView* LLViewerTextEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlF node->getAttributeBOOL("hide_border", hide_border); text_editor->setBorderVisible(!hide_border); - BOOL parse_html = text_editor->mParseHTML; + BOOL parse_html = true; node->getAttributeBOOL("allow_html", parse_html); text_editor->setParseHTML(parse_html); text_editor->setParseHighlights(TRUE); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 62b4a9a60..26dae3313 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -145,18 +145,106 @@ using namespace LLAvatarAppearanceDefines; //----------------------------------------------------------------------------- // Global constants //----------------------------------------------------------------------------- -const LLUUID ANIM_AGENT_BODY_NOISE = LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise" -const LLUUID ANIM_AGENT_BREATHE_ROT = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot" -const LLUUID ANIM_AGENT_EDITING = LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb"); //"editing" -const LLUUID ANIM_AGENT_EYE = LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea"); //"eye" -const LLUUID ANIM_AGENT_FLY_ADJUST = LLUUID("db95561f-f1b0-9f9a-7224-b12f71af126e"); //"fly_adjust" -const LLUUID ANIM_AGENT_HAND_MOTION = LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578"); //"hand_motion" -const LLUUID ANIM_AGENT_HEAD_ROT = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d"); //"head_rot" -const LLUUID ANIM_AGENT_PELVIS_FIX = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b"); //"pelvis_fix" -const LLUUID ANIM_AGENT_TARGET = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55"); //"target" -const LLUUID ANIM_AGENT_WALK_ADJUST = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust" -const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df440d987"); //"physics_motion" +const LLUUID ANIM_AGENT_BODY_NOISE_ID = LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise" +const LLUUID ANIM_AGENT_BREATHE_ROT_ID = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot" +const LLUUID ANIM_AGENT_PHYSICS_MOTION_ID = LLUUID("7360e029-3cb8-ebc4-863e-212df440d987"); //"physics_motion" +const LLUUID ANIM_AGENT_EDITING_ID = LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb"); //"editing" +const LLUUID ANIM_AGENT_EYE_ID = LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea"); //"eye" +const LLUUID ANIM_AGENT_FLY_ADJUST_ID = LLUUID("db95561f-f1b0-9f9a-7224-b12f71af126e"); //"fly_adjust" +const LLUUID ANIM_AGENT_HAND_MOTION_ID = LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578"); //"hand_motion" +const LLUUID ANIM_AGENT_HEAD_ROT_ID = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d"); //"head_rot" +const LLUUID ANIM_AGENT_PELVIS_FIX_ID = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b"); //"pelvis_fix" +const LLUUID ANIM_AGENT_TARGET_ID = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55"); //"target" +const LLUUID ANIM_AGENT_WALK_ADJUST_ID = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust" +// +// This must be in the same order as ANIM_AGENT_BODY_NOISE through ANIM_AGENT_WALK_ADJUST (see llmotion.h)! +static LLUUID const* lookup[] = { + &ANIM_AGENT_BODY_NOISE_ID, + &ANIM_AGENT_BREATHE_ROT_ID, + &ANIM_AGENT_PHYSICS_MOTION_ID, + &ANIM_AGENT_EDITING_ID, + &ANIM_AGENT_EYE_ID, + &ANIM_AGENT_FLY_ADJUST_ID, + &ANIM_AGENT_HAND_MOTION_ID, + &ANIM_AGENT_HEAD_ROT_ID, + &ANIM_AGENT_PELVIS_FIX_ID, + &ANIM_AGENT_TARGET_ID, + &ANIM_AGENT_WALK_ADJUST_ID +}; + +LLUUID const& mask2ID(U32 bit) +{ + int const lookupsize = sizeof(lookup) / sizeof(LLUUID const*); + int i = lookupsize - 1; + U32 mask = 1 << i; + for(;;) + { + if (bit == mask) + { + return *lookup[i]; + } + --i; + mask >>= 1; + llassert_always(i >= 0); + } +} + +#ifdef CWDEBUG +static char const* strlookup[] = { + "ANIM_AGENT_BODY_NOISE", + "ANIM_AGENT_BREATHE_ROT", + "ANIM_AGENT_PHYSICS_MOTION", + "ANIM_AGENT_EDITING", + "ANIM_AGENT_EYE", + "ANIM_AGENT_FLY_ADJUST", + "ANIM_AGENT_HAND_MOTION", + "ANIM_AGENT_HEAD_ROT", + "ANIM_AGENT_PELVIS_FIX", + "ANIM_AGENT_TARGET", + "ANIM_AGENT_WALK_ADJUST" +}; + +char const* mask2str(U32 bit) +{ + int const lookupsize = sizeof(lookup) / sizeof(LLUUID const*); + int i = lookupsize - 1; + U32 mask = 1 << i; + do + { + if (bit == mask) + { + return strlookup[i]; + } + --i; + mask >>= 1; + } + while(i >= 0); + return ""; +} +#endif + +// stopMotion(ANIM_AGENT_WALK_ADJUST) is called every frame, and for every avatar on the radar. +// That can be like 1000 times per second, so... speed that up a bit and lets not lookup the same LLUUID 1000 times +// per second in a std::map. Added the rest of the animations while I was at it. +void LLVOAvatar::startMotion(U32 bit, F32 time_offset) +{ + if (!isMotionActive(bit)) + { + mMotionController.disable_syncing(); // Don't attempt to synchronize AIMaskedMotion. + startMotion(mask2ID(bit), time_offset); + mMotionController.enable_syncing(); + } +} + +void LLVOAvatar::stopMotion(U32 bit, BOOL stop_immediate) +{ + if (isMotionActive(bit)) + { + stopMotion(mask2ID(bit), stop_immediate); + } +} +// //----------------------------------------------------------------------------- // Constants @@ -257,12 +345,12 @@ struct LLTextureMaskData // class LLBodyNoiseMotion //----------------------------------------------------------------------------- class LLBodyNoiseMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLBodyNoiseMotion(const LLUUID &id) - : LLMotion(id) + LLBodyNoiseMotion(LLUUID const& id, LLMotionController* controller) + : AIMaskedMotion(id, controller, ANIM_AGENT_BODY_NOISE) { mName = "body_noise"; mTorsoState = new LLJointState; @@ -277,7 +365,7 @@ public: //------------------------------------------------------------------------- // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLBodyNoiseMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLBodyNoiseMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -320,11 +408,6 @@ public: return STATUS_SUCCESS; } - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate() { return TRUE; } - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. @@ -348,9 +431,6 @@ public: return TRUE; } - // called when a motion is deactivated - virtual void onDeactivate() {} - private: //------------------------------------------------------------------------- // joint states to be animated @@ -362,12 +442,12 @@ private: // class LLBreatheMotionRot //----------------------------------------------------------------------------- class LLBreatheMotionRot : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLBreatheMotionRot(const LLUUID &id) : - LLMotion(id), + LLBreatheMotionRot(LLUUID const& id, LLMotionController* controller) : + AIMaskedMotion(id, controller, ANIM_AGENT_BREATHE_ROT), mBreatheRate(1.f), mCharacter(NULL) { @@ -384,7 +464,7 @@ public: //------------------------------------------------------------------------- // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLBreatheMotionRot(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLBreatheMotionRot(id, controller); } public: //------------------------------------------------------------------------- @@ -437,11 +517,6 @@ public: } } - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate() { return TRUE; } - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. @@ -456,9 +531,6 @@ public: return TRUE; } - // called when a motion is deactivated - virtual void onDeactivate() {} - private: //------------------------------------------------------------------------- // joint states to be animated @@ -472,12 +544,12 @@ private: // class LLPelvisFixMotion //----------------------------------------------------------------------------- class LLPelvisFixMotion : - public LLMotion + public AIMaskedMotion { public: // Constructor - LLPelvisFixMotion(const LLUUID &id) - : LLMotion(id), mCharacter(NULL) + LLPelvisFixMotion(LLUUID const& id, LLMotionController* controller) + : AIMaskedMotion(id, controller, ANIM_AGENT_PELVIS_FIX), mCharacter(NULL) { mName = "pelvis_fix"; @@ -493,7 +565,7 @@ public: //------------------------------------------------------------------------- // static constructor // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID& id) { return new LLPelvisFixMotion(id); } + static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLPelvisFixMotion(id, controller); } public: //------------------------------------------------------------------------- @@ -538,11 +610,6 @@ public: return STATUS_SUCCESS; } - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate() { return TRUE; } - // called per time step // must return TRUE while it is active, and // must return FALSE when the motion is completed. @@ -553,9 +620,6 @@ public: return TRUE; } - // called when a motion is deactivated - virtual void onDeactivate() {} - private: //------------------------------------------------------------------------- // joint states to be animated @@ -846,8 +910,10 @@ const LLUUID SHClientTagMgr::getClientID(const LLVOAvatar* pAvatar) const } return tag.asUUID(); } +bool mm_getMarkerColor(const LLUUID&, LLColor4&); bool SHClientTagMgr::getClientColor(const LLVOAvatar* pAvatar, bool check_status, LLColor4& color) const { + if (mm_getMarkerColor(pAvatar->getID(), color)) return true; static const LLCachedControl ascent_use_status_colors("AscentUseStatusColors",true); static const LLCachedControl ascent_show_self_tag_color("AscentShowSelfTagColor"); static const LLCachedControl ascent_show_others_tag_color("AscentShowOthersTagColor"); @@ -1438,17 +1504,17 @@ void LLVOAvatar::deleteCachedImages(bool clearAll) //------------------------------------------------------------------------ void LLVOAvatar::initClass() { - gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise"); - gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot"); - gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion"); - gAnimLibrary.animStateSetString(ANIM_AGENT_EDITING,"editing"); - gAnimLibrary.animStateSetString(ANIM_AGENT_EYE,"eye"); - gAnimLibrary.animStateSetString(ANIM_AGENT_FLY_ADJUST,"fly_adjust"); - gAnimLibrary.animStateSetString(ANIM_AGENT_HAND_MOTION,"hand_motion"); - gAnimLibrary.animStateSetString(ANIM_AGENT_HEAD_ROT,"head_rot"); - gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX,"pelvis_fix"); - gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET,"target"); - gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST,"walk_adjust"); + gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE_ID,"body_noise"); + gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT_ID,"breathe_rot"); + gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION_ID,"physics_motion"); + gAnimLibrary.animStateSetString(ANIM_AGENT_EDITING_ID,"editing"); + gAnimLibrary.animStateSetString(ANIM_AGENT_EYE_ID,"eye"); + gAnimLibrary.animStateSetString(ANIM_AGENT_FLY_ADJUST_ID,"fly_adjust"); + gAnimLibrary.animStateSetString(ANIM_AGENT_HAND_MOTION_ID,"hand_motion"); + gAnimLibrary.animStateSetString(ANIM_AGENT_HEAD_ROT_ID,"head_rot"); + gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX_ID,"pelvis_fix"); + gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET_ID,"target"); + gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST_ID,"walk_adjust"); SHClientTagMgr::instance(); //Instantiate. Parse. Will fetch a new tag file if AscentUpdateTagsOnLoad is true. } @@ -1506,19 +1572,19 @@ void LLVOAvatar::initInstance(void) registerMotion( ANIM_AGENT_WALK_NEW, LLKeyframeWalkMotion::create ); //v2 // motions without a start/stop bit - registerMotion( ANIM_AGENT_BODY_NOISE, LLBodyNoiseMotion::create ); - registerMotion( ANIM_AGENT_BREATHE_ROT, LLBreatheMotionRot::create ); - registerMotion( ANIM_AGENT_PHYSICS_MOTION, LLPhysicsMotionController::create ); - registerMotion( ANIM_AGENT_EDITING, LLEditingMotion::create ); - registerMotion( ANIM_AGENT_EYE, LLEyeMotion::create ); - registerMotion( ANIM_AGENT_FLY_ADJUST, LLFlyAdjustMotion::create ); - registerMotion( ANIM_AGENT_HAND_MOTION, LLHandMotion::create ); - registerMotion( ANIM_AGENT_HEAD_ROT, LLHeadRotMotion::create ); - registerMotion( ANIM_AGENT_PELVIS_FIX, LLPelvisFixMotion::create ); - registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create ); - registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create ); - registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create ); + registerMotion( ANIM_AGENT_BODY_NOISE_ID, LLBodyNoiseMotion::create ); + registerMotion( ANIM_AGENT_BREATHE_ROT_ID, LLBreatheMotionRot::create ); + registerMotion( ANIM_AGENT_PHYSICS_MOTION_ID, LLPhysicsMotionController::create ); + registerMotion( ANIM_AGENT_EDITING_ID, LLEditingMotion::create ); + registerMotion( ANIM_AGENT_EYE_ID, LLEyeMotion::create ); + registerMotion( ANIM_AGENT_FLY_ADJUST_ID, LLFlyAdjustMotion::create ); + registerMotion( ANIM_AGENT_HAND_MOTION_ID, LLHandMotion::create ); + registerMotion( ANIM_AGENT_HEAD_ROT_ID, LLHeadRotMotion::create ); + registerMotion( ANIM_AGENT_PELVIS_FIX_ID, LLPelvisFixMotion::create ); + registerMotion( ANIM_AGENT_TARGET_ID, LLTargetingMotion::create ); + registerMotion( ANIM_AGENT_WALK_ADJUST_ID, LLWalkAdjustMotion::create ); + registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create ); } LLAvatarAppearance::initInstance(); @@ -3748,6 +3814,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) if (LLVOAvatar::sShowAnimationDebug) { + addDebugText(llformat("at=%.1f", mMotionController.getAnimTime())); for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); iter != mMotionController.getActiveMotions().end(); ++iter) { @@ -3767,6 +3834,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) motionp->getName().c_str(), (U32)motionp->getPriority()); } + if (motionp->server()) + { +#ifdef SHOW_ASSERT + output += llformat(" rt=%.1f r=%d s=0x%xl", motionp->getRuntime(), motionp->mReadyEvents, motionp->server()); +#else + output += llformat(" rt=%.1f s=0x%xl", motionp->getRuntime(), motionp->server()); +#endif + } addDebugText(output); } } @@ -3884,7 +3959,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) getOffObject(); // //Singu note: this appears to be a safety catch: - // when getParent() is NULL and we're note playing ANIM_AGENT_SIT_GROUND_CONSTRAINED then we aren't sitting! + // when getParent() is NULL and we're not playing ANIM_AGENT_SIT_GROUND_CONSTRAINED then we aren't sitting! // The previous call existed in an attempt to fix this inconsistent state by standing up from an object. // However, since getParent() is NULL that function would crash! // Since we never got crash reports regarding to this, that apparently never happened, except, I discovered @@ -5437,6 +5512,7 @@ void LLVOAvatar::processAnimationStateChanges() } // clear all current animations + BOOL const AOEnabled = gSavedSettings.getBOOL("AOEnabled"); // Singu note: put this outside the loop. AnimIterator anim_it; for (anim_it = mPlayingAnimations.begin(); anim_it != mPlayingAnimations.end();) { @@ -5446,9 +5522,9 @@ void LLVOAvatar::processAnimationStateChanges() if (found_anim == mSignaledAnimations.end()) { - if (isSelf()) + if (AOEnabled && isSelf()) { - if ((gSavedSettings.getBOOL("AOEnabled")) && LLFloaterAO::stopMotion(anim_it->first, FALSE)) // if the AO replaced this anim serverside then stop it serverside + if (LLFloaterAO::stopMotion(anim_it->first, FALSE)) // if the AO replaced this anim serverside then stop it serverside { // return TRUE; //no local stop needed } @@ -5478,7 +5554,7 @@ void LLVOAvatar::processAnimationStateChanges() // if (processSingleAnimationStateChange(anim_it->first, TRUE)) { - if (isSelf() && gSavedSettings.getBOOL("AOEnabled")) // AO is only for ME + if (AOEnabled && isSelf()) // AO is only for ME { LLFloaterAO::startMotion(anim_it->first, 0,FALSE); // AO overrides the anim if needed } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 7044c1e1c..f8bd7fe13 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -54,6 +54,9 @@ #include "llavatarname.h" +// +#if 0 +// Hide these: should be using the bit masks everywhere. extern const LLUUID ANIM_AGENT_BODY_NOISE; extern const LLUUID ANIM_AGENT_BREATHE_ROT; extern const LLUUID ANIM_AGENT_PHYSICS_MOTION; @@ -65,6 +68,8 @@ extern const LLUUID ANIM_AGENT_HEAD_ROT; extern const LLUUID ANIM_AGENT_PELVIS_FIX; extern const LLUUID ANIM_AGENT_TARGET; extern const LLUUID ANIM_AGENT_WALK_ADJUST; +#endif +// class LLAPRFile; class LLViewerWearable; @@ -232,6 +237,10 @@ public: /*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); + // + void startMotion(U32 bit, F32 start_offset = 0.f); + void stopMotion(U32 bit, BOOL stop_immediate = FALSE); + // virtual void stopMotionFromSource(const LLUUID& source_id); virtual void requestStopMotion(LLMotion* motion); LLMotion* findMotion(const LLUUID& id) const; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 6f0a4bd9f..14cbd4993 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -897,9 +897,9 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp) //virtual void LLVOAvatarSelf::idleUpdateTractorBeam() { - - - if(gSavedSettings.getBOOL("DisablePointAtAndBeam")) + // + static LLCachedControl disable_pointat_effect("DisablePointAtAndBeam"); + if (disable_pointat_effect) { return; } @@ -2492,7 +2492,7 @@ public: /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { - if (200 <= status && status < 300) + if (isGoodStatus(status)) { LL_DEBUGS("Avatar") << "status OK" << llendl; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b88b673f6..c73511f08 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -343,6 +343,13 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, mTextureAnimp = new LLViewerTextureAnim(this); mTexAnimMode = 0; } + else + { + if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) + { + mTextureAnimp->reset(); + } + } mTextureAnimp->unpackTAMessage(mesgsys, block_num); } diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h index 969e188b6..cba1088f2 100644 --- a/indra/newview/llwlhandlers.h +++ b/indra/newview/llwlhandlers.h @@ -33,7 +33,6 @@ #ifndef LL_LLWLHANDLERS_H #define LL_LLWLHANDLERS_H -#include "llviewerprecompiledheaders.h" #include "llhttpclient.h" class AIHTTPTimeoutPolicy; diff --git a/indra/newview/rlvui.cpp b/indra/newview/rlvui.cpp index 1cd6cf2ad..aa1f83153 100644 --- a/indra/newview/rlvui.cpp +++ b/indra/newview/rlvui.cpp @@ -48,6 +48,7 @@ #include "llfloateravatarlist.h" #include "llfloaterworldmap.h" #include "llmenugl.h" +#include "lltoolbar.h" #include "lluictrlfactory.h" #include "llviewerregion.h" @@ -251,6 +252,8 @@ void RlvUIEnabler::onToggleShowInv(bool fQuitting) LLMenuGL::sMenuContainer->childSetEnabled("My Outfits", true); LLMenuGL::sMenuContainer->childSetEnabled("Favorites", true); } + gToolBar->childSetEnabled("outfits_btn", fEnable); + gToolBar->childSetEnabled("favs_btn", fEnable); } // Checked: 2010-04-22 (RLVa-1.2.0f) | Modified: RLVa-1.2.0f diff --git a/indra/newview/shfloatermediaticker.h b/indra/newview/shfloatermediaticker.h index 4668f33bd..e5d1b968a 100644 --- a/indra/newview/shfloatermediaticker.h +++ b/indra/newview/shfloatermediaticker.h @@ -1,3 +1,6 @@ +#ifndef SH_SHFLOATERMEDIATICKER_H +#define SH_SHFLOATERMEDIATICKER_H + #include "llfloater.h" class LLIconCtrl; @@ -56,3 +59,4 @@ private: BOOL handle_ticker_enabled(void *); void handle_ticker_toggle(void *); +#endif diff --git a/indra/newview/singularity.icns b/indra/newview/singularity_icon.icns similarity index 100% rename from indra/newview/singularity.icns rename to indra/newview/singularity_icon.icns diff --git a/indra/newview/skins/default/textures/icn_toolbar_about_land.tga b/indra/newview/skins/default/textures/icn_toolbar_about_land.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_about_land.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_about_region.tga b/indra/newview/skins/default/textures/icn_toolbar_about_region.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_about_region.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_about_viewer.tga b/indra/newview/skins/default/textures/icn_toolbar_about_viewer.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_about_viewer.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_anims_explorer.tga b/indra/newview/skins/default/textures/icn_toolbar_anims_explorer.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_anims_explorer.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_ao.tga b/indra/newview/skins/default/textures/icn_toolbar_ao.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_ao.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_appearance.tga b/indra/newview/skins/default/textures/icn_toolbar_appearance.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_appearance.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_areasearch.tga b/indra/newview/skins/default/textures/icn_toolbar_areasearch.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_areasearch.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_asset_blacklist.tga b/indra/newview/skins/default/textures/icn_toolbar_asset_blacklist.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_asset_blacklist.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_auto_replace.tga b/indra/newview/skins/default/textures/icn_toolbar_auto_replace.tga new file mode 100644 index 000000000..0a1a235f3 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_auto_replace.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_beacons.tga b/indra/newview/skins/default/textures/icn_toolbar_beacons.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_beacons.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_bumps.tga b/indra/newview/skins/default/textures/icn_toolbar_bumps.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_bumps.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_buy_currency.tga b/indra/newview/skins/default/textures/icn_toolbar_buy_currency.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_buy_currency.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_buy_land.tga b/indra/newview/skins/default/textures/icn_toolbar_buy_land.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_buy_land.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_camera_controls.tga b/indra/newview/skins/default/textures/icn_toolbar_camera_controls.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_camera_controls.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_change_buttons.tga b/indra/newview/skins/default/textures/icn_toolbar_change_buttons.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_change_buttons.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_day_cycle_editor.tga b/indra/newview/skins/default/textures/icn_toolbar_day_cycle_editor.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_day_cycle_editor.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_debug_avatar.tga b/indra/newview/skins/default/textures/icn_toolbar_debug_avatar.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_debug_avatar.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_debug_console.tga b/indra/newview/skins/default/textures/icn_toolbar_debug_console.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_debug_console.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_debug_settings.tga b/indra/newview/skins/default/textures/icn_toolbar_debug_settings.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_debug_settings.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_display_name.tga b/indra/newview/skins/default/textures/icn_toolbar_display_name.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_display_name.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_edit_ui.tga b/indra/newview/skins/default/textures/icn_toolbar_edit_ui.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_edit_ui.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_env_editor.tga b/indra/newview/skins/default/textures/icn_toolbar_env_editor.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_env_editor.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_fast_timers.tga b/indra/newview/skins/default/textures/icn_toolbar_fast_timers.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_fast_timers.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_favorites.tga b/indra/newview/skins/default/textures/icn_toolbar_favorites.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_favorites.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_font_test.tga b/indra/newview/skins/default/textures/icn_toolbar_font_test.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_font_test.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_frame_console.tga b/indra/newview/skins/default/textures/icn_toolbar_frame_console.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_frame_console.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_friends.tga b/indra/newview/skins/default/textures/icn_toolbar_friends.tga new file mode 100644 index 000000000..0a1a235f3 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_friends.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_gestures.tga b/indra/newview/skins/default/textures/icn_toolbar_gestures.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_gestures.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_god_tools.tga b/indra/newview/skins/default/textures/icn_toolbar_god_tools.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_god_tools.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_grid_options.tga b/indra/newview/skins/default/textures/icn_toolbar_grid_options.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_grid_options.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_group_titles.tga b/indra/newview/skins/default/textures/icn_toolbar_group_titles.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_group_titles.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_groups.tga b/indra/newview/skins/default/textures/icn_toolbar_groups.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_groups.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_http_console.tga b/indra/newview/skins/default/textures/icn_toolbar_http_console.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_http_console.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_im.tga b/indra/newview/skins/default/textures/icn_toolbar_im.tga new file mode 100644 index 000000000..0a1a235f3 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_im.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_inspect.tga b/indra/newview/skins/default/textures/icn_toolbar_inspect.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_inspect.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_lag_meter.tga b/indra/newview/skins/default/textures/icn_toolbar_lag_meter.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_lag_meter.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_local_assets.tga b/indra/newview/skins/default/textures/icn_toolbar_local_assets.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_local_assets.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_local_chat.tga b/indra/newview/skins/default/textures/icn_toolbar_local_chat.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_local_chat.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_make_outfit.tga b/indra/newview/skins/default/textures/icn_toolbar_make_outfit.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_make_outfit.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_media_filter.tga b/indra/newview/skins/default/textures/icn_toolbar_media_filter.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_media_filter.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_media_ticker.tga b/indra/newview/skins/default/textures/icn_toolbar_media_ticker.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_media_ticker.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_memleak.tga b/indra/newview/skins/default/textures/icn_toolbar_memleak.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_memleak.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_message_log.tga b/indra/newview/skins/default/textures/icn_toolbar_message_log.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_message_log.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_mouselook.tga b/indra/newview/skins/default/textures/icn_toolbar_mouselook.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_mouselook.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_movement_controls.tga b/indra/newview/skins/default/textures/icn_toolbar_movement_controls.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_movement_controls.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_mute_list.tga b/indra/newview/skins/default/textures/icn_toolbar_mute_list.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_mute_list.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_my_land.tga b/indra/newview/skins/default/textures/icn_toolbar_my_land.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_my_land.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_notifications_console.tga b/indra/newview/skins/default/textures/icn_toolbar_notifications_console.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_notifications_console.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_outbox.tga b/indra/newview/skins/default/textures/icn_toolbar_outbox.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_outbox.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_outfits.tga b/indra/newview/skins/default/textures/icn_toolbar_outfits.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_outfits.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_pathfinding_characters.tga b/indra/newview/skins/default/textures/icn_toolbar_pathfinding_characters.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_pathfinding_characters.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_pathing_linksets.tga b/indra/newview/skins/default/textures/icn_toolbar_pathing_linksets.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_pathing_linksets.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_post_process.tga b/indra/newview/skins/default/textures/icn_toolbar_post_process.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_post_process.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_preferences.tga b/indra/newview/skins/default/textures/icn_toolbar_preferences.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_preferences.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_region_console.tga b/indra/newview/skins/default/textures/icn_toolbar_region_console.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_region_console.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_report_abuse.tga b/indra/newview/skins/default/textures/icn_toolbar_report_abuse.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_report_abuse.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_rlv_locks.tga b/indra/newview/skins/default/textures/icn_toolbar_rlv_locks.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_rlv_locks.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_rlv_restrictions.tga b/indra/newview/skins/default/textures/icn_toolbar_rlv_restrictions.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_rlv_restrictions.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_rlv_strings.tga b/indra/newview/skins/default/textures/icn_toolbar_rlv_strings.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_rlv_strings.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_run.tga b/indra/newview/skins/default/textures/icn_toolbar_run.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_run.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_script_errors.tga b/indra/newview/skins/default/textures/icn_toolbar_script_errors.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_script_errors.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_script_info.tga b/indra/newview/skins/default/textures/icn_toolbar_script_info.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_script_info.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_sit.tga b/indra/newview/skins/default/textures/icn_toolbar_sit.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_sit.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_sound_explorer.tga b/indra/newview/skins/default/textures/icn_toolbar_sound_explorer.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_sound_explorer.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_stats.tga b/indra/newview/skins/default/textures/icn_toolbar_stats.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_stats.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_teleport_history.tga b/indra/newview/skins/default/textures/icn_toolbar_teleport_history.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_teleport_history.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_test.tga b/indra/newview/skins/default/textures/icn_toolbar_test.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_test.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_texture_category_console.tga b/indra/newview/skins/default/textures/icn_toolbar_texture_category_console.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_texture_category_console.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_texture_console.tga b/indra/newview/skins/default/textures/icn_toolbar_texture_console.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_texture_console.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_texture_size_console.tga b/indra/newview/skins/default/textures/icn_toolbar_texture_size_console.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_texture_size_console.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_tutorial.tga b/indra/newview/skins/default/textures/icn_toolbar_tutorial.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_tutorial.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_upload_perms.tga b/indra/newview/skins/default/textures/icn_toolbar_upload_perms.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_upload_perms.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_voice_effects.tga b/indra/newview/skins/default/textures/icn_toolbar_voice_effects.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_voice_effects.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_water_editor.tga b/indra/newview/skins/default/textures/icn_toolbar_water_editor.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_water_editor.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_web.tga b/indra/newview/skins/default/textures/icn_toolbar_web.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_web.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_windlight.tga b/indra/newview/skins/default/textures/icn_toolbar_windlight.tga new file mode 100644 index 000000000..0a1a235f3 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_windlight.tga differ diff --git a/indra/newview/skins/default/xui/de/floater_autoreplace.xml b/indra/newview/skins/default/xui/de/floater_autoreplace.xml new file mode 100644 index 000000000..a9b6aaabb --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_autoreplace.xml @@ -0,0 +1,32 @@ + + + + + + + + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/strings.xml b/indra/newview/skins/default/xui/en-us/strings.xml index b23b8e948..fed4eb9dc 100644 --- a/indra/newview/skins/default/xui/en-us/strings.xml +++ b/indra/newview/skins/default/xui/en-us/strings.xml @@ -352,6 +352,15 @@ Make sure you entered the correct Login URI. An example of a Login URI is: \"htt Return objects on your behalf (unknown)! + + [NAME] [ACT] with magnitude [MAG] + + bumped you + pushed you with a script + hit you with an object + hit you with a scripted object + hit you with a physical object + PG @@ -3058,10 +3067,10 @@ Where tag = tag string to match. Removes bot's matching the tag. - Currently not set - Currently set to: [ITEM] + Item currently not set + Item currently set to: [ITEM] Currently set to an item not on this account - Not logged in + Not logged in, item display unavailable Counting scripts, please wait... diff --git a/indra/newview/skins/default/xui/es/floater_autoreplace.xml b/indra/newview/skins/default/xui/es/floater_autoreplace.xml new file mode 100644 index 000000000..ccb4a03e6 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_autoreplace.xml @@ -0,0 +1,32 @@ + + + +