Merge branch 'master' of https://github.com/Shyotl/SingularityViewer
This commit is contained in:
@@ -3,16 +3,18 @@
|
||||
# - Find JSONCpp
|
||||
# Find the JSONCpp includes and library
|
||||
# This module defines
|
||||
# JSONCPP_INCLUDE_DIR, where to find json.h, etc.
|
||||
# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp.
|
||||
# JSONCPP_FOUND, If false, do not try to use jsoncpp.
|
||||
# also defined, but not for general use are
|
||||
# JSONCPP_LIBRARY, where to find the jsoncpp library.
|
||||
# JSONCPP_FOUND, System has libjsoncpp.
|
||||
# JSONCPP_INCLUDE_DIRS - The libjsoncpp include directories.
|
||||
# JSONCPP_LIBRARIES - The libraries needed to use libjsoncpp.
|
||||
# JSONCPP_DEFINITIONS - Compiler switches required for using libjsoncpp.
|
||||
|
||||
FIND_PATH(JSONCPP_INCLUDE_DIR json/json.h
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
PKG_CHECK_MODULES(PC_JSONCPP jsoncpp)
|
||||
SET(JSONCPP_DEFINITIONS ${PC_JSONCPP_CFLAGS_OTHER})
|
||||
|
||||
FIND_PATH(JSONCPP_INCLUDE_DIR json/reader.h
|
||||
HINTS ${PC_JSONCPP_INCLUDE_DIR} ${PC_JSONCPP_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES jsoncpp)
|
||||
|
||||
# Get the GCC compiler version
|
||||
EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
|
||||
@@ -22,39 +24,16 @@ EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
|
||||
)
|
||||
|
||||
# Try to find a library that was compiled with the same compiler version as we currently use.
|
||||
SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so)
|
||||
IF (STANDALONE)
|
||||
# On standalone, assume that the system installed library was compiled with the used compiler.
|
||||
SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson.so)
|
||||
ENDIF (STANDALONE)
|
||||
FIND_LIBRARY(JSONCPP_LIBRARY
|
||||
NAMES ${JSONCPP_NAMES}
|
||||
PATHS /usr/lib /usr/local/lib
|
||||
)
|
||||
NAMES libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so libjsoncpp.so
|
||||
HINTS ${PC_JSONCPP_LIBDIR} ${PC_JSONCPP_LIBRARY_DIRS}
|
||||
PATHS /usr/lib /usr/local/lib)
|
||||
|
||||
IF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
|
||||
SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
|
||||
SET(JSONCPP_FOUND "YES")
|
||||
ELSE (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
|
||||
SET(JSONCPP_FOUND "NO")
|
||||
ENDIF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
|
||||
SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
|
||||
SET(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(JSONCPP DEFAULT_MSG
|
||||
JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)
|
||||
|
||||
IF (JSONCPP_FOUND)
|
||||
IF (NOT JSONCPP_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}")
|
||||
ENDIF (NOT JSONCPP_FIND_QUIETLY)
|
||||
ELSE (JSONCPP_FOUND)
|
||||
IF (JSONCPP_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find JSONCpp library")
|
||||
ENDIF (JSONCPP_FIND_REQUIRED)
|
||||
ENDIF (JSONCPP_FOUND)
|
||||
|
||||
# Deprecated declarations.
|
||||
SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIR} )
|
||||
GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARY} PATH)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
JSONCPP_LIBRARY
|
||||
JSONCPP_INCLUDE_DIR
|
||||
)
|
||||
MARK_AS_ADVANCED(JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)
|
||||
|
||||
@@ -11,10 +11,10 @@ else (STANDALONE)
|
||||
if (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
|
||||
use_prebuilt_binary(gperftools)
|
||||
endif (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
|
||||
if (WINDOWS)
|
||||
if (WINDOWS AND NOT DISABLE_TCMALLOC)
|
||||
set(TCMALLOC_LIBRARIES libtcmalloc_minimal.lib)
|
||||
set(TCMALLOC_LINKER_FLAGS "/INCLUDE:\"__tcmalloc\"")
|
||||
endif (WINDOWS)
|
||||
endif (WINDOWS AND NOT DISABLE_TCMALLOC)
|
||||
if (LINUX)
|
||||
if(USE_GOOGLE_PERFTOOLS)
|
||||
set(TCMALLOC_LIBRARIES tcmalloc)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
include(Prebuilt)
|
||||
|
||||
set(JSONCPP_FIND_QUIETLY ON)
|
||||
set(JSONCPP_FIND_QUIETLY OFF)
|
||||
set(JSONCPP_FIND_REQUIRED ON)
|
||||
|
||||
if (STANDALONE)
|
||||
|
||||
@@ -30,6 +30,7 @@ set(LIBS_SERVER_DIR ${CMAKE_SOURCE_DIR}/${LIBS_SERVER_PREFIX})
|
||||
set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX})
|
||||
set(SERVER_DIR ${CMAKE_SOURCE_DIR}/${SERVER_PREFIX})
|
||||
set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX})
|
||||
set(DISABLE_TCMALLOC OFF CACHE BOOL "Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)")
|
||||
set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation)")
|
||||
set(VISTA_ICON OFF CACHE BOOL "Allow vista icon with pre 2008 Visual Studio IDEs. (Assumes replacement old rcdll.dll with new rcdll.dll from win sdk 7.0 or later)")
|
||||
|
||||
|
||||
@@ -782,13 +782,14 @@ Commands:
|
||||
|
||||
Command-options for "configure":
|
||||
We use cmake variables to change the build configuration.
|
||||
-DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc
|
||||
-DVIEWER:BOOL=OFF Don't configure the viewer
|
||||
-DPACKAGE:BOOL=ON Create "package" target to make installers
|
||||
-DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language
|
||||
-DLL_TESTS:BOOL=OFF Don't generate unit test projects
|
||||
-DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project
|
||||
-VISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!)
|
||||
-DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc
|
||||
-DVIEWER:BOOL=OFF Don't configure the viewer
|
||||
-DPACKAGE:BOOL=ON Create "package" target to make installers
|
||||
-DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language
|
||||
-DLL_TESTS:BOOL=OFF Don't generate unit test projects
|
||||
-DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project
|
||||
-DDISABLE_TCMALLOC:BOOL=ON Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)
|
||||
-DVISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!)
|
||||
|
||||
Examples:
|
||||
Set up a viewer-only project for your system:
|
||||
|
||||
@@ -50,8 +50,7 @@ LLMultiGesture::LLMultiGesture()
|
||||
mSteps(),
|
||||
mPlaying(FALSE),
|
||||
mCurrentStep(0),
|
||||
mDoneCallback(NULL),
|
||||
mCallbackData(NULL)
|
||||
mDoneCallback(NULL)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
@@ -100,8 +100,7 @@ public:
|
||||
// Timer for waiting
|
||||
LLFrameTimer mWaitTimer;
|
||||
|
||||
void (*mDoneCallback)(LLMultiGesture* gesture, void* data);
|
||||
void* mCallbackData;
|
||||
boost::function<void (LLMultiGesture*)> mDoneCallback;
|
||||
|
||||
// Animations that we requested to start
|
||||
std::set<LLUUID> mRequestedAnimIDs;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "linden_common.h"
|
||||
#include "llallocator.h"
|
||||
|
||||
#if LL_USE_TCMALLOC
|
||||
#if (LL_USE_TCMALLOC && LL_USE_HEAP_PROFILER)
|
||||
|
||||
#include "google/heap-profiler.h"
|
||||
#include "google/commandlineflags_public.h"
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
};
|
||||
|
||||
LLDynamicArray(S32 size=0) : std::vector<Type>(size) { if (size < BlockSize) std::vector<Type>::reserve(BlockSize); }
|
||||
LLDynamicArray(const std::vector<Type>& copy) : std::vector<Type>(copy) {}
|
||||
|
||||
void reset() { std::vector<Type>::clear(); }
|
||||
|
||||
|
||||
@@ -444,13 +444,13 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL
|
||||
{
|
||||
// The new node isn't last. Place it between the previous node and
|
||||
// the successor.
|
||||
newNode = (myprev + mydmi->second)/2.0;
|
||||
newNode = (myprev + mydmi->second)/2.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The new node is last. Bump myprev up to the next integer, add
|
||||
// 1.0 and use that.
|
||||
newNode = std::ceil(myprev) + 1.0;
|
||||
newNode = std::ceil(myprev) + 1.f;
|
||||
}
|
||||
// Now that newNode has a value that places it appropriately in mSignal,
|
||||
// connect it.
|
||||
|
||||
@@ -67,6 +67,17 @@ BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE;
|
||||
LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker;
|
||||
#endif
|
||||
|
||||
void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
|
||||
{
|
||||
#ifdef SHOW_ASSERT
|
||||
// Redundant, place to set breakpoints.
|
||||
if (ptr%alignment!=0)
|
||||
{
|
||||
llwarns << "alignment check failed" << llendl;
|
||||
}
|
||||
llassert(ptr%alignment==0);
|
||||
#endif
|
||||
}
|
||||
//static
|
||||
void LLMemory::initClass()
|
||||
{
|
||||
@@ -246,21 +257,6 @@ U32 LLMemory::getAllocatedMemKB()
|
||||
return sAllocatedMemInKB ;
|
||||
}
|
||||
|
||||
void* ll_allocate (size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
llwarns << "Null allocation" << llendl;
|
||||
}
|
||||
void *p = malloc(size);
|
||||
if (p == NULL)
|
||||
{
|
||||
LLMemory::freeReserve();
|
||||
llerrs << "Out of memory Error" << llendl;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
@@ -1358,7 +1354,7 @@ char* LLPrivateMemoryPool::allocate(U32 size)
|
||||
//if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it
|
||||
if(size >= CHUNK_SIZE)
|
||||
{
|
||||
return (char*)malloc(size) ;
|
||||
return (char*)ll_aligned_malloc_16(size) ;
|
||||
}
|
||||
|
||||
char* p = NULL ;
|
||||
@@ -1415,7 +1411,7 @@ char* LLPrivateMemoryPool::allocate(U32 size)
|
||||
to_log = false ;
|
||||
}
|
||||
|
||||
return (char*)malloc(size) ;
|
||||
return (char*)ll_aligned_malloc_16(size) ;
|
||||
}
|
||||
|
||||
return p ;
|
||||
@@ -1434,7 +1430,7 @@ void LLPrivateMemoryPool::freeMem(void* addr)
|
||||
|
||||
if(!chunk)
|
||||
{
|
||||
free(addr) ; //release from heap
|
||||
ll_aligned_free_16(addr) ; //release from heap
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1558,7 +1554,7 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde
|
||||
|
||||
mReservedPoolSize += preferred_size + overhead ;
|
||||
|
||||
char* buffer = (char*)malloc(preferred_size + overhead) ;
|
||||
char* buffer = (char*)ll_aligned_malloc_16(preferred_size + overhead) ;
|
||||
if(!buffer)
|
||||
{
|
||||
return NULL ;
|
||||
@@ -1626,7 +1622,7 @@ void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk)
|
||||
mReservedPoolSize -= chunk->getBufferSize() ;
|
||||
|
||||
//release memory
|
||||
free(chunk->getBuffer()) ;
|
||||
ll_aligned_free_16(chunk->getBuffer()) ;
|
||||
}
|
||||
|
||||
U16 LLPrivateMemoryPool::findHashKey(const char* addr)
|
||||
@@ -1970,7 +1966,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size,
|
||||
|
||||
if(!poolp)
|
||||
{
|
||||
p = (char*)malloc(size) ;
|
||||
p = (char*)ll_aligned_malloc_16(size) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1999,7 +1995,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size)
|
||||
}
|
||||
else
|
||||
{
|
||||
return (char*)malloc(size) ;
|
||||
return (char*)ll_aligned_malloc_16(size) ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2024,7 +2020,7 @@ void LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr
|
||||
{
|
||||
if(!sPrivatePoolEnabled)
|
||||
{
|
||||
free(addr) ; //private pool is disabled.
|
||||
ll_aligned_free_16(addr) ; //private pool is disabled.
|
||||
}
|
||||
else if(!sInstance) //the private memory manager is destroyed, try the dangling list
|
||||
{
|
||||
|
||||
@@ -39,9 +39,14 @@
|
||||
#include <stdint.h> // uintptr_t
|
||||
#endif
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llmemtype.h"
|
||||
#if LL_DEBUG
|
||||
|
||||
#if LL_WINDOWS && LL_DEBUG
|
||||
#define LL_CHECK_MEMORY llassert(_CrtCheckMemory());
|
||||
#else
|
||||
#define LL_CHECK_MEMORY
|
||||
#endif
|
||||
|
||||
inline void* ll_aligned_malloc( size_t size, int align )
|
||||
{
|
||||
void* mem = malloc( size + (align - 1) + sizeof(void*) );
|
||||
@@ -57,10 +62,11 @@ inline void ll_aligned_free( void* ptr )
|
||||
free( ((void**)ptr)[-1] );
|
||||
}
|
||||
|
||||
#if !LL_USE_TCMALLOC
|
||||
inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16().
|
||||
{
|
||||
#if defined(LL_WINDOWS)
|
||||
return _mm_malloc(size, 16);
|
||||
return _aligned_malloc(size, 16);
|
||||
#elif defined(LL_DARWIN)
|
||||
return malloc(size); // default osx malloc is 16 byte aligned.
|
||||
#else
|
||||
@@ -75,7 +81,7 @@ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed wi
|
||||
inline void ll_aligned_free_16(void *p)
|
||||
{
|
||||
#if defined(LL_WINDOWS)
|
||||
_mm_free(p);
|
||||
_aligned_free(p);
|
||||
#elif defined(LL_DARWIN)
|
||||
return free(p);
|
||||
#else
|
||||
@@ -83,10 +89,39 @@ inline void ll_aligned_free_16(void *p)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // returned hunk MUST be freed with ll_aligned_free_16().
|
||||
{
|
||||
#if defined(LL_WINDOWS)
|
||||
return _aligned_realloc(ptr, size, 16);
|
||||
#elif defined(LL_DARWIN)
|
||||
return realloc(ptr,size); // default osx malloc is 16 byte aligned.
|
||||
#else
|
||||
//FIXME: memcpy is SLOW
|
||||
void* ret = ll_aligned_malloc_16(size);
|
||||
if (ptr)
|
||||
{
|
||||
if (ret)
|
||||
{
|
||||
// Only copy the size of the smallest memory block to avoid memory corruption.
|
||||
memcpy(ret, ptr, llmin(old_size, size));
|
||||
}
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else // USE_TCMALLOC
|
||||
// ll_aligned_foo_16 are not needed with tcmalloc
|
||||
#define ll_aligned_malloc_16 malloc
|
||||
#define ll_aligned_realloc_16(a,b,c) realloc(a,b)
|
||||
#define ll_aligned_free_16 free
|
||||
#endif // USE_TCMALLOC
|
||||
|
||||
inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32().
|
||||
{
|
||||
#if defined(LL_WINDOWS)
|
||||
return _mm_malloc(size, 32);
|
||||
return _aligned_malloc(size, 32);
|
||||
#elif defined(LL_DARWIN)
|
||||
return ll_aligned_malloc( size, 32 );
|
||||
#else
|
||||
@@ -101,22 +136,13 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi
|
||||
inline void ll_aligned_free_32(void *p)
|
||||
{
|
||||
#if defined(LL_WINDOWS)
|
||||
_mm_free(p);
|
||||
_aligned_free(p);
|
||||
#elif defined(LL_DARWIN)
|
||||
ll_aligned_free( p );
|
||||
#else
|
||||
free(p); // posix_memalign() is compatible with heap deallocator
|
||||
#endif
|
||||
}
|
||||
#else // LL_DEBUG
|
||||
// ll_aligned_foo are noops now that we use tcmalloc everywhere (tcmalloc aligns automatically at appropriate intervals)
|
||||
#define ll_aligned_malloc( size, align ) malloc(size)
|
||||
#define ll_aligned_free( ptr ) free(ptr)
|
||||
#define ll_aligned_malloc_16 malloc
|
||||
#define ll_aligned_free_16 free
|
||||
#define ll_aligned_malloc_32 malloc
|
||||
#define ll_aligned_free_32 free
|
||||
#endif // LL_DEBUG
|
||||
|
||||
#ifndef __DEBUG_PRIVATE_MEM__
|
||||
#define __DEBUG_PRIVATE_MEM__ 0
|
||||
@@ -521,6 +547,14 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
|
||||
|
||||
#ifdef SHOW_ASSERT
|
||||
#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
|
||||
#else
|
||||
#define ll_assert_aligned(ptr,alignment)
|
||||
#endif
|
||||
|
||||
//EVENTUALLY REMOVE THESE:
|
||||
#include "llpointer.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
@@ -1690,6 +1690,12 @@ static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8*
|
||||
dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
|
||||
}
|
||||
|
||||
void LLImageBase::setDataAndSize(U8 *data, S32 size)
|
||||
{
|
||||
ll_assert_aligned(data, 16);
|
||||
mData = data; mDataSize = size;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 height, S32 nchannels)
|
||||
{
|
||||
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
|
||||
protected:
|
||||
// special accessor to allow direct setting of mData and mDataSize by LLImageFormatted
|
||||
void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; }
|
||||
void setDataAndSize(U8 *data, S32 size);
|
||||
|
||||
public:
|
||||
static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels);
|
||||
|
||||
@@ -66,7 +66,7 @@ static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
|
||||
// roll(), pitch(), yaw()
|
||||
// etc...
|
||||
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLCamera
|
||||
: public LLCoordFrame
|
||||
{
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
|
||||
LL_ALIGN_16(LLPlane mAgentPlanes[7]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
|
||||
U8 mPlaneMask[8]; // 8 for alignment
|
||||
|
||||
F32 mView; // angle between top and bottom frustum planes in radians.
|
||||
@@ -122,13 +122,13 @@ private:
|
||||
S32 mViewHeightInPixels; // for ViewHeightInPixels() only
|
||||
F32 mNearPlane;
|
||||
F32 mFarPlane;
|
||||
LLPlane mLocalPlanes[4];
|
||||
LL_ALIGN_16(LLPlane mLocalPlanes[4]);
|
||||
F32 mFixedDistance; // Always return this distance, unless < 0
|
||||
LLVector3 mFrustCenter; // center of frustum and radius squared for ultra-quick exclusion test
|
||||
F32 mFrustRadiusSquared;
|
||||
|
||||
LLPlane mWorldPlanes[PLANE_NUM];
|
||||
LLPlane mHorizPlanes[HORIZ_PLANE_NUM];
|
||||
LL_ALIGN_16(LLPlane mWorldPlanes[PLANE_NUM]);
|
||||
LL_ALIGN_16(LLPlane mHorizPlanes[HORIZ_PLANE_NUM]);
|
||||
|
||||
U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
|
||||
|
||||
@@ -214,7 +214,7 @@ protected:
|
||||
void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom);
|
||||
void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2);
|
||||
void calculateWorldFrustumPlanes();
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
LLVector4a mColumns[3];
|
||||
LL_ALIGN_16(LLVector4a mColumns[3]);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
class LLMatrix4a
|
||||
{
|
||||
public:
|
||||
LLVector4a mMatrix[4];
|
||||
LL_ALIGN_16(LLVector4a mMatrix[4]);
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "v3math.h"
|
||||
#include "llvector4a.h"
|
||||
#include <vector>
|
||||
#include <boost/pool/pool.hpp>
|
||||
|
||||
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
|
||||
#define OCT_ERRS LL_ERRS("OctreeErrors")
|
||||
@@ -46,6 +47,7 @@
|
||||
#endif
|
||||
|
||||
extern U32 gOctreeMaxCapacity;
|
||||
extern U32 gOctreeReserveCapacity;
|
||||
#if LL_DEBUG
|
||||
#define LL_OCTREE_PARANOIA_CHECK 0
|
||||
#else
|
||||
@@ -56,6 +58,106 @@ extern U32 gOctreeMaxCapacity;
|
||||
|
||||
template <class T> class LLOctreeNode;
|
||||
|
||||
#include "lltimer.h"
|
||||
|
||||
//#define LL_OCTREE_STATS
|
||||
#define LL_OCTREE_POOLS
|
||||
#ifdef LL_OCTREE_STATS
|
||||
class OctreeStats : public LLSingleton<OctreeStats>
|
||||
{
|
||||
public:
|
||||
OctreeStats() :
|
||||
mPeriodNodesCreated(0),
|
||||
mPeriodNodesDestroyed(0),
|
||||
mPeriodAllocs(0),
|
||||
mPeriodFrees(0),
|
||||
mPeriodLargestSize(0),
|
||||
mTotalNodes(0),
|
||||
mTotalAllocs(0),
|
||||
mTotalFrees(0),
|
||||
mLargestSize(0),
|
||||
mTotalSize(0)
|
||||
{
|
||||
mTotalTimer.reset();
|
||||
mPeriodTimer.reset();
|
||||
}
|
||||
void addNode()
|
||||
{
|
||||
++mTotalNodes;
|
||||
++mPeriodNodesCreated;
|
||||
}
|
||||
void removeNode()
|
||||
{
|
||||
--mTotalNodes;
|
||||
++mPeriodNodesDestroyed;
|
||||
}
|
||||
void realloc(U32 old_count, U32 new_count)
|
||||
{
|
||||
if(new_count >= old_count)
|
||||
mTotalSize+=new_count-old_count;
|
||||
else
|
||||
mTotalSize-=old_count-new_count;
|
||||
if(mLargestSize < new_count)
|
||||
mLargestSize = new_count;
|
||||
if(mPeriodLargestSize < new_count)
|
||||
mPeriodLargestSize = new_count;
|
||||
++mTotalAllocs;
|
||||
++mPeriodAllocs;
|
||||
}
|
||||
void free(U32 count)
|
||||
{
|
||||
mTotalSize-=count;
|
||||
++mTotalFrees;
|
||||
++mPeriodFrees;
|
||||
}
|
||||
void dump()
|
||||
{
|
||||
llinfos << llformat("Lifetime: Allocs:(+%u|-%u) Allocs/s: (+%lf|-%lf) Nodes: %u AccumSize: %llubytes Avg: %lf LargestSize: %u",
|
||||
mTotalAllocs,
|
||||
mTotalFrees,
|
||||
F64(mTotalAllocs)/mTotalTimer.getElapsedTimeF64(),
|
||||
F64(mTotalFrees)/mTotalTimer.getElapsedTimeF64(),
|
||||
mTotalNodes,
|
||||
mTotalSize*sizeof(LLPointer<LLRefCount>),
|
||||
F64(mTotalSize)/F64(mTotalNodes),
|
||||
mLargestSize
|
||||
) << llendl;
|
||||
llinfos << llformat("Timeslice: Allocs:(+%u|-%u) Allocs/s: (+%lf|-%lf) Nodes:(+%u|-%u) LargestSize: %u",
|
||||
mPeriodAllocs,
|
||||
mPeriodFrees,
|
||||
F64(mPeriodAllocs)/mPeriodTimer.getElapsedTimeF64(),
|
||||
F64(mPeriodFrees)/mPeriodTimer.getElapsedTimeF64(),
|
||||
mPeriodNodesCreated,
|
||||
mPeriodNodesDestroyed,
|
||||
mPeriodLargestSize
|
||||
) << llendl;
|
||||
|
||||
mPeriodNodesCreated=0;
|
||||
mPeriodNodesDestroyed=0;
|
||||
mPeriodAllocs=0;
|
||||
mPeriodFrees=0;
|
||||
mPeriodLargestSize=0;
|
||||
mPeriodTimer.reset();
|
||||
}
|
||||
private:
|
||||
//Accumulate per timer update
|
||||
U32 mPeriodNodesCreated;
|
||||
U32 mPeriodNodesDestroyed;
|
||||
U32 mPeriodAllocs;
|
||||
U32 mPeriodFrees;
|
||||
U32 mPeriodLargestSize;
|
||||
LLTimer mPeriodTimer;
|
||||
|
||||
//Accumulate through entire app lifetime:
|
||||
U32 mTotalNodes;
|
||||
U32 mTotalAllocs;
|
||||
U32 mTotalFrees;
|
||||
U32 mLargestSize;
|
||||
U64 mTotalSize;
|
||||
LLTimer mTotalTimer;
|
||||
};
|
||||
#endif //LL_OCTREE_STATS
|
||||
|
||||
template <class T>
|
||||
class LLOctreeListener: public LLTreeListener<T>
|
||||
{
|
||||
@@ -129,25 +231,52 @@ public:
|
||||
|
||||
typedef LLOctreeTraveler<T> oct_traveler;
|
||||
typedef LLTreeTraveler<T> tree_traveler;
|
||||
typedef LLPointer<T>* element_list;
|
||||
typedef LLPointer<T>* element_iter;
|
||||
typedef const LLPointer<T>* const_element_iter;
|
||||
typedef std::vector<LLPointer<T> > element_list;
|
||||
typedef typename element_list::iterator element_iter;
|
||||
typedef typename element_list::const_iterator const_element_iter;
|
||||
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
|
||||
typedef LLOctreeNode<T>** child_list;
|
||||
typedef LLOctreeNode<T>** child_iter;
|
||||
|
||||
typedef LLTreeNode<T> BaseType;
|
||||
typedef LLOctreeNode<T> oct_node;
|
||||
typedef LLOctreeListener<T> oct_listener;
|
||||
|
||||
/*void* operator new(size_t size)
|
||||
#ifdef LL_OCTREE_POOLS
|
||||
struct octree_pool_alloc
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
static char * malloc(const std::size_t bytes)
|
||||
{ return (char *)ll_aligned_malloc_16(bytes); }
|
||||
static void free(char * const block)
|
||||
{ ll_aligned_free_16(block); }
|
||||
};
|
||||
static boost::pool<octree_pool_alloc>& getPool(const std::size_t& size)
|
||||
{
|
||||
static boost::pool<octree_pool_alloc> sPool((std::size_t)LL_NEXT_ALIGNED_ADDRESS((char*)size),1200);
|
||||
llassert_always((std::size_t)LL_NEXT_ALIGNED_ADDRESS((char*)size) == sPool.get_requested_size());
|
||||
return sPool;
|
||||
}
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
return getPool(size).malloc();
|
||||
}
|
||||
void operator delete(void* ptr)
|
||||
{
|
||||
getPool(sizeof(LLOctreeNode<T>)).free(ptr);
|
||||
}
|
||||
#else
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
return ll_aligned_malloc_16(size);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr)
|
||||
{
|
||||
ll_aligned_free_16(ptr);
|
||||
}*/
|
||||
}
|
||||
#endif
|
||||
|
||||
LLOctreeNode( const LLVector4a& center,
|
||||
const LLVector4a& size,
|
||||
@@ -156,8 +285,16 @@ public:
|
||||
: mParent((oct_node*)parent),
|
||||
mOctant(octant)
|
||||
{
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
#ifdef LL_OCTREE_STATS
|
||||
OctreeStats::getInstance()->addNode();
|
||||
#endif
|
||||
if(gOctreeReserveCapacity)
|
||||
mData.reserve(gOctreeReserveCapacity);
|
||||
#ifdef LL_OCTREE_STATS
|
||||
OctreeStats::getInstance()->realloc(0,mData.capacity());
|
||||
#endif
|
||||
//mData = NULL;
|
||||
//mDataEnd = NULL;
|
||||
|
||||
mCenter = center;
|
||||
mSize = size;
|
||||
@@ -168,24 +305,31 @@ public:
|
||||
mOctant = ((oct_node*) mParent)->getOctant(mCenter);
|
||||
}
|
||||
|
||||
mElementCount = 0;
|
||||
//mElementCount = 0;
|
||||
|
||||
clearChildren();
|
||||
}
|
||||
|
||||
virtual ~LLOctreeNode()
|
||||
{
|
||||
{
|
||||
#ifdef LL_OCTREE_STATS
|
||||
OctreeStats::getInstance()->removeNode();
|
||||
#endif
|
||||
BaseType::destroyListeners();
|
||||
|
||||
for (U32 i = 0; i < mElementCount; ++i)
|
||||
//for (U32 i = 0; i < mElementCount; ++i)
|
||||
for (U32 i = 0; i < mData.size(); ++i)
|
||||
{
|
||||
mData[i]->setBinIndex(-1);
|
||||
mData[i] = NULL;
|
||||
}
|
||||
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
#ifdef LL_OCTREE_STATS
|
||||
OctreeStats::getInstance()->free(mData.capacity());
|
||||
#endif
|
||||
//free(mData);
|
||||
//mData = NULL;
|
||||
//mDataEnd = NULL;
|
||||
|
||||
for (U32 i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
@@ -285,14 +429,14 @@ public:
|
||||
void accept(oct_traveler* visitor) { visitor->visit(this); }
|
||||
virtual bool isLeaf() const { return mChildCount == 0; }
|
||||
|
||||
U32 getElementCount() const { return mElementCount; }
|
||||
bool isEmpty() const { return mElementCount == 0; }
|
||||
U32 getElementCount() const { return mData.size(); }
|
||||
bool isEmpty() const { return mData.size() == 0; }
|
||||
//element_list& getData() { return mData; }
|
||||
//const element_list& getData() const { return mData; }
|
||||
element_iter getDataBegin() { return mData; }
|
||||
element_iter getDataEnd() { return mDataEnd; }
|
||||
const_element_iter getDataBegin() const { return mData; }
|
||||
const_element_iter getDataEnd() const { return mDataEnd; }
|
||||
element_iter getDataBegin() { return mData.begin(); }
|
||||
element_iter getDataEnd() { return mData.end(); }
|
||||
const_element_iter getDataBegin() const { return mData.begin(); }
|
||||
const_element_iter getDataEnd() const { return mData.end(); }
|
||||
|
||||
U32 getChildCount() const { return mChildCount; }
|
||||
oct_node* getChild(U32 index) { return mChild[index]; }
|
||||
@@ -372,7 +516,10 @@ public:
|
||||
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
|
||||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
|
||||
{ //it belongs here
|
||||
mElementCount++;
|
||||
/*mElementCount++;
|
||||
#ifdef LL_OCTREE_STATS
|
||||
OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount);
|
||||
#endif
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
|
||||
//avoid unref on uninitialized memory
|
||||
@@ -380,7 +527,18 @@ public:
|
||||
|
||||
mData[mElementCount-1] = data;
|
||||
mDataEnd = mData + mElementCount;
|
||||
data->setBinIndex(mElementCount-1);
|
||||
data->setBinIndex(mElementCount-1);*/
|
||||
|
||||
#ifdef LL_OCTREE_STATS
|
||||
U32 old_cap = mData.capacity();
|
||||
#endif
|
||||
data->setBinIndex(mData.size());
|
||||
mData.push_back(data);
|
||||
#ifdef LL_OCTREE_STATS
|
||||
if(old_cap != mData.capacity())
|
||||
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
|
||||
#endif
|
||||
|
||||
BaseType::insert(data);
|
||||
return true;
|
||||
}
|
||||
@@ -415,7 +573,10 @@ public:
|
||||
|
||||
if( lt == 0x7 )
|
||||
{
|
||||
mElementCount++;
|
||||
/*mElementCount++;
|
||||
#ifdef LL_OCTREE_STATS
|
||||
OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount);
|
||||
#endif
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
|
||||
//avoid unref on uninitialized memory
|
||||
@@ -423,7 +584,17 @@ public:
|
||||
|
||||
mData[mElementCount-1] = data;
|
||||
mDataEnd = mData + mElementCount;
|
||||
data->setBinIndex(mElementCount-1);
|
||||
data->setBinIndex(mElementCount-1);*/
|
||||
#ifdef LL_OCTREE_STATS
|
||||
U32 old_cap = mData.capacity();
|
||||
#endif
|
||||
data->setBinIndex(mData.size());
|
||||
mData.push_back(data);
|
||||
#ifdef LL_OCTREE_STATS
|
||||
if(old_cap != mData.capacity())
|
||||
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
|
||||
#endif
|
||||
|
||||
BaseType::insert(data);
|
||||
return true;
|
||||
}
|
||||
@@ -476,10 +647,10 @@ public:
|
||||
void _remove(T* data, S32 i)
|
||||
{ //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
|
||||
OctreeGuard::checkGuarded(this);
|
||||
mElementCount--;
|
||||
//mElementCount--;
|
||||
data->setBinIndex(-1);
|
||||
|
||||
if (mElementCount > 0)
|
||||
|
||||
/* if (mElementCount > 0)
|
||||
{
|
||||
if (mElementCount != i)
|
||||
{
|
||||
@@ -488,15 +659,51 @@ public:
|
||||
}
|
||||
|
||||
mData[mElementCount] = NULL; //needed for unref
|
||||
#ifdef LL_OCTREE_STATS
|
||||
OctreeStats::getInstance()->realloc(mElementCount+1,mElementCount);
|
||||
#endif
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
mDataEnd = mData+mElementCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
mData[0] = NULL; //needed for unref
|
||||
#ifdef LL_OCTREE_STATS
|
||||
OctreeStats::getInstance()->free(1);
|
||||
#endif
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
}*/
|
||||
|
||||
if(mData.size())
|
||||
{
|
||||
if((mData.size()-1)!=i)
|
||||
{
|
||||
mData[i] = mData[mData.size()-1];
|
||||
mData[i]->setBinIndex(i);
|
||||
}
|
||||
#ifdef LL_OCTREE_STATS
|
||||
U32 old_cap = mData.capacity();
|
||||
#endif
|
||||
mData.pop_back();
|
||||
if( mData.size() == gOctreeReserveCapacity ||
|
||||
(mData.size() > gOctreeReserveCapacity && mData.capacity() > gOctreeReserveCapacity + mData.size() - 1 - (mData.size() - gOctreeReserveCapacity - 1) % 4))
|
||||
{
|
||||
//Shrink to lowest possible (reserve)+4*i size.. Say reserve is 5, here are [size,capacity] pairs. [10,13],[9,9],[8,9],[7,9],[6,9],[5,5],[4,5],[3,5],[2,5],[1,5],[0,5]
|
||||
//For Windows: We always assume vs2010 or later, which support this c++11 feature with no configuration needed.
|
||||
//For GCC: __cplusplus >= 201103L indicates C++11 support. __GXX_EXPERIMENTAL_CXX0X being set indicates experimental c++0x support. C++11 support replaces C++0x support.
|
||||
// std::vector::shrink_to_fit was added to GCCs C++0x implementation in version 4.5.0.
|
||||
#if defined(LL_WINDOWS) || __cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X) && __GNUC_MINOR__ >= 5)
|
||||
mData.shrink_to_fit();
|
||||
#else
|
||||
std::vector<LLPointer<T> >(mData.begin(), mData.end()).swap(mData); //Need to confirm this works on OSX..
|
||||
#endif
|
||||
}
|
||||
#ifdef LL_OCTREE_STATS
|
||||
if(old_cap != mData.capacity())
|
||||
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
|
||||
#endif
|
||||
}
|
||||
|
||||
this->notifyRemoval(data);
|
||||
@@ -508,7 +715,8 @@ public:
|
||||
OctreeGuard::checkGuarded(this);
|
||||
S32 i = data->getBinIndex();
|
||||
|
||||
if (i >= 0 && i < (S32)mElementCount)
|
||||
//if (i >= 0 && i < mElementCount)
|
||||
if (i >= 0 && i < (S32)mData.size())
|
||||
{
|
||||
if (mData[i] == data)
|
||||
{ //found it
|
||||
@@ -552,7 +760,8 @@ public:
|
||||
void removeByAddress(T* data)
|
||||
{
|
||||
OctreeGuard::checkGuarded(this);
|
||||
for (U32 i = 0; i < mElementCount; ++i)
|
||||
//for (U32 i = 0; i < mElementCount; ++i)
|
||||
for (U32 i = 0; i < mData.size(); ++i)
|
||||
{
|
||||
if (mData[i] == data)
|
||||
{ //we have data
|
||||
@@ -660,8 +869,6 @@ public:
|
||||
listener->handleChildRemoval(this, getChild(index));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (destroy)
|
||||
{
|
||||
mChild[index]->destroy();
|
||||
@@ -733,8 +940,8 @@ protected:
|
||||
U32 mChildCount;
|
||||
|
||||
element_list mData;
|
||||
element_iter mDataEnd;
|
||||
U32 mElementCount;
|
||||
//element_iter mDataEnd;
|
||||
//U32 mElementCount;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
// The plane normal = [A, B, C]
|
||||
// The closest approach = D / sqrt(A*A + B*B + C*C)
|
||||
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLPlane
|
||||
{
|
||||
public:
|
||||
@@ -100,7 +102,7 @@ public:
|
||||
|
||||
private:
|
||||
LLVector4a mV;
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -124,8 +124,8 @@ public:
|
||||
if (end_y < mBottom) clip_y = end_y - mBottom;
|
||||
// clip_? and delta_? should have same sign, since starting point is in rect
|
||||
// so ratios will be positive
|
||||
F32 ratio_x = ((F32)clip_x / (F32)delta_x);
|
||||
F32 ratio_y = ((F32)clip_y / (F32)delta_y);
|
||||
F32 ratio_x = delta_x ? ((F32)clip_x / (F32)delta_x) : 0.f;
|
||||
F32 ratio_y = delta_y ? ((F32)clip_y / (F32)delta_y) : 0.f;
|
||||
if (ratio_x > ratio_y)
|
||||
{
|
||||
// clip along x direction
|
||||
|
||||
@@ -67,11 +67,10 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
|
||||
|
||||
#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
|
||||
|
||||
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
#include "llmemory.h"
|
||||
#include "llsimdtypes.h"
|
||||
#include "llsimdtypes.inl"
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ inline LLSimdScalar operator/(const LLSimdScalar& a, const LLSimdScalar& b)
|
||||
inline LLSimdScalar operator-(const LLSimdScalar& a)
|
||||
{
|
||||
static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 };
|
||||
ll_assert_aligned(signMask,16);
|
||||
return _mm_xor_ps(*reinterpret_cast<const LLQuad*>(signMask), a);
|
||||
}
|
||||
|
||||
@@ -146,6 +147,7 @@ inline LLSimdScalar& LLSimdScalar::operator/=(const LLSimdScalar& rhs)
|
||||
inline LLSimdScalar LLSimdScalar::getAbs() const
|
||||
{
|
||||
static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
|
||||
ll_assert_aligned(F_ABS_MASK_4A,16);
|
||||
return _mm_and_ps( mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A));
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llmemory.h"
|
||||
#include "llmath.h"
|
||||
#include "llquantize.h"
|
||||
|
||||
@@ -44,7 +45,10 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast<const LLVector4a&> ( F
|
||||
assert(dst != NULL);
|
||||
assert(bytes > 0);
|
||||
assert((bytes % sizeof(F32))== 0);
|
||||
|
||||
ll_assert_aligned(src,16);
|
||||
ll_assert_aligned(dst,16);
|
||||
assert(bytes%16==0);
|
||||
|
||||
F32* end = dst + (bytes / sizeof(F32) );
|
||||
|
||||
if (bytes > 64)
|
||||
@@ -189,6 +193,8 @@ void LLVector4a::quantize16( const LLVector4a& low, const LLVector4a& high )
|
||||
LLVector4a oneOverDelta;
|
||||
{
|
||||
static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f };
|
||||
ll_assert_aligned(F_TWO_4A,16);
|
||||
|
||||
LLVector4a two; two.load4a( F_TWO_4A );
|
||||
|
||||
// Here we use _mm_rcp_ps plus one round of newton-raphson
|
||||
|
||||
@@ -32,6 +32,7 @@ class LLRotation;
|
||||
|
||||
#include <assert.h>
|
||||
#include "llpreprocessor.h"
|
||||
#include "llmemory.h"
|
||||
|
||||
///////////////////////////////////
|
||||
// FIRST TIME USERS PLEASE READ
|
||||
@@ -46,6 +47,7 @@ class LLRotation;
|
||||
// LLVector3/LLVector4.
|
||||
/////////////////////////////////
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLVector4a
|
||||
{
|
||||
public:
|
||||
@@ -90,6 +92,7 @@ public:
|
||||
|
||||
LLVector4a()
|
||||
{ //DO NOT INITIALIZE -- The overhead is completely unnecessary
|
||||
ll_assert_aligned(this,16);
|
||||
}
|
||||
|
||||
LLVector4a(F32 x, F32 y, F32 z, F32 w = 0.f)
|
||||
@@ -313,7 +316,7 @@ public:
|
||||
|
||||
private:
|
||||
LLQuad mQ;
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p)
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#ifndef LL_VECTOR4LOGICAL_H
|
||||
#define LL_VECTOR4LOGICAL_H
|
||||
|
||||
#include "llmemory.h"
|
||||
|
||||
////////////////////////////
|
||||
// LLVector4Logical
|
||||
@@ -77,6 +78,7 @@ public:
|
||||
inline LLVector4Logical& invert()
|
||||
{
|
||||
static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
ll_assert_aligned(allOnes,16);
|
||||
mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
#include "llmath.h"
|
||||
|
||||
#include <set>
|
||||
#if !LL_WINDOWS
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <cmath>
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llmemtype.h"
|
||||
@@ -91,17 +95,6 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1;
|
||||
|
||||
extern BOOL gDebugGL;
|
||||
|
||||
void assert_aligned(void* ptr, uintptr_t alignment)
|
||||
{
|
||||
#if 0
|
||||
uintptr_t t = (uintptr_t) ptr;
|
||||
if (t%alignment != 0)
|
||||
{
|
||||
llerrs << "Alignment check failed." << llendl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm)
|
||||
{
|
||||
LLVector3 test = (pt2-pt1)%(pt3-pt2);
|
||||
@@ -6963,14 +6956,14 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
|
||||
if (num_verts)
|
||||
{
|
||||
mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
|
||||
assert_aligned(mPositions, 16);
|
||||
ll_assert_aligned(mPositions, 16);
|
||||
mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
|
||||
assert_aligned(mNormals, 16);
|
||||
ll_assert_aligned(mNormals, 16);
|
||||
|
||||
//pad texture coordinate block end to allow for QWORD reads
|
||||
S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF;
|
||||
mTexCoords = (LLVector2*) ll_aligned_malloc_16(size);
|
||||
assert_aligned(mTexCoords, 16);
|
||||
ll_assert_aligned(mTexCoords, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6991,17 +6984,21 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
|
||||
{
|
||||
S32 new_verts = mNumVertices+1;
|
||||
S32 new_size = new_verts*16;
|
||||
// S32 old_size = mNumVertices*16;
|
||||
S32 old_size = mNumVertices*16;
|
||||
|
||||
//positions
|
||||
mPositions = (LLVector4a*) realloc(mPositions, new_size);
|
||||
mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_size, old_size);
|
||||
ll_assert_aligned(mPositions,16);
|
||||
|
||||
//normals
|
||||
mNormals = (LLVector4a*) realloc(mNormals, new_size);
|
||||
|
||||
mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_size, old_size);
|
||||
ll_assert_aligned(mNormals,16);
|
||||
|
||||
//tex coords
|
||||
new_size = ((new_verts*8)+0xF) & ~0xF;
|
||||
mTexCoords = (LLVector2*) realloc(mTexCoords, new_size);
|
||||
old_size = ((mNumVertices*8)+0xF) & ~0xF;
|
||||
mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, new_size, old_size);
|
||||
ll_assert_aligned(mTexCoords,16);
|
||||
|
||||
|
||||
//just clear binormals
|
||||
@@ -7054,7 +7051,8 @@ void LLVolumeFace::pushIndex(const U16& idx)
|
||||
S32 old_size = ((mNumIndices*2)+0xF) & ~0xF;
|
||||
if (new_size != old_size)
|
||||
{
|
||||
mIndices = (U16*) realloc(mIndices, new_size);
|
||||
mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size);
|
||||
ll_assert_aligned(mIndices,16);
|
||||
}
|
||||
|
||||
mIndices[mNumIndices++] = idx;
|
||||
@@ -7095,12 +7093,12 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
|
||||
}
|
||||
|
||||
//allocate new buffer space
|
||||
mPositions = (LLVector4a*) realloc(mPositions, new_count*sizeof(LLVector4a));
|
||||
assert_aligned(mPositions, 16);
|
||||
mNormals = (LLVector4a*) realloc(mNormals, new_count*sizeof(LLVector4a));
|
||||
assert_aligned(mNormals, 16);
|
||||
mTexCoords = (LLVector2*) realloc(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF);
|
||||
assert_aligned(mTexCoords, 16);
|
||||
mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a));
|
||||
ll_assert_aligned(mPositions, 16);
|
||||
mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a));
|
||||
ll_assert_aligned(mNormals, 16);
|
||||
mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF, (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF);
|
||||
ll_assert_aligned(mTexCoords, 16);
|
||||
|
||||
mNumVertices = new_count;
|
||||
|
||||
@@ -7146,7 +7144,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
|
||||
new_count = mNumIndices + face.mNumIndices;
|
||||
|
||||
//allocate new index buffer
|
||||
mIndices = (U16*) realloc(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF);
|
||||
mIndices = (U16*) ll_aligned_realloc_16(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF, (mNumIndices*sizeof(U16)+0xF) & ~0xF);
|
||||
|
||||
//get destination address into new index buffer
|
||||
U16* dst_idx = mIndices+mNumIndices;
|
||||
|
||||
@@ -37,6 +37,15 @@
|
||||
class LLVolumeTriangle : public LLRefCount
|
||||
{
|
||||
public:
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
return ll_aligned_malloc_16(size);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr)
|
||||
{
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
LLVolumeTriangle()
|
||||
{
|
||||
mBinIndex = -1;
|
||||
@@ -58,7 +67,7 @@ public:
|
||||
|
||||
}
|
||||
|
||||
LLVector4a mPositionGroup;
|
||||
LL_ALIGN_16(LLVector4a mPositionGroup);
|
||||
|
||||
const LLVector4a* mV[3];
|
||||
U16 mIndex[3];
|
||||
@@ -78,6 +87,16 @@ class LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
|
||||
{
|
||||
public:
|
||||
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
return ll_aligned_malloc_16(size);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr)
|
||||
{
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
|
||||
LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node);
|
||||
~LLVolumeOctreeListener();
|
||||
|
||||
@@ -104,8 +123,8 @@ public:
|
||||
|
||||
|
||||
public:
|
||||
LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects)
|
||||
LLVector4a mExtents[2]; // extents (min, max) of this node and all its children
|
||||
LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
|
||||
LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
|
||||
};
|
||||
|
||||
class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle>
|
||||
|
||||
@@ -418,6 +418,7 @@ void cleanupCurl(void)
|
||||
if (CurlMultiHandle::getTotalMultiHandles() != 0)
|
||||
llwarns << "Not all CurlMultiHandle objects were destroyed!" << llendl;
|
||||
AIStateMachine::flush();
|
||||
clearCommandQueue();
|
||||
Stats::print();
|
||||
ssl_cleanup();
|
||||
|
||||
@@ -491,12 +492,10 @@ void Stats::print(void)
|
||||
// Even more strict, BufferedCurlEasyRequest may not be created directly either, only as
|
||||
// base class of ThreadSafeBufferedCurlEasyRequest.
|
||||
llassert(BufferedCurlEasyRequest_count == ThreadSafeBufferedCurlEasyRequest_count);
|
||||
// Each AICurlEasyRequestStateMachine is responsible for exactly one easy handle.
|
||||
llassert(easy_handles >= AICurlEasyRequest_count);
|
||||
// Each AICurlEasyRequestStateMachine has one AICurlEasyRequest member.
|
||||
llassert(AICurlEasyRequest_count >= AICurlEasyRequestStateMachine_count);
|
||||
// AIFIXME: is this really always the case? And why?
|
||||
llassert(easy_handles <= ResponderBase_count);
|
||||
llassert(easy_handles <= S32(ResponderBase_count));
|
||||
}
|
||||
|
||||
} // namespace AICurlInterface
|
||||
@@ -1348,11 +1347,22 @@ void BufferedCurlEasyRequest::prepRequest(AICurlEasyRequest_wat& curl_easy_reque
|
||||
curl_easy_request_w->setReadCallback(&curlReadCallback, lockobj);
|
||||
curl_easy_request_w->setHeaderCallback(&curlHeaderCallback, lockobj);
|
||||
|
||||
bool allow_cookies = headers.hasHeader("Cookie");
|
||||
// Allow up to ten redirects.
|
||||
if (responder->followRedir())
|
||||
{
|
||||
curl_easy_request_w->setopt(CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_request_w->setopt(CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
|
||||
// This is needed (at least) for authentication after temporary redirection
|
||||
// to id.secondlife.com for marketplace.secondlife.com.
|
||||
allow_cookies = true;
|
||||
}
|
||||
if (allow_cookies)
|
||||
{
|
||||
// Given an empty or non-existing file or by passing the empty string (""),
|
||||
// this option will enable cookies for this curl handle, making it understand
|
||||
// and parse received cookies and then use matching cookies in future requests.
|
||||
curl_easy_request_w->setopt(CURLOPT_COOKIEFILE, "");
|
||||
}
|
||||
|
||||
// Keep responder alive.
|
||||
|
||||
@@ -56,12 +56,17 @@ PerHostRequestQueuePtr PerHostRequestQueue::instance(std::string const& hostname
|
||||
//static
|
||||
void PerHostRequestQueue::release(PerHostRequestQueuePtr& instance)
|
||||
{
|
||||
if (instance->lastone())
|
||||
if (instance->exactly_two_left()) // Being 'instance' and the one in sInstanceMap.
|
||||
{
|
||||
// The viewer can be have left main() we can't access the global sInstanceMap anymore.
|
||||
if (LLApp::isStopped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
instance_map_wat instance_map_w(sInstanceMap);
|
||||
// It is possible that 'lastone' is not up to date anymore.
|
||||
// It is possible that 'exactly_two_left' is not up to date anymore.
|
||||
// Therefore, recheck the condition now that we have locked sInstanceMap.
|
||||
if (!instance->lastone())
|
||||
if (!instance->exactly_two_left())
|
||||
{
|
||||
// Some other thread added this host in the meantime.
|
||||
return;
|
||||
@@ -87,13 +92,13 @@ void PerHostRequestQueue::release(PerHostRequestQueuePtr& instance)
|
||||
|
||||
bool PerHostRequestQueue::throttled() const
|
||||
{
|
||||
llassert(mAdded <= curl_concurrent_connections_per_host);
|
||||
return mAdded == curl_concurrent_connections_per_host;
|
||||
llassert(mAdded <= int(curl_concurrent_connections_per_host));
|
||||
return mAdded == int(curl_concurrent_connections_per_host);
|
||||
}
|
||||
|
||||
void PerHostRequestQueue::added_to_multi_handle(void)
|
||||
{
|
||||
llassert(mAdded < curl_concurrent_connections_per_host);
|
||||
llassert(mAdded < int(curl_concurrent_connections_per_host));
|
||||
++mAdded;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ class PerHostRequestQueue {
|
||||
class RefCountedThreadSafePerHostRequestQueue : public threadsafe_PerHostRequestQueue {
|
||||
public:
|
||||
RefCountedThreadSafePerHostRequestQueue(void) : mReferenceCount(0) { }
|
||||
bool lastone(void) const { llassert(mReferenceCount >= 2); return mReferenceCount == 2; }
|
||||
bool exactly_two_left(void) const { return mReferenceCount == 2; }
|
||||
|
||||
private:
|
||||
// Used by PerHostRequestQueuePtr. Object is deleted when reference count reaches zero.
|
||||
|
||||
@@ -119,6 +119,7 @@ inline CURLMcode check_multi_code(CURLMcode code) { AICurlInterface::Stats::mult
|
||||
bool curlThreadIsRunning(void);
|
||||
void wakeUpCurlThread(void);
|
||||
void stopCurlThread(void);
|
||||
void clearCommandQueue(void);
|
||||
|
||||
#define DECLARE_SETOPT(param_type) \
|
||||
CURLcode setopt(CURLoption option, param_type parameter)
|
||||
|
||||
@@ -1065,6 +1065,10 @@ void AICurlThread::wakeup_thread(void)
|
||||
DoutEntering(dc::curl, "AICurlThread::wakeup_thread");
|
||||
llassert(is_main_thread());
|
||||
|
||||
// If we are already exiting the viewer then return immediately.
|
||||
if (!mRunning)
|
||||
return;
|
||||
|
||||
// Try if curl thread is still awake and if so, pass the new commands directly.
|
||||
if (mWakeUpMutex.tryLock())
|
||||
{
|
||||
@@ -1609,7 +1613,9 @@ CURLMcode MultiHandle::remove_easy_request(addedEasyRequests_type::iterator cons
|
||||
ThreadSafeBufferedCurlEasyRequest* lockobj = iter->get_ptr().get();
|
||||
#endif
|
||||
mAddedEasyRequests.erase(iter);
|
||||
#if CWDEBUG
|
||||
Dout(dc::curl, "MultiHandle::remove_easy_request: Removed AICurlEasyRequest " << (void*)lockobj << "; now processing " << mAddedEasyRequests.size() << " easy handles.");
|
||||
#endif
|
||||
|
||||
// Attempt to add a queued request, if any.
|
||||
PerHostRequestQueue_wat(*per_host)->add_queued_to(this);
|
||||
@@ -2148,10 +2154,14 @@ void stopCurlThread(void)
|
||||
ms_sleep(10);
|
||||
}
|
||||
Dout(dc::curl, "Curl thread" << (curlThreadIsRunning() ? " not" : "") << " stopped after " << ((100 - count) * 10) << "ms.");
|
||||
// Clear the command queue, for a cleaner cleanup.
|
||||
}
|
||||
}
|
||||
|
||||
void clearCommandQueue(void)
|
||||
{
|
||||
// Clear the command queue now in order to avoid the global deinitialization order fiasco.
|
||||
command_queue_wat command_queue_w(command_queue);
|
||||
command_queue_w->clear();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2162,6 +2172,12 @@ void BufferedCurlEasyRequest::setStatusAndReason(U32 status, std::string const&
|
||||
mStatus = status;
|
||||
mReason = reason;
|
||||
AICurlInterface::Stats::status_count[AICurlInterface::Stats::status2index(mStatus)]++;
|
||||
|
||||
// Sanity check. If the server replies with a redirect status then we better have that option turned on!
|
||||
if ((status >= 300 && status < 400) && mResponder && !mResponder->followRedir())
|
||||
{
|
||||
llerrs << "Received " << status << " (" << reason << ") for responder \"" << mTimeoutPolicy->name() << "\" which has no followRedir()!" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
void BufferedCurlEasyRequest::processOutput(void)
|
||||
@@ -2353,10 +2369,10 @@ size_t BufferedCurlEasyRequest::curlHeaderCallback(char* data, size_t size, size
|
||||
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
|
||||
int debug_callback(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr)
|
||||
{
|
||||
BufferedCurlEasyRequest* request = (BufferedCurlEasyRequest*)user_ptr;
|
||||
|
||||
#ifdef CWDEBUG
|
||||
using namespace ::libcwd;
|
||||
|
||||
BufferedCurlEasyRequest* request = (BufferedCurlEasyRequest*)user_ptr;
|
||||
std::ostringstream marker;
|
||||
marker << (void*)request->get_lockobj();
|
||||
libcw_do.push_marker();
|
||||
|
||||
@@ -820,6 +820,7 @@ P(accountingCostResponder);
|
||||
P(agentStateResponder);
|
||||
P(assetUploadResponder);
|
||||
P(asyncConsoleResponder);
|
||||
P(avatarPickerResponder);
|
||||
P(authHandler);
|
||||
P(avatarNameResponder);
|
||||
P2(baseCapabilitiesComplete, transfer_18s);
|
||||
@@ -889,6 +890,7 @@ P(viewerStatsResponder);
|
||||
P(viewerVoiceAccountProvisionResponder);
|
||||
P(voiceCallCapResponder);
|
||||
P(voiceClientCapResponder);
|
||||
P(webProfileResponders);
|
||||
P(wholeModelFeeResponder);
|
||||
P(wholeModelUploadResponder);
|
||||
P2(XMLRPCResponder, connect_40s);
|
||||
|
||||
@@ -624,7 +624,7 @@ void debug_curl_easy_reset(CURL* handle)
|
||||
|
||||
CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...)
|
||||
{
|
||||
CURLcode ret;
|
||||
CURLcode ret = CURLE_UNKNOWN_OPTION; // Suppress compiler warning.
|
||||
va_list ap;
|
||||
union param_type {
|
||||
long along;
|
||||
@@ -841,7 +841,7 @@ CURLMcode debug_curl_multi_remove_handle(CURLM* multi_handle, CURL* easy_handle)
|
||||
|
||||
CURLMcode debug_curl_multi_setopt(CURLM* multi_handle, CURLMoption option, ...)
|
||||
{
|
||||
CURLMcode ret;
|
||||
CURLMcode ret = CURLM_UNKNOWN_OPTION; // Suppress compiler warning.
|
||||
va_list ap;
|
||||
union param_type {
|
||||
long along;
|
||||
|
||||
@@ -93,6 +93,9 @@ namespace LLAvatarNameCache
|
||||
/// Time when unrefreshed cached names were checked last
|
||||
static F64 sLastExpireCheck;
|
||||
|
||||
/// Time-to-live for a temp cache entry.
|
||||
const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Internal methods
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -291,13 +294,14 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
|
||||
// Clear this agent from the pending list
|
||||
LLAvatarNameCache::sPendingQueue.erase(agent_id);
|
||||
|
||||
const LLAvatarName& av_name = existing->second;
|
||||
LLAvatarName& av_name = existing->second;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent "
|
||||
<< agent_id
|
||||
<< "user '" << av_name.mUsername << "' "
|
||||
<< "display '" << av_name.mDisplayName << "' "
|
||||
<< "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
|
||||
<< LL_ENDL;
|
||||
av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,19 +346,23 @@ void LLAvatarNameCache::requestNamesViaCapability()
|
||||
// http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0
|
||||
//
|
||||
// Apache can handle URLs of 4096 chars, but let's be conservative
|
||||
const U32 NAME_URL_MAX = 4096;
|
||||
const U32 NAME_URL_SEND_THRESHOLD = 3000;
|
||||
static const U32 NAME_URL_MAX = 4096;
|
||||
static const U32 NAME_URL_SEND_THRESHOLD = 3500;
|
||||
|
||||
std::string url;
|
||||
url.reserve(NAME_URL_MAX);
|
||||
|
||||
std::vector<LLUUID> agent_ids;
|
||||
agent_ids.reserve(128);
|
||||
|
||||
U32 id_total = sAskQueue.size();
|
||||
U32 ids = 0;
|
||||
ask_queue_t::const_iterator it = sAskQueue.begin();
|
||||
for ( ; it != sAskQueue.end(); ++it)
|
||||
ask_queue_t::const_iterator it;
|
||||
while(!sAskQueue.empty())
|
||||
{
|
||||
it = sAskQueue.begin();
|
||||
const LLUUID& agent_id = *it;
|
||||
sAskQueue.erase(it);
|
||||
|
||||
if (url.empty())
|
||||
{
|
||||
@@ -377,27 +385,17 @@ void LLAvatarNameCache::requestNamesViaCapability()
|
||||
|
||||
if (url.size() > NAME_URL_SEND_THRESHOLD)
|
||||
{
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability first "
|
||||
<< ids << " ids"
|
||||
<< LL_ENDL;
|
||||
LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
|
||||
url.clear();
|
||||
agent_ids.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!url.empty())
|
||||
{
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability all "
|
||||
<< ids << " ids"
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested "
|
||||
<< ids << "/" << id_total << "ids "
|
||||
<< LL_ENDL;
|
||||
LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
|
||||
url.clear();
|
||||
agent_ids.clear();
|
||||
}
|
||||
|
||||
// We've moved all asks to the pending request queue
|
||||
sAskQueue.clear();
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
|
||||
@@ -414,20 +412,25 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
|
||||
<< LL_ENDL;
|
||||
buildLegacyName(full_name, &av_name);
|
||||
|
||||
// Don't add to cache, the data already exists in the legacy name system
|
||||
// cache and we don't want or need duplicate storage, because keeping the
|
||||
// two copies in sync is complex.
|
||||
processName(agent_id, av_name, false);
|
||||
// Add to cache, because if we don't we'll keep rerequesting the
|
||||
// same record forever. buildLegacyName should always guarantee
|
||||
// that these records expire reasonably soon
|
||||
// (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due
|
||||
// to something temporary we will eventually request and get the right data.
|
||||
processName(agent_id, av_name, true);
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::requestNamesViaLegacy()
|
||||
{
|
||||
static const S32 MAX_REQUESTS = 100;
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
std::string full_name;
|
||||
ask_queue_t::const_iterator it = sAskQueue.begin();
|
||||
for (; it != sAskQueue.end(); ++it)
|
||||
ask_queue_t::const_iterator it;
|
||||
for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests)
|
||||
{
|
||||
it = sAskQueue.begin();
|
||||
const LLUUID& agent_id = *it;
|
||||
sAskQueue.erase(it);
|
||||
|
||||
// Mark as pending first, just in case the callback is immediately
|
||||
// invoked below. This should never happen in practice.
|
||||
@@ -439,10 +442,6 @@ void LLAvatarNameCache::requestNamesViaLegacy()
|
||||
boost::bind(&LLAvatarNameCache::legacyNameCallback,
|
||||
_1, _2, _3));
|
||||
}
|
||||
|
||||
// We've either answered immediately or moved all asks to the
|
||||
// pending queue
|
||||
sAskQueue.clear();
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::initClass(bool running)
|
||||
@@ -519,11 +518,11 @@ void LLAvatarNameCache::idle()
|
||||
// *TODO: Possibly re-enabled this based on People API load measurements
|
||||
// 100 ms is the threshold for "user speed" operations, so we can
|
||||
// stall for about that long to batch up requests.
|
||||
//const F32 SECS_BETWEEN_REQUESTS = 0.1f;
|
||||
//if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS))
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
const F32 SECS_BETWEEN_REQUESTS = 0.1f;
|
||||
if (!sRequestTimer.hasExpired())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sAskQueue.empty())
|
||||
{
|
||||
@@ -538,6 +537,12 @@ void LLAvatarNameCache::idle()
|
||||
}
|
||||
}
|
||||
|
||||
if (sAskQueue.empty())
|
||||
{
|
||||
// cleared the list, reset the request timer.
|
||||
sRequestTimer.reset(SECS_BETWEEN_REQUESTS);
|
||||
}
|
||||
|
||||
// erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME
|
||||
eraseUnrefreshed();
|
||||
}
|
||||
@@ -595,7 +600,7 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
|
||||
av_name->mDisplayName = full_name;
|
||||
av_name->mIsDisplayNameDefault = true;
|
||||
av_name->mIsTemporaryName = true;
|
||||
av_name->mExpires = F64_MAX; // not used because these are not cached
|
||||
av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
|
||||
<< full_name
|
||||
<< LL_ENDL;
|
||||
@@ -673,8 +678,10 @@ void LLAvatarNameCache::fireSignal(const LLUUID& agent_id,
|
||||
signal(agent_id, av_name);
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
|
||||
LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
|
||||
{
|
||||
callback_connection_t connection;
|
||||
|
||||
if (sRunning)
|
||||
{
|
||||
// ...only do immediate lookups when cache is running
|
||||
@@ -690,7 +697,7 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
|
||||
{
|
||||
// ...name already exists in cache, fire callback now
|
||||
fireSignal(agent_id, slot, av_name);
|
||||
return;
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -703,7 +710,7 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
|
||||
LLAvatarName av_name;
|
||||
buildLegacyName(full_name, &av_name);
|
||||
fireSignal(agent_id, slot, av_name);
|
||||
return;
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -720,15 +727,17 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
|
||||
{
|
||||
// ...new callback for this id
|
||||
callback_signal_t* signal = new callback_signal_t();
|
||||
signal->connect(slot);
|
||||
connection = signal->connect(slot);
|
||||
sSignalMap[agent_id] = signal;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...existing callback, bind additional slot
|
||||
callback_signal_t* signal = sig_it->second;
|
||||
signal->connect(slot);
|
||||
connection = signal->connect(slot);
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-12-08 (RLVa-1.4.0a) | Added: RLVa-1.2.2c
|
||||
@@ -774,12 +783,6 @@ void LLAvatarNameCache::erase(const LLUUID& agent_id)
|
||||
sCache.erase(agent_id);
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::fetch(const LLUUID& agent_id)
|
||||
{
|
||||
// re-request, even if request is already pending
|
||||
sAskQueue.insert(agent_id);
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name)
|
||||
{
|
||||
// *TODO: update timestamp if zero?
|
||||
@@ -788,26 +791,35 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na
|
||||
|
||||
F64 LLAvatarNameCache::nameExpirationFromHeaders(AIHTTPReceivedHeaders const& headers)
|
||||
{
|
||||
F64 expires;
|
||||
expirationFromCacheControl(headers, &expires);
|
||||
return expires;
|
||||
F64 expires = 0.0;
|
||||
if (expirationFromCacheControl(headers, &expires))
|
||||
{
|
||||
return expires;
|
||||
}
|
||||
else
|
||||
{
|
||||
// With no expiration info, default to an hour
|
||||
const F64 DEFAULT_EXPIRES = 60.0 * 60.0;
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
return now + DEFAULT_EXPIRES;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLAvatarNameCache::expirationFromCacheControl(AIHTTPReceivedHeaders const& headers, F64* expires)
|
||||
{
|
||||
bool fromCacheControl = false;
|
||||
S32 max_age = 3600; // With no expiration info, default to an hour.
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
// Allow the header to override the default
|
||||
std::string cache_control;
|
||||
if (headers.getFirstValue("cache-control", cache_control))
|
||||
{
|
||||
S32 max_age = 0;
|
||||
if (max_age_from_cache_control(cache_control, &max_age))
|
||||
{
|
||||
*expires = now + (F64)max_age;
|
||||
fromCacheControl = true;
|
||||
}
|
||||
}
|
||||
*expires = now + (F64)max_age;
|
||||
LL_DEBUGS("AvNameCache")
|
||||
<< ( fromCacheControl ? "expires based on cache control " : "default expiration " )
|
||||
<< "in " << *expires - now << " seconds"
|
||||
|
||||
@@ -71,10 +71,11 @@ namespace LLAvatarNameCache
|
||||
void (const LLUUID& agent_id, const LLAvatarName& av_name)>
|
||||
callback_signal_t;
|
||||
typedef callback_signal_t::slot_type callback_slot_t;
|
||||
typedef boost::signals2::connection callback_connection_t;
|
||||
|
||||
// Fetches name information and calls callback.
|
||||
// If name information is in cache, callback will be called immediately.
|
||||
void get(const LLUUID& agent_id, callback_slot_t slot);
|
||||
callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
|
||||
|
||||
// Allow display names to be explicitly disabled for testing.
|
||||
void setUseDisplayNames(bool use);
|
||||
@@ -90,10 +91,6 @@ namespace LLAvatarNameCache
|
||||
/// Provide some fallback for agents that return errors
|
||||
void handleAgentError(const LLUUID& agent_id);
|
||||
|
||||
// Force a re-fetch of the most recent data, but keep the current
|
||||
// data in cache
|
||||
void fetch(const LLUUID& agent_id);
|
||||
|
||||
void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
|
||||
|
||||
// Compute name expiration time from HTTP Cache-Control header,
|
||||
|
||||
@@ -161,7 +161,7 @@ public:
|
||||
|
||||
// A derived class should return true if curl should follow redirections.
|
||||
// The default is not to follow redirections.
|
||||
virtual bool followRedir(void) { return false; }
|
||||
virtual bool followRedir(void) const { return false; }
|
||||
|
||||
// Timeout policy to use.
|
||||
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const = 0;
|
||||
@@ -188,6 +188,7 @@ public:
|
||||
class ResponderHeadersOnly : public ResponderBase {
|
||||
private:
|
||||
/*virtual*/ bool needsHeaders(void) const { return true; }
|
||||
/*virtual*/ bool followRedir(void) const { return true; }
|
||||
|
||||
protected:
|
||||
// ResponderBase event
|
||||
|
||||
@@ -85,11 +85,6 @@ LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, std::string cons
|
||||
|
||||
void LLURLRequest::initialize_impl(void)
|
||||
{
|
||||
if (mHeaders.hasHeader("Cookie"))
|
||||
{
|
||||
allowCookies();
|
||||
}
|
||||
|
||||
// If the header is "Pragma" with no value, the caller intends to
|
||||
// force libcurl to drop the Pragma header it so gratuitously inserts.
|
||||
// Before inserting the header, force libcurl to not use the proxy.
|
||||
@@ -105,7 +100,7 @@ void LLURLRequest::initialize_impl(void)
|
||||
// but if they did not specify a Content-Type, then ask the injector.
|
||||
mHeaders.addHeader("Content-Type", mBody->contentType(), AIHTTPHeaders::keep_existing_header);
|
||||
}
|
||||
else
|
||||
else if (mAction != HTTP_HEAD)
|
||||
{
|
||||
// Check to see if we have already set Accept or not. If no one
|
||||
// set it, set it to application/llsd+xml since that's what we
|
||||
@@ -199,12 +194,6 @@ void LLURLRequest::useProxy(const std::string &proxy)
|
||||
}
|
||||
#endif
|
||||
|
||||
void LLURLRequest::allowCookies()
|
||||
{
|
||||
AICurlEasyRequest_wat curlEasyRequest_w(*mCurlEasyRequest);
|
||||
curlEasyRequest_w->setoptString(CURLOPT_COOKIEFILE, "");
|
||||
}
|
||||
|
||||
bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w)
|
||||
{
|
||||
bool rv = false;
|
||||
@@ -213,13 +202,11 @@ bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w)
|
||||
{
|
||||
case HTTP_HEAD:
|
||||
curlEasyRequest_w->setopt(CURLOPT_NOBODY, 1);
|
||||
curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1);
|
||||
rv = true;
|
||||
break;
|
||||
|
||||
case HTTP_GET:
|
||||
curlEasyRequest_w->setopt(CURLOPT_HTTPGET, 1);
|
||||
curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1);
|
||||
|
||||
// Set Accept-Encoding to allow response compression
|
||||
curlEasyRequest_w->setoptString(CURLOPT_ENCODING, mNoCompression ? "identity" : "");
|
||||
|
||||
@@ -84,11 +84,6 @@ class LLURLRequest : public AICurlEasyRequestStateMachine {
|
||||
/*virtual*/ ~LLURLRequest() { }
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Turn on cookie handling for this request with CURLOPT_COOKIEFILE.
|
||||
*/
|
||||
void allowCookies(void);
|
||||
|
||||
/**
|
||||
* @ brief Turn off (or on) the CURLOPT_PROXY header.
|
||||
*/
|
||||
|
||||
@@ -1027,7 +1027,8 @@ void LLModel::setVolumeFaceData(
|
||||
|
||||
if (tc.get())
|
||||
{
|
||||
LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32));
|
||||
U32 tex_size = (num_verts*2*sizeof(F32)+0xF)&~0xF;
|
||||
LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), tex_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -71,7 +71,7 @@ void LLStyle::drawControl(ControlElement element, const QStyleOption *option, QP
|
||||
QPlastiqueStyle::drawControl(element, &localOption, painter, widget);
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -935,7 +935,7 @@ void LLGLManager::initExtensions()
|
||||
mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
|
||||
mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
|
||||
mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
|
||||
mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE;
|
||||
mHasTransformFeedback = mGLVersion >= 4.f || ExtensionExists("GL_EXT_transform_feedback", gGLHExts.mSysExts);
|
||||
#if !LL_DARWIN
|
||||
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
|
||||
#endif
|
||||
|
||||
@@ -1329,6 +1329,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
||||
llassert(mCurrentDiscardLevel >= 0);
|
||||
discard_level = mCurrentDiscardLevel;
|
||||
}
|
||||
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
|
||||
|
||||
if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
|
||||
{
|
||||
@@ -1586,7 +1587,18 @@ void LLImageGL::destroyGLTexture()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//force to invalidate the gl texture, most likely a sculpty texture
|
||||
void LLImageGL::forceToInvalidateGLTexture()
|
||||
{
|
||||
if (mTexName != 0)
|
||||
{
|
||||
destroyGLTexture();
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -119,6 +119,7 @@ public:
|
||||
// Read back a raw image for this discard level, if it exists
|
||||
BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok);
|
||||
void destroyGLTexture();
|
||||
void forceToInvalidateGLTexture();
|
||||
|
||||
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
|
||||
void setComponents(S8 ncomponents) { mComponents = ncomponents; }
|
||||
|
||||
@@ -229,8 +229,6 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
|
||||
stop_glerror();
|
||||
if (mIndex < 0) return false;
|
||||
|
||||
gGL.flush();
|
||||
|
||||
LLImageGL* gl_tex = NULL ;
|
||||
if (texture == NULL || !(gl_tex = texture->getGLTexture()))
|
||||
{
|
||||
@@ -258,6 +256,7 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
|
||||
}
|
||||
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
|
||||
{
|
||||
gGL.flush();
|
||||
activate();
|
||||
enable(gl_tex->getTarget());
|
||||
mCurrTexture = gl_tex->getTexName();
|
||||
@@ -1120,6 +1119,9 @@ void LLRender::refreshState(void)
|
||||
|
||||
setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal);
|
||||
|
||||
//Singu note: Also reset glBlendFunc
|
||||
blendFunc(mCurrBlendColorSFactor,mCurrBlendColorDFactor,mCurrBlendAlphaSFactor,mCurrBlendAlphaDFactor);
|
||||
|
||||
mDirty = false;
|
||||
}
|
||||
|
||||
@@ -1510,20 +1512,26 @@ void LLRender::pushUIMatrix()
|
||||
{
|
||||
if (mUIOffset.empty())
|
||||
{
|
||||
mUIOffset.push_back(new LLVector4a(0.f));
|
||||
mUIOffset.push_back(static_cast<LLVector4a*>(ll_aligned_malloc_16(sizeof(LLVector4a))));
|
||||
mUIOffset.back()->splat(0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
mUIOffset.push_back(new LLVector4a(*mUIOffset.back()));
|
||||
const LLVector4a* last_entry = mUIOffset.back();
|
||||
mUIOffset.push_back(static_cast<LLVector4a*>(ll_aligned_malloc_16(sizeof(LLVector4a))));
|
||||
*mUIOffset.back() = *last_entry;
|
||||
}
|
||||
|
||||
if (mUIScale.empty())
|
||||
{
|
||||
mUIScale.push_back(new LLVector4a(1.f));
|
||||
mUIScale.push_back(static_cast<LLVector4a*>(ll_aligned_malloc_16(sizeof(LLVector4a))));
|
||||
mUIScale.back()->splat(1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
mUIScale.push_back(new LLVector4a(*mUIScale.back()));
|
||||
const LLVector4a* last_entry = mUIScale.back();
|
||||
mUIScale.push_back(static_cast<LLVector4a*>(ll_aligned_malloc_16(sizeof(LLVector4a))));
|
||||
*mUIScale.back() = *last_entry;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1533,9 +1541,9 @@ void LLRender::popUIMatrix()
|
||||
{
|
||||
llerrs << "UI offset stack blown." << llendl;
|
||||
}
|
||||
delete mUIOffset.back();
|
||||
ll_aligned_free_16(mUIOffset.back());
|
||||
mUIOffset.pop_back();
|
||||
delete mUIScale.back();
|
||||
ll_aligned_free_16(mUIScale.back());
|
||||
mUIScale.pop_back();
|
||||
}
|
||||
|
||||
@@ -1580,7 +1588,7 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB
|
||||
if (mCurrColorMask[0] != writeColorR ||
|
||||
mCurrColorMask[1] != writeColorG ||
|
||||
mCurrColorMask[2] != writeColorB ||
|
||||
mCurrColorMask[3] != writeAlpha)
|
||||
mCurrColorMask[3] != writeAlpha || mDirty)
|
||||
{
|
||||
mCurrColorMask[0] = writeColorR;
|
||||
mCurrColorMask[1] = writeColorG;
|
||||
@@ -1635,7 +1643,7 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
|
||||
}
|
||||
|
||||
if (mCurrAlphaFunc != func ||
|
||||
mCurrAlphaFuncVal != value)
|
||||
mCurrAlphaFuncVal != value || mDirty)
|
||||
{
|
||||
mCurrAlphaFunc = func;
|
||||
mCurrAlphaFuncVal = value;
|
||||
@@ -1679,7 +1687,7 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
|
||||
llassert(sfactor < BF_UNDEF);
|
||||
llassert(dfactor < BF_UNDEF);
|
||||
if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor ||
|
||||
mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor)
|
||||
mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor || mDirty)
|
||||
{
|
||||
mCurrBlendColorSFactor = sfactor;
|
||||
mCurrBlendAlphaSFactor = sfactor;
|
||||
@@ -1704,7 +1712,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
|
||||
return;
|
||||
}
|
||||
if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor ||
|
||||
mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor)
|
||||
mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor || mDirty)
|
||||
{
|
||||
mCurrBlendColorSFactor = color_sfactor;
|
||||
mCurrBlendAlphaSFactor = alpha_sfactor;
|
||||
|
||||
@@ -813,7 +813,6 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
|
||||
{
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth);
|
||||
}
|
||||
check_framebuffer_status();
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
@@ -660,6 +660,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
||||
}
|
||||
}
|
||||
|
||||
static const LLCachedControl<bool> SHPackDeferredNormals("SHPackDeferredNormals",false);
|
||||
if(SHPackDeferredNormals)
|
||||
text[count++] = strdup("#define PACK_NORMALS\n");
|
||||
|
||||
//copy preprocessor definitions into buffer
|
||||
for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter)
|
||||
{
|
||||
@@ -1116,7 +1120,7 @@ void LLShaderMgr::initAttribsAndUniforms()
|
||||
mReservedUniforms.push_back("ssao_max_radius");
|
||||
mReservedUniforms.push_back("ssao_factor");
|
||||
mReservedUniforms.push_back("ssao_factor_inv");
|
||||
mReservedUniforms.push_back("ssao_effect_mat");
|
||||
mReservedUniforms.push_back("ssao_effect");
|
||||
mReservedUniforms.push_back("screen_res");
|
||||
mReservedUniforms.push_back("near_clip");
|
||||
mReservedUniforms.push_back("shadow_offset");
|
||||
|
||||
@@ -120,7 +120,7 @@ public:
|
||||
DEFERRED_SSAO_MAX_RADIUS,
|
||||
DEFERRED_SSAO_FACTOR,
|
||||
DEFERRED_SSAO_FACTOR_INV,
|
||||
DEFERRED_SSAO_EFFECT_MAT,
|
||||
DEFERRED_SSAO_EFFECT,
|
||||
DEFERRED_SCREEN_RES,
|
||||
DEFERRED_NEAR_CLIP,
|
||||
DEFERRED_SHADOW_OFFSET,
|
||||
|
||||
@@ -2083,6 +2083,16 @@ void LLVertexBuffer::flush()
|
||||
}
|
||||
}
|
||||
|
||||
// bind for transform feedback (quick 'n dirty)
|
||||
void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count)
|
||||
{
|
||||
#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
|
||||
U32 offset = mOffsets[type] + sTypeSize[type]*index;
|
||||
U32 size= (sTypeSize[type]*count);
|
||||
glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set for rendering
|
||||
void LLVertexBuffer::setBuffer(U32 data_mask)
|
||||
{
|
||||
|
||||
@@ -202,16 +202,18 @@ protected:
|
||||
void destroyGLIndices();
|
||||
void updateNumVerts(S32 nverts);
|
||||
void updateNumIndices(S32 nindices);
|
||||
bool useVBOs() const;
|
||||
void unmapBuffer();
|
||||
|
||||
public:
|
||||
|
||||
LLVertexBuffer(U32 typemask, S32 usage);
|
||||
|
||||
// map for data access
|
||||
volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
|
||||
volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
|
||||
|
||||
void bindForFeedback(U32 channel, U32 type, U32 index, U32 count);
|
||||
|
||||
// set for rendering
|
||||
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
|
||||
void flush(); //flush pending data to GL memory
|
||||
@@ -240,6 +242,7 @@ public:
|
||||
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
|
||||
|
||||
bool useVBOs() const;
|
||||
bool isEmpty() const { return mEmpty; }
|
||||
bool isLocked() const { return mVertexLocked || mIndexLocked; }
|
||||
S32 getNumVerts() const { return mNumVerts; }
|
||||
|
||||
@@ -615,7 +615,7 @@ void LLComboBox::showList()
|
||||
S32 min_width = getRect().getWidth();
|
||||
S32 max_width = llmax(min_width, MAX_COMBO_WIDTH);
|
||||
// make sure we have up to date content width metrics
|
||||
mList->calcColumnWidths();
|
||||
mList->updateColumnWidths();
|
||||
S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width);
|
||||
|
||||
if (mListPosition == BELOW)
|
||||
@@ -707,7 +707,7 @@ void LLComboBox::hideList()
|
||||
|
||||
mButton->setToggleState(FALSE);
|
||||
mList->setVisible(FALSE);
|
||||
mList->highlightNthItem(-1);
|
||||
mList->mouseOverHighlightNthItem(-1);
|
||||
|
||||
setUseBoundingRect(FALSE);
|
||||
if( gFocusMgr.getTopCtrl() == this )
|
||||
@@ -731,7 +731,7 @@ void LLComboBox::onButtonDown(void *userdata)
|
||||
if (last_selected_item)
|
||||
{
|
||||
// highlight the original selection before potentially selecting a new item
|
||||
self->mList->highlightNthItem(self->mList->getItemIndex(last_selected_item));
|
||||
self->mList->mouseOverHighlightNthItem(self->mList->getItemIndex(last_selected_item));
|
||||
}
|
||||
|
||||
if( self->mPrearrangeCallback )
|
||||
@@ -839,7 +839,7 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask)
|
||||
if (last_selected_item)
|
||||
{
|
||||
// highlight the original selection before potentially selecting a new item
|
||||
mList->highlightNthItem(mList->getItemIndex(last_selected_item));
|
||||
mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item));
|
||||
}
|
||||
result = mList->handleKeyHere(key, mask);
|
||||
|
||||
@@ -873,7 +873,7 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char)
|
||||
if (last_selected_item)
|
||||
{
|
||||
// highlight the original selection before potentially selecting a new item
|
||||
mList->highlightNthItem(mList->getItemIndex(last_selected_item));
|
||||
mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item));
|
||||
}
|
||||
result = mList->handleUnicodeCharHere(uni_char);
|
||||
if (mList->getLastSelectedItem() != last_selected_item)
|
||||
|
||||
@@ -148,7 +148,6 @@ LLFloater::LLFloater() :
|
||||
mResizeHandle[i] = NULL;
|
||||
}
|
||||
mDragHandle = NULL;
|
||||
mHandle.bind(this);
|
||||
mNotificationContext = new LLFloaterNotificationContext(getHandle());
|
||||
}
|
||||
|
||||
@@ -222,7 +221,6 @@ void LLFloater::initFloater(const std::string& title,
|
||||
BOOL resizable, S32 min_width, S32 min_height,
|
||||
BOOL drag_on_left, BOOL minimizable, BOOL close_btn)
|
||||
{
|
||||
mHandle.bind(this);
|
||||
mNotificationContext = new LLFloaterNotificationContext(getHandle());
|
||||
|
||||
// Init function can be called more than once, so clear out old data.
|
||||
@@ -422,7 +420,7 @@ void LLFloater::initFloater(const std::string& title,
|
||||
setVisible(FALSE);
|
||||
|
||||
// add self to handle->floater map
|
||||
sFloaterMap[mHandle] = this;
|
||||
sFloaterMap[getHandle()] = this;
|
||||
|
||||
if (!getParent())
|
||||
{
|
||||
@@ -483,7 +481,7 @@ LLFloater::~LLFloater()
|
||||
// correct, non-minimized positions.
|
||||
setMinimized( FALSE );
|
||||
|
||||
sFloaterMap.erase(mHandle);
|
||||
sFloaterMap.erase(getHandle());
|
||||
|
||||
delete mDragHandle;
|
||||
for (S32 i = 0; i < 4; i++)
|
||||
|
||||
@@ -227,7 +227,7 @@ public:
|
||||
void clearSnapTarget() { mSnappedTo.markDead(); }
|
||||
LLHandle<LLFloater> getSnapTarget() const { return mSnappedTo; }
|
||||
|
||||
LLHandle<LLFloater> getHandle() const { return mHandle; }
|
||||
LLHandle<LLFloater> getHandle() const { return getDerivedHandle<LLFloater>(); }
|
||||
|
||||
// Return a closeable floater, if any, given the current focus.
|
||||
static LLFloater* getClosableFloaterFromFocus();
|
||||
@@ -331,7 +331,6 @@ private:
|
||||
S32 mPreviousMinimizedLeft;
|
||||
|
||||
LLFloaterNotificationContext* mNotificationContext;
|
||||
LLRootHandle<LLFloater> mHandle;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -28,38 +28,67 @@
|
||||
#define LLHANDLE_H
|
||||
|
||||
#include "llpointer.h"
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
template <typename T>
|
||||
/**
|
||||
* Helper object for LLHandle. Don't instantiate these directly, used
|
||||
* exclusively by LLHandle.
|
||||
*/
|
||||
class LLTombStone : public LLRefCount
|
||||
{
|
||||
public:
|
||||
LLTombStone(T* target = NULL) : mTarget(target) {}
|
||||
LLTombStone(void* target = NULL) : mTarget(target) {}
|
||||
|
||||
void setTarget(T* target) { mTarget = target; }
|
||||
T* getTarget() const { return mTarget; }
|
||||
void setTarget(void* target) { mTarget = target; }
|
||||
void* getTarget() const { return mTarget; }
|
||||
private:
|
||||
T* mTarget;
|
||||
mutable void* mTarget;
|
||||
};
|
||||
|
||||
// LLHandles are used to refer to objects whose lifetime you do not control or influence.
|
||||
// Calling get() on a handle will return a pointer to the referenced object or NULL,
|
||||
// if the object no longer exists. Note that during the lifetime of the returned pointer,
|
||||
// you are assuming that the object will not be deleted by any action you perform,
|
||||
// or any other thread, as normal when using pointers, so avoid using that pointer outside of
|
||||
// the local code block.
|
||||
//
|
||||
// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
|
||||
|
||||
/**
|
||||
* LLHandles are used to refer to objects whose lifetime you do not control or influence.
|
||||
* Calling get() on a handle will return a pointer to the referenced object or NULL,
|
||||
* if the object no longer exists. Note that during the lifetime of the returned pointer,
|
||||
* you are assuming that the object will not be deleted by any action you perform,
|
||||
* or any other thread, as normal when using pointers, so avoid using that pointer outside of
|
||||
* the local code block.
|
||||
*
|
||||
* https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
|
||||
*
|
||||
* The implementation is like some "weak pointer" implementations. When we
|
||||
* can't control the lifespan of the referenced object of interest, we can
|
||||
* still instantiate a proxy object whose lifespan we DO control, and store in
|
||||
* the proxy object a dumb pointer to the actual target. Then we just have to
|
||||
* ensure that on destruction of the target object, the proxy's dumb pointer
|
||||
* is set NULL.
|
||||
*
|
||||
* LLTombStone is our proxy object. LLHandle contains an LLPointer to the
|
||||
* LLTombStone, so every copy of an LLHandle increments the LLTombStone's ref
|
||||
* count as usual.
|
||||
*
|
||||
* One copy of the LLHandle, specifically the LLRootHandle, must be stored in
|
||||
* the referenced object. Destroying the LLRootHandle is what NULLs the
|
||||
* proxy's target pointer.
|
||||
*
|
||||
* Minor optimization: we want LLHandle's mTombStone to always be a valid
|
||||
* LLPointer, saving some conditionals in dereferencing. That's the
|
||||
* getDefaultTombStone() mechanism. The default LLTombStone object's target
|
||||
* pointer is always NULL, so it's semantically identical to allowing
|
||||
* mTombStone to be invalid.
|
||||
*/
|
||||
template <typename T>
|
||||
class LLHandle
|
||||
{
|
||||
template <typename U> friend class LLHandle;
|
||||
template <typename U> friend class LLHandleProvider;
|
||||
public:
|
||||
LLHandle() : mTombStone(getDefaultTombStone()) {}
|
||||
const LLHandle<T>& operator =(const LLHandle<T>& other)
|
||||
{
|
||||
mTombStone = other.mTombStone;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
LLHandle(const LLHandle<U>& other, typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0)
|
||||
: mTombStone(other.mTombStone)
|
||||
{}
|
||||
|
||||
bool isDead() const
|
||||
{
|
||||
@@ -73,7 +102,7 @@ public:
|
||||
|
||||
T* get() const
|
||||
{
|
||||
return mTombStone->getTarget();
|
||||
return reinterpret_cast<T*>(mTombStone->getTarget());
|
||||
}
|
||||
|
||||
friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
|
||||
@@ -94,37 +123,49 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
LLPointer<LLTombStone<T> > mTombStone;
|
||||
LLPointer<LLTombStone> mTombStone;
|
||||
|
||||
private:
|
||||
static LLPointer<LLTombStone<T> >& getDefaultTombStone()
|
||||
typedef T* pointer_t;
|
||||
static LLPointer<LLTombStone>& getDefaultTombStone()
|
||||
{
|
||||
static LLPointer<LLTombStone<T> > sDefaultTombStone = new LLTombStone<T>;
|
||||
static LLPointer<LLTombStone> sDefaultTombStone = new LLTombStone;
|
||||
return sDefaultTombStone;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LLRootHandle isa LLHandle which must be stored in the referenced object.
|
||||
* You can either store it directly and explicitly bind(this), or derive from
|
||||
* LLHandleProvider (q.v.) which automates that for you. The essential point
|
||||
* is that destroying the LLRootHandle (as a consequence of destroying the
|
||||
* referenced object) calls unbind(), setting the LLTombStone's target pointer
|
||||
* NULL.
|
||||
*/
|
||||
template <typename T>
|
||||
class LLRootHandle : public LLHandle<T>
|
||||
{
|
||||
public:
|
||||
typedef LLRootHandle<T> self_t;
|
||||
typedef LLHandle<T> base_t;
|
||||
|
||||
LLRootHandle(T* object) { bind(object); }
|
||||
LLRootHandle() {};
|
||||
~LLRootHandle() { unbind(); }
|
||||
|
||||
// this is redundant, since a LLRootHandle *is* an LLHandle
|
||||
LLHandle<T> getHandle() { return LLHandle<T>(*this); }
|
||||
// this is redundant, since an LLRootHandle *is* an LLHandle
|
||||
//LLHandle<T> getHandle() { return LLHandle<T>(*this); }
|
||||
|
||||
void bind(T* object)
|
||||
{
|
||||
// unbind existing tombstone
|
||||
if (LLHandle<T>::mTombStone.notNull())
|
||||
{
|
||||
if (LLHandle<T>::mTombStone->getTarget() == object) return;
|
||||
if (LLHandle<T>::mTombStone->getTarget() == (void*)object) return;
|
||||
LLHandle<T>::mTombStone->setTarget(NULL);
|
||||
}
|
||||
// tombstone reference counted, so no paired delete
|
||||
LLHandle<T>::mTombStone = new LLTombStone<T>(object);
|
||||
LLHandle<T>::mTombStone = new LLTombStone((void*)object);
|
||||
}
|
||||
|
||||
void unbind()
|
||||
@@ -137,11 +178,22 @@ private:
|
||||
LLRootHandle(const LLRootHandle& other) {};
|
||||
};
|
||||
|
||||
// Use this as a mixin for simple classes that need handles and when you don't
|
||||
// want handles at multiple points of the inheritance hierarchy
|
||||
/**
|
||||
* Use this as a mixin for simple classes that need handles and when you don't
|
||||
* want handles at multiple points of the inheritance hierarchy
|
||||
*/
|
||||
template <typename T>
|
||||
class LLHandleProvider
|
||||
{
|
||||
public:
|
||||
LLHandle<T> getHandle() const
|
||||
{
|
||||
// perform lazy binding to avoid small tombstone allocations for handle
|
||||
// providers whose handles are never referenced
|
||||
mHandle.bind(static_cast<T*>(const_cast<LLHandleProvider<T>* >(this)));
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef LLHandle<T> handle_type_t;
|
||||
LLHandleProvider()
|
||||
@@ -149,16 +201,17 @@ protected:
|
||||
// provided here to enforce T deriving from LLHandleProvider<T>
|
||||
}
|
||||
|
||||
LLHandle<T> getHandle()
|
||||
{
|
||||
// perform lazy binding to avoid small tombstone allocations for handle
|
||||
// providers whose handles are never referenced
|
||||
mHandle.bind(static_cast<T*>(this));
|
||||
return mHandle;
|
||||
template <typename U>
|
||||
LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
|
||||
{
|
||||
LLHandle<U> downcast_handle;
|
||||
downcast_handle.mTombStone = getHandle().mTombStone;
|
||||
return downcast_handle;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
LLRootHandle<T> mHandle;
|
||||
mutable LLRootHandle<T> mHandle;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -80,7 +80,6 @@ void LLPanel::init()
|
||||
mDefaultBtn = NULL;
|
||||
setIsChrome(FALSE); //is this a decorator to a live window or a form?
|
||||
|
||||
mPanelHandle.bind(this);
|
||||
setTabStop(FALSE);
|
||||
mVisibleSignal = NULL;
|
||||
}
|
||||
@@ -766,19 +765,6 @@ void LLPanel::childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanel::childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void *userdata )
|
||||
{
|
||||
LLUICtrl* child = getChild<LLUICtrl>(id, true);
|
||||
if (child)
|
||||
{
|
||||
child->setDoubleClickCallback(cb);
|
||||
if (userdata)
|
||||
{
|
||||
child->setCallbackUserData(userdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanel::childSetValidate(const std::string& id, BOOL (*cb)(LLUICtrl*, void*))
|
||||
{
|
||||
LLUICtrl* child = getChild<LLUICtrl>(id, true);
|
||||
@@ -963,7 +949,7 @@ void LLPanel::childSetWrappedText(const std::string& id, const std::string& text
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void* value)
|
||||
void LLPanel::childSetAction(const std::string& id, boost::function<void(void*)> function, void* value)
|
||||
{
|
||||
LLButton* button = getChild<LLButton>(id);
|
||||
if (button)
|
||||
@@ -972,6 +958,15 @@ void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanel::childSetAction(const std::string& id, const commit_signal_t::slot_type& function)
|
||||
{
|
||||
LLButton* button = getChild<LLButton>(id);
|
||||
if (button)
|
||||
{
|
||||
button->setClickedCallback(function);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*), void* value)
|
||||
{
|
||||
LLTextBox* textbox = getChild<LLTextBox>(id);
|
||||
|
||||
@@ -57,7 +57,7 @@ const BOOL BORDER_NO = FALSE;
|
||||
* With or without border,
|
||||
* Can contain LLUICtrls.
|
||||
*/
|
||||
class LLPanel : public LLUICtrl, public boost::signals2::trackable
|
||||
class LLPanel : public LLUICtrl
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -136,7 +136,7 @@ public:
|
||||
|
||||
void setCtrlsEnabled(BOOL b);
|
||||
|
||||
LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
|
||||
LLHandle<LLPanel> getHandle() const { return getDerivedHandle<LLPanel>(); }
|
||||
|
||||
const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
|
||||
|
||||
@@ -170,7 +170,6 @@ public:
|
||||
BOOL childHasFocus(const std::string& id);
|
||||
|
||||
void childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void* userdata = NULL );
|
||||
void childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void* userdata = NULL );
|
||||
void childSetValidate(const std::string& id, BOOL (*cb)(LLUICtrl*, void*) );
|
||||
void childSetUserData(const std::string& id, void* userdata);
|
||||
|
||||
@@ -211,7 +210,8 @@ public:
|
||||
void childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) );
|
||||
|
||||
// LLButton
|
||||
void childSetAction(const std::string& id, void(*function)(void*), void* value);
|
||||
void childSetAction(const std::string& id, boost::function<void(void*)> function, void* value);
|
||||
void childSetAction(const std::string& id, const commit_signal_t::slot_type& function);
|
||||
void childSetActionTextbox(const std::string& id, void(*function)(void*), void* value = NULL);
|
||||
void childSetControlName(const std::string& id, const std::string& control_name);
|
||||
|
||||
@@ -246,7 +246,6 @@ private:
|
||||
LLViewBorder* mBorder;
|
||||
LLButton* mDefaultBtn;
|
||||
std::string mLabel;
|
||||
LLRootHandle<LLPanel> mPanelHandle;
|
||||
|
||||
typedef std::map<std::string, std::string> ui_string_map_t;
|
||||
ui_string_map_t mUIStrings;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -51,6 +51,7 @@
|
||||
#include "lldate.h"
|
||||
// <edit>
|
||||
#include "lllineeditor.h"
|
||||
#include <boost/function.hpp>
|
||||
// </edit>
|
||||
|
||||
/*
|
||||
@@ -69,13 +70,13 @@ public:
|
||||
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible
|
||||
virtual S32 getWidth() const {return mWidth;}
|
||||
virtual S32 getContentWidth() const { return 0; }
|
||||
virtual S32 getHeight() const = 0;
|
||||
virtual S32 getHeight() const { return 0; }
|
||||
virtual const LLSD getValue() const { return LLStringUtil::null; }
|
||||
virtual void setValue(const LLSD& value) { }
|
||||
virtual BOOL getVisible() const { return TRUE; }
|
||||
virtual void setWidth(S32 width) { mWidth = width; }
|
||||
virtual void highlightText(S32 offset, S32 num_chars) {}
|
||||
virtual BOOL isText() const = 0;
|
||||
virtual BOOL isText() const { return FALSE; }
|
||||
virtual void setColor(const LLColor4&) {}
|
||||
virtual void onCommit() {};
|
||||
|
||||
@@ -86,19 +87,6 @@ private:
|
||||
S32 mWidth;
|
||||
};
|
||||
|
||||
/*
|
||||
* Draws a horizontal line.
|
||||
*/
|
||||
class LLScrollListSeparator : public LLScrollListCell
|
||||
{
|
||||
public:
|
||||
LLScrollListSeparator(S32 width);
|
||||
virtual ~LLScrollListSeparator() {};
|
||||
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible
|
||||
virtual S32 getHeight() const;
|
||||
virtual BOOL isText() const { return FALSE; }
|
||||
};
|
||||
|
||||
/*
|
||||
* Cell displaying a text label.
|
||||
*/
|
||||
@@ -108,22 +96,27 @@ public:
|
||||
LLScrollListText( const std::string& text, const LLFontGL* font, S32 width = 0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
|
||||
/*virtual*/ ~LLScrollListText();
|
||||
|
||||
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
|
||||
virtual S32 getContentWidth() const;
|
||||
virtual S32 getHeight() const;
|
||||
virtual void setValue(const LLSD& value);
|
||||
virtual const LLSD getValue() const;
|
||||
virtual BOOL getVisible() const;
|
||||
virtual void highlightText(S32 offset, S32 num_chars);
|
||||
/*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const;
|
||||
/*virtual*/ S32 getContentWidth() const;
|
||||
/*virtual*/ S32 getHeight() const;
|
||||
/*virtual*/ void setValue(const LLSD& value);
|
||||
/*virtual*/ const LLSD getValue() const;
|
||||
/*virtual*/ BOOL getVisible() const;
|
||||
/*virtual*/ void highlightText(S32 offset, S32 num_chars);
|
||||
|
||||
virtual void setColor(const LLColor4&);
|
||||
virtual BOOL isText() const;
|
||||
/*virtual*/ void setColor(const LLColor4&);
|
||||
/*virtual*/ BOOL isText() const;
|
||||
|
||||
S32 getTextWidth() const { return mTextWidth;}
|
||||
void setTextWidth(S32 value) { mTextWidth = value;}
|
||||
virtual void setWidth(S32 width) { LLScrollListCell::setWidth(width); mTextWidth = width; }
|
||||
|
||||
void setText(const LLStringExplicit& text);
|
||||
void setFontStyle(const U8 font_style) { mFontStyle = font_style; }
|
||||
void setFontStyle(const U8 font_style);
|
||||
|
||||
private:
|
||||
LLUIString mText;
|
||||
S32 mTextWidth;
|
||||
const LLFontGL* mFont;
|
||||
LLColor4 mColor;
|
||||
U8 mUseColor;
|
||||
@@ -138,18 +131,6 @@ private:
|
||||
static U32 sCount;
|
||||
};
|
||||
|
||||
|
||||
class LLScrollListDate : public LLScrollListText
|
||||
{
|
||||
public:
|
||||
LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
|
||||
virtual void setValue(const LLSD& value);
|
||||
virtual const LLSD getValue() const;
|
||||
|
||||
private:
|
||||
LLDate mDate;
|
||||
};
|
||||
|
||||
/*
|
||||
* Cell displaying an image.
|
||||
*/
|
||||
@@ -159,24 +140,22 @@ public:
|
||||
LLScrollListIcon( LLUIImagePtr icon, S32 width = 0);
|
||||
LLScrollListIcon(const LLSD& value, S32 width = 0);
|
||||
/*virtual*/ ~LLScrollListIcon();
|
||||
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
|
||||
virtual S32 getWidth() const;
|
||||
virtual S32 getHeight() const { return mIcon ? mIcon->getHeight() : 0; }
|
||||
virtual const LLSD getValue() const { return mIcon.isNull() ? LLStringUtil::null : mIcon->getName(); }
|
||||
virtual void setColor(const LLColor4&);
|
||||
virtual BOOL isText()const { return FALSE; }
|
||||
virtual void setValue(const LLSD& value);
|
||||
/*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const;
|
||||
/*virtual*/ S32 getWidth() const;
|
||||
/*virtual*/ S32 getHeight() const;
|
||||
/*virtual*/ const LLSD getValue() const;
|
||||
/*virtual*/ void setColor(const LLColor4&);
|
||||
/*virtual*/ void setValue(const LLSD& value);
|
||||
// <edit>
|
||||
void setClickCallback(BOOL (*callback)(void*), void* user_data);
|
||||
void setClickCallback(boost::function<bool (void)> cb);
|
||||
virtual BOOL handleClick();
|
||||
// </edit>
|
||||
|
||||
private:
|
||||
LLUIImagePtr mIcon;
|
||||
LLPointer<LLUIImage> mIcon;
|
||||
LLColor4 mColor;
|
||||
// <edit>
|
||||
BOOL (*mCallback)(void*);
|
||||
void* mUserData;
|
||||
boost::function<bool (void)> mCallback;
|
||||
// </edit>
|
||||
};
|
||||
|
||||
@@ -188,22 +167,33 @@ class LLScrollListCheck : public LLScrollListCell
|
||||
public:
|
||||
LLScrollListCheck( LLCheckBoxCtrl* check_box, S32 width = 0);
|
||||
/*virtual*/ ~LLScrollListCheck();
|
||||
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
|
||||
virtual S32 getHeight() const { return 0; }
|
||||
virtual const LLSD getValue() const { return mCheckBox->getValue(); }
|
||||
virtual void setValue(const LLSD& value) { mCheckBox->setValue(value); }
|
||||
virtual void onCommit() { mCheckBox->onCommit(); }
|
||||
/*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const;
|
||||
/*virtual*/ S32 getHeight() const { return 0; }
|
||||
/*virtual*/ const LLSD getValue() const;
|
||||
/*virtual*/ void setValue(const LLSD& value);
|
||||
/*virtual*/ void onCommit();
|
||||
|
||||
virtual BOOL handleClick();
|
||||
virtual void setEnabled(BOOL enable) { mCheckBox->setEnabled(enable); }
|
||||
/*virtual*/ BOOL handleClick();
|
||||
/*virtual*/ void setEnabled(BOOL enable);
|
||||
|
||||
LLCheckBoxCtrl* getCheckBox() { return mCheckBox; }
|
||||
virtual BOOL isText() const { return FALSE; }
|
||||
|
||||
private:
|
||||
LLCheckBoxCtrl* mCheckBox;
|
||||
};
|
||||
|
||||
|
||||
class LLScrollListDate : public LLScrollListText
|
||||
{
|
||||
public:
|
||||
LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
|
||||
virtual void setValue(const LLSD& value);
|
||||
virtual const LLSD getValue() const;
|
||||
|
||||
private:
|
||||
LLDate mDate;
|
||||
};
|
||||
|
||||
// <edit>
|
||||
class LLScrollListLineEditor : public LLScrollListCell
|
||||
{
|
||||
@@ -228,43 +218,12 @@ private:
|
||||
};
|
||||
// </edit>
|
||||
|
||||
/*
|
||||
* A simple data class describing a column within a scroll list.
|
||||
*/
|
||||
class LLScrollListColumn
|
||||
class LLScrollListColumn;
|
||||
class LLScrollColumnHeader : public LLComboBox
|
||||
{
|
||||
public:
|
||||
LLScrollListColumn();
|
||||
LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent);
|
||||
|
||||
void setWidth(S32 width);
|
||||
S32 getWidth() const { return mWidth; }
|
||||
|
||||
// Public data is fine so long as this remains a simple struct-like data class.
|
||||
// If it ever gets any smarter than that, these should all become private
|
||||
// with protected or public accessor methods added as needed. -MG
|
||||
std::string mName;
|
||||
std::string mSortingColumn;
|
||||
BOOL mSortAscending;
|
||||
std::string mLabel;
|
||||
F32 mRelWidth;
|
||||
BOOL mDynamicWidth;
|
||||
S32 mMaxContentWidth;
|
||||
S32 mIndex;
|
||||
LLScrollListCtrl* mParentCtrl;
|
||||
class LLColumnHeader* mHeader;
|
||||
LLFontGL::HAlign mFontAlignment;
|
||||
|
||||
private:
|
||||
S32 mWidth;
|
||||
|
||||
};
|
||||
|
||||
class LLColumnHeader : public LLComboBox
|
||||
{
|
||||
public:
|
||||
LLColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL *font = NULL);
|
||||
~LLColumnHeader();
|
||||
LLScrollColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL *font = NULL);
|
||||
~LLScrollColumnHeader();
|
||||
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
|
||||
@@ -301,7 +260,44 @@ private:
|
||||
LLColor4 mImageOverlayColor;
|
||||
};
|
||||
|
||||
class LLScrollListItem
|
||||
/*
|
||||
* A simple data class describing a column within a scroll list.
|
||||
*/
|
||||
class LLScrollListColumn
|
||||
{
|
||||
public:
|
||||
typedef enum e_sort_direction
|
||||
{
|
||||
DESCENDING,
|
||||
ASCENDING
|
||||
} ESortDirection;
|
||||
LLScrollListColumn();
|
||||
LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent);
|
||||
|
||||
void setWidth(S32 width);
|
||||
S32 getWidth() const { return mWidth; }
|
||||
|
||||
// Public data is fine so long as this remains a simple struct-like data class.
|
||||
// If it ever gets any smarter than that, these should all become private
|
||||
// with protected or public accessor methods added as needed. -MG
|
||||
std::string mName;
|
||||
std::string mSortingColumn;
|
||||
ESortDirection mSortDirection;
|
||||
std::string mLabel;
|
||||
F32 mRelWidth;
|
||||
BOOL mDynamicWidth;
|
||||
S32 mMaxContentWidth;
|
||||
S32 mIndex;
|
||||
LLScrollListCtrl* mParentCtrl;
|
||||
LLScrollColumnHeader* mHeader;
|
||||
LLFontGL::HAlign mFontAlignment;
|
||||
|
||||
private:
|
||||
S32 mWidth;
|
||||
|
||||
};
|
||||
|
||||
class LLScrollListItem : public LLHandleProvider<LLScrollListItem>
|
||||
{
|
||||
public:
|
||||
LLScrollListItem( BOOL enabled = TRUE, void* userdata = NULL, const LLUUID& uuid = LLUUID::null )
|
||||
@@ -314,7 +310,7 @@ public:
|
||||
void setSelected( BOOL b ) { mSelected = b; }
|
||||
BOOL getSelected() const { return mSelected; }
|
||||
|
||||
void setEnabled( BOOL b );
|
||||
void setEnabled( BOOL b ) { mEnabled = b; }
|
||||
BOOL getEnabled() const { return mEnabled; }
|
||||
|
||||
void setUserdata( void* userdata ) { mUserdata = userdata; }
|
||||
@@ -323,9 +319,12 @@ public:
|
||||
void setToolTip(const std::string tool_tip) { mToolTip=tool_tip; }
|
||||
std::string getToolTip() { return mToolTip; }
|
||||
|
||||
LLUUID getUUID() const { return mItemValue.asUUID(); }
|
||||
virtual LLUUID getUUID() const { return mItemValue.asUUID(); }
|
||||
LLSD getValue() const { return mItemValue; }
|
||||
|
||||
void setRect(LLRect rect) { mRectangle = rect; }
|
||||
LLRect getRect() const { return mRectangle; }
|
||||
|
||||
// If width = 0, just use the width of the text. Otherwise override with
|
||||
// specified width in pixels.
|
||||
void addColumn( const std::string& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, BOOL visible = TRUE)
|
||||
@@ -341,9 +340,9 @@ public:
|
||||
|
||||
void setColumn( S32 column, LLScrollListCell *cell );
|
||||
|
||||
S32 getNumColumns() const { return mColumns.size(); }
|
||||
S32 getNumColumns() const;
|
||||
|
||||
LLScrollListCell *getColumn(const S32 i) const { if (0 <= i && i < (S32)mColumns.size()) { return mColumns[i]; } return NULL; }
|
||||
LLScrollListCell *getColumn(const S32 i) const;
|
||||
|
||||
std::string getContentsCSV() const;
|
||||
|
||||
@@ -356,42 +355,45 @@ private:
|
||||
LLSD mItemValue;
|
||||
std::string mToolTip;
|
||||
std::vector<LLScrollListCell *> mColumns;
|
||||
};
|
||||
|
||||
/*
|
||||
* A graphical control representing a scrollable table.
|
||||
* Cells in the table can be simple text or more complicated things
|
||||
* such as icons or even interactive elements like check boxes.
|
||||
*/
|
||||
class LLScrollListItemComment : public LLScrollListItem
|
||||
{
|
||||
public:
|
||||
LLScrollListItemComment(const std::string& comment_string, const LLColor4& color);
|
||||
|
||||
/*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
|
||||
private:
|
||||
LLColor4 mColor;
|
||||
};
|
||||
|
||||
class LLScrollListItemSeparator : public LLScrollListItem
|
||||
{
|
||||
public:
|
||||
LLScrollListItemSeparator();
|
||||
|
||||
/*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
|
||||
LLRect mRectangle;
|
||||
};
|
||||
|
||||
class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
|
||||
public LLCtrlListInterface, public LLCtrlScrollInterface
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void (void)> callback_t;
|
||||
|
||||
template<typename T> struct maximum
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
template<typename InputIterator>
|
||||
T operator()(InputIterator first, InputIterator last) const
|
||||
{
|
||||
// If there are no slots to call, just return the
|
||||
// default-constructed value
|
||||
if(first == last ) return T();
|
||||
T max_value = *first++;
|
||||
while (first != last) {
|
||||
if (max_value < *first)
|
||||
max_value = *first;
|
||||
++first;
|
||||
}
|
||||
|
||||
return max_value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef boost::signals2::signal<S32 (S32,const LLScrollListItem*,const LLScrollListItem*),maximum<S32> > sort_signal_t;
|
||||
LLScrollListCtrl(
|
||||
const std::string& name,
|
||||
const LLRect& rect,
|
||||
void (*commit_callback)(LLUICtrl*, void*),
|
||||
void* callback_userdata,
|
||||
BOOL allow_multiple_selection,
|
||||
BOOL draw_border = TRUE);
|
||||
BOOL draw_border = TRUE, bool draw_heading = false);
|
||||
|
||||
virtual ~LLScrollListCtrl();
|
||||
|
||||
@@ -415,6 +417,7 @@ public:
|
||||
virtual void setColumnLabel(const std::string& column, const std::string& label);
|
||||
|
||||
virtual LLScrollListColumn* getColumn(S32 index);
|
||||
virtual LLScrollListColumn* getColumn(const std::string& name);
|
||||
virtual S32 getNumColumns() const { return mColumnsIndexed.size(); }
|
||||
|
||||
// Adds a single element, from an array of:
|
||||
@@ -465,10 +468,17 @@ public:
|
||||
void deleteSelectedItems();
|
||||
void deselectAllItems(BOOL no_commit_on_change = FALSE); // by default, go ahead and commit on selection change
|
||||
|
||||
void highlightNthItem( S32 index );
|
||||
void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; }
|
||||
void setMaximumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; }
|
||||
void setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; }
|
||||
void clearHighlightedItems();
|
||||
|
||||
virtual void mouseOverHighlightNthItem( S32 index );
|
||||
|
||||
S32 getHighlightedItemInx() const { return mHighlightedItem; }
|
||||
|
||||
void setDoubleClickCallback( callback_t cb ) { mOnDoubleClickCallback = cb; }
|
||||
void setMaximumSelectCallback( callback_t cb ) { mOnMaximumSelectCallback = cb; }
|
||||
void setSortChangedCallback( callback_t cb ) { mOnSortChangedCallback = cb; }
|
||||
// Convenience function; *TODO: replace with setter above + boost::bind() in calling code
|
||||
void setDoubleClickCallback( boost::function<void (void* userdata)> cb, void* userdata) { mOnDoubleClickCallback = boost::bind(cb, userdata); }
|
||||
|
||||
void swapWithNext(S32 index);
|
||||
void swapWithPrevious(S32 index);
|
||||
@@ -480,7 +490,7 @@ public:
|
||||
S32 getItemIndex( LLScrollListItem* item ) const;
|
||||
S32 getItemIndex( const LLUUID& item_id ) const;
|
||||
|
||||
LLScrollListItem* addCommentText( const std::string& comment_text, EAddPosition pos = ADD_BOTTOM);
|
||||
void setCommentText( const std::string& comment_text);
|
||||
LLScrollListItem* addSeparator(EAddPosition pos);
|
||||
|
||||
// "Simple" interface: use this when you're creating a list that contains only unique strings, only
|
||||
@@ -491,6 +501,7 @@ public:
|
||||
BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE ); // FALSE if item not found
|
||||
BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE);
|
||||
BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE);
|
||||
LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 );
|
||||
const std::string getSelectedItemLabel(S32 column = 0) const;
|
||||
LLSD getSelectedValue();
|
||||
|
||||
@@ -503,7 +514,8 @@ public:
|
||||
LLScrollListItem* getFirstSelected() const;
|
||||
virtual S32 getFirstSelectedIndex() const;
|
||||
std::vector<LLScrollListItem*> getAllSelected() const;
|
||||
LLDynamicArray<LLUUID> getSelectedIDs();
|
||||
uuid_vec_t getSelectedIDs(); //Helper. Much like getAllSelected, but just provides a LLUUID vec
|
||||
S32 getNumSelected() const;
|
||||
LLScrollListItem* getLastSelectedItem() const { return mLastSelected; }
|
||||
|
||||
// iterate over all items
|
||||
@@ -578,17 +590,26 @@ public:
|
||||
|
||||
LLRect getItemListRect() { return mItemListRect; }
|
||||
|
||||
/// Returns rect, in local coords, of a given row/column
|
||||
LLRect getCellRect(S32 row_index, S32 column_index);
|
||||
|
||||
// Used "internally" by the scroll bar.
|
||||
static void onScrollChange( S32 new_pos, LLScrollbar* src, void* userdata );
|
||||
|
||||
static void onClickColumn(void *userdata);
|
||||
|
||||
void updateColumns();
|
||||
void calcColumnWidths();
|
||||
virtual void updateColumns();
|
||||
S32 calcMaxContentWidth();
|
||||
bool updateColumnWidths();
|
||||
S32 getMaxContentWidth() { return mMaxContentWidth; }
|
||||
|
||||
void setDisplayHeading(BOOL display);
|
||||
void setHeadingHeight(S32 heading_height);
|
||||
/**
|
||||
* Sets max visible lines without scroolbar, if this value equals to 0,
|
||||
* then display all items.
|
||||
*/
|
||||
void setPageLines(S32 page_lines );
|
||||
void setCollapseEmptyColumns(BOOL collapse);
|
||||
|
||||
LLScrollListItem* hitItem(S32 x,S32 y);
|
||||
@@ -610,17 +631,25 @@ public:
|
||||
|
||||
std::string getSortColumnName();
|
||||
BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
|
||||
BOOL needsSorting();
|
||||
BOOL hasSortOrder() const;
|
||||
void clearSortOrder();
|
||||
|
||||
S32 selectMultiple( LLDynamicArray<LLUUID> ids );
|
||||
void sortItems();
|
||||
S32 selectMultiple( uuid_vec_t ids );
|
||||
// conceptually const, but mutates mItemList
|
||||
void updateSort() const;
|
||||
// sorts a list without affecting the permanent sort order (so further list insertions can be unsorted, for example)
|
||||
void sortOnce(S32 column, BOOL ascending);
|
||||
|
||||
// manually call this whenever editing list items in place to flag need for resorting
|
||||
void setSorted(BOOL sorted) { mSorted = sorted; }
|
||||
void setNeedsSort(bool val = true) { mSorted = !val; }
|
||||
void dirtyColumns(); // some operation has potentially affected column layout or ordering
|
||||
|
||||
boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
|
||||
{
|
||||
if (!mSortCallback) mSortCallback = new sort_signal_t();
|
||||
return mSortCallback->connect(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
// "Full" interface: use this when you're creating a list that has one or more of the following:
|
||||
// * contains icons
|
||||
@@ -642,11 +671,13 @@ protected:
|
||||
typedef std::deque<LLScrollListItem *> item_list;
|
||||
item_list& getItemList() { return mItemList; }
|
||||
|
||||
void updateLineHeight();
|
||||
|
||||
private:
|
||||
void selectPrevItem(BOOL extend_selection);
|
||||
void selectNextItem(BOOL extend_selection);
|
||||
void drawItems();
|
||||
void updateLineHeight();
|
||||
|
||||
void updateLineHeightInsert(LLScrollListItem* item);
|
||||
void reportInvalidInput();
|
||||
BOOL isRepeatedChars(const LLWString& string) const;
|
||||
@@ -654,10 +685,7 @@ private:
|
||||
void deselectItem(LLScrollListItem* itemp);
|
||||
void commitIfChanged();
|
||||
BOOL setSort(S32 column, BOOL ascending);
|
||||
|
||||
|
||||
S32 mCurIndex; // For get[First/Next]Data
|
||||
S32 mCurSelectedIndex; // For get[First/Next]Selected
|
||||
S32 getLinesPerPage();
|
||||
|
||||
S32 mLineHeight; // the max height of a single line
|
||||
S32 mScrollLines; // how many lines we've scrolled down
|
||||
@@ -665,18 +693,19 @@ private:
|
||||
S32 mHeadingHeight; // the height of the column header buttons, if visible
|
||||
U32 mMaxSelectable;
|
||||
LLScrollbar* mScrollbar;
|
||||
BOOL mAllowMultipleSelection;
|
||||
BOOL mAllowKeyboardMovement;
|
||||
BOOL mCommitOnKeyboardMovement;
|
||||
BOOL mCommitOnSelectionChange;
|
||||
BOOL mSelectionChanged;
|
||||
BOOL mNeedsScroll;
|
||||
BOOL mMouseWheelOpaque;
|
||||
BOOL mCanSelect;
|
||||
BOOL mDisplayColumnHeaders;
|
||||
BOOL mColumnsDirty;
|
||||
bool mAllowMultipleSelection;
|
||||
bool mAllowKeyboardMovement;
|
||||
bool mCommitOnKeyboardMovement;
|
||||
bool mCommitOnSelectionChange;
|
||||
bool mSelectionChanged;
|
||||
bool mNeedsScroll;
|
||||
bool mMouseWheelOpaque;
|
||||
bool mCanSelect;
|
||||
bool mDisplayColumnHeaders;
|
||||
bool mColumnsDirty;
|
||||
bool mColumnWidthsDirty;
|
||||
|
||||
item_list mItemList;
|
||||
mutable item_list mItemList;
|
||||
|
||||
LLScrollListItem *mLastSelected;
|
||||
|
||||
@@ -700,12 +729,14 @@ private:
|
||||
LLColor4 mDefaultListTextColor;
|
||||
|
||||
S32 mBorderThickness;
|
||||
void (*mOnDoubleClickCallback)(void* userdata);
|
||||
void (*mOnMaximumSelectCallback)(void* userdata );
|
||||
void (*mOnSortChangedCallback)(void* userdata);
|
||||
callback_t mOnDoubleClickCallback;
|
||||
callback_t mOnMaximumSelectCallback;
|
||||
callback_t mOnSortChangedCallback;
|
||||
|
||||
S32 mHighlightedItem;
|
||||
class LLViewBorder* mBorder;
|
||||
|
||||
LLView *mCommentTextView;
|
||||
|
||||
LLWString mSearchString;
|
||||
LLFrameTimer mSearchTimer;
|
||||
@@ -715,12 +746,12 @@ private:
|
||||
S32 mTotalStaticColumnWidth;
|
||||
S32 mTotalColumnPadding;
|
||||
|
||||
BOOL mSorted;
|
||||
mutable bool mSorted;
|
||||
|
||||
typedef std::map<std::string, LLScrollListColumn> column_map_t;
|
||||
typedef std::map<std::string, LLScrollListColumn*> column_map_t;
|
||||
column_map_t mColumns;
|
||||
|
||||
BOOL mDirty;
|
||||
bool mDirty;
|
||||
S32 mOriginalSelection;
|
||||
|
||||
typedef std::vector<LLScrollListColumn*> ordered_columns_t;
|
||||
@@ -729,8 +760,7 @@ private:
|
||||
typedef std::pair<S32, BOOL> sort_column_t;
|
||||
std::vector<sort_column_t> mSortColumns;
|
||||
|
||||
// HACK: Did we draw one selected item this frame?
|
||||
BOOL mDrewSelected;
|
||||
sort_signal_t* mSortCallback;
|
||||
}; // end class LLScrollListCtrl
|
||||
|
||||
|
||||
|
||||
@@ -527,10 +527,6 @@ BOOL LLUICtrl::getTentative() const
|
||||
return mTentative;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLUICtrl::setDoubleClickCallback( void (*cb)(void*) )
|
||||
{
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLUICtrl::setColor(const LLColor4& color)
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include "llviewmodel.h" // *TODO move dependency to .cpp file
|
||||
|
||||
class LLUICtrl
|
||||
: public LLView
|
||||
: public LLView
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> commit_callback_t;
|
||||
@@ -103,7 +103,6 @@ public:
|
||||
// Default to no-op:
|
||||
virtual void onTabInto();
|
||||
virtual void clear();
|
||||
virtual void setDoubleClickCallback( void (*cb)(void*) );
|
||||
virtual void setColor(const LLColor4& color);
|
||||
virtual void setAlpha(F32 alpha);
|
||||
virtual void setMinValue(LLSD min_value);
|
||||
|
||||
@@ -132,8 +132,8 @@ public:
|
||||
class LLView
|
||||
: public LLMouseHandler, // handles mouse events
|
||||
public LLFocusableElement, // handles keyboard events
|
||||
public LLMortician // lazy deletion
|
||||
//public LLHandleProvider<LLView> // passes out weak references to self
|
||||
public LLMortician, // lazy deletion
|
||||
public LLHandleProvider<LLView> // passes out weak references to self
|
||||
{
|
||||
public:
|
||||
struct Follows : public LLInitParam::ChoiceBlock<Follows>
|
||||
@@ -344,8 +344,6 @@ public:
|
||||
void popVisible() { setVisible(mLastVisible); }
|
||||
BOOL getLastVisible() const { return mLastVisible; }
|
||||
|
||||
LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; }
|
||||
|
||||
U32 getFollows() const { return mReshapeFlags; }
|
||||
BOOL followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; }
|
||||
BOOL followsRight() const { return mReshapeFlags & FOLLOWS_RIGHT; }
|
||||
@@ -679,7 +677,6 @@ private:
|
||||
BOOL mIsFocusRoot;
|
||||
BOOL mUseBoundingRect; // hit test against bounding rectangle that includes all child elements
|
||||
|
||||
LLRootHandle<LLView> mHandle;
|
||||
BOOL mLastVisible;
|
||||
|
||||
S32 mNextInsertionOrdinal;
|
||||
|
||||
@@ -866,7 +866,9 @@ BOOL LLWindowWin32::setPosition(const LLCoordScreen position)
|
||||
return FALSE;
|
||||
}
|
||||
getSize(&size);
|
||||
|
||||
moveWindow(position, size);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -881,6 +883,7 @@ BOOL LLWindowWin32::setSize(const LLCoordScreen size)
|
||||
}
|
||||
|
||||
moveWindow(position, size);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1655,6 +1658,23 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre
|
||||
|
||||
// THIS CAUSES DEV-15484 and DEV-15949
|
||||
//ShowWindow(mWindowHandle, SW_RESTORE);
|
||||
|
||||
// Singu note: Attempt at fixing this in a different way. Keep an eye out for regression. DEV-15484 showed graphical corruption, especially on impostors.
|
||||
LLCoordScreen old_pos;
|
||||
LLCoordScreen old_size;
|
||||
getSize(&old_size);
|
||||
getPosition(&old_pos);
|
||||
if(position != old_pos || size != old_size)
|
||||
{
|
||||
WINDOWPLACEMENT placement;
|
||||
placement.length = sizeof(WINDOWPLACEMENT);
|
||||
if(GetWindowPlacement(mWindowHandle, &placement))
|
||||
{
|
||||
placement.showCmd = SW_NORMAL;
|
||||
SetWindowPlacement(mWindowHandle, &placement);
|
||||
}
|
||||
}
|
||||
|
||||
// NOW we can call MoveWindow
|
||||
MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ endif(FMOD)
|
||||
include(OPENAL)
|
||||
include(FindOpenGL)
|
||||
include(Hunspell)
|
||||
#include(JsonCpp)
|
||||
include(JsonCpp)
|
||||
include(LLAddBuildTest)
|
||||
include(LLAudio)
|
||||
include(LLCharacter)
|
||||
@@ -370,6 +370,7 @@ set(viewer_SOURCE_FILES
|
||||
llpanelpermissions.cpp
|
||||
llpanelpick.cpp
|
||||
llpanelplace.cpp
|
||||
llpanelprofile.cpp
|
||||
llpanelskins.cpp
|
||||
llpanelvolume.cpp
|
||||
llpanelweb.cpp
|
||||
@@ -538,6 +539,7 @@ set(viewer_SOURCE_FILES
|
||||
llwearablelist.cpp
|
||||
llwearabletype.cpp
|
||||
llweb.cpp
|
||||
llwebprofile.cpp
|
||||
llwind.cpp
|
||||
llwlanimator.cpp
|
||||
llwldaycycle.cpp
|
||||
@@ -546,6 +548,7 @@ set(viewer_SOURCE_FILES
|
||||
llwlparamset.cpp
|
||||
llworld.cpp
|
||||
llworldmap.cpp
|
||||
llworldmapmessage.cpp
|
||||
llworldmipmap.cpp
|
||||
llworldmapview.cpp
|
||||
llxmlrpcresponder.cpp
|
||||
@@ -874,6 +877,7 @@ set(viewer_HEADER_FILES
|
||||
llpanelpermissions.h
|
||||
llpanelpick.h
|
||||
llpanelplace.h
|
||||
llpanelprofile.h
|
||||
llpanelskins.h
|
||||
llpanelvolume.h
|
||||
llpanelweb.h
|
||||
@@ -1047,6 +1051,7 @@ set(viewer_HEADER_FILES
|
||||
llwearablelist.h
|
||||
llwearabletype.h
|
||||
llweb.h
|
||||
llwebprofile.h
|
||||
llwind.h
|
||||
llwindebug.h
|
||||
llwlanimator.h
|
||||
@@ -1056,6 +1061,7 @@ set(viewer_HEADER_FILES
|
||||
llwlparamset.h
|
||||
llworld.h
|
||||
llworldmap.h
|
||||
llworldmapmessage.h
|
||||
llworldmipmap.h
|
||||
llworldmapview.h
|
||||
llxmlrpcresponder.h
|
||||
|
||||
@@ -7414,7 +7414,7 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>WebProfileURL</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>URL for Web Profiles</string>
|
||||
<string>URL for SL Web Profiles</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
@@ -7422,6 +7422,17 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<string>https://my.secondlife.com/[AGENT_NAME]</string>
|
||||
</map>
|
||||
<key>WebProfileNonProductionURL</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>URL for SL Web Profiles on Non-Production grids</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>https://my-demo.secondlife.com/[AGENT_NAME]</string>
|
||||
</map>
|
||||
<key>HighResSnapshot</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -9894,17 +9905,6 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
</map>
|
||||
<key>SaveScriptsAsMono</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When set to TRUE, save scripts in inventory as Mono scripts instead of LSL2</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>PreviewSoundRect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -10163,6 +10163,18 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<integer>128</integer>
|
||||
</map>
|
||||
|
||||
<key>OctreeReserveNodeCapacity</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Default number of elements to pre-allocate for in a single octree node</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>4</integer>
|
||||
</map>
|
||||
|
||||
<key>OctreeStaticObjectSizeFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -10536,7 +10548,7 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>500.0</real>
|
||||
<real>1500.0</real>
|
||||
</map>
|
||||
<key>RenderSSAOMaxScale</key>
|
||||
<map>
|
||||
@@ -10547,7 +10559,7 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>200</integer>
|
||||
<integer>250</integer>
|
||||
</map>
|
||||
<key>RenderSSAOFactor</key>
|
||||
<map>
|
||||
@@ -10558,19 +10570,19 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.30</real>
|
||||
<real>5.0</real>
|
||||
</map>
|
||||
<key>RenderSSAOEffect</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Multiplier for (1) value and (2) saturation (HSV definition), for areas which are totally occluded. Blends with original color for partly-occluded areas. (Third component is unused.)</string>
|
||||
<string>Multiplier for (1) value for areas which are totally occluded. Blends with original color for partly-occluded areas. (Third component is unused.)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>0.80</real>
|
||||
<real>0.50</real>
|
||||
<real>1.00</real>
|
||||
<real>0.00</real>
|
||||
</array>
|
||||
@@ -11157,7 +11169,7 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>3.0</real>
|
||||
<real>1.0</real>
|
||||
<real>2.0</real>
|
||||
<real>0.0</real>
|
||||
</array>
|
||||
@@ -11172,7 +11184,7 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.4</real>
|
||||
<real>3.0</real>
|
||||
</map>
|
||||
<key>RenderShadowBlurSamples</key>
|
||||
<map>
|
||||
|
||||
@@ -174,5 +174,38 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SHPackDeferredNormals</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Pack deferred normals into two components.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SHPrecisionDeferredNormals</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable usage of RGB10A2 for the deferred normalMap format. Reduces normalmapping artifacts.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>SHOcclusionFudge</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Padding added to occlusion bounds. Larger = less aggressive occlusion/less pop-in.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.25</real>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
||||
@@ -34,6 +34,17 @@ uniform sampler2D diffuseMap;
|
||||
VARYING vec3 vary_normal;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
@@ -46,6 +57,6 @@ void main()
|
||||
frag_data[0] = vec4(diff.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(pack(nvn), 0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,32 +64,45 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
vec3 norm = unpack(tc); // unpack norm
|
||||
|
||||
vec3 pos = getPosition(tc).xyz;
|
||||
vec4 ccol = texture2DRect(lightMap, tc).rgba;
|
||||
|
||||
vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
|
||||
vec2 dlt = kern_scale * delta / (vec2(1.0)+norm.xy*norm.xy);
|
||||
dlt /= max(-pos.z*dist_factor, 1.0);
|
||||
|
||||
vec2 defined_weight = getKern(0).xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
|
||||
vec4 col = defined_weight.xyxx * ccol;
|
||||
|
||||
// relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
|
||||
float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005;
|
||||
float pointplanedist_tolerance_pow2 = pos.z*-0.001;
|
||||
|
||||
// perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large
|
||||
float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
|
||||
tc_mod -= floor(tc_mod);
|
||||
tc_mod *= 2.0;
|
||||
vec2 tc_v = fract(0.5 * tc.xy); // we now have floor(mod(tc,2.0))*0.5
|
||||
float tc_mod = 2.0 * abs(tc_v.x - tc_v.y); // diff of x,y makes checkerboard
|
||||
tc += ( (tc_mod - 0.5) * getKern(1).z * dlt * 0.5 );
|
||||
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
vec2 samptc = tc + getKern(i).z*dlt;
|
||||
vec2 samptc = (tc + getKern(i).z * dlt);
|
||||
vec3 samppos = getPosition(samptc).xyz;
|
||||
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
|
||||
if (d*d <= pointplanedist_tolerance_pow2)
|
||||
@@ -100,7 +113,7 @@ void main()
|
||||
}
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
vec2 samptc = tc - getKern(i).z*dlt;
|
||||
vec2 samptc = (tc - getKern(i).z * dlt);
|
||||
vec3 samppos = getPosition(samptc).xyz;
|
||||
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
|
||||
if (d*d <= pointplanedist_tolerance_pow2)
|
||||
@@ -111,7 +124,7 @@ void main()
|
||||
}
|
||||
|
||||
col /= defined_weight.xyxx;
|
||||
col.y *= col.y;
|
||||
col.y *= col.y; // delinearize SSAO effect post-blur
|
||||
|
||||
frag_color = col;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,17 @@ VARYING vec3 vary_mat2;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
|
||||
@@ -52,5 +63,5 @@ void main()
|
||||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(tnorm);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(pack(nvn), 0.0);
|
||||
}
|
||||
|
||||
@@ -102,6 +102,11 @@ void main()
|
||||
/// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(scaleSoftClip(color.rgb), alpha1);
|
||||
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
|
||||
frag_data[2] = vec4(0,0,1,0);
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
frag_data[2] = vec4(0.5,0.5,0.0,0.0);
|
||||
#else
|
||||
frag_data[2] = vec4(0.0,0.0,1.0,0.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,17 @@ VARYING vec3 vary_normal;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color;
|
||||
@@ -49,6 +60,6 @@ void main()
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,17 @@ uniform float minimum_alpha;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color;
|
||||
@@ -48,5 +59,5 @@ void main()
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(pack(nvn), 0.0);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,17 @@ uniform sampler2D diffuseMap;
|
||||
VARYING vec3 vary_normal;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
@@ -49,6 +60,6 @@ void main()
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,17 @@ VARYING vec3 vary_normal;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
|
||||
@@ -42,6 +53,6 @@ void main()
|
||||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,17 @@ VARYING vec3 vary_normal;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
|
||||
@@ -41,5 +52,5 @@ void main()
|
||||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,20 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
|
||||
@@ -78,9 +92,8 @@ void main()
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
norm = normalize(norm);
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
|
||||
@@ -125,6 +125,20 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
@@ -141,10 +155,9 @@ void main()
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0, norm.z);
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
|
||||
norm = normalize(norm);
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
||||
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
|
||||
|
||||
@@ -67,6 +67,20 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
@@ -83,15 +97,14 @@ void main()
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
float da = dot(norm, lv);
|
||||
if (da < 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
norm = normalize(norm);
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
lv = normalize(lv);
|
||||
da = dot(norm, lv);
|
||||
|
||||
|
||||
@@ -61,6 +61,11 @@ void main()
|
||||
/// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);
|
||||
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
|
||||
frag_data[2] = vec4(0,0,1,0);
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
frag_data[2] = vec4(0.5,0.5,0.0,0.0);
|
||||
#else
|
||||
frag_data[2] = vec4(0.0,0.0,1.0,0.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ uniform float max_y;
|
||||
uniform vec4 glow;
|
||||
uniform float scene_light_strength;
|
||||
uniform mat3 env_mat;
|
||||
uniform mat3 ssao_effect_mat;
|
||||
uniform float ssao_effect;
|
||||
|
||||
uniform vec3 sun_dir;
|
||||
VARYING vec2 vary_fragcoord;
|
||||
@@ -203,22 +203,15 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
//increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
|
||||
|
||||
/* decrease value and saturation (that in HSV, not HSL) for occluded areas
|
||||
* // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
|
||||
* // The following line of code performs the equivalent of:
|
||||
* float ambAlpha = tmpAmbient.a;
|
||||
* float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
|
||||
* vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
|
||||
* tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
|
||||
*/
|
||||
tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
|
||||
|
||||
//haze color
|
||||
setAdditiveColor(
|
||||
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
|
||||
+ (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
|
||||
+ tmpAmbient)));
|
||||
|
||||
// decrease value for occluded areas
|
||||
tmpAmbient = vec4(mix(ssao_effect * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
|
||||
|
||||
//brightness of surface both sunlight and ambient
|
||||
setSunlitColor(vec3(sunlight * .5));
|
||||
setAmblitColor(vec3(tmpAmbient * .25));
|
||||
@@ -271,13 +264,26 @@ vec3 scaleSoftClip(vec3 light)
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
float depth = texture2DRect(depthMap, tc.xy).r;
|
||||
vec3 pos = getPosition_d(tc, depth).xyz;
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
vec3 norm = unpack(tc); // unpack norm
|
||||
|
||||
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
|
||||
|
||||
|
||||
@@ -127,6 +127,20 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
@@ -143,10 +157,9 @@ void main()
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0, norm.z);
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
|
||||
norm = normalize(norm);
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
||||
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
|
||||
|
||||
@@ -40,5 +40,10 @@ void main()
|
||||
|
||||
frag_data[0] = col;
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
frag_data[2] = vec4(0,0,1,0);
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
frag_data[2] = vec4(0.5,0.5,0.0,0.0);
|
||||
#else
|
||||
frag_data[2] = vec4(0.0,0.0,1.0,0.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -65,8 +65,6 @@ vec4 getPosition(vec2 pos_screen)
|
||||
//calculate decreases in ambient lighting when crowded out (SSAO)
|
||||
float calcAmbientOcclusion(vec4 pos, vec3 norm)
|
||||
{
|
||||
float ret = 1.0;
|
||||
|
||||
vec2 kern[8];
|
||||
// exponentially (^2) distant occlusion samples spread around origin
|
||||
kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
|
||||
@@ -82,38 +80,54 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm)
|
||||
vec3 pos_world = pos.xyz;
|
||||
vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
|
||||
|
||||
// We treat the first sample as the origin, which definitely doesn't obscure itself thanks to being visible for sampling in the first place.
|
||||
float points = 1.0;
|
||||
float angle_hidden = 0.0;
|
||||
int points = 0;
|
||||
|
||||
float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
|
||||
|
||||
// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations unrolling?)
|
||||
|
||||
// use a kernel scale that diminishes with distance.
|
||||
// a scale of less than 32 is just wasting good samples, though.
|
||||
float scale = max(32.0, min(ssao_radius / -pos.z, ssao_max_radius));
|
||||
|
||||
// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
|
||||
vec3 samppos_world = getPosition(samppos_screen).xyz;
|
||||
|
||||
vec3 diff = pos_world - samppos_world;
|
||||
float dist2 = dot(diff, diff);
|
||||
|
||||
// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
|
||||
// --> solid angle shrinking by the square of distance
|
||||
//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
|
||||
//(k should vary inversely with # of samples, but this is taken care of later)
|
||||
|
||||
angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
|
||||
|
||||
// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
|
||||
points = points + int(diff.z > -1.0);
|
||||
vec3 samppos_world = getPosition(samppos_screen).xyz;
|
||||
|
||||
vec3 diff = samppos_world - pos.xyz;
|
||||
|
||||
if (diff.z < ssao_factor && diff.z != 0.0)
|
||||
{
|
||||
float dist = length(diff);
|
||||
float angrel = max(0.0, dot(norm.xyz, diff/dist));
|
||||
float distrel = 1.0/(1.0+dist*dist);
|
||||
float samplehidden = min(angrel, distrel);
|
||||
|
||||
angle_hidden += (samplehidden);
|
||||
points += 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
|
||||
|
||||
ret = (1.0 - (float(points != 0) * angle_hidden));
|
||||
|
||||
return min(ret, 1.0);
|
||||
angle_hidden /= points;
|
||||
|
||||
float rtn = (1.0 - angle_hidden);
|
||||
|
||||
return (rtn * rtn);
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
void main()
|
||||
{
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
@@ -122,8 +136,7 @@ void main()
|
||||
|
||||
vec4 pos = getPosition(pos_screen);
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
vec3 norm = unpack(pos_screen); // unpack norm
|
||||
|
||||
frag_color[0] = 1.0;
|
||||
frag_color[1] = calcAmbientOcclusion(pos, norm);
|
||||
|
||||
@@ -39,6 +39,17 @@ VARYING vec3 vary_normal;
|
||||
VARYING vec4 vary_texcoord0;
|
||||
VARYING vec4 vary_texcoord1;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
|
||||
@@ -56,6 +67,6 @@ void main()
|
||||
frag_data[0] = vec4(outColor.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,17 @@ VARYING vec2 vary_texcoord0;
|
||||
|
||||
uniform float minimum_alpha;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
@@ -48,5 +59,5 @@ void main()
|
||||
frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
}
|
||||
|
||||
@@ -67,6 +67,17 @@ VARYING vec4 littleWave;
|
||||
VARYING vec4 view;
|
||||
VARYING vec4 vary_position;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color;
|
||||
@@ -151,8 +162,9 @@ void main()
|
||||
//spec *= shadow;
|
||||
//color.rgb += spec * specular;
|
||||
|
||||
//color.rgb = atmosTransport(color.rgb);
|
||||
//color.rgb = scaleSoftClip(color.rgb);
|
||||
color.rgb = atmosTransport(color.rgb);
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
//color.a = spec * sunAngle2;
|
||||
|
||||
//wavef.z *= 0.1f;
|
||||
@@ -161,5 +173,5 @@ void main()
|
||||
|
||||
frag_data[0] = vec4(color.rgb, 0.5); // diffuse
|
||||
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
|
||||
frag_data[2] = vec4(screenspacewavef.xy*0.5+0.5, screenspacewavef.z, screenspacewavef.z*0.5); // normalxyz, displace
|
||||
frag_data[2] = vec4(pack(screenspacewavef), 0.5);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ void main()
|
||||
pos.w = 1.0;
|
||||
pos = modelview_matrix*pos;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
calcAtmospherics(view.xyz);
|
||||
|
||||
//pass wave parameters to pixel shader
|
||||
vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
|
||||
|
||||
@@ -81,7 +81,7 @@ void main()
|
||||
pos.w = 1.0;
|
||||
pos = modelview_matrix*pos;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
calcAtmospherics(view.xyz);
|
||||
|
||||
|
||||
//pass wave parameters to pixel shader
|
||||
|
||||
@@ -126,6 +126,20 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
@@ -153,10 +167,9 @@ void main()
|
||||
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
|
||||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
|
||||
norm = normalize(norm);
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
||||
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
|
||||
|
||||
@@ -63,7 +63,7 @@ uniform vec4 glow;
|
||||
uniform float scene_light_strength;
|
||||
uniform mat3 env_mat;
|
||||
uniform vec4 shadow_clip;
|
||||
uniform mat3 ssao_effect_mat;
|
||||
uniform float ssao_effect;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
@@ -205,22 +205,15 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
//increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
|
||||
|
||||
/* decrease value and saturation (that in HSV, not HSL) for occluded areas
|
||||
* // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
|
||||
* // The following line of code performs the equivalent of:
|
||||
* float ambAlpha = tmpAmbient.a;
|
||||
* float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
|
||||
* vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
|
||||
* tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
|
||||
*/
|
||||
tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
|
||||
|
||||
//haze color
|
||||
setAdditiveColor(
|
||||
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
|
||||
+ (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
|
||||
+ tmpAmbient)));
|
||||
|
||||
// decrease ambient value for occluded areas
|
||||
tmpAmbient *= mix(ssao_effect, 1.0, ambFactor);
|
||||
|
||||
//brightness of surface both sunlight and ambient
|
||||
setSunlitColor(vec3(sunlight * .5));
|
||||
setAmblitColor(vec3(tmpAmbient * .25));
|
||||
@@ -273,13 +266,26 @@ vec3 scaleSoftClip(vec3 light)
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
float depth = texture2DRect(depthMap, tc.xy).r;
|
||||
vec3 pos = getPosition_d(tc, depth).xyz;
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
vec3 norm = unpack(tc); // unpack norm
|
||||
|
||||
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
|
||||
|
||||
|
||||
@@ -126,6 +126,20 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
@@ -153,10 +167,9 @@ void main()
|
||||
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
|
||||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
|
||||
norm = normalize(norm);
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
||||
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
|
||||
|
||||
@@ -116,6 +116,22 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
vec4 unpack(vec2 tc)
|
||||
{
|
||||
vec4 norm = texture2DRect(normalMap, tc).xyzw;
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
norm.xy = (norm.xy*4.0)-2.0;
|
||||
float prod = dot(norm.xy,norm.xy);
|
||||
norm.xy *= sqrt(1.0-prod*.25);
|
||||
norm.z = 1.0-prod*.5;
|
||||
#else
|
||||
norm.xyz = norm.xyz*2.0-1.0;
|
||||
#endif
|
||||
norm.w *= norm.z;
|
||||
return norm;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
@@ -124,8 +140,7 @@ void main()
|
||||
|
||||
vec4 pos = getPosition(pos_screen);
|
||||
|
||||
vec4 nmap4 = texture2DRect(normalMap, pos_screen);
|
||||
nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm
|
||||
vec4 nmap4 = unpack(pos_screen); // unpack norm
|
||||
float displace = nmap4.w;
|
||||
vec3 norm = nmap4.xyz;
|
||||
|
||||
|
||||
@@ -97,46 +97,40 @@ vec2 getKern(int i)
|
||||
//calculate decreases in ambient lighting when crowded out (SSAO)
|
||||
float calcAmbientOcclusion(vec4 pos, vec3 norm)
|
||||
{
|
||||
float ret = 1.0;
|
||||
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
vec3 pos_world = pos.xyz;
|
||||
vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
|
||||
|
||||
|
||||
// We treat the first sample as the origin, which definitely doesn't obscure itself thanks to being visible for sampling in the first place.
|
||||
float points = 1.0;
|
||||
float angle_hidden = 0.0;
|
||||
float points = 0;
|
||||
|
||||
float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
|
||||
// use a kernel scale that diminishes with distance.
|
||||
// a scale of less than 32 is just wasting good samples, though.
|
||||
float scale = max(32.0, min(ssao_radius / -pos.z, ssao_max_radius));
|
||||
|
||||
// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
vec2 samppos_screen = pos_screen + scale * reflect(getKern(i), noise_reflect);
|
||||
vec3 samppos_world = getPosition(samppos_screen).xyz;
|
||||
|
||||
vec3 diff = pos_world - samppos_world;
|
||||
float dist2 = dot(diff, diff);
|
||||
|
||||
// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
|
||||
// --> solid angle shrinking by the square of distance
|
||||
//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
|
||||
//(k should vary inversely with # of samples, but this is taken care of later)
|
||||
|
||||
float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0;
|
||||
angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv);
|
||||
|
||||
// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
|
||||
float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0;
|
||||
points = points + diffz_val;
|
||||
}
|
||||
|
||||
angle_hidden = min(ssao_factor*angle_hidden/points, 1.0);
|
||||
|
||||
float points_val = (points > 0.0) ? 1.0 : 0.0;
|
||||
ret = (1.0 - (points_val * angle_hidden));
|
||||
|
||||
ret = max(ret, 0.0);
|
||||
return min(ret, 1.0);
|
||||
vec3 diff = samppos_world - pos.xyz;
|
||||
|
||||
if (diff.z < ssao_factor && diff.z != 0.0)
|
||||
{
|
||||
float dist = length(diff);
|
||||
float angrel = max(0.0, dot(norm.xyz, diff/dist));
|
||||
float distrel = 1.0/(1.0+dist*dist);
|
||||
float samplehidden = min(angrel, distrel);
|
||||
|
||||
angle_hidden += (samplehidden);
|
||||
points += 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
angle_hidden /= points;
|
||||
float rtn = (1.0 - angle_hidden);
|
||||
return (rtn * rtn);
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
@@ -177,6 +171,22 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
vec4 unpack(vec2 tc)
|
||||
{
|
||||
vec4 norm = texture2DRect(normalMap, tc).xyzw;
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
norm.xy = (norm.xy*4.0)-2.0;
|
||||
float prod = dot(norm.xy,norm.xy);
|
||||
norm.xy *= sqrt(1.0-prod*.25);
|
||||
norm.z = 1.0-prod*.5;
|
||||
#else
|
||||
norm.xyz = norm.xyz*2.0-1.0;
|
||||
#endif
|
||||
norm.w *= norm.z;
|
||||
return norm;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
@@ -185,8 +195,7 @@ void main()
|
||||
|
||||
vec4 pos = getPosition(pos_screen);
|
||||
|
||||
vec4 nmap4 = texture2DRect(normalMap, pos_screen);
|
||||
nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm
|
||||
vec4 nmap4 = unpack(pos_screen); // unpack norm
|
||||
float displace = nmap4.w;
|
||||
vec3 norm = nmap4.xyz;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "llfloaterchat.h"
|
||||
|
||||
ASFloaterContactGroups* ASFloaterContactGroups::sInstance = NULL;
|
||||
LLDynamicArray<LLUUID> ASFloaterContactGroups::mSelectedUUIDs;
|
||||
uuid_vec_t ASFloaterContactGroups::mSelectedUUIDs;
|
||||
LLSD ASFloaterContactGroups::mContactGroupData;
|
||||
|
||||
ASFloaterContactGroups::ASFloaterContactGroups()
|
||||
@@ -40,7 +40,7 @@ ASFloaterContactGroups::ASFloaterContactGroups()
|
||||
}
|
||||
|
||||
// static
|
||||
void ASFloaterContactGroups::show(LLDynamicArray<LLUUID> ids)
|
||||
void ASFloaterContactGroups::show(const uuid_vec_t& ids)
|
||||
{
|
||||
if (!sInstance)
|
||||
sInstance = new ASFloaterContactGroups();
|
||||
@@ -84,7 +84,8 @@ void ASFloaterContactGroups::onBtnAdd(void* userdata)
|
||||
self->createContactGroup(name);
|
||||
combo->selectByValue(name);
|
||||
}
|
||||
for (S32 i = (self->mSelectedUUIDs.count() - 1); i >= 0; --i)
|
||||
uuid_vec_t::reverse_iterator it = self->mSelectedUUIDs.rbegin();
|
||||
for (;it != self->mSelectedUUIDs.rend();++it)
|
||||
{
|
||||
//self->addContactMember(combo->getSimple(), self->mSelectedUUIDs.get(i));
|
||||
}
|
||||
@@ -98,19 +99,21 @@ void ASFloaterContactGroups::onBtnRemove(void* userdata)
|
||||
|
||||
if(self)
|
||||
{
|
||||
if (self->mSelectedUUIDs.count() > 0)
|
||||
if (!self->mSelectedUUIDs.empty())
|
||||
{
|
||||
LLScrollListCtrl* scroller = self->getChild<LLScrollListCtrl>("group_scroll_list");
|
||||
if(scroller != NULL)
|
||||
{
|
||||
for (S32 i = (self->mSelectedUUIDs.count() - 1); i >= 0; --i)
|
||||
uuid_vec_t::size_type i = self->mSelectedUUIDs.size();
|
||||
uuid_vec_t::reverse_iterator it = self->mSelectedUUIDs.rbegin();
|
||||
for (;it != self->mSelectedUUIDs.rend();++it)
|
||||
{
|
||||
std::string i_str;
|
||||
LLResMgr::getInstance()->getIntegerString(i_str, i);
|
||||
LLChat msg("Adding index " + i_str + ": " + self->mSelectedUUIDs.get(i).asString());
|
||||
LLResMgr::getInstance()->getIntegerString(i_str, --i);
|
||||
LLChat msg("Adding index " + i_str + ": " + it->asString());
|
||||
LLFloaterChat::addChat(msg);
|
||||
|
||||
self->addContactMember(scroller->getValue().asString(), self->mSelectedUUIDs.get(i));
|
||||
self->addContactMember(scroller->getValue().asString(), *it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
virtual ~ASFloaterContactGroups();
|
||||
|
||||
// by convention, this shows the floater and does instance management
|
||||
static void show(LLDynamicArray<LLUUID> ids);
|
||||
static void show(const uuid_vec_t& ids);
|
||||
|
||||
void populateGroupList();
|
||||
void populateActiveGroupList(LLUUID to_add);
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
private:
|
||||
//assuming we just need one, which is typical
|
||||
static ASFloaterContactGroups* sInstance;
|
||||
static LLDynamicArray<LLUUID> mSelectedUUIDs;
|
||||
static uuid_vec_t mSelectedUUIDs;
|
||||
static LLSD mContactGroupData;
|
||||
};
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@ void LLPrefsAscentSys::refreshValues()
|
||||
mResetCameraAfterTP = gSavedSettings.getBOOL("OptionRotateCamAfterLocalTP");
|
||||
mOffsetTPByUserHeight = gSavedSettings.getBOOL("OptionOffsetTPByAgentHeight");
|
||||
mPreviewAnimInWorld = gSavedSettings.getBOOL("PreviewAnimInWorld");
|
||||
// mSaveScriptsAsMono = gSavedSettings.getBOOL("SaveScriptsAsMono");
|
||||
mSaveScriptsAsMono = gSavedSettings.getBOOL("SaveInventoryScriptsAsMono");
|
||||
mAlwaysRezInGroup = gSavedSettings.getBOOL("AscentAlwaysRezInGroup");
|
||||
mBuildAlwaysEnabled = gSavedSettings.getBOOL("AscentBuildAlwaysEnabled");
|
||||
mAlwaysShowFly = gSavedSettings.getBOOL("AscentFlyAlwaysEnabled");
|
||||
@@ -417,7 +417,7 @@ void LLPrefsAscentSys::cancel()
|
||||
gSavedSettings.setBOOL("OptionRotateCamAfterLocalTP", mResetCameraAfterTP);
|
||||
gSavedSettings.setBOOL("OptionOffsetTPByAgentHeight", mOffsetTPByUserHeight);
|
||||
gSavedSettings.setBOOL("PreviewAnimInWorld", mPreviewAnimInWorld);
|
||||
// gSavedSettings.setBOOL("SaveScriptsAsMono", mSaveScriptsAsMono);
|
||||
gSavedSettings.setBOOL("SaveInventoryScriptsAsMono", mSaveScriptsAsMono);
|
||||
gSavedSettings.setBOOL("AscentAlwaysRezInGroup", mAlwaysRezInGroup);
|
||||
gSavedSettings.setBOOL("AscentBuildAlwaysEnabled", mBuildAlwaysEnabled);
|
||||
gSavedSettings.setBOOL("AscentFlyAlwaysEnabled", mAlwaysShowFly);
|
||||
|
||||
@@ -59,7 +59,7 @@ protected:
|
||||
BOOL mResetCameraAfterTP;
|
||||
BOOL mOffsetTPByUserHeight;
|
||||
BOOL mPreviewAnimInWorld;
|
||||
// BOOL mSaveScriptsAsMono;
|
||||
BOOL mSaveScriptsAsMono;
|
||||
BOOL mAlwaysRezInGroup;
|
||||
BOOL mBuildAlwaysEnabled;
|
||||
BOOL mAlwaysShowFly;
|
||||
|
||||
@@ -300,8 +300,6 @@ bool cmd_line_chat(std::string revised_text, EChatType type)
|
||||
if(LLUUID::parseUUID(avatarKey, &tempUUID))
|
||||
{
|
||||
char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */
|
||||
LLDynamicArray<LLUUID> ids;
|
||||
ids.push_back(tempUUID);
|
||||
std::string tpMsg="Join me!";
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_StartLure);
|
||||
@@ -312,11 +310,8 @@ bool cmd_line_chat(std::string revised_text, EChatType type)
|
||||
msg->addU8Fast(_PREHASH_LureType, (U8)0);
|
||||
|
||||
msg->addStringFast(_PREHASH_Message, tpMsg);
|
||||
for(LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
|
||||
{
|
||||
msg->nextBlockFast(_PREHASH_TargetData);
|
||||
msg->addUUIDFast(_PREHASH_TargetID, *itr);
|
||||
}
|
||||
msg->nextBlockFast(_PREHASH_TargetData);
|
||||
msg->addUUIDFast(_PREHASH_TargetID, tempUUID);
|
||||
gAgent.sendReliableMessage();
|
||||
snprintf(buffer,sizeof(buffer),"Offered TP to key %s",tempUUID.asString().c_str());
|
||||
cmdline_printchat(std::string(buffer));
|
||||
|
||||
@@ -356,9 +356,9 @@ BOOL LLFloaterAO::postBuild()
|
||||
childSetAction("newcard",onClickNewCard,this);
|
||||
childSetAction("prevstand",onClickPrevStand,this);
|
||||
childSetAction("nextstand",onClickNextStand,this);
|
||||
childSetCommitCallback("AOEnabled",onClickToggleAO);
|
||||
childSetCommitCallback("AOSitsEnabled",onClickToggleSits);
|
||||
childSetCommitCallback("standtime",onSpinnerCommit);
|
||||
getChild<LLComboBox>("AOEnabled")->setCommitCallback(boost::bind(&LLFloaterAO::onClickToggleAO));
|
||||
getChild<LLComboBox>("AOSitsEnabled")->setCommitCallback(boost::bind(&LLFloaterAO::onClickToggleSits));
|
||||
getChild<LLComboBox>("standtime")->setCommitCallback(boost::bind(&LLFloaterAO::onSpinnerCommit,_1));
|
||||
mcomboBox_stands = getChild<LLComboBox>("stands");
|
||||
mcomboBox_walks = getChild<LLComboBox>("walks");
|
||||
mcomboBox_runs = getChild<LLComboBox>("runs");
|
||||
@@ -376,28 +376,28 @@ BOOL LLFloaterAO::postBuild()
|
||||
mcomboBox_lands = getChild<LLComboBox>("lands");
|
||||
mcomboBox_standups = getChild<LLComboBox>("standups");
|
||||
mcomboBox_prejumps = getChild<LLComboBox>("prejumps");
|
||||
getChild<LLComboBox>("stands")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("walks")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("runs")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("jumps")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("sits")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("gsits")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("crouchs")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("cwalks")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("falls")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("hovers")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("flys")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("flyslows")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("flyups")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("flydowns")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("lands")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("standups")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("prejumps")->setCommitCallback(onComboBoxCommit);
|
||||
getChild<LLComboBox>("stands")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("walks")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("runs")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("jumps")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("sits")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("gsits")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("crouchs")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("cwalks")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("falls")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("hovers")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("flys")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("flyslows")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("flyups")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("flydowns")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("lands")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("standups")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
getChild<LLComboBox>("prejumps")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterAO::onSpinnerCommit(LLUICtrl* ctrl, void* userdata)
|
||||
void LLFloaterAO::onSpinnerCommit(LLUICtrl* ctrl)
|
||||
{
|
||||
LLSpinCtrl* spin = (LLSpinCtrl*) ctrl;
|
||||
if(spin)
|
||||
@@ -409,7 +409,7 @@ void LLFloaterAO::onSpinnerCommit(LLUICtrl* ctrl, void* userdata)
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterAO::onComboBoxCommit(LLUICtrl* ctrl, void* userdata)
|
||||
void LLFloaterAO::onComboBoxCommit(LLUICtrl* ctrl)
|
||||
{
|
||||
LLComboBox* box = (LLComboBox*)ctrl;
|
||||
if(box)
|
||||
@@ -727,12 +727,12 @@ void LLFloaterAO::onClickLess(void* data)
|
||||
updateLayout(sInstance);
|
||||
}
|
||||
|
||||
void LLFloaterAO::onClickToggleAO(LLUICtrl *, void*)
|
||||
void LLFloaterAO::onClickToggleAO()
|
||||
{
|
||||
run();
|
||||
}
|
||||
|
||||
void LLFloaterAO::onClickToggleSits(LLUICtrl *, void*)
|
||||
void LLFloaterAO::onClickToggleSits()
|
||||
{
|
||||
run();
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@ public:
|
||||
static void show(void*);
|
||||
static void init();
|
||||
|
||||
static void onClickToggleAO(LLUICtrl *, void*);
|
||||
static void onClickToggleSits(LLUICtrl *, void*);
|
||||
static void onClickToggleAO();
|
||||
static void onClickToggleSits();
|
||||
static void run();
|
||||
static void updateLayout(LLFloaterAO* floater);
|
||||
|
||||
@@ -115,8 +115,8 @@ private:
|
||||
|
||||
static AONoteCardDropTarget* mAOItemDropTarget;
|
||||
static void AOItemDrop(LLViewerInventoryItem* item);
|
||||
static void onSpinnerCommit(LLUICtrl* ctrl, void* userdata);
|
||||
static void onComboBoxCommit(LLUICtrl* ctrl, void* userdata);
|
||||
static void onSpinnerCommit(LLUICtrl* ctrl);
|
||||
static void onComboBoxCommit(LLUICtrl* ctrl);
|
||||
static BOOL SetDefault(void *userdata, LLUUID ao_id, std::string defaultanim);
|
||||
|
||||
BOOL mDirty;
|
||||
|
||||
@@ -800,13 +800,13 @@ FloaterLocalAssetBrowser::FloaterLocalAssetBrowser()
|
||||
mUploadBtn->setClickedCallback( onClickUpload, this);
|
||||
|
||||
// combo callback
|
||||
mTypeComboBox->setCommitCallback(onCommitTypeCombo);
|
||||
mTypeComboBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onCommitTypeCombo,this));
|
||||
|
||||
// scrolllist callbacks
|
||||
mBitmapList->setCommitCallback(onChooseBitmapList);
|
||||
mBitmapList->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onChooseBitmapList,this));
|
||||
|
||||
// checkbox callbacks
|
||||
mUpdateChkBox->setCommitCallback(onClickUpdateChkbox);
|
||||
mUpdateChkBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onClickUpdateChkbox,this));
|
||||
|
||||
}
|
||||
|
||||
@@ -857,34 +857,33 @@ void FloaterLocalAssetBrowser::onClickUpload(void* userdata)
|
||||
}
|
||||
}
|
||||
|
||||
void FloaterLocalAssetBrowser::onChooseBitmapList(LLUICtrl* ctrl, void *userdata)
|
||||
void FloaterLocalAssetBrowser::onChooseBitmapList()
|
||||
{
|
||||
bool button_status = sLFInstance->mBitmapList->isEmpty();
|
||||
sLFInstance->mDelBtn->setEnabled(!button_status);
|
||||
sLFInstance->mUploadBtn->setEnabled(!button_status);
|
||||
bool button_status = mBitmapList->isEmpty();
|
||||
mDelBtn->setEnabled(!button_status);
|
||||
mUploadBtn->setEnabled(!button_status);
|
||||
|
||||
sLFInstance->UpdateRightSide();
|
||||
UpdateRightSide();
|
||||
}
|
||||
|
||||
void FloaterLocalAssetBrowser::onClickUpdateChkbox(LLUICtrl *ctrl, void *userdata)
|
||||
void FloaterLocalAssetBrowser::onClickUpdateChkbox()
|
||||
{
|
||||
std::string temp_str = sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID);
|
||||
std::string temp_str = mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID);
|
||||
if ( !temp_str.empty() )
|
||||
{
|
||||
gLocalBrowser->onUpdateBool( (LLUUID)temp_str );
|
||||
sLFInstance->UpdateRightSide();
|
||||
UpdateRightSide();
|
||||
}
|
||||
}
|
||||
|
||||
void FloaterLocalAssetBrowser::onCommitTypeCombo(LLUICtrl* ctrl, void *userdata)
|
||||
void FloaterLocalAssetBrowser::onCommitTypeCombo()
|
||||
{
|
||||
std::string temp_str = sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID);
|
||||
std::string temp_str = mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID);
|
||||
|
||||
if ( !temp_str.empty() )
|
||||
{
|
||||
S32 selection = sLFInstance->mTypeComboBox->getCurrentIndex();
|
||||
gLocalBrowser->onSetType( (LLUUID)temp_str, selection );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user